From 39e5b5a89416b1902c1f25ab0c753d16a1c2464c Mon Sep 17 00:00:00 2001
From: jespergravgaard
Date: Sun, 21 May 2017 12:56:11 +0200
Subject: [PATCH] Added do {} while(). Fixed relative jump labels. Added fib2 &
y-usage.
---
src/dk/camelot64/kickc/asm/AsmFragment.java | 14 +-
.../kickc/asm/fragment/xby_neq_0_then_la1.asm | 2 +
.../kickc/asm/fragment/yby=coby1.asm | 1 +
.../kickc/asm/fragment/yby=zpby1.asm | 1 +
.../asm/fragment/zpby1=yby_plus_zpby2.asm | 4 +
.../camelot64/kickc/icl/ControlFlowBlock.java | 8 +
.../icl/Pass1GenerateStatementSequence.java | 12 +
.../kickc/icl/Pass3RegisterAllocation.java | 6 +-
.../kickc/icl/Pass4CodeGeneration.java | 13 +-
.../kickc/icl/RegisterAllocation.java | 26 +-
src/dk/camelot64/kickc/parser/KickC.g4 | 1 +
src/dk/camelot64/kickc/parser/KickC.tokens | 68 ++---
.../kickc/parser/KickCBaseListener.java | 12 +
.../kickc/parser/KickCBaseVisitor.java | 7 +
src/dk/camelot64/kickc/parser/KickCLexer.java | 247 +++++++++---------
.../camelot64/kickc/parser/KickCLexer.tokens | 68 ++---
.../camelot64/kickc/parser/KickCListener.java | 12 +
.../camelot64/kickc/parser/KickCParser.java | 180 ++++++++-----
.../camelot64/kickc/parser/KickCVisitor.java | 7 +
src/dk/camelot64/kickc/test/Main.java | 13 +-
src/dk/camelot64/kickc/test/fib2.kc | 10 +
21 files changed, 437 insertions(+), 275 deletions(-)
create mode 100644 src/dk/camelot64/kickc/asm/fragment/xby_neq_0_then_la1.asm
create mode 100644 src/dk/camelot64/kickc/asm/fragment/yby=coby1.asm
create mode 100644 src/dk/camelot64/kickc/asm/fragment/yby=zpby1.asm
create mode 100644 src/dk/camelot64/kickc/asm/fragment/zpby1=yby_plus_zpby2.asm
create mode 100644 src/dk/camelot64/kickc/test/fib2.kc
diff --git a/src/dk/camelot64/kickc/asm/AsmFragment.java b/src/dk/camelot64/kickc/asm/AsmFragment.java
index c1f0aa66f..3df80db4f 100644
--- a/src/dk/camelot64/kickc/asm/AsmFragment.java
+++ b/src/dk/camelot64/kickc/asm/AsmFragment.java
@@ -32,7 +32,7 @@ public class AsmFragment {
*/
private String signature;
- public AsmFragment(StatementConditionalJump conditionalJump, SymbolTable symbols) {
+ public AsmFragment(StatementConditionalJump conditionalJump, SymbolTable symbols, ControlFlowGraph graph, ControlFlowBlock block) {
this.bindings = new HashMap<>();
this.symbols = symbols;
StringBuilder signature = new StringBuilder();
@@ -48,7 +48,13 @@ public class AsmFragment {
signature.append(bind(conditionalJump.getRValue2()));
}
signature.append("_then_");
- signature.append(bind(conditionalJump.getDestination()));
+ Label destination = conditionalJump.getDestination();
+ ControlFlowBlock destinationBlock = graph.getBlock(destination);
+ String destinationLabel = destination.getName();
+ if(destinationBlock.hasPhiStatements()) {
+ destinationLabel = destination.getName()+"_from_"+block.getLabel().getName();
+ }
+ signature.append(bind(new Label(destinationLabel, false)));
setSignature(signature.toString());
}
@@ -172,6 +178,10 @@ public class AsmFragment {
String name = "xby";
bindings.put(name, value);
return name;
+ } else if (RegisterAllocation.RegisterType.REG_Y_BYTE.equals(register.getType())) {
+ String name = "yby";
+ bindings.put(name, value);
+ return name;
} else {
throw new RuntimeException("Binding of register type not supported " + register.getType());
}
diff --git a/src/dk/camelot64/kickc/asm/fragment/xby_neq_0_then_la1.asm b/src/dk/camelot64/kickc/asm/fragment/xby_neq_0_then_la1.asm
new file mode 100644
index 000000000..0f99f0508
--- /dev/null
+++ b/src/dk/camelot64/kickc/asm/fragment/xby_neq_0_then_la1.asm
@@ -0,0 +1,2 @@
+cpx #0
+bne {la1}
\ No newline at end of file
diff --git a/src/dk/camelot64/kickc/asm/fragment/yby=coby1.asm b/src/dk/camelot64/kickc/asm/fragment/yby=coby1.asm
new file mode 100644
index 000000000..c9907eace
--- /dev/null
+++ b/src/dk/camelot64/kickc/asm/fragment/yby=coby1.asm
@@ -0,0 +1 @@
+ldy #{coby1}
\ No newline at end of file
diff --git a/src/dk/camelot64/kickc/asm/fragment/yby=zpby1.asm b/src/dk/camelot64/kickc/asm/fragment/yby=zpby1.asm
new file mode 100644
index 000000000..cc9e7b012
--- /dev/null
+++ b/src/dk/camelot64/kickc/asm/fragment/yby=zpby1.asm
@@ -0,0 +1 @@
+ldy {zpby1}
\ No newline at end of file
diff --git a/src/dk/camelot64/kickc/asm/fragment/zpby1=yby_plus_zpby2.asm b/src/dk/camelot64/kickc/asm/fragment/zpby1=yby_plus_zpby2.asm
new file mode 100644
index 000000000..56a5f591f
--- /dev/null
+++ b/src/dk/camelot64/kickc/asm/fragment/zpby1=yby_plus_zpby2.asm
@@ -0,0 +1,4 @@
+tya
+clc
+adc {zpby2}
+sta {zpby1}
\ No newline at end of file
diff --git a/src/dk/camelot64/kickc/icl/ControlFlowBlock.java b/src/dk/camelot64/kickc/icl/ControlFlowBlock.java
index 07beaf984..12d411846 100644
--- a/src/dk/camelot64/kickc/icl/ControlFlowBlock.java
+++ b/src/dk/camelot64/kickc/icl/ControlFlowBlock.java
@@ -104,4 +104,12 @@ public class ControlFlowBlock {
return label.hashCode();
}
+ public boolean hasPhiStatements() {
+ if(statements.size()>0) {
+ if(statements.get(0) instanceof StatementPhi) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java b/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java
index 41bc59f0e..5de45ba40 100644
--- a/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java
+++ b/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java
@@ -97,6 +97,18 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor {
return null;
}
+ @Override
+ public RValue visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) {
+ Label beginJumpLabel = symbolTable.newIntermediateJumpLabel();
+ StatementJumpTarget beginJumpTarget = new StatementJumpTarget(beginJumpLabel);
+ sequence.addStatement(beginJumpTarget);
+ this.visit(ctx.stmt());
+ RValue rValue = this.visit(ctx.expr());
+ Statement doJmpStmt = new StatementConditionalJump(rValue, beginJumpLabel);
+ sequence.addStatement(doJmpStmt);
+ return null;
+ }
+
@Override
public RValue visitStmtAssignment(KickCParser.StmtAssignmentContext ctx) {
if(ctx.TYPE()!=null) {
diff --git a/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java b/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java
index be44c4180..05efa95c0 100644
--- a/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java
+++ b/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java
@@ -23,9 +23,9 @@ public class Pass3RegisterAllocation {
}
}
allocation.allocate(symbols.getVariable("i#1"), RegisterAllocation.getRegisterX());
- allocation.allocate(symbols.getVariable("i#3"), RegisterAllocation.getRegisterX());
- allocation.allocate(symbols.getVariable("n1#1"), new RegisterAllocation.RegisterZpByte(8));
- allocation.allocate(symbols.getVariable("n1#2"), new RegisterAllocation.RegisterZpByte(8));
+ allocation.allocate(symbols.getVariable("i#2"), RegisterAllocation.getRegisterX());
+ allocation.allocate(symbols.getVariable("n1#1"), RegisterAllocation.getRegisterY());
+ allocation.allocate(symbols.getVariable("n1#2"), RegisterAllocation.getRegisterY());
symbols.setAllocation(allocation);
}
diff --git a/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java b/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java
index cc8184b7f..08499a86e 100644
--- a/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java
+++ b/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java
@@ -2,8 +2,6 @@ package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.asm.*;
-import java.util.List;
-
/**
* Code Generation of 6502 Assembler from ICL/SSA Control Flow Graph
*/
@@ -29,7 +27,7 @@ public class Pass4CodeGeneration {
// Generate exit
ControlFlowBlock defaultSuccessor = block.getDefaultSuccessor();
if (defaultSuccessor != null) {
- if(defaultSuccessor.getStatements().size()>0 && defaultSuccessor.getStatements().get(0) instanceof StatementPhi) {
+ if(defaultSuccessor.hasPhiStatements()) {
genBlockPhiTransition(asm, block, defaultSuccessor);
}
asm.addInstruction("JMP", AsmAddressingMode.ABS, defaultSuccessor.getLabel().getName().replace('@', 'B'));
@@ -41,18 +39,18 @@ public class Pass4CodeGeneration {
private void genStatements(AsmProgram asm, ControlFlowBlock block) {
for (Statement statement : block.getStatements()) {
if (!(statement instanceof StatementPhi)) {
- genStatement(asm, statement);
+ genStatement(asm, statement, block);
}
}
}
- private void genStatement(AsmProgram asm, Statement statement) {
+ private void genStatement(AsmProgram asm, Statement statement, ControlFlowBlock block) {
if (statement instanceof StatementAssignment) {
AsmFragment asmFragment = new AsmFragment((StatementAssignment) statement, symbols);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else if (statement instanceof StatementConditionalJump) {
- AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, symbols);
+ AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, symbols, graph, block);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else {
@@ -61,8 +59,7 @@ public class Pass4CodeGeneration {
}
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
- List statements = block.getStatements();
- if (statements.size() > 0 && (statements.get(0) instanceof StatementPhi)) {
+ if(block.hasPhiStatements()) {
for (ControlFlowBlock predecessor : block.getPredecessors()) {
if(block.equals(predecessor.getConditionalSuccessor())) {
genBlockPhiTransition(asm, predecessor, block);
diff --git a/src/dk/camelot64/kickc/icl/RegisterAllocation.java b/src/dk/camelot64/kickc/icl/RegisterAllocation.java
index 683be78ea..69b9069bd 100644
--- a/src/dk/camelot64/kickc/icl/RegisterAllocation.java
+++ b/src/dk/camelot64/kickc/icl/RegisterAllocation.java
@@ -36,7 +36,7 @@ public class RegisterAllocation {
/** The register type. */
public enum RegisterType {
- ZP_BYTE, ZP_BOOL, REG_X_BYTE
+ ZP_BYTE, ZP_BOOL, REG_Y_BYTE, REG_X_BYTE
};
/** A zero page address used as a register for a single byte variable. */
@@ -136,10 +136,34 @@ public class RegisterAllocation {
}
}
+ /** The Y register. */
+ public static class RegisterYByte implements Register {
+ @Override
+ public RegisterType getType() {
+ return RegisterType.REG_Y_BYTE;
+ }
+
+ @Override
+ public String toString() {
+ return "reg byte y";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ return true;
+ }
+ }
+
public static Register getRegisterX() {
return new RegisterXByte();
}
+ public static Register getRegisterY() {
+ return new RegisterYByte();
+ }
+
@Override
public String toString() {
StringBuffer out = new StringBuffer();
diff --git a/src/dk/camelot64/kickc/parser/KickC.g4 b/src/dk/camelot64/kickc/parser/KickC.g4
index 791e091e2..19ad17d2e 100644
--- a/src/dk/camelot64/kickc/parser/KickC.g4
+++ b/src/dk/camelot64/kickc/parser/KickC.g4
@@ -15,6 +15,7 @@ stmt
| expr ';' #stmtExpr
| 'if' '(' expr ')' stmt ( 'else' stmt )? #stmtIfElse
| 'while' '(' expr ')' stmt #stmtWhile
+ | 'do' stmt 'while' '(' expr ')' #stmtDoWhile
;
diff --git a/src/dk/camelot64/kickc/parser/KickC.tokens b/src/dk/camelot64/kickc/parser/KickC.tokens
index 69c474e0f..fb63df5b8 100644
--- a/src/dk/camelot64/kickc/parser/KickC.tokens
+++ b/src/dk/camelot64/kickc/parser/KickC.tokens
@@ -26,20 +26,21 @@ T__24=25
T__25=26
T__26=27
T__27=28
-TYPE=29
-STRING=30
-BOOLEAN=31
-NUMBER=32
-NUMFLOAT=33
-BINFLOAT=34
-DECFLOAT=35
-HEXFLOAT=36
-NUMINT=37
-BININTEGER=38
-DECINTEGER=39
-HEXINTEGER=40
-NAME=41
-WS=42
+T__28=29
+TYPE=30
+STRING=31
+BOOLEAN=32
+NUMBER=33
+NUMFLOAT=34
+BINFLOAT=35
+DECFLOAT=36
+HEXFLOAT=37
+NUMINT=38
+BININTEGER=39
+DECINTEGER=40
+HEXINTEGER=41
+NAME=42
+WS=43
'{'=1
'}'=2
'='=3
@@ -49,22 +50,23 @@ WS=42
')'=7
'else'=8
'while'=9
-'+'=10
-'-'=11
-'not'=12
-'!'=13
-'*'=14
-'/'=15
-'=='=16
-'!='=17
-'<>'=18
-'<'=19
-'<='=20
-'=<'=21
-'>='=22
-'=>'=23
-'>'=24
-'and'=25
-'&&'=26
-'or'=27
-'||'=28
+'do'=10
+'+'=11
+'-'=12
+'not'=13
+'!'=14
+'*'=15
+'/'=16
+'=='=17
+'!='=18
+'<>'=19
+'<'=20
+'<='=21
+'=<'=22
+'>='=23
+'=>'=24
+'>'=25
+'and'=26
+'&&'=27
+'or'=28
+'||'=29
diff --git a/src/dk/camelot64/kickc/parser/KickCBaseListener.java b/src/dk/camelot64/kickc/parser/KickCBaseListener.java
index dd59af9bd..1f24d9c7f 100644
--- a/src/dk/camelot64/kickc/parser/KickCBaseListener.java
+++ b/src/dk/camelot64/kickc/parser/KickCBaseListener.java
@@ -95,6 +95,18 @@ public class KickCBaseListener implements KickCListener {
* The default implementation does nothing.
*/
@Override public void exitStmtWhile(KickCParser.StmtWhileContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterStmtDoWhile(KickCParser.StmtDoWhileContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) { }
/**
* {@inheritDoc}
*
diff --git a/src/dk/camelot64/kickc/parser/KickCBaseVisitor.java b/src/dk/camelot64/kickc/parser/KickCBaseVisitor.java
index 01e0a560f..bbaa7ecaf 100644
--- a/src/dk/camelot64/kickc/parser/KickCBaseVisitor.java
+++ b/src/dk/camelot64/kickc/parser/KickCBaseVisitor.java
@@ -60,6 +60,13 @@ public class KickCBaseVisitor extends AbstractParseTreeVisitor implements
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitStmtWhile(KickCParser.StmtWhileContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
diff --git a/src/dk/camelot64/kickc/parser/KickCLexer.java b/src/dk/camelot64/kickc/parser/KickCLexer.java
index 57d8252cc..ffa71b9e2 100644
--- a/src/dk/camelot64/kickc/parser/KickCLexer.java
+++ b/src/dk/camelot64/kickc/parser/KickCLexer.java
@@ -20,9 +20,9 @@ public class KickCLexer extends Lexer {
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
- T__24=25, T__25=26, T__26=27, T__27=28, TYPE=29, STRING=30, BOOLEAN=31,
- NUMBER=32, NUMFLOAT=33, BINFLOAT=34, DECFLOAT=35, HEXFLOAT=36, NUMINT=37,
- BININTEGER=38, DECINTEGER=39, HEXINTEGER=40, NAME=41, WS=42;
+ T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, TYPE=30, STRING=31,
+ BOOLEAN=32, NUMBER=33, NUMFLOAT=34, BINFLOAT=35, DECFLOAT=36, HEXFLOAT=37,
+ NUMINT=38, BININTEGER=39, DECINTEGER=40, HEXINTEGER=41, NAME=42, WS=43;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@@ -35,23 +35,24 @@ public class KickCLexer extends Lexer {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
- "T__25", "T__26", "T__27", "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
- "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
- "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME", "NAME_START",
- "NAME_CHAR", "WS"
+ "T__25", "T__26", "T__27", "T__28", "TYPE", "STRING", "BOOLEAN", "NUMBER",
+ "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
+ "DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME",
+ "NAME_START", "NAME_CHAR", "WS"
};
private static final String[] _LITERAL_NAMES = {
null, "'{'", "'}'", "'='", "';'", "'if'", "'('", "')'", "'else'", "'while'",
- "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'", "'<'",
- "'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'", "'||'"
+ "'do'", "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'",
+ "'<'", "'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'",
+ "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
- "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
- "HEXINTEGER", "NAME", "WS"
+ null, null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER",
+ "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
+ "DECINTEGER", "HEXINTEGER", "NAME", "WS"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -111,121 +112,123 @@ public class KickCLexer extends Lexer {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
- "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2,\u0154\b\1\4\2\t"+
+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2-\u0159\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
- ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3"+
- "\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13"+
- "\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21"+
- "\3\21\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\25\3\25\3\25\3\26\3\26"+
- "\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\32\3\32\3\33"+
- "\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36"+
- "\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36"+
- "\3\36\5\36\u00c5\n\36\3\37\3\37\3\37\3\37\7\37\u00cb\n\37\f\37\16\37\u00ce"+
- "\13\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3 \3 \5 \u00db\n \3!\3!\5!\u00df"+
- "\n!\3\"\3\"\3\"\5\"\u00e4\n\"\3#\3#\3#\3#\3#\5#\u00eb\n#\3#\7#\u00ee\n"+
- "#\f#\16#\u00f1\13#\3#\3#\6#\u00f5\n#\r#\16#\u00f6\3$\7$\u00fa\n$\f$\16"+
- "$\u00fd\13$\3$\3$\6$\u0101\n$\r$\16$\u0102\3%\3%\3%\3%\3%\5%\u010a\n%"+
- "\3%\7%\u010d\n%\f%\16%\u0110\13%\3%\3%\6%\u0114\n%\r%\16%\u0115\3&\3&"+
- "\3&\5&\u011b\n&\3\'\3\'\3\'\6\'\u0120\n\'\r\'\16\'\u0121\3\'\3\'\6\'\u0126"+
- "\n\'\r\'\16\'\u0127\5\'\u012a\n\'\3(\6(\u012d\n(\r(\16(\u012e\3)\3)\3"+
- ")\3)\3)\5)\u0136\n)\3)\6)\u0139\n)\r)\16)\u013a\3*\3*\3+\3+\3,\3,\3-\3"+
- "-\7-\u0145\n-\f-\16-\u0148\13-\3.\3.\3/\3/\3\60\6\60\u014f\n\60\r\60\16"+
- "\60\u0150\3\60\3\60\2\2\61\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25"+
- "\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32"+
- "\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S\2U\2W\2Y+[\2]\2_,"+
- "\3\2\n\3\2$$\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|\6\2\62;"+
- "C\\aac|\5\2\13\f\17\17\"\"\2\u016c\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2"+
- "\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3"+
- "\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2"+
- "\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2"+
- "\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2"+
- "\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2"+
- "\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2"+
- "O\3\2\2\2\2Q\3\2\2\2\2Y\3\2\2\2\2_\3\2\2\2\3a\3\2\2\2\5c\3\2\2\2\7e\3"+
- "\2\2\2\tg\3\2\2\2\13i\3\2\2\2\rl\3\2\2\2\17n\3\2\2\2\21p\3\2\2\2\23u\3"+
- "\2\2\2\25{\3\2\2\2\27}\3\2\2\2\31\177\3\2\2\2\33\u0083\3\2\2\2\35\u0085"+
- "\3\2\2\2\37\u0087\3\2\2\2!\u0089\3\2\2\2#\u008c\3\2\2\2%\u008f\3\2\2\2"+
- "\'\u0092\3\2\2\2)\u0094\3\2\2\2+\u0097\3\2\2\2-\u009a\3\2\2\2/\u009d\3"+
- "\2\2\2\61\u00a0\3\2\2\2\63\u00a2\3\2\2\2\65\u00a6\3\2\2\2\67\u00a9\3\2"+
- "\2\29\u00ac\3\2\2\2;\u00c4\3\2\2\2=\u00c6\3\2\2\2?\u00da\3\2\2\2A\u00de"+
- "\3\2\2\2C\u00e3\3\2\2\2E\u00ea\3\2\2\2G\u00fb\3\2\2\2I\u0109\3\2\2\2K"+
- "\u011a\3\2\2\2M\u0129\3\2\2\2O\u012c\3\2\2\2Q\u0135\3\2\2\2S\u013c\3\2"+
- "\2\2U\u013e\3\2\2\2W\u0140\3\2\2\2Y\u0142\3\2\2\2[\u0149\3\2\2\2]\u014b"+
- "\3\2\2\2_\u014e\3\2\2\2ab\7}\2\2b\4\3\2\2\2cd\7\177\2\2d\6\3\2\2\2ef\7"+
- "?\2\2f\b\3\2\2\2gh\7=\2\2h\n\3\2\2\2ij\7k\2\2jk\7h\2\2k\f\3\2\2\2lm\7"+
- "*\2\2m\16\3\2\2\2no\7+\2\2o\20\3\2\2\2pq\7g\2\2qr\7n\2\2rs\7u\2\2st\7"+
- "g\2\2t\22\3\2\2\2uv\7y\2\2vw\7j\2\2wx\7k\2\2xy\7n\2\2yz\7g\2\2z\24\3\2"+
- "\2\2{|\7-\2\2|\26\3\2\2\2}~\7/\2\2~\30\3\2\2\2\177\u0080\7p\2\2\u0080"+
- "\u0081\7q\2\2\u0081\u0082\7v\2\2\u0082\32\3\2\2\2\u0083\u0084\7#\2\2\u0084"+
- "\34\3\2\2\2\u0085\u0086\7,\2\2\u0086\36\3\2\2\2\u0087\u0088\7\61\2\2\u0088"+
- " \3\2\2\2\u0089\u008a\7?\2\2\u008a\u008b\7?\2\2\u008b\"\3\2\2\2\u008c"+
- "\u008d\7#\2\2\u008d\u008e\7?\2\2\u008e$\3\2\2\2\u008f\u0090\7>\2\2\u0090"+
- "\u0091\7@\2\2\u0091&\3\2\2\2\u0092\u0093\7>\2\2\u0093(\3\2\2\2\u0094\u0095"+
- "\7>\2\2\u0095\u0096\7?\2\2\u0096*\3\2\2\2\u0097\u0098\7?\2\2\u0098\u0099"+
- "\7>\2\2\u0099,\3\2\2\2\u009a\u009b\7@\2\2\u009b\u009c\7?\2\2\u009c.\3"+
- "\2\2\2\u009d\u009e\7?\2\2\u009e\u009f\7@\2\2\u009f\60\3\2\2\2\u00a0\u00a1"+
- "\7@\2\2\u00a1\62\3\2\2\2\u00a2\u00a3\7c\2\2\u00a3\u00a4\7p\2\2\u00a4\u00a5"+
- "\7f\2\2\u00a5\64\3\2\2\2\u00a6\u00a7\7(\2\2\u00a7\u00a8\7(\2\2\u00a8\66"+
- "\3\2\2\2\u00a9\u00aa\7q\2\2\u00aa\u00ab\7t\2\2\u00ab8\3\2\2\2\u00ac\u00ad"+
- "\7~\2\2\u00ad\u00ae\7~\2\2\u00ae:\3\2\2\2\u00af\u00b0\7d\2\2\u00b0\u00b1"+
- "\7{\2\2\u00b1\u00b2\7v\2\2\u00b2\u00c5\7g\2\2\u00b3\u00b4\7y\2\2\u00b4"+
- "\u00b5\7q\2\2\u00b5\u00b6\7t\2\2\u00b6\u00c5\7f\2\2\u00b7\u00b8\7u\2\2"+
- "\u00b8\u00b9\7v\2\2\u00b9\u00ba\7t\2\2\u00ba\u00bb\7k\2\2\u00bb\u00bc"+
- "\7p\2\2\u00bc\u00c5\7i\2\2\u00bd\u00be\7d\2\2\u00be\u00bf\7q\2\2\u00bf"+
- "\u00c0\7q\2\2\u00c0\u00c1\7n\2\2\u00c1\u00c2\7g\2\2\u00c2\u00c3\7c\2\2"+
- "\u00c3\u00c5\7p\2\2\u00c4\u00af\3\2\2\2\u00c4\u00b3\3\2\2\2\u00c4\u00b7"+
- "\3\2\2\2\u00c4\u00bd\3\2\2\2\u00c5<\3\2\2\2\u00c6\u00cc\7$\2\2\u00c7\u00c8"+
- "\7^\2\2\u00c8\u00cb\7$\2\2\u00c9\u00cb\n\2\2\2\u00ca\u00c7\3\2\2\2\u00ca"+
- "\u00c9\3\2\2\2\u00cb\u00ce\3\2\2\2\u00cc\u00ca\3\2\2\2\u00cc\u00cd\3\2"+
- "\2\2\u00cd\u00cf\3\2\2\2\u00ce\u00cc\3\2\2\2\u00cf\u00d0\7$\2\2\u00d0"+
- ">\3\2\2\2\u00d1\u00d2\7v\2\2\u00d2\u00d3\7t\2\2\u00d3\u00d4\7w\2\2\u00d4"+
- "\u00db\7g\2\2\u00d5\u00d6\7h\2\2\u00d6\u00d7\7c\2\2\u00d7\u00d8\7n\2\2"+
- "\u00d8\u00d9\7u\2\2\u00d9\u00db\7g\2\2\u00da\u00d1\3\2\2\2\u00da\u00d5"+
- "\3\2\2\2\u00db@\3\2\2\2\u00dc\u00df\5C\"\2\u00dd\u00df\5K&\2\u00de\u00dc"+
- "\3\2\2\2\u00de\u00dd\3\2\2\2\u00dfB\3\2\2\2\u00e0\u00e4\5E#\2\u00e1\u00e4"+
- "\5G$\2\u00e2\u00e4\5I%\2\u00e3\u00e0\3\2\2\2\u00e3\u00e1\3\2\2\2\u00e3"+
- "\u00e2\3\2\2\2\u00e4D\3\2\2\2\u00e5\u00eb\7\'\2\2\u00e6\u00e7\7\62\2\2"+
- "\u00e7\u00eb\7d\2\2\u00e8\u00e9\7\62\2\2\u00e9\u00eb\7D\2\2\u00ea\u00e5"+
- "\3\2\2\2\u00ea\u00e6\3\2\2\2\u00ea\u00e8\3\2\2\2\u00eb\u00ef\3\2\2\2\u00ec"+
- "\u00ee\5S*\2\u00ed\u00ec\3\2\2\2\u00ee\u00f1\3\2\2\2\u00ef\u00ed\3\2\2"+
- "\2\u00ef\u00f0\3\2\2\2\u00f0\u00f2\3\2\2\2\u00f1\u00ef\3\2\2\2\u00f2\u00f4"+
- "\7\60\2\2\u00f3\u00f5\5S*\2\u00f4\u00f3\3\2\2\2\u00f5\u00f6\3\2\2\2\u00f6"+
- "\u00f4\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7F\3\2\2\2\u00f8\u00fa\5U+\2\u00f9"+
- "\u00f8\3\2\2\2\u00fa\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2"+
- "\2\2\u00fc\u00fe\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fe\u0100\7\60\2\2\u00ff"+
- "\u0101\5U+\2\u0100\u00ff\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0100\3\2\2"+
- "\2\u0102\u0103\3\2\2\2\u0103H\3\2\2\2\u0104\u010a\7&\2\2\u0105\u0106\7"+
- "\62\2\2\u0106\u010a\7z\2\2\u0107\u0108\7\62\2\2\u0108\u010a\7Z\2\2\u0109"+
- "\u0104\3\2\2\2\u0109\u0105\3\2\2\2\u0109\u0107\3\2\2\2\u010a\u010e\3\2"+
- "\2\2\u010b\u010d\5W,\2\u010c\u010b\3\2\2\2\u010d\u0110\3\2\2\2\u010e\u010c"+
- "\3\2\2\2\u010e\u010f\3\2\2\2\u010f\u0111\3\2\2\2\u0110\u010e\3\2\2\2\u0111"+
- "\u0113\7\60\2\2\u0112\u0114\5W,\2\u0113\u0112\3\2\2\2\u0114\u0115\3\2"+
- "\2\2\u0115\u0113\3\2\2\2\u0115\u0116\3\2\2\2\u0116J\3\2\2\2\u0117\u011b"+
- "\5O(\2\u0118\u011b\5Q)\2\u0119\u011b\5M\'\2\u011a\u0117\3\2\2\2\u011a"+
- "\u0118\3\2\2\2\u011a\u0119\3\2\2\2\u011bL\3\2\2\2\u011c\u011d\7\62\2\2"+
- "\u011d\u011f\t\3\2\2\u011e\u0120\5S*\2\u011f\u011e\3\2\2\2\u0120\u0121"+
- "\3\2\2\2\u0121\u011f\3\2\2\2\u0121\u0122\3\2\2\2\u0122\u012a\3\2\2\2\u0123"+
- "\u0125\7\'\2\2\u0124\u0126\5S*\2\u0125\u0124\3\2\2\2\u0126\u0127\3\2\2"+
- "\2\u0127\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u012a\3\2\2\2\u0129\u011c"+
- "\3\2\2\2\u0129\u0123\3\2\2\2\u012aN\3\2\2\2\u012b\u012d\5U+\2\u012c\u012b"+
- "\3\2\2\2\u012d\u012e\3\2\2\2\u012e\u012c\3\2\2\2\u012e\u012f\3\2\2\2\u012f"+
- "P\3\2\2\2\u0130\u0136\7&\2\2\u0131\u0132\7\62\2\2\u0132\u0136\7z\2\2\u0133"+
- "\u0134\7\62\2\2\u0134\u0136\7Z\2\2\u0135\u0130\3\2\2\2\u0135\u0131\3\2"+
- "\2\2\u0135\u0133\3\2\2\2\u0136\u0138\3\2\2\2\u0137\u0139\5W,\2\u0138\u0137"+
- "\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b"+
- "R\3\2\2\2\u013c\u013d\t\4\2\2\u013dT\3\2\2\2\u013e\u013f\t\5\2\2\u013f"+
- "V\3\2\2\2\u0140\u0141\t\6\2\2\u0141X\3\2\2\2\u0142\u0146\5[.\2\u0143\u0145"+
- "\5]/\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\u0147Z\3\2\2\2\u0148\u0146\3\2\2\2\u0149\u014a\t\7\2\2"+
- "\u014a\\\3\2\2\2\u014b\u014c\t\b\2\2\u014c^\3\2\2\2\u014d\u014f\t\t\2"+
- "\2\u014e\u014d\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151"+
- "\3\2\2\2\u0151\u0152\3\2\2\2\u0152\u0153\b\60\2\2\u0153`\3\2\2\2\32\2"+
- "\u00c4\u00ca\u00cc\u00da\u00de\u00e3\u00ea\u00ef\u00f6\u00fb\u0102\u0109"+
- "\u010e\u0115\u011a\u0121\u0127\u0129\u012e\u0135\u013a\u0146\u0150\3\b"+
+ ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\3\2\3\2\3\3\3\3\3\4\3\4\3\5"+
+ "\3\5\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3"+
+ "\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\16\3\16\3\17\3\17\3"+
+ "\20\3\20\3\21\3\21\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3"+
+ "\25\3\26\3\26\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\32\3"+
+ "\32\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3"+
+ "\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3"+
+ "\37\3\37\3\37\3\37\3\37\3\37\3\37\5\37\u00ca\n\37\3 \3 \3 \3 \7 \u00d0"+
+ "\n \f \16 \u00d3\13 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\5!\u00e0\n!\3\""+
+ "\3\"\5\"\u00e4\n\"\3#\3#\3#\5#\u00e9\n#\3$\3$\3$\3$\3$\5$\u00f0\n$\3$"+
+ "\7$\u00f3\n$\f$\16$\u00f6\13$\3$\3$\6$\u00fa\n$\r$\16$\u00fb\3%\7%\u00ff"+
+ "\n%\f%\16%\u0102\13%\3%\3%\6%\u0106\n%\r%\16%\u0107\3&\3&\3&\3&\3&\5&"+
+ "\u010f\n&\3&\7&\u0112\n&\f&\16&\u0115\13&\3&\3&\6&\u0119\n&\r&\16&\u011a"+
+ "\3\'\3\'\3\'\5\'\u0120\n\'\3(\3(\3(\6(\u0125\n(\r(\16(\u0126\3(\3(\6("+
+ "\u012b\n(\r(\16(\u012c\5(\u012f\n(\3)\6)\u0132\n)\r)\16)\u0133\3*\3*\3"+
+ "*\3*\3*\5*\u013b\n*\3*\6*\u013e\n*\r*\16*\u013f\3+\3+\3,\3,\3-\3-\3.\3"+
+ ".\7.\u014a\n.\f.\16.\u014d\13.\3/\3/\3\60\3\60\3\61\6\61\u0154\n\61\r"+
+ "\61\16\61\u0155\3\61\3\61\2\2\62\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23"+
+ "\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31"+
+ "\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U\2W\2Y\2[,"+
+ "]\2_\2a-\3\2\n\3\2$$\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|"+
+ "\6\2\62;C\\aac|\5\2\13\f\17\17\"\"\2\u0171\2\3\3\2\2\2\2\5\3\2\2\2\2\7"+
+ "\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2"+
+ "\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2"+
+ "\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2"+
+ "\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2"+
+ "\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2"+
+ "\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M"+
+ "\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2[\3\2\2\2\2a\3\2\2\2\3c\3\2"+
+ "\2\2\5e\3\2\2\2\7g\3\2\2\2\ti\3\2\2\2\13k\3\2\2\2\rn\3\2\2\2\17p\3\2\2"+
+ "\2\21r\3\2\2\2\23w\3\2\2\2\25}\3\2\2\2\27\u0080\3\2\2\2\31\u0082\3\2\2"+
+ "\2\33\u0084\3\2\2\2\35\u0088\3\2\2\2\37\u008a\3\2\2\2!\u008c\3\2\2\2#"+
+ "\u008e\3\2\2\2%\u0091\3\2\2\2\'\u0094\3\2\2\2)\u0097\3\2\2\2+\u0099\3"+
+ "\2\2\2-\u009c\3\2\2\2/\u009f\3\2\2\2\61\u00a2\3\2\2\2\63\u00a5\3\2\2\2"+
+ "\65\u00a7\3\2\2\2\67\u00ab\3\2\2\29\u00ae\3\2\2\2;\u00b1\3\2\2\2=\u00c9"+
+ "\3\2\2\2?\u00cb\3\2\2\2A\u00df\3\2\2\2C\u00e3\3\2\2\2E\u00e8\3\2\2\2G"+
+ "\u00ef\3\2\2\2I\u0100\3\2\2\2K\u010e\3\2\2\2M\u011f\3\2\2\2O\u012e\3\2"+
+ "\2\2Q\u0131\3\2\2\2S\u013a\3\2\2\2U\u0141\3\2\2\2W\u0143\3\2\2\2Y\u0145"+
+ "\3\2\2\2[\u0147\3\2\2\2]\u014e\3\2\2\2_\u0150\3\2\2\2a\u0153\3\2\2\2c"+
+ "d\7}\2\2d\4\3\2\2\2ef\7\177\2\2f\6\3\2\2\2gh\7?\2\2h\b\3\2\2\2ij\7=\2"+
+ "\2j\n\3\2\2\2kl\7k\2\2lm\7h\2\2m\f\3\2\2\2no\7*\2\2o\16\3\2\2\2pq\7+\2"+
+ "\2q\20\3\2\2\2rs\7g\2\2st\7n\2\2tu\7u\2\2uv\7g\2\2v\22\3\2\2\2wx\7y\2"+
+ "\2xy\7j\2\2yz\7k\2\2z{\7n\2\2{|\7g\2\2|\24\3\2\2\2}~\7f\2\2~\177\7q\2"+
+ "\2\177\26\3\2\2\2\u0080\u0081\7-\2\2\u0081\30\3\2\2\2\u0082\u0083\7/\2"+
+ "\2\u0083\32\3\2\2\2\u0084\u0085\7p\2\2\u0085\u0086\7q\2\2\u0086\u0087"+
+ "\7v\2\2\u0087\34\3\2\2\2\u0088\u0089\7#\2\2\u0089\36\3\2\2\2\u008a\u008b"+
+ "\7,\2\2\u008b \3\2\2\2\u008c\u008d\7\61\2\2\u008d\"\3\2\2\2\u008e\u008f"+
+ "\7?\2\2\u008f\u0090\7?\2\2\u0090$\3\2\2\2\u0091\u0092\7#\2\2\u0092\u0093"+
+ "\7?\2\2\u0093&\3\2\2\2\u0094\u0095\7>\2\2\u0095\u0096\7@\2\2\u0096(\3"+
+ "\2\2\2\u0097\u0098\7>\2\2\u0098*\3\2\2\2\u0099\u009a\7>\2\2\u009a\u009b"+
+ "\7?\2\2\u009b,\3\2\2\2\u009c\u009d\7?\2\2\u009d\u009e\7>\2\2\u009e.\3"+
+ "\2\2\2\u009f\u00a0\7@\2\2\u00a0\u00a1\7?\2\2\u00a1\60\3\2\2\2\u00a2\u00a3"+
+ "\7?\2\2\u00a3\u00a4\7@\2\2\u00a4\62\3\2\2\2\u00a5\u00a6\7@\2\2\u00a6\64"+
+ "\3\2\2\2\u00a7\u00a8\7c\2\2\u00a8\u00a9\7p\2\2\u00a9\u00aa\7f\2\2\u00aa"+
+ "\66\3\2\2\2\u00ab\u00ac\7(\2\2\u00ac\u00ad\7(\2\2\u00ad8\3\2\2\2\u00ae"+
+ "\u00af\7q\2\2\u00af\u00b0\7t\2\2\u00b0:\3\2\2\2\u00b1\u00b2\7~\2\2\u00b2"+
+ "\u00b3\7~\2\2\u00b3<\3\2\2\2\u00b4\u00b5\7d\2\2\u00b5\u00b6\7{\2\2\u00b6"+
+ "\u00b7\7v\2\2\u00b7\u00ca\7g\2\2\u00b8\u00b9\7y\2\2\u00b9\u00ba\7q\2\2"+
+ "\u00ba\u00bb\7t\2\2\u00bb\u00ca\7f\2\2\u00bc\u00bd\7u\2\2\u00bd\u00be"+
+ "\7v\2\2\u00be\u00bf\7t\2\2\u00bf\u00c0\7k\2\2\u00c0\u00c1\7p\2\2\u00c1"+
+ "\u00ca\7i\2\2\u00c2\u00c3\7d\2\2\u00c3\u00c4\7q\2\2\u00c4\u00c5\7q\2\2"+
+ "\u00c5\u00c6\7n\2\2\u00c6\u00c7\7g\2\2\u00c7\u00c8\7c\2\2\u00c8\u00ca"+
+ "\7p\2\2\u00c9\u00b4\3\2\2\2\u00c9\u00b8\3\2\2\2\u00c9\u00bc\3\2\2\2\u00c9"+
+ "\u00c2\3\2\2\2\u00ca>\3\2\2\2\u00cb\u00d1\7$\2\2\u00cc\u00cd\7^\2\2\u00cd"+
+ "\u00d0\7$\2\2\u00ce\u00d0\n\2\2\2\u00cf\u00cc\3\2\2\2\u00cf\u00ce\3\2"+
+ "\2\2\u00d0\u00d3\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2"+
+ "\u00d4\3\2\2\2\u00d3\u00d1\3\2\2\2\u00d4\u00d5\7$\2\2\u00d5@\3\2\2\2\u00d6"+
+ "\u00d7\7v\2\2\u00d7\u00d8\7t\2\2\u00d8\u00d9\7w\2\2\u00d9\u00e0\7g\2\2"+
+ "\u00da\u00db\7h\2\2\u00db\u00dc\7c\2\2\u00dc\u00dd\7n\2\2\u00dd\u00de"+
+ "\7u\2\2\u00de\u00e0\7g\2\2\u00df\u00d6\3\2\2\2\u00df\u00da\3\2\2\2\u00e0"+
+ "B\3\2\2\2\u00e1\u00e4\5E#\2\u00e2\u00e4\5M\'\2\u00e3\u00e1\3\2\2\2\u00e3"+
+ "\u00e2\3\2\2\2\u00e4D\3\2\2\2\u00e5\u00e9\5G$\2\u00e6\u00e9\5I%\2\u00e7"+
+ "\u00e9\5K&\2\u00e8\u00e5\3\2\2\2\u00e8\u00e6\3\2\2\2\u00e8\u00e7\3\2\2"+
+ "\2\u00e9F\3\2\2\2\u00ea\u00f0\7\'\2\2\u00eb\u00ec\7\62\2\2\u00ec\u00f0"+
+ "\7d\2\2\u00ed\u00ee\7\62\2\2\u00ee\u00f0\7D\2\2\u00ef\u00ea\3\2\2\2\u00ef"+
+ "\u00eb\3\2\2\2\u00ef\u00ed\3\2\2\2\u00f0\u00f4\3\2\2\2\u00f1\u00f3\5U"+
+ "+\2\u00f2\u00f1\3\2\2\2\u00f3\u00f6\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f4"+
+ "\u00f5\3\2\2\2\u00f5\u00f7\3\2\2\2\u00f6\u00f4\3\2\2\2\u00f7\u00f9\7\60"+
+ "\2\2\u00f8\u00fa\5U+\2\u00f9\u00f8\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00f9"+
+ "\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fcH\3\2\2\2\u00fd\u00ff\5W,\2\u00fe\u00fd"+
+ "\3\2\2\2\u00ff\u0102\3\2\2\2\u0100\u00fe\3\2\2\2\u0100\u0101\3\2\2\2\u0101"+
+ "\u0103\3\2\2\2\u0102\u0100\3\2\2\2\u0103\u0105\7\60\2\2\u0104\u0106\5"+
+ "W,\2\u0105\u0104\3\2\2\2\u0106\u0107\3\2\2\2\u0107\u0105\3\2\2\2\u0107"+
+ "\u0108\3\2\2\2\u0108J\3\2\2\2\u0109\u010f\7&\2\2\u010a\u010b\7\62\2\2"+
+ "\u010b\u010f\7z\2\2\u010c\u010d\7\62\2\2\u010d\u010f\7Z\2\2\u010e\u0109"+
+ "\3\2\2\2\u010e\u010a\3\2\2\2\u010e\u010c\3\2\2\2\u010f\u0113\3\2\2\2\u0110"+
+ "\u0112\5Y-\2\u0111\u0110\3\2\2\2\u0112\u0115\3\2\2\2\u0113\u0111\3\2\2"+
+ "\2\u0113\u0114\3\2\2\2\u0114\u0116\3\2\2\2\u0115\u0113\3\2\2\2\u0116\u0118"+
+ "\7\60\2\2\u0117\u0119\5Y-\2\u0118\u0117\3\2\2\2\u0119\u011a\3\2\2\2\u011a"+
+ "\u0118\3\2\2\2\u011a\u011b\3\2\2\2\u011bL\3\2\2\2\u011c\u0120\5Q)\2\u011d"+
+ "\u0120\5S*\2\u011e\u0120\5O(\2\u011f\u011c\3\2\2\2\u011f\u011d\3\2\2\2"+
+ "\u011f\u011e\3\2\2\2\u0120N\3\2\2\2\u0121\u0122\7\62\2\2\u0122\u0124\t"+
+ "\3\2\2\u0123\u0125\5U+\2\u0124\u0123\3\2\2\2\u0125\u0126\3\2\2\2\u0126"+
+ "\u0124\3\2\2\2\u0126\u0127\3\2\2\2\u0127\u012f\3\2\2\2\u0128\u012a\7\'"+
+ "\2\2\u0129\u012b\5U+\2\u012a\u0129\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u012a"+
+ "\3\2\2\2\u012c\u012d\3\2\2\2\u012d\u012f\3\2\2\2\u012e\u0121\3\2\2\2\u012e"+
+ "\u0128\3\2\2\2\u012fP\3\2\2\2\u0130\u0132\5W,\2\u0131\u0130\3\2\2\2\u0132"+
+ "\u0133\3\2\2\2\u0133\u0131\3\2\2\2\u0133\u0134\3\2\2\2\u0134R\3\2\2\2"+
+ "\u0135\u013b\7&\2\2\u0136\u0137\7\62\2\2\u0137\u013b\7z\2\2\u0138\u0139"+
+ "\7\62\2\2\u0139\u013b\7Z\2\2\u013a\u0135\3\2\2\2\u013a\u0136\3\2\2\2\u013a"+
+ "\u0138\3\2\2\2\u013b\u013d\3\2\2\2\u013c\u013e\5Y-\2\u013d\u013c\3\2\2"+
+ "\2\u013e\u013f\3\2\2\2\u013f\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140T"+
+ "\3\2\2\2\u0141\u0142\t\4\2\2\u0142V\3\2\2\2\u0143\u0144\t\5\2\2\u0144"+
+ "X\3\2\2\2\u0145\u0146\t\6\2\2\u0146Z\3\2\2\2\u0147\u014b\5]/\2\u0148\u014a"+
+ "\5_\60\2\u0149\u0148\3\2\2\2\u014a\u014d\3\2\2\2\u014b\u0149\3\2\2\2\u014b"+
+ "\u014c\3\2\2\2\u014c\\\3\2\2\2\u014d\u014b\3\2\2\2\u014e\u014f\t\7\2\2"+
+ "\u014f^\3\2\2\2\u0150\u0151\t\b\2\2\u0151`\3\2\2\2\u0152\u0154\t\t\2\2"+
+ "\u0153\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0153\3\2\2\2\u0155\u0156"+
+ "\3\2\2\2\u0156\u0157\3\2\2\2\u0157\u0158\b\61\2\2\u0158b\3\2\2\2\32\2"+
+ "\u00c9\u00cf\u00d1\u00df\u00e3\u00e8\u00ef\u00f4\u00fb\u0100\u0107\u010e"+
+ "\u0113\u011a\u011f\u0126\u012c\u012e\u0133\u013a\u013f\u014b\u0155\3\b"+
"\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
diff --git a/src/dk/camelot64/kickc/parser/KickCLexer.tokens b/src/dk/camelot64/kickc/parser/KickCLexer.tokens
index 69c474e0f..fb63df5b8 100644
--- a/src/dk/camelot64/kickc/parser/KickCLexer.tokens
+++ b/src/dk/camelot64/kickc/parser/KickCLexer.tokens
@@ -26,20 +26,21 @@ T__24=25
T__25=26
T__26=27
T__27=28
-TYPE=29
-STRING=30
-BOOLEAN=31
-NUMBER=32
-NUMFLOAT=33
-BINFLOAT=34
-DECFLOAT=35
-HEXFLOAT=36
-NUMINT=37
-BININTEGER=38
-DECINTEGER=39
-HEXINTEGER=40
-NAME=41
-WS=42
+T__28=29
+TYPE=30
+STRING=31
+BOOLEAN=32
+NUMBER=33
+NUMFLOAT=34
+BINFLOAT=35
+DECFLOAT=36
+HEXFLOAT=37
+NUMINT=38
+BININTEGER=39
+DECINTEGER=40
+HEXINTEGER=41
+NAME=42
+WS=43
'{'=1
'}'=2
'='=3
@@ -49,22 +50,23 @@ WS=42
')'=7
'else'=8
'while'=9
-'+'=10
-'-'=11
-'not'=12
-'!'=13
-'*'=14
-'/'=15
-'=='=16
-'!='=17
-'<>'=18
-'<'=19
-'<='=20
-'=<'=21
-'>='=22
-'=>'=23
-'>'=24
-'and'=25
-'&&'=26
-'or'=27
-'||'=28
+'do'=10
+'+'=11
+'-'=12
+'not'=13
+'!'=14
+'*'=15
+'/'=16
+'=='=17
+'!='=18
+'<>'=19
+'<'=20
+'<='=21
+'=<'=22
+'>='=23
+'=>'=24
+'>'=25
+'and'=26
+'&&'=27
+'or'=28
+'||'=29
diff --git a/src/dk/camelot64/kickc/parser/KickCListener.java b/src/dk/camelot64/kickc/parser/KickCListener.java
index dfce0dcdd..7053c9c07 100644
--- a/src/dk/camelot64/kickc/parser/KickCListener.java
+++ b/src/dk/camelot64/kickc/parser/KickCListener.java
@@ -87,6 +87,18 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitStmtWhile(KickCParser.StmtWhileContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code stmtDoWhile}
+ * labeled alternative in {@link KickCParser#stmt}.
+ * @param ctx the parse tree
+ */
+ void enterStmtDoWhile(KickCParser.StmtDoWhileContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code stmtDoWhile}
+ * labeled alternative in {@link KickCParser#stmt}.
+ * @param ctx the parse tree
+ */
+ void exitStmtDoWhile(KickCParser.StmtDoWhileContext ctx);
/**
* Enter a parse tree produced by the {@code exprBinary}
* labeled alternative in {@link KickCParser#expr}.
diff --git a/src/dk/camelot64/kickc/parser/KickCParser.java b/src/dk/camelot64/kickc/parser/KickCParser.java
index 44744aa15..ed8b3e6d3 100644
--- a/src/dk/camelot64/kickc/parser/KickCParser.java
+++ b/src/dk/camelot64/kickc/parser/KickCParser.java
@@ -20,9 +20,9 @@ public class KickCParser extends Parser {
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
- T__24=25, T__25=26, T__26=27, T__27=28, TYPE=29, STRING=30, BOOLEAN=31,
- NUMBER=32, NUMFLOAT=33, BINFLOAT=34, DECFLOAT=35, HEXFLOAT=36, NUMINT=37,
- BININTEGER=38, DECINTEGER=39, HEXINTEGER=40, NAME=41, WS=42;
+ T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, TYPE=30, STRING=31,
+ BOOLEAN=32, NUMBER=33, NUMFLOAT=34, BINFLOAT=35, DECFLOAT=36, HEXFLOAT=37,
+ NUMINT=38, BININTEGER=39, DECINTEGER=40, HEXINTEGER=41, NAME=42, WS=43;
public static final int
RULE_file = 0, RULE_stmtSeq = 1, RULE_stmt = 2, RULE_expr = 3;
public static final String[] ruleNames = {
@@ -31,15 +31,16 @@ public class KickCParser extends Parser {
private static final String[] _LITERAL_NAMES = {
null, "'{'", "'}'", "'='", "';'", "'if'", "'('", "')'", "'else'", "'while'",
- "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'", "'<'",
- "'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'", "'||'"
+ "'do'", "'+'", "'-'", "'not'", "'!'", "'*'", "'/'", "'=='", "'!='", "'<>'",
+ "'<'", "'<='", "'=<'", "'>='", "'=>'", "'>'", "'and'", "'&&'", "'or'",
+ "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER", "NUMFLOAT",
- "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER",
- "HEXINTEGER", "NAME", "WS"
+ null, null, null, null, null, null, "TYPE", "STRING", "BOOLEAN", "NUMBER",
+ "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
+ "DECINTEGER", "HEXINTEGER", "NAME", "WS"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -183,7 +184,7 @@ public class KickCParser extends Parser {
setState(14);
_errHandler.sync(this);
_la = _input.LA(1);
- } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__4) | (1L << T__5) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << TYPE) | (1L << STRING) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) );
+ } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__4) | (1L << T__5) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << TYPE) | (1L << STRING) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) );
}
}
catch (RecognitionException re) {
@@ -268,6 +269,28 @@ public class KickCParser extends Parser {
else return visitor.visitChildren(this);
}
}
+ public static class StmtDoWhileContext extends StmtContext {
+ public StmtContext stmt() {
+ return getRuleContext(StmtContext.class,0);
+ }
+ public ExprContext expr() {
+ return getRuleContext(ExprContext.class,0);
+ }
+ public StmtDoWhileContext(StmtContext ctx) { copyFrom(ctx); }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStmtDoWhile(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStmtDoWhile(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof KickCVisitor ) return ((KickCVisitor extends T>)visitor).visitStmtDoWhile(this);
+ else return visitor.visitChildren(this);
+ }
+ }
public static class StmtAssignmentContext extends StmtContext {
public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); }
public TerminalNode TYPE() { return getToken(KickCParser.TYPE, 0); }
@@ -320,7 +343,7 @@ public class KickCParser extends Parser {
enterRule(_localctx, 4, RULE_stmt);
int _la;
try {
- setState(47);
+ setState(54);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
case 1:
@@ -421,6 +444,24 @@ public class KickCParser extends Parser {
stmt();
}
break;
+ case 6:
+ _localctx = new StmtDoWhileContext(_localctx);
+ enterOuterAlt(_localctx, 6);
+ {
+ setState(47);
+ match(T__9);
+ setState(48);
+ stmt();
+ setState(49);
+ match(T__8);
+ setState(50);
+ match(T__5);
+ setState(51);
+ expr(0);
+ setState(52);
+ match(T__6);
+ }
+ break;
}
}
catch (RecognitionException re) {
@@ -590,7 +631,7 @@ public class KickCParser extends Parser {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(60);
+ setState(67);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__5:
@@ -599,25 +640,25 @@ public class KickCParser extends Parser {
_ctx = _localctx;
_prevctx = _localctx;
- setState(50);
+ setState(57);
match(T__5);
- setState(51);
+ setState(58);
expr(0);
- setState(52);
+ setState(59);
match(T__6);
}
break;
- case T__9:
case T__10:
case T__11:
case T__12:
+ case T__13:
{
_localctx = new ExprUnaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(54);
+ setState(61);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12))) != 0)) ) {
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@@ -625,7 +666,7 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(55);
+ setState(62);
expr(10);
}
break;
@@ -634,7 +675,7 @@ public class KickCParser extends Parser {
_localctx = new ExprIdContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(56);
+ setState(63);
match(NAME);
}
break;
@@ -643,7 +684,7 @@ public class KickCParser extends Parser {
_localctx = new ExprNumberContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(57);
+ setState(64);
match(NUMBER);
}
break;
@@ -652,7 +693,7 @@ public class KickCParser extends Parser {
_localctx = new ExprStringContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(58);
+ setState(65);
match(STRING);
}
break;
@@ -661,7 +702,7 @@ public class KickCParser extends Parser {
_localctx = new ExprBoolContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(59);
+ setState(66);
match(BOOLEAN);
}
break;
@@ -669,7 +710,7 @@ public class KickCParser extends Parser {
throw new NoViableAltException(this);
}
_ctx.stop = _input.LT(-1);
- setState(79);
+ setState(86);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -677,18 +718,18 @@ public class KickCParser extends Parser {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(77);
+ setState(84);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
case 1:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
- setState(62);
+ setState(69);
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
- setState(63);
+ setState(70);
_la = _input.LA(1);
- if ( !(_la==T__13 || _la==T__14) ) {
+ if ( !(_la==T__14 || _la==T__15) ) {
_errHandler.recoverInline(this);
}
else {
@@ -696,7 +737,7 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(64);
+ setState(71);
expr(10);
}
break;
@@ -704,11 +745,11 @@ public class KickCParser extends Parser {
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
- setState(65);
+ setState(72);
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
- setState(66);
+ setState(73);
_la = _input.LA(1);
- if ( !(_la==T__9 || _la==T__10) ) {
+ if ( !(_la==T__10 || _la==T__11) ) {
_errHandler.recoverInline(this);
}
else {
@@ -716,7 +757,7 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(67);
+ setState(74);
expr(9);
}
break;
@@ -724,11 +765,11 @@ public class KickCParser extends Parser {
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
- setState(68);
+ setState(75);
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
- setState(69);
+ setState(76);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23))) != 0)) ) {
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@@ -736,7 +777,7 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(70);
+ setState(77);
expr(8);
}
break;
@@ -744,11 +785,11 @@ public class KickCParser extends Parser {
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
- setState(71);
+ setState(78);
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
- setState(72);
+ setState(79);
_la = _input.LA(1);
- if ( !(_la==T__24 || _la==T__25) ) {
+ if ( !(_la==T__25 || _la==T__26) ) {
_errHandler.recoverInline(this);
}
else {
@@ -756,7 +797,7 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(73);
+ setState(80);
expr(7);
}
break;
@@ -764,11 +805,11 @@ public class KickCParser extends Parser {
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
- setState(74);
+ setState(81);
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
- setState(75);
+ setState(82);
_la = _input.LA(1);
- if ( !(_la==T__26 || _la==T__27) ) {
+ if ( !(_la==T__27 || _la==T__28) ) {
_errHandler.recoverInline(this);
}
else {
@@ -776,14 +817,14 @@ public class KickCParser extends Parser {
_errHandler.reportMatch(this);
consume();
}
- setState(76);
+ setState(83);
expr(6);
}
break;
}
}
}
- setState(81);
+ setState(88);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
}
@@ -824,30 +865,31 @@ public class KickCParser extends Parser {
}
public static final String _serializedATN =
- "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3,U\4\2\t\2\4\3\t\3"+
- "\4\4\t\4\4\5\t\5\3\2\3\2\3\2\3\3\6\3\17\n\3\r\3\16\3\20\3\4\3\4\3\4\3"+
- "\4\3\4\5\4\30\n\4\3\4\3\4\3\4\5\4\35\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+
- "\4\3\4\3\4\3\4\5\4*\n\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\62\n\4\3\5\3\5\3\5"+
- "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5?\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+
- "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\7\5P\n\5\f\5\16\5S\13\5\3\5\2\3\b\6\2"+
- "\4\6\b\2\b\3\2\f\17\3\2\20\21\3\2\f\r\3\2\22\32\3\2\33\34\3\2\35\36\2"+
- "b\2\n\3\2\2\2\4\16\3\2\2\2\6\61\3\2\2\2\b>\3\2\2\2\n\13\5\4\3\2\13\f\7"+
- "\2\2\3\f\3\3\2\2\2\r\17\5\6\4\2\16\r\3\2\2\2\17\20\3\2\2\2\20\16\3\2\2"+
- "\2\20\21\3\2\2\2\21\5\3\2\2\2\22\23\7\3\2\2\23\24\5\4\3\2\24\25\7\4\2"+
- "\2\25\62\3\2\2\2\26\30\7\37\2\2\27\26\3\2\2\2\27\30\3\2\2\2\30\31\3\2"+
- "\2\2\31\34\7+\2\2\32\33\7\5\2\2\33\35\5\b\5\2\34\32\3\2\2\2\34\35\3\2"+
- "\2\2\35\36\3\2\2\2\36\62\7\6\2\2\37 \5\b\5\2 !\7\6\2\2!\62\3\2\2\2\"#"+
- "\7\7\2\2#$\7\b\2\2$%\5\b\5\2%&\7\t\2\2&)\5\6\4\2\'(\7\n\2\2(*\5\6\4\2"+
- ")\'\3\2\2\2)*\3\2\2\2*\62\3\2\2\2+,\7\13\2\2,-\7\b\2\2-.\5\b\5\2./\7\t"+
- "\2\2/\60\5\6\4\2\60\62\3\2\2\2\61\22\3\2\2\2\61\27\3\2\2\2\61\37\3\2\2"+
- "\2\61\"\3\2\2\2\61+\3\2\2\2\62\7\3\2\2\2\63\64\b\5\1\2\64\65\7\b\2\2\65"+
- "\66\5\b\5\2\66\67\7\t\2\2\67?\3\2\2\289\t\2\2\29?\5\b\5\f:?\7+\2\2;?\7"+
- "\"\2\2\7 \2\2=?\7!\2\2>\63\3\2\2\2>8\3\2\2\2>:\3\2\2\2>;\3\2\2\2><\3"+
- "\2\2\2>=\3\2\2\2?Q\3\2\2\2@A\f\13\2\2AB\t\3\2\2BP\5\b\5\fCD\f\n\2\2DE"+
- "\t\4\2\2EP\5\b\5\13FG\f\t\2\2GH\t\5\2\2HP\5\b\5\nIJ\f\b\2\2JK\t\6\2\2"+
- "KP\5\b\5\tLM\f\7\2\2MN\t\7\2\2NP\5\b\5\bO@\3\2\2\2OC\3\2\2\2OF\3\2\2\2"+
- "OI\3\2\2\2OL\3\2\2\2PS\3\2\2\2QO\3\2\2\2QR\3\2\2\2R\t\3\2\2\2SQ\3\2\2"+
- "\2\n\20\27\34)\61>OQ";
+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3-\\\4\2\t\2\4\3\t"+
+ "\3\4\4\t\4\4\5\t\5\3\2\3\2\3\2\3\3\6\3\17\n\3\r\3\16\3\20\3\4\3\4\3\4"+
+ "\3\4\3\4\5\4\30\n\4\3\4\3\4\3\4\5\4\35\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+
+ "\3\4\3\4\3\4\3\4\5\4*\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+
+ "\3\4\3\4\5\49\n\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5F\n\5"+
+ "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\7\5W\n\5"+
+ "\f\5\16\5Z\13\5\3\5\2\3\b\6\2\4\6\b\2\b\3\2\r\20\3\2\21\22\3\2\r\16\3"+
+ "\2\23\33\3\2\34\35\3\2\36\37\2j\2\n\3\2\2\2\4\16\3\2\2\2\68\3\2\2\2\b"+
+ "E\3\2\2\2\n\13\5\4\3\2\13\f\7\2\2\3\f\3\3\2\2\2\r\17\5\6\4\2\16\r\3\2"+
+ "\2\2\17\20\3\2\2\2\20\16\3\2\2\2\20\21\3\2\2\2\21\5\3\2\2\2\22\23\7\3"+
+ "\2\2\23\24\5\4\3\2\24\25\7\4\2\2\259\3\2\2\2\26\30\7 \2\2\27\26\3\2\2"+
+ "\2\27\30\3\2\2\2\30\31\3\2\2\2\31\34\7,\2\2\32\33\7\5\2\2\33\35\5\b\5"+
+ "\2\34\32\3\2\2\2\34\35\3\2\2\2\35\36\3\2\2\2\369\7\6\2\2\37 \5\b\5\2 "+
+ "!\7\6\2\2!9\3\2\2\2\"#\7\7\2\2#$\7\b\2\2$%\5\b\5\2%&\7\t\2\2&)\5\6\4\2"+
+ "\'(\7\n\2\2(*\5\6\4\2)\'\3\2\2\2)*\3\2\2\2*9\3\2\2\2+,\7\13\2\2,-\7\b"+
+ "\2\2-.\5\b\5\2./\7\t\2\2/\60\5\6\4\2\609\3\2\2\2\61\62\7\f\2\2\62\63\5"+
+ "\6\4\2\63\64\7\13\2\2\64\65\7\b\2\2\65\66\5\b\5\2\66\67\7\t\2\2\679\3"+
+ "\2\2\28\22\3\2\2\28\27\3\2\2\28\37\3\2\2\28\"\3\2\2\28+\3\2\2\28\61\3"+
+ "\2\2\29\7\3\2\2\2:;\b\5\1\2;<\7\b\2\2<=\5\b\5\2=>\7\t\2\2>F\3\2\2\2?@"+
+ "\t\2\2\2@F\5\b\5\fAF\7,\2\2BF\7#\2\2CF\7!\2\2DF\7\"\2\2E:\3\2\2\2E?\3"+
+ "\2\2\2EA\3\2\2\2EB\3\2\2\2EC\3\2\2\2ED\3\2\2\2FX\3\2\2\2GH\f\13\2\2HI"+
+ "\t\3\2\2IW\5\b\5\fJK\f\n\2\2KL\t\4\2\2LW\5\b\5\13MN\f\t\2\2NO\t\5\2\2"+
+ "OW\5\b\5\nPQ\f\b\2\2QR\t\6\2\2RW\5\b\5\tST\f\7\2\2TU\t\7\2\2UW\5\b\5\b"+
+ "VG\3\2\2\2VJ\3\2\2\2VM\3\2\2\2VP\3\2\2\2VS\3\2\2\2WZ\3\2\2\2XV\3\2\2\2"+
+ "XY\3\2\2\2Y\t\3\2\2\2ZX\3\2\2\2\n\20\27\34)8EVX";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/src/dk/camelot64/kickc/parser/KickCVisitor.java b/src/dk/camelot64/kickc/parser/KickCVisitor.java
index ccafef85a..c82e30341 100644
--- a/src/dk/camelot64/kickc/parser/KickCVisitor.java
+++ b/src/dk/camelot64/kickc/parser/KickCVisitor.java
@@ -57,6 +57,13 @@ public interface KickCVisitor extends ParseTreeVisitor {
* @return the visitor result
*/
T visitStmtWhile(KickCParser.StmtWhileContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code stmtDoWhile}
+ * labeled alternative in {@link KickCParser#stmt}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx);
/**
* Visit a parse tree produced by the {@code exprBinary}
* labeled alternative in {@link KickCParser#expr}.
diff --git a/src/dk/camelot64/kickc/test/Main.java b/src/dk/camelot64/kickc/test/Main.java
index ca5ca6842..68c01db5b 100644
--- a/src/dk/camelot64/kickc/test/Main.java
+++ b/src/dk/camelot64/kickc/test/Main.java
@@ -4,9 +4,7 @@ import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.icl.*;
import dk.camelot64.kickc.parser.KickCLexer;
import dk.camelot64.kickc.parser.KickCParser;
-import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.CharStreams;
-import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.*;
import java.io.IOException;
import java.util.ArrayList;
@@ -15,11 +13,18 @@ import java.util.List;
/** Test my KickC Grammar */
public class Main {
public static void main(String[] args) throws IOException {
- CharStream input = CharStreams.fromFileName("src/dk/camelot64/kickc/test/fib.kc");
+ final String fileName = "src/dk/camelot64/kickc/test/fib2.kc";
+ final CharStream input = CharStreams.fromFileName(fileName);
System.out.println(input.toString());
KickCLexer lexer = new KickCLexer(input);
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
parser.setBuildParseTree(true);
+ parser.addErrorListener(new BaseErrorListener() {
+ @Override
+ public void syntaxError(Recognizer, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
+ throw new RuntimeException("Error parsing file "+fileName+"\n - Line: "+line+"\n - Message: "+msg);
+ }
+ });
KickCParser.FileContext file = parser.file();
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence();
pass1GenerateStatementSequence.generate(file);
diff --git a/src/dk/camelot64/kickc/test/fib2.kc b/src/dk/camelot64/kickc/test/fib2.kc
new file mode 100644
index 000000000..2059e8cc5
--- /dev/null
+++ b/src/dk/camelot64/kickc/test/fib2.kc
@@ -0,0 +1,10 @@
+byte n1 = 0;
+byte n2 = 1;
+byte i = 12;
+byte fib = 0;
+do {
+ fib = n1 + n2;
+ n1 = n2;
+ n2 = fib;
+ i = i - 1;
+} while(i!=0)