1
0
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:
jespergravgaard 2017-10-29 01:56:53 +02:00
parent f60be66531
commit 00f53c49b6
53 changed files with 629 additions and 284 deletions

View File

@ -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();

View File

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

View File

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

View File

@ -1 +1 @@
lda >{zpptrby1}
lda {zpptrby1}+1

View File

@ -1 +1 @@
lda <{zpptrby1}
lda {zpptrby1}

View File

@ -0,0 +1 @@
ora >{zpptrby1}

View File

@ -0,0 +1 @@
ora <{zpptrby1}

View File

@ -0,0 +1 @@
// A is A or A

View File

@ -0,0 +1 @@
ora {cowo1},x

View File

@ -0,0 +1 @@
ora {cowo1},y

View File

@ -0,0 +1,3 @@
lda {zpby1}
ldx {zpby2}
ora {cowo1},x

View File

@ -0,0 +1,3 @@
sta {zpptrby1}
lda #>{cowo1}
sta {zpptrby1}+1

View File

@ -0,0 +1,3 @@
stx {zpptrby1}
lda #>{cowo1}
sta {zpptrby1}+1

View File

@ -0,0 +1,3 @@
sty {zpptrby1}
lda #>{cowo1}
sta {zpptrby1}+1

View File

@ -0,0 +1,4 @@
lda {zpby1}
sta {zpptrby1}
lda #>{cowo1}
sta {zpptrby1}+1

View File

@ -0,0 +1,8 @@
lda {zpptrby1}
clc
adc #<{cowo1}
sta {zpptrby1}
lda {zpptrby1}+1
adc #>{cowo1}
sta {zpptrby1}+1

View File

@ -0,0 +1 @@
sta {zpptrby1}+1

View File

@ -0,0 +1 @@
stx {zpptrby1}+1

View File

@ -0,0 +1 @@
sty {zpptrby1}+1

View File

@ -0,0 +1 @@
sta {zpptrby1}

View File

@ -0,0 +1 @@
stx {zpptrby1}

View File

@ -0,0 +1 @@
sty {zpptrby1}

View File

@ -0,0 +1,3 @@
sta {zpptrby1}+1
lda {zpptrby2}
sta {zpptrby1}

View File

@ -0,0 +1,3 @@
stx {zpptrby1}+1
lda {zpptrby2}
sta {zpptrby1}

View File

@ -0,0 +1,3 @@
sty {zpptrby1}+1
lda {zpptrby2}
sta {zpptrby1}

View File

@ -0,0 +1,4 @@
lda {zpptrby2}
sta {zpptrby1}
lda {zpby1}
sta {zpptrby1}+1

View File

@ -0,0 +1,3 @@
sta {zpptrby1}
lda {zpptrby2}+1
sta {zpptrby1}+1

View File

@ -0,0 +1,3 @@
stx {zpptrby1}
lda {zpptrby2}+1
sta {zpptrby1}+1

View File

@ -0,0 +1,3 @@
sty {zpptrby1}
lda {zpptrby2}+1
sta {zpptrby1}+1

View File

@ -0,0 +1,4 @@
lda {zpby1}
sta {zpptrby1}
lda {zpptrby2}+1
sta {zpptrby1}+1

View 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;
}
}

View File

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

View File

@ -16,4 +16,4 @@ public class VariableRef extends SymbolRef implements RValue, LValue {
this(variable.getFullName());
}
}
}

View File

@ -52,6 +52,7 @@ lvalue
: '(' lvalue ')' #lvaluePar
| NAME #lvalueName
| '*' lvalue #lvaluePtr
| ('<' | '>' ) lvalue #lvalueLoHi
| lvalue '[' expr ']' #lvalueArray
;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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>&lt;plotter = x &amp; 8 </code>
* <br>Becomes: <code> $1 =x &amp; 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;
}
}

View File

@ -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());

View File

@ -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 (&gt;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());
}
}

View File

@ -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());
}
}

View File

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

View File

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

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}

View File

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

View File

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

View File

@ -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();