better solution for registerpair as subroutine param/returnvalue

This commit is contained in:
Irmen de Jong 2018-11-10 12:25:46 +01:00
parent c415f731da
commit 95b05d08b3
4 changed files with 200 additions and 190 deletions

View File

@ -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

View File

@ -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<IStatement>,
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<Register>
private fun prog8Parser.Asmsub_returnsContext.toAst(): List<AsmSubroutineReturn>
= 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<AsmSubroutineParameter>
= 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())

View File

@ -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<Register, Int>().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)

View File

@ -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 {