mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-10-11 12:23:45 +00:00
Added support for lo/hi lvalues. Added more ALU options. Working on bitmap plotter.
This commit is contained in:
parent
f60be66531
commit
00f53c49b6
@ -59,11 +59,13 @@ public class Compiler {
|
||||
}
|
||||
|
||||
public Program pass1GenerateSSA(KickCParser.FileContext file, CompileLog log) {
|
||||
Pass1GenerateStatementSequence pass1GenerateStatementSequence1 = new Pass1GenerateStatementSequence(log);
|
||||
pass1GenerateStatementSequence1.generate(file);
|
||||
Pass1GenerateStatementSequence pass1GenerateStatementSequence = pass1GenerateStatementSequence1;
|
||||
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);
|
||||
|
||||
@ -124,6 +126,7 @@ public class Compiler {
|
||||
assertions.add(new Pass2AssertBlocks(program));
|
||||
assertions.add(new Pass2AssertNoCallParameters(program));
|
||||
assertions.add(new Pass2AssertNoCallLvalues(program));
|
||||
assertions.add(new Pass2AssertNoLvalueLoHi(program));
|
||||
assertions.add(new Pass2AssertNoReturnValues(program));
|
||||
assertions.add(new Pass2AssertNoProcs(program));
|
||||
assertions.add(new Pass2AssertNoLabels(program));
|
||||
@ -256,12 +259,14 @@ public class Compiler {
|
||||
|
||||
// Attempt uplifting registers through a lot of combinations
|
||||
//program.getLog().setVerboseUplift(true);
|
||||
new Pass4RegisterUpliftCombinations(program).performUplift(200_000);
|
||||
new Pass4RegisterUpliftCombinations(program).performUplift(10_000);
|
||||
|
||||
//program.getLog().setVerboseUplift(true);
|
||||
//new Pass4RegisterUpliftStatic(program).performUplift();
|
||||
//program.getLog().setVerboseUplift(false);
|
||||
|
||||
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
|
||||
new Pass4RegisterUpliftRemains(program).performUplift(100_000);
|
||||
new Pass4RegisterUpliftRemains(program).performUplift(10_000);
|
||||
|
||||
// Final register coalesce and finalization
|
||||
new Pass4ZeroPageCoalesce(program).allocate();
|
||||
|
@ -2,6 +2,7 @@ Known Problems
|
||||
- Increment/decrement of value pointed to by pointer does not work. eg. byte* BGCOL = $d020; (*BGCOL)++;
|
||||
- Arrays / strings allocated inline destroy functions (because they are allocated where the call enters.
|
||||
- Classic for() does not allow assignment as increment, eg. for(byte i=0;i<25;i=i+2) {}
|
||||
- Range-based for does not recognize symbolic constants. The following gives a ParseTreeConstantEvaluator$NotConstantException - const byte* BITMAP = $2000; for(byte* b : BITMAP..BITMAP+$2000) { *b = 0; }
|
||||
|
||||
Features
|
||||
- Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS.
|
||||
@ -23,8 +24,10 @@ Features
|
||||
- Remove unused functions.
|
||||
- Support calculated pointers eg. *(ptr+i)
|
||||
- Add syntax for encoded chars (eg. PETSCII instead of SCREEN)
|
||||
- Add support for casting. Specifically casting a byte* to a word (to enable calculating D018-value from pointer to bitmap & screen.)
|
||||
- Add support for casting. Specifically casting a byte* to a word and the other way (eg. to enable calculating D018-value from pointer to bitmap & screen.) - *D018 = (byte*)((word)SCREEN/$40)|((word)BITMAP/$400);
|
||||
- Consider whether autocasting word & byte* is possible ?
|
||||
- Add UpliftRemains support for attempting to uplift potentials to ALU (requires modifying two registers: 1. the ALU potential to ALU - the one added to the ALU potential to A.)
|
||||
- Support array-initializer syntax as literal word syntax. byte* plotter = { lo, hi };
|
||||
|
||||
Arrays / Strings / Inline data
|
||||
- New semantic: Arrays are always allocated inline (and must therefore have a size). Pointers are never.
|
||||
@ -33,6 +36,7 @@ Arrays / Strings / Inline data
|
||||
- Add array initializer filling with a specific value / (pattern?).
|
||||
- Add support for empty / filled byte data arrays.
|
||||
- Add support for expressions in data initializers.
|
||||
- Create a fill-like array initialization - byte[$100] plot_xlo = { [x] = x&$f8 };
|
||||
|
||||
- Inline ASM
|
||||
- Add support for inline asm
|
||||
@ -142,3 +146,5 @@ Done
|
||||
+ Implemenent Assertions for the output of different phases (ensuring that the result of the phase is consistent)
|
||||
+ Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)
|
||||
+ Remove "string" keyword (if it exists).
|
||||
+ Support hi/lo-byte lvalues - <plotter = plot_xlo[x]+plot_ylo[y]; >plotter = plot_xhi[x]+plot_yhi[y];
|
||||
+ Add ALU support for lo/hi operators on pointers - to avoid unnecessary zp-variable holding for cases like byte v = y&$7 | <yoffs;
|
@ -270,6 +270,10 @@ public class AsmFragment {
|
||||
return "_not_";
|
||||
case "~":
|
||||
return "_bnot_";
|
||||
case "lo=":
|
||||
return "_setlo_";
|
||||
case "hi=":
|
||||
return "_sethi_";
|
||||
default:
|
||||
return op;
|
||||
}
|
||||
@ -436,21 +440,6 @@ public class AsmFragment {
|
||||
} else {
|
||||
throw new RuntimeException("Register Type not implemented " + register);
|
||||
}
|
||||
} else if (boundValue instanceof PointerDereferenceSimple) {
|
||||
PointerDereferenceSimple deref = (PointerDereferenceSimple) boundValue;
|
||||
RValue pointer = deref.getPointer();
|
||||
if (pointer instanceof ConstantValue) {
|
||||
ConstantValue pointerConst = (ConstantValue) pointer;
|
||||
if (pointerConst instanceof ConstantInteger) {
|
||||
ConstantInteger intPointer = (ConstantInteger) pointerConst;
|
||||
String param = getAsmNumber(intPointer.getNumber());
|
||||
return new AsmParameter(param, SymbolTypeBasic.BYTE.equals(intPointer.getType(program.getScope())));
|
||||
} else {
|
||||
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
|
||||
}
|
||||
} else if (boundValue instanceof ConstantVar) {
|
||||
ConstantVar constantVar = (ConstantVar) boundValue;
|
||||
String constantValueAsm = getAsmConstant(program, constantVar.getRef(), 99);
|
||||
|
@ -1 +1 @@
|
||||
lda >{zpptrby1}
|
||||
lda {zpptrby1}+1
|
@ -1 +1 @@
|
||||
lda <{zpptrby1}
|
||||
lda {zpptrby1}
|
@ -0,0 +1 @@
|
||||
ora >{zpptrby1}
|
@ -0,0 +1 @@
|
||||
ora <{zpptrby1}
|
@ -0,0 +1 @@
|
||||
// A is A or A
|
@ -0,0 +1 @@
|
||||
ora {cowo1},x
|
@ -0,0 +1 @@
|
||||
ora {cowo1},y
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
ldx {zpby2}
|
||||
ora {cowo1},x
|
@ -0,0 +1,3 @@
|
||||
sta {zpptrby1}
|
||||
lda #>{cowo1}
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,3 @@
|
||||
stx {zpptrby1}
|
||||
lda #>{cowo1}
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,3 @@
|
||||
sty {zpptrby1}
|
||||
lda #>{cowo1}
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
sta {zpptrby1}
|
||||
lda #>{cowo1}
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,8 @@
|
||||
lda {zpptrby1}
|
||||
clc
|
||||
adc #<{cowo1}
|
||||
sta {zpptrby1}
|
||||
lda {zpptrby1}+1
|
||||
adc #>{cowo1}
|
||||
sta {zpptrby1}+1
|
||||
|
@ -0,0 +1 @@
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1 @@
|
||||
stx {zpptrby1}+1
|
@ -0,0 +1 @@
|
||||
sty {zpptrby1}+1
|
@ -0,0 +1 @@
|
||||
sta {zpptrby1}
|
@ -0,0 +1 @@
|
||||
stx {zpptrby1}
|
@ -0,0 +1 @@
|
||||
sty {zpptrby1}
|
@ -0,0 +1,3 @@
|
||||
sta {zpptrby1}+1
|
||||
lda {zpptrby2}
|
||||
sta {zpptrby1}
|
@ -0,0 +1,3 @@
|
||||
stx {zpptrby1}+1
|
||||
lda {zpptrby2}
|
||||
sta {zpptrby1}
|
@ -0,0 +1,3 @@
|
||||
sty {zpptrby1}+1
|
||||
lda {zpptrby2}
|
||||
sta {zpptrby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpptrby2}
|
||||
sta {zpptrby1}
|
||||
lda {zpby1}
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,3 @@
|
||||
sta {zpptrby1}
|
||||
lda {zpptrby2}+1
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,3 @@
|
||||
stx {zpptrby1}
|
||||
lda {zpptrby2}+1
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,3 @@
|
||||
sty {zpptrby1}
|
||||
lda {zpptrby2}+1
|
||||
sta {zpptrby1}+1
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
sta {zpptrby1}
|
||||
lda {zpptrby2}+1
|
||||
sta {zpptrby1}+1
|
36
src/main/java/dk/camelot64/kickc/model/LvalueLoHiByte.java
Normal file
36
src/main/java/dk/camelot64/kickc/model/LvalueLoHiByte.java
Normal file
@ -0,0 +1,36 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
/**
|
||||
* The low/high-byte component of a word variable or pointer variable
|
||||
*/
|
||||
public class LvalueLoHiByte implements LValue {
|
||||
|
||||
private VariableRef variable;
|
||||
|
||||
/**
|
||||
* The lo/hi operator ({@link Operator#LOWBYTE} or {@link Operator#HIBYTE}).
|
||||
*/
|
||||
private Operator operator;
|
||||
|
||||
public LvalueLoHiByte(Operator operator, VariableRef variable) {
|
||||
this.variable = variable;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public VariableRef getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public Operator getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Program program) {
|
||||
return operator.getOperator() + "(" + variable.toString(program) + ")";
|
||||
}
|
||||
|
||||
public void setVariable(VariableRef variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
}
|
@ -53,6 +53,10 @@ public class Operator {
|
||||
return SHIFT_LEFT;
|
||||
case ">>":
|
||||
return SHIFT_RIGHT;
|
||||
case "lo=":
|
||||
return SET_LOWBYTE;
|
||||
case "hi=":
|
||||
return SET_HIBYTE;
|
||||
default:
|
||||
throw new RuntimeException("Unknown operator " + op);
|
||||
}
|
||||
@ -97,6 +101,8 @@ public class Operator {
|
||||
public static Operator LOWBYTE = new Operator("<", Type.UNARY, 2);
|
||||
public static Operator HIBYTE = new Operator(">", Type.UNARY, 2);
|
||||
public static Operator STAR_IDX = new Operator("*idx", Type.BINARY, 2);
|
||||
public static Operator SET_LOWBYTE = new Operator("lo=", Type.BINARY, 2);
|
||||
public static Operator SET_HIBYTE = new Operator("hi=", Type.BINARY, 2);
|
||||
public static Operator MULTIPLY = new Operator("*", Type.BINARY, 3);
|
||||
public static Operator DIVIDE = new Operator("/", Type.BINARY, 3);
|
||||
public static Operator PLUS = new Operator("+", Type.BINARY, 4);
|
||||
|
@ -16,4 +16,4 @@ public class VariableRef extends SymbolRef implements RValue, LValue {
|
||||
this(variable.getFullName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -52,6 +52,7 @@ lvalue
|
||||
: '(' lvalue ')' #lvaluePar
|
||||
| NAME #lvalueName
|
||||
| '*' lvalue #lvaluePtr
|
||||
| ('<' | '>' ) lvalue #lvalueLoHi
|
||||
| lvalue '[' expr ']' #lvalueArray
|
||||
;
|
||||
|
||||
|
@ -80,16 +80,16 @@ COMMENT_BLOCK=63
|
||||
'*'=17
|
||||
'['=18
|
||||
']'=19
|
||||
'--'=20
|
||||
'++'=21
|
||||
'+'=22
|
||||
'-'=23
|
||||
'not'=24
|
||||
'!'=25
|
||||
'&'=26
|
||||
'~'=27
|
||||
'<'=28
|
||||
'>'=29
|
||||
'<'=20
|
||||
'>'=21
|
||||
'--'=22
|
||||
'++'=23
|
||||
'+'=24
|
||||
'-'=25
|
||||
'not'=26
|
||||
'!'=27
|
||||
'&'=28
|
||||
'~'=29
|
||||
'>>'=30
|
||||
'<<'=31
|
||||
'/'=32
|
||||
|
@ -323,6 +323,18 @@ public class KickCBaseListener implements KickCListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLvaluePar(KickCParser.LvalueParContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLvalueLoHi(KickCParser.LvalueLoHiContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLvalueLoHi(KickCParser.LvalueLoHiContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -193,6 +193,13 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitLvaluePar(KickCParser.LvalueParContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitLvalueLoHi(KickCParser.LvalueLoHiContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -49,8 +49,8 @@ public class KickCLexer extends Lexer {
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'",
|
||||
"'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['",
|
||||
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'",
|
||||
"'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
|
||||
"']'", "'<'", "'>'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'",
|
||||
"'~'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
|
||||
"'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
@ -132,8 +132,8 @@ public class KickCLexer extends Lexer {
|
||||
"\4\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n\3\n"+
|
||||
"\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\r"+
|
||||
"\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21"+
|
||||
"\3\22\3\22\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\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35"+
|
||||
"\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\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\33\3\33\3\33\3\33\3\34\3\34\3\35\3\35"+
|
||||
"\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3!\3!\3\"\3\"\3#\3#\3#\3$\3$\3$\3%"+
|
||||
"\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3+\3+\3,\3,\3,\3,"+
|
||||
"\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3"+
|
||||
@ -172,8 +172,8 @@ public class KickCLexer extends Lexer {
|
||||
"\2\2\17\u009b\3\2\2\2\21\u009d\3\2\2\2\23\u00a0\3\2\2\2\25\u00a5\3\2\2"+
|
||||
"\2\27\u00ab\3\2\2\2\31\u00ae\3\2\2\2\33\u00b2\3\2\2\2\35\u00b9\3\2\2\2"+
|
||||
"\37\u00bb\3\2\2\2!\u00be\3\2\2\2#\u00c0\3\2\2\2%\u00c2\3\2\2\2\'\u00c4"+
|
||||
"\3\2\2\2)\u00c6\3\2\2\2+\u00c9\3\2\2\2-\u00cc\3\2\2\2/\u00ce\3\2\2\2\61"+
|
||||
"\u00d0\3\2\2\2\63\u00d4\3\2\2\2\65\u00d6\3\2\2\2\67\u00d8\3\2\2\29\u00da"+
|
||||
"\3\2\2\2)\u00c6\3\2\2\2+\u00c8\3\2\2\2-\u00ca\3\2\2\2/\u00cd\3\2\2\2\61"+
|
||||
"\u00d0\3\2\2\2\63\u00d2\3\2\2\2\65\u00d4\3\2\2\2\67\u00d8\3\2\2\29\u00da"+
|
||||
"\3\2\2\2;\u00dc\3\2\2\2=\u00de\3\2\2\2?\u00e1\3\2\2\2A\u00e4\3\2\2\2C"+
|
||||
"\u00e6\3\2\2\2E\u00e8\3\2\2\2G\u00eb\3\2\2\2I\u00ee\3\2\2\2K\u00f1\3\2"+
|
||||
"\2\2M\u00f4\3\2\2\2O\u00f7\3\2\2\2Q\u00fa\3\2\2\2S\u00fd\3\2\2\2U\u00ff"+
|
||||
@ -198,17 +198,17 @@ public class KickCLexer extends Lexer {
|
||||
"\u00ba\7<\2\2\u00ba\36\3\2\2\2\u00bb\u00bc\7\60\2\2\u00bc\u00bd\7\60\2"+
|
||||
"\2\u00bd \3\2\2\2\u00be\u00bf\7.\2\2\u00bf\"\3\2\2\2\u00c0\u00c1\7,\2"+
|
||||
"\2\u00c1$\3\2\2\2\u00c2\u00c3\7]\2\2\u00c3&\3\2\2\2\u00c4\u00c5\7_\2\2"+
|
||||
"\u00c5(\3\2\2\2\u00c6\u00c7\7/\2\2\u00c7\u00c8\7/\2\2\u00c8*\3\2\2\2\u00c9"+
|
||||
"\u00ca\7-\2\2\u00ca\u00cb\7-\2\2\u00cb,\3\2\2\2\u00cc\u00cd\7-\2\2\u00cd"+
|
||||
".\3\2\2\2\u00ce\u00cf\7/\2\2\u00cf\60\3\2\2\2\u00d0\u00d1\7p\2\2\u00d1"+
|
||||
"\u00d2\7q\2\2\u00d2\u00d3\7v\2\2\u00d3\62\3\2\2\2\u00d4\u00d5\7#\2\2\u00d5"+
|
||||
"\64\3\2\2\2\u00d6\u00d7\7(\2\2\u00d7\66\3\2\2\2\u00d8\u00d9\7\u0080\2"+
|
||||
"\2\u00d98\3\2\2\2\u00da\u00db\7>\2\2\u00db:\3\2\2\2\u00dc\u00dd\7@\2\2"+
|
||||
"\u00dd<\3\2\2\2\u00de\u00df\7@\2\2\u00df\u00e0\7@\2\2\u00e0>\3\2\2\2\u00e1"+
|
||||
"\u00e2\7>\2\2\u00e2\u00e3\7>\2\2\u00e3@\3\2\2\2\u00e4\u00e5\7\61\2\2\u00e5"+
|
||||
"B\3\2\2\2\u00e6\u00e7\7\'\2\2\u00e7D\3\2\2\2\u00e8\u00e9\7?\2\2\u00e9"+
|
||||
"\u00ea\7?\2\2\u00eaF\3\2\2\2\u00eb\u00ec\7#\2\2\u00ec\u00ed\7?\2\2\u00ed"+
|
||||
"H\3\2\2\2\u00ee\u00ef\7>\2\2\u00ef\u00f0\7@\2\2\u00f0J\3\2\2\2\u00f1\u00f2"+
|
||||
"\u00c5(\3\2\2\2\u00c6\u00c7\7>\2\2\u00c7*\3\2\2\2\u00c8\u00c9\7@\2\2\u00c9"+
|
||||
",\3\2\2\2\u00ca\u00cb\7/\2\2\u00cb\u00cc\7/\2\2\u00cc.\3\2\2\2\u00cd\u00ce"+
|
||||
"\7-\2\2\u00ce\u00cf\7-\2\2\u00cf\60\3\2\2\2\u00d0\u00d1\7-\2\2\u00d1\62"+
|
||||
"\3\2\2\2\u00d2\u00d3\7/\2\2\u00d3\64\3\2\2\2\u00d4\u00d5\7p\2\2\u00d5"+
|
||||
"\u00d6\7q\2\2\u00d6\u00d7\7v\2\2\u00d7\66\3\2\2\2\u00d8\u00d9\7#\2\2\u00d9"+
|
||||
"8\3\2\2\2\u00da\u00db\7(\2\2\u00db:\3\2\2\2\u00dc\u00dd\7\u0080\2\2\u00dd"+
|
||||
"<\3\2\2\2\u00de\u00df\7@\2\2\u00df\u00e0\7@\2\2\u00e0>\3\2\2\2\u00e1\u00e2"+
|
||||
"\7>\2\2\u00e2\u00e3\7>\2\2\u00e3@\3\2\2\2\u00e4\u00e5\7\61\2\2\u00e5B"+
|
||||
"\3\2\2\2\u00e6\u00e7\7\'\2\2\u00e7D\3\2\2\2\u00e8\u00e9\7?\2\2\u00e9\u00ea"+
|
||||
"\7?\2\2\u00eaF\3\2\2\2\u00eb\u00ec\7#\2\2\u00ec\u00ed\7?\2\2\u00edH\3"+
|
||||
"\2\2\2\u00ee\u00ef\7>\2\2\u00ef\u00f0\7@\2\2\u00f0J\3\2\2\2\u00f1\u00f2"+
|
||||
"\7>\2\2\u00f2\u00f3\7?\2\2\u00f3L\3\2\2\2\u00f4\u00f5\7?\2\2\u00f5\u00f6"+
|
||||
"\7>\2\2\u00f6N\3\2\2\2\u00f7\u00f8\7@\2\2\u00f8\u00f9\7?\2\2\u00f9P\3"+
|
||||
"\2\2\2\u00fa\u00fb\7?\2\2\u00fb\u00fc\7@\2\2\u00fcR\3\2\2\2\u00fd\u00fe"+
|
||||
|
@ -80,16 +80,16 @@ COMMENT_BLOCK=63
|
||||
'*'=17
|
||||
'['=18
|
||||
']'=19
|
||||
'--'=20
|
||||
'++'=21
|
||||
'+'=22
|
||||
'-'=23
|
||||
'not'=24
|
||||
'!'=25
|
||||
'&'=26
|
||||
'~'=27
|
||||
'<'=28
|
||||
'>'=29
|
||||
'<'=20
|
||||
'>'=21
|
||||
'--'=22
|
||||
'++'=23
|
||||
'+'=24
|
||||
'-'=25
|
||||
'not'=26
|
||||
'!'=27
|
||||
'&'=28
|
||||
'~'=29
|
||||
'>>'=30
|
||||
'<<'=31
|
||||
'/'=32
|
||||
|
@ -311,6 +311,18 @@ public interface KickCListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLvaluePar(KickCParser.LvalueParContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code lvalueLoHi}
|
||||
* labeled alternative in {@link KickCParser#lvalue}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLvalueLoHi(KickCParser.LvalueLoHiContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code lvalueLoHi}
|
||||
* labeled alternative in {@link KickCParser#lvalue}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLvalueLoHi(KickCParser.LvalueLoHiContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code exprPreMod}
|
||||
* labeled alternative in {@link KickCParser#expr}.
|
||||
|
@ -39,8 +39,8 @@ public class KickCParser extends Parser {
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'",
|
||||
"'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['",
|
||||
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'",
|
||||
"'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
|
||||
"']'", "'<'", "'>'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'",
|
||||
"'~'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
|
||||
"'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
@ -1369,6 +1369,25 @@ public class KickCParser extends Parser {
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class LvalueLoHiContext extends LvalueContext {
|
||||
public LvalueContext lvalue() {
|
||||
return getRuleContext(LvalueContext.class,0);
|
||||
}
|
||||
public LvalueLoHiContext(LvalueContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).enterLvalueLoHi(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof KickCListener ) ((KickCListener)listener).exitLvalueLoHi(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof KickCVisitor ) return ((KickCVisitor<? extends T>)visitor).visitLvalueLoHi(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final LvalueContext lvalue() throws RecognitionException {
|
||||
return lvalue(0);
|
||||
@ -1381,11 +1400,12 @@ public class KickCParser extends Parser {
|
||||
LvalueContext _prevctx = _localctx;
|
||||
int _startState = 18;
|
||||
enterRecursionRule(_localctx, 18, RULE_lvalue, _p);
|
||||
int _la;
|
||||
try {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(177);
|
||||
setState(179);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__2:
|
||||
@ -1419,6 +1439,26 @@ public class KickCParser extends Parser {
|
||||
setState(175);
|
||||
match(T__16);
|
||||
setState(176);
|
||||
lvalue(3);
|
||||
}
|
||||
break;
|
||||
case T__19:
|
||||
case T__20:
|
||||
{
|
||||
_localctx = new LvalueLoHiContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(177);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__19 || _la==T__20) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(178);
|
||||
lvalue(2);
|
||||
}
|
||||
break;
|
||||
@ -1426,7 +1466,7 @@ public class KickCParser extends Parser {
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(186);
|
||||
setState(188);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,21,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
@ -1437,18 +1477,18 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new LvalueArrayContext(new LvalueContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_lvalue);
|
||||
setState(179);
|
||||
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
|
||||
setState(180);
|
||||
match(T__17);
|
||||
setState(181);
|
||||
expr(0);
|
||||
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
|
||||
setState(182);
|
||||
match(T__17);
|
||||
setState(183);
|
||||
expr(0);
|
||||
setState(184);
|
||||
match(T__18);
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(188);
|
||||
setState(190);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,21,_ctx);
|
||||
}
|
||||
@ -1740,7 +1780,7 @@ public class KickCParser extends Parser {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(214);
|
||||
setState(216);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) {
|
||||
case 1:
|
||||
@ -1749,11 +1789,11 @@ public class KickCParser extends Parser {
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
|
||||
setState(190);
|
||||
match(T__2);
|
||||
setState(191);
|
||||
expr(0);
|
||||
setState(192);
|
||||
match(T__2);
|
||||
setState(193);
|
||||
expr(0);
|
||||
setState(194);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
@ -1762,21 +1802,21 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprCallContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(194);
|
||||
setState(196);
|
||||
match(NAME);
|
||||
setState(195);
|
||||
match(T__2);
|
||||
setState(197);
|
||||
match(T__2);
|
||||
setState(199);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
|
||||
{
|
||||
setState(196);
|
||||
setState(198);
|
||||
parameterList();
|
||||
}
|
||||
}
|
||||
|
||||
setState(199);
|
||||
setState(201);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
@ -1785,13 +1825,13 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprCastContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(200);
|
||||
match(T__2);
|
||||
setState(201);
|
||||
typeDecl(0);
|
||||
setState(202);
|
||||
match(T__3);
|
||||
match(T__2);
|
||||
setState(203);
|
||||
typeDecl(0);
|
||||
setState(204);
|
||||
match(T__3);
|
||||
setState(205);
|
||||
expr(19);
|
||||
}
|
||||
break;
|
||||
@ -1800,28 +1840,9 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprPreModContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(205);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__19 || _la==T__20) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(206);
|
||||
expr(17);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
_localctx = new ExprUnaryContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(207);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28))) != 0)) ) {
|
||||
if ( !(_la==T__21 || _la==T__22) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -1830,6 +1851,25 @@ public class KickCParser extends Parser {
|
||||
consume();
|
||||
}
|
||||
setState(208);
|
||||
expr(17);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
_localctx = new ExprUnaryContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(209);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(210);
|
||||
expr(15);
|
||||
}
|
||||
break;
|
||||
@ -1838,7 +1878,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprIdContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(209);
|
||||
setState(211);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
@ -1847,7 +1887,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprNumberContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(210);
|
||||
setState(212);
|
||||
match(NUMBER);
|
||||
}
|
||||
break;
|
||||
@ -1856,7 +1896,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprStringContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(211);
|
||||
setState(213);
|
||||
match(STRING);
|
||||
}
|
||||
break;
|
||||
@ -1865,7 +1905,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprCharContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(212);
|
||||
setState(214);
|
||||
match(CHAR);
|
||||
}
|
||||
break;
|
||||
@ -1874,13 +1914,13 @@ public class KickCParser extends Parser {
|
||||
_localctx = new ExprBoolContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(213);
|
||||
setState(215);
|
||||
match(BOOLEAN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(252);
|
||||
setState(254);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,25,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
@ -1888,16 +1928,16 @@ public class KickCParser extends Parser {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(250);
|
||||
setState(252);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(216);
|
||||
setState(218);
|
||||
if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)");
|
||||
setState(217);
|
||||
setState(219);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__29 || _la==T__30) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -1907,7 +1947,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(218);
|
||||
setState(220);
|
||||
expr(15);
|
||||
}
|
||||
break;
|
||||
@ -1915,9 +1955,9 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(219);
|
||||
setState(221);
|
||||
if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)");
|
||||
setState(220);
|
||||
setState(222);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__31) | (1L << T__32))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -1927,7 +1967,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(221);
|
||||
setState(223);
|
||||
expr(14);
|
||||
}
|
||||
break;
|
||||
@ -1935,11 +1975,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(222);
|
||||
setState(224);
|
||||
if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)");
|
||||
setState(223);
|
||||
setState(225);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__21 || _la==T__22) ) {
|
||||
if ( !(_la==T__23 || _la==T__24) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -1947,7 +1987,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(224);
|
||||
setState(226);
|
||||
expr(13);
|
||||
}
|
||||
break;
|
||||
@ -1955,11 +1995,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(225);
|
||||
setState(227);
|
||||
if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)");
|
||||
setState(226);
|
||||
setState(228);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__27) | (1L << T__28) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39))) != 0)) ) {
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__19) | (1L << T__20) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -1967,7 +2007,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(227);
|
||||
setState(229);
|
||||
expr(12);
|
||||
}
|
||||
break;
|
||||
@ -1975,13 +2015,13 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(228);
|
||||
setState(230);
|
||||
if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)");
|
||||
{
|
||||
setState(229);
|
||||
match(T__25);
|
||||
setState(231);
|
||||
match(T__27);
|
||||
}
|
||||
setState(230);
|
||||
setState(232);
|
||||
expr(11);
|
||||
}
|
||||
break;
|
||||
@ -1989,13 +2029,13 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(231);
|
||||
setState(233);
|
||||
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
|
||||
{
|
||||
setState(232);
|
||||
setState(234);
|
||||
match(T__40);
|
||||
}
|
||||
setState(233);
|
||||
setState(235);
|
||||
expr(10);
|
||||
}
|
||||
break;
|
||||
@ -2003,13 +2043,13 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(234);
|
||||
setState(236);
|
||||
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
|
||||
{
|
||||
setState(235);
|
||||
setState(237);
|
||||
match(T__41);
|
||||
}
|
||||
setState(236);
|
||||
setState(238);
|
||||
expr(9);
|
||||
}
|
||||
break;
|
||||
@ -2017,9 +2057,9 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(237);
|
||||
setState(239);
|
||||
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
||||
setState(238);
|
||||
setState(240);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__42 || _la==T__43) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -2029,7 +2069,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(239);
|
||||
setState(241);
|
||||
expr(8);
|
||||
}
|
||||
break;
|
||||
@ -2037,9 +2077,9 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(240);
|
||||
setState(242);
|
||||
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
||||
setState(241);
|
||||
setState(243);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__44 || _la==T__45) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -2049,7 +2089,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(242);
|
||||
setState(244);
|
||||
expr(7);
|
||||
}
|
||||
break;
|
||||
@ -2057,13 +2097,13 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprArrayContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(243);
|
||||
if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)");
|
||||
setState(244);
|
||||
match(T__17);
|
||||
setState(245);
|
||||
expr(0);
|
||||
if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)");
|
||||
setState(246);
|
||||
match(T__17);
|
||||
setState(247);
|
||||
expr(0);
|
||||
setState(248);
|
||||
match(T__18);
|
||||
}
|
||||
break;
|
||||
@ -2071,11 +2111,11 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new ExprPostModContext(new ExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expr);
|
||||
setState(248);
|
||||
setState(250);
|
||||
if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)");
|
||||
setState(249);
|
||||
setState(251);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__19 || _la==T__20) ) {
|
||||
if ( !(_la==T__21 || _la==T__22) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
else {
|
||||
@ -2088,7 +2128,7 @@ public class KickCParser extends Parser {
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(254);
|
||||
setState(256);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,25,_ctx);
|
||||
}
|
||||
@ -2138,21 +2178,21 @@ public class KickCParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(255);
|
||||
setState(257);
|
||||
expr(0);
|
||||
setState(260);
|
||||
setState(262);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==T__15) {
|
||||
{
|
||||
{
|
||||
setState(256);
|
||||
setState(258);
|
||||
match(T__15);
|
||||
setState(257);
|
||||
setState(259);
|
||||
expr(0);
|
||||
}
|
||||
}
|
||||
setState(262);
|
||||
setState(264);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
@ -2225,7 +2265,7 @@ public class KickCParser extends Parser {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3A\u010a\4\2\t\2\4"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3A\u010c\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\3\2\3\2\3\2\3\3\6\3\37\n\3\r\3\16\3 \3\4\3\4\5\4%"+
|
||||
"\n\4\3\4\3\4\3\4\3\4\3\4\5\4,\n\4\3\4\3\4\3\4\5\4\61\n\4\3\4\3\4\3\4\5"+
|
||||
@ -2237,86 +2277,87 @@ public class KickCParser extends Parser {
|
||||
"\7\f\7\16\7\u0089\13\7\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\5\t"+
|
||||
"\u0096\n\t\3\t\7\t\u0099\n\t\f\t\16\t\u009c\13\t\3\n\3\n\3\n\3\n\3\n\7"+
|
||||
"\n\u00a3\n\n\f\n\16\n\u00a6\13\n\3\n\3\n\5\n\u00aa\n\n\3\13\3\13\3\13"+
|
||||
"\3\13\3\13\3\13\3\13\3\13\5\13\u00b4\n\13\3\13\3\13\3\13\3\13\3\13\7\13"+
|
||||
"\u00bb\n\13\f\13\16\13\u00be\13\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f"+
|
||||
"\u00c8\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"+
|
||||
"\5\f\u00d9\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\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\7\f\u00fd\n\f\f\f\16\f\u0100\13\f\3\r\3\r\3\r\7\r\u0105\n\r"+
|
||||
"\f\r\16\r\u0108\13\r\3\r\2\5\20\24\26\16\2\4\6\b\n\f\16\20\22\24\26\30"+
|
||||
"\2\n\3\2\26\27\4\2\23\23\30\37\3\2 !\4\2\23\23\"#\3\2\30\31\4\2\36\37"+
|
||||
"$*\3\2-.\3\2/\60\2\u0132\2\32\3\2\2\2\4\36\3\2\2\2\6k\3\2\2\2\bn\3\2\2"+
|
||||
"\2\n\u0080\3\2\2\2\f\u0082\3\2\2\2\16\u008a\3\2\2\2\20\u008d\3\2\2\2\22"+
|
||||
"\u00a9\3\2\2\2\24\u00b3\3\2\2\2\26\u00d8\3\2\2\2\30\u0101\3\2\2\2\32\33"+
|
||||
"\5\4\3\2\33\34\7\2\2\3\34\3\3\2\2\2\35\37\5\6\4\2\36\35\3\2\2\2\37 \3"+
|
||||
"\2\2\2 \36\3\2\2\2 !\3\2\2\2!\5\3\2\2\2\"$\7\3\2\2#%\5\4\3\2$#\3\2\2\2"+
|
||||
"$%\3\2\2\2%&\3\2\2\2&l\7\4\2\2\'(\5\20\t\2()\7>\2\2)+\7\5\2\2*,\5\f\7"+
|
||||
"\2+*\3\2\2\2+,\3\2\2\2,-\3\2\2\2-.\7\6\2\2.\60\7\3\2\2/\61\5\4\3\2\60"+
|
||||
"/\3\2\2\2\60\61\3\2\2\2\61\62\3\2\2\2\62\63\7\4\2\2\63l\3\2\2\2\64\66"+
|
||||
"\7\7\2\2\65\64\3\2\2\2\65\66\3\2\2\2\66\67\3\2\2\2\678\5\20\t\28;\7>\2"+
|
||||
"\29:\7\b\2\2:<\5\22\n\2;9\3\2\2\2;<\3\2\2\2<=\3\2\2\2=>\7\t\2\2>l\3\2"+
|
||||
"\2\2?@\5\24\13\2@A\7\b\2\2AB\5\26\f\2BC\7\t\2\2Cl\3\2\2\2DE\5\26\f\2E"+
|
||||
"F\7\t\2\2Fl\3\2\2\2GH\7\n\2\2HI\7\5\2\2IJ\5\26\f\2JK\7\6\2\2KN\5\6\4\2"+
|
||||
"LM\7\13\2\2MO\5\6\4\2NL\3\2\2\2NO\3\2\2\2Ol\3\2\2\2PQ\7\f\2\2QR\7\5\2"+
|
||||
"\2RS\5\26\f\2ST\7\6\2\2TU\5\6\4\2Ul\3\2\2\2VW\7\r\2\2WX\5\6\4\2XY\7\f"+
|
||||
"\2\2YZ\7\5\2\2Z[\5\26\f\2[\\\7\6\2\2\\l\3\2\2\2]^\7\16\2\2^`\7\5\2\2_"+
|
||||
"a\5\b\5\2`_\3\2\2\2`a\3\2\2\2ab\3\2\2\2bc\5\n\6\2cd\7\6\2\2de\5\6\4\2"+
|
||||
"el\3\2\2\2fh\7\17\2\2gi\5\26\f\2hg\3\2\2\2hi\3\2\2\2ij\3\2\2\2jl\7\t\2"+
|
||||
"\2k\"\3\2\2\2k\'\3\2\2\2k\65\3\2\2\2k?\3\2\2\2kD\3\2\2\2kG\3\2\2\2kP\3"+
|
||||
"\2\2\2kV\3\2\2\2k]\3\2\2\2kf\3\2\2\2l\7\3\2\2\2mo\5\20\t\2nm\3\2\2\2n"+
|
||||
"o\3\2\2\2op\3\2\2\2ps\7>\2\2qr\7\b\2\2rt\5\22\n\2sq\3\2\2\2st\3\2\2\2"+
|
||||
"t\t\3\2\2\2uv\7\t\2\2vw\5\26\f\2wy\7\t\2\2xz\5\26\f\2yx\3\2\2\2yz\3\2"+
|
||||
"\2\2z\u0081\3\2\2\2{|\7\20\2\2|}\5\26\f\2}~\7\21\2\2~\177\5\26\f\2\177"+
|
||||
"\u0081\3\2\2\2\u0080u\3\2\2\2\u0080{\3\2\2\2\u0081\13\3\2\2\2\u0082\u0087"+
|
||||
"\5\16\b\2\u0083\u0084\7\22\2\2\u0084\u0086\5\16\b\2\u0085\u0083\3\2\2"+
|
||||
"\2\u0086\u0089\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\r"+
|
||||
"\3\2\2\2\u0089\u0087\3\2\2\2\u008a\u008b\5\20\t\2\u008b\u008c\7>\2\2\u008c"+
|
||||
"\17\3\2\2\2\u008d\u008e\b\t\1\2\u008e\u008f\7\61\2\2\u008f\u009a\3\2\2"+
|
||||
"\2\u0090\u0091\f\4\2\2\u0091\u0099\7\23\2\2\u0092\u0093\f\3\2\2\u0093"+
|
||||
"\u0095\7\24\2\2\u0094\u0096\5\26\f\2\u0095\u0094\3\2\2\2\u0095\u0096\3"+
|
||||
"\2\2\2\u0096\u0097\3\2\2\2\u0097\u0099\7\25\2\2\u0098\u0090\3\2\2\2\u0098"+
|
||||
"\u0092\3\2\2\2\u0099\u009c\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b\3\2"+
|
||||
"\2\2\u009b\21\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u00aa\5\26\f\2\u009e\u009f"+
|
||||
"\7\3\2\2\u009f\u00a4\5\22\n\2\u00a0\u00a1\7\22\2\2\u00a1\u00a3\5\22\n"+
|
||||
"\2\u00a2\u00a0\3\2\2\2\u00a3\u00a6\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a4\u00a5"+
|
||||
"\3\2\2\2\u00a5\u00a7\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a7\u00a8\7\4\2\2\u00a8"+
|
||||
"\u00aa\3\2\2\2\u00a9\u009d\3\2\2\2\u00a9\u009e\3\2\2\2\u00aa\23\3\2\2"+
|
||||
"\2\u00ab\u00ac\b\13\1\2\u00ac\u00ad\7\5\2\2\u00ad\u00ae\5\24\13\2\u00ae"+
|
||||
"\u00af\7\6\2\2\u00af\u00b4\3\2\2\2\u00b0\u00b4\7>\2\2\u00b1\u00b2\7\23"+
|
||||
"\2\2\u00b2\u00b4\5\24\13\4\u00b3\u00ab\3\2\2\2\u00b3\u00b0\3\2\2\2\u00b3"+
|
||||
"\u00b1\3\2\2\2\u00b4\u00bc\3\2\2\2\u00b5\u00b6\f\3\2\2\u00b6\u00b7\7\24"+
|
||||
"\2\2\u00b7\u00b8\5\26\f\2\u00b8\u00b9\7\25\2\2\u00b9\u00bb\3\2\2\2\u00ba"+
|
||||
"\u00b5\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc\u00ba\3\2\2\2\u00bc\u00bd\3\2"+
|
||||
"\2\2\u00bd\25\3\2\2\2\u00be\u00bc\3\2\2\2\u00bf\u00c0\b\f\1\2\u00c0\u00c1"+
|
||||
"\7\5\2\2\u00c1\u00c2\5\26\f\2\u00c2\u00c3\7\6\2\2\u00c3\u00d9\3\2\2\2"+
|
||||
"\u00c4\u00c5\7>\2\2\u00c5\u00c7\7\5\2\2\u00c6\u00c8\5\30\r\2\u00c7\u00c6"+
|
||||
"\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\u00c9\3\2\2\2\u00c9\u00d9\7\6\2\2\u00ca"+
|
||||
"\u00cb\7\5\2\2\u00cb\u00cc\5\20\t\2\u00cc\u00cd\7\6\2\2\u00cd\u00ce\5"+
|
||||
"\26\f\25\u00ce\u00d9\3\2\2\2\u00cf\u00d0\t\2\2\2\u00d0\u00d9\5\26\f\23"+
|
||||
"\u00d1\u00d2\t\3\2\2\u00d2\u00d9\5\26\f\21\u00d3\u00d9\7>\2\2\u00d4\u00d9"+
|
||||
"\7\65\2\2\u00d5\u00d9\7\62\2\2\u00d6\u00d9\7\63\2\2\u00d7\u00d9\7\64\2"+
|
||||
"\2\u00d8\u00bf\3\2\2\2\u00d8\u00c4\3\2\2\2\u00d8\u00ca\3\2\2\2\u00d8\u00cf"+
|
||||
"\3\2\2\2\u00d8\u00d1\3\2\2\2\u00d8\u00d3\3\2\2\2\u00d8\u00d4\3\2\2\2\u00d8"+
|
||||
"\u00d5\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d7\3\2\2\2\u00d9\u00fe\3\2"+
|
||||
"\2\2\u00da\u00db\f\20\2\2\u00db\u00dc\t\4\2\2\u00dc\u00fd\5\26\f\21\u00dd"+
|
||||
"\u00de\f\17\2\2\u00de\u00df\t\5\2\2\u00df\u00fd\5\26\f\20\u00e0\u00e1"+
|
||||
"\f\16\2\2\u00e1\u00e2\t\6\2\2\u00e2\u00fd\5\26\f\17\u00e3\u00e4\f\r\2"+
|
||||
"\2\u00e4\u00e5\t\7\2\2\u00e5\u00fd\5\26\f\16\u00e6\u00e7\f\f\2\2\u00e7"+
|
||||
"\u00e8\7\34\2\2\u00e8\u00fd\5\26\f\r\u00e9\u00ea\f\13\2\2\u00ea\u00eb"+
|
||||
"\7+\2\2\u00eb\u00fd\5\26\f\f\u00ec\u00ed\f\n\2\2\u00ed\u00ee\7,\2\2\u00ee"+
|
||||
"\u00fd\5\26\f\13\u00ef\u00f0\f\t\2\2\u00f0\u00f1\t\b\2\2\u00f1\u00fd\5"+
|
||||
"\26\f\n\u00f2\u00f3\f\b\2\2\u00f3\u00f4\t\t\2\2\u00f4\u00fd\5\26\f\t\u00f5"+
|
||||
"\u00f6\f\24\2\2\u00f6\u00f7\7\24\2\2\u00f7\u00f8\5\26\f\2\u00f8\u00f9"+
|
||||
"\7\25\2\2\u00f9\u00fd\3\2\2\2\u00fa\u00fb\f\22\2\2\u00fb\u00fd\t\2\2\2"+
|
||||
"\u00fc\u00da\3\2\2\2\u00fc\u00dd\3\2\2\2\u00fc\u00e0\3\2\2\2\u00fc\u00e3"+
|
||||
"\3\2\2\2\u00fc\u00e6\3\2\2\2\u00fc\u00e9\3\2\2\2\u00fc\u00ec\3\2\2\2\u00fc"+
|
||||
"\u00ef\3\2\2\2\u00fc\u00f2\3\2\2\2\u00fc\u00f5\3\2\2\2\u00fc\u00fa\3\2"+
|
||||
"\2\2\u00fd\u0100\3\2\2\2\u00fe\u00fc\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff"+
|
||||
"\27\3\2\2\2\u0100\u00fe\3\2\2\2\u0101\u0106\5\26\f\2\u0102\u0103\7\22"+
|
||||
"\2\2\u0103\u0105\5\26\f\2\u0104\u0102\3\2\2\2\u0105\u0108\3\2\2\2\u0106"+
|
||||
"\u0104\3\2\2\2\u0106\u0107\3\2\2\2\u0107\31\3\2\2\2\u0108\u0106\3\2\2"+
|
||||
"\2\35 $+\60\65;N`hknsy\u0080\u0087\u0095\u0098\u009a\u00a4\u00a9\u00b3"+
|
||||
"\u00bc\u00c7\u00d8\u00fc\u00fe\u0106";
|
||||
"\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u00b6\n\13\3\13\3\13\3\13\3\13"+
|
||||
"\3\13\7\13\u00bd\n\13\f\13\16\13\u00c0\13\13\3\f\3\f\3\f\3\f\3\f\3\f\3"+
|
||||
"\f\3\f\5\f\u00ca\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\5\f\u00db\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\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\7\f\u00ff\n\f\f\f\16\f\u0102\13\f\3\r\3\r\3\r\7\r"+
|
||||
"\u0107\n\r\f\r\16\r\u010a\13\r\3\r\2\5\20\24\26\16\2\4\6\b\n\f\16\20\22"+
|
||||
"\24\26\30\2\13\3\2\26\27\3\2\30\31\5\2\23\23\26\27\32\37\3\2 !\4\2\23"+
|
||||
"\23\"#\3\2\32\33\4\2\26\27$*\3\2-.\3\2/\60\2\u0135\2\32\3\2\2\2\4\36\3"+
|
||||
"\2\2\2\6k\3\2\2\2\bn\3\2\2\2\n\u0080\3\2\2\2\f\u0082\3\2\2\2\16\u008a"+
|
||||
"\3\2\2\2\20\u008d\3\2\2\2\22\u00a9\3\2\2\2\24\u00b5\3\2\2\2\26\u00da\3"+
|
||||
"\2\2\2\30\u0103\3\2\2\2\32\33\5\4\3\2\33\34\7\2\2\3\34\3\3\2\2\2\35\37"+
|
||||
"\5\6\4\2\36\35\3\2\2\2\37 \3\2\2\2 \36\3\2\2\2 !\3\2\2\2!\5\3\2\2\2\""+
|
||||
"$\7\3\2\2#%\5\4\3\2$#\3\2\2\2$%\3\2\2\2%&\3\2\2\2&l\7\4\2\2\'(\5\20\t"+
|
||||
"\2()\7>\2\2)+\7\5\2\2*,\5\f\7\2+*\3\2\2\2+,\3\2\2\2,-\3\2\2\2-.\7\6\2"+
|
||||
"\2.\60\7\3\2\2/\61\5\4\3\2\60/\3\2\2\2\60\61\3\2\2\2\61\62\3\2\2\2\62"+
|
||||
"\63\7\4\2\2\63l\3\2\2\2\64\66\7\7\2\2\65\64\3\2\2\2\65\66\3\2\2\2\66\67"+
|
||||
"\3\2\2\2\678\5\20\t\28;\7>\2\29:\7\b\2\2:<\5\22\n\2;9\3\2\2\2;<\3\2\2"+
|
||||
"\2<=\3\2\2\2=>\7\t\2\2>l\3\2\2\2?@\5\24\13\2@A\7\b\2\2AB\5\26\f\2BC\7"+
|
||||
"\t\2\2Cl\3\2\2\2DE\5\26\f\2EF\7\t\2\2Fl\3\2\2\2GH\7\n\2\2HI\7\5\2\2IJ"+
|
||||
"\5\26\f\2JK\7\6\2\2KN\5\6\4\2LM\7\13\2\2MO\5\6\4\2NL\3\2\2\2NO\3\2\2\2"+
|
||||
"Ol\3\2\2\2PQ\7\f\2\2QR\7\5\2\2RS\5\26\f\2ST\7\6\2\2TU\5\6\4\2Ul\3\2\2"+
|
||||
"\2VW\7\r\2\2WX\5\6\4\2XY\7\f\2\2YZ\7\5\2\2Z[\5\26\f\2[\\\7\6\2\2\\l\3"+
|
||||
"\2\2\2]^\7\16\2\2^`\7\5\2\2_a\5\b\5\2`_\3\2\2\2`a\3\2\2\2ab\3\2\2\2bc"+
|
||||
"\5\n\6\2cd\7\6\2\2de\5\6\4\2el\3\2\2\2fh\7\17\2\2gi\5\26\f\2hg\3\2\2\2"+
|
||||
"hi\3\2\2\2ij\3\2\2\2jl\7\t\2\2k\"\3\2\2\2k\'\3\2\2\2k\65\3\2\2\2k?\3\2"+
|
||||
"\2\2kD\3\2\2\2kG\3\2\2\2kP\3\2\2\2kV\3\2\2\2k]\3\2\2\2kf\3\2\2\2l\7\3"+
|
||||
"\2\2\2mo\5\20\t\2nm\3\2\2\2no\3\2\2\2op\3\2\2\2ps\7>\2\2qr\7\b\2\2rt\5"+
|
||||
"\22\n\2sq\3\2\2\2st\3\2\2\2t\t\3\2\2\2uv\7\t\2\2vw\5\26\f\2wy\7\t\2\2"+
|
||||
"xz\5\26\f\2yx\3\2\2\2yz\3\2\2\2z\u0081\3\2\2\2{|\7\20\2\2|}\5\26\f\2}"+
|
||||
"~\7\21\2\2~\177\5\26\f\2\177\u0081\3\2\2\2\u0080u\3\2\2\2\u0080{\3\2\2"+
|
||||
"\2\u0081\13\3\2\2\2\u0082\u0087\5\16\b\2\u0083\u0084\7\22\2\2\u0084\u0086"+
|
||||
"\5\16\b\2\u0085\u0083\3\2\2\2\u0086\u0089\3\2\2\2\u0087\u0085\3\2\2\2"+
|
||||
"\u0087\u0088\3\2\2\2\u0088\r\3\2\2\2\u0089\u0087\3\2\2\2\u008a\u008b\5"+
|
||||
"\20\t\2\u008b\u008c\7>\2\2\u008c\17\3\2\2\2\u008d\u008e\b\t\1\2\u008e"+
|
||||
"\u008f\7\61\2\2\u008f\u009a\3\2\2\2\u0090\u0091\f\4\2\2\u0091\u0099\7"+
|
||||
"\23\2\2\u0092\u0093\f\3\2\2\u0093\u0095\7\24\2\2\u0094\u0096\5\26\f\2"+
|
||||
"\u0095\u0094\3\2\2\2\u0095\u0096\3\2\2\2\u0096\u0097\3\2\2\2\u0097\u0099"+
|
||||
"\7\25\2\2\u0098\u0090\3\2\2\2\u0098\u0092\3\2\2\2\u0099\u009c\3\2\2\2"+
|
||||
"\u009a\u0098\3\2\2\2\u009a\u009b\3\2\2\2\u009b\21\3\2\2\2\u009c\u009a"+
|
||||
"\3\2\2\2\u009d\u00aa\5\26\f\2\u009e\u009f\7\3\2\2\u009f\u00a4\5\22\n\2"+
|
||||
"\u00a0\u00a1\7\22\2\2\u00a1\u00a3\5\22\n\2\u00a2\u00a0\3\2\2\2\u00a3\u00a6"+
|
||||
"\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5\u00a7\3\2\2\2\u00a6"+
|
||||
"\u00a4\3\2\2\2\u00a7\u00a8\7\4\2\2\u00a8\u00aa\3\2\2\2\u00a9\u009d\3\2"+
|
||||
"\2\2\u00a9\u009e\3\2\2\2\u00aa\23\3\2\2\2\u00ab\u00ac\b\13\1\2\u00ac\u00ad"+
|
||||
"\7\5\2\2\u00ad\u00ae\5\24\13\2\u00ae\u00af\7\6\2\2\u00af\u00b6\3\2\2\2"+
|
||||
"\u00b0\u00b6\7>\2\2\u00b1\u00b2\7\23\2\2\u00b2\u00b6\5\24\13\5\u00b3\u00b4"+
|
||||
"\t\2\2\2\u00b4\u00b6\5\24\13\4\u00b5\u00ab\3\2\2\2\u00b5\u00b0\3\2\2\2"+
|
||||
"\u00b5\u00b1\3\2\2\2\u00b5\u00b3\3\2\2\2\u00b6\u00be\3\2\2\2\u00b7\u00b8"+
|
||||
"\f\3\2\2\u00b8\u00b9\7\24\2\2\u00b9\u00ba\5\26\f\2\u00ba\u00bb\7\25\2"+
|
||||
"\2\u00bb\u00bd\3\2\2\2\u00bc\u00b7\3\2\2\2\u00bd\u00c0\3\2\2\2\u00be\u00bc"+
|
||||
"\3\2\2\2\u00be\u00bf\3\2\2\2\u00bf\25\3\2\2\2\u00c0\u00be\3\2\2\2\u00c1"+
|
||||
"\u00c2\b\f\1\2\u00c2\u00c3\7\5\2\2\u00c3\u00c4\5\26\f\2\u00c4\u00c5\7"+
|
||||
"\6\2\2\u00c5\u00db\3\2\2\2\u00c6\u00c7\7>\2\2\u00c7\u00c9\7\5\2\2\u00c8"+
|
||||
"\u00ca\5\30\r\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00cb\3"+
|
||||
"\2\2\2\u00cb\u00db\7\6\2\2\u00cc\u00cd\7\5\2\2\u00cd\u00ce\5\20\t\2\u00ce"+
|
||||
"\u00cf\7\6\2\2\u00cf\u00d0\5\26\f\25\u00d0\u00db\3\2\2\2\u00d1\u00d2\t"+
|
||||
"\3\2\2\u00d2\u00db\5\26\f\23\u00d3\u00d4\t\4\2\2\u00d4\u00db\5\26\f\21"+
|
||||
"\u00d5\u00db\7>\2\2\u00d6\u00db\7\65\2\2\u00d7\u00db\7\62\2\2\u00d8\u00db"+
|
||||
"\7\63\2\2\u00d9\u00db\7\64\2\2\u00da\u00c1\3\2\2\2\u00da\u00c6\3\2\2\2"+
|
||||
"\u00da\u00cc\3\2\2\2\u00da\u00d1\3\2\2\2\u00da\u00d3\3\2\2\2\u00da\u00d5"+
|
||||
"\3\2\2\2\u00da\u00d6\3\2\2\2\u00da\u00d7\3\2\2\2\u00da\u00d8\3\2\2\2\u00da"+
|
||||
"\u00d9\3\2\2\2\u00db\u0100\3\2\2\2\u00dc\u00dd\f\20\2\2\u00dd\u00de\t"+
|
||||
"\5\2\2\u00de\u00ff\5\26\f\21\u00df\u00e0\f\17\2\2\u00e0\u00e1\t\6\2\2"+
|
||||
"\u00e1\u00ff\5\26\f\20\u00e2\u00e3\f\16\2\2\u00e3\u00e4\t\7\2\2\u00e4"+
|
||||
"\u00ff\5\26\f\17\u00e5\u00e6\f\r\2\2\u00e6\u00e7\t\b\2\2\u00e7\u00ff\5"+
|
||||
"\26\f\16\u00e8\u00e9\f\f\2\2\u00e9\u00ea\7\36\2\2\u00ea\u00ff\5\26\f\r"+
|
||||
"\u00eb\u00ec\f\13\2\2\u00ec\u00ed\7+\2\2\u00ed\u00ff\5\26\f\f\u00ee\u00ef"+
|
||||
"\f\n\2\2\u00ef\u00f0\7,\2\2\u00f0\u00ff\5\26\f\13\u00f1\u00f2\f\t\2\2"+
|
||||
"\u00f2\u00f3\t\t\2\2\u00f3\u00ff\5\26\f\n\u00f4\u00f5\f\b\2\2\u00f5\u00f6"+
|
||||
"\t\n\2\2\u00f6\u00ff\5\26\f\t\u00f7\u00f8\f\24\2\2\u00f8\u00f9\7\24\2"+
|
||||
"\2\u00f9\u00fa\5\26\f\2\u00fa\u00fb\7\25\2\2\u00fb\u00ff\3\2\2\2\u00fc"+
|
||||
"\u00fd\f\22\2\2\u00fd\u00ff\t\3\2\2\u00fe\u00dc\3\2\2\2\u00fe\u00df\3"+
|
||||
"\2\2\2\u00fe\u00e2\3\2\2\2\u00fe\u00e5\3\2\2\2\u00fe\u00e8\3\2\2\2\u00fe"+
|
||||
"\u00eb\3\2\2\2\u00fe\u00ee\3\2\2\2\u00fe\u00f1\3\2\2\2\u00fe\u00f4\3\2"+
|
||||
"\2\2\u00fe\u00f7\3\2\2\2\u00fe\u00fc\3\2\2\2\u00ff\u0102\3\2\2\2\u0100"+
|
||||
"\u00fe\3\2\2\2\u0100\u0101\3\2\2\2\u0101\27\3\2\2\2\u0102\u0100\3\2\2"+
|
||||
"\2\u0103\u0108\5\26\f\2\u0104\u0105\7\22\2\2\u0105\u0107\5\26\f\2\u0106"+
|
||||
"\u0104\3\2\2\2\u0107\u010a\3\2\2\2\u0108\u0106\3\2\2\2\u0108\u0109\3\2"+
|
||||
"\2\2\u0109\31\3\2\2\2\u010a\u0108\3\2\2\2\35 $+\60\65;N`hknsy\u0080\u0087"+
|
||||
"\u0095\u0098\u009a\u00a4\u00a9\u00b5\u00be\u00c9\u00da\u00fe\u0100\u0108";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -188,6 +188,13 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitLvaluePar(KickCParser.LvalueParContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code lvalueLoHi}
|
||||
* labeled alternative in {@link KickCParser#lvalue}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitLvalueLoHi(KickCParser.LvalueLoHiContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code exprPreMod}
|
||||
* labeled alternative in {@link KickCParser#expr}.
|
||||
|
@ -0,0 +1,66 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Replaces all LValueLoHi with a separate assignment to the modified variable.
|
||||
* <br>Example: <code><plotter = x & 8 </code>
|
||||
* <br>Becomes: <code> $1 =x & 8 , plotter = plotter lo= $1 </code>
|
||||
*/
|
||||
public class Pass1FixLvalueLoHi {
|
||||
|
||||
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 StatementSequence fix() {
|
||||
Stack<Scope> scopeStack = new Stack<>();
|
||||
scopeStack.push(programScope);
|
||||
StatementSequence fixedSequence = new StatementSequence();
|
||||
for (Statement statement : statementSequence.getStatements()) {
|
||||
if (statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if (assignment.getlValue() instanceof LvalueLoHiByte) {
|
||||
LvalueLoHiByte loHiByte = (LvalueLoHiByte) assignment.getlValue();
|
||||
if (assignment.getOperator() != null || assignment.getrValue1()!=null) {
|
||||
Scope currentScope = scopeStack.peek();
|
||||
VariableIntermediate tmpVar = currentScope.addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement tmpAssignment = new StatementAssignment(tmpVarRef, assignment.getrValue1(), assignment.getOperator(), assignment.getrValue2());
|
||||
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());
|
||||
} else {
|
||||
Statement setLoHiAssignment = new StatementAssignment(loHiByte.getVariable(), loHiByte.getVariable(), loHiByte.getOperator(), assignment.getrValue2());
|
||||
fixedSequence.addStatement(setLoHiAssignment);
|
||||
log.append("Fixing lo/hi-lvalue " + assignment.toString());
|
||||
}
|
||||
} else {
|
||||
fixedSequence.addStatement(statement);
|
||||
}
|
||||
} else {
|
||||
fixedSequence.addStatement(statement);
|
||||
}
|
||||
if (statement instanceof StatementProcedureBegin) {
|
||||
ProcedureRef procedureRef = ((StatementProcedureBegin) statement).getProcedure();
|
||||
Procedure procedure = programScope.getProcedure(procedureRef);
|
||||
scopeStack.push(procedure);
|
||||
} else if (statement instanceof StatementProcedureEnd) {
|
||||
scopeStack.pop();
|
||||
}
|
||||
}
|
||||
return fixedSequence;
|
||||
}
|
||||
|
||||
}
|
@ -385,6 +385,22 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLvalueLoHi(KickCParser.LvalueLoHiContext ctx) {
|
||||
LValue lval = (LValue) visit(ctx.lvalue());
|
||||
if (lval instanceof VariableRef) {
|
||||
String opTxt = ctx.getChild(0).getText();
|
||||
if (opTxt.equals("<")) {
|
||||
return new LvalueLoHiByte(Operator.SET_LOWBYTE, (VariableRef) lval);
|
||||
} else if (opTxt.equals(">")) {
|
||||
return new LvalueLoHiByte(Operator.SET_HIBYTE, (VariableRef) lval);
|
||||
} else {
|
||||
throw new RuntimeException("Not implemented - lo/hi-lvalue operator "+opTxt);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Not implemented - lo/hi lvalues of non-variables");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LValue visitLvalueArray(KickCParser.LvalueArrayContext ctx) {
|
||||
LValue lval = (LValue) visit(ctx.lvalue());
|
||||
|
@ -0,0 +1,28 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
|
||||
/** Asserts that the program does not contain any lo/hi lvalues (>plotter = $20) as they are replaced with =lo assignments ( plotter = plotter =lo $20 ) */
|
||||
public class Pass2AssertNoLvalueLoHi extends Pass2SsaAssertion {
|
||||
|
||||
public Pass2AssertNoLvalueLoHi(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check() throws AssertionFailed {
|
||||
|
||||
ControlFlowGraphBaseVisitor<Void> checkCalls = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
if(assignment.getlValue() instanceof LvalueLoHiByte) {
|
||||
throw new AssertionFailed("No lValue lo/hi allowed! "+ assignment);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
checkCalls.visitGraph(getGraph());
|
||||
}
|
||||
|
||||
}
|
@ -77,7 +77,7 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
||||
} else if(symbol instanceof PointerDereferenceIndexed) {
|
||||
addSymbol(((PointerDereferenceIndexed) symbol).getPointer());
|
||||
addSymbol(((PointerDereferenceIndexed) symbol).getIndex());
|
||||
} else if(symbol instanceof PointerDereference) {
|
||||
} else if(symbol instanceof PointerDereferenceSimple) {
|
||||
addSymbol(((PointerDereference) symbol).getPointer());
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +177,8 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
case "+":
|
||||
case "++":
|
||||
case "--":
|
||||
case "<":
|
||||
case ">":
|
||||
return new ConstantUnary(operator, c);
|
||||
case "*": { // pointer dereference - not constant
|
||||
return null;
|
||||
|
@ -56,9 +56,9 @@ public class Pass3VariableRegisterWeightAnalysis extends Pass2Base {
|
||||
}
|
||||
// Also add weight to used pointers
|
||||
if(lValue instanceof PointerDereferenceSimple) {
|
||||
addUsageWeightRValue(((PointerDereference) lValue).getPointer(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((PointerDereferenceSimple) lValue).getPointer(), statement, block.getLabel());
|
||||
} else if(lValue instanceof PointerDereferenceIndexed) {
|
||||
addUsageWeightRValue(((PointerDereference) lValue).getPointer(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) lValue).getPointer(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) lValue).getIndex(), statement, block.getLabel());
|
||||
}
|
||||
// Add weights for each usage of variables
|
||||
|
@ -43,7 +43,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
||||
// The variable has ALU potential
|
||||
setHasAluPotential(registerPotentials, potentialAluVar);
|
||||
}
|
||||
} else if (assignment.getOperator()!=null && "+".equals(assignment.getOperator().getOperator())) {
|
||||
} else if (assignment.getOperator()!=null && (Operator.PLUS.equals(assignment.getOperator()) || Operator.BOOL_OR.equals(assignment.getOperator()))) {
|
||||
// ALU applicable if the variable is one of the two values
|
||||
if (assignment.getrValue2().equals(potentialAluVar) && assignment.getrValue1() != null) {
|
||||
// The variable has ALU potential
|
||||
@ -65,6 +65,12 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
||||
if (assignment.getOperator()!=null && "*idx".equals(assignment.getOperator().getOperator())) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
if (assignment.getOperator()!=null && Operator.LOWBYTE.equals(assignment.getOperator()) && assignment.getrValue1()==null) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
if (assignment.getOperator()!=null && Operator.HIBYTE.equals(assignment.getOperator()) && assignment.getrValue1()==null) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,13 +59,20 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
||||
setRegister(combination, "main::nxt#1", new Registers.RegisterZpPointerByte(2));
|
||||
*/
|
||||
|
||||
// ALU combination for bitmap-bresenham.kc
|
||||
// ALU combination plotter ORA in bitmap-bresenham.kc
|
||||
collapseEquivalenceClasses("line::plotter#0", "line::plotter#1");
|
||||
//setRegister(combination, "line::plotter#1", new Registers.RegisterZpPointerByte(21));
|
||||
setRegister(combination, "line::$11", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$9", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$10", Registers.getRegisterALU());
|
||||
setRegister(combination, "line::$3", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$5", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$4", Registers.getRegisterALU());
|
||||
setRegister(combination, "line::$6", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$8", Registers.getRegisterA());
|
||||
setRegister(combination, "line::$7", Registers.getRegisterALU());
|
||||
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
||||
setRegister(combination, "initplottables::$7", Registers.getRegisterALU());
|
||||
|
||||
boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm(
|
||||
combination,
|
||||
@ -99,4 +106,17 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
||||
combination.setRegister(equivalenceClass, register);
|
||||
}
|
||||
|
||||
private void collapseEquivalenceClasses(String varFullName1, String varFullName2) {
|
||||
LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet();
|
||||
ProgramScope scope = getProgram().getScope();
|
||||
VariableRef variableRef1 = scope.getVariable(varFullName1).getRef();
|
||||
LiveRangeEquivalenceClass equivalenceClass1 = equivalenceClassSet.getEquivalenceClass(variableRef1);
|
||||
VariableRef variableRef2 = scope.getVariable(varFullName2).getRef();
|
||||
LiveRangeEquivalenceClass equivalenceClass2 = equivalenceClassSet.getEquivalenceClass(variableRef2);
|
||||
if(!equivalenceClass1.equals(equivalenceClass2)) {
|
||||
equivalenceClass1.addAll(equivalenceClass2);
|
||||
equivalenceClassSet.remove(equivalenceClass2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class Pass4ZeroPageCoalesce extends Pass2Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find two equivalence classes that can be coalesced into one - and perform the colalescence.
|
||||
* Find two equivalence classes that can be coalesced into one - and perform the coalescence.
|
||||
*
|
||||
* @param liveRangeEquivalenceClassSet The set of live range equivalence classes
|
||||
* @return true if any classes were coalesced. False otherwise.
|
||||
|
@ -100,8 +100,7 @@ public class VariableReplacer {
|
||||
if (getReplacement(pointer) != null) {
|
||||
deref.setPointer(getReplacement(pointer));
|
||||
}
|
||||
}
|
||||
if (lValue instanceof PointerDereferenceIndexed) {
|
||||
} else if (lValue instanceof PointerDereferenceIndexed) {
|
||||
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) lValue;
|
||||
RValue pointer = deref.getPointer();
|
||||
if (getReplacement(pointer) != null) {
|
||||
|
@ -16,62 +16,43 @@ byte MCM = %00010000;
|
||||
byte CSEL = %00001000;
|
||||
|
||||
byte* SCREEN = $400;
|
||||
byte* BITMAP = $2000;
|
||||
const byte* BITMAP = $2000;
|
||||
|
||||
// TODO: Make all arrays in-program allocations - byte[$100] plot_xlo;
|
||||
// TODO: Create a fill-like array initialization - byte[$100] plot_xlo = { [x] = x&$f8 };
|
||||
byte[] plot_xlo = $1000;
|
||||
byte[] plot_xhi = $1100;
|
||||
byte[] plot_ylo = $1200;
|
||||
byte[] plot_yhi = $1300;
|
||||
|
||||
main();
|
||||
byte[] plot_bit = $1400;
|
||||
|
||||
void main() {
|
||||
*BGCOL = 0;
|
||||
*FGCOL = 0;
|
||||
*D011 = BMM|DEN|RSEL;
|
||||
*D018 = $18; // ((word)SCREEN/$40)|((word)BITMAP/$400); - casting byte* to word needed before this works.
|
||||
*D011 = BMM|DEN|RSEL|3;
|
||||
//TODO: Add ability to cast byte* to word. *D018 = ((word)SCREEN/$40)|((word)BITMAP/$400);
|
||||
*D018 = $18;
|
||||
initscreen();
|
||||
initplottables();
|
||||
line(0,0,10,20);
|
||||
// TODO: Error with constant identification of the parameters!
|
||||
line(0,0,20,10);
|
||||
line(10,20,40,40);
|
||||
}
|
||||
|
||||
void initscreen() {
|
||||
for(byte* b = BITMAP; b!=BITMAP+$2000; b++) {
|
||||
*b = $5a;
|
||||
}
|
||||
for(byte* c = SCREEN; c!=SCREEN+$400;c++) {
|
||||
*c = $14;
|
||||
}
|
||||
}
|
||||
|
||||
void initplottables() {
|
||||
|
||||
for(byte x : 0..255) {
|
||||
plot_xlo[x] = x&$f8;
|
||||
plot_xhi[x] = $20;
|
||||
}
|
||||
byte* yoffs = $0;
|
||||
for(byte y : 0..255) {
|
||||
plot_xlo[y] = <yoffs | y&$7;
|
||||
plot_xhi[y] = >yoffs;
|
||||
yoffs = yoffs + 40*8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void line(byte x0, byte y0, byte x1, byte y1) {
|
||||
byte* plot_lo = $fd;
|
||||
byte* plot_hi = $fe;
|
||||
//byte* plotter;
|
||||
byte xd = x1-x0;
|
||||
byte yd = y1-y0;
|
||||
byte x = x0;
|
||||
byte y = y0;
|
||||
byte e = yd<<1;
|
||||
byte e = yd>>1;
|
||||
do {
|
||||
//plot(x,y);
|
||||
*plot_lo = plot_xlo[x]+plot_ylo[y];
|
||||
*plot_hi = plot_xhi[x]+plot_yhi[y];
|
||||
plot(x,y);
|
||||
// TODO: Nice2have: Support array-initializer as words. plotter = { plot_xlo[x]+plot_ylo[y], plot_xhi[x]+plot_yhi[y] };
|
||||
// TODO: Need2have: Ensure coalescing of plotter#0 and plotter#1 into a single live range equivalence class.
|
||||
//<plotter = plot_xlo[x]+plot_ylo[y];
|
||||
//>plotter = plot_xhi[x]+plot_yhi[y];
|
||||
//*plotter = *plotter | plot_bit[x];
|
||||
x = x + 1;
|
||||
e = e+yd;
|
||||
if(xd<e) {
|
||||
@ -81,6 +62,50 @@ void line(byte x0, byte y0, byte x1, byte y1) {
|
||||
} while (x<(x1+1))
|
||||
}
|
||||
|
||||
//void plot(byte x, byte y) {
|
||||
//}
|
||||
void initscreen() {
|
||||
//TODO: Fix problem in interval-based for-loop: for(byte* b = BITMAP..BITMAP+$2000; b++)
|
||||
for(byte* b = BITMAP; b!=BITMAP+$2000; b++) {
|
||||
*b = 0;
|
||||
}
|
||||
for(byte* c = SCREEN; c!=SCREEN+$400;c++) {
|
||||
*c = $14;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initplottables() {
|
||||
byte bit = $80;
|
||||
for(byte x : 0..255) {
|
||||
plot_xlo[x] = x&$f8;
|
||||
plot_xhi[x] = >BITMAP;
|
||||
plot_bit[x] = bit;
|
||||
bit = bit>>1;
|
||||
if(bit==0) {
|
||||
bit = $80;
|
||||
}
|
||||
}
|
||||
byte* yoffs = $0;
|
||||
for(byte y : 0..255) {
|
||||
plot_ylo[y] = y&$7 | <yoffs;
|
||||
plot_yhi[y] = >yoffs;
|
||||
if((y&$7)==7) {
|
||||
// TODO: Error: Identify 8*40 as a word constant (not a byte)
|
||||
yoffs = yoffs + 320;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Implement inline functions (will be perfect for plot)
|
||||
void plot(byte x, byte y) {
|
||||
byte* plotter = BITMAP;
|
||||
<plotter = plot_xlo[x]+plot_ylo[y];
|
||||
>plotter = plot_xhi[x]+plot_yhi[y];
|
||||
// TODO: Error - <plotter can overflow - and carry must then be added to the >plotter part. Requires new logic?
|
||||
*plotter = *plotter | plot_bit[x];
|
||||
}
|
||||
|
||||
//TODO: Add a default main()-call.
|
||||
main();
|
||||
|
Loading…
Reference in New Issue
Block a user