Serpent - basic array support introduced:

1. a = [1, 2, 3]
 2. b = a[0]
 3. a[1] = 90
This commit is contained in:
romanman 2014-05-31 22:17:55 +03:00
parent 24f2903ef4
commit 13ae5387dd
11 changed files with 1487 additions and 918 deletions

View File

@ -29,7 +29,7 @@ parse: block EOF
parse_init_code_block : 'init' ':' INDENT block DEDENT 'code' ':' INDENT block DEDENT;
block: ( asm | assign | contract_storage_assign | special_func | if_elif_else_stmt |
block: ( asm | array_assign | assign | contract_storage_assign | special_func | if_elif_else_stmt |
while_stmt | ret_func_1 | ret_func_2 | suicide_func | stop_func)* ;
@ -106,7 +106,13 @@ send_func: 'send' '(' int_val ',' int_val ',' int_val ')';
msg_data: 'msg.data' '[' expression ']' ;
assign: VAR EQ_OP expression NL;
array_assign: VAR '[' int_val ']' EQ_OP expression NL;
array_retreive: VAR '[' int_val ']';
assign: VAR EQ_OP (expression | arr_def) NL;
arr_def : '[' (int_val ','?)* ']';
contract_storage_assign: 'contract.storage' '[' expression ']' EQ_OP expression NL;
contract_storage_load: 'contract.storage' '[' expression ']';
@ -171,9 +177,11 @@ int_val : INT |
msg_func |
msg_data |
send_func |
contract_storage_load
contract_storage_load |
array_retreive
;
// todo: here the val should include also retrieve a variable
hex_num
: HEX_NUMBER
@ -189,7 +197,7 @@ get_var: VAR;
INT: [0-9]+;
ASM_SYMBOLS: 'STOP' | 'ADD' | 'MUL' | 'SUB' | 'DIV' | 'SDIV' | 'MOD' |'SMOD' | 'EXP' | 'NEG' | 'LT' | 'GT' | 'SLT' | 'SGT'| 'EQ' | 'NOT' | 'AND' | 'OR' | 'XOR' | 'BYTE' | 'SHA3' | 'ADDRESS' | 'BALANCE' | 'ORIGIN' | 'CALLER' | 'CALLVALUE' | 'CALLDATALOAD' | 'CALLDATASIZE' | 'CALLDATACOPY' | 'CODESIZE' | 'CODECOPY' | 'GASPRICE' | 'PREVHASH' | 'COINBASE' | 'TIMESTAMP' | 'NUMBER' | 'DIFFICULTY' | 'GASLIMIT' | 'POP' | 'DUP' | 'SWAP' | 'MLOAD' | 'MSTORE' | 'MSTORE8' | 'SLOAD' | 'SSTORE' | 'JUMP' | 'JUMPI' | 'PC' | 'MSIZE' | 'GAS' | 'PUSH1' | 'PUSH2' | 'PUSH3' | 'PUSH4' | 'PUSH5' | 'PUSH6' | 'PUSH7' | 'PUSH8' | 'PUSH9' | 'PUSH10' | 'PUSH11' | 'PUSH12' | 'PUSH13' | 'PUSH14' | 'PUSH15' | 'PUSH16' | 'PUSH17' | 'PUSH18' | 'PUSH19' | 'PUSH20' | 'PUSH21' | 'PUSH22' | 'PUSH23' | 'PUSH24' | 'PUSH25' | 'PUSH26' | 'PUSH27' | 'PUSH28' | 'PUSH29' | 'PUSH30' | 'PUSH31' | 'PUSH32' | 'CREATE' | 'CALL' | 'RETURN' | 'SUICIDE';
ASM_SYMBOLS: 'STOP' | 'ADD' | 'MUL' | 'SUB' | 'DIV' | 'SDIV' | 'MOD' |'SMOD' | 'EXP' | 'NEG' | 'LT' | 'GT' | 'SLT' | 'SGT'| 'EQ' | 'NOT' | 'AND' | 'OR' | 'XOR' | 'BYTE' | 'SHA3' | 'ADDRESS' | 'BALANCE' | 'ORIGIN' | 'CALLER' | 'CALLVALUE' | 'CALLDATALOAD' | 'CALLDATASIZE' | 'CALLDATACOPY' | 'CODESIZE' | 'CODECOPY' | 'GASPRICE' | 'PREVHASH' | 'COINBASE' | 'TIMESTAMP' | 'NUMBER' | 'DIFFICULTY' | 'GASLIMIT' | 'POP' | 'DUP' | 'SWAP' | 'MLOAD' | 'MSTORE' | 'MSTORE8' | 'SLOAD' | 'SSTORE' | 'JUMP' | 'JUMPI' | 'PC' | 'MEMSIZE' | 'GAS' | 'PUSH1' | 'PUSH2' | 'PUSH3' | 'PUSH4' | 'PUSH5' | 'PUSH6' | 'PUSH7' | 'PUSH8' | 'PUSH9' | 'PUSH10' | 'PUSH11' | 'PUSH12' | 'PUSH13' | 'PUSH14' | 'PUSH15' | 'PUSH16' | 'PUSH17' | 'PUSH18' | 'PUSH19' | 'PUSH20' | 'PUSH21' | 'PUSH22' | 'PUSH23' | 'PUSH24' | 'PUSH25' | 'PUSH26' | 'PUSH27' | 'PUSH28' | 'PUSH29' | 'PUSH30' | 'PUSH31' | 'PUSH32' | 'CREATE' | 'CALL' | 'RETURN' | 'SUICIDE';
/* 'xor', 'and', 'or', 'not' operands should be defined
@ -210,6 +218,7 @@ LINE_COMMENT: '#' ~[\r\n]* -> skip;
VAR: [a-zA-Z][a-zA-Z0-9]* ;
OP_ADD : '+' | '-';
OP_MUL : '*' | '/' | '^' | '%' ;

View File

@ -207,6 +207,32 @@ public class SerpentBaseListener implements SerpentListener {
*/
@Override public void exitBlock_difficulty(@NotNull SerpentParser.Block_difficultyContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void enterArray_assign(@NotNull SerpentParser.Array_assignContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void exitArray_assign(@NotNull SerpentParser.Array_assignContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void enterArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void exitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx) { }
/**
* {@inheritDoc}
* <p/>
@ -428,6 +454,19 @@ public class SerpentBaseListener implements SerpentListener {
*/
@Override public void exitSend_func(@NotNull SerpentParser.Send_funcContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void enterArr_def(@NotNull SerpentParser.Arr_defContext ctx) { }
/**
* {@inheritDoc}
* <p/>
* The default implementation does nothing.
*/
@Override public void exitArr_def(@NotNull SerpentParser.Arr_defContext ctx) { }
/**
* {@inheritDoc}
* <p/>

View File

@ -132,6 +132,22 @@ public class SerpentBaseVisitor<T> extends AbstractParseTreeVisitor<T> implement
*/
@Override public T visitBlock_difficulty(@NotNull SerpentParser.Block_difficultyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
* <p/>
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitArray_assign(@NotNull SerpentParser.Array_assignContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
* <p/>
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
* <p/>
@ -268,6 +284,14 @@ public class SerpentBaseVisitor<T> extends AbstractParseTreeVisitor<T> implement
*/
@Override public T visitSend_func(@NotNull SerpentParser.Send_funcContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
* <p/>
* The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitArr_def(@NotNull SerpentParser.Arr_defContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
* <p/>

View File

@ -225,4 +225,6 @@ public class SerpentCompiler {
return result;
}
}

View File

@ -108,7 +108,7 @@ public class SerpentLexer extends Lexer {
}
public static final String _serializedATN =
"\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2\67\u03be\b\1\4\2"+
"\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2\67\u03c0\b\1\4\2"+
"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+
@ -154,296 +154,297 @@ public class SerpentLexer extends Lexer {
"\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%"+
"\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%"+
"\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%"+
"\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\5%\u0361\n%\3&\3&\3&\3&\3\'\3\'\3"+
"\'\3\'\3\'\5\'\u036c\n\'\3(\3(\3(\3(\5(\u0372\n(\3)\3)\3)\3)\5)\u0378"+
"\n)\3*\3*\3+\5+\u037d\n+\3+\3+\7+\u0381\n+\f+\16+\u0384\13+\3,\6,\u0387"+
"\n,\r,\16,\u0388\3,\3,\3-\3-\7-\u038f\n-\f-\16-\u0392\13-\3-\3-\3.\3."+
"\7.\u0398\n.\f.\16.\u039b\13.\3/\3/\3\60\3\60\3\61\3\61\3\61\3\61\3\61"+
"\5\61\u03a6\n\61\3\62\3\62\3\62\3\62\5\62\u03ac\n\62\3\63\3\63\3\64\3"+
"\64\3\65\3\65\3\66\3\66\3\66\3\66\5\66\u03b8\n\66\3\66\6\66\u03bb\n\66"+
"\r\66\16\66\u03bc\2\67\3\3\1\5\4\1\7\5\1\t\6\1\13\7\1\r\b\1\17\t\1\21"+
"\n\1\23\13\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20\1\37\21\1!\22\1#\23\1"+
"%\24\1\'\25\1)\26\1+\27\1-\30\1/\31\1\61\32\1\63\33\1\65\34\1\67\35\1"+
"9\36\1;\37\1= \1?!\1A\"\1C#\1E$\1G%\1I&\1K\'\1M(\1O)\1Q*\1S+\1U,\1W-\2"+
"Y.\3[/\1]\60\1_\61\1a\62\1c\63\1e\64\1g\65\1i\66\1k\67\1\3\2\13\3\2\62"+
";\4\2\13\13\"\"\4\2\f\f\17\17\4\2C\\c|\5\2\62;C\\c|\4\2--//\6\2\'\',,"+
"\61\61``\4\2>>@@\5\2\62;CHch\u0421\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2"+
"\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3"+
"\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2"+
"\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2"+
"\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2"+
"\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2"+
"\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2"+
"O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3"+
"\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2"+
"\2\2i\3\2\2\2\2k\3\2\2\2\3m\3\2\2\2\5o\3\2\2\2\7t\3\2\2\2\t\u0083\3\2"+
"\2\2\13\u0085\3\2\2\2\r\u0089\3\2\2\2\17\u0090\3\2\2\2\21\u0096\3\2\2"+
"\2\23\u0098\3\2\2\2\25\u009a\3\2\2\2\27\u009c\3\2\2\2\31\u009f\3\2\2\2"+
"\33\u00a4\3\2\2\2\35\u00b4\3\2\2\2\37\u00b9\3\2\2\2!\u00c3\3\2\2\2#\u00c8"+
"\3\2\2\2%\u00d7\3\2\2\2\'\u00e8\3\2\2\2)\u00f0\3\2\2\2+\u0101\3\2\2\2"+
"-\u010e\3\2\2\2/\u0110\3\2\2\2\61\u011c\3\2\2\2\63\u0122\3\2\2\2\65\u012c"+
"\3\2\2\2\67\u0135\3\2\2\29\u013a\3\2\2\2;\u0141\3\2\2\2=\u014c\3\2\2\2"+
"?\u015d\3\2\2\2A\u0162\3\2\2\2C\u0171\3\2\2\2E\u017e\3\2\2\2G\u0184\3"+
"\2\2\2I\u0360\3\2\2\2K\u0362\3\2\2\2M\u036b\3\2\2\2O\u0371\3\2\2\2Q\u0377"+
"\3\2\2\2S\u0379\3\2\2\2U\u037c\3\2\2\2W\u0386\3\2\2\2Y\u038c\3\2\2\2["+
"\u0395\3\2\2\2]\u039c\3\2\2\2_\u039e\3\2\2\2a\u03a5\3\2\2\2c\u03ab\3\2"+
"\2\2e\u03ad\3\2\2\2g\u03af\3\2\2\2i\u03b1\3\2\2\2k\u03b7\3\2\2\2mn\7_"+
"\2\2n\4\3\2\2\2op\7u\2\2pq\7v\2\2qr\7q\2\2rs\7r\2\2s\6\3\2\2\2tu\7d\2"+
"\2uv\7n\2\2vw\7q\2\2wx\7e\2\2xy\7m\2\2yz\7\60\2\2z{\7e\2\2{|\7q\2\2|}"+
"\7k\2\2}~\7p\2\2~\177\7d\2\2\177\u0080\7c\2\2\u0080\u0081\7u\2\2\u0081"+
"\u0082\7g\2\2\u0082\b\3\2\2\2\u0083\u0084\7.\2\2\u0084\n\3\2\2\2\u0085"+
"\u0086\7o\2\2\u0086\u0087\7u\2\2\u0087\u0088\7i\2\2\u0088\f\3\2\2\2\u0089"+
"\u008a\7v\2\2\u008a\u008b\7z\2\2\u008b\u008c\7\60\2\2\u008c\u008d\7i\2"+
"\2\u008d\u008e\7c\2\2\u008e\u008f\7u\2\2\u008f\16\3\2\2\2\u0090\u0091"+
"\7y\2\2\u0091\u0092\7j\2\2\u0092\u0093\7k\2\2\u0093\u0094\7n\2\2\u0094"+
"\u0095\7g\2\2\u0095\20\3\2\2\2\u0096\u0097\7]\2\2\u0097\22\3\2\2\2\u0098"+
"\u0099\7*\2\2\u0099\24\3\2\2\2\u009a\u009b\7<\2\2\u009b\26\3\2\2\2\u009c"+
"\u009d\7k\2\2\u009d\u009e\7h\2\2\u009e\30\3\2\2\2\u009f\u00a0\7u\2\2\u00a0"+
"\u00a1\7g\2\2\u00a1\u00a2\7p\2\2\u00a2\u00a3\7f\2\2\u00a3\32\3\2\2\2\u00a4"+
"\u00a5\7d\2\2\u00a5\u00a6\7n\2\2\u00a6\u00a7\7q\2\2\u00a7\u00a8\7e\2\2"+
"\u00a8\u00a9\7m\2\2\u00a9\u00aa\7\60\2\2\u00aa\u00ab\7v\2\2\u00ab\u00ac"+
"\7k\2\2\u00ac\u00ad\7o\2\2\u00ad\u00ae\7g\2\2\u00ae\u00af\7u\2\2\u00af"+
"\u00b0\7v\2\2\u00b0\u00b1\7c\2\2\u00b1\u00b2\7o\2\2\u00b2\u00b3\7r\2\2"+
"\u00b3\34\3\2\2\2\u00b4\u00b5\7]\2\2\u00b5\u00b6\7c\2\2\u00b6\u00b7\7"+
"u\2\2\u00b7\u00b8\7o\2\2\u00b8\36\3\2\2\2\u00b9\u00ba\7o\2\2\u00ba\u00bb"+
"\7u\2\2\u00bb\u00bc\7i\2\2\u00bc\u00bd\7\60\2\2\u00bd\u00be\7x\2\2\u00be"+
"\u00bf\7c\2\2\u00bf\u00c0\7n\2\2\u00c0\u00c1\7w\2\2\u00c1\u00c2\7g\2\2"+
"\u00c2 \3\2\2\2\u00c3\u00c4\7k\2\2\u00c4\u00c5\7p\2\2\u00c5\u00c6\7k\2"+
"\2\u00c6\u00c7\7v\2\2\u00c7\"\3\2\2\2\u00c8\u00c9\7d\2\2\u00c9\u00ca\7"+
"n\2\2\u00ca\u00cb\7q\2\2\u00cb\u00cc\7e\2\2\u00cc\u00cd\7m\2\2\u00cd\u00ce"+
"\7\60\2\2\u00ce\u00cf\7r\2\2\u00cf\u00d0\7t\2\2\u00d0\u00d1\7g\2\2\u00d1"+
"\u00d2\7x\2\2\u00d2\u00d3\7j\2\2\u00d3\u00d4\7c\2\2\u00d4\u00d5\7u\2\2"+
"\u00d5\u00d6\7j\2\2\u00d6$\3\2\2\2\u00d7\u00d8\7e\2\2\u00d8\u00d9\7q\2"+
"\2\u00d9\u00da\7p\2\2\u00da\u00db\7v\2\2\u00db\u00dc\7t\2\2\u00dc\u00dd"+
"\7c\2\2\u00dd\u00de\7e\2\2\u00de\u00df\7v\2\2\u00df\u00e0\7\60\2\2\u00e0"+
"\u00e1\7u\2\2\u00e1\u00e2\7v\2\2\u00e2\u00e3\7q\2\2\u00e3\u00e4\7t\2\2"+
"\u00e4\u00e5\7c\2\2\u00e5\u00e6\7i\2\2\u00e6\u00e7\7g\2\2\u00e7&\3\2\2"+
"\2\u00e8\u00e9\7u\2\2\u00e9\u00ea\7w\2\2\u00ea\u00eb\7k\2\2\u00eb\u00ec"+
"\7e\2\2\u00ec\u00ed\7k\2\2\u00ed\u00ee\7f\2\2\u00ee\u00ef\7g\2\2\u00ef"+
"(\3\2\2\2\u00f0\u00f1\7d\2\2\u00f1\u00f2\7n\2\2\u00f2\u00f3\7q\2\2\u00f3"+
"\u00f4\7e\2\2\u00f4\u00f5\7m\2\2\u00f5\u00f6\7\60\2\2\u00f6\u00f7\7f\2"+
"\2\u00f7\u00f8\7k\2\2\u00f8\u00f9\7h\2\2\u00f9\u00fa\7h\2\2\u00fa\u00fb"+
"\7k\2\2\u00fb\u00fc\7e\2\2\u00fc\u00fd\7w\2\2\u00fd\u00fe\7n\2\2\u00fe"+
"\u00ff\7v\2\2\u00ff\u0100\7{\2\2\u0100*\3\2\2\2\u0101\u0102\7o\2\2\u0102"+
"\u0103\7u\2\2\u0103\u0104\7i\2\2\u0104\u0105\7\60\2\2\u0105\u0106\7f\2"+
"\2\u0106\u0107\7c\2\2\u0107\u0108\7v\2\2\u0108\u0109\7c\2\2\u0109\u010a"+
"\7u\2\2\u010a\u010b\7k\2\2\u010b\u010c\7|\2\2\u010c\u010d\7g\2\2\u010d"+
",\3\2\2\2\u010e\u010f\7+\2\2\u010f.\3\2\2\2\u0110\u0111\7v\2\2\u0111\u0112"+
"\7z\2\2\u0112\u0113\7\60\2\2\u0113\u0114\7i\2\2\u0114\u0115\7c\2\2\u0115"+
"\u0116\7u\2\2\u0116\u0117\7r\2\2\u0117\u0118\7t\2\2\u0118\u0119\7k\2\2"+
"\u0119\u011a\7e\2\2\u011a\u011b\7g\2\2\u011b\60\3\2\2\2\u011c\u011d\7"+
"g\2\2\u011d\u011e\7n\2\2\u011e\u011f\7u\2\2\u011f\u0120\7g\2\2\u0120\u0121"+
"\7<\2\2\u0121\62\3\2\2\2\u0122\u0123\7v\2\2\u0123\u0124\7z\2\2\u0124\u0125"+
"\7\60\2\2\u0125\u0126\7q\2\2\u0126\u0127\7t\2\2\u0127\u0128\7k\2\2\u0128"+
"\u0129\7i\2\2\u0129\u012a\7k\2\2\u012a\u012b\7p\2\2\u012b\64\3\2\2\2\u012c"+
"\u012d\7o\2\2\u012d\u012e\7u\2\2\u012e\u012f\7i\2\2\u012f\u0130\7\60\2"+
"\2\u0130\u0131\7f\2\2\u0131\u0132\7c\2\2\u0132\u0133\7v\2\2\u0133\u0134"+
"\7c\2\2\u0134\66\3\2\2\2\u0135\u0136\7g\2\2\u0136\u0137\7n\2\2\u0137\u0138"+
"\7k\2\2\u0138\u0139\7h\2\2\u01398\3\2\2\2\u013a\u013b\7t\2\2\u013b\u013c"+
"\7g\2\2\u013c\u013d\7v\2\2\u013d\u013e\7w\2\2\u013e\u013f\7t\2\2\u013f"+
"\u0140\7p\2\2\u0140:\3\2\2\2\u0141\u0142\7o\2\2\u0142\u0143\7u\2\2\u0143"+
"\u0144\7i\2\2\u0144\u0145\7\60\2\2\u0145\u0146\7u\2\2\u0146\u0147\7g\2"+
"\2\u0147\u0148\7p\2\2\u0148\u0149\7f\2\2\u0149\u014a\7g\2\2\u014a\u014b"+
"\7t\2\2\u014b<\3\2\2\2\u014c\u014d\7e\2\2\u014d\u014e\7q\2\2\u014e\u014f"+
"\7p\2\2\u014f\u0150\7v\2\2\u0150\u0151\7t\2\2\u0151\u0152\7c\2\2\u0152"+
"\u0153\7e\2\2\u0153\u0154\7v\2\2\u0154\u0155\7\60\2\2\u0155\u0156\7d\2"+
"\2\u0156\u0157\7c\2\2\u0157\u0158\7n\2\2\u0158\u0159\7c\2\2\u0159\u015a"+
"\7p\2\2\u015a\u015b\7e\2\2\u015b\u015c\7g\2\2\u015c>\3\2\2\2\u015d\u015e"+
"\7c\2\2\u015e\u015f\7u\2\2\u015f\u0160\7o\2\2\u0160\u0161\7_\2\2\u0161"+
"@\3\2\2\2\u0162\u0163\7d\2\2\u0163\u0164\7n\2\2\u0164\u0165\7q\2\2\u0165"+
"\u0166\7e\2\2\u0166\u0167\7m\2\2\u0167\u0168\7\60\2\2\u0168\u0169\7i\2"+
"\2\u0169\u016a\7c\2\2\u016a\u016b\7u\2\2\u016b\u016c\7n\2\2\u016c\u016d"+
"\7k\2\2\u016d\u016e\7o\2\2\u016e\u016f\7k\2\2\u016f\u0170\7v\2\2\u0170"+
"B\3\2\2\2\u0171\u0172\7d\2\2\u0172\u0173\7n\2\2\u0173\u0174\7q\2\2\u0174"+
"\u0175\7e\2\2\u0175\u0176\7m\2\2\u0176\u0177\7\60\2\2\u0177\u0178\7p\2"+
"\2\u0178\u0179\7w\2\2\u0179\u017a\7o\2\2\u017a\u017b\7d\2\2\u017b\u017c"+
"\7g\2\2\u017c\u017d\7t\2\2\u017dD\3\2\2\2\u017e\u017f\7e\2\2\u017f\u0180"+
"\7q\2\2\u0180\u0181\7f\2\2\u0181\u0182\7g\2\2\u0182F\3\2\2\2\u0183\u0185"+
"\t\2\2\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u0184\3\2\2\2\u0186"+
"\u0187\3\2\2\2\u0187H\3\2\2\2\u0188\u0189\7U\2\2\u0189\u018a\7V\2\2\u018a"+
"\u018b\7Q\2\2\u018b\u0361\7R\2\2\u018c\u018d\7C\2\2\u018d\u018e\7F\2\2"+
"\u018e\u0361\7F\2\2\u018f\u0190\7O\2\2\u0190\u0191\7W\2\2\u0191\u0361"+
"\7N\2\2\u0192\u0193\7U\2\2\u0193\u0194\7W\2\2\u0194\u0361\7D\2\2\u0195"+
"\u0196\7F\2\2\u0196\u0197\7K\2\2\u0197\u0361\7X\2\2\u0198\u0199\7U\2\2"+
"\u0199\u019a\7F\2\2\u019a\u019b\7K\2\2\u019b\u0361\7X\2\2\u019c\u019d"+
"\7O\2\2\u019d\u019e\7Q\2\2\u019e\u0361\7F\2\2\u019f\u01a0\7U\2\2\u01a0"+
"\u01a1\7O\2\2\u01a1\u01a2\7Q\2\2\u01a2\u0361\7F\2\2\u01a3\u01a4\7G\2\2"+
"\u01a4\u01a5\7Z\2\2\u01a5\u0361\7R\2\2\u01a6\u01a7\7P\2\2\u01a7\u01a8"+
"\7G\2\2\u01a8\u0361\7I\2\2\u01a9\u01aa\7N\2\2\u01aa\u0361\7V\2\2\u01ab"+
"\u01ac\7I\2\2\u01ac\u0361\7V\2\2\u01ad\u01ae\7U\2\2\u01ae\u01af\7N\2\2"+
"\u01af\u0361\7V\2\2\u01b0\u01b1\7U\2\2\u01b1\u01b2\7I\2\2\u01b2\u0361"+
"\7V\2\2\u01b3\u01b4\7G\2\2\u01b4\u0361\7S\2\2\u01b5\u01b6\7P\2\2\u01b6"+
"\u01b7\7Q\2\2\u01b7\u0361\7V\2\2\u01b8\u01b9\7C\2\2\u01b9\u01ba\7P\2\2"+
"\u01ba\u0361\7F\2\2\u01bb\u01bc\7Q\2\2\u01bc\u0361\7T\2\2\u01bd\u01be"+
"\7Z\2\2\u01be\u01bf\7Q\2\2\u01bf\u0361\7T\2\2\u01c0\u01c1\7D\2\2\u01c1"+
"\u01c2\7[\2\2\u01c2\u01c3\7V\2\2\u01c3\u0361\7G\2\2\u01c4\u01c5\7U\2\2"+
"\u01c5\u01c6\7J\2\2\u01c6\u01c7\7C\2\2\u01c7\u0361\7\65\2\2\u01c8\u01c9"+
"\7C\2\2\u01c9\u01ca\7F\2\2\u01ca\u01cb\7F\2\2\u01cb\u01cc\7T\2\2\u01cc"+
"\u01cd\7G\2\2\u01cd\u01ce\7U\2\2\u01ce\u0361\7U\2\2\u01cf\u01d0\7D\2\2"+
"\u01d0\u01d1\7C\2\2\u01d1\u01d2\7N\2\2\u01d2\u01d3\7C\2\2\u01d3\u01d4"+
"\7P\2\2\u01d4\u01d5\7E\2\2\u01d5\u0361\7G\2\2\u01d6\u01d7\7Q\2\2\u01d7"+
"\u01d8\7T\2\2\u01d8\u01d9\7K\2\2\u01d9\u01da\7I\2\2\u01da\u01db\7K\2\2"+
"\u01db\u0361\7P\2\2\u01dc\u01dd\7E\2\2\u01dd\u01de\7C\2\2\u01de\u01df"+
"\7N\2\2\u01df\u01e0\7N\2\2\u01e0\u01e1\7G\2\2\u01e1\u0361\7T\2\2\u01e2"+
"\u01e3\7E\2\2\u01e3\u01e4\7C\2\2\u01e4\u01e5\7N\2\2\u01e5\u01e6\7N\2\2"+
"\u01e6\u01e7\7X\2\2\u01e7\u01e8\7C\2\2\u01e8\u01e9\7N\2\2\u01e9\u01ea"+
"\7W\2\2\u01ea\u0361\7G\2\2\u01eb\u01ec\7E\2\2\u01ec\u01ed\7C\2\2\u01ed"+
"\u01ee\7N\2\2\u01ee\u01ef\7N\2\2\u01ef\u01f0\7F\2\2\u01f0\u01f1\7C\2\2"+
"\u01f1\u01f2\7V\2\2\u01f2\u01f3\7C\2\2\u01f3\u01f4\7N\2\2\u01f4\u01f5"+
"\7Q\2\2\u01f5\u01f6\7C\2\2\u01f6\u0361\7F\2\2\u01f7\u01f8\7E\2\2\u01f8"+
"\u01f9\7C\2\2\u01f9\u01fa\7N\2\2\u01fa\u01fb\7N\2\2\u01fb\u01fc\7F\2\2"+
"\u01fc\u01fd\7C\2\2\u01fd\u01fe\7V\2\2\u01fe\u01ff\7C\2\2\u01ff\u0200"+
"\7U\2\2\u0200\u0201\7K\2\2\u0201\u0202\7\\\2\2\u0202\u0361\7G\2\2\u0203"+
"\u0204\7E\2\2\u0204\u0205\7C\2\2\u0205\u0206\7N\2\2\u0206\u0207\7N\2\2"+
"\u0207\u0208\7F\2\2\u0208\u0209\7C\2\2\u0209\u020a\7V\2\2\u020a\u020b"+
"\7C\2\2\u020b\u020c\7E\2\2\u020c\u020d\7Q\2\2\u020d\u020e\7R\2\2\u020e"+
"\u0361\7[\2\2\u020f\u0210\7E\2\2\u0210\u0211\7Q\2\2\u0211\u0212\7F\2\2"+
"\u0212\u0213\7G\2\2\u0213\u0214\7U\2\2\u0214\u0215\7K\2\2\u0215\u0216"+
"\7\\\2\2\u0216\u0361\7G\2\2\u0217\u0218\7E\2\2\u0218\u0219\7Q\2\2\u0219"+
"\u021a\7F\2\2\u021a\u021b\7G\2\2\u021b\u021c\7E\2\2\u021c\u021d\7Q\2\2"+
"\u021d\u021e\7R\2\2\u021e\u0361\7[\2\2\u021f\u0220\7I\2\2\u0220\u0221"+
"\7C\2\2\u0221\u0222\7U\2\2\u0222\u0223\7R\2\2\u0223\u0224\7T\2\2\u0224"+
"\u0225\7K\2\2\u0225\u0226\7E\2\2\u0226\u0361\7G\2\2\u0227\u0228\7R\2\2"+
"\u0228\u0229\7T\2\2\u0229\u022a\7G\2\2\u022a\u022b\7X\2\2\u022b\u022c"+
"\7J\2\2\u022c\u022d\7C\2\2\u022d\u022e\7U\2\2\u022e\u0361\7J\2\2\u022f"+
"\u0230\7E\2\2\u0230\u0231\7Q\2\2\u0231\u0232\7K\2\2\u0232\u0233\7P\2\2"+
"\u0233\u0234\7D\2\2\u0234\u0235\7C\2\2\u0235\u0236\7U\2\2\u0236\u0361"+
"\7G\2\2\u0237\u0238\7V\2\2\u0238\u0239\7K\2\2\u0239\u023a\7O\2\2\u023a"+
"\u023b\7G\2\2\u023b\u023c\7U\2\2\u023c\u023d\7V\2\2\u023d\u023e\7C\2\2"+
"\u023e\u023f\7O\2\2\u023f\u0361\7R\2\2\u0240\u0241\7P\2\2\u0241\u0242"+
"\7W\2\2\u0242\u0243\7O\2\2\u0243\u0244\7D\2\2\u0244\u0245\7G\2\2\u0245"+
"\u0361\7T\2\2\u0246\u0247\7F\2\2\u0247\u0248\7K\2\2\u0248\u0249\7H\2\2"+
"\u0249\u024a\7H\2\2\u024a\u024b\7K\2\2\u024b\u024c\7E\2\2\u024c\u024d"+
"\7W\2\2\u024d\u024e\7N\2\2\u024e\u024f\7V\2\2\u024f\u0361\7[\2\2\u0250"+
"\u0251\7I\2\2\u0251\u0252\7C\2\2\u0252\u0253\7U\2\2\u0253\u0254\7N\2\2"+
"\u0254\u0255\7K\2\2\u0255\u0256\7O\2\2\u0256\u0257\7K\2\2\u0257\u0361"+
"\7V\2\2\u0258\u0259\7R\2\2\u0259\u025a\7Q\2\2\u025a\u0361\7R\2\2\u025b"+
"\u025c\7F\2\2\u025c\u025d\7W\2\2\u025d\u0361\7R\2\2\u025e\u025f\7U\2\2"+
"\u025f\u0260\7Y\2\2\u0260\u0261\7C\2\2\u0261\u0361\7R\2\2\u0262\u0263"+
"\7O\2\2\u0263\u0264\7N\2\2\u0264\u0265\7Q\2\2\u0265\u0266\7C\2\2\u0266"+
"\u0361\7F\2\2\u0267\u0268\7O\2\2\u0268\u0269\7U\2\2\u0269\u026a\7V\2\2"+
"\u026a\u026b\7Q\2\2\u026b\u026c\7T\2\2\u026c\u0361\7G\2\2\u026d\u026e"+
"\7O\2\2\u026e\u026f\7U\2\2\u026f\u0270\7V\2\2\u0270\u0271\7Q\2\2\u0271"+
"\u0272\7T\2\2\u0272\u0273\7G\2\2\u0273\u0361\7:\2\2\u0274\u0275\7U\2\2"+
"\u0275\u0276\7N\2\2\u0276\u0277\7Q\2\2\u0277\u0278\7C\2\2\u0278\u0361"+
"\7F\2\2\u0279\u027a\7U\2\2\u027a\u027b\7U\2\2\u027b\u027c\7V\2\2\u027c"+
"\u027d\7Q\2\2\u027d\u027e\7T\2\2\u027e\u0361\7G\2\2\u027f\u0280\7L\2\2"+
"\u0280\u0281\7W\2\2\u0281\u0282\7O\2\2\u0282\u0361\7R\2\2\u0283\u0284"+
"\7L\2\2\u0284\u0285\7W\2\2\u0285\u0286\7O\2\2\u0286\u0287\7R\2\2\u0287"+
"\u0361\7K\2\2\u0288\u0289\7R\2\2\u0289\u0361\7E\2\2\u028a\u028b\7O\2\2"+
"\u028b\u028c\7U\2\2\u028c\u028d\7K\2\2\u028d\u028e\7\\\2\2\u028e\u0361"+
"\7G\2\2\u028f\u0290\7I\2\2\u0290\u0291\7C\2\2\u0291\u0361\7U\2\2\u0292"+
"\u0293\7R\2\2\u0293\u0294\7W\2\2\u0294\u0295\7U\2\2\u0295\u0296\7J\2\2"+
"\u0296\u0361\7\63\2\2\u0297\u0298\7R\2\2\u0298\u0299\7W\2\2\u0299\u029a"+
"\7U\2\2\u029a\u029b\7J\2\2\u029b\u0361\7\64\2\2\u029c\u029d\7R\2\2\u029d"+
"\u029e\7W\2\2\u029e\u029f\7U\2\2\u029f\u02a0\7J\2\2\u02a0\u0361\7\65\2"+
"\2\u02a1\u02a2\7R\2\2\u02a2\u02a3\7W\2\2\u02a3\u02a4\7U\2\2\u02a4\u02a5"+
"\7J\2\2\u02a5\u0361\7\66\2\2\u02a6\u02a7\7R\2\2\u02a7\u02a8\7W\2\2\u02a8"+
"\u02a9\7U\2\2\u02a9\u02aa\7J\2\2\u02aa\u0361\7\67\2\2\u02ab\u02ac\7R\2"+
"\2\u02ac\u02ad\7W\2\2\u02ad\u02ae\7U\2\2\u02ae\u02af\7J\2\2\u02af\u0361"+
"\78\2\2\u02b0\u02b1\7R\2\2\u02b1\u02b2\7W\2\2\u02b2\u02b3\7U\2\2\u02b3"+
"\u02b4\7J\2\2\u02b4\u0361\79\2\2\u02b5\u02b6\7R\2\2\u02b6\u02b7\7W\2\2"+
"\u02b7\u02b8\7U\2\2\u02b8\u02b9\7J\2\2\u02b9\u0361\7:\2\2\u02ba\u02bb"+
"\7R\2\2\u02bb\u02bc\7W\2\2\u02bc\u02bd\7U\2\2\u02bd\u02be\7J\2\2\u02be"+
"\u0361\7;\2\2\u02bf\u02c0\7R\2\2\u02c0\u02c1\7W\2\2\u02c1\u02c2\7U\2\2"+
"\u02c2\u02c3\7J\2\2\u02c3\u02c4\7\63\2\2\u02c4\u0361\7\62\2\2\u02c5\u02c6"+
"\7R\2\2\u02c6\u02c7\7W\2\2\u02c7\u02c8\7U\2\2\u02c8\u02c9\7J\2\2\u02c9"+
"\u02ca\7\63\2\2\u02ca\u0361\7\63\2\2\u02cb\u02cc\7R\2\2\u02cc\u02cd\7"+
"W\2\2\u02cd\u02ce\7U\2\2\u02ce\u02cf\7J\2\2\u02cf\u02d0\7\63\2\2\u02d0"+
"\u0361\7\64\2\2\u02d1\u02d2\7R\2\2\u02d2\u02d3\7W\2\2\u02d3\u02d4\7U\2"+
"\2\u02d4\u02d5\7J\2\2\u02d5\u02d6\7\63\2\2\u02d6\u0361\7\65\2\2\u02d7"+
"\u02d8\7R\2\2\u02d8\u02d9\7W\2\2\u02d9\u02da\7U\2\2\u02da\u02db\7J\2\2"+
"\u02db\u02dc\7\63\2\2\u02dc\u0361\7\66\2\2\u02dd\u02de\7R\2\2\u02de\u02df"+
"\7W\2\2\u02df\u02e0\7U\2\2\u02e0\u02e1\7J\2\2\u02e1\u02e2\7\63\2\2\u02e2"+
"\u0361\7\67\2\2\u02e3\u02e4\7R\2\2\u02e4\u02e5\7W\2\2\u02e5\u02e6\7U\2"+
"\2\u02e6\u02e7\7J\2\2\u02e7\u02e8\7\63\2\2\u02e8\u0361\78\2\2\u02e9\u02ea"+
"\7R\2\2\u02ea\u02eb\7W\2\2\u02eb\u02ec\7U\2\2\u02ec\u02ed\7J\2\2\u02ed"+
"\u02ee\7\63\2\2\u02ee\u0361\79\2\2\u02ef\u02f0\7R\2\2\u02f0\u02f1\7W\2"+
"\2\u02f1\u02f2\7U\2\2\u02f2\u02f3\7J\2\2\u02f3\u02f4\7\63\2\2\u02f4\u0361"+
"\7:\2\2\u02f5\u02f6\7R\2\2\u02f6\u02f7\7W\2\2\u02f7\u02f8\7U\2\2\u02f8"+
"\u02f9\7J\2\2\u02f9\u02fa\7\63\2\2\u02fa\u0361\7;\2\2\u02fb\u02fc\7R\2"+
"\2\u02fc\u02fd\7W\2\2\u02fd\u02fe\7U\2\2\u02fe\u02ff\7J\2\2\u02ff\u0300"+
"\7\64\2\2\u0300\u0361\7\62\2\2\u0301\u0302\7R\2\2\u0302\u0303\7W\2\2\u0303"+
"\u0304\7U\2\2\u0304\u0305\7J\2\2\u0305\u0306\7\64\2\2\u0306\u0361\7\63"+
"\2\2\u0307\u0308\7R\2\2\u0308\u0309\7W\2\2\u0309\u030a\7U\2\2\u030a\u030b"+
"\7J\2\2\u030b\u030c\7\64\2\2\u030c\u0361\7\64\2\2\u030d\u030e\7R\2\2\u030e"+
"\u030f\7W\2\2\u030f\u0310\7U\2\2\u0310\u0311\7J\2\2\u0311\u0312\7\64\2"+
"\2\u0312\u0361\7\65\2\2\u0313\u0314\7R\2\2\u0314\u0315\7W\2\2\u0315\u0316"+
"\7U\2\2\u0316\u0317\7J\2\2\u0317\u0318\7\64\2\2\u0318\u0361\7\66\2\2\u0319"+
"\u031a\7R\2\2\u031a\u031b\7W\2\2\u031b\u031c\7U\2\2\u031c\u031d\7J\2\2"+
"\u031d\u031e\7\64\2\2\u031e\u0361\7\67\2\2\u031f\u0320\7R\2\2\u0320\u0321"+
"\7W\2\2\u0321\u0322\7U\2\2\u0322\u0323\7J\2\2\u0323\u0324\7\64\2\2\u0324"+
"\u0361\78\2\2\u0325\u0326\7R\2\2\u0326\u0327\7W\2\2\u0327\u0328\7U\2\2"+
"\u0328\u0329\7J\2\2\u0329\u032a\7\64\2\2\u032a\u0361\79\2\2\u032b\u032c"+
"\7R\2\2\u032c\u032d\7W\2\2\u032d\u032e\7U\2\2\u032e\u032f\7J\2\2\u032f"+
"\u0330\7\64\2\2\u0330\u0361\7:\2\2\u0331\u0332\7R\2\2\u0332\u0333\7W\2"+
"\2\u0333\u0334\7U\2\2\u0334\u0335\7J\2\2\u0335\u0336\7\64\2\2\u0336\u0361"+
"\7;\2\2\u0337\u0338\7R\2\2\u0338\u0339\7W\2\2\u0339\u033a\7U\2\2\u033a"+
"\u033b\7J\2\2\u033b\u033c\7\65\2\2\u033c\u0361\7\62\2\2\u033d\u033e\7"+
"R\2\2\u033e\u033f\7W\2\2\u033f\u0340\7U\2\2\u0340\u0341\7J\2\2\u0341\u0342"+
"\7\65\2\2\u0342\u0361\7\63\2\2\u0343\u0344\7R\2\2\u0344\u0345\7W\2\2\u0345"+
"\u0346\7U\2\2\u0346\u0347\7J\2\2\u0347\u0348\7\65\2\2\u0348\u0361\7\64"+
"\2\2\u0349\u034a\7E\2\2\u034a\u034b\7T\2\2\u034b\u034c\7G\2\2\u034c\u034d"+
"\7C\2\2\u034d\u034e\7V\2\2\u034e\u0361\7G\2\2\u034f\u0350\7E\2\2\u0350"+
"\u0351\7C\2\2\u0351\u0352\7N\2\2\u0352\u0361\7N\2\2\u0353\u0354\7T\2\2"+
"\u0354\u0355\7G\2\2\u0355\u0356\7V\2\2\u0356\u0357\7W\2\2\u0357\u0358"+
"\7T\2\2\u0358\u0361\7P\2\2\u0359\u035a\7U\2\2\u035a\u035b\7W\2\2\u035b"+
"\u035c\7K\2\2\u035c\u035d\7E\2\2\u035d\u035e\7K\2\2\u035e\u035f\7F\2\2"+
"\u035f\u0361\7G\2\2\u0360\u0188\3\2\2\2\u0360\u018c\3\2\2\2\u0360\u018f"+
"\3\2\2\2\u0360\u0192\3\2\2\2\u0360\u0195\3\2\2\2\u0360\u0198\3\2\2\2\u0360"+
"\u019c\3\2\2\2\u0360\u019f\3\2\2\2\u0360\u01a3\3\2\2\2\u0360\u01a6\3\2"+
"\2\2\u0360\u01a9\3\2\2\2\u0360\u01ab\3\2\2\2\u0360\u01ad\3\2\2\2\u0360"+
"\u01b0\3\2\2\2\u0360\u01b3\3\2\2\2\u0360\u01b5\3\2\2\2\u0360\u01b8\3\2"+
"\2\2\u0360\u01bb\3\2\2\2\u0360\u01bd\3\2\2\2\u0360\u01c0\3\2\2\2\u0360"+
"\u01c4\3\2\2\2\u0360\u01c8\3\2\2\2\u0360\u01cf\3\2\2\2\u0360\u01d6\3\2"+
"\2\2\u0360\u01dc\3\2\2\2\u0360\u01e2\3\2\2\2\u0360\u01eb\3\2\2\2\u0360"+
"\u01f7\3\2\2\2\u0360\u0203\3\2\2\2\u0360\u020f\3\2\2\2\u0360\u0217\3\2"+
"\2\2\u0360\u021f\3\2\2\2\u0360\u0227\3\2\2\2\u0360\u022f\3\2\2\2\u0360"+
"\u0237\3\2\2\2\u0360\u0240\3\2\2\2\u0360\u0246\3\2\2\2\u0360\u0250\3\2"+
"\2\2\u0360\u0258\3\2\2\2\u0360\u025b\3\2\2\2\u0360\u025e\3\2\2\2\u0360"+
"\u0262\3\2\2\2\u0360\u0267\3\2\2\2\u0360\u026d\3\2\2\2\u0360\u0274\3\2"+
"\2\2\u0360\u0279\3\2\2\2\u0360\u027f\3\2\2\2\u0360\u0283\3\2\2\2\u0360"+
"\u0288\3\2\2\2\u0360\u028a\3\2\2\2\u0360\u028f\3\2\2\2\u0360\u0292\3\2"+
"\2\2\u0360\u0297\3\2\2\2\u0360\u029c\3\2\2\2\u0360\u02a1\3\2\2\2\u0360"+
"\u02a6\3\2\2\2\u0360\u02ab\3\2\2\2\u0360\u02b0\3\2\2\2\u0360\u02b5\3\2"+
"\2\2\u0360\u02ba\3\2\2\2\u0360\u02bf\3\2\2\2\u0360\u02c5\3\2\2\2\u0360"+
"\u02cb\3\2\2\2\u0360\u02d1\3\2\2\2\u0360\u02d7\3\2\2\2\u0360\u02dd\3\2"+
"\2\2\u0360\u02e3\3\2\2\2\u0360\u02e9\3\2\2\2\u0360\u02ef\3\2\2\2\u0360"+
"\u02f5\3\2\2\2\u0360\u02fb\3\2\2\2\u0360\u0301\3\2\2\2\u0360\u0307\3\2"+
"\2\2\u0360\u030d\3\2\2\2\u0360\u0313\3\2\2\2\u0360\u0319\3\2\2\2\u0360"+
"\u031f\3\2\2\2\u0360\u0325\3\2\2\2\u0360\u032b\3\2\2\2\u0360\u0331\3\2"+
"\2\2\u0360\u0337\3\2\2\2\u0360\u033d\3\2\2\2\u0360\u0343\3\2\2\2\u0360"+
"\u0349\3\2\2\2\u0360\u034f\3\2\2\2\u0360\u0353\3\2\2\2\u0360\u0359\3\2"+
"\2\2\u0361J\3\2\2\2\u0362\u0363\7z\2\2\u0363\u0364\7q\2\2\u0364\u0365"+
"\7t\2\2\u0365L\3\2\2\2\u0366\u0367\7(\2\2\u0367\u036c\7(\2\2\u0368\u0369"+
"\7c\2\2\u0369\u036a\7p\2\2\u036a\u036c\7f\2\2\u036b\u0366\3\2\2\2\u036b"+
"\u0368\3\2\2\2\u036cN\3\2\2\2\u036d\u036e\7~\2\2\u036e\u0372\7~\2\2\u036f"+
"\u0370\7q\2\2\u0370\u0372\7t\2\2\u0371\u036d\3\2\2\2\u0371\u036f\3\2\2"+
"\2\u0372P\3\2\2\2\u0373\u0378\7#\2\2\u0374\u0375\7p\2\2\u0375\u0376\7"+
"q\2\2\u0376\u0378\7v\2\2\u0377\u0373\3\2\2\2\u0377\u0374\3\2\2\2\u0378"+
"R\3\2\2\2\u0379\u037a\7?\2\2\u037aT\3\2\2\2\u037b\u037d\7\17\2\2\u037c"+
"\u037b\3\2\2\2\u037c\u037d\3\2\2\2\u037d\u037e\3\2\2\2\u037e\u0382\7\f"+
"\2\2\u037f\u0381\7\"\2\2\u0380\u037f\3\2\2\2\u0381\u0384\3\2\2\2\u0382"+
"\u0380\3\2\2\2\u0382\u0383\3\2\2\2\u0383V\3\2\2\2\u0384\u0382\3\2\2\2"+
"\u0385\u0387\t\3\2\2\u0386\u0385\3\2\2\2\u0387\u0388\3\2\2\2\u0388\u0386"+
"\3\2\2\2\u0388\u0389\3\2\2\2\u0389\u038a\3\2\2\2\u038a\u038b\b,\2\2\u038b"+
"X\3\2\2\2\u038c\u0390\7%\2\2\u038d\u038f\n\4\2\2\u038e\u038d\3\2\2\2\u038f"+
"\u0392\3\2\2\2\u0390\u038e\3\2\2\2\u0390\u0391\3\2\2\2\u0391\u0393\3\2"+
"\2\2\u0392\u0390\3\2\2\2\u0393\u0394\b-\3\2\u0394Z\3\2\2\2\u0395\u0399"+
"\t\5\2\2\u0396\u0398\t\6\2\2\u0397\u0396\3\2\2\2\u0398\u039b\3\2\2\2\u0399"+
"\u0397\3\2\2\2\u0399\u039a\3\2\2\2\u039a\\\3\2\2\2\u039b\u0399\3\2\2\2"+
"\u039c\u039d\t\7\2\2\u039d^\3\2\2\2\u039e\u039f\t\b\2\2\u039f`\3\2\2\2"+
"\u03a0\u03a6\t\t\2\2\u03a1\u03a2\7>\2\2\u03a2\u03a6\7?\2\2\u03a3\u03a4"+
"\7@\2\2\u03a4\u03a6\7?\2\2\u03a5\u03a0\3\2\2\2\u03a5\u03a1\3\2\2\2\u03a5"+
"\u03a3\3\2\2\2\u03a6b\3\2\2\2\u03a7\u03a8\7?\2\2\u03a8\u03ac\7?\2\2\u03a9"+
"\u03aa\7#\2\2\u03aa\u03ac\7?\2\2\u03ab\u03a7\3\2\2\2\u03ab\u03a9\3\2\2"+
"\2\u03acd\3\2\2\2\u03ad\u03ae\7(\2\2\u03aef\3\2\2\2\u03af\u03b0\7~\2\2"+
"\u03b0h\3\2\2\2\u03b1\u03b2\t\n\2\2\u03b2j\3\2\2\2\u03b3\u03b4\7\62\2"+
"\2\u03b4\u03b8\7z\2\2\u03b5\u03b6\7\62\2\2\u03b6\u03b8\7Z\2\2\u03b7\u03b3"+
"\3\2\2\2\u03b7\u03b5\3\2\2\2\u03b8\u03ba\3\2\2\2\u03b9\u03bb\5i\65\2\u03ba"+
"\u03b9\3\2\2\2\u03bb\u03bc\3\2\2\2\u03bc\u03ba\3\2\2\2\u03bc\u03bd\3\2"+
"\2\2\u03bdl\3\2\2\2\21\2\u0186\u0360\u036b\u0371\u0377\u037c\u0382\u0388"+
"\u0390\u0399\u03a5\u03ab\u03b7\u03bc";
"\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\5%\u0363\n%\3&\3&\3&\3&\3\'"+
"\3\'\3\'\3\'\3\'\5\'\u036e\n\'\3(\3(\3(\3(\5(\u0374\n(\3)\3)\3)\3)\5)"+
"\u037a\n)\3*\3*\3+\5+\u037f\n+\3+\3+\7+\u0383\n+\f+\16+\u0386\13+\3,\6"+
",\u0389\n,\r,\16,\u038a\3,\3,\3-\3-\7-\u0391\n-\f-\16-\u0394\13-\3-\3"+
"-\3.\3.\7.\u039a\n.\f.\16.\u039d\13.\3/\3/\3\60\3\60\3\61\3\61\3\61\3"+
"\61\3\61\5\61\u03a8\n\61\3\62\3\62\3\62\3\62\5\62\u03ae\n\62\3\63\3\63"+
"\3\64\3\64\3\65\3\65\3\66\3\66\3\66\3\66\5\66\u03ba\n\66\3\66\6\66\u03bd"+
"\n\66\r\66\16\66\u03be\2\67\3\3\1\5\4\1\7\5\1\t\6\1\13\7\1\r\b\1\17\t"+
"\1\21\n\1\23\13\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20\1\37\21\1!\22\1"+
"#\23\1%\24\1\'\25\1)\26\1+\27\1-\30\1/\31\1\61\32\1\63\33\1\65\34\1\67"+
"\35\19\36\1;\37\1= \1?!\1A\"\1C#\1E$\1G%\1I&\1K\'\1M(\1O)\1Q*\1S+\1U,"+
"\1W-\2Y.\3[/\1]\60\1_\61\1a\62\1c\63\1e\64\1g\65\1i\66\1k\67\1\3\2\13"+
"\3\2\62;\4\2\13\13\"\"\4\2\f\f\17\17\4\2C\\c|\5\2\62;C\\c|\4\2--//\6\2"+
"\'\',,\61\61``\4\2>>@@\5\2\62;CHch\u0423\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3"+
"\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2"+
"\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35"+
"\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)"+
"\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2"+
"\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2"+
"A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3"+
"\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2"+
"\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2"+
"g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\3m\3\2\2\2\5o\3\2\2\2\7t\3\2\2\2\t\u0083"+
"\3\2\2\2\13\u0085\3\2\2\2\r\u0089\3\2\2\2\17\u0090\3\2\2\2\21\u0096\3"+
"\2\2\2\23\u0098\3\2\2\2\25\u009a\3\2\2\2\27\u009c\3\2\2\2\31\u009f\3\2"+
"\2\2\33\u00a4\3\2\2\2\35\u00b4\3\2\2\2\37\u00b9\3\2\2\2!\u00c3\3\2\2\2"+
"#\u00c8\3\2\2\2%\u00d7\3\2\2\2\'\u00e8\3\2\2\2)\u00f0\3\2\2\2+\u0101\3"+
"\2\2\2-\u010e\3\2\2\2/\u0110\3\2\2\2\61\u011c\3\2\2\2\63\u0122\3\2\2\2"+
"\65\u012c\3\2\2\2\67\u0135\3\2\2\29\u013a\3\2\2\2;\u0141\3\2\2\2=\u014c"+
"\3\2\2\2?\u015d\3\2\2\2A\u0162\3\2\2\2C\u0171\3\2\2\2E\u017e\3\2\2\2G"+
"\u0184\3\2\2\2I\u0362\3\2\2\2K\u0364\3\2\2\2M\u036d\3\2\2\2O\u0373\3\2"+
"\2\2Q\u0379\3\2\2\2S\u037b\3\2\2\2U\u037e\3\2\2\2W\u0388\3\2\2\2Y\u038e"+
"\3\2\2\2[\u0397\3\2\2\2]\u039e\3\2\2\2_\u03a0\3\2\2\2a\u03a7\3\2\2\2c"+
"\u03ad\3\2\2\2e\u03af\3\2\2\2g\u03b1\3\2\2\2i\u03b3\3\2\2\2k\u03b9\3\2"+
"\2\2mn\7_\2\2n\4\3\2\2\2op\7u\2\2pq\7v\2\2qr\7q\2\2rs\7r\2\2s\6\3\2\2"+
"\2tu\7d\2\2uv\7n\2\2vw\7q\2\2wx\7e\2\2xy\7m\2\2yz\7\60\2\2z{\7e\2\2{|"+
"\7q\2\2|}\7k\2\2}~\7p\2\2~\177\7d\2\2\177\u0080\7c\2\2\u0080\u0081\7u"+
"\2\2\u0081\u0082\7g\2\2\u0082\b\3\2\2\2\u0083\u0084\7.\2\2\u0084\n\3\2"+
"\2\2\u0085\u0086\7o\2\2\u0086\u0087\7u\2\2\u0087\u0088\7i\2\2\u0088\f"+
"\3\2\2\2\u0089\u008a\7v\2\2\u008a\u008b\7z\2\2\u008b\u008c\7\60\2\2\u008c"+
"\u008d\7i\2\2\u008d\u008e\7c\2\2\u008e\u008f\7u\2\2\u008f\16\3\2\2\2\u0090"+
"\u0091\7y\2\2\u0091\u0092\7j\2\2\u0092\u0093\7k\2\2\u0093\u0094\7n\2\2"+
"\u0094\u0095\7g\2\2\u0095\20\3\2\2\2\u0096\u0097\7]\2\2\u0097\22\3\2\2"+
"\2\u0098\u0099\7*\2\2\u0099\24\3\2\2\2\u009a\u009b\7<\2\2\u009b\26\3\2"+
"\2\2\u009c\u009d\7k\2\2\u009d\u009e\7h\2\2\u009e\30\3\2\2\2\u009f\u00a0"+
"\7u\2\2\u00a0\u00a1\7g\2\2\u00a1\u00a2\7p\2\2\u00a2\u00a3\7f\2\2\u00a3"+
"\32\3\2\2\2\u00a4\u00a5\7d\2\2\u00a5\u00a6\7n\2\2\u00a6\u00a7\7q\2\2\u00a7"+
"\u00a8\7e\2\2\u00a8\u00a9\7m\2\2\u00a9\u00aa\7\60\2\2\u00aa\u00ab\7v\2"+
"\2\u00ab\u00ac\7k\2\2\u00ac\u00ad\7o\2\2\u00ad\u00ae\7g\2\2\u00ae\u00af"+
"\7u\2\2\u00af\u00b0\7v\2\2\u00b0\u00b1\7c\2\2\u00b1\u00b2\7o\2\2\u00b2"+
"\u00b3\7r\2\2\u00b3\34\3\2\2\2\u00b4\u00b5\7]\2\2\u00b5\u00b6\7c\2\2\u00b6"+
"\u00b7\7u\2\2\u00b7\u00b8\7o\2\2\u00b8\36\3\2\2\2\u00b9\u00ba\7o\2\2\u00ba"+
"\u00bb\7u\2\2\u00bb\u00bc\7i\2\2\u00bc\u00bd\7\60\2\2\u00bd\u00be\7x\2"+
"\2\u00be\u00bf\7c\2\2\u00bf\u00c0\7n\2\2\u00c0\u00c1\7w\2\2\u00c1\u00c2"+
"\7g\2\2\u00c2 \3\2\2\2\u00c3\u00c4\7k\2\2\u00c4\u00c5\7p\2\2\u00c5\u00c6"+
"\7k\2\2\u00c6\u00c7\7v\2\2\u00c7\"\3\2\2\2\u00c8\u00c9\7d\2\2\u00c9\u00ca"+
"\7n\2\2\u00ca\u00cb\7q\2\2\u00cb\u00cc\7e\2\2\u00cc\u00cd\7m\2\2\u00cd"+
"\u00ce\7\60\2\2\u00ce\u00cf\7r\2\2\u00cf\u00d0\7t\2\2\u00d0\u00d1\7g\2"+
"\2\u00d1\u00d2\7x\2\2\u00d2\u00d3\7j\2\2\u00d3\u00d4\7c\2\2\u00d4\u00d5"+
"\7u\2\2\u00d5\u00d6\7j\2\2\u00d6$\3\2\2\2\u00d7\u00d8\7e\2\2\u00d8\u00d9"+
"\7q\2\2\u00d9\u00da\7p\2\2\u00da\u00db\7v\2\2\u00db\u00dc\7t\2\2\u00dc"+
"\u00dd\7c\2\2\u00dd\u00de\7e\2\2\u00de\u00df\7v\2\2\u00df\u00e0\7\60\2"+
"\2\u00e0\u00e1\7u\2\2\u00e1\u00e2\7v\2\2\u00e2\u00e3\7q\2\2\u00e3\u00e4"+
"\7t\2\2\u00e4\u00e5\7c\2\2\u00e5\u00e6\7i\2\2\u00e6\u00e7\7g\2\2\u00e7"+
"&\3\2\2\2\u00e8\u00e9\7u\2\2\u00e9\u00ea\7w\2\2\u00ea\u00eb\7k\2\2\u00eb"+
"\u00ec\7e\2\2\u00ec\u00ed\7k\2\2\u00ed\u00ee\7f\2\2\u00ee\u00ef\7g\2\2"+
"\u00ef(\3\2\2\2\u00f0\u00f1\7d\2\2\u00f1\u00f2\7n\2\2\u00f2\u00f3\7q\2"+
"\2\u00f3\u00f4\7e\2\2\u00f4\u00f5\7m\2\2\u00f5\u00f6\7\60\2\2\u00f6\u00f7"+
"\7f\2\2\u00f7\u00f8\7k\2\2\u00f8\u00f9\7h\2\2\u00f9\u00fa\7h\2\2\u00fa"+
"\u00fb\7k\2\2\u00fb\u00fc\7e\2\2\u00fc\u00fd\7w\2\2\u00fd\u00fe\7n\2\2"+
"\u00fe\u00ff\7v\2\2\u00ff\u0100\7{\2\2\u0100*\3\2\2\2\u0101\u0102\7o\2"+
"\2\u0102\u0103\7u\2\2\u0103\u0104\7i\2\2\u0104\u0105\7\60\2\2\u0105\u0106"+
"\7f\2\2\u0106\u0107\7c\2\2\u0107\u0108\7v\2\2\u0108\u0109\7c\2\2\u0109"+
"\u010a\7u\2\2\u010a\u010b\7k\2\2\u010b\u010c\7|\2\2\u010c\u010d\7g\2\2"+
"\u010d,\3\2\2\2\u010e\u010f\7+\2\2\u010f.\3\2\2\2\u0110\u0111\7v\2\2\u0111"+
"\u0112\7z\2\2\u0112\u0113\7\60\2\2\u0113\u0114\7i\2\2\u0114\u0115\7c\2"+
"\2\u0115\u0116\7u\2\2\u0116\u0117\7r\2\2\u0117\u0118\7t\2\2\u0118\u0119"+
"\7k\2\2\u0119\u011a\7e\2\2\u011a\u011b\7g\2\2\u011b\60\3\2\2\2\u011c\u011d"+
"\7g\2\2\u011d\u011e\7n\2\2\u011e\u011f\7u\2\2\u011f\u0120\7g\2\2\u0120"+
"\u0121\7<\2\2\u0121\62\3\2\2\2\u0122\u0123\7v\2\2\u0123\u0124\7z\2\2\u0124"+
"\u0125\7\60\2\2\u0125\u0126\7q\2\2\u0126\u0127\7t\2\2\u0127\u0128\7k\2"+
"\2\u0128\u0129\7i\2\2\u0129\u012a\7k\2\2\u012a\u012b\7p\2\2\u012b\64\3"+
"\2\2\2\u012c\u012d\7o\2\2\u012d\u012e\7u\2\2\u012e\u012f\7i\2\2\u012f"+
"\u0130\7\60\2\2\u0130\u0131\7f\2\2\u0131\u0132\7c\2\2\u0132\u0133\7v\2"+
"\2\u0133\u0134\7c\2\2\u0134\66\3\2\2\2\u0135\u0136\7g\2\2\u0136\u0137"+
"\7n\2\2\u0137\u0138\7k\2\2\u0138\u0139\7h\2\2\u01398\3\2\2\2\u013a\u013b"+
"\7t\2\2\u013b\u013c\7g\2\2\u013c\u013d\7v\2\2\u013d\u013e\7w\2\2\u013e"+
"\u013f\7t\2\2\u013f\u0140\7p\2\2\u0140:\3\2\2\2\u0141\u0142\7o\2\2\u0142"+
"\u0143\7u\2\2\u0143\u0144\7i\2\2\u0144\u0145\7\60\2\2\u0145\u0146\7u\2"+
"\2\u0146\u0147\7g\2\2\u0147\u0148\7p\2\2\u0148\u0149\7f\2\2\u0149\u014a"+
"\7g\2\2\u014a\u014b\7t\2\2\u014b<\3\2\2\2\u014c\u014d\7e\2\2\u014d\u014e"+
"\7q\2\2\u014e\u014f\7p\2\2\u014f\u0150\7v\2\2\u0150\u0151\7t\2\2\u0151"+
"\u0152\7c\2\2\u0152\u0153\7e\2\2\u0153\u0154\7v\2\2\u0154\u0155\7\60\2"+
"\2\u0155\u0156\7d\2\2\u0156\u0157\7c\2\2\u0157\u0158\7n\2\2\u0158\u0159"+
"\7c\2\2\u0159\u015a\7p\2\2\u015a\u015b\7e\2\2\u015b\u015c\7g\2\2\u015c"+
">\3\2\2\2\u015d\u015e\7c\2\2\u015e\u015f\7u\2\2\u015f\u0160\7o\2\2\u0160"+
"\u0161\7_\2\2\u0161@\3\2\2\2\u0162\u0163\7d\2\2\u0163\u0164\7n\2\2\u0164"+
"\u0165\7q\2\2\u0165\u0166\7e\2\2\u0166\u0167\7m\2\2\u0167\u0168\7\60\2"+
"\2\u0168\u0169\7i\2\2\u0169\u016a\7c\2\2\u016a\u016b\7u\2\2\u016b\u016c"+
"\7n\2\2\u016c\u016d\7k\2\2\u016d\u016e\7o\2\2\u016e\u016f\7k\2\2\u016f"+
"\u0170\7v\2\2\u0170B\3\2\2\2\u0171\u0172\7d\2\2\u0172\u0173\7n\2\2\u0173"+
"\u0174\7q\2\2\u0174\u0175\7e\2\2\u0175\u0176\7m\2\2\u0176\u0177\7\60\2"+
"\2\u0177\u0178\7p\2\2\u0178\u0179\7w\2\2\u0179\u017a\7o\2\2\u017a\u017b"+
"\7d\2\2\u017b\u017c\7g\2\2\u017c\u017d\7t\2\2\u017dD\3\2\2\2\u017e\u017f"+
"\7e\2\2\u017f\u0180\7q\2\2\u0180\u0181\7f\2\2\u0181\u0182\7g\2\2\u0182"+
"F\3\2\2\2\u0183\u0185\t\2\2\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2"+
"\u0186\u0184\3\2\2\2\u0186\u0187\3\2\2\2\u0187H\3\2\2\2\u0188\u0189\7"+
"U\2\2\u0189\u018a\7V\2\2\u018a\u018b\7Q\2\2\u018b\u0363\7R\2\2\u018c\u018d"+
"\7C\2\2\u018d\u018e\7F\2\2\u018e\u0363\7F\2\2\u018f\u0190\7O\2\2\u0190"+
"\u0191\7W\2\2\u0191\u0363\7N\2\2\u0192\u0193\7U\2\2\u0193\u0194\7W\2\2"+
"\u0194\u0363\7D\2\2\u0195\u0196\7F\2\2\u0196\u0197\7K\2\2\u0197\u0363"+
"\7X\2\2\u0198\u0199\7U\2\2\u0199\u019a\7F\2\2\u019a\u019b\7K\2\2\u019b"+
"\u0363\7X\2\2\u019c\u019d\7O\2\2\u019d\u019e\7Q\2\2\u019e\u0363\7F\2\2"+
"\u019f\u01a0\7U\2\2\u01a0\u01a1\7O\2\2\u01a1\u01a2\7Q\2\2\u01a2\u0363"+
"\7F\2\2\u01a3\u01a4\7G\2\2\u01a4\u01a5\7Z\2\2\u01a5\u0363\7R\2\2\u01a6"+
"\u01a7\7P\2\2\u01a7\u01a8\7G\2\2\u01a8\u0363\7I\2\2\u01a9\u01aa\7N\2\2"+
"\u01aa\u0363\7V\2\2\u01ab\u01ac\7I\2\2\u01ac\u0363\7V\2\2\u01ad\u01ae"+
"\7U\2\2\u01ae\u01af\7N\2\2\u01af\u0363\7V\2\2\u01b0\u01b1\7U\2\2\u01b1"+
"\u01b2\7I\2\2\u01b2\u0363\7V\2\2\u01b3\u01b4\7G\2\2\u01b4\u0363\7S\2\2"+
"\u01b5\u01b6\7P\2\2\u01b6\u01b7\7Q\2\2\u01b7\u0363\7V\2\2\u01b8\u01b9"+
"\7C\2\2\u01b9\u01ba\7P\2\2\u01ba\u0363\7F\2\2\u01bb\u01bc\7Q\2\2\u01bc"+
"\u0363\7T\2\2\u01bd\u01be\7Z\2\2\u01be\u01bf\7Q\2\2\u01bf\u0363\7T\2\2"+
"\u01c0\u01c1\7D\2\2\u01c1\u01c2\7[\2\2\u01c2\u01c3\7V\2\2\u01c3\u0363"+
"\7G\2\2\u01c4\u01c5\7U\2\2\u01c5\u01c6\7J\2\2\u01c6\u01c7\7C\2\2\u01c7"+
"\u0363\7\65\2\2\u01c8\u01c9\7C\2\2\u01c9\u01ca\7F\2\2\u01ca\u01cb\7F\2"+
"\2\u01cb\u01cc\7T\2\2\u01cc\u01cd\7G\2\2\u01cd\u01ce\7U\2\2\u01ce\u0363"+
"\7U\2\2\u01cf\u01d0\7D\2\2\u01d0\u01d1\7C\2\2\u01d1\u01d2\7N\2\2\u01d2"+
"\u01d3\7C\2\2\u01d3\u01d4\7P\2\2\u01d4\u01d5\7E\2\2\u01d5\u0363\7G\2\2"+
"\u01d6\u01d7\7Q\2\2\u01d7\u01d8\7T\2\2\u01d8\u01d9\7K\2\2\u01d9\u01da"+
"\7I\2\2\u01da\u01db\7K\2\2\u01db\u0363\7P\2\2\u01dc\u01dd\7E\2\2\u01dd"+
"\u01de\7C\2\2\u01de\u01df\7N\2\2\u01df\u01e0\7N\2\2\u01e0\u01e1\7G\2\2"+
"\u01e1\u0363\7T\2\2\u01e2\u01e3\7E\2\2\u01e3\u01e4\7C\2\2\u01e4\u01e5"+
"\7N\2\2\u01e5\u01e6\7N\2\2\u01e6\u01e7\7X\2\2\u01e7\u01e8\7C\2\2\u01e8"+
"\u01e9\7N\2\2\u01e9\u01ea\7W\2\2\u01ea\u0363\7G\2\2\u01eb\u01ec\7E\2\2"+
"\u01ec\u01ed\7C\2\2\u01ed\u01ee\7N\2\2\u01ee\u01ef\7N\2\2\u01ef\u01f0"+
"\7F\2\2\u01f0\u01f1\7C\2\2\u01f1\u01f2\7V\2\2\u01f2\u01f3\7C\2\2\u01f3"+
"\u01f4\7N\2\2\u01f4\u01f5\7Q\2\2\u01f5\u01f6\7C\2\2\u01f6\u0363\7F\2\2"+
"\u01f7\u01f8\7E\2\2\u01f8\u01f9\7C\2\2\u01f9\u01fa\7N\2\2\u01fa\u01fb"+
"\7N\2\2\u01fb\u01fc\7F\2\2\u01fc\u01fd\7C\2\2\u01fd\u01fe\7V\2\2\u01fe"+
"\u01ff\7C\2\2\u01ff\u0200\7U\2\2\u0200\u0201\7K\2\2\u0201\u0202\7\\\2"+
"\2\u0202\u0363\7G\2\2\u0203\u0204\7E\2\2\u0204\u0205\7C\2\2\u0205\u0206"+
"\7N\2\2\u0206\u0207\7N\2\2\u0207\u0208\7F\2\2\u0208\u0209\7C\2\2\u0209"+
"\u020a\7V\2\2\u020a\u020b\7C\2\2\u020b\u020c\7E\2\2\u020c\u020d\7Q\2\2"+
"\u020d\u020e\7R\2\2\u020e\u0363\7[\2\2\u020f\u0210\7E\2\2\u0210\u0211"+
"\7Q\2\2\u0211\u0212\7F\2\2\u0212\u0213\7G\2\2\u0213\u0214\7U\2\2\u0214"+
"\u0215\7K\2\2\u0215\u0216\7\\\2\2\u0216\u0363\7G\2\2\u0217\u0218\7E\2"+
"\2\u0218\u0219\7Q\2\2\u0219\u021a\7F\2\2\u021a\u021b\7G\2\2\u021b\u021c"+
"\7E\2\2\u021c\u021d\7Q\2\2\u021d\u021e\7R\2\2\u021e\u0363\7[\2\2\u021f"+
"\u0220\7I\2\2\u0220\u0221\7C\2\2\u0221\u0222\7U\2\2\u0222\u0223\7R\2\2"+
"\u0223\u0224\7T\2\2\u0224\u0225\7K\2\2\u0225\u0226\7E\2\2\u0226\u0363"+
"\7G\2\2\u0227\u0228\7R\2\2\u0228\u0229\7T\2\2\u0229\u022a\7G\2\2\u022a"+
"\u022b\7X\2\2\u022b\u022c\7J\2\2\u022c\u022d\7C\2\2\u022d\u022e\7U\2\2"+
"\u022e\u0363\7J\2\2\u022f\u0230\7E\2\2\u0230\u0231\7Q\2\2\u0231\u0232"+
"\7K\2\2\u0232\u0233\7P\2\2\u0233\u0234\7D\2\2\u0234\u0235\7C\2\2\u0235"+
"\u0236\7U\2\2\u0236\u0363\7G\2\2\u0237\u0238\7V\2\2\u0238\u0239\7K\2\2"+
"\u0239\u023a\7O\2\2\u023a\u023b\7G\2\2\u023b\u023c\7U\2\2\u023c\u023d"+
"\7V\2\2\u023d\u023e\7C\2\2\u023e\u023f\7O\2\2\u023f\u0363\7R\2\2\u0240"+
"\u0241\7P\2\2\u0241\u0242\7W\2\2\u0242\u0243\7O\2\2\u0243\u0244\7D\2\2"+
"\u0244\u0245\7G\2\2\u0245\u0363\7T\2\2\u0246\u0247\7F\2\2\u0247\u0248"+
"\7K\2\2\u0248\u0249\7H\2\2\u0249\u024a\7H\2\2\u024a\u024b\7K\2\2\u024b"+
"\u024c\7E\2\2\u024c\u024d\7W\2\2\u024d\u024e\7N\2\2\u024e\u024f\7V\2\2"+
"\u024f\u0363\7[\2\2\u0250\u0251\7I\2\2\u0251\u0252\7C\2\2\u0252\u0253"+
"\7U\2\2\u0253\u0254\7N\2\2\u0254\u0255\7K\2\2\u0255\u0256\7O\2\2\u0256"+
"\u0257\7K\2\2\u0257\u0363\7V\2\2\u0258\u0259\7R\2\2\u0259\u025a\7Q\2\2"+
"\u025a\u0363\7R\2\2\u025b\u025c\7F\2\2\u025c\u025d\7W\2\2\u025d\u0363"+
"\7R\2\2\u025e\u025f\7U\2\2\u025f\u0260\7Y\2\2\u0260\u0261\7C\2\2\u0261"+
"\u0363\7R\2\2\u0262\u0263\7O\2\2\u0263\u0264\7N\2\2\u0264\u0265\7Q\2\2"+
"\u0265\u0266\7C\2\2\u0266\u0363\7F\2\2\u0267\u0268\7O\2\2\u0268\u0269"+
"\7U\2\2\u0269\u026a\7V\2\2\u026a\u026b\7Q\2\2\u026b\u026c\7T\2\2\u026c"+
"\u0363\7G\2\2\u026d\u026e\7O\2\2\u026e\u026f\7U\2\2\u026f\u0270\7V\2\2"+
"\u0270\u0271\7Q\2\2\u0271\u0272\7T\2\2\u0272\u0273\7G\2\2\u0273\u0363"+
"\7:\2\2\u0274\u0275\7U\2\2\u0275\u0276\7N\2\2\u0276\u0277\7Q\2\2\u0277"+
"\u0278\7C\2\2\u0278\u0363\7F\2\2\u0279\u027a\7U\2\2\u027a\u027b\7U\2\2"+
"\u027b\u027c\7V\2\2\u027c\u027d\7Q\2\2\u027d\u027e\7T\2\2\u027e\u0363"+
"\7G\2\2\u027f\u0280\7L\2\2\u0280\u0281\7W\2\2\u0281\u0282\7O\2\2\u0282"+
"\u0363\7R\2\2\u0283\u0284\7L\2\2\u0284\u0285\7W\2\2\u0285\u0286\7O\2\2"+
"\u0286\u0287\7R\2\2\u0287\u0363\7K\2\2\u0288\u0289\7R\2\2\u0289\u0363"+
"\7E\2\2\u028a\u028b\7O\2\2\u028b\u028c\7G\2\2\u028c\u028d\7O\2\2\u028d"+
"\u028e\7U\2\2\u028e\u028f\7K\2\2\u028f\u0290\7\\\2\2\u0290\u0363\7G\2"+
"\2\u0291\u0292\7I\2\2\u0292\u0293\7C\2\2\u0293\u0363\7U\2\2\u0294\u0295"+
"\7R\2\2\u0295\u0296\7W\2\2\u0296\u0297\7U\2\2\u0297\u0298\7J\2\2\u0298"+
"\u0363\7\63\2\2\u0299\u029a\7R\2\2\u029a\u029b\7W\2\2\u029b\u029c\7U\2"+
"\2\u029c\u029d\7J\2\2\u029d\u0363\7\64\2\2\u029e\u029f\7R\2\2\u029f\u02a0"+
"\7W\2\2\u02a0\u02a1\7U\2\2\u02a1\u02a2\7J\2\2\u02a2\u0363\7\65\2\2\u02a3"+
"\u02a4\7R\2\2\u02a4\u02a5\7W\2\2\u02a5\u02a6\7U\2\2\u02a6\u02a7\7J\2\2"+
"\u02a7\u0363\7\66\2\2\u02a8\u02a9\7R\2\2\u02a9\u02aa\7W\2\2\u02aa\u02ab"+
"\7U\2\2\u02ab\u02ac\7J\2\2\u02ac\u0363\7\67\2\2\u02ad\u02ae\7R\2\2\u02ae"+
"\u02af\7W\2\2\u02af\u02b0\7U\2\2\u02b0\u02b1\7J\2\2\u02b1\u0363\78\2\2"+
"\u02b2\u02b3\7R\2\2\u02b3\u02b4\7W\2\2\u02b4\u02b5\7U\2\2\u02b5\u02b6"+
"\7J\2\2\u02b6\u0363\79\2\2\u02b7\u02b8\7R\2\2\u02b8\u02b9\7W\2\2\u02b9"+
"\u02ba\7U\2\2\u02ba\u02bb\7J\2\2\u02bb\u0363\7:\2\2\u02bc\u02bd\7R\2\2"+
"\u02bd\u02be\7W\2\2\u02be\u02bf\7U\2\2\u02bf\u02c0\7J\2\2\u02c0\u0363"+
"\7;\2\2\u02c1\u02c2\7R\2\2\u02c2\u02c3\7W\2\2\u02c3\u02c4\7U\2\2\u02c4"+
"\u02c5\7J\2\2\u02c5\u02c6\7\63\2\2\u02c6\u0363\7\62\2\2\u02c7\u02c8\7"+
"R\2\2\u02c8\u02c9\7W\2\2\u02c9\u02ca\7U\2\2\u02ca\u02cb\7J\2\2\u02cb\u02cc"+
"\7\63\2\2\u02cc\u0363\7\63\2\2\u02cd\u02ce\7R\2\2\u02ce\u02cf\7W\2\2\u02cf"+
"\u02d0\7U\2\2\u02d0\u02d1\7J\2\2\u02d1\u02d2\7\63\2\2\u02d2\u0363\7\64"+
"\2\2\u02d3\u02d4\7R\2\2\u02d4\u02d5\7W\2\2\u02d5\u02d6\7U\2\2\u02d6\u02d7"+
"\7J\2\2\u02d7\u02d8\7\63\2\2\u02d8\u0363\7\65\2\2\u02d9\u02da\7R\2\2\u02da"+
"\u02db\7W\2\2\u02db\u02dc\7U\2\2\u02dc\u02dd\7J\2\2\u02dd\u02de\7\63\2"+
"\2\u02de\u0363\7\66\2\2\u02df\u02e0\7R\2\2\u02e0\u02e1\7W\2\2\u02e1\u02e2"+
"\7U\2\2\u02e2\u02e3\7J\2\2\u02e3\u02e4\7\63\2\2\u02e4\u0363\7\67\2\2\u02e5"+
"\u02e6\7R\2\2\u02e6\u02e7\7W\2\2\u02e7\u02e8\7U\2\2\u02e8\u02e9\7J\2\2"+
"\u02e9\u02ea\7\63\2\2\u02ea\u0363\78\2\2\u02eb\u02ec\7R\2\2\u02ec\u02ed"+
"\7W\2\2\u02ed\u02ee\7U\2\2\u02ee\u02ef\7J\2\2\u02ef\u02f0\7\63\2\2\u02f0"+
"\u0363\79\2\2\u02f1\u02f2\7R\2\2\u02f2\u02f3\7W\2\2\u02f3\u02f4\7U\2\2"+
"\u02f4\u02f5\7J\2\2\u02f5\u02f6\7\63\2\2\u02f6\u0363\7:\2\2\u02f7\u02f8"+
"\7R\2\2\u02f8\u02f9\7W\2\2\u02f9\u02fa\7U\2\2\u02fa\u02fb\7J\2\2\u02fb"+
"\u02fc\7\63\2\2\u02fc\u0363\7;\2\2\u02fd\u02fe\7R\2\2\u02fe\u02ff\7W\2"+
"\2\u02ff\u0300\7U\2\2\u0300\u0301\7J\2\2\u0301\u0302\7\64\2\2\u0302\u0363"+
"\7\62\2\2\u0303\u0304\7R\2\2\u0304\u0305\7W\2\2\u0305\u0306\7U\2\2\u0306"+
"\u0307\7J\2\2\u0307\u0308\7\64\2\2\u0308\u0363\7\63\2\2\u0309\u030a\7"+
"R\2\2\u030a\u030b\7W\2\2\u030b\u030c\7U\2\2\u030c\u030d\7J\2\2\u030d\u030e"+
"\7\64\2\2\u030e\u0363\7\64\2\2\u030f\u0310\7R\2\2\u0310\u0311\7W\2\2\u0311"+
"\u0312\7U\2\2\u0312\u0313\7J\2\2\u0313\u0314\7\64\2\2\u0314\u0363\7\65"+
"\2\2\u0315\u0316\7R\2\2\u0316\u0317\7W\2\2\u0317\u0318\7U\2\2\u0318\u0319"+
"\7J\2\2\u0319\u031a\7\64\2\2\u031a\u0363\7\66\2\2\u031b\u031c\7R\2\2\u031c"+
"\u031d\7W\2\2\u031d\u031e\7U\2\2\u031e\u031f\7J\2\2\u031f\u0320\7\64\2"+
"\2\u0320\u0363\7\67\2\2\u0321\u0322\7R\2\2\u0322\u0323\7W\2\2\u0323\u0324"+
"\7U\2\2\u0324\u0325\7J\2\2\u0325\u0326\7\64\2\2\u0326\u0363\78\2\2\u0327"+
"\u0328\7R\2\2\u0328\u0329\7W\2\2\u0329\u032a\7U\2\2\u032a\u032b\7J\2\2"+
"\u032b\u032c\7\64\2\2\u032c\u0363\79\2\2\u032d\u032e\7R\2\2\u032e\u032f"+
"\7W\2\2\u032f\u0330\7U\2\2\u0330\u0331\7J\2\2\u0331\u0332\7\64\2\2\u0332"+
"\u0363\7:\2\2\u0333\u0334\7R\2\2\u0334\u0335\7W\2\2\u0335\u0336\7U\2\2"+
"\u0336\u0337\7J\2\2\u0337\u0338\7\64\2\2\u0338\u0363\7;\2\2\u0339\u033a"+
"\7R\2\2\u033a\u033b\7W\2\2\u033b\u033c\7U\2\2\u033c\u033d\7J\2\2\u033d"+
"\u033e\7\65\2\2\u033e\u0363\7\62\2\2\u033f\u0340\7R\2\2\u0340\u0341\7"+
"W\2\2\u0341\u0342\7U\2\2\u0342\u0343\7J\2\2\u0343\u0344\7\65\2\2\u0344"+
"\u0363\7\63\2\2\u0345\u0346\7R\2\2\u0346\u0347\7W\2\2\u0347\u0348\7U\2"+
"\2\u0348\u0349\7J\2\2\u0349\u034a\7\65\2\2\u034a\u0363\7\64\2\2\u034b"+
"\u034c\7E\2\2\u034c\u034d\7T\2\2\u034d\u034e\7G\2\2\u034e\u034f\7C\2\2"+
"\u034f\u0350\7V\2\2\u0350\u0363\7G\2\2\u0351\u0352\7E\2\2\u0352\u0353"+
"\7C\2\2\u0353\u0354\7N\2\2\u0354\u0363\7N\2\2\u0355\u0356\7T\2\2\u0356"+
"\u0357\7G\2\2\u0357\u0358\7V\2\2\u0358\u0359\7W\2\2\u0359\u035a\7T\2\2"+
"\u035a\u0363\7P\2\2\u035b\u035c\7U\2\2\u035c\u035d\7W\2\2\u035d\u035e"+
"\7K\2\2\u035e\u035f\7E\2\2\u035f\u0360\7K\2\2\u0360\u0361\7F\2\2\u0361"+
"\u0363\7G\2\2\u0362\u0188\3\2\2\2\u0362\u018c\3\2\2\2\u0362\u018f\3\2"+
"\2\2\u0362\u0192\3\2\2\2\u0362\u0195\3\2\2\2\u0362\u0198\3\2\2\2\u0362"+
"\u019c\3\2\2\2\u0362\u019f\3\2\2\2\u0362\u01a3\3\2\2\2\u0362\u01a6\3\2"+
"\2\2\u0362\u01a9\3\2\2\2\u0362\u01ab\3\2\2\2\u0362\u01ad\3\2\2\2\u0362"+
"\u01b0\3\2\2\2\u0362\u01b3\3\2\2\2\u0362\u01b5\3\2\2\2\u0362\u01b8\3\2"+
"\2\2\u0362\u01bb\3\2\2\2\u0362\u01bd\3\2\2\2\u0362\u01c0\3\2\2\2\u0362"+
"\u01c4\3\2\2\2\u0362\u01c8\3\2\2\2\u0362\u01cf\3\2\2\2\u0362\u01d6\3\2"+
"\2\2\u0362\u01dc\3\2\2\2\u0362\u01e2\3\2\2\2\u0362\u01eb\3\2\2\2\u0362"+
"\u01f7\3\2\2\2\u0362\u0203\3\2\2\2\u0362\u020f\3\2\2\2\u0362\u0217\3\2"+
"\2\2\u0362\u021f\3\2\2\2\u0362\u0227\3\2\2\2\u0362\u022f\3\2\2\2\u0362"+
"\u0237\3\2\2\2\u0362\u0240\3\2\2\2\u0362\u0246\3\2\2\2\u0362\u0250\3\2"+
"\2\2\u0362\u0258\3\2\2\2\u0362\u025b\3\2\2\2\u0362\u025e\3\2\2\2\u0362"+
"\u0262\3\2\2\2\u0362\u0267\3\2\2\2\u0362\u026d\3\2\2\2\u0362\u0274\3\2"+
"\2\2\u0362\u0279\3\2\2\2\u0362\u027f\3\2\2\2\u0362\u0283\3\2\2\2\u0362"+
"\u0288\3\2\2\2\u0362\u028a\3\2\2\2\u0362\u0291\3\2\2\2\u0362\u0294\3\2"+
"\2\2\u0362\u0299\3\2\2\2\u0362\u029e\3\2\2\2\u0362\u02a3\3\2\2\2\u0362"+
"\u02a8\3\2\2\2\u0362\u02ad\3\2\2\2\u0362\u02b2\3\2\2\2\u0362\u02b7\3\2"+
"\2\2\u0362\u02bc\3\2\2\2\u0362\u02c1\3\2\2\2\u0362\u02c7\3\2\2\2\u0362"+
"\u02cd\3\2\2\2\u0362\u02d3\3\2\2\2\u0362\u02d9\3\2\2\2\u0362\u02df\3\2"+
"\2\2\u0362\u02e5\3\2\2\2\u0362\u02eb\3\2\2\2\u0362\u02f1\3\2\2\2\u0362"+
"\u02f7\3\2\2\2\u0362\u02fd\3\2\2\2\u0362\u0303\3\2\2\2\u0362\u0309\3\2"+
"\2\2\u0362\u030f\3\2\2\2\u0362\u0315\3\2\2\2\u0362\u031b\3\2\2\2\u0362"+
"\u0321\3\2\2\2\u0362\u0327\3\2\2\2\u0362\u032d\3\2\2\2\u0362\u0333\3\2"+
"\2\2\u0362\u0339\3\2\2\2\u0362\u033f\3\2\2\2\u0362\u0345\3\2\2\2\u0362"+
"\u034b\3\2\2\2\u0362\u0351\3\2\2\2\u0362\u0355\3\2\2\2\u0362\u035b\3\2"+
"\2\2\u0363J\3\2\2\2\u0364\u0365\7z\2\2\u0365\u0366\7q\2\2\u0366\u0367"+
"\7t\2\2\u0367L\3\2\2\2\u0368\u0369\7(\2\2\u0369\u036e\7(\2\2\u036a\u036b"+
"\7c\2\2\u036b\u036c\7p\2\2\u036c\u036e\7f\2\2\u036d\u0368\3\2\2\2\u036d"+
"\u036a\3\2\2\2\u036eN\3\2\2\2\u036f\u0370\7~\2\2\u0370\u0374\7~\2\2\u0371"+
"\u0372\7q\2\2\u0372\u0374\7t\2\2\u0373\u036f\3\2\2\2\u0373\u0371\3\2\2"+
"\2\u0374P\3\2\2\2\u0375\u037a\7#\2\2\u0376\u0377\7p\2\2\u0377\u0378\7"+
"q\2\2\u0378\u037a\7v\2\2\u0379\u0375\3\2\2\2\u0379\u0376\3\2\2\2\u037a"+
"R\3\2\2\2\u037b\u037c\7?\2\2\u037cT\3\2\2\2\u037d\u037f\7\17\2\2\u037e"+
"\u037d\3\2\2\2\u037e\u037f\3\2\2\2\u037f\u0380\3\2\2\2\u0380\u0384\7\f"+
"\2\2\u0381\u0383\7\"\2\2\u0382\u0381\3\2\2\2\u0383\u0386\3\2\2\2\u0384"+
"\u0382\3\2\2\2\u0384\u0385\3\2\2\2\u0385V\3\2\2\2\u0386\u0384\3\2\2\2"+
"\u0387\u0389\t\3\2\2\u0388\u0387\3\2\2\2\u0389\u038a\3\2\2\2\u038a\u0388"+
"\3\2\2\2\u038a\u038b\3\2\2\2\u038b\u038c\3\2\2\2\u038c\u038d\b,\2\2\u038d"+
"X\3\2\2\2\u038e\u0392\7%\2\2\u038f\u0391\n\4\2\2\u0390\u038f\3\2\2\2\u0391"+
"\u0394\3\2\2\2\u0392\u0390\3\2\2\2\u0392\u0393\3\2\2\2\u0393\u0395\3\2"+
"\2\2\u0394\u0392\3\2\2\2\u0395\u0396\b-\3\2\u0396Z\3\2\2\2\u0397\u039b"+
"\t\5\2\2\u0398\u039a\t\6\2\2\u0399\u0398\3\2\2\2\u039a\u039d\3\2\2\2\u039b"+
"\u0399\3\2\2\2\u039b\u039c\3\2\2\2\u039c\\\3\2\2\2\u039d\u039b\3\2\2\2"+
"\u039e\u039f\t\7\2\2\u039f^\3\2\2\2\u03a0\u03a1\t\b\2\2\u03a1`\3\2\2\2"+
"\u03a2\u03a8\t\t\2\2\u03a3\u03a4\7>\2\2\u03a4\u03a8\7?\2\2\u03a5\u03a6"+
"\7@\2\2\u03a6\u03a8\7?\2\2\u03a7\u03a2\3\2\2\2\u03a7\u03a3\3\2\2\2\u03a7"+
"\u03a5\3\2\2\2\u03a8b\3\2\2\2\u03a9\u03aa\7?\2\2\u03aa\u03ae\7?\2\2\u03ab"+
"\u03ac\7#\2\2\u03ac\u03ae\7?\2\2\u03ad\u03a9\3\2\2\2\u03ad\u03ab\3\2\2"+
"\2\u03aed\3\2\2\2\u03af\u03b0\7(\2\2\u03b0f\3\2\2\2\u03b1\u03b2\7~\2\2"+
"\u03b2h\3\2\2\2\u03b3\u03b4\t\n\2\2\u03b4j\3\2\2\2\u03b5\u03b6\7\62\2"+
"\2\u03b6\u03ba\7z\2\2\u03b7\u03b8\7\62\2\2\u03b8\u03ba\7Z\2\2\u03b9\u03b5"+
"\3\2\2\2\u03b9\u03b7\3\2\2\2\u03ba\u03bc\3\2\2\2\u03bb\u03bd\5i\65\2\u03bc"+
"\u03bb\3\2\2\2\u03bd\u03be\3\2\2\2\u03be\u03bc\3\2\2\2\u03be\u03bf\3\2"+
"\2\2\u03bfl\3\2\2\2\21\2\u0186\u0362\u036d\u0373\u0379\u037e\u0384\u038a"+
"\u0392\u039b\u03a7\u03ad\u03b9\u03be";
public static final ATN _ATN =
ATNSimulator.deserialize(_serializedATN.toCharArray());
static {

View File

@ -173,6 +173,28 @@ public interface SerpentListener extends ParseTreeListener {
*/
void exitBlock_difficulty(@NotNull SerpentParser.Block_difficultyContext ctx);
/**
* Enter a parse tree produced by {@link SerpentParser#array_assign}.
* @param ctx the parse tree
*/
void enterArray_assign(@NotNull SerpentParser.Array_assignContext ctx);
/**
* Exit a parse tree produced by {@link SerpentParser#array_assign}.
* @param ctx the parse tree
*/
void exitArray_assign(@NotNull SerpentParser.Array_assignContext ctx);
/**
* Enter a parse tree produced by {@link SerpentParser#array_retreive}.
* @param ctx the parse tree
*/
void enterArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx);
/**
* Exit a parse tree produced by {@link SerpentParser#array_retreive}.
* @param ctx the parse tree
*/
void exitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx);
/**
* Enter a parse tree produced by {@link SerpentParser#parse_init_code_block}.
* @param ctx the parse tree
@ -360,6 +382,17 @@ public interface SerpentListener extends ParseTreeListener {
*/
void exitSend_func(@NotNull SerpentParser.Send_funcContext ctx);
/**
* Enter a parse tree produced by {@link SerpentParser#arr_def}.
* @param ctx the parse tree
*/
void enterArr_def(@NotNull SerpentParser.Arr_defContext ctx);
/**
* Exit a parse tree produced by {@link SerpentParser#arr_def}.
* @param ctx the parse tree
*/
void exitArr_def(@NotNull SerpentParser.Arr_defContext ctx);
/**
* Enter a parse tree produced by {@link SerpentParser#while_stmt}.
* @param ctx the parse tree

View File

@ -5,6 +5,9 @@ import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@ -15,35 +18,68 @@ import java.util.regex.Pattern;
public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
int labelIndex = 0;
private ArrayList<String> vars = new ArrayList<String>();
private ArrayList<String> vars = new ArrayList<String>();
private HashMap<String, Integer> arraysSize = new HashMap<String, Integer>();
private List<String> arraysIndex = new ArrayList<String>();
@Override
public String visitParse(@NotNull SerpentParser.ParseContext ctx) {
StringBuffer result = new StringBuffer();
String codeBlock = visit(ctx.block());
int memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
result.append( super.visitParse(ctx) );
String initMemCodeBlock = "";
if ( ! arraysSize.isEmpty() && vars.size() > 0)
initMemCodeBlock = String.format(" 0 %d MSTORE8 ", memSize);
// todo: calc the wrapping with memory usage data
if (memSize == 0)
codeBlock= codeBlock.replace("@vars_table@", "0");
else
codeBlock= codeBlock.replace("@vars_table@", memSize + 1 + "");
return result.toString();
return initMemCodeBlock + codeBlock;
}
@Override
public String visitParse_init_code_block(@NotNull SerpentParser.Parse_init_code_blockContext ctx) {
String initBlock = visit(ctx.block(0));
String codeBlock = visit(ctx.block(1));
int memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
return String.format(" [init %s init] [code %s code] ", initBlock, codeBlock);
String initMemInitBlock = "";
if ( ! arraysSize.isEmpty() && vars.size() > 0)
initMemInitBlock = String.format(" 0 %d MSTORE8 ", memSize);
if (memSize == 0)
initBlock= initBlock.replace("@vars_table@", "0");
else
initBlock= initBlock.replace("@vars_table@", memSize + 1 + "");
vars.clear();
String codeBlock = visit(ctx.block(1));
memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
if (memSize == 0)
codeBlock= codeBlock.replace("@vars_table@", "0");
else
codeBlock= codeBlock.replace("@vars_table@", memSize + 1 + "");
String initMemCodeBlock = "";
if ( ! arraysSize.isEmpty() && vars.size() > 0)
initMemCodeBlock = String.format(" 0 %d MSTORE8 ", memSize);
return String.format(" [init %s %s init] [code %s %s code] ", initMemInitBlock, initBlock,
initMemCodeBlock, codeBlock);
}
@Override
public String visitIf_elif_else_stmt(@NotNull SerpentParser.If_elif_else_stmtContext ctx) {
//todo: when you find some error throw expectation exception
StringBuffer retCode = new StringBuffer();
int endOfStmtLabel = labelIndex++ ;
@ -164,15 +200,29 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
String varName = ctx.VAR().toString();
int addr = 0;
addr = vars.indexOf(varName);
if (addr == -1){
addr = vars.size();
vars.add(varName);
if (ctx.arr_def() != null){
// if it's an array the all management is different
String arrayCode = visitArr_def(ctx.arr_def());
// calc the pointer addr
int pos = getArraySize(arrayCode);
arraysSize.put(varName, pos);
arraysIndex.add(varName);
return arrayCode;
} else{
// if it's an array the all management is different
String expression = visitExpression(ctx.expression());
addr = vars.indexOf(varName);
if (addr == -1){
addr = vars.size();
vars.add(varName);
}
return String.format(" %s %d MSTORE ", expression, addr * 32);
}
String expression = visitExpression(ctx.expression());
return String.format(" %s %d MSTORE ", expression, addr * 32);
}
@Override
@ -223,9 +273,69 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
if (ctx.send_func() != null)
return visitSend_func(ctx.send_func());
if (ctx.array_retreive() != null)
return visitArray_retreive(ctx.array_retreive());
return ctx.INT().toString();
}
@Override
public String visitArr_def(@NotNull SerpentParser.Arr_defContext ctx) {
List<SerpentParser.Int_valContext> numElements = ctx.int_val();
int arraySize = numElements.size() * 32 + 32;
StringBuffer arrayInit = new StringBuffer();
int i = 32;
for (SerpentParser.Int_valContext int_val : ctx.int_val()){
arrayInit.append(String.format(" DUP %d ADD %s SWAP MSTORE ", i, visit(int_val)));
i += 32;
}
return String.format(" MEMSIZE %s %d SWAP MSTORE ", arrayInit, arraySize);
}
@Override
public String visitArray_assign(@NotNull SerpentParser.Array_assignContext ctx) {
int order = this.arraysIndex.indexOf( ctx.VAR().toString());
if (order == -1){
throw new Error("array with that name was not defined");
}
//calcAllocatedBefore();
int allocSize = 0;
for (int i = 0; i < order; ++i ){
String var = arraysIndex.get(i);
allocSize += arraysSize.get(var);
}
String index = visit(ctx.int_val());
String assignValue = visit(ctx.expression());
return String.format(" %s 32 %s MUL 32 ADD %d ADD @vars_table@ ADD MSTORE ", assignValue, index, allocSize);
}
@Override
public String visitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx) {
int order = this.arraysIndex.indexOf( ctx.VAR().toString());
if (order == -1){
throw new Error("array with that name was not defined");
}
int allocSize = 0;
for (int i = 0; i < order; ++i ){
String var = arraysIndex.get(i);
allocSize += arraysSize.get(var);
}
String index = visit(ctx.int_val());
return String.format(" 32 %s MUL %d ADD @vars_table@ ADD MLOAD ", index, allocSize );
}
@Override
public String visitMul_expr(@NotNull SerpentParser.Mul_exprContext ctx) {
@ -264,8 +374,8 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
if (ctx.rel_exp() == null) return visit(ctx.add_expr());
String operand0 = visit(ctx.add_expr());
String operand1 = visit(ctx.rel_exp());
String operand0 = visit(ctx.rel_exp());
String operand1 = visit(ctx.add_expr());
switch (ctx.OP_REL().getText().toLowerCase()) {
case "<": return operand1 + " " + operand0 + " LT";
@ -490,7 +600,7 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
String operand2 = visit(ctx.int_val(2));
// OUTDATASIZE OUTDATASTART INDATASIZE INDATASTART VALUE TO GAS CALL
return String.format("0 0 0 0 %s %s %s CALL ", operand1, operand0, operand2);
return String.format("0 0 0 0 %s %s %s CALL ", operand1, operand0, operand2);
}
@Override
@ -564,4 +674,19 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
}
}
private Integer getArraySize(String code){
String result = "0";
Pattern pattern = Pattern.compile(" [0-9]* SWAP MSTORE$");
Matcher matcher = pattern.matcher(code.trim());
if (matcher.find()) {
String group = matcher.group(0);
result = group.replace("SWAP MSTORE", "").trim();
}
return Integer.parseInt(result);
}
}

View File

@ -116,6 +116,20 @@ public interface SerpentVisitor<T> extends ParseTreeVisitor<T> {
*/
T visitBlock_difficulty(@NotNull SerpentParser.Block_difficultyContext ctx);
/**
* Visit a parse tree produced by {@link SerpentParser#array_assign}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitArray_assign(@NotNull SerpentParser.Array_assignContext ctx);
/**
* Visit a parse tree produced by {@link SerpentParser#array_retreive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx);
/**
* Visit a parse tree produced by {@link SerpentParser#parse_init_code_block}.
* @param ctx the parse tree
@ -235,6 +249,13 @@ public interface SerpentVisitor<T> extends ParseTreeVisitor<T> {
*/
T visitSend_func(@NotNull SerpentParser.Send_funcContext ctx);
/**
* Visit a parse tree produced by {@link SerpentParser#arr_def}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitArr_def(@NotNull SerpentParser.Arr_defContext ctx);
/**
* Visit a parse tree produced by {@link SerpentParser#while_stmt}.
* @param ctx the parse tree

View File

@ -262,7 +262,7 @@ public class SerpentCompileTest {
public void test14(){
String code = "a = 1 > 2 > 3 > 4";
String expected = "1 2 GT 3 GT 4 GT 0 MSTORE";
String expected = "4 3 2 1 GT GT GT 0 MSTORE";
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
code);
@ -297,13 +297,14 @@ public class SerpentCompileTest {
String code = "if 1>2: \n" +
" a=2";
String expected = "1 2 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 LABEL_0";
String expected = "2 1 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 LABEL_0";
/**
1 2 GT NOT REF_1 JUMPI
2 1 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP LABEL_1 LABEL_0
REF_0 JUMP
LABEL_1 LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -322,13 +323,14 @@ public class SerpentCompileTest {
String code = "if 10 > 2 + 5: \n" +
" a=2";
String expected = "10 5 2 ADD GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 LABEL_0";
String expected = "5 2 ADD 10 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 LABEL_0";
/**
10 5 2 ADD GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP LABEL_1 LABEL_0
5 2 ADD 10 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1 LABEL_0
*/
@ -350,14 +352,15 @@ public class SerpentCompileTest {
" a=2\n" +
"else: \n" +
" c=3\n";
String expected = "10 5 2 ADD GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 3 32 MSTORE LABEL_0";
String expected = "5 2 ADD 10 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 3 32 MSTORE LABEL_0";
/**
10 5 2 ADD GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP LABEL_1
3 32 MSTORE
LABEL_0
5 2 ADD 10 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
3 32 MSTORE
LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -379,15 +382,16 @@ public class SerpentCompileTest {
"else: \n" +
" c=123\n" +
" d=0xFFAA";
String expected = "10 5 2 ADD GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 123 32 MSTORE 65450 64 MSTORE LABEL_0";
String expected = "5 2 ADD 10 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 123 32 MSTORE 65450 64 MSTORE LABEL_0";
/**
10 5 2 ADD GT NOT REF_1 JUMPI
2 0 MSTORE REF_0
JUMP LABEL_1
123 32 MSTORE
65450 64 MSTORE
LABEL_0
5 2 ADD 10 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
123 32 MSTORE
65450 64 MSTORE
LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -411,20 +415,20 @@ public class SerpentCompileTest {
"else: \n" +
" c=123\n" +
" d=0xFFAA";
String expected = "10 5 2 ADD GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE REF_0 JUMP LABEL_2 123 32 MSTORE 65450 64 MSTORE LABEL_0";
String expected = "5 2 ADD 10 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE REF_0 JUMP LABEL_2 123 32 MSTORE 65450 64 MSTORE LABEL_0";
/**
10 5 2 ADD GT NOT REF_1 JUMPI
2 0 MSTORE REF_0
JUMP LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
REF_0 JUMP LABEL_2
123 32 MSTORE
65450 64 MSTORE
LABEL_0
5 2 ADD 10 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
REF_0 JUMP
LABEL_2
123 32 MSTORE
65450 64 MSTORE
LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -452,27 +456,27 @@ public class SerpentCompileTest {
"else: \n" +
" c=123\n" +
" d=0xFFAA";
String expected = "10 5 2 ADD LT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_3 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_3 123 32 MSTORE 65450 64 MSTORE LABEL_0";
String expected = "5 2 ADD 10 LT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_3 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_3 123 32 MSTORE 65450 64 MSTORE LABEL_0";
/**
10 5 2 ADD LT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
REF_0 JUMP
LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_3 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_3
123 32 MSTORE
65450 64 MSTORE LABEL_0
5 2 ADD 10 LT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
REF_0 JUMP
LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_3 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_3
123 32 MSTORE
65450 64 MSTORE
LABEL_0
*/
@ -504,31 +508,31 @@ public class SerpentCompileTest {
"else: \n" +
" c=123\n" +
" d=0xFFAA";
String expected = "10 5 2 ADD GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE 3 0 MLOAD EQ NOT REF_4 JUMPI 123 32 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_5 123 64 MSTORE 65450 96 MSTORE LABEL_0";
String expected = "5 2 ADD 10 GT NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE 3 0 MLOAD EQ NOT REF_4 JUMPI 123 32 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_5 123 64 MSTORE 65450 96 MSTORE LABEL_0";
/**
10 5 2 ADD GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
5 2 ADD 10 GT NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
3 0 MLOAD
EQ NOT REF_4 JUMPI
123 32 MSTORE
REF_3 JUMP
LABEL_4
LABEL_3
REF_0 JUMP LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_5
123 64 MSTORE
65450 96 MSTORE
LABEL_0
3 0 MSTORE
3 0 MLOAD EQ NOT REF_4 JUMPI
123 32 MSTORE
REF_3 JUMP
LABEL_4
LABEL_3
REF_0
JUMP LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_5
123 64 MSTORE
65450 96 MSTORE
LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -558,30 +562,31 @@ public class SerpentCompileTest {
"else: \n" +
" c=123\n" +
" d=0xFFAA";
String expected = "7 2 MUL 96 GT 10 5 2 ADD LT NOT NOT NOT MUL NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE 3 0 MLOAD EQ NOT REF_4 JUMPI 123 32 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_5 123 64 MSTORE 65450 96 MSTORE LABEL_0";
String expected = "96 7 2 MUL GT 5 2 ADD 10 LT NOT NOT NOT MUL NOT REF_1 JUMPI 2 0 MSTORE REF_0 JUMP LABEL_1 4 2 2 MUL EQ NOT REF_2 JUMPI 3 0 MSTORE 3 0 MLOAD EQ NOT REF_4 JUMPI 123 32 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_0 JUMP LABEL_2 40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI 3 0 MSTORE 9 0 MSTORE 21 0 MSTORE REF_0 JUMP LABEL_5 123 64 MSTORE 65450 96 MSTORE LABEL_0";
/**
7 2 MUL 96 GT 10 5 2 ADD LT NOT NOT NOT MUL NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
3 0 MLOAD EQ NOT REF_4 JUMPI
123 32 MSTORE REF_3 JUMP
96 7 2 MUL GT 5 2 ADD 10 LT NOT NOT NOT MUL NOT REF_1 JUMPI
2 0 MSTORE
REF_0 JUMP
LABEL_1
4 2 2 MUL EQ NOT REF_2 JUMPI
3 0 MSTORE
3 0 MLOAD EQ NOT REF_4 JUMPI
123 32 MSTORE
REF_3 JUMP
LABEL_4
LABEL_3
REF_0 JUMP
LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_5
123 64 MSTORE
65450 96 MSTORE
LABEL_0
REF_0 JUMP
LABEL_2
40 10 2 2 MUL ADD EQ NOT REF_5 JUMPI
3 0 MSTORE
9 0 MSTORE
21 0 MSTORE
REF_0 JUMP
LABEL_5
123 64 MSTORE
65450 96 MSTORE
LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -680,17 +685,18 @@ public class SerpentCompileTest {
" if 4>3:\n" +
" if 5>4:\n" +
" a = 10\n";
String expected = "2 1 GT NOT REF_7 JUMPI 3 2 GT NOT REF_6 JUMPI 4 3 GT NOT REF_5 JUMPI 5 4 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
String expected = "1 2 GT NOT REF_7 JUMPI 2 3 GT NOT REF_6 JUMPI 3 4 GT NOT REF_5 JUMPI 4 5 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
/**
2 1 GT NOT REF_7 JUMPI
3 2 GT NOT REF_6 JUMPI
4 3 GT NOT REF_5 JUMPI
5 4 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
1 2 GT NOT REF_7 JUMPI
2 3 GT NOT REF_6 JUMPI
3 4 GT NOT REF_5 JUMPI
4 5 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -712,16 +718,17 @@ public class SerpentCompileTest {
" if 4>3:\n" +
" if 5>4:\n" +
" a = 10\n";
String expected = "2 1 GT NOT REF_7 JUMPI 3 2 GT NOT REF_6 JUMPI 4 3 GT NOT REF_5 JUMPI 5 4 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
String expected = "1 2 GT NOT REF_7 JUMPI 2 3 GT NOT REF_6 JUMPI 3 4 GT NOT REF_5 JUMPI 4 5 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
/**
2 1 GT NOT REF_7 JUMPI
3 2 GT NOT REF_6 JUMPI
4 3 GT NOT REF_5 JUMPI
5 4 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
1 2 GT NOT REF_7 JUMPI
2 3 GT NOT REF_6 JUMPI
3 4 GT NOT REF_5 JUMPI
4 5 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4 LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
*/
SerpentParser parser = ParserUtils.getParser(SerpentLexer.class, SerpentParser.class,
@ -745,19 +752,19 @@ public class SerpentCompileTest {
" a = 10\n" +
" else:\n" +
" b = 20\n";
String expected = "2 1 GT NOT REF_7 JUMPI 3 2 GT NOT REF_6 JUMPI 4 3 GT NOT REF_5 JUMPI 5 4 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 20 32 MSTORE LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
String expected = "1 2 GT NOT REF_7 JUMPI 2 3 GT NOT REF_6 JUMPI 3 4 GT NOT REF_5 JUMPI 4 5 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 20 32 MSTORE LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0";
/**
2 1 GT NOT REF_7 JUMPI
3 2 GT NOT REF_6 JUMPI
4 3 GT NOT REF_5 JUMPI
5 4 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4
20 32 MSTORE
LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
1 2 GT NOT REF_7 JUMPI
2 3 GT NOT REF_6 JUMPI
3 4 GT NOT REF_5 JUMPI
4 5 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4
20 32 MSTORE
LABEL_3 REF_2 JUMP LABEL_5 LABEL_2 REF_1 JUMP LABEL_6 LABEL_1 REF_0 JUMP LABEL_7 LABEL_0
*/
@ -921,15 +928,23 @@ public class SerpentCompileTest {
" b = 20\n" +
" elif 2*2 != 4: \n" +
" a = 15\n";
String expected = "2 1 GT NOT REF_8 JUMPI 3 2 GT NOT REF_7 JUMPI 4 3 GT NOT REF_5 JUMPI 5 4 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 20 32 MSTORE LABEL_3 REF_2 JUMP LABEL_5 4 2 2 MUL EQ NOT NOT REF_6 JUMPI 15 0 MSTORE REF_2 JUMP LABEL_6 LABEL_2 REF_1 JUMP LABEL_7 LABEL_1 REF_0 JUMP LABEL_8 LABEL_0";
String expected = "1 2 GT NOT REF_8 JUMPI 2 3 GT NOT REF_7 JUMPI 3 4 GT NOT REF_5 JUMPI 4 5 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 20 32 MSTORE LABEL_3 REF_2 JUMP LABEL_5 4 2 2 MUL EQ NOT NOT REF_6 JUMPI 15 0 MSTORE REF_2 JUMP LABEL_6 LABEL_2 REF_1 JUMP LABEL_7 LABEL_1 REF_0 JUMP LABEL_8 LABEL_0";
/**
2 1 GT NOT REF_8 JUMPI
3 2 GT NOT REF_7 JUMPI
4 3 GT NOT REF_5 JUMPI
5 4 GT NOT REF_4 JUMPI 10 0 MSTORE REF_3 JUMP LABEL_4 20 32 MSTORE LABEL_3 REF_2 JUMP LABEL_5 4 2 2 MUL EQ NOT NOT REF_6 JUMPI 15 0 MSTORE REF_2 JUMP LABEL_6 LABEL_2 REF_1 JUMP LABEL_7 LABEL_1 REF_0 JUMP LABEL_8 LABEL_0
1 2 GT NOT REF_8 JUMPI
2 3 GT NOT REF_7 JUMPI
3 4 GT NOT REF_5 JUMPI
4 5 GT NOT REF_4 JUMPI
10 0 MSTORE
REF_3 JUMP
LABEL_4
20 32 MSTORE
LABEL_3 REF_2 JUMP
LABEL_5
4 2 2 MUL EQ NOT NOT REF_6 JUMPI
15 0 MSTORE
REF_2 JUMP LABEL_6 LABEL_2 REF_1 JUMP LABEL_7 LABEL_1 REF_0 JUMP LABEL_8 LABEL_0
*/
@ -956,24 +971,24 @@ public class SerpentCompileTest {
"else: \n" +
" a=50 \n" ;
String expected = "2 1 GT NOT REF_1 JUMPI 20 0 MSTORE REF_0 JUMP LABEL_1 5 1 LT NOT REF_2 JUMPI 30 0 MSTORE REF_0 JUMP LABEL_2 6 6 GT NOT REF_3 JUMPI 40 0 MSTORE REF_0 JUMP LABEL_3 50 0 MSTORE LABEL_0";
String expected = "1 2 GT NOT REF_1 JUMPI 20 0 MSTORE REF_0 JUMP LABEL_1 1 5 LT NOT REF_2 JUMPI 30 0 MSTORE REF_0 JUMP LABEL_2 6 6 GT NOT REF_3 JUMPI 40 0 MSTORE REF_0 JUMP LABEL_3 50 0 MSTORE LABEL_0";
/**
2 1 GT NOT REF_1 JUMPI
20 0 MSTORE
REF_0 JUMP
LABEL_1
5 1 LT NOT REF_2 JUMPI
30 0 MSTORE
REF_0 JUMP
LABEL_2
6 6 GT NOT REF_3 JUMPI
40 0 MSTORE
REF_0 JUMP
LABEL_3
50 0 MSTORE
LABEL_0
1 2 GT NOT REF_1 JUMPI
20 0 MSTORE
REF_0 JUMP
LABEL_1
1 5 LT NOT REF_2 JUMPI
30 0 MSTORE
REF_0 JUMP
LABEL_2
6 6 GT NOT REF_3 JUMPI
40 0 MSTORE
REF_0 JUMP
LABEL_3
50 0 MSTORE
LABEL_0
*/
@ -995,14 +1010,16 @@ public class SerpentCompileTest {
"while a>0: \n" +
" a = a - 1 \n" ;
String expected = "20 0 MSTORE LABEL_0 0 MLOAD 0 GT NOT REF_1 JUMPI 1 0 MLOAD SUB 0 MSTORE REF_0 JUMP LABEL_1";
String expected = "20 0 MSTORE LABEL_0 0 0 MLOAD GT NOT REF_1 JUMPI 1 0 MLOAD SUB 0 MSTORE REF_0 JUMP LABEL_1";
/**
20 0 MSTORE
LABEL_0 0 MLOAD 0 GT NOT REF_1 JUMPI
1 0 MLOAD SUB 0 MSTORE
REF_0 JUMP LABEL_1
20 0 MSTORE
LABEL_0
0 0 MLOAD GT EQ NOT REF_1 JUMPI
1 0 MLOAD SUB 0 MSTORE
REF_0 JUMP
LABEL_1
*/
@ -1027,18 +1044,22 @@ public class SerpentCompileTest {
" else: \n " +
" x = 3 * x + 1 \n" ;
String expected = "248 0 MSTORE LABEL_0 0 MLOAD 1 GT NOT REF_1 JUMPI 0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI 2 0 MLOAD DIV 0 MSTORE REF_2 JUMP LABEL_3 1 0 MLOAD 3 MUL ADD 0 MSTORE LABEL_2 REF_0 JUMP LABEL_1";
String expected = "248 0 MSTORE LABEL_0 1 0 MLOAD GT NOT REF_1 JUMPI 0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI 2 0 MLOAD DIV 0 MSTORE REF_2 JUMP LABEL_3 1 0 MLOAD 3 MUL ADD 0 MSTORE LABEL_2 REF_0 JUMP LABEL_1";
/**
248 0 MSTORE
LABEL_0 0 MLOAD 1 GT NOT REF_1 JUMPI
0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI
2 0 MLOAD DIV 0 MSTORE
REF_2 JUMP LABEL_3
1 0 MLOAD 3 MUL ADD 0 MSTORE
LABEL_2 REF_0 JUMP
LABEL_1
248 0 MSTORE
LABEL_0
1 0 MLOAD GT NOT REF_1 JUMPI
0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI
2 0 MLOAD DIV 0 MSTORE
REF_2 JUMP
LABEL_3
1 0 MLOAD 3 MUL ADD 0 MSTORE
LABEL_2
REF_0 JUMP
LABEL_1
*/
@ -1063,19 +1084,20 @@ public class SerpentCompileTest {
"x = x +2 \n" +
"x = 3 * x + 1 \n" ;
String expected = "255 0 MSTORE LABEL_0 0 MLOAD 1 GT NOT REF_1 JUMPI 0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI 2 0 MLOAD DIV 0 MSTORE REF_2 JUMP LABEL_3 LABEL_2 REF_0 JUMP LABEL_1 2 0 MLOAD ADD 0 MSTORE 1 0 MLOAD 3 MUL ADD 0 MSTORE";
String expected = "255 0 MSTORE LABEL_0 1 0 MLOAD GT NOT REF_1 JUMPI 0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI 2 0 MLOAD DIV 0 MSTORE REF_2 JUMP LABEL_3 LABEL_2 REF_0 JUMP LABEL_1 2 0 MLOAD ADD 0 MSTORE 1 0 MLOAD 3 MUL ADD 0 MSTORE";
/**
255 0 MSTORE
LABEL_0 0 MLOAD 1 GT NOT REF_1 JUMPI
255 0 MSTORE
LABEL_0
1 0 MLOAD GT EQ NOT REF_1 JUMPI
0 2 0 MLOAD MOD EQ NOT REF_3 JUMPI
2 0 MLOAD DIV 0 MSTORE
REF_2 JUMP LABEL_3 LABEL_2
REF_0 JUMP LABEL_1
2 0 MLOAD ADD 0 MSTORE
1 0 MLOAD 3 MUL ADD 0 MSTORE
2 0 MLOAD DIV 0 MSTORE REF_2 JUMP
LABEL_3 LABEL_2
REF_0 JUMP
LABEL_1
2 0 MLOAD ADD 0 MSTORE
1 0 MLOAD 3 MUL ADD 0 MSTORE
*/
@ -1123,14 +1145,15 @@ public class SerpentCompileTest {
"while (x > 1) && (x > 2) && (x > 3) && (2 <9):\n" +
" x = x -2\n" ;
String expected = "255 0 MSTORE LABEL_0 2 9 LT 0 MLOAD 3 GT 0 MLOAD 2 GT 0 MLOAD 1 GT NOT NOT MUL NOT NOT MUL NOT NOT MUL NOT REF_1 JUMPI 2 0 MLOAD SUB 0 MSTORE REF_0 JUMP LABEL_1";
String expected = "255 0 MSTORE LABEL_0 9 2 LT 3 0 MLOAD GT 2 0 MLOAD GT 1 0 MLOAD GT NOT NOT MUL NOT NOT MUL NOT NOT MUL NOT REF_1 JUMPI 2 0 MLOAD SUB 0 MSTORE REF_0 JUMP LABEL_1";
/**
255 0 MSTORE LABEL_0
2 9 LT 0 MLOAD 3 GT 0 MLOAD 2 GT 0 MLOAD 1 GT NOT NOT MUL NOT NOT MUL NOT NOT MUL NOT REF_1 JUMPI
2 0 MLOAD SUB 0 MSTORE
REF_0 JUMP
255 0 MSTORE
LABEL_0
9 2 LT 3 0 MLOAD GT 2 0 MLOAD GT 1 0 MLOAD GT NOT NOT MUL NOT NOT MUL NOT NOT MUL EQ NOT REF_1 JUMPI
2 0 MLOAD SUB 0 MSTORE
REF_0 JUMP
LABEL_1
*/
@ -1225,24 +1248,77 @@ public class SerpentCompileTest {
" b=msg.data[1]\n" +
" stop\n" ;
String expected = "[init 2 0 MSTORE init] [code 1 32 MUL CALLDATALOAD 32 MSTORE STOP code]";
String expected = "[init 2 0 MSTORE init] [code 1 32 MUL CALLDATALOAD 0 MSTORE STOP code]";
String asmResult = SerpentCompiler.compileFullNotion(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 1 simple create
public void test45(){
String code = "c = 2\n" +
"d = 3\n" +
"a = [11, 22, 33]" ;
String expected = "0 63 MSTORE8 2 0 MSTORE 3 32 MSTORE MEMSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // todo delete this one
public void testFoo(){
System.out.println(ByteUtil.numBytes("65536"));
@Test // test arrays 2 simple set
public void test46(){
String code = "a = [11, 22, 33]\n" +
"a[ 2 ] = 3" ;
String expected = "MEMSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 0 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 3 complicated set after 2 arrays
public void test47(){
String code = "a = [2, 4, 6]\n" +
"b = [12, 14]\n" +
"c = [22, 24, 25]\n" +
"c[ 0 ] = 3" ;
String expected = "MEMSIZE DUP 32 ADD 2 SWAP MSTORE DUP 64 ADD 4 SWAP MSTORE DUP 96 ADD 6 SWAP MSTORE 128 SWAP MSTORE MEMSIZE DUP 32 ADD 12 SWAP MSTORE DUP 64 ADD 14 SWAP MSTORE 96 SWAP MSTORE MEMSIZE DUP 32 ADD 22 SWAP MSTORE DUP 64 ADD 24 SWAP MSTORE DUP 96 ADD 25 SWAP MSTORE 128 SWAP MSTORE 3 32 0 MUL 32 ADD 224 ADD 0 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 4 simple set
public void test48(){
String code = "b = 1\n" +
"c = 2\n" +
"a = [11, 22, 33]\n" +
"a[ 2 ] = 3" ;
String expected = "0 63 MSTORE8 1 0 MSTORE 2 32 MSTORE MEMSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 64 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 5 simple retrieve value
public void test49(){
String code = "c = [5]\n" +
"a = [11, 22, 33]\n" +
"b = a [0]" ;
String expected = "0 31 MSTORE8 MEMSIZE DUP 32 ADD 5 SWAP MSTORE 64 SWAP MSTORE MEMSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 32 0 MUL 64 ADD 32 ADD MLOAD 0 MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
/*
todo: more to implement
# *) a = msg.data
# 0) sha();
# 2) create(1, 2, 3, 4)
# 3) x = sha3(v)

View File

@ -31,4 +31,4 @@ code:
contract.storage[to] = contract.storage[to] + value
return(1)
else:
return(0)
return(0)