diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index e5fafd67e..650dd15b8 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -6,6 +6,8 @@ import dk.camelot64.kickc.parser.KickCParser; import dk.camelot64.kickc.passes.*; import org.antlr.v4.runtime.*; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -14,23 +16,39 @@ import java.util.List; */ public class Compiler { - public Program compile(final CharStream input) { - CompileLog log = new CompileLog(); + private Program program; + + public Compiler() { + this.program = new Program(new ProgramScope(), new CompileLog()); + this.program.setImportPaths(new ArrayList<>()); + } + + public CompileLog getLog() { + return program.getLog(); + } + + public void addImportPath(String path) { + program.getImportPaths().add(path); + } + + public Program compile(String fileName) throws IOException { try { - KickCParser.FileContext file = pass0ParseInput(input, log); - Program program = pass1GenerateSSA(file, log); - pass2OptimizeSSA(program); - log.append("FINAL SYMBOL TABLE"); - log.append(program.getScope().getSymbolTableContents(program)); - pass3Analysis(program); - pass4RegisterAllocation(program); - pass5GenerateAndOptimizeAsm(program); - - log.append("FINAL SYMBOL TABLE"); - log.append(program.getScope().getSymbolTableContents(program)); - log.append("FINAL CODE"); - log.append(program.getAsm().toString()); - + StatementSequenceGenerator statementSequenceGenerator = new StatementSequenceGenerator(program); + loadAndParseFile(fileName, program, statementSequenceGenerator); + StatementSequence sequence = statementSequenceGenerator.getSequence(); + sequence.addStatement(new StatementCall(null, "main", new ArrayList<>())); + program.setStatementSequence(sequence); + pass1GenerateSSA(); + pass2OptimizeSSA(); + getLog().append("FINAL SYMBOL TABLE"); + getLog().append(program.getScope().getSymbolTableContents(program)); + pass3Analysis(); + pass4RegisterAllocation(); + pass5GenerateAndOptimizeAsm(); + getLog().append("FINAL SYMBOL TABLE"); + getLog().append(program.getScope().getSymbolTableContents(program)); + getLog().append("FINAL CODE"); + getLog().append(program.getAsm().toString()); return program; } catch (Exception e) { //System.out.println(log.getLog()); @@ -38,9 +56,10 @@ public class Compiler { } } - public KickCParser.FileContext pass0ParseInput(final CharStream input, CompileLog log) { - log.append(input.toString()); - KickCLexer lexer = new KickCLexer(input); + public static void loadAndParseFile(String fileName, Program program, StatementSequenceGenerator statementSequenceGenerator) { + CharStream fileStream = loadFile(fileName, program); + program.getLog().append(fileStream.toString()); + KickCLexer lexer = new KickCLexer(fileStream); KickCParser parser = new KickCParser(new CommonTokenStream(lexer)); parser.setBuildParseTree(true); parser.addErrorListener(new BaseErrorListener() { @@ -52,64 +71,80 @@ public class Compiler { int charPositionInLine, String msg, RecognitionException e) { - throw new CompileError("Error parsing file " + input.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg); + throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg); } }); - return parser.file(); + statementSequenceGenerator.generate(parser.file()); } - public Program pass1GenerateSSA(KickCParser.FileContext file, CompileLog log) { - Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence(log); - pass1GenerateStatementSequence.generate(file); - StatementSequence statementSequence = pass1GenerateStatementSequence.getSequence(); - ProgramScope programScope = pass1GenerateStatementSequence.getProgramScope(); - statementSequence = new Pass1FixLvalueLoHi(statementSequence, programScope, log).fix(); - Pass1TypeInference pass1TypeInference = new Pass1TypeInference(programScope); - pass1TypeInference.inferTypes(statementSequence); + private static CharStream loadFile(String fileName, Program program) { + if(!fileName.endsWith(".kc")) { + fileName += ".kc"; + } + try { + List importPaths = program.getImportPaths(); + for (String importPath : importPaths) { + if(!importPath.endsWith("/")) { + importPath += "/"; + } + String filePath = importPath + fileName; + File file = new File(filePath); + if(file.exists()) { + return CharStreams.fromPath(file.toPath()); + } + } + } catch (IOException e) { + throw new CompileError("Error loading file " + fileName, e); + } + throw new CompileError("File not found " + fileName); + } - Program program = new Program(programScope, log); - log.append("PROGRAM"); - log.append(statementSequence.toString(program)); - log.append("SYMBOLS"); - log.append(programScope.getSymbolTableContents(program)); - program.setGraph(new Pass1GenerateControlFlowGraph(programScope).generate(statementSequence)); + private Program pass1GenerateSSA() { + new Pass1FixLvalueLoHi(program).execute(); + new Pass1TypeInference(program).execute(); + + getLog().append("PROGRAM"); + getLog().append(program.getStatementSequence().toString(program)); + getLog().append("SYMBOLS"); + getLog().append(program.getScope().getSymbolTableContents(program)); + new Pass1GenerateControlFlowGraph(program).execute(); new Pass1AddTypePromotions(program).execute(); - log.append("INITIAL CONTROL FLOW GRAPH"); - log.append(program.getGraph().toString(program)); + getLog().append("INITIAL CONTROL FLOW GRAPH"); + getLog().append(program.getGraph().toString(program)); new Pass1ExtractInlineStrings(program).execute(); new Pass1EliminateUncalledProcedures(program).execute(); new Pass1EliminateUnusedVars(program).execute(); new Pass1EliminateEmptyBlocks(program).execute(); - log.append("CONTROL FLOW GRAPH"); - log.append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH"); + getLog().append(program.getGraph().toString(program)); new Pass1ModifiedVarsAnalysis(program).execute(); - log.append("PROCEDURE MODIFY VARIABLE ANALYSIS"); - log.append(program.getProcedureModifiedVars().toString(program)); + getLog().append("PROCEDURE MODIFY VARIABLE ANALYSIS"); + getLog().append(program.getProcedureModifiedVars().toString(program)); new Pass1ProcedureCallParameters(program).generate(); - log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL"); - log.append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL"); + getLog().append(program.getGraph().toString(program)); new Pass1GenerateSingleStaticAssignmentForm(program).execute(); - log.append("CONTROL FLOW GRAPH SSA"); - log.append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH SSA"); + getLog().append(program.getGraph().toString(program)); program.setGraph(new Pass1ProcedureCallsReturnValue(program).generate()); - log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN"); - log.append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN"); + getLog().append(program.getGraph().toString(program)); - log.append("INITIAL SSA SYMBOL TABLE"); - log.append(program.getScope().getSymbolTableContents(program)); + getLog().append("INITIAL SSA SYMBOL TABLE"); + getLog().append(program.getScope().getSymbolTableContents(program)); return program; } - public void pass2AssertSSA(Program program) { + private void pass2AssertSSA() { List assertions = new ArrayList<>(); assertions.add(new Pass2AssertTypeMatch(program)); assertions.add(new Pass2AssertSymbols(program)); @@ -126,7 +161,7 @@ public class Compiler { } } - public void pass2OptimizeSSA(Program program) { + private void pass2OptimizeSSA() { List optimizations = new ArrayList<>(); optimizations.add(new Pass2CullEmptyBlocks(program)); optimizations.add(new Pass2UnaryNotSimplification(program)); @@ -136,29 +171,29 @@ public class Compiler { optimizations.add(new Pass2ConditionalJumpSimplification(program)); optimizations.add(new Pass2ConstantIdentification(program)); optimizations.add(new Pass2ConstantAdditionElimination(program)); - pass2OptimizeSSA(program, optimizations); + pass2OptimizeSSA(optimizations); // Constant inlining optimizations - as the last step to ensure that constant identification has been completed List constantOptimizations = new ArrayList<>(); constantOptimizations.add(new Pass2ConstantInlining(program)); - pass2OptimizeSSA(program, constantOptimizations); + pass2OptimizeSSA(constantOptimizations); } - private void pass2OptimizeSSA(Program program, List optimizations) { + private void pass2OptimizeSSA(List optimizations) { boolean ssaOptimized = true; while (ssaOptimized) { - pass2AssertSSA(program); + pass2AssertSSA(); ssaOptimized = false; for (Pass2SsaOptimization optimization : optimizations) { boolean stepOptimized = true; while (stepOptimized) { stepOptimized = optimization.optimize(); if (stepOptimized) { - program.getLog().append("Succesful SSA optimization " + optimization.getClass().getSimpleName() + ""); + getLog().append("Succesful SSA optimization " + optimization.getClass().getSimpleName() + ""); ssaOptimized = true; - program.getLog().append("CONTROL FLOW GRAPH"); - program.getLog().append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH"); + getLog().append(program.getGraph().toString(program)); //pass2AssertSSA(program); } } @@ -166,34 +201,34 @@ public class Compiler { } } - private void pass3Analysis(Program program) { + private void pass3Analysis() { new Pass3BlockSequencePlanner(program).plan(); // Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes new Pass3PhiLifting(program).perform(); new Pass3BlockSequencePlanner(program).plan(); - program.getLog().append("CONTROL FLOW GRAPH - PHI LIFTED"); - program.getLog().append(program.getGraph().toString(program)); - pass2AssertSSA(program); + getLog().append("CONTROL FLOW GRAPH - PHI LIFTED"); + getLog().append(program.getGraph().toString(program)); + pass2AssertSSA(); new Pass3AddNopBeforeCallOns(program).generate(); new Pass3StatementIndices(program).generateStatementIndices(); new Pass3CallGraphAnalysis(program).findCallGraph(); - program.getLog().append("CALL GRAPH"); - program.getLog().append(program.getCallGraph().toString()); + getLog().append("CALL GRAPH"); + getLog().append(program.getCallGraph().toString()); - //program.getLog().setVerboseLiveRanges(true); + //getLog().setVerboseLiveRanges(true); new Pass3StatementInfos(program).generateStatementInfos(); new Pass3VariableReferenceInfos(program).generateVariableReferenceInfos(); new Pass3LiveRangesAnalysis(program).findLiveRanges(); - program.getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND"); - program.getLog().append(program.getGraph().toString(program)); - pass2AssertSSA(program); + getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND"); + getLog().append(program.getGraph().toString(program)); + pass2AssertSSA(); - //program.getLog().setVerboseLiveRanges(false); + //getLog().setVerboseLiveRanges(false); // Phi mem coalesce removes as many variables introduced by phi lifting as possible - as long as their live ranges do not overlap new Pass3PhiMemCoalesce(program).optimize(); @@ -206,32 +241,32 @@ public class Compiler { new Pass3VariableReferenceInfos(program).generateVariableReferenceInfos(); new Pass3SymbolInfos(program).generateSymbolInfos(); new Pass3LiveRangesAnalysis(program).findLiveRanges(); - program.getLog().append("CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES"); - program.getLog().append(program.getGraph().toString(program)); + getLog().append("CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES"); + getLog().append(program.getGraph().toString(program)); new Pass3LiveRangesEffectiveAnalysis(program).findLiveRangesEffective(); - program.getLog().append("CONTROL FLOW GRAPH - PHI MEM COALESCED"); - program.getLog().append(program.getGraph().toString(program)); - pass2AssertSSA(program); + getLog().append("CONTROL FLOW GRAPH - PHI MEM COALESCED"); + getLog().append(program.getGraph().toString(program)); + pass2AssertSSA(); new Pass3DominatorsAnalysis(program).findDominators(); - program.getLog().append("DOMINATORS"); - program.getLog().append(program.getDominators().toString()); + getLog().append("DOMINATORS"); + getLog().append(program.getDominators().toString()); new Pass3LoopAnalysis(program).findLoops(); - program.getLog().append("NATURAL LOOPS"); - program.getLog().append(program.getLoopSet().toString()); + getLog().append("NATURAL LOOPS"); + getLog().append(program.getLoopSet().toString()); new Pass3LoopDepthAnalysis(program).findLoopDepths(); - program.getLog().append("NATURAL LOOPS WITH DEPTH"); - program.getLog().append(program.getLoopSet().toString()); + getLog().append("NATURAL LOOPS WITH DEPTH"); + getLog().append(program.getLoopSet().toString()); new Pass3VariableRegisterWeightAnalysis(program).findWeights(); - program.getLog().append("\nVARIABLE REGISTER WEIGHTS"); - program.getLog().append(program.getScope().toString(program, Variable.class)); + getLog().append("\nVARIABLE REGISTER WEIGHTS"); + getLog().append(program.getScope().toString(program, Variable.class)); } - private void pass4RegisterAllocation(Program program) { + private void pass4RegisterAllocation() { new Pass4LiveRangeEquivalenceClassesFinalize(program).allocate(); new Pass4RegistersFinalize(program).allocate(true); @@ -239,31 +274,31 @@ public class Compiler { // Initial Code generation new Pass4CodeGeneration(program, true).generate(); new Pass4AssertNoCpuClobber(program).check(); - program.getLog().append("INITIAL ASM"); - program.getLog().append(program.getAsm().toString()); + getLog().append("INITIAL ASM"); + getLog().append(program.getAsm().toString()); // Find potential registers for each live range equivalence class - based on clobbering of fragments - program.getLog().append("REGISTER UPLIFT POTENTIAL REGISTERS"); + getLog().append("REGISTER UPLIFT POTENTIAL REGISTERS"); new Pass4RegisterUpliftPotentialInitialize(program).initPotentialRegisters(); new Pass4RegisterUpliftPotentialAluAnalysis(program).findPotentialAlu(); boolean change; do { change = new Pass4RegisterUpliftPotentialRegisterAnalysis(program).findPotentialRegisters(); } while (change); - program.getLog().append(program.getRegisterPotentials().toString()); + getLog().append(program.getRegisterPotentials().toString()); // Find register uplift scopes new Pass4RegisterUpliftScopeAnalysis(program).findScopes(); - program.getLog().append("REGISTER UPLIFT SCOPES"); - program.getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); + getLog().append("REGISTER UPLIFT SCOPES"); + getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); // Attempt uplifting registers through a lot of combinations - //program.getLog().setVerboseUplift(true); + //getLog().setVerboseUplift(true); new Pass4RegisterUpliftCombinations(program).performUplift(10_000); - //program.getLog().setVerboseUplift(true); + //getLog().setVerboseUplift(true); //new Pass4RegisterUpliftStatic(program).performUplift(); - //program.getLog().setVerboseUplift(false); + //getLog().setVerboseUplift(false); // Attempt uplifting registers one at a time to catch remaining potential not realized by combination search new Pass4RegisterUpliftRemains(program).performUplift(10_000); @@ -274,7 +309,7 @@ public class Compiler { } - public void pass5GenerateAndOptimizeAsm(Program program) { + private void pass5GenerateAndOptimizeAsm() { // Final ASM code generation before optimization new Pass4CodeGeneration(program, true).generate(); @@ -288,16 +323,15 @@ public class Compiler { pass5Optimizations.add(new Pass5DoubleJumpElimination(program)); pass5Optimizations.add(new Pass5UnreachableCodeElimination(program)); boolean asmOptimized = true; - CompileLog log = program.getLog(); while (asmOptimized) { asmOptimized = false; for (Pass5AsmOptimization optimization : pass5Optimizations) { boolean stepOptimized = optimization.optimize(); if (stepOptimized) { - log.append("Succesful ASM optimization " + optimization.getClass().getSimpleName()); + getLog().append("Succesful ASM optimization " + optimization.getClass().getSimpleName()); asmOptimized = true; - log.append("ASSEMBLER"); - log.append(program.getAsm().toString()); + getLog().append("ASSEMBLER"); + getLog().append(program.getAsm().toString()); } } } diff --git a/src/main/java/dk/camelot64/kickc/model/CompileError.java b/src/main/java/dk/camelot64/kickc/model/CompileError.java index e6b98e00f..b9d5fa0c6 100644 --- a/src/main/java/dk/camelot64/kickc/model/CompileError.java +++ b/src/main/java/dk/camelot64/kickc/model/CompileError.java @@ -7,5 +7,7 @@ public class CompileError extends RuntimeException { super(message); } - + public CompileError(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index e3d609c25..6688724c2 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -5,9 +5,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import dk.camelot64.kickc.CompileLog; import dk.camelot64.kickc.asm.AsmProgram; +import java.util.List; + /** A KickC Intermediate Compiler Language (ICL) Program */ public class Program { + /** Paths used for importing files. */ + private List importPaths; + /** The initial statement sequence generated byt the parser. */ + private StatementSequence statementSequence; /** The main scope. */ private ProgramScope scope; /** The control flow graph. */ @@ -29,7 +35,9 @@ public class Program { /** Which block is each statement a part of. */ private StatementInfos statementInfos; - /** The variables freferenced by blocks/statements. */ + /** Cached information about symbols. Contains a symbol table cache for fast access.*/ + private SymbolInfos symbolInfos; + /** The variables referenced by blocks/statements. */ private VariableReferenceInfos variableReferenceInfos; /** The live ranges of all variables. */ private LiveRangeVariables liveRangeVariables; @@ -43,7 +51,6 @@ public class Program { private RegisterPotentials registerPotentials; /** Separation of live range equivalence classes into scopes - used for register uplift */ private RegisterUpliftProgram registerUpliftProgram; - private SymbolInfos symbolInfos; @JsonCreator public Program( @@ -60,6 +67,22 @@ public class Program { this.log = log; } + public List getImportPaths() { + return importPaths; + } + + public void setImportPaths(List importPaths) { + this.importPaths = importPaths; + } + + public StatementSequence getStatementSequence() { + return statementSequence; + } + + public void setStatementSequence(StatementSequence statementSequence) { + this.statementSequence = statementSequence; + } + public ProgramScope getScope() { return scope; } @@ -108,7 +131,7 @@ public class Program { return dominators; } - public void setLoops(NaturalLoopSet loopSet) { + public void setLoopSet(NaturalLoopSet loopSet) { this.loopSet = loopSet; } diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 index 4f69a3961..1b551516e 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 @@ -10,7 +10,7 @@ asmFile ; importSeq - : importDecl+ + : importDecl* ; importDecl diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java index a1847e631..a5e887cf9 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java @@ -240,20 +240,20 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(56); + setState(58); _errHandler.sync(this); _la = _input.LA(1); - do { + while (_la==T__0) { { { setState(55); importDecl(); } } - setState(58); + setState(60); _errHandler.sync(this); _la = _input.LA(1); - } while ( _la==T__0 ); + } } } catch (RecognitionException re) { @@ -294,9 +294,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(60); - match(T__0); setState(61); + match(T__0); + setState(62); match(STRING); } } @@ -344,17 +344,17 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(64); + setState(65); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(63); + setState(64); decl(); } } - setState(66); + setState(67); _errHandler.sync(this); _la = _input.LA(1); } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__18) | (1L << SIMPLETYPE))) != 0) ); @@ -433,44 +433,44 @@ public class KickCParser extends Parser { enterRule(_localctx, 10, RULE_decl); int _la; try { - setState(82); + setState(83); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { case 1: _localctx = new DeclMethodContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(68); - typeDecl(0); setState(69); - match(NAME); + typeDecl(0); setState(70); + match(NAME); + setState(71); match(T__1); - setState(72); + setState(73); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__18 || _la==SIMPLETYPE) { { - setState(71); + setState(72); parameterListDecl(); } } - setState(74); - match(T__2); setState(75); + match(T__2); + setState(76); match(T__3); - setState(77); + setState(78); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__3) | (1L << T__6) | (1L << T__9) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__18) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(76); + setState(77); stmtSeq(); } } - setState(79); + setState(80); match(T__4); } break; @@ -478,7 +478,7 @@ public class KickCParser extends Parser { _localctx = new DeclVariableContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(81); + setState(82); declVar(); } break; @@ -528,21 +528,21 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(84); + setState(85); parameterDecl(); - setState(89); + setState(90); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(85); - match(T__5); setState(86); + match(T__5); + setState(87); parameterDecl(); } } - setState(91); + setState(92); _errHandler.sync(this); _la = _input.LA(1); } @@ -589,9 +589,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(92); - typeDecl(0); setState(93); + typeDecl(0); + setState(94); match(NAME); } } @@ -640,33 +640,33 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(96); + setState(97); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__6) { { - setState(95); + setState(96); match(T__6); } } - setState(98); - typeDecl(0); setState(99); + typeDecl(0); + setState(100); match(NAME); - setState(102); + setState(103); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__7) { { - setState(100); - match(T__7); setState(101); + match(T__7); + setState(102); initializer(); } } - setState(104); + setState(105); match(T__8); } } @@ -714,17 +714,17 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(107); + setState(108); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(106); + setState(107); stmt(); } } - setState(109); + setState(110); _errHandler.sync(this); _la = _input.LA(1); } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__3) | (1L << T__6) | (1L << T__9) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__18) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) ); @@ -969,14 +969,14 @@ public class KickCParser extends Parser { enterRule(_localctx, 20, RULE_stmt); int _la; try { - setState(167); + setState(168); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { case 1: _localctx = new StmtDeclVarContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(111); + setState(112); declVar(); } break; @@ -984,19 +984,19 @@ public class KickCParser extends Parser { _localctx = new StmtBlockContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(112); + setState(113); match(T__3); - setState(114); + setState(115); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__3) | (1L << T__6) | (1L << T__9) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__18) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(113); + setState(114); stmtSeq(); } } - setState(116); + setState(117); match(T__4); } break; @@ -1004,13 +1004,13 @@ public class KickCParser extends Parser { _localctx = new StmtAssignmentContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(117); - lvalue(0); setState(118); - match(T__7); + lvalue(0); setState(119); - expr(0); + match(T__7); setState(120); + expr(0); + setState(121); match(T__8); } break; @@ -1018,9 +1018,9 @@ public class KickCParser extends Parser { _localctx = new StmtExprContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(122); - expr(0); setState(123); + expr(0); + setState(124); match(T__8); } break; @@ -1028,24 +1028,24 @@ public class KickCParser extends Parser { _localctx = new StmtIfElseContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(125); - match(T__9); setState(126); - match(T__1); + match(T__9); setState(127); - expr(0); + match(T__1); setState(128); - match(T__2); + expr(0); setState(129); + match(T__2); + setState(130); stmt(); - setState(132); + setState(133); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: { - setState(130); - match(T__10); setState(131); + match(T__10); + setState(132); stmt(); } break; @@ -1056,15 +1056,15 @@ public class KickCParser extends Parser { _localctx = new StmtWhileContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(134); - match(T__11); setState(135); - match(T__1); + match(T__11); setState(136); - expr(0); + match(T__1); setState(137); - match(T__2); + expr(0); setState(138); + match(T__2); + setState(139); stmt(); } break; @@ -1072,19 +1072,19 @@ public class KickCParser extends Parser { _localctx = new StmtDoWhileContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(140); - match(T__12); setState(141); - stmt(); + match(T__12); setState(142); - match(T__11); + stmt(); setState(143); - match(T__1); + match(T__11); setState(144); - expr(0); + match(T__1); setState(145); - match(T__2); + expr(0); setState(146); + match(T__2); + setState(147); match(T__8); } break; @@ -1092,25 +1092,25 @@ public class KickCParser extends Parser { _localctx = new StmtForContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(148); - match(T__13); setState(149); + match(T__13); + setState(150); match(T__1); - setState(151); + setState(152); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__18) | (1L << SIMPLETYPE) | (1L << NAME))) != 0)) { { - setState(150); + setState(151); forDeclaration(); } } - setState(153); - forIteration(); setState(154); - match(T__2); + forIteration(); setState(155); + match(T__2); + setState(156); stmt(); } break; @@ -1118,19 +1118,19 @@ public class KickCParser extends Parser { _localctx = new StmtReturnContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(157); + setState(158); match(T__14); - setState(159); + setState(160); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(158); + setState(159); expr(0); } } - setState(161); + setState(162); match(T__8); } break; @@ -1138,13 +1138,13 @@ public class KickCParser extends Parser { _localctx = new StmtAsmContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(162); - match(T__15); setState(163); - match(T__3); + match(T__15); setState(164); - asmLines(); + match(T__3); setState(165); + asmLines(); + setState(166); match(T__4); } break; @@ -1204,26 +1204,26 @@ public class KickCParser extends Parser { _localctx = new ForDeclContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(170); + setState(171); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__18 || _la==SIMPLETYPE) { { - setState(169); + setState(170); typeDecl(0); } } - setState(172); + setState(173); match(NAME); - setState(175); + setState(176); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__7) { { - setState(173); - match(T__7); setState(174); + match(T__7); + setState(175); initializer(); } } @@ -1302,25 +1302,25 @@ public class KickCParser extends Parser { enterRule(_localctx, 24, RULE_forIteration); int _la; try { - setState(188); + setState(189); _errHandler.sync(this); switch (_input.LA(1)) { case T__8: _localctx = new ForClassicContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(177); - match(T__8); setState(178); - expr(0); - setState(179); match(T__8); - setState(181); + setState(179); + expr(0); + setState(180); + match(T__8); + setState(182); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(180); + setState(181); expr(0); } } @@ -1331,15 +1331,15 @@ public class KickCParser extends Parser { _localctx = new ForRangeContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(183); - match(T__16); setState(184); + match(T__16); + setState(185); expr(0); { - setState(185); + setState(186); match(T__17); } - setState(186); + setState(187); expr(0); } break; @@ -1461,7 +1461,7 @@ public class KickCParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(194); + setState(195); _errHandler.sync(this); switch (_input.LA(1)) { case SIMPLETYPE: @@ -1470,7 +1470,7 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(191); + setState(192); match(SIMPLETYPE); } break; @@ -1479,9 +1479,9 @@ public class KickCParser extends Parser { _localctx = new TypeSignedSimpleContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(192); - match(T__18); setState(193); + match(T__18); + setState(194); match(SIMPLETYPE); } break; @@ -1489,7 +1489,7 @@ public class KickCParser extends Parser { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(206); + setState(207); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,21,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1497,16 +1497,16 @@ public class KickCParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(204); + setState(205); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { case 1: { _localctx = new TypePtrContext(new TypeDeclContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_typeDecl); - setState(196); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); setState(197); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(198); match(T__19); } break; @@ -1514,28 +1514,28 @@ public class KickCParser extends Parser { { _localctx = new TypeArrayContext(new TypeDeclContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_typeDecl); - setState(198); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(199); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(200); match(T__20); - setState(201); + setState(202); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(200); + setState(201); expr(0); } } - setState(203); + setState(204); match(T__21); } break; } } } - setState(208); + setState(209); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,21,_ctx); } @@ -1610,7 +1610,7 @@ public class KickCParser extends Parser { enterRule(_localctx, 28, RULE_initializer); int _la; try { - setState(221); + setState(222); _errHandler.sync(this); switch (_input.LA(1)) { case T__1: @@ -1632,7 +1632,7 @@ public class KickCParser extends Parser { _localctx = new InitExprContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(209); + setState(210); expr(0); } break; @@ -1640,27 +1640,27 @@ public class KickCParser extends Parser { _localctx = new InitListContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(210); - match(T__3); setState(211); + match(T__3); + setState(212); initializer(); - setState(216); + setState(217); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(212); - match(T__5); setState(213); + match(T__5); + setState(214); initializer(); } } - setState(218); + setState(219); _errHandler.sync(this); _la = _input.LA(1); } - setState(219); + setState(220); match(T__4); } break; @@ -1801,7 +1801,7 @@ public class KickCParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(234); + setState(235); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) { case 1: @@ -1810,7 +1810,7 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(224); + setState(225); match(NAME); } break; @@ -1819,9 +1819,9 @@ public class KickCParser extends Parser { _localctx = new LvaluePtrContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(225); - match(T__19); setState(226); + match(T__19); + setState(227); match(NAME); } break; @@ -1830,13 +1830,13 @@ public class KickCParser extends Parser { _localctx = new LvaluePtrExprContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(227); - match(T__19); setState(228); - match(T__1); + match(T__19); setState(229); - expr(0); + match(T__1); setState(230); + expr(0); + setState(231); match(T__2); } break; @@ -1845,7 +1845,7 @@ public class KickCParser extends Parser { _localctx = new LvalueLoHiContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(232); + setState(233); _la = _input.LA(1); if ( !(_la==T__22 || _la==T__23) ) { _errHandler.recoverInline(this); @@ -1855,13 +1855,13 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(233); + setState(234); lvalue(2); } break; } _ctx.stop = _input.LT(-1); - setState(243); + setState(244); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,25,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1872,18 +1872,18 @@ public class KickCParser extends Parser { { _localctx = new LvalueArrayContext(new LvalueContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_lvalue); - setState(236); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(237); - match(T__20); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(238); - expr(0); + match(T__20); setState(239); + expr(0); + setState(240); match(T__21); } } } - setState(245); + setState(246); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,25,_ctx); } @@ -2175,7 +2175,7 @@ public class KickCParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(271); + setState(272); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) { case 1: @@ -2184,11 +2184,11 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(247); - match(T__1); setState(248); - expr(0); + match(T__1); setState(249); + expr(0); + setState(250); match(T__2); } break; @@ -2197,21 +2197,21 @@ public class KickCParser extends Parser { _localctx = new ExprCallContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(251); - match(NAME); setState(252); + match(NAME); + setState(253); match(T__1); - setState(254); + setState(255); _errHandler.sync(this); _la = _input.LA(1); if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { - setState(253); + setState(254); parameterList(); } } - setState(256); + setState(257); match(T__2); } break; @@ -2220,13 +2220,13 @@ public class KickCParser extends Parser { _localctx = new ExprCastContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(257); - match(T__1); setState(258); - typeDecl(0); + match(T__1); setState(259); - match(T__2); + typeDecl(0); setState(260); + match(T__2); + setState(261); expr(19); } break; @@ -2235,7 +2235,7 @@ public class KickCParser extends Parser { _localctx = new ExprPreModContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(262); + setState(263); _la = _input.LA(1); if ( !(_la==T__24 || _la==T__25) ) { _errHandler.recoverInline(this); @@ -2245,7 +2245,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(263); + setState(264); expr(17); } break; @@ -2254,7 +2254,7 @@ public class KickCParser extends Parser { _localctx = new ExprUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(264); + setState(265); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__19) | (1L << T__22) | (1L << T__23) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30))) != 0)) ) { _errHandler.recoverInline(this); @@ -2264,7 +2264,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(265); + setState(266); expr(15); } break; @@ -2273,7 +2273,7 @@ public class KickCParser extends Parser { _localctx = new ExprIdContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(266); + setState(267); match(NAME); } break; @@ -2282,7 +2282,7 @@ public class KickCParser extends Parser { _localctx = new ExprNumberContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(267); + setState(268); match(NUMBER); } break; @@ -2291,7 +2291,7 @@ public class KickCParser extends Parser { _localctx = new ExprStringContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(268); + setState(269); match(STRING); } break; @@ -2300,7 +2300,7 @@ public class KickCParser extends Parser { _localctx = new ExprCharContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(269); + setState(270); match(CHAR); } break; @@ -2309,13 +2309,13 @@ public class KickCParser extends Parser { _localctx = new ExprBoolContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(270); + setState(271); match(BOOLEAN); } break; } _ctx.stop = _input.LT(-1); - setState(309); + setState(310); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,29,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -2323,16 +2323,16 @@ public class KickCParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(307); + setState(308); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { case 1: { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(273); - if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); setState(274); + if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); + setState(275); _la = _input.LA(1); if ( !(_la==T__31 || _la==T__32) ) { _errHandler.recoverInline(this); @@ -2342,7 +2342,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(275); + setState(276); expr(15); } break; @@ -2350,9 +2350,9 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(276); - if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); setState(277); + if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); + setState(278); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__19) | (1L << T__33) | (1L << T__34))) != 0)) ) { _errHandler.recoverInline(this); @@ -2362,7 +2362,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(278); + setState(279); expr(14); } break; @@ -2370,9 +2370,9 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(279); - if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); setState(280); + if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); + setState(281); _la = _input.LA(1); if ( !(_la==T__26 || _la==T__27) ) { _errHandler.recoverInline(this); @@ -2382,7 +2382,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(281); + setState(282); expr(13); } break; @@ -2390,9 +2390,9 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(282); - if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); setState(283); + if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); + setState(284); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__22) | (1L << T__23) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41))) != 0)) ) { _errHandler.recoverInline(this); @@ -2402,7 +2402,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(284); + setState(285); expr(12); } break; @@ -2410,13 +2410,13 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(285); + setState(286); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); { - setState(286); + setState(287); match(T__29); } - setState(287); + setState(288); expr(11); } break; @@ -2424,13 +2424,13 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(288); + setState(289); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); { - setState(289); + setState(290); match(T__42); } - setState(290); + setState(291); expr(10); } break; @@ -2438,13 +2438,13 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(291); + setState(292); if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); { - setState(292); + setState(293); match(T__43); } - setState(293); + setState(294); expr(9); } break; @@ -2452,13 +2452,13 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(294); + setState(295); if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); { - setState(295); + setState(296); match(T__44); } - setState(296); + setState(297); expr(8); } break; @@ -2466,13 +2466,13 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(297); + setState(298); if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); { - setState(298); + setState(299); match(T__45); } - setState(299); + setState(300); expr(7); } break; @@ -2480,13 +2480,13 @@ public class KickCParser extends Parser { { _localctx = new ExprArrayContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(300); - if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); setState(301); - match(T__20); + if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); setState(302); - expr(0); + match(T__20); setState(303); + expr(0); + setState(304); match(T__21); } break; @@ -2494,9 +2494,9 @@ public class KickCParser extends Parser { { _localctx = new ExprPostModContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(305); - if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)"); setState(306); + if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)"); + setState(307); _la = _input.LA(1); if ( !(_la==T__24 || _la==T__25) ) { _errHandler.recoverInline(this); @@ -2511,7 +2511,7 @@ public class KickCParser extends Parser { } } } - setState(311); + setState(312); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,29,_ctx); } @@ -2561,21 +2561,21 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(312); + setState(313); expr(0); - setState(317); + setState(318); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(313); - match(T__5); setState(314); + match(T__5); + setState(315); expr(0); } } - setState(319); + setState(320); _errHandler.sync(this); _la = _input.LA(1); } @@ -2625,17 +2625,17 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(323); + setState(324); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__28) | (1L << MNEMONIC) | (1L << NAME))) != 0)) { { { - setState(320); + setState(321); asmLine(); } } - setState(325); + setState(326); _errHandler.sync(this); _la = _input.LA(1); } @@ -2682,21 +2682,21 @@ public class KickCParser extends Parser { AsmLineContext _localctx = new AsmLineContext(_ctx, getState()); enterRule(_localctx, 38, RULE_asmLine); try { - setState(328); + setState(329); _errHandler.sync(this); switch (_input.LA(1)) { case T__28: case NAME: enterOuterAlt(_localctx, 1); { - setState(326); + setState(327); asmLabel(); } break; case MNEMONIC: enterOuterAlt(_localctx, 2); { - setState(327); + setState(328); asmInstruction(); } break; @@ -2740,24 +2740,24 @@ public class KickCParser extends Parser { AsmLabelContext _localctx = new AsmLabelContext(_ctx, getState()); enterRule(_localctx, 40, RULE_asmLabel); try { - setState(334); + setState(335); _errHandler.sync(this); switch (_input.LA(1)) { case NAME: enterOuterAlt(_localctx, 1); { - setState(330); - match(NAME); setState(331); + match(NAME); + setState(332); match(T__16); } break; case T__28: enterOuterAlt(_localctx, 2); { - setState(332); - match(T__28); setState(333); + match(T__28); + setState(334); match(T__16); } break; @@ -2806,14 +2806,14 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(336); + setState(337); match(MNEMONIC); - setState(338); + setState(339); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { case 1: { - setState(337); + setState(338); asmParamMode(); } break; @@ -2964,14 +2964,14 @@ public class KickCParser extends Parser { AsmParamModeContext _localctx = new AsmParamModeContext(_ctx, getState()); enterRule(_localctx, 44, RULE_asmParamMode); try { - setState(363); + setState(364); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,35,_ctx) ) { case 1: _localctx = new AsmModeAbsContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(340); + setState(341); asmExpr(0); } break; @@ -2979,9 +2979,9 @@ public class KickCParser extends Parser { _localctx = new AsmModeImmContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(341); - match(T__46); setState(342); + match(T__46); + setState(343); asmExpr(0); } break; @@ -2989,11 +2989,11 @@ public class KickCParser extends Parser { _localctx = new AsmModeAbsXYContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(343); - asmExpr(0); setState(344); - match(T__5); + asmExpr(0); setState(345); + match(T__5); + setState(346); match(NAME); } break; @@ -3001,15 +3001,15 @@ public class KickCParser extends Parser { _localctx = new AsmModeIndIdxXYContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(347); - match(T__1); setState(348); - asmExpr(0); + match(T__1); setState(349); - match(T__2); + asmExpr(0); setState(350); - match(T__5); + match(T__2); setState(351); + match(T__5); + setState(352); match(NAME); } break; @@ -3017,15 +3017,15 @@ public class KickCParser extends Parser { _localctx = new AsmModeIdxIndXYContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(353); - match(T__1); setState(354); - asmExpr(0); + match(T__1); setState(355); - match(T__5); + asmExpr(0); setState(356); - match(NAME); + match(T__5); setState(357); + match(NAME); + setState(358); match(T__2); } break; @@ -3033,11 +3033,11 @@ public class KickCParser extends Parser { _localctx = new AsmModeIndContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(359); - match(T__1); setState(360); - asmExpr(0); + match(T__1); setState(361); + asmExpr(0); + setState(362); match(T__2); } break; @@ -3208,7 +3208,7 @@ public class KickCParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(375); + setState(376); _errHandler.sync(this); switch (_input.LA(1)) { case T__22: @@ -3220,7 +3220,7 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(366); + setState(367); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__22) | (1L << T__23) | (1L << T__26) | (1L << T__27))) != 0)) ) { _errHandler.recoverInline(this); @@ -3230,7 +3230,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(367); + setState(368); asmExpr(8); } break; @@ -3239,7 +3239,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprLabelContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(368); + setState(369); match(NAME); } break; @@ -3248,7 +3248,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprLabelRelContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(369); + setState(370); match(ASMREL); } break; @@ -3257,11 +3257,11 @@ public class KickCParser extends Parser { _localctx = new AsmExprReplaceContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(370); - match(T__3); setState(371); - match(NAME); + match(T__3); setState(372); + match(NAME); + setState(373); match(T__4); } break; @@ -3270,7 +3270,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprIntContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(373); + setState(374); match(NUMBER); } break; @@ -3279,7 +3279,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprCharContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(374); + setState(375); match(CHAR); } break; @@ -3287,7 +3287,7 @@ public class KickCParser extends Parser { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(385); + setState(386); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,38,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -3295,16 +3295,16 @@ public class KickCParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(383); + setState(384); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) { case 1: { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(377); - if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); setState(378); + if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + setState(379); _la = _input.LA(1); if ( !(_la==T__19 || _la==T__33) ) { _errHandler.recoverInline(this); @@ -3314,7 +3314,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(379); + setState(380); asmExpr(8); } break; @@ -3322,9 +3322,9 @@ public class KickCParser extends Parser { { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(380); - if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); setState(381); + if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); + setState(382); _la = _input.LA(1); if ( !(_la==T__26 || _la==T__27) ) { _errHandler.recoverInline(this); @@ -3334,14 +3334,14 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(382); + setState(383); asmExpr(7); } break; } } } - setState(387); + setState(388); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,38,_ctx); } @@ -3425,153 +3425,153 @@ public class KickCParser extends Parser { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3D\u0187\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3D\u0188\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"+ - "\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4\6\4;\n\4\r\4\16\4<\3\5\3\5\3\5\3\6\6"+ - "\6C\n\6\r\6\16\6D\3\7\3\7\3\7\3\7\5\7K\n\7\3\7\3\7\3\7\5\7P\n\7\3\7\3"+ - "\7\3\7\5\7U\n\7\3\b\3\b\3\b\7\bZ\n\b\f\b\16\b]\13\b\3\t\3\t\3\t\3\n\5"+ - "\nc\n\n\3\n\3\n\3\n\3\n\5\ni\n\n\3\n\3\n\3\13\6\13n\n\13\r\13\16\13o\3"+ - "\f\3\f\3\f\5\fu\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+ - "\f\3\f\3\f\3\f\5\f\u0087\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+ - "\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u009a\n\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00a2"+ - "\n\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00aa\n\f\3\r\5\r\u00ad\n\r\3\r\3\r\3"+ - "\r\5\r\u00b2\n\r\3\16\3\16\3\16\3\16\5\16\u00b8\n\16\3\16\3\16\3\16\3"+ - "\16\3\16\5\16\u00bf\n\16\3\17\3\17\3\17\3\17\5\17\u00c5\n\17\3\17\3\17"+ - "\3\17\3\17\3\17\5\17\u00cc\n\17\3\17\7\17\u00cf\n\17\f\17\16\17\u00d2"+ - "\13\17\3\20\3\20\3\20\3\20\3\20\7\20\u00d9\n\20\f\20\16\20\u00dc\13\20"+ - "\3\20\3\20\5\20\u00e0\n\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ - "\3\21\3\21\5\21\u00ed\n\21\3\21\3\21\3\21\3\21\3\21\7\21\u00f4\n\21\f"+ - "\21\16\21\u00f7\13\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u0101"+ + "\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4\7\4;\n\4\f\4\16\4>\13\4\3\5\3\5\3\5\3"+ + "\6\6\6D\n\6\r\6\16\6E\3\7\3\7\3\7\3\7\5\7L\n\7\3\7\3\7\3\7\5\7Q\n\7\3"+ + "\7\3\7\3\7\5\7V\n\7\3\b\3\b\3\b\7\b[\n\b\f\b\16\b^\13\b\3\t\3\t\3\t\3"+ + "\n\5\nd\n\n\3\n\3\n\3\n\3\n\5\nj\n\n\3\n\3\n\3\13\6\13o\n\13\r\13\16\13"+ + "p\3\f\3\f\3\f\5\fv\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+ + "\3\f\3\f\3\f\3\f\5\f\u0088\n\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+ + "\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u009b\n\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f"+ + "\u00a3\n\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00ab\n\f\3\r\5\r\u00ae\n\r\3\r"+ + "\3\r\3\r\5\r\u00b3\n\r\3\16\3\16\3\16\3\16\5\16\u00b9\n\16\3\16\3\16\3"+ + "\16\3\16\3\16\5\16\u00c0\n\16\3\17\3\17\3\17\3\17\5\17\u00c6\n\17\3\17"+ + "\3\17\3\17\3\17\3\17\5\17\u00cd\n\17\3\17\7\17\u00d0\n\17\f\17\16\17\u00d3"+ + "\13\17\3\20\3\20\3\20\3\20\3\20\7\20\u00da\n\20\f\20\16\20\u00dd\13\20"+ + "\3\20\3\20\5\20\u00e1\n\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ + "\3\21\3\21\5\21\u00ee\n\21\3\21\3\21\3\21\3\21\3\21\7\21\u00f5\n\21\f"+ + "\21\16\21\u00f8\13\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u0102"+ "\n\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+ - "\3\22\3\22\5\22\u0112\n\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+ + "\3\22\3\22\5\22\u0113\n\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+ "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+ - "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\7\22\u0136\n\22"+ - "\f\22\16\22\u0139\13\22\3\23\3\23\3\23\7\23\u013e\n\23\f\23\16\23\u0141"+ - "\13\23\3\24\7\24\u0144\n\24\f\24\16\24\u0147\13\24\3\25\3\25\5\25\u014b"+ - "\n\25\3\26\3\26\3\26\3\26\5\26\u0151\n\26\3\27\3\27\5\27\u0155\n\27\3"+ + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\7\22\u0137\n\22"+ + "\f\22\16\22\u013a\13\22\3\23\3\23\3\23\7\23\u013f\n\23\f\23\16\23\u0142"+ + "\13\23\3\24\7\24\u0145\n\24\f\24\16\24\u0148\13\24\3\25\3\25\5\25\u014c"+ + "\n\25\3\26\3\26\3\26\3\26\5\26\u0152\n\26\3\27\3\27\5\27\u0156\n\27\3"+ "\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3"+ - "\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u016e\n\30\3\31\3\31"+ - "\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\5\31\u017a\n\31\3\31\3\31\3\31"+ - "\3\31\3\31\3\31\7\31\u0182\n\31\f\31\16\31\u0185\13\31\3\31\2\6\34 \""+ + "\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u016f\n\30\3\31\3\31"+ + "\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\5\31\u017b\n\31\3\31\3\31\3\31"+ + "\3\31\3\31\3\31\7\31\u0183\n\31\f\31\16\31\u0186\13\31\3\31\2\6\34 \""+ "\60\32\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2\13\3\2\31"+ "\32\3\2\33\34\5\2\26\26\31\32\35!\3\2\"#\4\2\26\26$%\3\2\35\36\4\2\31"+ - "\32&,\4\2\31\32\35\36\4\2\26\26$$\2\u01b8\2\62\3\2\2\2\4\66\3\2\2\2\6"+ - ":\3\2\2\2\b>\3\2\2\2\nB\3\2\2\2\fT\3\2\2\2\16V\3\2\2\2\20^\3\2\2\2\22"+ - "b\3\2\2\2\24m\3\2\2\2\26\u00a9\3\2\2\2\30\u00ac\3\2\2\2\32\u00be\3\2\2"+ - "\2\34\u00c4\3\2\2\2\36\u00df\3\2\2\2 \u00ec\3\2\2\2\"\u0111\3\2\2\2$\u013a"+ - "\3\2\2\2&\u0145\3\2\2\2(\u014a\3\2\2\2*\u0150\3\2\2\2,\u0152\3\2\2\2."+ - "\u016d\3\2\2\2\60\u0179\3\2\2\2\62\63\5\6\4\2\63\64\5\n\6\2\64\65\7\2"+ + "\32&,\4\2\31\32\35\36\4\2\26\26$$\2\u01b9\2\62\3\2\2\2\4\66\3\2\2\2\6"+ + "<\3\2\2\2\b?\3\2\2\2\nC\3\2\2\2\fU\3\2\2\2\16W\3\2\2\2\20_\3\2\2\2\22"+ + "c\3\2\2\2\24n\3\2\2\2\26\u00aa\3\2\2\2\30\u00ad\3\2\2\2\32\u00bf\3\2\2"+ + "\2\34\u00c5\3\2\2\2\36\u00e0\3\2\2\2 \u00ed\3\2\2\2\"\u0112\3\2\2\2$\u013b"+ + "\3\2\2\2&\u0146\3\2\2\2(\u014b\3\2\2\2*\u0151\3\2\2\2,\u0153\3\2\2\2."+ + "\u016e\3\2\2\2\60\u017a\3\2\2\2\62\63\5\6\4\2\63\64\5\n\6\2\64\65\7\2"+ "\2\3\65\3\3\2\2\2\66\67\5&\24\2\678\7\2\2\38\5\3\2\2\29;\5\b\5\2:9\3\2"+ - "\2\2;<\3\2\2\2<:\3\2\2\2<=\3\2\2\2=\7\3\2\2\2>?\7\3\2\2?@\7\64\2\2@\t"+ - "\3\2\2\2AC\5\f\7\2BA\3\2\2\2CD\3\2\2\2DB\3\2\2\2DE\3\2\2\2E\13\3\2\2\2"+ - "FG\5\34\17\2GH\7@\2\2HJ\7\4\2\2IK\5\16\b\2JI\3\2\2\2JK\3\2\2\2KL\3\2\2"+ - "\2LM\7\5\2\2MO\7\6\2\2NP\5\24\13\2ON\3\2\2\2OP\3\2\2\2PQ\3\2\2\2QR\7\7"+ - "\2\2RU\3\2\2\2SU\5\22\n\2TF\3\2\2\2TS\3\2\2\2U\r\3\2\2\2V[\5\20\t\2WX"+ - "\7\b\2\2XZ\5\20\t\2YW\3\2\2\2Z]\3\2\2\2[Y\3\2\2\2[\\\3\2\2\2\\\17\3\2"+ - "\2\2][\3\2\2\2^_\5\34\17\2_`\7@\2\2`\21\3\2\2\2ac\7\t\2\2ba\3\2\2\2bc"+ - "\3\2\2\2cd\3\2\2\2de\5\34\17\2eh\7@\2\2fg\7\n\2\2gi\5\36\20\2hf\3\2\2"+ - "\2hi\3\2\2\2ij\3\2\2\2jk\7\13\2\2k\23\3\2\2\2ln\5\26\f\2ml\3\2\2\2no\3"+ - "\2\2\2om\3\2\2\2op\3\2\2\2p\25\3\2\2\2q\u00aa\5\22\n\2rt\7\6\2\2su\5\24"+ - "\13\2ts\3\2\2\2tu\3\2\2\2uv\3\2\2\2v\u00aa\7\7\2\2wx\5 \21\2xy\7\n\2\2"+ - "yz\5\"\22\2z{\7\13\2\2{\u00aa\3\2\2\2|}\5\"\22\2}~\7\13\2\2~\u00aa\3\2"+ - "\2\2\177\u0080\7\f\2\2\u0080\u0081\7\4\2\2\u0081\u0082\5\"\22\2\u0082"+ - "\u0083\7\5\2\2\u0083\u0086\5\26\f\2\u0084\u0085\7\r\2\2\u0085\u0087\5"+ - "\26\f\2\u0086\u0084\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u00aa\3\2\2\2\u0088"+ - "\u0089\7\16\2\2\u0089\u008a\7\4\2\2\u008a\u008b\5\"\22\2\u008b\u008c\7"+ - "\5\2\2\u008c\u008d\5\26\f\2\u008d\u00aa\3\2\2\2\u008e\u008f\7\17\2\2\u008f"+ - "\u0090\5\26\f\2\u0090\u0091\7\16\2\2\u0091\u0092\7\4\2\2\u0092\u0093\5"+ - "\"\22\2\u0093\u0094\7\5\2\2\u0094\u0095\7\13\2\2\u0095\u00aa\3\2\2\2\u0096"+ - "\u0097\7\20\2\2\u0097\u0099\7\4\2\2\u0098\u009a\5\30\r\2\u0099\u0098\3"+ - "\2\2\2\u0099\u009a\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u009c\5\32\16\2\u009c"+ - "\u009d\7\5\2\2\u009d\u009e\5\26\f\2\u009e\u00aa\3\2\2\2\u009f\u00a1\7"+ - "\21\2\2\u00a0\u00a2\5\"\22\2\u00a1\u00a0\3\2\2\2\u00a1\u00a2\3\2\2\2\u00a2"+ - "\u00a3\3\2\2\2\u00a3\u00aa\7\13\2\2\u00a4\u00a5\7\22\2\2\u00a5\u00a6\7"+ - "\6\2\2\u00a6\u00a7\5&\24\2\u00a7\u00a8\7\7\2\2\u00a8\u00aa\3\2\2\2\u00a9"+ - "q\3\2\2\2\u00a9r\3\2\2\2\u00a9w\3\2\2\2\u00a9|\3\2\2\2\u00a9\177\3\2\2"+ - "\2\u00a9\u0088\3\2\2\2\u00a9\u008e\3\2\2\2\u00a9\u0096\3\2\2\2\u00a9\u009f"+ - "\3\2\2\2\u00a9\u00a4\3\2\2\2\u00aa\27\3\2\2\2\u00ab\u00ad\5\34\17\2\u00ac"+ - "\u00ab\3\2\2\2\u00ac\u00ad\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\u00b1\7@"+ - "\2\2\u00af\u00b0\7\n\2\2\u00b0\u00b2\5\36\20\2\u00b1\u00af\3\2\2\2\u00b1"+ - "\u00b2\3\2\2\2\u00b2\31\3\2\2\2\u00b3\u00b4\7\13\2\2\u00b4\u00b5\5\"\22"+ - "\2\u00b5\u00b7\7\13\2\2\u00b6\u00b8\5\"\22\2\u00b7\u00b6\3\2\2\2\u00b7"+ - "\u00b8\3\2\2\2\u00b8\u00bf\3\2\2\2\u00b9\u00ba\7\23\2\2\u00ba\u00bb\5"+ - "\"\22\2\u00bb\u00bc\7\24\2\2\u00bc\u00bd\5\"\22\2\u00bd\u00bf\3\2\2\2"+ - "\u00be\u00b3\3\2\2\2\u00be\u00b9\3\2\2\2\u00bf\33\3\2\2\2\u00c0\u00c1"+ - "\b\17\1\2\u00c1\u00c5\7\63\2\2\u00c2\u00c3\7\25\2\2\u00c3\u00c5\7\63\2"+ - "\2\u00c4\u00c0\3\2\2\2\u00c4\u00c2\3\2\2\2\u00c5\u00d0\3\2\2\2\u00c6\u00c7"+ - "\f\4\2\2\u00c7\u00cf\7\26\2\2\u00c8\u00c9\f\3\2\2\u00c9\u00cb\7\27\2\2"+ - "\u00ca\u00cc\5\"\22\2\u00cb\u00ca\3\2\2\2\u00cb\u00cc\3\2\2\2\u00cc\u00cd"+ - "\3\2\2\2\u00cd\u00cf\7\30\2\2\u00ce\u00c6\3\2\2\2\u00ce\u00c8\3\2\2\2"+ - "\u00cf\u00d2\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1\35"+ - "\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d3\u00e0\5\"\22\2\u00d4\u00d5\7\6\2\2"+ - "\u00d5\u00da\5\36\20\2\u00d6\u00d7\7\b\2\2\u00d7\u00d9\5\36\20\2\u00d8"+ - "\u00d6\3\2\2\2\u00d9\u00dc\3\2\2\2\u00da\u00d8\3\2\2\2\u00da\u00db\3\2"+ - "\2\2\u00db\u00dd\3\2\2\2\u00dc\u00da\3\2\2\2\u00dd\u00de\7\7\2\2\u00de"+ - "\u00e0\3\2\2\2\u00df\u00d3\3\2\2\2\u00df\u00d4\3\2\2\2\u00e0\37\3\2\2"+ - "\2\u00e1\u00e2\b\21\1\2\u00e2\u00ed\7@\2\2\u00e3\u00e4\7\26\2\2\u00e4"+ - "\u00ed\7@\2\2\u00e5\u00e6\7\26\2\2\u00e6\u00e7\7\4\2\2\u00e7\u00e8\5\""+ - "\22\2\u00e8\u00e9\7\5\2\2\u00e9\u00ed\3\2\2\2\u00ea\u00eb\t\2\2\2\u00eb"+ - "\u00ed\5 \21\4\u00ec\u00e1\3\2\2\2\u00ec\u00e3\3\2\2\2\u00ec\u00e5\3\2"+ - "\2\2\u00ec\u00ea\3\2\2\2\u00ed\u00f5\3\2\2\2\u00ee\u00ef\f\3\2\2\u00ef"+ - "\u00f0\7\27\2\2\u00f0\u00f1\5\"\22\2\u00f1\u00f2\7\30\2\2\u00f2\u00f4"+ - "\3\2\2\2\u00f3\u00ee\3\2\2\2\u00f4\u00f7\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f5"+ - "\u00f6\3\2\2\2\u00f6!\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f8\u00f9\b\22\1\2"+ - "\u00f9\u00fa\7\4\2\2\u00fa\u00fb\5\"\22\2\u00fb\u00fc\7\5\2\2\u00fc\u0112"+ - "\3\2\2\2\u00fd\u00fe\7@\2\2\u00fe\u0100\7\4\2\2\u00ff\u0101\5$\23\2\u0100"+ - "\u00ff\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0112\7\5"+ - "\2\2\u0103\u0104\7\4\2\2\u0104\u0105\5\34\17\2\u0105\u0106\7\5\2\2\u0106"+ - "\u0107\5\"\22\25\u0107\u0112\3\2\2\2\u0108\u0109\t\3\2\2\u0109\u0112\5"+ - "\"\22\23\u010a\u010b\t\4\2\2\u010b\u0112\5\"\22\21\u010c\u0112\7@\2\2"+ - "\u010d\u0112\7\67\2\2\u010e\u0112\7\64\2\2\u010f\u0112\7\65\2\2\u0110"+ - "\u0112\7\66\2\2\u0111\u00f8\3\2\2\2\u0111\u00fd\3\2\2\2\u0111\u0103\3"+ - "\2\2\2\u0111\u0108\3\2\2\2\u0111\u010a\3\2\2\2\u0111\u010c\3\2\2\2\u0111"+ - "\u010d\3\2\2\2\u0111\u010e\3\2\2\2\u0111\u010f\3\2\2\2\u0111\u0110\3\2"+ - "\2\2\u0112\u0137\3\2\2\2\u0113\u0114\f\20\2\2\u0114\u0115\t\5\2\2\u0115"+ - "\u0136\5\"\22\21\u0116\u0117\f\17\2\2\u0117\u0118\t\6\2\2\u0118\u0136"+ - "\5\"\22\20\u0119\u011a\f\16\2\2\u011a\u011b\t\7\2\2\u011b\u0136\5\"\22"+ - "\17\u011c\u011d\f\r\2\2\u011d\u011e\t\b\2\2\u011e\u0136\5\"\22\16\u011f"+ - "\u0120\f\f\2\2\u0120\u0121\7 \2\2\u0121\u0136\5\"\22\r\u0122\u0123\f\13"+ - "\2\2\u0123\u0124\7-\2\2\u0124\u0136\5\"\22\f\u0125\u0126\f\n\2\2\u0126"+ - "\u0127\7.\2\2\u0127\u0136\5\"\22\13\u0128\u0129\f\t\2\2\u0129\u012a\7"+ - "/\2\2\u012a\u0136\5\"\22\n\u012b\u012c\f\b\2\2\u012c\u012d\7\60\2\2\u012d"+ - "\u0136\5\"\22\t\u012e\u012f\f\24\2\2\u012f\u0130\7\27\2\2\u0130\u0131"+ - "\5\"\22\2\u0131\u0132\7\30\2\2\u0132\u0136\3\2\2\2\u0133\u0134\f\22\2"+ - "\2\u0134\u0136\t\3\2\2\u0135\u0113\3\2\2\2\u0135\u0116\3\2\2\2\u0135\u0119"+ - "\3\2\2\2\u0135\u011c\3\2\2\2\u0135\u011f\3\2\2\2\u0135\u0122\3\2\2\2\u0135"+ - "\u0125\3\2\2\2\u0135\u0128\3\2\2\2\u0135\u012b\3\2\2\2\u0135\u012e\3\2"+ - "\2\2\u0135\u0133\3\2\2\2\u0136\u0139\3\2\2\2\u0137\u0135\3\2\2\2\u0137"+ - "\u0138\3\2\2\2\u0138#\3\2\2\2\u0139\u0137\3\2\2\2\u013a\u013f\5\"\22\2"+ - "\u013b\u013c\7\b\2\2\u013c\u013e\5\"\22\2\u013d\u013b\3\2\2\2\u013e\u0141"+ - "\3\2\2\2\u013f\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140%\3\2\2\2\u0141"+ - "\u013f\3\2\2\2\u0142\u0144\5(\25\2\u0143\u0142\3\2\2\2\u0144\u0147\3\2"+ - "\2\2\u0145\u0143\3\2\2\2\u0145\u0146\3\2\2\2\u0146\'\3\2\2\2\u0147\u0145"+ - "\3\2\2\2\u0148\u014b\5*\26\2\u0149\u014b\5,\27\2\u014a\u0148\3\2\2\2\u014a"+ - "\u0149\3\2\2\2\u014b)\3\2\2\2\u014c\u014d\7@\2\2\u014d\u0151\7\23\2\2"+ - "\u014e\u014f\7\37\2\2\u014f\u0151\7\23\2\2\u0150\u014c\3\2\2\2\u0150\u014e"+ - "\3\2\2\2\u0151+\3\2\2\2\u0152\u0154\7\62\2\2\u0153\u0155\5.\30\2\u0154"+ - "\u0153\3\2\2\2\u0154\u0155\3\2\2\2\u0155-\3\2\2\2\u0156\u016e\5\60\31"+ - "\2\u0157\u0158\7\61\2\2\u0158\u016e\5\60\31\2\u0159\u015a\5\60\31\2\u015a"+ - "\u015b\7\b\2\2\u015b\u015c\7@\2\2\u015c\u016e\3\2\2\2\u015d\u015e\7\4"+ - "\2\2\u015e\u015f\5\60\31\2\u015f\u0160\7\5\2\2\u0160\u0161\7\b\2\2\u0161"+ - "\u0162\7@\2\2\u0162\u016e\3\2\2\2\u0163\u0164\7\4\2\2\u0164\u0165\5\60"+ - "\31\2\u0165\u0166\7\b\2\2\u0166\u0167\7@\2\2\u0167\u0168\7\5\2\2\u0168"+ - "\u016e\3\2\2\2\u0169\u016a\7\4\2\2\u016a\u016b\5\60\31\2\u016b\u016c\7"+ - "\5\2\2\u016c\u016e\3\2\2\2\u016d\u0156\3\2\2\2\u016d\u0157\3\2\2\2\u016d"+ - "\u0159\3\2\2\2\u016d\u015d\3\2\2\2\u016d\u0163\3\2\2\2\u016d\u0169\3\2"+ - "\2\2\u016e/\3\2\2\2\u016f\u0170\b\31\1\2\u0170\u0171\t\t\2\2\u0171\u017a"+ - "\5\60\31\n\u0172\u017a\7@\2\2\u0173\u017a\7A\2\2\u0174\u0175\7\6\2\2\u0175"+ - "\u0176\7@\2\2\u0176\u017a\7\7\2\2\u0177\u017a\7\67\2\2\u0178\u017a\7\65"+ - "\2\2\u0179\u016f\3\2\2\2\u0179\u0172\3\2\2\2\u0179\u0173\3\2\2\2\u0179"+ - "\u0174\3\2\2\2\u0179\u0177\3\2\2\2\u0179\u0178\3\2\2\2\u017a\u0183\3\2"+ - "\2\2\u017b\u017c\f\t\2\2\u017c\u017d\t\n\2\2\u017d\u0182\5\60\31\n\u017e"+ - "\u017f\f\b\2\2\u017f\u0180\t\7\2\2\u0180\u0182\5\60\31\t\u0181\u017b\3"+ - "\2\2\2\u0181\u017e\3\2\2\2\u0182\u0185\3\2\2\2\u0183\u0181\3\2\2\2\u0183"+ - "\u0184\3\2\2\2\u0184\61\3\2\2\2\u0185\u0183\3\2\2\2)\3\2\2\2<:\3\2\2\2<=\3\2\2\2=\7\3\2\2\2><\3\2\2\2?@\7\3\2\2@A\7"+ + "\64\2\2A\t\3\2\2\2BD\5\f\7\2CB\3\2\2\2DE\3\2\2\2EC\3\2\2\2EF\3\2\2\2F"+ + "\13\3\2\2\2GH\5\34\17\2HI\7@\2\2IK\7\4\2\2JL\5\16\b\2KJ\3\2\2\2KL\3\2"+ + "\2\2LM\3\2\2\2MN\7\5\2\2NP\7\6\2\2OQ\5\24\13\2PO\3\2\2\2PQ\3\2\2\2QR\3"+ + "\2\2\2RS\7\7\2\2SV\3\2\2\2TV\5\22\n\2UG\3\2\2\2UT\3\2\2\2V\r\3\2\2\2W"+ + "\\\5\20\t\2XY\7\b\2\2Y[\5\20\t\2ZX\3\2\2\2[^\3\2\2\2\\Z\3\2\2\2\\]\3\2"+ + "\2\2]\17\3\2\2\2^\\\3\2\2\2_`\5\34\17\2`a\7@\2\2a\21\3\2\2\2bd\7\t\2\2"+ + "cb\3\2\2\2cd\3\2\2\2de\3\2\2\2ef\5\34\17\2fi\7@\2\2gh\7\n\2\2hj\5\36\20"+ + "\2ig\3\2\2\2ij\3\2\2\2jk\3\2\2\2kl\7\13\2\2l\23\3\2\2\2mo\5\26\f\2nm\3"+ + "\2\2\2op\3\2\2\2pn\3\2\2\2pq\3\2\2\2q\25\3\2\2\2r\u00ab\5\22\n\2su\7\6"+ + "\2\2tv\5\24\13\2ut\3\2\2\2uv\3\2\2\2vw\3\2\2\2w\u00ab\7\7\2\2xy\5 \21"+ + "\2yz\7\n\2\2z{\5\"\22\2{|\7\13\2\2|\u00ab\3\2\2\2}~\5\"\22\2~\177\7\13"+ + "\2\2\177\u00ab\3\2\2\2\u0080\u0081\7\f\2\2\u0081\u0082\7\4\2\2\u0082\u0083"+ + "\5\"\22\2\u0083\u0084\7\5\2\2\u0084\u0087\5\26\f\2\u0085\u0086\7\r\2\2"+ + "\u0086\u0088\5\26\f\2\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u00ab"+ + "\3\2\2\2\u0089\u008a\7\16\2\2\u008a\u008b\7\4\2\2\u008b\u008c\5\"\22\2"+ + "\u008c\u008d\7\5\2\2\u008d\u008e\5\26\f\2\u008e\u00ab\3\2\2\2\u008f\u0090"+ + "\7\17\2\2\u0090\u0091\5\26\f\2\u0091\u0092\7\16\2\2\u0092\u0093\7\4\2"+ + "\2\u0093\u0094\5\"\22\2\u0094\u0095\7\5\2\2\u0095\u0096\7\13\2\2\u0096"+ + "\u00ab\3\2\2\2\u0097\u0098\7\20\2\2\u0098\u009a\7\4\2\2\u0099\u009b\5"+ + "\30\r\2\u009a\u0099\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u009c\3\2\2\2\u009c"+ + "\u009d\5\32\16\2\u009d\u009e\7\5\2\2\u009e\u009f\5\26\f\2\u009f\u00ab"+ + "\3\2\2\2\u00a0\u00a2\7\21\2\2\u00a1\u00a3\5\"\22\2\u00a2\u00a1\3\2\2\2"+ + "\u00a2\u00a3\3\2\2\2\u00a3\u00a4\3\2\2\2\u00a4\u00ab\7\13\2\2\u00a5\u00a6"+ + "\7\22\2\2\u00a6\u00a7\7\6\2\2\u00a7\u00a8\5&\24\2\u00a8\u00a9\7\7\2\2"+ + "\u00a9\u00ab\3\2\2\2\u00aar\3\2\2\2\u00aas\3\2\2\2\u00aax\3\2\2\2\u00aa"+ + "}\3\2\2\2\u00aa\u0080\3\2\2\2\u00aa\u0089\3\2\2\2\u00aa\u008f\3\2\2\2"+ + "\u00aa\u0097\3\2\2\2\u00aa\u00a0\3\2\2\2\u00aa\u00a5\3\2\2\2\u00ab\27"+ + "\3\2\2\2\u00ac\u00ae\5\34\17\2\u00ad\u00ac\3\2\2\2\u00ad\u00ae\3\2\2\2"+ + "\u00ae\u00af\3\2\2\2\u00af\u00b2\7@\2\2\u00b0\u00b1\7\n\2\2\u00b1\u00b3"+ + "\5\36\20\2\u00b2\u00b0\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\31\3\2\2\2\u00b4"+ + "\u00b5\7\13\2\2\u00b5\u00b6\5\"\22\2\u00b6\u00b8\7\13\2\2\u00b7\u00b9"+ + "\5\"\22\2\u00b8\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\u00c0\3\2\2\2"+ + "\u00ba\u00bb\7\23\2\2\u00bb\u00bc\5\"\22\2\u00bc\u00bd\7\24\2\2\u00bd"+ + "\u00be\5\"\22\2\u00be\u00c0\3\2\2\2\u00bf\u00b4\3\2\2\2\u00bf\u00ba\3"+ + "\2\2\2\u00c0\33\3\2\2\2\u00c1\u00c2\b\17\1\2\u00c2\u00c6\7\63\2\2\u00c3"+ + "\u00c4\7\25\2\2\u00c4\u00c6\7\63\2\2\u00c5\u00c1\3\2\2\2\u00c5\u00c3\3"+ + "\2\2\2\u00c6\u00d1\3\2\2\2\u00c7\u00c8\f\4\2\2\u00c8\u00d0\7\26\2\2\u00c9"+ + "\u00ca\f\3\2\2\u00ca\u00cc\7\27\2\2\u00cb\u00cd\5\"\22\2\u00cc\u00cb\3"+ + "\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\u00ce\3\2\2\2\u00ce\u00d0\7\30\2\2\u00cf"+ + "\u00c7\3\2\2\2\u00cf\u00c9\3\2\2\2\u00d0\u00d3\3\2\2\2\u00d1\u00cf\3\2"+ + "\2\2\u00d1\u00d2\3\2\2\2\u00d2\35\3\2\2\2\u00d3\u00d1\3\2\2\2\u00d4\u00e1"+ + "\5\"\22\2\u00d5\u00d6\7\6\2\2\u00d6\u00db\5\36\20\2\u00d7\u00d8\7\b\2"+ + "\2\u00d8\u00da\5\36\20\2\u00d9\u00d7\3\2\2\2\u00da\u00dd\3\2\2\2\u00db"+ + "\u00d9\3\2\2\2\u00db\u00dc\3\2\2\2\u00dc\u00de\3\2\2\2\u00dd\u00db\3\2"+ + "\2\2\u00de\u00df\7\7\2\2\u00df\u00e1\3\2\2\2\u00e0\u00d4\3\2\2\2\u00e0"+ + "\u00d5\3\2\2\2\u00e1\37\3\2\2\2\u00e2\u00e3\b\21\1\2\u00e3\u00ee\7@\2"+ + "\2\u00e4\u00e5\7\26\2\2\u00e5\u00ee\7@\2\2\u00e6\u00e7\7\26\2\2\u00e7"+ + "\u00e8\7\4\2\2\u00e8\u00e9\5\"\22\2\u00e9\u00ea\7\5\2\2\u00ea\u00ee\3"+ + "\2\2\2\u00eb\u00ec\t\2\2\2\u00ec\u00ee\5 \21\4\u00ed\u00e2\3\2\2\2\u00ed"+ + "\u00e4\3\2\2\2\u00ed\u00e6\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ee\u00f6\3\2"+ + "\2\2\u00ef\u00f0\f\3\2\2\u00f0\u00f1\7\27\2\2\u00f1\u00f2\5\"\22\2\u00f2"+ + "\u00f3\7\30\2\2\u00f3\u00f5\3\2\2\2\u00f4\u00ef\3\2\2\2\u00f5\u00f8\3"+ + "\2\2\2\u00f6\u00f4\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7!\3\2\2\2\u00f8\u00f6"+ + "\3\2\2\2\u00f9\u00fa\b\22\1\2\u00fa\u00fb\7\4\2\2\u00fb\u00fc\5\"\22\2"+ + "\u00fc\u00fd\7\5\2\2\u00fd\u0113\3\2\2\2\u00fe\u00ff\7@\2\2\u00ff\u0101"+ + "\7\4\2\2\u0100\u0102\5$\23\2\u0101\u0100\3\2\2\2\u0101\u0102\3\2\2\2\u0102"+ + "\u0103\3\2\2\2\u0103\u0113\7\5\2\2\u0104\u0105\7\4\2\2\u0105\u0106\5\34"+ + "\17\2\u0106\u0107\7\5\2\2\u0107\u0108\5\"\22\25\u0108\u0113\3\2\2\2\u0109"+ + "\u010a\t\3\2\2\u010a\u0113\5\"\22\23\u010b\u010c\t\4\2\2\u010c\u0113\5"+ + "\"\22\21\u010d\u0113\7@\2\2\u010e\u0113\7\67\2\2\u010f\u0113\7\64\2\2"+ + "\u0110\u0113\7\65\2\2\u0111\u0113\7\66\2\2\u0112\u00f9\3\2\2\2\u0112\u00fe"+ + "\3\2\2\2\u0112\u0104\3\2\2\2\u0112\u0109\3\2\2\2\u0112\u010b\3\2\2\2\u0112"+ + "\u010d\3\2\2\2\u0112\u010e\3\2\2\2\u0112\u010f\3\2\2\2\u0112\u0110\3\2"+ + "\2\2\u0112\u0111\3\2\2\2\u0113\u0138\3\2\2\2\u0114\u0115\f\20\2\2\u0115"+ + "\u0116\t\5\2\2\u0116\u0137\5\"\22\21\u0117\u0118\f\17\2\2\u0118\u0119"+ + "\t\6\2\2\u0119\u0137\5\"\22\20\u011a\u011b\f\16\2\2\u011b\u011c\t\7\2"+ + "\2\u011c\u0137\5\"\22\17\u011d\u011e\f\r\2\2\u011e\u011f\t\b\2\2\u011f"+ + "\u0137\5\"\22\16\u0120\u0121\f\f\2\2\u0121\u0122\7 \2\2\u0122\u0137\5"+ + "\"\22\r\u0123\u0124\f\13\2\2\u0124\u0125\7-\2\2\u0125\u0137\5\"\22\f\u0126"+ + "\u0127\f\n\2\2\u0127\u0128\7.\2\2\u0128\u0137\5\"\22\13\u0129\u012a\f"+ + "\t\2\2\u012a\u012b\7/\2\2\u012b\u0137\5\"\22\n\u012c\u012d\f\b\2\2\u012d"+ + "\u012e\7\60\2\2\u012e\u0137\5\"\22\t\u012f\u0130\f\24\2\2\u0130\u0131"+ + "\7\27\2\2\u0131\u0132\5\"\22\2\u0132\u0133\7\30\2\2\u0133\u0137\3\2\2"+ + "\2\u0134\u0135\f\22\2\2\u0135\u0137\t\3\2\2\u0136\u0114\3\2\2\2\u0136"+ + "\u0117\3\2\2\2\u0136\u011a\3\2\2\2\u0136\u011d\3\2\2\2\u0136\u0120\3\2"+ + "\2\2\u0136\u0123\3\2\2\2\u0136\u0126\3\2\2\2\u0136\u0129\3\2\2\2\u0136"+ + "\u012c\3\2\2\2\u0136\u012f\3\2\2\2\u0136\u0134\3\2\2\2\u0137\u013a\3\2"+ + "\2\2\u0138\u0136\3\2\2\2\u0138\u0139\3\2\2\2\u0139#\3\2\2\2\u013a\u0138"+ + "\3\2\2\2\u013b\u0140\5\"\22\2\u013c\u013d\7\b\2\2\u013d\u013f\5\"\22\2"+ + "\u013e\u013c\3\2\2\2\u013f\u0142\3\2\2\2\u0140\u013e\3\2\2\2\u0140\u0141"+ + "\3\2\2\2\u0141%\3\2\2\2\u0142\u0140\3\2\2\2\u0143\u0145\5(\25\2\u0144"+ + "\u0143\3\2\2\2\u0145\u0148\3\2\2\2\u0146\u0144\3\2\2\2\u0146\u0147\3\2"+ + "\2\2\u0147\'\3\2\2\2\u0148\u0146\3\2\2\2\u0149\u014c\5*\26\2\u014a\u014c"+ + "\5,\27\2\u014b\u0149\3\2\2\2\u014b\u014a\3\2\2\2\u014c)\3\2\2\2\u014d"+ + "\u014e\7@\2\2\u014e\u0152\7\23\2\2\u014f\u0150\7\37\2\2\u0150\u0152\7"+ + "\23\2\2\u0151\u014d\3\2\2\2\u0151\u014f\3\2\2\2\u0152+\3\2\2\2\u0153\u0155"+ + "\7\62\2\2\u0154\u0156\5.\30\2\u0155\u0154\3\2\2\2\u0155\u0156\3\2\2\2"+ + "\u0156-\3\2\2\2\u0157\u016f\5\60\31\2\u0158\u0159\7\61\2\2\u0159\u016f"+ + "\5\60\31\2\u015a\u015b\5\60\31\2\u015b\u015c\7\b\2\2\u015c\u015d\7@\2"+ + "\2\u015d\u016f\3\2\2\2\u015e\u015f\7\4\2\2\u015f\u0160\5\60\31\2\u0160"+ + "\u0161\7\5\2\2\u0161\u0162\7\b\2\2\u0162\u0163\7@\2\2\u0163\u016f\3\2"+ + "\2\2\u0164\u0165\7\4\2\2\u0165\u0166\5\60\31\2\u0166\u0167\7\b\2\2\u0167"+ + "\u0168\7@\2\2\u0168\u0169\7\5\2\2\u0169\u016f\3\2\2\2\u016a\u016b\7\4"+ + "\2\2\u016b\u016c\5\60\31\2\u016c\u016d\7\5\2\2\u016d\u016f\3\2\2\2\u016e"+ + "\u0157\3\2\2\2\u016e\u0158\3\2\2\2\u016e\u015a\3\2\2\2\u016e\u015e\3\2"+ + "\2\2\u016e\u0164\3\2\2\2\u016e\u016a\3\2\2\2\u016f/\3\2\2\2\u0170\u0171"+ + "\b\31\1\2\u0171\u0172\t\t\2\2\u0172\u017b\5\60\31\n\u0173\u017b\7@\2\2"+ + "\u0174\u017b\7A\2\2\u0175\u0176\7\6\2\2\u0176\u0177\7@\2\2\u0177\u017b"+ + "\7\7\2\2\u0178\u017b\7\67\2\2\u0179\u017b\7\65\2\2\u017a\u0170\3\2\2\2"+ + "\u017a\u0173\3\2\2\2\u017a\u0174\3\2\2\2\u017a\u0175\3\2\2\2\u017a\u0178"+ + "\3\2\2\2\u017a\u0179\3\2\2\2\u017b\u0184\3\2\2\2\u017c\u017d\f\t\2\2\u017d"+ + "\u017e\t\n\2\2\u017e\u0183\5\60\31\n\u017f\u0180\f\b\2\2\u0180\u0181\t"+ + "\7\2\2\u0181\u0183\5\60\31\t\u0182\u017c\3\2\2\2\u0182\u017f\3\2\2\2\u0183"+ + "\u0186\3\2\2\2\u0184\u0182\3\2\2\2\u0184\u0185\3\2\2\2\u0185\61\3\2\2"+ + "\2\u0186\u0184\3\2\2\2)Example: <plotter = x & 8 *
Becomes: $1 =x & 8 , plotter = plotter lo= $1 */ -public class Pass1FixLvalueLoHi { +public class Pass1FixLvalueLoHi extends Pass1Base { - private final StatementSequence statementSequence; - private final ProgramScope programScope; - private CompileLog log; - - - public Pass1FixLvalueLoHi(StatementSequence statementSequence, ProgramScope programScope, CompileLog log) { - this.statementSequence = statementSequence; - this.programScope = programScope; - this.log = log; + public Pass1FixLvalueLoHi(Program program) { + super(program); } - public StatementSequence fix() { + @Override + boolean executeStep() { Stack scopeStack = new Stack<>(); - scopeStack.push(programScope); + scopeStack.push(getScope()); StatementSequence fixedSequence = new StatementSequence(); - for (Statement statement : statementSequence.getStatements()) { + for (Statement statement : getProgram().getStatementSequence().getStatements()) { if (statement instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) statement; if (assignment.getlValue() instanceof LvalueLoHiByte) { @@ -40,11 +33,11 @@ public class Pass1FixLvalueLoHi { fixedSequence.addStatement(tmpAssignment); Statement setLoHiAssignment = new StatementAssignment(loHiByte.getVariable(), loHiByte.getVariable(), loHiByte.getOperator(), tmpVarRef); fixedSequence.addStatement(setLoHiAssignment); - log.append("Fixing lo/hi-lvalue with new tmpVar " + tmpVarRef + " " + assignment.toString()); + getLog().append("Fixing lo/hi-lvalue with new tmpVar " + tmpVarRef + " " + assignment.toString()); } else { Statement setLoHiAssignment = new StatementAssignment(loHiByte.getVariable(), loHiByte.getVariable(), loHiByte.getOperator(), assignment.getrValue2()); fixedSequence.addStatement(setLoHiAssignment); - log.append("Fixing lo/hi-lvalue " + assignment.toString()); + getLog().append("Fixing lo/hi-lvalue " + assignment.toString()); } } else { fixedSequence.addStatement(statement); @@ -54,13 +47,14 @@ public class Pass1FixLvalueLoHi { } if (statement instanceof StatementProcedureBegin) { ProcedureRef procedureRef = ((StatementProcedureBegin) statement).getProcedure(); - Procedure procedure = programScope.getProcedure(procedureRef); + Procedure procedure = getScope().getProcedure(procedureRef); scopeStack.push(procedure); } else if (statement instanceof StatementProcedureEnd) { scopeStack.pop(); } } - return fixedSequence; + getProgram().setStatementSequence(fixedSequence); + return false; } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateControlFlowGraph.java b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateControlFlowGraph.java index a3a952725..9e7678e1c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateControlFlowGraph.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateControlFlowGraph.java @@ -7,19 +7,20 @@ import java.util.Map; import java.util.Stack; /** Pass that generates a control flow graph for the program */ -public class Pass1GenerateControlFlowGraph { +public class Pass1GenerateControlFlowGraph extends Pass1Base { - private ProgramScope scope; - private Map blocks; - private ControlFlowBlock firstBlock; - - public Pass1GenerateControlFlowGraph(ProgramScope scope) { - this.scope = scope; - this.blocks = new LinkedHashMap<>(); + public Pass1GenerateControlFlowGraph(Program program) { + super(program); } - public ControlFlowGraph generate(StatementSequence sequence) { - this.firstBlock = getOrCreateBlock(scope.addLabel(SymbolRef.BEGIN_BLOCK_NAME).getRef(), ScopeRef.ROOT); + private Map blocks; + + @Override + boolean executeStep() { + this.blocks = new LinkedHashMap<>(); + ProgramScope scope = getScope(); + StatementSequence sequence = getProgram().getStatementSequence(); + ControlFlowBlock firstBlock = getOrCreateBlock(scope.addLabel(SymbolRef.BEGIN_BLOCK_NAME).getRef(), ScopeRef.ROOT); Stack blockStack = new Stack<>(); blockStack.push(firstBlock); sequence.addStatement(new StatementLabel(scope.addLabel(SymbolRef.END_BLOCK_NAME).getRef())); @@ -79,8 +80,9 @@ public class Pass1GenerateControlFlowGraph { currentBlock.addStatement(statement); } } - - return new ControlFlowGraph(blocks, firstBlock.getLabel()); + ControlFlowGraph controlFlowGraph = new ControlFlowGraph(blocks, firstBlock.getLabel()); + getProgram().setGraph(controlFlowGraph); + return false; } private ControlFlowBlock getOrCreateBlock(LabelRef label, ScopeRef scope) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java b/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java index b8561d25d..b0eb55178 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java @@ -8,22 +8,18 @@ import java.util.Stack; * Pass through the generated statements inferring types of unresolved variables. * Also updates procedure calls to point to the actual procedure called. */ -public class Pass1TypeInference { +public class Pass1TypeInference extends Pass1Base { - private ProgramScope programScope; - - public Pass1TypeInference(ProgramScope programScope) { - this.programScope = programScope; + public Pass1TypeInference(Program program) { + super(program); } - public ProgramScope getProgramScope() { - return programScope; - } - - public void inferTypes(StatementSequence sequence) { + @Override + boolean executeStep() { Stack scopes = new Stack<>(); + ProgramScope programScope = getScope(); scopes.add(programScope); - for (Statement statement : sequence.getStatements()) { + for (Statement statement : getProgram().getStatementSequence().getStatements()) { if(statement instanceof StatementProcedureBegin) { StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement; ProcedureRef procedureRef = procedureBegin.getProcedure(); @@ -66,6 +62,7 @@ public class Pass1TypeInference { } } } + return false; } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LoopAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LoopAnalysis.java index 856149148..53cee536f 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LoopAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LoopAnalysis.java @@ -83,7 +83,7 @@ public class Pass3LoopAnalysis extends Pass2Base { } } - getProgram().setLoops(loopSet); + getProgram().setLoopSet(loopSet); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/StatementSequenceGenerator.java similarity index 96% rename from src/main/java/dk/camelot64/kickc/passes/Pass1GenerateStatementSequence.java rename to src/main/java/dk/camelot64/kickc/passes/StatementSequenceGenerator.java index 5c28b573b..39efdb4f6 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/StatementSequenceGenerator.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.CompileLog; +import dk.camelot64.kickc.Compiler; import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.parser.KickCBaseVisitor; @@ -15,23 +15,19 @@ import java.util.Stack; /** * Generates program SSA form by visiting the ANTLR4 parse tree */ -public class Pass1GenerateStatementSequence extends KickCBaseVisitor { +public class StatementSequenceGenerator extends KickCBaseVisitor { private Program program; private Stack scopeStack; private StatementSequence sequence; - public Pass1GenerateStatementSequence(CompileLog log) { - this.program = new Program(new ProgramScope(), log); + public StatementSequenceGenerator(Program program) { + this.program = program; this.scopeStack = new Stack<>(); scopeStack.push(program.getScope()); this.sequence = new StatementSequence(); } - public ProgramScope getProgramScope() { - return program.getScope(); - } - private Scope getCurrentSymbols() { return scopeStack.peek(); } @@ -47,7 +43,6 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { public void generate(KickCParser.FileContext file) { this.visit(file); - sequence.addStatement(new StatementCall(null, "main", new ArrayList())); } @Override @@ -68,9 +63,10 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { @Override public Object visitImportDecl(KickCParser.ImportDeclContext ctx) { String importName = ctx.STRING().getText(); - program.getLog().append("Importing "+importName.substring(1, importName.length() - 1)); - throw new RuntimeException("TODO: Implement importing!"); - //return null; + String importFileName = importName.substring(1, importName.length() - 1); + program.getLog().append("Importing "+ importFileName); + Compiler.loadAndParseFile(importFileName, program, this); + return null; } @Override @@ -638,9 +634,9 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { private List postMods; private List preMods; - private Pass1GenerateStatementSequence mainParser; + private StatementSequenceGenerator mainParser; - public PrePostModifierHandler(Pass1GenerateStatementSequence mainParser) { + public PrePostModifierHandler(StatementSequenceGenerator mainParser) { this.mainParser = mainParser; preMods = new ArrayList<>(); postMods = new ArrayList<>(); @@ -654,14 +650,14 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { return postMods; } - public static void addPostModifiers(Pass1GenerateStatementSequence parser, ParserRuleContext ctx) { + public static void addPostModifiers(StatementSequenceGenerator parser, ParserRuleContext ctx) { PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser); prePostModifierHandler.visit(ctx); List modifiers = prePostModifierHandler.getPostMods(); addModifierStatements(parser, modifiers); } - public static void addPreModifiers(Pass1GenerateStatementSequence parser, ParserRuleContext ctx) { + public static void addPreModifiers(StatementSequenceGenerator parser, ParserRuleContext ctx) { PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser); modifierHandler.visit(ctx); List modifiers = modifierHandler.getPreMods(); @@ -669,7 +665,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { } private static void addModifierStatements( - Pass1GenerateStatementSequence parser, + StatementSequenceGenerator parser, List modifiers) { for (PrePostModifier mod : modifiers) { Statement stmt = new StatementAssignment((LValue) mod.child, mod.operator, mod.child); diff --git a/src/main/java/dk/camelot64/kickc/test/TestErrors.java b/src/main/java/dk/camelot64/kickc/test/TestErrors.java index d2f4324a8..0744a982b 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestErrors.java +++ b/src/main/java/dk/camelot64/kickc/test/TestErrors.java @@ -53,11 +53,10 @@ public class TestErrors extends TestCase { } private void testFile(String fileName) throws IOException, URISyntaxException { - String inputPath = testPath + fileName + ".kc"; - System.out.println("Testing output for " + inputPath); - CharStream input = CharStreams.fromFileName(inputPath); + System.out.println("Testing output for " + fileName); Compiler compiler = new Compiler(); - Program program = compiler.compile(input); + compiler.addImportPath(testPath); + Program program = compiler.compile(fileName); boolean success = true; success &= helper.testOutput(fileName, ".asm", program.getAsm().toString(false)); success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program)); diff --git a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java index b84ec5542..75e176494 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java @@ -282,11 +282,10 @@ public class TestPrograms extends TestCase { } private void testFile(String fileName) throws IOException, URISyntaxException { - String inputPath = testPath + fileName + ".kc"; - System.out.println("Testing output for " + inputPath); - CharStream input = CharStreams.fromFileName(inputPath); + System.out.println("Testing output for " + fileName); Compiler compiler = new Compiler(); - Program program = compiler.compile(input); + compiler.addImportPath(testPath); + Program program = compiler.compile(fileName); boolean success = true; success &= helper.testOutput(fileName, ".asm", program.getAsm().toString(false)); success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program)); diff --git a/src/main/java/dk/camelot64/kickc/test/ref/importing.asm b/src/main/java/dk/camelot64/kickc/test/ref/importing.asm new file mode 100644 index 000000000..5d04c1e32 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/importing.asm @@ -0,0 +1,14 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const BGCOL = $d021 + .const RED = 2 + jsr main +main: { + .const screen = $400 + lda #1 + sta screen + lda #RED + sta BGCOL + rts +} diff --git a/src/main/java/dk/camelot64/kickc/test/ref/importing.cfg b/src/main/java/dk/camelot64/kickc/test/ref/importing.cfg new file mode 100644 index 000000000..8f9f10f2d --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/importing.cfg @@ -0,0 +1,16 @@ +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@1 +@1: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main param-assignment [ ] ( ) + to:@end +@end: scope:[] from @1 + [3] phi() [ ] ( ) +main: scope:[main] from @1 + [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) + [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) + to:main::@return +main::@return: scope:[main] from main + [6] return [ ] ( main:2 [ ] ) + to:@return diff --git a/src/main/java/dk/camelot64/kickc/test/ref/importing.log b/src/main/java/dk/camelot64/kickc/test/ref/importing.log new file mode 100644 index 000000000..9782c5076 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/importing.log @@ -0,0 +1,568 @@ +import "imported.kc" + +void main() { + byte* screen = $0400; + *screen = 1; + *BGCOL = RED; +} +Importing imported.kc +const byte *BGCOL = $d021; +const byte RED = 2; + +PROGRAM + (byte*) BGCOL ← (word) 53281 + (byte) RED ← (byte/signed byte/word/signed word) 2 +proc (void()) main() + (byte*) main::screen ← (word/signed word) 1024 + *((byte*) main::screen) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL) ← (byte) RED +main::@return: + return +endproc // main() + call main + +SYMBOLS +(byte*) BGCOL +(byte) RED +(void()) main() +(label) main::@return +(byte*) main::screen + +Promoting word to byte* in BGCOL ← ((byte*)) 53281 +Promoting word/signed word to byte* in main::screen ← ((byte*)) 1024 +INITIAL CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) BGCOL ← ((byte*)) (word) 53281 + (byte) RED ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from + (byte*) main::screen ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL) ← (byte) RED + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main + to:@end +@end: scope:[] from @1 + +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) BGCOL ← ((byte*)) (word) 53281 + (byte) RED ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from + (byte*) main::screen ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL) ← (byte) RED + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main + to:@end +@end: scope:[] from @1 + +PROCEDURE MODIFY VARIABLE ANALYSIS + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL +@begin: scope:[] from + (byte*) BGCOL ← ((byte*)) (word) 53281 + (byte) RED ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) main::screen ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL) ← (byte) RED + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +Completing Phi functions... +Completing Phi functions... +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) BGCOL#0 ← ((byte*)) (word) 53281 + (byte) RED#0 ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 ) + (byte) RED#1 ← phi( @1/(byte) RED#2 ) + (byte*) main::screen#0 ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL#1) ← (byte) RED#1 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + (byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 ) + (byte) RED#2 ← phi( @begin/(byte) RED#0 ) + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN +@begin: scope:[] from + (byte*) BGCOL#0 ← ((byte*)) (word) 53281 + (byte) RED#0 ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 ) + (byte) RED#1 ← phi( @1/(byte) RED#2 ) + (byte*) main::screen#0 ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL#1) ← (byte) RED#1 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + (byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 ) + (byte) RED#2 ← phi( @begin/(byte) RED#0 ) + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +INITIAL SSA SYMBOL TABLE +(label) @1 +(label) @2 +(label) @begin +(label) @end +(byte*) BGCOL +(byte*) BGCOL#0 +(byte*) BGCOL#1 +(byte*) BGCOL#2 +(byte) RED +(byte) RED#0 +(byte) RED#1 +(byte) RED#2 +(void()) main() +(label) main::@return +(byte*) main::screen +(byte*) main::screen#0 + +Culled Empty Block (label) @2 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) BGCOL#0 ← ((byte*)) (word) 53281 + (byte) RED#0 ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 ) + (byte) RED#1 ← phi( @1/(byte) RED#2 ) + (byte*) main::screen#0 ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL#1) ← (byte) RED#1 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + (byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 ) + (byte) RED#2 ← phi( @begin/(byte) RED#0 ) + call main param-assignment + to:@end +@end: scope:[] from @1 + +Not aliassing across scopes: RED#1 RED#2 +Not aliassing across scopes: BGCOL#1 BGCOL#2 +Alias (byte) RED#0 = (byte) RED#2 +Alias (byte*) BGCOL#0 = (byte*) BGCOL#2 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) BGCOL#0 ← ((byte*)) (word) 53281 + (byte) RED#0 ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#0 ) + (byte) RED#1 ← phi( @1/(byte) RED#0 ) + (byte*) main::screen#0 ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL#1) ← (byte) RED#1 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Not aliassing across scopes: RED#1 RED#0 +Not aliassing across scopes: BGCOL#1 BGCOL#0 +Redundant Phi (byte) RED#1 (byte) RED#0 +Redundant Phi (byte*) BGCOL#1 (byte*) BGCOL#0 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) BGCOL#0 ← ((byte*)) (word) 53281 + (byte) RED#0 ← (byte/signed byte/word/signed word) 2 + to:@1 +main: scope:[main] from @1 + (byte*) main::screen#0 ← ((byte*)) (word/signed word) 1024 + *((byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((byte*) BGCOL#0) ← (byte) RED#0 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Constant (const byte*) BGCOL#0 = ((byte*))53281 +Constant (const byte) RED#0 = 2 +Constant (const byte*) main::screen#0 = ((byte*))1024 +Succesful SSA optimization Pass2ConstantIdentification +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((const byte*) BGCOL#0) ← (const byte) RED#0 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 = ((byte*))(word) 53281 +(byte) RED +(const byte) RED#0 = (byte/signed byte/word/signed word) 2 +(void()) main() +(label) main::@return +(byte*) main::screen +(const byte*) main::screen#0 = ((byte*))(word/signed word) 1024 + +Block Sequence Planned @begin @1 @end main main::@return +Block Sequence Planned @begin @1 @end main main::@return +CONTROL FLOW GRAPH - PHI LIFTED +@begin: scope:[] from + to:@1 +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 +main: scope:[main] from @1 + *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 + *((const byte*) BGCOL#0) ← (const byte) RED#0 + to:main::@return +main::@return: scope:[main] from main + return + to:@return + +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES FOUND +@begin: scope:[] from + [0] phi() [ ] + to:@1 +@1: scope:[] from @begin + [1] phi() [ ] + [2] call main param-assignment [ ] + to:@end +@end: scope:[] from @1 + [3] phi() [ ] +main: scope:[main] from @1 + [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] + [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] + to:main::@return +main::@return: scope:[main] from main + [6] return [ ] + to:@return + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Block Sequence Planned @begin @1 @end main main::@return +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Propagating live ranges... +CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES +@begin: scope:[] from + [0] phi() [ ] + to:@1 +@1: scope:[] from @begin + [1] phi() [ ] + [2] call main param-assignment [ ] + to:@end +@end: scope:[] from @1 + [3] phi() [ ] +main: scope:[main] from @1 + [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] + [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] + to:main::@return +main::@return: scope:[main] from main + [6] return [ ] + to:@return + +CONTROL FLOW GRAPH - PHI MEM COALESCED +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@1 +@1: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main param-assignment [ ] ( ) + to:@end +@end: scope:[] from @1 + [3] phi() [ ] ( ) +main: scope:[main] from @1 + [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) + [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) + to:main::@return +main::@return: scope:[main] from main + [6] return [ ] ( main:2 [ ] ) + to:@return + +DOMINATORS +@begin dominated by @begin +@1 dominated by @1 @begin +@end dominated by @1 @begin @end +main dominated by @1 @begin main +main::@return dominated by main::@return @1 @begin main + +NATURAL LOOPS + +Found 0 loops in scope [] +Found 0 loops in scope [main] +NATURAL LOOPS WITH DEPTH + + +VARIABLE REGISTER WEIGHTS +(byte*) BGCOL +(byte) RED +(void()) main() +(byte*) main::screen + +Initial phi equivalence classes +Complete equivalence classes +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const BGCOL = $d021 + .const RED = 2 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG4 @1 +b1: +//SEG5 [2] call main param-assignment [ ] ( ) + jsr main +//SEG6 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + .const screen = $400 + //SEG9 [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #1 + sta screen + //SEG10 [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #RED + sta BGCOL + jmp breturn + //SEG11 main::@return + breturn: + //SEG12 [6] return [ ] ( main:2 [ ] ) + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 33 combination +Uplifting [] best 33 combination +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const BGCOL = $d021 + .const RED = 2 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: +//SEG4 @1 +b1: +//SEG5 [2] call main param-assignment [ ] ( ) + jsr main +//SEG6 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: +//SEG7 @end +bend: +//SEG8 main +main: { + .const screen = $400 + //SEG9 [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #1 + sta screen + //SEG10 [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #RED + sta BGCOL + //SEG11 main::@return + breturn: + //SEG12 [6] return [ ] ( main:2 [ ] ) + rts +} + +Removing instruction bbegin: +Removing instruction b1_from_bbegin: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const BGCOL = $d021 + .const RED = 2 +//SEG2 @begin +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG4 @1 +b1: +//SEG5 [2] call main param-assignment [ ] ( ) + jsr main +//SEG6 [3] phi from @1 to @end [phi:@1->@end] +//SEG7 @end +bend: +//SEG8 main +main: { + .const screen = $400 + //SEG9 [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #1 + sta screen + //SEG10 [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #RED + sta BGCOL + //SEG11 main::@return + breturn: + //SEG12 [6] return [ ] ( main:2 [ ] ) + rts +} + +Removing instruction b1: +Removing instruction bend: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const BGCOL = $d021 + .const RED = 2 +//SEG2 @begin +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG4 @1 +//SEG5 [2] call main param-assignment [ ] ( ) + jsr main +//SEG6 [3] phi from @1 to @end [phi:@1->@end] +//SEG7 @end +//SEG8 main +main: { + .const screen = $400 + //SEG9 [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #1 + sta screen + //SEG10 [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #RED + sta BGCOL + //SEG11 main::@return + //SEG12 [6] return [ ] ( main:2 [ ] ) + rts +} + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word) 53281 +(byte) RED +(const byte) RED#0 RED = (byte/signed byte/word/signed word) 2 +(void()) main() +(label) main::@return +(byte*) main::screen +(const byte*) main::screen#0 screen = ((byte*))(word/signed word) 1024 + + +FINAL CODE +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const BGCOL = $d021 + .const RED = 2 +//SEG2 @begin +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG4 @1 +//SEG5 [2] call main param-assignment [ ] ( ) + jsr main +//SEG6 [3] phi from @1 to @end [phi:@1->@end] +//SEG7 @end +//SEG8 main +main: { + .const screen = $400 + //SEG9 [4] *((const byte*) main::screen#0) ← (byte/signed byte/word/signed word) 1 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #1 + sta screen + //SEG10 [5] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2 + lda #RED + sta BGCOL + //SEG11 main::@return + //SEG12 [6] return [ ] ( main:2 [ ] ) + rts +} + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/importing.sym b/src/main/java/dk/camelot64/kickc/test/ref/importing.sym new file mode 100644 index 000000000..f3d182b84 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/importing.sym @@ -0,0 +1,12 @@ +(label) @1 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word) 53281 +(byte) RED +(const byte) RED#0 RED = (byte/signed byte/word/signed word) 2 +(void()) main() +(label) main::@return +(byte*) main::screen +(const byte*) main::screen#0 screen = ((byte*))(word/signed word) 1024 +