From 95b05d08b366ffb9f05afb2cce00fae11523c62e Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 10 Nov 2018 12:25:46 +0100 Subject: [PATCH] better solution for registerpair as subroutine param/returnvalue --- compiler/antlr/prog8.g4 | 6 +- compiler/src/prog8/ast/AST.kt | 25 +- compiler/src/prog8/ast/AstChecker.kt | 42 ++- compiler/src/prog8/parser/prog8Parser.java | 317 ++++++++++----------- 4 files changed, 200 insertions(+), 190 deletions(-) diff --git a/compiler/antlr/prog8.g4 b/compiler/antlr/prog8.g4 index 0052f0343..69b65deab 100644 --- a/compiler/antlr/prog8.g4 +++ b/compiler/antlr/prog8.g4 @@ -178,7 +178,7 @@ scoped_identifier : NAME ('.' NAME)+ ; register : 'A' | 'X' | 'Y' ; -registerpair : 'AX' | 'AY' | 'XY' ; +registerorpair : 'A' | 'X' | 'Y' | 'AX' | 'AY' | 'XY' ; // only used in subroutine params and returnvalues statusregister : 'Pc' | 'Pz' | 'Pn' | 'Pv' ; @@ -236,13 +236,13 @@ asmsub_address : '=' address=integerliteral ; asmsub_params : asmsub_param (',' EOL? asmsub_param)* ; -asmsub_param : identifier ':' datatype '@' (register | registerpair | statusregister); +asmsub_param : identifier ':' datatype '@' (registerorpair | statusregister); clobber : register (',' register)* ; asmsub_returns : asmsub_return (',' EOL? asmsub_return)* ; -asmsub_return : datatype '@' (register | registerpair | statusregister) ; +asmsub_return : datatype '@' (registerorpair | statusregister) ; if_stmt : 'if' expression EOL? (statement | statement_block) EOL? else_part? EOL ; // statement is constrained later diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index a38615995..8c1363d28 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -39,7 +39,10 @@ enum class Register { Y } -enum class Registerpair { +enum class RegisterOrPair { + A, + X, + Y, AX, AY, XY @@ -1418,7 +1421,7 @@ class InlineAssembly(val assembly: String, override val position: Position) : IS } -class RegisterOrStatusflag(val register: Register?, val statusflag: Statusflag?) +class RegisterOrStatusflag(val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?) class AnonymousScope(override var statements: MutableList, override val position: Position) : INameScope, IStatement { @@ -1711,8 +1714,8 @@ private fun prog8Parser.AsmsubroutineContext.toAst(): IStatement { val returns = asmsub_returns()?.toAst() ?: emptyList() val normalParameters = params.map { SubroutineParameter(it.name, it.type, it.position) } val normalReturnvalues = returns.map { it.type } - val paramRegisters = params.map { RegisterOrStatusflag(it.register, it.statusflag) } - val returnRegisters = returns.map { RegisterOrStatusflag(it.register, it.statusflag) } + val paramRegisters = params.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag) } + val returnRegisters = returns.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag) } val clobbers = clobber()?.toAst() ?: emptySet() val statements = statement_block()?.toAst() ?: mutableListOf() return Subroutine(name, normalParameters, normalReturnvalues, @@ -1721,14 +1724,12 @@ private fun prog8Parser.AsmsubroutineContext.toAst(): IStatement { private class AsmSubroutineParameter(name: String, type: DataType, - val register: Register?, - val registerpair: Registerpair?, + val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, position: Position) : SubroutineParameter(name, type, position) private class AsmSubroutineReturn(val type: DataType, - val register: Register?, - val registerpair: Registerpair?, + val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, val position: Position) @@ -1737,11 +1738,11 @@ private fun prog8Parser.ClobberContext.toAst(): Set private fun prog8Parser.Asmsub_returnsContext.toAst(): List - = asmsub_return().map { AsmSubroutineReturn(it.datatype().toAst(), it.register()?.toAst(), it.registerpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) } + = asmsub_return().map { AsmSubroutineReturn(it.datatype().toAst(), it.registerorpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) } private fun prog8Parser.Asmsub_paramsContext.toAst(): List - = asmsub_param().map { AsmSubroutineParameter(it.identifier().text, it.datatype().toAst(), it.register()?.toAst(), it.registerpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) } + = asmsub_param().map { AsmSubroutineParameter(it.identifier().text, it.datatype().toAst(), it.registerorpair()?.toAst(), it.statusregister()?.toAst(), toPosition()) } private fun prog8Parser.StatusregisterContext.toAst() = Statusflag.valueOf(text) @@ -1828,10 +1829,10 @@ private fun prog8Parser.Assign_targetContext.toAst() : AssignTarget { private fun prog8Parser.RegisterContext.toAst() = Register.valueOf(text.toUpperCase()) -private fun prog8Parser.RegisterpairContext.toAst() = Registerpair.valueOf(text.toUpperCase()) - private fun prog8Parser.DatatypeContext.toAst() = DataType.valueOf(text.toUpperCase()) +private fun prog8Parser.RegisterorpairContext.toAst() = RegisterOrPair.valueOf(text.toUpperCase()) + private fun prog8Parser.ArrayspecContext.toAst() : ArraySpec = ArraySpec(expression().toAst(), toPosition()) diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index b70450549..0c81194ad 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -230,16 +230,26 @@ class AstChecker(private val namespace: INameScope, if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size) err("number of return registers is not the same as number of return values") for(param in subroutine.parameters.zip(subroutine.asmParameterRegisters)) { - if(param.second.register!=null || param.second.statusflag!=null) { + if(param.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) + if(param.first.type!=DataType.UBYTE) + err("parameter '${param.first.name}' should be ubyte") + else if(param.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) + if(param.first.type!=DataType.UWORD) + err("parameter '${param.first.name}' should be uword") + else if(param.second.statusflag!=null) if(param.first.type!=DataType.UBYTE) err("parameter '${param.first.name}' should be ubyte") - } } for(ret in subroutine.returntypes.withIndex().zip(subroutine.asmReturnvaluesRegisters)) { - if(ret.second.register!=null || ret.second.statusflag!=null) { + if(ret.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) + if(ret.first.value!=DataType.UBYTE) + err("return value #${ret.first.index+1} should be ubyte") + else if(ret.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) + if(ret.first.value!=DataType.UWORD) + err("return value #${ret.first.index+1} should be uword") + else if(ret.second.statusflag!=null) if(ret.first.value!=DataType.UBYTE) err("return value #${ret.first.index+1} should be ubyte") - } } val regCounts = mutableMapOf().withDefault { 0 } @@ -248,10 +258,26 @@ class AstChecker(private val namespace: INameScope, regCounts.clear() statusflagCounts.clear() for(p in from) { - if (p.register != null) - regCounts[p.register] = regCounts.getValue(p.register) + 1 - else if(p.statusflag!=null) - statusflagCounts[p.statusflag] = statusflagCounts.getValue(p.statusflag) + 1 + when(p.registerOrPair) { + RegisterOrPair.A -> regCounts[Register.A]=regCounts.getValue(Register.A)+1 + RegisterOrPair.X -> regCounts[Register.X]=regCounts.getValue(Register.X)+1 + RegisterOrPair.Y -> regCounts[Register.Y]=regCounts.getValue(Register.Y)+1 + RegisterOrPair.AX -> { + regCounts[Register.A]=regCounts.getValue(Register.A)+1 + regCounts[Register.X]=regCounts.getValue(Register.X)+1 + } + RegisterOrPair.AY -> { + regCounts[Register.A]=regCounts.getValue(Register.A)+1 + regCounts[Register.Y]=regCounts.getValue(Register.Y)+1 + } + RegisterOrPair.XY -> { + regCounts[Register.X]=regCounts.getValue(Register.X)+1 + regCounts[Register.Y]=regCounts.getValue(Register.Y)+1 + } + null -> + if(p.statusflag!=null) + statusflagCounts[p.statusflag] = statusflagCounts.getValue(p.statusflag) + 1 + } } } countRegisters(subroutine.asmParameterRegisters) diff --git a/compiler/src/prog8/parser/prog8Parser.java b/compiler/src/prog8/parser/prog8Parser.java index 3af96d1e0..659d73288 100644 --- a/compiler/src/prog8/parser/prog8Parser.java +++ b/compiler/src/prog8/parser/prog8Parser.java @@ -44,7 +44,7 @@ public class prog8Parser extends Parser { RULE_arrayindexed = 19, RULE_functioncall = 20, RULE_functioncall_stmt = 21, RULE_expression_list = 22, RULE_returnstmt = 23, RULE_breakstmt = 24, RULE_continuestmt = 25, RULE_identifier = 26, RULE_scoped_identifier = 27, - RULE_register = 28, RULE_registerpair = 29, RULE_statusregister = 30, + RULE_register = 28, RULE_registerorpair = 29, RULE_statusregister = 30, RULE_integerliteral = 31, RULE_wordsuffix = 32, RULE_booleanliteral = 33, RULE_arrayliteral = 34, RULE_stringliteral = 35, RULE_charliteral = 36, RULE_floatliteral = 37, RULE_literalvalue = 38, RULE_inlineasm = 39, RULE_subroutine = 40, @@ -59,7 +59,7 @@ public class prog8Parser extends Parser { "memoryvardecl", "datatype", "arrayspec", "assignment", "augassignment", "assign_target", "postincrdecr", "expression", "arrayindexed", "functioncall", "functioncall_stmt", "expression_list", "returnstmt", "breakstmt", "continuestmt", - "identifier", "scoped_identifier", "register", "registerpair", "statusregister", + "identifier", "scoped_identifier", "register", "registerorpair", "statusregister", "integerliteral", "wordsuffix", "booleanliteral", "arrayliteral", "stringliteral", "charliteral", "floatliteral", "literalvalue", "inlineasm", "subroutine", "sub_return_part", "statement_block", "sub_params", "sub_param", "sub_returns", @@ -2110,23 +2110,23 @@ public class prog8Parser extends Parser { return _localctx; } - public static class RegisterpairContext extends ParserRuleContext { - public RegisterpairContext(ParserRuleContext parent, int invokingState) { + public static class RegisterorpairContext extends ParserRuleContext { + public RegisterorpairContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } - @Override public int getRuleIndex() { return RULE_registerpair; } + @Override public int getRuleIndex() { return RULE_registerorpair; } } - public final RegisterpairContext registerpair() throws RecognitionException { - RegisterpairContext _localctx = new RegisterpairContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_registerpair); + public final RegisterorpairContext registerorpair() throws RecognitionException { + RegisterorpairContext _localctx = new RegisterorpairContext(_ctx, getState()); + enterRule(_localctx, 58, RULE_registerorpair); int _la; try { enterOuterAlt(_localctx, 1); { setState(354); _la = _input.LA(1); - if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (T__70 - 71)) | (1L << (T__71 - 71)) | (1L << (T__72 - 71)))) != 0)) ) { + if ( !(((((_la - 68)) & ~0x3f) == 0 && ((1L << (_la - 68)) & ((1L << (T__67 - 68)) | (1L << (T__68 - 68)) | (1L << (T__69 - 68)) | (1L << (T__70 - 68)) | (1L << (T__71 - 68)) | (1L << (T__72 - 68)))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -3217,11 +3217,8 @@ public class prog8Parser extends Parser { public DatatypeContext datatype() { return getRuleContext(DatatypeContext.class,0); } - public RegisterContext register() { - return getRuleContext(RegisterContext.class,0); - } - public RegisterpairContext registerpair() { - return getRuleContext(RegisterpairContext.class,0); + public RegisterorpairContext registerorpair() { + return getRuleContext(RegisterorpairContext.class,0); } public StatusregisterContext statusregister() { return getRuleContext(StatusregisterContext.class,0); @@ -3246,23 +3243,18 @@ public class prog8Parser extends Parser { datatype(); setState(497); match(T__87); - setState(501); + setState(500); _errHandler.sync(this); switch (_input.LA(1)) { case T__67: case T__68: case T__69: - { - setState(498); - register(); - } - break; case T__70: case T__71: case T__72: { - setState(499); - registerpair(); + setState(498); + registerorpair(); } break; case T__73: @@ -3270,7 +3262,7 @@ public class prog8Parser extends Parser { case T__75: case T__76: { - setState(500); + setState(499); statusregister(); } break; @@ -3310,21 +3302,21 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(503); + setState(502); register(); - setState(508); + setState(507); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__13) { { { - setState(504); + setState(503); match(T__13); - setState(505); + setState(504); register(); } } - setState(510); + setState(509); _errHandler.sync(this); _la = _input.LA(1); } @@ -3365,31 +3357,31 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(511); + setState(510); asmsub_return(); - setState(519); + setState(518); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__13) { { { - setState(512); + setState(511); match(T__13); - setState(514); + setState(513); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(513); + setState(512); match(EOL); } } - setState(516); + setState(515); asmsub_return(); } } - setState(521); + setState(520); _errHandler.sync(this); _la = _input.LA(1); } @@ -3410,11 +3402,8 @@ public class prog8Parser extends Parser { public DatatypeContext datatype() { return getRuleContext(DatatypeContext.class,0); } - public RegisterContext register() { - return getRuleContext(RegisterContext.class,0); - } - public RegisterpairContext registerpair() { - return getRuleContext(RegisterpairContext.class,0); + public RegisterorpairContext registerorpair() { + return getRuleContext(RegisterorpairContext.class,0); } public StatusregisterContext statusregister() { return getRuleContext(StatusregisterContext.class,0); @@ -3431,27 +3420,22 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(522); + setState(521); datatype(); - setState(523); + setState(522); match(T__87); - setState(527); + setState(525); _errHandler.sync(this); switch (_input.LA(1)) { case T__67: case T__68: case T__69: - { - setState(524); - register(); - } - break; case T__70: case T__71: case T__72: { - setState(525); - registerpair(); + setState(523); + registerorpair(); } break; case T__73: @@ -3459,7 +3443,7 @@ public class prog8Parser extends Parser { case T__75: case T__76: { - setState(526); + setState(524); statusregister(); } break; @@ -3509,21 +3493,21 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(529); + setState(527); match(T__88); - setState(530); + setState(528); expression(0); - setState(532); + setState(530); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(531); + setState(529); match(EOL); } } - setState(536); + setState(534); _errHandler.sync(this); switch (_input.LA(1)) { case T__2: @@ -3575,40 +3559,40 @@ public class prog8Parser extends Parser { case T__105: case NAME: { - setState(534); + setState(532); statement(); } break; case T__83: { - setState(535); + setState(533); statement_block(); } break; default: throw new NoViableAltException(this); } - setState(539); + setState(537); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,53,_ctx) ) { case 1: { - setState(538); + setState(536); match(EOL); } break; } - setState(542); + setState(540); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__89) { { - setState(541); + setState(539); else_part(); } } - setState(544); + setState(542); match(EOL); } } @@ -3644,19 +3628,19 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(546); + setState(544); match(T__89); - setState(548); + setState(546); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(547); + setState(545); match(EOL); } } - setState(552); + setState(550); _errHandler.sync(this); switch (_input.LA(1)) { case T__2: @@ -3708,13 +3692,13 @@ public class prog8Parser extends Parser { case T__105: case NAME: { - setState(550); + setState(548); statement(); } break; case T__83: { - setState(551); + setState(549); statement_block(); } break; @@ -3764,19 +3748,19 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(554); + setState(552); branchcondition(); - setState(556); + setState(554); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(555); + setState(553); match(EOL); } } - setState(560); + setState(558); _errHandler.sync(this); switch (_input.LA(1)) { case T__2: @@ -3828,40 +3812,40 @@ public class prog8Parser extends Parser { case T__105: case NAME: { - setState(558); + setState(556); statement(); } break; case T__83: { - setState(559); + setState(557); statement_block(); } break; default: throw new NoViableAltException(this); } - setState(563); + setState(561); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,59,_ctx) ) { case 1: { - setState(562); + setState(560); match(EOL); } break; } - setState(566); + setState(564); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__89) { { - setState(565); + setState(563); else_part(); } } - setState(568); + setState(566); match(EOL); } } @@ -3890,7 +3874,7 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(570); + setState(568); _la = _input.LA(1); if ( !(((((_la - 91)) & ~0x3f) == 0 && ((1L << (_la - 91)) & ((1L << (T__90 - 91)) | (1L << (T__91 - 91)) | (1L << (T__92 - 91)) | (1L << (T__93 - 91)) | (1L << (T__94 - 91)) | (1L << (T__95 - 91)) | (1L << (T__96 - 91)) | (1L << (T__97 - 91)) | (1L << (T__98 - 91)) | (1L << (T__99 - 91)) | (1L << (T__100 - 91)) | (1L << (T__101 - 91)))) != 0)) ) { _errHandler.recoverInline(this); @@ -3943,53 +3927,53 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(572); + setState(570); match(T__102); - setState(574); + setState(572); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__17) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25))) != 0)) { { - setState(573); + setState(571); datatype(); } } - setState(578); + setState(576); _errHandler.sync(this); switch (_input.LA(1)) { case T__67: case T__68: case T__69: { - setState(576); + setState(574); register(); } break; case NAME: { - setState(577); + setState(575); identifier(); } break; default: throw new NoViableAltException(this); } - setState(580); + setState(578); match(T__103); - setState(581); + setState(579); expression(0); - setState(583); + setState(581); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(582); + setState(580); match(EOL); } } - setState(585); + setState(583); statement_block(); } } @@ -4028,21 +4012,21 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(587); + setState(585); match(T__104); - setState(588); + setState(586); expression(0); - setState(590); + setState(588); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(589); + setState(587); match(EOL); } } - setState(594); + setState(592); _errHandler.sync(this); switch (_input.LA(1)) { case T__2: @@ -4094,13 +4078,13 @@ public class prog8Parser extends Parser { case T__105: case NAME: { - setState(592); + setState(590); statement(); } break; case T__83: { - setState(593); + setState(591); statement_block(); } break; @@ -4144,9 +4128,9 @@ public class prog8Parser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(596); + setState(594); match(T__105); - setState(599); + setState(597); _errHandler.sync(this); switch (_input.LA(1)) { case T__2: @@ -4198,32 +4182,32 @@ public class prog8Parser extends Parser { case T__105: case NAME: { - setState(597); + setState(595); statement(); } break; case T__83: { - setState(598); + setState(596); statement_block(); } break; default: throw new NoViableAltException(this); } - setState(602); + setState(600); _errHandler.sync(this); _la = _input.LA(1); if (_la==EOL) { { - setState(601); + setState(599); match(EOL); } } - setState(604); + setState(602); match(T__106); - setState(605); + setState(603); expression(0); } } @@ -4276,7 +4260,7 @@ public class prog8Parser extends Parser { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3y\u0262\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3y\u0260\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"+ @@ -4311,22 +4295,22 @@ public class prog8Parser extends Parser { "\13/\3\60\3\60\3\60\3\60\5\60\u01cf\n\60\3\60\3\60\3\60\3\60\3\60\5\60"+ "\u01d6\n\60\3\60\3\60\3\60\3\60\5\60\u01dc\n\60\3\60\3\60\3\60\5\60\u01e1"+ "\n\60\3\61\3\61\3\61\3\62\3\62\3\62\5\62\u01e9\n\62\3\62\7\62\u01ec\n"+ - "\62\f\62\16\62\u01ef\13\62\3\63\3\63\3\63\3\63\3\63\3\63\3\63\5\63\u01f8"+ - "\n\63\3\64\3\64\3\64\7\64\u01fd\n\64\f\64\16\64\u0200\13\64\3\65\3\65"+ - "\3\65\5\65\u0205\n\65\3\65\7\65\u0208\n\65\f\65\16\65\u020b\13\65\3\66"+ - "\3\66\3\66\3\66\3\66\5\66\u0212\n\66\3\67\3\67\3\67\5\67\u0217\n\67\3"+ - "\67\3\67\5\67\u021b\n\67\3\67\5\67\u021e\n\67\3\67\5\67\u0221\n\67\3\67"+ - "\3\67\38\38\58\u0227\n8\38\38\58\u022b\n8\39\39\59\u022f\n9\39\39\59\u0233"+ - "\n9\39\59\u0236\n9\39\59\u0239\n9\39\39\3:\3:\3;\3;\5;\u0241\n;\3;\3;"+ - "\5;\u0245\n;\3;\3;\3;\5;\u024a\n;\3;\3;\3<\3<\3<\5<\u0251\n<\3<\3<\5<"+ - "\u0255\n<\3=\3=\3=\5=\u025a\n=\3=\5=\u025d\n=\3=\3=\3=\3=\2\3&>\2\4\6"+ - "\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRT"+ - "VXZ\\^`bdfhjlnprtvx\2\21\3\2\6\17\3\2\24\34\3\2\37\'\3\2()\4\2\3\3,-\3"+ - "\2/\62\3\2,-\3\2\63\66\3\2\678\3\2FH\3\2IK\3\2LO\3\2su\3\2QR\3\2]h\2\u0298"+ - "\2~\3\2\2\2\4\u0085\3\2\2\2\6\u0087\3\2\2\2\b\u00a5\3\2\2\2\n\u00a7\3"+ - "\2\2\2\f\u00aa\3\2\2\2\16\u00b0\3\2\2\2\20\u00c1\3\2\2\2\22\u00c3\3\2"+ - "\2\2\24\u00c9\3\2\2\2\26\u00d1\3\2\2\2\30\u00d4\3\2\2\2\32\u00d7\3\2\2"+ - "\2\34\u00d9\3\2\2\2\36\u00dd\3\2\2\2 \u00e1\3\2\2\2\"\u00e9\3\2\2\2$\u00eb"+ + "\62\f\62\16\62\u01ef\13\62\3\63\3\63\3\63\3\63\3\63\3\63\5\63\u01f7\n"+ + "\63\3\64\3\64\3\64\7\64\u01fc\n\64\f\64\16\64\u01ff\13\64\3\65\3\65\3"+ + "\65\5\65\u0204\n\65\3\65\7\65\u0207\n\65\f\65\16\65\u020a\13\65\3\66\3"+ + "\66\3\66\3\66\5\66\u0210\n\66\3\67\3\67\3\67\5\67\u0215\n\67\3\67\3\67"+ + "\5\67\u0219\n\67\3\67\5\67\u021c\n\67\3\67\5\67\u021f\n\67\3\67\3\67\3"+ + "8\38\58\u0225\n8\38\38\58\u0229\n8\39\39\59\u022d\n9\39\39\59\u0231\n"+ + "9\39\59\u0234\n9\39\59\u0237\n9\39\39\3:\3:\3;\3;\5;\u023f\n;\3;\3;\5"+ + ";\u0243\n;\3;\3;\3;\5;\u0248\n;\3;\3;\3<\3<\3<\5<\u024f\n<\3<\3<\5<\u0253"+ + "\n<\3=\3=\3=\5=\u0258\n=\3=\5=\u025b\n=\3=\3=\3=\3=\2\3&>\2\4\6\b\n\f"+ + "\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^"+ + "`bdfhjlnprtvx\2\21\3\2\6\17\3\2\24\34\3\2\37\'\3\2()\4\2\3\3,-\3\2/\62"+ + "\3\2,-\3\2\63\66\3\2\678\3\2FH\3\2FK\3\2LO\3\2su\3\2QR\3\2]h\2\u0294\2"+ + "~\3\2\2\2\4\u0085\3\2\2\2\6\u0087\3\2\2\2\b\u00a5\3\2\2\2\n\u00a7\3\2"+ + "\2\2\f\u00aa\3\2\2\2\16\u00b0\3\2\2\2\20\u00c1\3\2\2\2\22\u00c3\3\2\2"+ + "\2\24\u00c9\3\2\2\2\26\u00d1\3\2\2\2\30\u00d4\3\2\2\2\32\u00d7\3\2\2\2"+ + "\34\u00d9\3\2\2\2\36\u00dd\3\2\2\2 \u00e1\3\2\2\2\"\u00e9\3\2\2\2$\u00eb"+ "\3\2\2\2&\u00fd\3\2\2\2(\u012e\3\2\2\2*\u0134\3\2\2\2,\u013e\3\2\2\2."+ "\u0146\3\2\2\2\60\u0151\3\2\2\2\62\u0155\3\2\2\2\64\u0157\3\2\2\2\66\u0159"+ "\3\2\2\28\u015b\3\2\2\2:\u0162\3\2\2\2<\u0164\3\2\2\2>\u0166\3\2\2\2@"+ @@ -4334,9 +4318,9 @@ public class prog8Parser extends Parser { "\2\2J\u0186\3\2\2\2L\u0188\3\2\2\2N\u0190\3\2\2\2P\u0192\3\2\2\2R\u0195"+ "\3\2\2\2T\u01a2\3\2\2\2V\u01a5\3\2\2\2X\u01b0\3\2\2\2Z\u01bb\3\2\2\2\\"+ "\u01bf\3\2\2\2^\u01ca\3\2\2\2`\u01e2\3\2\2\2b\u01e5\3\2\2\2d\u01f0\3\2"+ - "\2\2f\u01f9\3\2\2\2h\u0201\3\2\2\2j\u020c\3\2\2\2l\u0213\3\2\2\2n\u0224"+ - "\3\2\2\2p\u022c\3\2\2\2r\u023c\3\2\2\2t\u023e\3\2\2\2v\u024d\3\2\2\2x"+ - "\u0256\3\2\2\2z}\5\4\3\2{}\7q\2\2|z\3\2\2\2|{\3\2\2\2}\u0080\3\2\2\2~"+ + "\2\2f\u01f8\3\2\2\2h\u0200\3\2\2\2j\u020b\3\2\2\2l\u0211\3\2\2\2n\u0222"+ + "\3\2\2\2p\u022a\3\2\2\2r\u023a\3\2\2\2t\u023c\3\2\2\2v\u024b\3\2\2\2x"+ + "\u0254\3\2\2\2z}\5\4\3\2{}\7q\2\2|z\3\2\2\2|{\3\2\2\2}\u0080\3\2\2\2~"+ "|\3\2\2\2~\177\3\2\2\2\177\u0081\3\2\2\2\u0080~\3\2\2\2\u0081\u0082\7"+ "\2\2\3\u0082\3\3\2\2\2\u0083\u0086\5\16\b\2\u0084\u0086\5\6\4\2\u0085"+ "\u0083\3\2\2\2\u0085\u0084\3\2\2\2\u0086\5\3\2\2\2\u0087\u0088\7\3\2\2"+ @@ -4464,49 +4448,48 @@ public class prog8Parser extends Parser { "\u01e9\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01ec\5d\63\2\u01eb\u01e6\3\2"+ "\2\2\u01ec\u01ef\3\2\2\2\u01ed\u01eb\3\2\2\2\u01ed\u01ee\3\2\2\2\u01ee"+ "c\3\2\2\2\u01ef\u01ed\3\2\2\2\u01f0\u01f1\5\66\34\2\u01f1\u01f2\7\4\2"+ - "\2\u01f2\u01f3\5\32\16\2\u01f3\u01f7\7Z\2\2\u01f4\u01f8\5:\36\2\u01f5"+ - "\u01f8\5<\37\2\u01f6\u01f8\5> \2\u01f7\u01f4\3\2\2\2\u01f7\u01f5\3\2\2"+ - "\2\u01f7\u01f6\3\2\2\2\u01f8e\3\2\2\2\u01f9\u01fe\5:\36\2\u01fa\u01fb"+ - "\7\20\2\2\u01fb\u01fd\5:\36\2\u01fc\u01fa\3\2\2\2\u01fd\u0200\3\2\2\2"+ - "\u01fe\u01fc\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ffg\3\2\2\2\u0200\u01fe\3"+ - "\2\2\2\u0201\u0209\5j\66\2\u0202\u0204\7\20\2\2\u0203\u0205\7q\2\2\u0204"+ - "\u0203\3\2\2\2\u0204\u0205\3\2\2\2\u0205\u0206\3\2\2\2\u0206\u0208\5j"+ - "\66\2\u0207\u0202\3\2\2\2\u0208\u020b\3\2\2\2\u0209\u0207\3\2\2\2\u0209"+ - "\u020a\3\2\2\2\u020ai\3\2\2\2\u020b\u0209\3\2\2\2\u020c\u020d\5\32\16"+ - "\2\u020d\u0211\7Z\2\2\u020e\u0212\5:\36\2\u020f\u0212\5<\37\2\u0210\u0212"+ - "\5> \2\u0211\u020e\3\2\2\2\u0211\u020f\3\2\2\2\u0211\u0210\3\2\2\2\u0212"+ - "k\3\2\2\2\u0213\u0214\7[\2\2\u0214\u0216\5&\24\2\u0215\u0217\7q\2\2\u0216"+ - "\u0215\3\2\2\2\u0216\u0217\3\2\2\2\u0217\u021a\3\2\2\2\u0218\u021b\5\b"+ - "\5\2\u0219\u021b\5V,\2\u021a\u0218\3\2\2\2\u021a\u0219\3\2\2\2\u021b\u021d"+ - "\3\2\2\2\u021c\u021e\7q\2\2\u021d\u021c\3\2\2\2\u021d\u021e\3\2\2\2\u021e"+ - "\u0220\3\2\2\2\u021f\u0221\5n8\2\u0220\u021f\3\2\2\2\u0220\u0221\3\2\2"+ - "\2\u0221\u0222\3\2\2\2\u0222\u0223\7q\2\2\u0223m\3\2\2\2\u0224\u0226\7"+ - "\\\2\2\u0225\u0227\7q\2\2\u0226\u0225\3\2\2\2\u0226\u0227\3\2\2\2\u0227"+ - "\u022a\3\2\2\2\u0228\u022b\5\b\5\2\u0229\u022b\5V,\2\u022a\u0228\3\2\2"+ - "\2\u022a\u0229\3\2\2\2\u022bo\3\2\2\2\u022c\u022e\5r:\2\u022d\u022f\7"+ - "q\2\2\u022e\u022d\3\2\2\2\u022e\u022f\3\2\2\2\u022f\u0232\3\2\2\2\u0230"+ - "\u0233\5\b\5\2\u0231\u0233\5V,\2\u0232\u0230\3\2\2\2\u0232\u0231\3\2\2"+ - "\2\u0233\u0235\3\2\2\2\u0234\u0236\7q\2\2\u0235\u0234\3\2\2\2\u0235\u0236"+ - "\3\2\2\2\u0236\u0238\3\2\2\2\u0237\u0239\5n8\2\u0238\u0237\3\2\2\2\u0238"+ - "\u0239\3\2\2\2\u0239\u023a\3\2\2\2\u023a\u023b\7q\2\2\u023bq\3\2\2\2\u023c"+ - "\u023d\t\20\2\2\u023ds\3\2\2\2\u023e\u0240\7i\2\2\u023f\u0241\5\32\16"+ - "\2\u0240\u023f\3\2\2\2\u0240\u0241\3\2\2\2\u0241\u0244\3\2\2\2\u0242\u0245"+ - "\5:\36\2\u0243\u0245\5\66\34\2\u0244\u0242\3\2\2\2\u0244\u0243\3\2\2\2"+ - "\u0245\u0246\3\2\2\2\u0246\u0247\7j\2\2\u0247\u0249\5&\24\2\u0248\u024a"+ - "\7q\2\2\u0249\u0248\3\2\2\2\u0249\u024a\3\2\2\2\u024a\u024b\3\2\2\2\u024b"+ - "\u024c\5V,\2\u024cu\3\2\2\2\u024d\u024e\7k\2\2\u024e\u0250\5&\24\2\u024f"+ - "\u0251\7q\2\2\u0250\u024f\3\2\2\2\u0250\u0251\3\2\2\2\u0251\u0254\3\2"+ - "\2\2\u0252\u0255\5\b\5\2\u0253\u0255\5V,\2\u0254\u0252\3\2\2\2\u0254\u0253"+ - "\3\2\2\2\u0255w\3\2\2\2\u0256\u0259\7l\2\2\u0257\u025a\5\b\5\2\u0258\u025a"+ - "\5V,\2\u0259\u0257\3\2\2\2\u0259\u0258\3\2\2\2\u025a\u025c\3\2\2\2\u025b"+ - "\u025d\7q\2\2\u025c\u025b\3\2\2\2\u025c\u025d\3\2\2\2\u025d\u025e\3\2"+ - "\2\2\u025e\u025f\7m\2\2\u025f\u0260\5&\24\2\u0260y\3\2\2\2F|~\u0085\u008a"+ + "\2\u01f2\u01f3\5\32\16\2\u01f3\u01f6\7Z\2\2\u01f4\u01f7\5<\37\2\u01f5"+ + "\u01f7\5> \2\u01f6\u01f4\3\2\2\2\u01f6\u01f5\3\2\2\2\u01f7e\3\2\2\2\u01f8"+ + "\u01fd\5:\36\2\u01f9\u01fa\7\20\2\2\u01fa\u01fc\5:\36\2\u01fb\u01f9\3"+ + "\2\2\2\u01fc\u01ff\3\2\2\2\u01fd\u01fb\3\2\2\2\u01fd\u01fe\3\2\2\2\u01fe"+ + "g\3\2\2\2\u01ff\u01fd\3\2\2\2\u0200\u0208\5j\66\2\u0201\u0203\7\20\2\2"+ + "\u0202\u0204\7q\2\2\u0203\u0202\3\2\2\2\u0203\u0204\3\2\2\2\u0204\u0205"+ + "\3\2\2\2\u0205\u0207\5j\66\2\u0206\u0201\3\2\2\2\u0207\u020a\3\2\2\2\u0208"+ + "\u0206\3\2\2\2\u0208\u0209\3\2\2\2\u0209i\3\2\2\2\u020a\u0208\3\2\2\2"+ + "\u020b\u020c\5\32\16\2\u020c\u020f\7Z\2\2\u020d\u0210\5<\37\2\u020e\u0210"+ + "\5> \2\u020f\u020d\3\2\2\2\u020f\u020e\3\2\2\2\u0210k\3\2\2\2\u0211\u0212"+ + "\7[\2\2\u0212\u0214\5&\24\2\u0213\u0215\7q\2\2\u0214\u0213\3\2\2\2\u0214"+ + "\u0215\3\2\2\2\u0215\u0218\3\2\2\2\u0216\u0219\5\b\5\2\u0217\u0219\5V"+ + ",\2\u0218\u0216\3\2\2\2\u0218\u0217\3\2\2\2\u0219\u021b\3\2\2\2\u021a"+ + "\u021c\7q\2\2\u021b\u021a\3\2\2\2\u021b\u021c\3\2\2\2\u021c\u021e\3\2"+ + "\2\2\u021d\u021f\5n8\2\u021e\u021d\3\2\2\2\u021e\u021f\3\2\2\2\u021f\u0220"+ + "\3\2\2\2\u0220\u0221\7q\2\2\u0221m\3\2\2\2\u0222\u0224\7\\\2\2\u0223\u0225"+ + "\7q\2\2\u0224\u0223\3\2\2\2\u0224\u0225\3\2\2\2\u0225\u0228\3\2\2\2\u0226"+ + "\u0229\5\b\5\2\u0227\u0229\5V,\2\u0228\u0226\3\2\2\2\u0228\u0227\3\2\2"+ + "\2\u0229o\3\2\2\2\u022a\u022c\5r:\2\u022b\u022d\7q\2\2\u022c\u022b\3\2"+ + "\2\2\u022c\u022d\3\2\2\2\u022d\u0230\3\2\2\2\u022e\u0231\5\b\5\2\u022f"+ + "\u0231\5V,\2\u0230\u022e\3\2\2\2\u0230\u022f\3\2\2\2\u0231\u0233\3\2\2"+ + "\2\u0232\u0234\7q\2\2\u0233\u0232\3\2\2\2\u0233\u0234\3\2\2\2\u0234\u0236"+ + "\3\2\2\2\u0235\u0237\5n8\2\u0236\u0235\3\2\2\2\u0236\u0237\3\2\2\2\u0237"+ + "\u0238\3\2\2\2\u0238\u0239\7q\2\2\u0239q\3\2\2\2\u023a\u023b\t\20\2\2"+ + "\u023bs\3\2\2\2\u023c\u023e\7i\2\2\u023d\u023f\5\32\16\2\u023e\u023d\3"+ + "\2\2\2\u023e\u023f\3\2\2\2\u023f\u0242\3\2\2\2\u0240\u0243\5:\36\2\u0241"+ + "\u0243\5\66\34\2\u0242\u0240\3\2\2\2\u0242\u0241\3\2\2\2\u0243\u0244\3"+ + "\2\2\2\u0244\u0245\7j\2\2\u0245\u0247\5&\24\2\u0246\u0248\7q\2\2\u0247"+ + "\u0246\3\2\2\2\u0247\u0248\3\2\2\2\u0248\u0249\3\2\2\2\u0249\u024a\5V"+ + ",\2\u024au\3\2\2\2\u024b\u024c\7k\2\2\u024c\u024e\5&\24\2\u024d\u024f"+ + "\7q\2\2\u024e\u024d\3\2\2\2\u024e\u024f\3\2\2\2\u024f\u0252\3\2\2\2\u0250"+ + "\u0253\5\b\5\2\u0251\u0253\5V,\2\u0252\u0250\3\2\2\2\u0252\u0251\3\2\2"+ + "\2\u0253w\3\2\2\2\u0254\u0257\7l\2\2\u0255\u0258\5\b\5\2\u0256\u0258\5"+ + "V,\2\u0257\u0255\3\2\2\2\u0257\u0256\3\2\2\2\u0258\u025a\3\2\2\2\u0259"+ + "\u025b\7q\2\2\u025a\u0259\3\2\2\2\u025a\u025b\3\2\2\2\u025b\u025c\3\2"+ + "\2\2\u025c\u025d\7m\2\2\u025d\u025e\5&\24\2\u025ey\3\2\2\2F|~\u0085\u008a"+ "\u00a5\u00ae\u00b2\u00b9\u00bc\u00c1\u00c5\u00cb\u00e9\u00fd\u0125\u0127"+ "\u0129\u012e\u0134\u0138\u013e\u0142\u0149\u014e\u0153\u0160\u016a\u0172"+ "\u0177\u017c\u0180\u0190\u0199\u019d\u01a9\u01ab\u01b3\u01b8\u01c2\u01c7"+ - "\u01ce\u01d5\u01db\u01e0\u01e8\u01ed\u01f7\u01fe\u0204\u0209\u0211\u0216"+ - "\u021a\u021d\u0220\u0226\u022a\u022e\u0232\u0235\u0238\u0240\u0244\u0249"+ - "\u0250\u0254\u0259\u025c"; + "\u01ce\u01d5\u01db\u01e0\u01e8\u01ed\u01f6\u01fd\u0203\u0208\u020f\u0214"+ + "\u0218\u021b\u021e\u0224\u0228\u022c\u0230\u0233\u0236\u023e\u0242\u0247"+ + "\u024e\u0252\u0257\u025a"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static {