This commit is contained in:
Irmen de Jong 2018-09-02 16:38:18 +02:00
parent d4341b7afe
commit 492c64f348
6 changed files with 1138 additions and 903 deletions

View File

@ -113,7 +113,6 @@ expression :
| left = expression bop = '**' right = expression
| left = expression bop = ('*' | '/' ) right = expression
| left = expression bop = ('+' | '-' ) right = expression
| left = expression bop = ('<<' | '>>') right = expression
| left = expression bop = ('<' | '>' | '<=' | '>=') right = expression
| left = expression bop = ('==' | '!=') right = expression
| left = expression bop = '&' right = expression

View File

@ -76,19 +76,17 @@ T__74=75
T__75=76
T__76=77
T__77=78
T__78=79
T__79=80
LINECOMMENT=81
COMMENT=82
WS=83
EOL=84
NAME=85
DEC_INTEGER=86
HEX_INTEGER=87
BIN_INTEGER=88
FLOAT_NUMBER=89
STRING=90
INLINEASMBLOCK=91
LINECOMMENT=79
COMMENT=80
WS=81
EOL=82
NAME=83
DEC_INTEGER=84
HEX_INTEGER=85
BIN_INTEGER=86
FLOAT_NUMBER=87
STRING=88
INLINEASMBLOCK=89
'~'=1
':'=2
'goto'=3
@ -131,41 +129,39 @@ INLINEASMBLOCK=91
'**'=40
'*'=41
'/'=42
'<<'=43
'>>'=44
'<'=45
'>'=46
'<='=47
'>='=48
'=='=49
'!='=50
'&'=51
'^'=52
'|'=53
'to'=54
'and'=55
'or'=56
'xor'=57
'not'=58
'return'=59
'.'=60
'A'=61
'X'=62
'Y'=63
'AX'=64
'AY'=65
'XY'=66
'Pc'=67
'Pz'=68
'Pn'=69
'Pv'=70
'true'=71
'false'=72
'%asm'=73
'sub'=74
'->'=75
'{'=76
'}'=77
'?'=78
'if'=79
'else'=80
'<'=43
'>'=44
'<='=45
'>='=46
'=='=47
'!='=48
'&'=49
'^'=50
'|'=51
'to'=52
'and'=53
'or'=54
'xor'=55
'not'=56
'return'=57
'.'=58
'A'=59
'X'=60
'Y'=61
'AX'=62
'AY'=63
'XY'=64
'Pc'=65
'Pz'=66
'Pn'=67
'Pv'=68
'true'=69
'false'=70
'%asm'=71
'sub'=72
'->'=73
'{'=74
'}'=75
'?'=76
'if'=77
'else'=78

View File

@ -27,9 +27,9 @@ public class il65Lexer extends Lexer {
T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59,
T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66,
T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73,
T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, T__78=79, T__79=80,
LINECOMMENT=81, COMMENT=82, WS=83, EOL=84, NAME=85, DEC_INTEGER=86, HEX_INTEGER=87,
BIN_INTEGER=88, FLOAT_NUMBER=89, STRING=90, INLINEASMBLOCK=91;
T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, LINECOMMENT=79, COMMENT=80,
WS=81, EOL=82, NAME=83, DEC_INTEGER=84, HEX_INTEGER=85, BIN_INTEGER=86,
FLOAT_NUMBER=87, STRING=88, INLINEASMBLOCK=89;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@ -48,9 +48,9 @@ public class il65Lexer extends Lexer {
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72",
"T__73", "T__74", "T__75", "T__76", "T__77", "T__78", "T__79", "LINECOMMENT",
"COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER",
"FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK"
"T__73", "T__74", "T__75", "T__76", "T__77", "LINECOMMENT", "COMMENT",
"WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
"FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK"
};
private static final String[] _LITERAL_NAMES = {
@ -59,10 +59,10 @@ public class il65Lexer extends Lexer {
"'%option'", "','", "'='", "'const'", "'memory'", "'byte'", "'word'",
"'float'", "'str'", "'str_p'", "'str_s'", "'str_ps'", "'['", "']'", "'+='",
"'-='", "'/='", "'*='", "'**='", "'&='", "'|='", "'^='", "'++'", "'--'",
"'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'<<'", "'>>'", "'<'",
"'>'", "'<='", "'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'and'",
"'or'", "'xor'", "'not'", "'return'", "'.'", "'A'", "'X'", "'Y'", "'AX'",
"'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'true'", "'false'", "'%asm'",
"'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'<'", "'>'", "'<='",
"'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'and'", "'or'",
"'xor'", "'not'", "'return'", "'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'",
"'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'true'", "'false'", "'%asm'",
"'sub'", "'->'", "'{'", "'}'", "'?'", "'if'", "'else'"
};
private static final String[] _SYMBOLIC_NAMES = {
@ -72,8 +72,8 @@ public class il65Lexer extends Lexer {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, "LINECOMMENT", "COMMENT",
"WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
null, null, null, null, null, null, null, "LINECOMMENT", "COMMENT", "WS",
"EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
"STRING", "INLINEASMBLOCK"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -136,10 +136,10 @@ public class il65Lexer extends Lexer {
@Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) {
case 91:
case 89:
STRING_action((RuleContext)_localctx, actionIndex);
break;
case 92:
case 90:
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
break;
}
@ -168,7 +168,7 @@ public class il65Lexer extends Lexer {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2]\u026b\b\1\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2[\u0261\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\t\31"+
@ -178,202 +178,198 @@ public class il65Lexer extends Lexer {
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\3\2\3\2"+
"\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3"+
"\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7"+
"\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+
"\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13"+
"\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+
"\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3"+
"\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+
"\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3"+
"\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3"+
"\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3"+
"\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3"+
"\37\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\60\3\60"+
"\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\65\3\65"+
"\3\66\3\66\3\67\3\67\3\67\38\38\38\38\39\39\39\3:\3:\3:\3:\3;\3;\3;\3"+
";\3<\3<\3<\3<\3<\3<\3<\3=\3=\3>\3>\3?\3?\3@\3@\3A\3A\3A\3B\3B\3B\3C\3"+
"C\3C\3D\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3I\3"+
"I\3I\3J\3J\3J\3J\3J\3K\3K\3K\3K\3L\3L\3L\3M\3M\3N\3N\3O\3O\3P\3P\3P\3"+
"Q\3Q\3Q\3Q\3Q\3R\3R\7R\u0202\nR\fR\16R\u0205\13R\3R\3R\3R\3R\3S\3S\7S"+
"\u020d\nS\fS\16S\u0210\13S\3S\3S\3T\3T\3T\3T\3U\6U\u0219\nU\rU\16U\u021a"+
"\3V\3V\7V\u021f\nV\fV\16V\u0222\13V\3W\3W\3W\6W\u0227\nW\rW\16W\u0228"+
"\5W\u022b\nW\3X\3X\6X\u022f\nX\rX\16X\u0230\3Y\3Y\6Y\u0235\nY\rY\16Y\u0236"+
"\3Z\3Z\3Z\5Z\u023c\nZ\3Z\5Z\u023f\nZ\3[\6[\u0242\n[\r[\16[\u0243\3[\3"+
"[\6[\u0248\n[\r[\16[\u0249\5[\u024c\n[\3\\\3\\\3\\\3\\\5\\\u0252\n\\\3"+
"]\3]\3]\7]\u0257\n]\f]\16]\u025a\13]\3]\3]\3]\3^\3^\3^\3^\6^\u0263\n^"+
"\r^\16^\u0264\3^\3^\3^\3^\3^\3\u0264\2_\3\3\5\4\7\5\t\6\13\7\r\b\17\t"+
"\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27"+
"-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W"+
"-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083"+
"C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097"+
"M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00ab"+
"W\u00adX\u00afY\u00b1Z\u00b3[\u00b5\2\u00b7\2\u00b9\\\u00bb]\3\2\n\4\2"+
"\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aac|\5\2\62;CHch\4\2GGg"+
"g\4\2--//\6\2\f\f\16\17$$^^\2\u0279\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"+
"\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\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\177\3\2\2\2"+
"\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+
"\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+
"\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+
"\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+
"\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+
"\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b9\3\2\2"+
"\2\2\u00bb\3\2\2\2\3\u00bd\3\2\2\2\5\u00bf\3\2\2\2\7\u00c1\3\2\2\2\t\u00c6"+
"\3\2\2\2\13\u00ce\3\2\2\2\r\u00d8\3\2\2\2\17\u00e2\3\2\2\2\21\u00eb\3"+
"\2\2\2\23\u00f3\3\2\2\2\25\u00ff\3\2\2\2\27\u010b\3\2\2\2\31\u0116\3\2"+
"\2\2\33\u011e\3\2\2\2\35\u0120\3\2\2\2\37\u0122\3\2\2\2!\u0128\3\2\2\2"+
"#\u012f\3\2\2\2%\u0134\3\2\2\2\'\u0139\3\2\2\2)\u013f\3\2\2\2+\u0143\3"+
"\2\2\2-\u0149\3\2\2\2/\u014f\3\2\2\2\61\u0156\3\2\2\2\63\u0158\3\2\2\2"+
"\65\u015a\3\2\2\2\67\u015d\3\2\2\29\u0160\3\2\2\2;\u0163\3\2\2\2=\u0166"+
"\3\2\2\2?\u016a\3\2\2\2A\u016d\3\2\2\2C\u0170\3\2\2\2E\u0173\3\2\2\2G"+
"\u0176\3\2\2\2I\u0179\3\2\2\2K\u017b\3\2\2\2M\u017d\3\2\2\2O\u017f\3\2"+
"\2\2Q\u0181\3\2\2\2S\u0184\3\2\2\2U\u0186\3\2\2\2W\u0188\3\2\2\2Y\u018b"+
"\3\2\2\2[\u018e\3\2\2\2]\u0190\3\2\2\2_\u0192\3\2\2\2a\u0195\3\2\2\2c"+
"\u0198\3\2\2\2e\u019b\3\2\2\2g\u019e\3\2\2\2i\u01a0\3\2\2\2k\u01a2\3\2"+
"\2\2m\u01a4\3\2\2\2o\u01a7\3\2\2\2q\u01ab\3\2\2\2s\u01ae\3\2\2\2u\u01b2"+
"\3\2\2\2w\u01b6\3\2\2\2y\u01bd\3\2\2\2{\u01bf\3\2\2\2}\u01c1\3\2\2\2\177"+
"\u01c3\3\2\2\2\u0081\u01c5\3\2\2\2\u0083\u01c8\3\2\2\2\u0085\u01cb\3\2"+
"\2\2\u0087\u01ce\3\2\2\2\u0089\u01d1\3\2\2\2\u008b\u01d4\3\2\2\2\u008d"+
"\u01d7\3\2\2\2\u008f\u01da\3\2\2\2\u0091\u01df\3\2\2\2\u0093\u01e5\3\2"+
"\2\2\u0095\u01ea\3\2\2\2\u0097\u01ee\3\2\2\2\u0099\u01f1\3\2\2\2\u009b"+
"\u01f3\3\2\2\2\u009d\u01f5\3\2\2\2\u009f\u01f7\3\2\2\2\u00a1\u01fa\3\2"+
"\2\2\u00a3\u01ff\3\2\2\2\u00a5\u020a\3\2\2\2\u00a7\u0213\3\2\2\2\u00a9"+
"\u0218\3\2\2\2\u00ab\u021c\3\2\2\2\u00ad\u022a\3\2\2\2\u00af\u022c\3\2"+
"\2\2\u00b1\u0232\3\2\2\2\u00b3\u0238\3\2\2\2\u00b5\u0241\3\2\2\2\u00b7"+
"\u0251\3\2\2\2\u00b9\u0253\3\2\2\2\u00bb\u025e\3\2\2\2\u00bd\u00be\7\u0080"+
"\2\2\u00be\4\3\2\2\2\u00bf\u00c0\7<\2\2\u00c0\6\3\2\2\2\u00c1\u00c2\7"+
"i\2\2\u00c2\u00c3\7q\2\2\u00c3\u00c4\7v\2\2\u00c4\u00c5\7q\2\2\u00c5\b"+
"\3\2\2\2\u00c6\u00c7\7\'\2\2\u00c7\u00c8\7q\2\2\u00c8\u00c9\7w\2\2\u00c9"+
"\u00ca\7v\2\2\u00ca\u00cb\7r\2\2\u00cb\u00cc\7w\2\2\u00cc\u00cd\7v\2\2"+
"\u00cd\n\3\2\2\2\u00ce\u00cf\7\'\2\2\u00cf\u00d0\7n\2\2\u00d0\u00d1\7"+
"c\2\2\u00d1\u00d2\7w\2\2\u00d2\u00d3\7p\2\2\u00d3\u00d4\7e\2\2\u00d4\u00d5"+
"\7j\2\2\u00d5\u00d6\7g\2\2\u00d6\u00d7\7t\2\2\u00d7\f\3\2\2\2\u00d8\u00d9"+
"\7\'\2\2\u00d9\u00da\7|\2\2\u00da\u00db\7g\2\2\u00db\u00dc\7t\2\2\u00dc"+
"\u00dd\7q\2\2\u00dd\u00de\7r\2\2\u00de\u00df\7c\2\2\u00df\u00e0\7i\2\2"+
"\u00e0\u00e1\7g\2\2\u00e1\16\3\2\2\2\u00e2\u00e3\7\'\2\2\u00e3\u00e4\7"+
"c\2\2\u00e4\u00e5\7f\2\2\u00e5\u00e6\7f\2\2\u00e6\u00e7\7t\2\2\u00e7\u00e8"+
"\7g\2\2\u00e8\u00e9\7u\2\2\u00e9\u00ea\7u\2\2\u00ea\20\3\2\2\2\u00eb\u00ec"+
"\7\'\2\2\u00ec\u00ed\7k\2\2\u00ed\u00ee\7o\2\2\u00ee\u00ef\7r\2\2\u00ef"+
"\u00f0\7q\2\2\u00f0\u00f1\7t\2\2\u00f1\u00f2\7v\2\2\u00f2\22\3\2\2\2\u00f3"+
"\u00f4\7\'\2\2\u00f4\u00f5\7d\2\2\u00f5\u00f6\7t\2\2\u00f6\u00f7\7g\2"+
"\2\u00f7\u00f8\7c\2\2\u00f8\u00f9\7m\2\2\u00f9\u00fa\7r\2\2\u00fa\u00fb"+
"\7q\2\2\u00fb\u00fc\7k\2\2\u00fc\u00fd\7p\2\2\u00fd\u00fe\7v\2\2\u00fe"+
"\24\3\2\2\2\u00ff\u0100\7\'\2\2\u0100\u0101\7c\2\2\u0101\u0102\7u\2\2"+
"\u0102\u0103\7o\2\2\u0103\u0104\7k\2\2\u0104\u0105\7p\2\2\u0105\u0106"+
"\7e\2\2\u0106\u0107\7n\2\2\u0107\u0108\7w\2\2\u0108\u0109\7f\2\2\u0109"+
"\u010a\7g\2\2\u010a\26\3\2\2\2\u010b\u010c\7\'\2\2\u010c\u010d\7c\2\2"+
"\u010d\u010e\7u\2\2\u010e\u010f\7o\2\2\u010f\u0110\7d\2\2\u0110\u0111"+
"\7k\2\2\u0111\u0112\7p\2\2\u0112\u0113\7c\2\2\u0113\u0114\7t\2\2\u0114"+
"\u0115\7{\2\2\u0115\30\3\2\2\2\u0116\u0117\7\'\2\2\u0117\u0118\7q\2\2"+
"\u0118\u0119\7r\2\2\u0119\u011a\7v\2\2\u011a\u011b\7k\2\2\u011b\u011c"+
"\7q\2\2\u011c\u011d\7p\2\2\u011d\32\3\2\2\2\u011e\u011f\7.\2\2\u011f\34"+
"\3\2\2\2\u0120\u0121\7?\2\2\u0121\36\3\2\2\2\u0122\u0123\7e\2\2\u0123"+
"\u0124\7q\2\2\u0124\u0125\7p\2\2\u0125\u0126\7u\2\2\u0126\u0127\7v\2\2"+
"\u0127 \3\2\2\2\u0128\u0129\7o\2\2\u0129\u012a\7g\2\2\u012a\u012b\7o\2"+
"\2\u012b\u012c\7q\2\2\u012c\u012d\7t\2\2\u012d\u012e\7{\2\2\u012e\"\3"+
"\2\2\2\u012f\u0130\7d\2\2\u0130\u0131\7{\2\2\u0131\u0132\7v\2\2\u0132"+
"\u0133\7g\2\2\u0133$\3\2\2\2\u0134\u0135\7y\2\2\u0135\u0136\7q\2\2\u0136"+
"\u0137\7t\2\2\u0137\u0138\7f\2\2\u0138&\3\2\2\2\u0139\u013a\7h\2\2\u013a"+
"\u013b\7n\2\2\u013b\u013c\7q\2\2\u013c\u013d\7c\2\2\u013d\u013e\7v\2\2"+
"\u013e(\3\2\2\2\u013f\u0140\7u\2\2\u0140\u0141\7v\2\2\u0141\u0142\7t\2"+
"\2\u0142*\3\2\2\2\u0143\u0144\7u\2\2\u0144\u0145\7v\2\2\u0145\u0146\7"+
"t\2\2\u0146\u0147\7a\2\2\u0147\u0148\7r\2\2\u0148,\3\2\2\2\u0149\u014a"+
"\7u\2\2\u014a\u014b\7v\2\2\u014b\u014c\7t\2\2\u014c\u014d\7a\2\2\u014d"+
"\u014e\7u\2\2\u014e.\3\2\2\2\u014f\u0150\7u\2\2\u0150\u0151\7v\2\2\u0151"+
"\u0152\7t\2\2\u0152\u0153\7a\2\2\u0153\u0154\7r\2\2\u0154\u0155\7u\2\2"+
"\u0155\60\3\2\2\2\u0156\u0157\7]\2\2\u0157\62\3\2\2\2\u0158\u0159\7_\2"+
"\2\u0159\64\3\2\2\2\u015a\u015b\7-\2\2\u015b\u015c\7?\2\2\u015c\66\3\2"+
"\2\2\u015d\u015e\7/\2\2\u015e\u015f\7?\2\2\u015f8\3\2\2\2\u0160\u0161"+
"\7\61\2\2\u0161\u0162\7?\2\2\u0162:\3\2\2\2\u0163\u0164\7,\2\2\u0164\u0165"+
"\7?\2\2\u0165<\3\2\2\2\u0166\u0167\7,\2\2\u0167\u0168\7,\2\2\u0168\u0169"+
"\7?\2\2\u0169>\3\2\2\2\u016a\u016b\7(\2\2\u016b\u016c\7?\2\2\u016c@\3"+
"\2\2\2\u016d\u016e\7~\2\2\u016e\u016f\7?\2\2\u016fB\3\2\2\2\u0170\u0171"+
"\7`\2\2\u0171\u0172\7?\2\2\u0172D\3\2\2\2\u0173\u0174\7-\2\2\u0174\u0175"+
"\7-\2\2\u0175F\3\2\2\2\u0176\u0177\7/\2\2\u0177\u0178\7/\2\2\u0178H\3"+
"\2\2\2\u0179\u017a\7*\2\2\u017aJ\3\2\2\2\u017b\u017c\7+\2\2\u017cL\3\2"+
"\2\2\u017d\u017e\7-\2\2\u017eN\3\2\2\2\u017f\u0180\7/\2\2\u0180P\3\2\2"+
"\2\u0181\u0182\7,\2\2\u0182\u0183\7,\2\2\u0183R\3\2\2\2\u0184\u0185\7"+
",\2\2\u0185T\3\2\2\2\u0186\u0187\7\61\2\2\u0187V\3\2\2\2\u0188\u0189\7"+
">\2\2\u0189\u018a\7>\2\2\u018aX\3\2\2\2\u018b\u018c\7@\2\2\u018c\u018d"+
"\7@\2\2\u018dZ\3\2\2\2\u018e\u018f\7>\2\2\u018f\\\3\2\2\2\u0190\u0191"+
"\7@\2\2\u0191^\3\2\2\2\u0192\u0193\7>\2\2\u0193\u0194\7?\2\2\u0194`\3"+
"\2\2\2\u0195\u0196\7@\2\2\u0196\u0197\7?\2\2\u0197b\3\2\2\2\u0198\u0199"+
"\7?\2\2\u0199\u019a\7?\2\2\u019ad\3\2\2\2\u019b\u019c\7#\2\2\u019c\u019d"+
"\7?\2\2\u019df\3\2\2\2\u019e\u019f\7(\2\2\u019fh\3\2\2\2\u01a0\u01a1\7"+
"`\2\2\u01a1j\3\2\2\2\u01a2\u01a3\7~\2\2\u01a3l\3\2\2\2\u01a4\u01a5\7v"+
"\2\2\u01a5\u01a6\7q\2\2\u01a6n\3\2\2\2\u01a7\u01a8\7c\2\2\u01a8\u01a9"+
"\7p\2\2\u01a9\u01aa\7f\2\2\u01aap\3\2\2\2\u01ab\u01ac\7q\2\2\u01ac\u01ad"+
"\7t\2\2\u01adr\3\2\2\2\u01ae\u01af\7z\2\2\u01af\u01b0\7q\2\2\u01b0\u01b1"+
"\7t\2\2\u01b1t\3\2\2\2\u01b2\u01b3\7p\2\2\u01b3\u01b4\7q\2\2\u01b4\u01b5"+
"\7v\2\2\u01b5v\3\2\2\2\u01b6\u01b7\7t\2\2\u01b7\u01b8\7g\2\2\u01b8\u01b9"+
"\7v\2\2\u01b9\u01ba\7w\2\2\u01ba\u01bb\7t\2\2\u01bb\u01bc\7p\2\2\u01bc"+
"x\3\2\2\2\u01bd\u01be\7\60\2\2\u01bez\3\2\2\2\u01bf\u01c0\7C\2\2\u01c0"+
"|\3\2\2\2\u01c1\u01c2\7Z\2\2\u01c2~\3\2\2\2\u01c3\u01c4\7[\2\2\u01c4\u0080"+
"\3\2\2\2\u01c5\u01c6\7C\2\2\u01c6\u01c7\7Z\2\2\u01c7\u0082\3\2\2\2\u01c8"+
"\u01c9\7C\2\2\u01c9\u01ca\7[\2\2\u01ca\u0084\3\2\2\2\u01cb\u01cc\7Z\2"+
"\2\u01cc\u01cd\7[\2\2\u01cd\u0086\3\2\2\2\u01ce\u01cf\7R\2\2\u01cf\u01d0"+
"\7e\2\2\u01d0\u0088\3\2\2\2\u01d1\u01d2\7R\2\2\u01d2\u01d3\7|\2\2\u01d3"+
"\u008a\3\2\2\2\u01d4\u01d5\7R\2\2\u01d5\u01d6\7p\2\2\u01d6\u008c\3\2\2"+
"\2\u01d7\u01d8\7R\2\2\u01d8\u01d9\7x\2\2\u01d9\u008e\3\2\2\2\u01da\u01db"+
"\7v\2\2\u01db\u01dc\7t\2\2\u01dc\u01dd\7w\2\2\u01dd\u01de\7g\2\2\u01de"+
"\u0090\3\2\2\2\u01df\u01e0\7h\2\2\u01e0\u01e1\7c\2\2\u01e1\u01e2\7n\2"+
"\2\u01e2\u01e3\7u\2\2\u01e3\u01e4\7g\2\2\u01e4\u0092\3\2\2\2\u01e5\u01e6"+
"\7\'\2\2\u01e6\u01e7\7c\2\2\u01e7\u01e8\7u\2\2\u01e8\u01e9\7o\2\2\u01e9"+
"\u0094\3\2\2\2\u01ea\u01eb\7u\2\2\u01eb\u01ec\7w\2\2\u01ec\u01ed\7d\2"+
"\2\u01ed\u0096\3\2\2\2\u01ee\u01ef\7/\2\2\u01ef\u01f0\7@\2\2\u01f0\u0098"+
"\3\2\2\2\u01f1\u01f2\7}\2\2\u01f2\u009a\3\2\2\2\u01f3\u01f4\7\177\2\2"+
"\u01f4\u009c\3\2\2\2\u01f5\u01f6\7A\2\2\u01f6\u009e\3\2\2\2\u01f7\u01f8"+
"\7k\2\2\u01f8\u01f9\7h\2\2\u01f9\u00a0\3\2\2\2\u01fa\u01fb\7g\2\2\u01fb"+
"\u01fc\7n\2\2\u01fc\u01fd\7u\2\2\u01fd\u01fe\7g\2\2\u01fe\u00a2\3\2\2"+
"\2\u01ff\u0203\t\2\2\2\u0200\u0202\t\3\2\2\u0201\u0200\3\2\2\2\u0202\u0205"+
"\3\2\2\2\u0203\u0201\3\2\2\2\u0203\u0204\3\2\2\2\u0204\u0206\3\2\2\2\u0205"+
"\u0203\3\2\2\2\u0206\u0207\5\u00a5S\2\u0207\u0208\3\2\2\2\u0208\u0209"+
"\bR\2\2\u0209\u00a4\3\2\2\2\u020a\u020e\7=\2\2\u020b\u020d\n\2\2\2\u020c"+
"\u020b\3\2\2\2\u020d\u0210\3\2\2\2\u020e\u020c\3\2\2\2\u020e\u020f\3\2"+
"\2\2\u020f\u0211\3\2\2\2\u0210\u020e\3\2\2\2\u0211\u0212\bS\2\2\u0212"+
"\u00a6\3\2\2\2\u0213\u0214\t\3\2\2\u0214\u0215\3\2\2\2\u0215\u0216\bT"+
"\3\2\u0216\u00a8\3\2\2\2\u0217\u0219\t\2\2\2\u0218\u0217\3\2\2\2\u0219"+
"\u021a\3\2\2\2\u021a\u0218\3\2\2\2\u021a\u021b\3\2\2\2\u021b\u00aa\3\2"+
"\2\2\u021c\u0220\t\4\2\2\u021d\u021f\t\5\2\2\u021e\u021d\3\2\2\2\u021f"+
"\u0222\3\2\2\2\u0220\u021e\3\2\2\2\u0220\u0221\3\2\2\2\u0221\u00ac\3\2"+
"\2\2\u0222\u0220\3\2\2\2\u0223\u022b\4\62;\2\u0224\u0226\4\63;\2\u0225"+
"\u0227\4\62;\2\u0226\u0225\3\2\2\2\u0227\u0228\3\2\2\2\u0228\u0226\3\2"+
"\2\2\u0228\u0229\3\2\2\2\u0229\u022b\3\2\2\2\u022a\u0223\3\2\2\2\u022a"+
"\u0224\3\2\2\2\u022b\u00ae\3\2\2\2\u022c\u022e\7&\2\2\u022d\u022f\t\6"+
"\2\2\u022e\u022d\3\2\2\2\u022f\u0230\3\2\2\2\u0230\u022e\3\2\2\2\u0230"+
"\u0231\3\2\2\2\u0231\u00b0\3\2\2\2\u0232\u0234\7\'\2\2\u0233\u0235\4\62"+
"\63\2\u0234\u0233\3\2\2\2\u0235\u0236\3\2\2\2\u0236\u0234\3\2\2\2\u0236"+
"\u0237\3\2\2\2\u0237\u00b2\3\2\2\2\u0238\u023e\5\u00b5[\2\u0239\u023b"+
"\t\7\2\2\u023a\u023c\t\b\2\2\u023b\u023a\3\2\2\2\u023b\u023c\3\2\2\2\u023c"+
"\u023d\3\2\2\2\u023d\u023f\5\u00b5[\2\u023e\u0239\3\2\2\2\u023e\u023f"+
"\3\2\2\2\u023f\u00b4\3\2\2\2\u0240\u0242\4\62;\2\u0241\u0240\3\2\2\2\u0242"+
"\u0243\3\2\2\2\u0243\u0241\3\2\2\2\u0243\u0244\3\2\2\2\u0244\u024b\3\2"+
"\2\2\u0245\u0247\7\60\2\2\u0246\u0248\4\62;\2\u0247\u0246\3\2\2\2\u0248"+
"\u0249\3\2\2\2\u0249\u0247\3\2\2\2\u0249\u024a\3\2\2\2\u024a\u024c\3\2"+
"\2\2\u024b\u0245\3\2\2\2\u024b\u024c\3\2\2\2\u024c\u00b6\3\2\2\2\u024d"+
"\u024e\7^\2\2\u024e\u0252\13\2\2\2\u024f\u0250\7^\2\2\u0250\u0252\5\u00a9"+
"U\2\u0251\u024d\3\2\2\2\u0251\u024f\3\2\2\2\u0252\u00b8\3\2\2\2\u0253"+
"\u0258\7$\2\2\u0254\u0257\5\u00b7\\\2\u0255\u0257\n\t\2\2\u0256\u0254"+
"\3\2\2\2\u0256\u0255\3\2\2\2\u0257\u025a\3\2\2\2\u0258\u0256\3\2\2\2\u0258"+
"\u0259\3\2\2\2\u0259\u025b\3\2\2\2\u025a\u0258\3\2\2\2\u025b\u025c\7$"+
"\2\2\u025c\u025d\b]\4\2\u025d\u00ba\3\2\2\2\u025e\u025f\7}\2\2\u025f\u0260"+
"\7}\2\2\u0260\u0262\3\2\2\2\u0261\u0263\13\2\2\2\u0262\u0261\3\2\2\2\u0263"+
"\u0264\3\2\2\2\u0264\u0265\3\2\2\2\u0264\u0262\3\2\2\2\u0265\u0266\3\2"+
"\2\2\u0266\u0267\7\177\2\2\u0267\u0268\7\177\2\2\u0268\u0269\3\2\2\2\u0269"+
"\u026a\b^\5\2\u026a\u00bc\3\2\2\2\25\2\u0203\u020e\u021a\u0220\u0228\u022a"+
"\u022e\u0230\u0236\u023b\u023e\u0243\u0249\u024b\u0251\u0256\u0258\u0264"+
"\6\2\3\2\b\2\2\3]\2\3^\3";
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\3\2\3\2\3\3\3\3\3\4"+
"\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3"+
"\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b"+
"\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3"+
"\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+
"\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+
"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3"+
"\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3"+
"\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3"+
"\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3"+
"\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\33\3"+
"\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\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\60\3\60\3\60\3\61"+
"\3\61\3\61\3\62\3\62\3\63\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66"+
"\3\66\3\67\3\67\3\67\38\38\38\38\39\39\39\39\3:\3:\3:\3:\3:\3:\3:\3;\3"+
";\3<\3<\3=\3=\3>\3>\3?\3?\3?\3@\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3"+
"D\3D\3E\3E\3E\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3"+
"I\3I\3J\3J\3J\3K\3K\3L\3L\3M\3M\3N\3N\3N\3O\3O\3O\3O\3O\3P\3P\7P\u01f8"+
"\nP\fP\16P\u01fb\13P\3P\3P\3P\3P\3Q\3Q\7Q\u0203\nQ\fQ\16Q\u0206\13Q\3"+
"Q\3Q\3R\3R\3R\3R\3S\6S\u020f\nS\rS\16S\u0210\3T\3T\7T\u0215\nT\fT\16T"+
"\u0218\13T\3U\3U\3U\6U\u021d\nU\rU\16U\u021e\5U\u0221\nU\3V\3V\6V\u0225"+
"\nV\rV\16V\u0226\3W\3W\6W\u022b\nW\rW\16W\u022c\3X\3X\3X\5X\u0232\nX\3"+
"X\5X\u0235\nX\3Y\6Y\u0238\nY\rY\16Y\u0239\3Y\3Y\6Y\u023e\nY\rY\16Y\u023f"+
"\5Y\u0242\nY\3Z\3Z\3Z\3Z\5Z\u0248\nZ\3[\3[\3[\7[\u024d\n[\f[\16[\u0250"+
"\13[\3[\3[\3[\3\\\3\\\3\\\3\\\6\\\u0259\n\\\r\\\16\\\u025a\3\\\3\\\3\\"+
"\3\\\3\\\3\u025a\2]\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r"+
"\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33"+
"\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63"+
"e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089"+
"F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009d"+
"P\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1"+
"\2\u00b3\2\u00b5Z\u00b7[\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|"+
"\6\2\62;C\\aac|\5\2\62;CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u026f"+
"\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\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2"+
"U\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\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\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+
"\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2"+
"\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+
"\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+
"\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+
"\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b5\3\2\2"+
"\2\2\u00b7\3\2\2\2\3\u00b9\3\2\2\2\5\u00bb\3\2\2\2\7\u00bd\3\2\2\2\t\u00c2"+
"\3\2\2\2\13\u00ca\3\2\2\2\r\u00d4\3\2\2\2\17\u00de\3\2\2\2\21\u00e7\3"+
"\2\2\2\23\u00ef\3\2\2\2\25\u00fb\3\2\2\2\27\u0107\3\2\2\2\31\u0112\3\2"+
"\2\2\33\u011a\3\2\2\2\35\u011c\3\2\2\2\37\u011e\3\2\2\2!\u0124\3\2\2\2"+
"#\u012b\3\2\2\2%\u0130\3\2\2\2\'\u0135\3\2\2\2)\u013b\3\2\2\2+\u013f\3"+
"\2\2\2-\u0145\3\2\2\2/\u014b\3\2\2\2\61\u0152\3\2\2\2\63\u0154\3\2\2\2"+
"\65\u0156\3\2\2\2\67\u0159\3\2\2\29\u015c\3\2\2\2;\u015f\3\2\2\2=\u0162"+
"\3\2\2\2?\u0166\3\2\2\2A\u0169\3\2\2\2C\u016c\3\2\2\2E\u016f\3\2\2\2G"+
"\u0172\3\2\2\2I\u0175\3\2\2\2K\u0177\3\2\2\2M\u0179\3\2\2\2O\u017b\3\2"+
"\2\2Q\u017d\3\2\2\2S\u0180\3\2\2\2U\u0182\3\2\2\2W\u0184\3\2\2\2Y\u0186"+
"\3\2\2\2[\u0188\3\2\2\2]\u018b\3\2\2\2_\u018e\3\2\2\2a\u0191\3\2\2\2c"+
"\u0194\3\2\2\2e\u0196\3\2\2\2g\u0198\3\2\2\2i\u019a\3\2\2\2k\u019d\3\2"+
"\2\2m\u01a1\3\2\2\2o\u01a4\3\2\2\2q\u01a8\3\2\2\2s\u01ac\3\2\2\2u\u01b3"+
"\3\2\2\2w\u01b5\3\2\2\2y\u01b7\3\2\2\2{\u01b9\3\2\2\2}\u01bb\3\2\2\2\177"+
"\u01be\3\2\2\2\u0081\u01c1\3\2\2\2\u0083\u01c4\3\2\2\2\u0085\u01c7\3\2"+
"\2\2\u0087\u01ca\3\2\2\2\u0089\u01cd\3\2\2\2\u008b\u01d0\3\2\2\2\u008d"+
"\u01d5\3\2\2\2\u008f\u01db\3\2\2\2\u0091\u01e0\3\2\2\2\u0093\u01e4\3\2"+
"\2\2\u0095\u01e7\3\2\2\2\u0097\u01e9\3\2\2\2\u0099\u01eb\3\2\2\2\u009b"+
"\u01ed\3\2\2\2\u009d\u01f0\3\2\2\2\u009f\u01f5\3\2\2\2\u00a1\u0200\3\2"+
"\2\2\u00a3\u0209\3\2\2\2\u00a5\u020e\3\2\2\2\u00a7\u0212\3\2\2\2\u00a9"+
"\u0220\3\2\2\2\u00ab\u0222\3\2\2\2\u00ad\u0228\3\2\2\2\u00af\u022e\3\2"+
"\2\2\u00b1\u0237\3\2\2\2\u00b3\u0247\3\2\2\2\u00b5\u0249\3\2\2\2\u00b7"+
"\u0254\3\2\2\2\u00b9\u00ba\7\u0080\2\2\u00ba\4\3\2\2\2\u00bb\u00bc\7<"+
"\2\2\u00bc\6\3\2\2\2\u00bd\u00be\7i\2\2\u00be\u00bf\7q\2\2\u00bf\u00c0"+
"\7v\2\2\u00c0\u00c1\7q\2\2\u00c1\b\3\2\2\2\u00c2\u00c3\7\'\2\2\u00c3\u00c4"+
"\7q\2\2\u00c4\u00c5\7w\2\2\u00c5\u00c6\7v\2\2\u00c6\u00c7\7r\2\2\u00c7"+
"\u00c8\7w\2\2\u00c8\u00c9\7v\2\2\u00c9\n\3\2\2\2\u00ca\u00cb\7\'\2\2\u00cb"+
"\u00cc\7n\2\2\u00cc\u00cd\7c\2\2\u00cd\u00ce\7w\2\2\u00ce\u00cf\7p\2\2"+
"\u00cf\u00d0\7e\2\2\u00d0\u00d1\7j\2\2\u00d1\u00d2\7g\2\2\u00d2\u00d3"+
"\7t\2\2\u00d3\f\3\2\2\2\u00d4\u00d5\7\'\2\2\u00d5\u00d6\7|\2\2\u00d6\u00d7"+
"\7g\2\2\u00d7\u00d8\7t\2\2\u00d8\u00d9\7q\2\2\u00d9\u00da\7r\2\2\u00da"+
"\u00db\7c\2\2\u00db\u00dc\7i\2\2\u00dc\u00dd\7g\2\2\u00dd\16\3\2\2\2\u00de"+
"\u00df\7\'\2\2\u00df\u00e0\7c\2\2\u00e0\u00e1\7f\2\2\u00e1\u00e2\7f\2"+
"\2\u00e2\u00e3\7t\2\2\u00e3\u00e4\7g\2\2\u00e4\u00e5\7u\2\2\u00e5\u00e6"+
"\7u\2\2\u00e6\20\3\2\2\2\u00e7\u00e8\7\'\2\2\u00e8\u00e9\7k\2\2\u00e9"+
"\u00ea\7o\2\2\u00ea\u00eb\7r\2\2\u00eb\u00ec\7q\2\2\u00ec\u00ed\7t\2\2"+
"\u00ed\u00ee\7v\2\2\u00ee\22\3\2\2\2\u00ef\u00f0\7\'\2\2\u00f0\u00f1\7"+
"d\2\2\u00f1\u00f2\7t\2\2\u00f2\u00f3\7g\2\2\u00f3\u00f4\7c\2\2\u00f4\u00f5"+
"\7m\2\2\u00f5\u00f6\7r\2\2\u00f6\u00f7\7q\2\2\u00f7\u00f8\7k\2\2\u00f8"+
"\u00f9\7p\2\2\u00f9\u00fa\7v\2\2\u00fa\24\3\2\2\2\u00fb\u00fc\7\'\2\2"+
"\u00fc\u00fd\7c\2\2\u00fd\u00fe\7u\2\2\u00fe\u00ff\7o\2\2\u00ff\u0100"+
"\7k\2\2\u0100\u0101\7p\2\2\u0101\u0102\7e\2\2\u0102\u0103\7n\2\2\u0103"+
"\u0104\7w\2\2\u0104\u0105\7f\2\2\u0105\u0106\7g\2\2\u0106\26\3\2\2\2\u0107"+
"\u0108\7\'\2\2\u0108\u0109\7c\2\2\u0109\u010a\7u\2\2\u010a\u010b\7o\2"+
"\2\u010b\u010c\7d\2\2\u010c\u010d\7k\2\2\u010d\u010e\7p\2\2\u010e\u010f"+
"\7c\2\2\u010f\u0110\7t\2\2\u0110\u0111\7{\2\2\u0111\30\3\2\2\2\u0112\u0113"+
"\7\'\2\2\u0113\u0114\7q\2\2\u0114\u0115\7r\2\2\u0115\u0116\7v\2\2\u0116"+
"\u0117\7k\2\2\u0117\u0118\7q\2\2\u0118\u0119\7p\2\2\u0119\32\3\2\2\2\u011a"+
"\u011b\7.\2\2\u011b\34\3\2\2\2\u011c\u011d\7?\2\2\u011d\36\3\2\2\2\u011e"+
"\u011f\7e\2\2\u011f\u0120\7q\2\2\u0120\u0121\7p\2\2\u0121\u0122\7u\2\2"+
"\u0122\u0123\7v\2\2\u0123 \3\2\2\2\u0124\u0125\7o\2\2\u0125\u0126\7g\2"+
"\2\u0126\u0127\7o\2\2\u0127\u0128\7q\2\2\u0128\u0129\7t\2\2\u0129\u012a"+
"\7{\2\2\u012a\"\3\2\2\2\u012b\u012c\7d\2\2\u012c\u012d\7{\2\2\u012d\u012e"+
"\7v\2\2\u012e\u012f\7g\2\2\u012f$\3\2\2\2\u0130\u0131\7y\2\2\u0131\u0132"+
"\7q\2\2\u0132\u0133\7t\2\2\u0133\u0134\7f\2\2\u0134&\3\2\2\2\u0135\u0136"+
"\7h\2\2\u0136\u0137\7n\2\2\u0137\u0138\7q\2\2\u0138\u0139\7c\2\2\u0139"+
"\u013a\7v\2\2\u013a(\3\2\2\2\u013b\u013c\7u\2\2\u013c\u013d\7v\2\2\u013d"+
"\u013e\7t\2\2\u013e*\3\2\2\2\u013f\u0140\7u\2\2\u0140\u0141\7v\2\2\u0141"+
"\u0142\7t\2\2\u0142\u0143\7a\2\2\u0143\u0144\7r\2\2\u0144,\3\2\2\2\u0145"+
"\u0146\7u\2\2\u0146\u0147\7v\2\2\u0147\u0148\7t\2\2\u0148\u0149\7a\2\2"+
"\u0149\u014a\7u\2\2\u014a.\3\2\2\2\u014b\u014c\7u\2\2\u014c\u014d\7v\2"+
"\2\u014d\u014e\7t\2\2\u014e\u014f\7a\2\2\u014f\u0150\7r\2\2\u0150\u0151"+
"\7u\2\2\u0151\60\3\2\2\2\u0152\u0153\7]\2\2\u0153\62\3\2\2\2\u0154\u0155"+
"\7_\2\2\u0155\64\3\2\2\2\u0156\u0157\7-\2\2\u0157\u0158\7?\2\2\u0158\66"+
"\3\2\2\2\u0159\u015a\7/\2\2\u015a\u015b\7?\2\2\u015b8\3\2\2\2\u015c\u015d"+
"\7\61\2\2\u015d\u015e\7?\2\2\u015e:\3\2\2\2\u015f\u0160\7,\2\2\u0160\u0161"+
"\7?\2\2\u0161<\3\2\2\2\u0162\u0163\7,\2\2\u0163\u0164\7,\2\2\u0164\u0165"+
"\7?\2\2\u0165>\3\2\2\2\u0166\u0167\7(\2\2\u0167\u0168\7?\2\2\u0168@\3"+
"\2\2\2\u0169\u016a\7~\2\2\u016a\u016b\7?\2\2\u016bB\3\2\2\2\u016c\u016d"+
"\7`\2\2\u016d\u016e\7?\2\2\u016eD\3\2\2\2\u016f\u0170\7-\2\2\u0170\u0171"+
"\7-\2\2\u0171F\3\2\2\2\u0172\u0173\7/\2\2\u0173\u0174\7/\2\2\u0174H\3"+
"\2\2\2\u0175\u0176\7*\2\2\u0176J\3\2\2\2\u0177\u0178\7+\2\2\u0178L\3\2"+
"\2\2\u0179\u017a\7-\2\2\u017aN\3\2\2\2\u017b\u017c\7/\2\2\u017cP\3\2\2"+
"\2\u017d\u017e\7,\2\2\u017e\u017f\7,\2\2\u017fR\3\2\2\2\u0180\u0181\7"+
",\2\2\u0181T\3\2\2\2\u0182\u0183\7\61\2\2\u0183V\3\2\2\2\u0184\u0185\7"+
">\2\2\u0185X\3\2\2\2\u0186\u0187\7@\2\2\u0187Z\3\2\2\2\u0188\u0189\7>"+
"\2\2\u0189\u018a\7?\2\2\u018a\\\3\2\2\2\u018b\u018c\7@\2\2\u018c\u018d"+
"\7?\2\2\u018d^\3\2\2\2\u018e\u018f\7?\2\2\u018f\u0190\7?\2\2\u0190`\3"+
"\2\2\2\u0191\u0192\7#\2\2\u0192\u0193\7?\2\2\u0193b\3\2\2\2\u0194\u0195"+
"\7(\2\2\u0195d\3\2\2\2\u0196\u0197\7`\2\2\u0197f\3\2\2\2\u0198\u0199\7"+
"~\2\2\u0199h\3\2\2\2\u019a\u019b\7v\2\2\u019b\u019c\7q\2\2\u019cj\3\2"+
"\2\2\u019d\u019e\7c\2\2\u019e\u019f\7p\2\2\u019f\u01a0\7f\2\2\u01a0l\3"+
"\2\2\2\u01a1\u01a2\7q\2\2\u01a2\u01a3\7t\2\2\u01a3n\3\2\2\2\u01a4\u01a5"+
"\7z\2\2\u01a5\u01a6\7q\2\2\u01a6\u01a7\7t\2\2\u01a7p\3\2\2\2\u01a8\u01a9"+
"\7p\2\2\u01a9\u01aa\7q\2\2\u01aa\u01ab\7v\2\2\u01abr\3\2\2\2\u01ac\u01ad"+
"\7t\2\2\u01ad\u01ae\7g\2\2\u01ae\u01af\7v\2\2\u01af\u01b0\7w\2\2\u01b0"+
"\u01b1\7t\2\2\u01b1\u01b2\7p\2\2\u01b2t\3\2\2\2\u01b3\u01b4\7\60\2\2\u01b4"+
"v\3\2\2\2\u01b5\u01b6\7C\2\2\u01b6x\3\2\2\2\u01b7\u01b8\7Z\2\2\u01b8z"+
"\3\2\2\2\u01b9\u01ba\7[\2\2\u01ba|\3\2\2\2\u01bb\u01bc\7C\2\2\u01bc\u01bd"+
"\7Z\2\2\u01bd~\3\2\2\2\u01be\u01bf\7C\2\2\u01bf\u01c0\7[\2\2\u01c0\u0080"+
"\3\2\2\2\u01c1\u01c2\7Z\2\2\u01c2\u01c3\7[\2\2\u01c3\u0082\3\2\2\2\u01c4"+
"\u01c5\7R\2\2\u01c5\u01c6\7e\2\2\u01c6\u0084\3\2\2\2\u01c7\u01c8\7R\2"+
"\2\u01c8\u01c9\7|\2\2\u01c9\u0086\3\2\2\2\u01ca\u01cb\7R\2\2\u01cb\u01cc"+
"\7p\2\2\u01cc\u0088\3\2\2\2\u01cd\u01ce\7R\2\2\u01ce\u01cf\7x\2\2\u01cf"+
"\u008a\3\2\2\2\u01d0\u01d1\7v\2\2\u01d1\u01d2\7t\2\2\u01d2\u01d3\7w\2"+
"\2\u01d3\u01d4\7g\2\2\u01d4\u008c\3\2\2\2\u01d5\u01d6\7h\2\2\u01d6\u01d7"+
"\7c\2\2\u01d7\u01d8\7n\2\2\u01d8\u01d9\7u\2\2\u01d9\u01da\7g\2\2\u01da"+
"\u008e\3\2\2\2\u01db\u01dc\7\'\2\2\u01dc\u01dd\7c\2\2\u01dd\u01de\7u\2"+
"\2\u01de\u01df\7o\2\2\u01df\u0090\3\2\2\2\u01e0\u01e1\7u\2\2\u01e1\u01e2"+
"\7w\2\2\u01e2\u01e3\7d\2\2\u01e3\u0092\3\2\2\2\u01e4\u01e5\7/\2\2\u01e5"+
"\u01e6\7@\2\2\u01e6\u0094\3\2\2\2\u01e7\u01e8\7}\2\2\u01e8\u0096\3\2\2"+
"\2\u01e9\u01ea\7\177\2\2\u01ea\u0098\3\2\2\2\u01eb\u01ec\7A\2\2\u01ec"+
"\u009a\3\2\2\2\u01ed\u01ee\7k\2\2\u01ee\u01ef\7h\2\2\u01ef\u009c\3\2\2"+
"\2\u01f0\u01f1\7g\2\2\u01f1\u01f2\7n\2\2\u01f2\u01f3\7u\2\2\u01f3\u01f4"+
"\7g\2\2\u01f4\u009e\3\2\2\2\u01f5\u01f9\t\2\2\2\u01f6\u01f8\t\3\2\2\u01f7"+
"\u01f6\3\2\2\2\u01f8\u01fb\3\2\2\2\u01f9\u01f7\3\2\2\2\u01f9\u01fa\3\2"+
"\2\2\u01fa\u01fc\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fc\u01fd\5\u00a1Q\2\u01fd"+
"\u01fe\3\2\2\2\u01fe\u01ff\bP\2\2\u01ff\u00a0\3\2\2\2\u0200\u0204\7=\2"+
"\2\u0201\u0203\n\2\2\2\u0202\u0201\3\2\2\2\u0203\u0206\3\2\2\2\u0204\u0202"+
"\3\2\2\2\u0204\u0205\3\2\2\2\u0205\u0207\3\2\2\2\u0206\u0204\3\2\2\2\u0207"+
"\u0208\bQ\2\2\u0208\u00a2\3\2\2\2\u0209\u020a\t\3\2\2\u020a\u020b\3\2"+
"\2\2\u020b\u020c\bR\3\2\u020c\u00a4\3\2\2\2\u020d\u020f\t\2\2\2\u020e"+
"\u020d\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u020e\3\2\2\2\u0210\u0211\3\2"+
"\2\2\u0211\u00a6\3\2\2\2\u0212\u0216\t\4\2\2\u0213\u0215\t\5\2\2\u0214"+
"\u0213\3\2\2\2\u0215\u0218\3\2\2\2\u0216\u0214\3\2\2\2\u0216\u0217\3\2"+
"\2\2\u0217\u00a8\3\2\2\2\u0218\u0216\3\2\2\2\u0219\u0221\4\62;\2\u021a"+
"\u021c\4\63;\2\u021b\u021d\4\62;\2\u021c\u021b\3\2\2\2\u021d\u021e\3\2"+
"\2\2\u021e\u021c\3\2\2\2\u021e\u021f\3\2\2\2\u021f\u0221\3\2\2\2\u0220"+
"\u0219\3\2\2\2\u0220\u021a\3\2\2\2\u0221\u00aa\3\2\2\2\u0222\u0224\7&"+
"\2\2\u0223\u0225\t\6\2\2\u0224\u0223\3\2\2\2\u0225\u0226\3\2\2\2\u0226"+
"\u0224\3\2\2\2\u0226\u0227\3\2\2\2\u0227\u00ac\3\2\2\2\u0228\u022a\7\'"+
"\2\2\u0229\u022b\4\62\63\2\u022a\u0229\3\2\2\2\u022b\u022c\3\2\2\2\u022c"+
"\u022a\3\2\2\2\u022c\u022d\3\2\2\2\u022d\u00ae\3\2\2\2\u022e\u0234\5\u00b1"+
"Y\2\u022f\u0231\t\7\2\2\u0230\u0232\t\b\2\2\u0231\u0230\3\2\2\2\u0231"+
"\u0232\3\2\2\2\u0232\u0233\3\2\2\2\u0233\u0235\5\u00b1Y\2\u0234\u022f"+
"\3\2\2\2\u0234\u0235\3\2\2\2\u0235\u00b0\3\2\2\2\u0236\u0238\4\62;\2\u0237"+
"\u0236\3\2\2\2\u0238\u0239\3\2\2\2\u0239\u0237\3\2\2\2\u0239\u023a\3\2"+
"\2\2\u023a\u0241\3\2\2\2\u023b\u023d\7\60\2\2\u023c\u023e\4\62;\2\u023d"+
"\u023c\3\2\2\2\u023e\u023f\3\2\2\2\u023f\u023d\3\2\2\2\u023f\u0240\3\2"+
"\2\2\u0240\u0242\3\2\2\2\u0241\u023b\3\2\2\2\u0241\u0242\3\2\2\2\u0242"+
"\u00b2\3\2\2\2\u0243\u0244\7^\2\2\u0244\u0248\13\2\2\2\u0245\u0246\7^"+
"\2\2\u0246\u0248\5\u00a5S\2\u0247\u0243\3\2\2\2\u0247\u0245\3\2\2\2\u0248"+
"\u00b4\3\2\2\2\u0249\u024e\7$\2\2\u024a\u024d\5\u00b3Z\2\u024b\u024d\n"+
"\t\2\2\u024c\u024a\3\2\2\2\u024c\u024b\3\2\2\2\u024d\u0250\3\2\2\2\u024e"+
"\u024c\3\2\2\2\u024e\u024f\3\2\2\2\u024f\u0251\3\2\2\2\u0250\u024e\3\2"+
"\2\2\u0251\u0252\7$\2\2\u0252\u0253\b[\4\2\u0253\u00b6\3\2\2\2\u0254\u0255"+
"\7}\2\2\u0255\u0256\7}\2\2\u0256\u0258\3\2\2\2\u0257\u0259\13\2\2\2\u0258"+
"\u0257\3\2\2\2\u0259\u025a\3\2\2\2\u025a\u025b\3\2\2\2\u025a\u0258\3\2"+
"\2\2\u025b\u025c\3\2\2\2\u025c\u025d\7\177\2\2\u025d\u025e\7\177\2\2\u025e"+
"\u025f\3\2\2\2\u025f\u0260\b\\\5\2\u0260\u00b8\3\2\2\2\25\2\u01f9\u0204"+
"\u0210\u0216\u021e\u0220\u0224\u0226\u022c\u0231\u0234\u0239\u023f\u0241"+
"\u0247\u024c\u024e\u025a\6\2\3\2\b\2\2\3[\2\3\\\3";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -76,19 +76,17 @@ T__74=75
T__75=76
T__76=77
T__77=78
T__78=79
T__79=80
LINECOMMENT=81
COMMENT=82
WS=83
EOL=84
NAME=85
DEC_INTEGER=86
HEX_INTEGER=87
BIN_INTEGER=88
FLOAT_NUMBER=89
STRING=90
INLINEASMBLOCK=91
LINECOMMENT=79
COMMENT=80
WS=81
EOL=82
NAME=83
DEC_INTEGER=84
HEX_INTEGER=85
BIN_INTEGER=86
FLOAT_NUMBER=87
STRING=88
INLINEASMBLOCK=89
'~'=1
':'=2
'goto'=3
@ -131,41 +129,39 @@ INLINEASMBLOCK=91
'**'=40
'*'=41
'/'=42
'<<'=43
'>>'=44
'<'=45
'>'=46
'<='=47
'>='=48
'=='=49
'!='=50
'&'=51
'^'=52
'|'=53
'to'=54
'and'=55
'or'=56
'xor'=57
'not'=58
'return'=59
'.'=60
'A'=61
'X'=62
'Y'=63
'AX'=64
'AY'=65
'XY'=66
'Pc'=67
'Pz'=68
'Pn'=69
'Pv'=70
'true'=71
'false'=72
'%asm'=73
'sub'=74
'->'=75
'{'=76
'}'=77
'?'=78
'if'=79
'else'=80
'<'=43
'>'=44
'<='=45
'>='=46
'=='=47
'!='=48
'&'=49
'^'=50
'|'=51
'to'=52
'and'=53
'or'=54
'xor'=55
'not'=56
'return'=57
'.'=58
'A'=59
'X'=60
'Y'=61
'AX'=62
'AY'=63
'XY'=64
'Pc'=65
'Pz'=66
'Pn'=67
'Pv'=68
'true'=69
'false'=70
'%asm'=71
'sub'=72
'->'=73
'{'=74
'}'=75
'?'=76
'if'=77
'else'=78

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,11 @@ package il65.stackvm
import il65.ast.DataType
import il65.compiler.Mflpt5
import il65.compiler.Petscii
import java.io.FileOutputStream
import java.io.PrintWriter
import java.util.*
import kotlin.math.max
import kotlin.math.pow
enum class Opcode {
@ -21,29 +25,47 @@ enum class Opcode {
SUB,
MUL,
DIV,
POW,
NEG,
SHL,
SHL_MEM,
SHL_MEM_W,
SHL_LOCAL,
SHR,
SHR_MEM,
SHR_MEM_W,
SHR_LOCAL,
ROL,
ROL_MEM,
ROL_MEM_W,
ROL_LOCAL,
ROR,
ROR_MEM,
ROR_MEM_W,
ROR_LOCAL,
ROL2,
ROL2_MEM,
ROL2_MEM_W,
ROL2_LOCAL,
ROR2,
ROR2_MEM,
ROR2_MEM_W,
ROR2_LOCAL,
AND,
OR,
XOR,
INV,
// logical operations (?)
// increment, decrement
INC,
INC_MEM,
INC_MEM_W,
INC_MEM_F,
INC_LOCAL,
DEC,
DEC_MEM,
DEC_MEM_W,
DEC_MEM_F,
DEC_LOCAL,
// comparisons (?)
@ -57,12 +79,16 @@ enum class Opcode {
SYSCALL,
// misc
SEC,
CLC,
TERMINATE
}
enum class Syscall(val callNr: Short) {
WRITECHR(10),
WRITESTR(11)
WRITESTR(11),
WRITE_NUM(12),
WRITE_CHAR(13)
}
class Memory {
@ -99,189 +125,236 @@ class Memory {
fun getFloat(address: Int): Double {
return Mflpt5(mem[address], mem[address+1], mem[address+2], mem[address+3], mem[address+4]).toDouble()
}
fun setString(address: Int, str: String) {
// lowercase PETSCII
val petscii = Petscii.encodePetscii(str, true)
var addr = address
for (c in petscii) mem[addr++] = c
mem[addr] = 0
}
fun getString(strAddress: Int): String {
// lowercase PETSCII
val petscii = mutableListOf<Short>()
var addr = strAddress
while(true) {
val byte = mem[addr++]
if(byte==0.toShort()) break
petscii.add(byte)
}
return Petscii.decodePetscii(petscii, true)
}
}
data class Value(val type: DataType,
val byteval: Short?,
val wordval: Int?,
val floatval: Double?)
data class Value(val type: DataType, private val value: Number)
{
private var byteval: Short? = null
private var wordval: Int? = null
private var floatval: Double? = null
init {
when(type) {
DataType.BYTE -> byteval = (value.toInt() and 255).toShort()
DataType.WORD -> wordval = value.toInt() and 65535
DataType.FLOAT -> floatval = value.toDouble()
else -> throw VmExecutionException("invalid value datatype $type")
}
}
fun numericValue(): Number {
return when(type) {
DataType.BYTE -> byteval!!
DataType.WORD-> wordval!!
DataType.FLOAT -> floatval!!
else -> throw VmExecutionException("invalid datatype")
}
}
fun integerValue(): Int {
return when(type) {
DataType.BYTE -> byteval!!.toInt()
DataType.WORD-> wordval!!
DataType.FLOAT -> floatval!!.toInt()
else -> throw VmExecutionException("invalid datatype")
}
}
fun add(other: Value): Value {
val v1: Number = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
floatval!=null -> floatval
else -> throw VmExecutionException("add missing value 1")
}
val v2: Number = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
other.floatval!=null -> other.floatval
else -> throw VmExecutionException("add missing value 2")
}
val v1 = numericValue()
val v2 = other.numericValue()
val result = v1.toDouble() + v2.toDouble()
return resultvalue(type, result)
return Value(type, result)
}
fun sub(other: Value): Value {
val v1: Number = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
floatval!=null -> floatval
else -> throw VmExecutionException("sub missing value 1")
}
val v2: Number = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
other.floatval!=null -> other.floatval
else -> throw VmExecutionException("sub missing value 2")
}
val v1 = numericValue()
val v2 = other.numericValue()
val result = v1.toDouble() - v2.toDouble()
return resultvalue(type, result)
return Value(type, result)
}
fun mul(other: Value): Value {
val v1: Number = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
floatval!=null -> floatval
else -> throw VmExecutionException("mul missing value 1")
}
val v2: Number = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
other.floatval!=null -> other.floatval
else -> throw VmExecutionException("mul missing value 2")
}
val v1 = numericValue()
val v2 = other.numericValue()
val result = v1.toDouble() * v2.toDouble()
return resultvalue(type, result)
return Value(type, result)
}
fun div(other: Value): Value {
val v1: Number = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
floatval!=null -> floatval
else -> throw VmExecutionException("div missing value 1")
}
val v2: Number = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
other.floatval!=null -> other.floatval
else -> throw VmExecutionException("div missing value 2")
}
val v1 = numericValue()
val v2 = other.numericValue()
val result = v1.toDouble() / v2.toDouble()
return resultvalue(type, result)
return Value(type, result)
}
fun shl(other: Value): Value {
val v1 = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
else -> throw VmExecutionException("shl can only work on byte/word")
}
val v2 = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
else -> throw VmExecutionException("shl can only work on byte/word")
}
val result = v1.shl(v2)
return resultvalue(type, result)
fun pow(other: Value): Value {
val v1 = numericValue()
val v2 = other.numericValue()
val result = v1.toDouble().pow(v2.toDouble())
return Value(type, result)
}
fun shr(other: Value): Value {
val v1 = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
else -> throw VmExecutionException("shr can only work on byte/word")
}
val v2 = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
else -> throw VmExecutionException("shr can only work on byte/word")
}
val result = v1.ushr(v2)
return resultvalue(type, result)
fun shl(): Value {
val v = integerValue()
return Value(type, v.shl(1))
}
fun rol(other: Value): Value = TODO()
fun shr(): Value {
val v = integerValue()
return Value(type, v.ushr(1))
}
fun ror(other: Value): Value = TODO()
fun rol(carry: Boolean): Pair<Value, Boolean> {
// 9 or 17 bit rotate left (with carry))
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
val newCarry = (v and 0x80) != 0
val newval = (v and 0x7f shl 1) or (if(carry) 1 else 0)
Pair(Value(DataType.BYTE, newval), newCarry)
}
DataType.WORD -> {
val v = wordval!!
val newCarry = (v and 0x8000) != 0
val newval = (v and 0x7fff shl 1) or (if(carry) 1 else 0)
Pair(Value(DataType.WORD, newval), newCarry)
}
else -> throw VmExecutionException("rol can only work on byte/word")
}
}
fun ror(carry: Boolean): Pair<Value, Boolean> {
// 9 or 17 bit rotate right (with carry)
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
val newCarry = v and 1 != 0
val newval = (v ushr 1) or (if(carry) 0x80 else 0)
Pair(Value(DataType.BYTE, newval), newCarry)
}
DataType.WORD -> {
val v = wordval!!
val newCarry = v and 1 != 0
val newval = (v ushr 1) or (if(carry) 0x8000 else 0)
Pair(Value(DataType.WORD, newval), newCarry)
}
else -> throw VmExecutionException("ror2 can only work on byte/word")
}
}
fun rol2(): Value {
// 8 or 16 bit rotate left
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
val carry = (v and 0x80) ushr 7
val newval = (v and 0x7f shl 1) or carry
Value(DataType.BYTE, newval)
}
DataType.WORD -> {
val v = wordval!!
val carry = (v and 0x8000) ushr 15
val newval = (v and 0x7fff shl 1) or carry
Value(DataType.WORD, newval)
}
else -> throw VmExecutionException("rol2 can only work on byte/word")
}
}
fun ror2(): Value {
// 8 or 16 bit rotate right
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
val carry = v and 1 shl 7
val newval = (v ushr 1) or carry
Value(DataType.BYTE, newval)
}
DataType.WORD -> {
val v = wordval!!
val carry = v and 1 shl 15
val newval = (v ushr 1) or carry
Value(DataType.WORD, newval)
}
else -> throw VmExecutionException("ror2 can only work on byte/word")
}
}
fun neg(): Value {
return when {
byteval!=null -> resultvalue(DataType.BYTE, -byteval)
wordval!=null -> resultvalue(DataType.WORD, -wordval)
floatval!=null -> resultvalue(DataType.FLOAT, -floatval)
return when(type) {
DataType.BYTE -> Value(DataType.BYTE, -(byteval!!))
DataType.WORD -> Value(DataType.WORD, -(wordval!!))
DataType.FLOAT -> Value(DataType.FLOAT, -(floatval)!!)
else -> throw VmExecutionException("neg can only work on byte/word/float")
}
}
fun and(other: Value): Value {
val v1 = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
else -> throw VmExecutionException("and can only work on byte/word")
}
val v2 = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
else -> throw VmExecutionException("and can only work on byte/word")
}
val v1 = integerValue()
val v2 = other.integerValue()
val result = v1.and(v2)
return resultvalue(type, result)
return Value(type, result)
}
fun or(other: Value): Value {
val v1 = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
else -> throw VmExecutionException("or can only work on byte/word")
}
val v2 = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
else -> throw VmExecutionException("or can only work on byte/word")
}
val v1 = integerValue()
val v2 = other.integerValue()
val result = v1.or(v2)
return resultvalue(type, result)
return Value(type, result)
}
fun xor(other: Value): Value {
val v1 = when {
byteval!=null -> byteval.toInt()
wordval!=null -> wordval
else -> throw VmExecutionException("xor can only work on byte/word")
}
val v2 = when {
other.byteval!=null -> other.byteval.toInt()
other.wordval!=null -> other.wordval
else -> throw VmExecutionException("xor can only work on byte/word")
}
val v1 = integerValue()
val v2 = other.integerValue()
val result = v1.xor(v2)
return resultvalue(type, result)
return Value(type, result)
}
fun inv(): Value {
return when {
byteval!=null -> resultvalue(DataType.BYTE, byteval.toInt().inv())
wordval!=null -> resultvalue(DataType.WORD, wordval.inv())
return when(type) {
DataType.BYTE -> Value(DataType.BYTE, byteval!!.toInt().inv())
DataType.WORD -> Value(DataType.WORD, wordval!!.inv())
else -> throw VmExecutionException("not can only work on byte/word")
}
}
fun inc(): Value = TODO()
fun dec(): Value = TODO()
fun inc(): Value {
return when(type) {
DataType.BYTE -> Value(DataType.BYTE, (byteval!! + 1).and(255))
DataType.WORD -> Value(DataType.WORD, (wordval!! + 1).and(65535))
DataType.FLOAT -> Value(DataType.FLOAT, floatval!! + 1)
else -> throw VmExecutionException("inc can only work on byte/word/float")
}
}
private fun resultvalue(type: DataType, value: Number) : Value {
return when (type) {
DataType.BYTE -> Value(DataType.BYTE, value.toShort(), null, null)
DataType.WORD -> Value(DataType.WORD, null, value.toInt(), null)
DataType.FLOAT -> Value(DataType.FLOAT, null, null, value.toDouble())
else -> throw VmExecutionException("can only work on byte/word/float")
fun dec(): Value {
return when(type) {
DataType.BYTE -> Value(DataType.BYTE, (byteval!! - 1).and(255))
DataType.WORD -> Value(DataType.WORD, (wordval!! - 1).and(65535))
DataType.FLOAT -> Value(DataType.FLOAT, floatval!! - 1)
else -> throw VmExecutionException("dec can only work on byte/word/float")
}
}
}
@ -289,7 +362,7 @@ data class Value(val type: DataType,
data class Instruction(val opcode: Opcode, val args: List<Value>) {
lateinit var next: Instruction
lateinit var nextAlt: Instruction
var nextAlt: Instruction? = null
}
@ -297,83 +370,150 @@ private class VmExecutionException(msg: String?) : Exception(msg)
private class VmTerminationException(msg: String?) : Exception(msg)
private class MyStack<T> : Stack<T>() {
fun peek(amount: Int) : List<T> {
return this.toList().subList(max(0, size-amount), size)
}
class StackVm {
fun pop2() : Pair<T, T> = Pair(pop(), pop())
fun printTop(amount: Int) {
peek(amount).reversed().forEach { println(" $it") }
}
}
class Program {
var prog: List<Instruction> = listOf()
fun load(prog: List<Instruction>) {
this.prog = prog.plus(listOf(
Instruction(Opcode.TERMINATE, listOf()),
Instruction(Opcode.TERMINATE, listOf())
))
connectPointers()
}
fun connectPointers() {
val it1 = prog.iterator()
val it2 = prog.iterator()
it2.next()
while(it1.hasNext() && it2.hasNext()) {
val instr = it1.next()
val nextInstr = it2.next()
when(instr.opcode) {
Opcode.TERMINATE -> instr.next = instr
Opcode.CALL -> TODO()
Opcode.JUMP -> TODO()
Opcode.RETURN -> TODO()
else -> instr.next = nextInstr
}
}
}
}
class StackVm(val vmOutputFile: String) {
val mem = Memory()
private val es = Stack<Value>()
private val es = MyStack<Value>()
private var carry: Boolean = false
private var program = listOf<Instruction>()
private var output = PrintWriter(FileOutputStream(vmOutputFile, true))
fun run(program: Program) {
this.program = program.prog
var ins = this.program[0]
output.println("---- new session at ${Date()} ----")
try {
while (true) {
ins = dispatch(ins)
}
} catch (x: VmTerminationException) {
output.println("---- session ended ----")
output.flush()
output.close()
println("Execution terminated.")
}
}
fun dispatch(ins: Instruction) : Instruction {
when(ins.opcode) {
println("dispatching: $ins")
when (ins.opcode) {
Opcode.PUSH -> es.push(ins.args[0])
Opcode.DISCARD -> es.pop()
Opcode.POP_MEM -> {
val value = es.pop()
val address = ins.args[0].wordval!!
when(value.type) {
DataType.BYTE -> mem.setByte(address, value.byteval!!)
DataType.WORD -> mem.setWord(address, value.wordval!!)
DataType.FLOAT -> mem.setFloat(address, value.floatval!!)
val address = ins.args[0].integerValue()
when (value.type) {
DataType.BYTE -> mem.setByte(address, value.integerValue().toShort())
DataType.WORD -> mem.setWord(address, value.integerValue())
DataType.FLOAT -> mem.setFloat(address, value.numericValue().toDouble())
else -> throw VmExecutionException("can only manipulate byte/word/float on stack")
}
}
Opcode.ADD -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.add(v2))
val (top, second) = es.pop2()
es.push(second.add(top))
}
Opcode.SUB -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.sub(v2))
val (top, second) = es.pop2()
es.push(second.sub(top))
}
Opcode.MUL -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.mul(v2))
val (top, second) = es.pop2()
es.push(second.mul(top))
}
Opcode.DIV -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.div(v2))
val (top, second) = es.pop2()
es.push(second.div(top))
}
Opcode.POW -> {
val (top, second) = es.pop2()
es.push(second.pow(top))
}
Opcode.NEG -> {
val v = es.pop()
es.push(v.neg())
}
Opcode.SHL -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.shl(v2))
val v = es.pop()
es.push(v.shl())
}
Opcode.SHR -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.shr(v2))
val v = es.pop()
es.push(v.shr())
}
Opcode.ROL -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.rol(v2))
val v = es.pop()
val (result, newCarry) = v.rol(carry)
this.carry = newCarry
es.push(result)
}
Opcode.ROL2 -> {
val v = es.pop()
es.push(v.rol2())
}
Opcode.ROR -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.ror(v2))
val v = es.pop()
val (result, newCarry) = v.ror(carry)
this.carry = newCarry
es.push(result)
}
Opcode.ROR2 -> {
val v = es.pop()
es.push(v.ror2())
}
Opcode.AND -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.and(v2))
val (top, second) = es.pop2()
es.push(second.and(top))
}
Opcode.OR -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.or(v2))
val (top, second) = es.pop2()
es.push(second.or(top))
}
Opcode.XOR -> {
val v1 = es.pop()
val v2 = es.pop()
es.push(v1.xor(v2))
val (top, second) = es.pop2()
es.push(second.xor(top))
}
Opcode.INV -> {
val v = es.pop()
@ -387,48 +527,183 @@ class StackVm {
val v = es.pop()
es.push(v.dec())
}
Opcode.JUMP -> TODO()
Opcode.CALL -> TODO()
Opcode.RETURN -> TODO()
Opcode.SYSCALL -> {
val callId = ins.args[0].byteval
val syscall = Syscall.values().first { it.callNr==callId }
when(syscall){
Syscall.WRITECHR -> syscallWriteChr(ins.args[0].wordval!!)
Syscall.WRITESTR -> syscallWriteStr(ins.args[0].wordval!!)
val callId = ins.args[0].integerValue().toShort()
val syscall = Syscall.values().first { it.callNr == callId }
when (syscall) {
Syscall.WRITECHR -> output.print(Petscii.decodePetscii(listOf(mem.getByte(ins.args[1].integerValue())), true))
Syscall.WRITESTR -> output.print(mem.getString(ins.args[1].integerValue()))
Syscall.WRITE_NUM -> output.print(es.pop().numericValue())
Syscall.WRITE_CHAR -> output.print(Petscii.decodePetscii(listOf(es.pop().integerValue().toShort()), true))
else -> throw VmExecutionException("unimplemented syscall $syscall")
}
}
Opcode.SEC -> carry = true
Opcode.CLC -> carry = false
Opcode.TERMINATE -> throw VmTerminationException("execution terminated")
Opcode.INC_MEM -> {
val addr = ins.args[0].integerValue()
val newValue = Value(DataType.BYTE, mem.getByte(addr)).inc()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.INC_MEM_W -> {
val addr = ins.args[0].integerValue()
val newValue = Value(DataType.WORD, mem.getWord(addr)).inc()
mem.setWord(addr, newValue.integerValue())
}
Opcode.DEC_MEM -> {
val addr = ins.args[0].integerValue()
val newValue = Value(DataType.BYTE, mem.getByte(addr)).dec()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.DEC_MEM_W -> {
val addr = ins.args[0].integerValue()
val newValue = Value(DataType.WORD, mem.getWord(addr)).dec()
mem.setWord(addr, newValue.integerValue())
}
Opcode.SHL_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val newValue = value.shl()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.SHL_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val newValue = value.shl()
mem.setWord(addr, newValue.integerValue())
}
Opcode.SHR_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val newValue = value.shr()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.SHR_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val newValue = value.shr()
mem.setWord(addr, newValue.integerValue())
}
Opcode.ROL_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val (newValue, newCarry) = value.rol(carry)
mem.setByte(addr, newValue.integerValue().toShort())
carry = newCarry
}
Opcode.ROL_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val (newValue, newCarry) = value.rol(carry)
mem.setWord(addr, newValue.integerValue())
carry = newCarry
}
Opcode.ROR_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val (newValue, newCarry) = value.ror(carry)
mem.setByte(addr, newValue.integerValue().toShort())
carry = newCarry
}
Opcode.ROR_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val (newValue, newCarry) = value.ror(carry)
mem.setWord(addr, newValue.integerValue())
carry = newCarry
}
Opcode.ROL2_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val newValue = value.rol2()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.ROL2_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val newValue = value.rol2()
mem.setWord(addr, newValue.integerValue())
}
Opcode.ROR2_MEM -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.BYTE, mem.getByte(addr))
val newValue = value.ror2()
mem.setByte(addr, newValue.integerValue().toShort())
}
Opcode.ROR2_MEM_W -> {
val addr = ins.args[0].integerValue()
val value = Value(DataType.WORD, mem.getWord(addr))
val newValue = value.ror2()
mem.setWord(addr, newValue.integerValue())
}
Opcode.JUMP -> {} // do nothing; the next instruction is wired up already
Opcode.CALL -> TODO()
Opcode.RETURN -> TODO()
Opcode.PUSH_LOCAL -> TODO()
Opcode.POP_LOCAL -> TODO()
Opcode.INC_LOCAL -> TODO()
Opcode.DEC_LOCAL -> TODO()
Opcode.INC_MEM -> TODO()
Opcode.INC_MEM_W -> TODO()
Opcode.INC_MEM_F -> TODO()
Opcode.DEC_MEM -> TODO()
Opcode.DEC_MEM_W -> TODO()
Opcode.DEC_MEM_F -> TODO()
Opcode.SHL_LOCAL -> TODO()
Opcode.SHR_LOCAL -> TODO()
Opcode.ROL_LOCAL -> TODO()
Opcode.ROR_LOCAL -> TODO()
Opcode.ROL2_LOCAL -> TODO()
Opcode.ROR2_LOCAL -> TODO()
}
println(" es:")
es.printTop(5)
return ins.next
}
private fun syscallWriteStr(strAddress: Int) {
val petscii = mutableListOf<Short>()
var addr = strAddress
while(true) {
val byte = mem.getByte(addr++)
if(byte==0.toShort()) break
petscii.add(byte)
}
print(Petscii.decodePetscii(petscii, true))
}
private fun syscallWriteChr(strAddress: Int) {
val petscii = listOf(mem.getByte(strAddress))
print(Petscii.decodePetscii(petscii, true))
}
}
fun main(args: Array<String>) {
val vm = StackVm(vmOutputFile = "vmout.txt")
val program = Program()
program.load(listOf(
Instruction(Opcode.PUSH, listOf(Value(DataType.BYTE, 100))),
Instruction(Opcode.PUSH, listOf(Value(DataType.BYTE, 133))),
Instruction(Opcode.ADD, emptyList()),
Instruction(Opcode.PUSH, listOf(Value(DataType.BYTE, 3))),
Instruction(Opcode.DIV, emptyList()),
Instruction(Opcode.INC, emptyList()),
Instruction(Opcode.PUSH, listOf(Value(DataType.BYTE, 2))),
Instruction(Opcode.SHR, emptyList()),
Instruction(Opcode.SYSCALL, listOf(Value(DataType.BYTE, Syscall.WRITESTR.callNr), Value(DataType.WORD, 0x1000))),
Instruction(Opcode.SYSCALL, listOf(Value(DataType.BYTE, Syscall.WRITE_NUM.callNr))),
Instruction(Opcode.PUSH, listOf(Value(DataType.BYTE, Petscii.encodePetscii("@", true)[0]))),
Instruction(Opcode.SYSCALL, listOf(Value(DataType.BYTE, Syscall.WRITE_CHAR.callNr))),
Instruction(Opcode.CLC, emptyList()),
Instruction(Opcode.PUSH, listOf(Value(DataType.WORD, 2))),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.ROR2, emptyList()),
Instruction(Opcode.CLC, emptyList()),
Instruction(Opcode.PUSH, listOf(Value(DataType.WORD, 16384))),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList()),
Instruction(Opcode.ROL2, emptyList())
))
vm.mem.setString(0x1000, "Hallo!\n")
vm.run(program)
}