diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 73e2b0e83..4af0c2b20 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -256,12 +256,12 @@ public class Compiler { // Attempt uplifting registers through a lot of combinations //program.getLog().setVerboseUplift(true); - new Pass4RegisterUpliftCombinations(program).performUplift(10_000); + new Pass4RegisterUpliftCombinations(program).performUplift(200_000); //new Pass4RegisterUpliftStatic(program).performUplift(); // Attempt uplifting registers one at a time to catch remaining potential not realized by combination search - new Pass4RegisterUpliftRemains(program).performUplift(10_000); + new Pass4RegisterUpliftRemains(program).performUplift(100_000); // Final register coalesce and finalization new Pass4ZeroPageCoalesce(program).allocate(); diff --git a/src/main/java/dk/camelot64/kickc/TODO.txt b/src/main/java/dk/camelot64/kickc/TODO.txt index 2ff9d7e87..655da3ea8 100644 --- a/src/main/java/dk/camelot64/kickc/TODO.txt +++ b/src/main/java/dk/camelot64/kickc/TODO.txt @@ -1,5 +1,5 @@ Known Problems -- Increment/decrement of value pointed to by piinter does not work. eg. byte* BGCOL = $d020; (*BGCOL)++; +- 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) {} @@ -7,8 +7,7 @@ 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. - Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end: - Optimize if/else by swapping if & else if cond is easier to evaluate than !cond. -- Add signed bytes -- Add signed words +- Add signed bytes / words - Add Fixed Point number types fixed[8.8], fixed[16.8] - maybe even fixed[24.4] - Add imports - Add structs @@ -24,6 +23,8 @@ 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 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.) Arrays / Strings / Inline data - New semantic: Arrays are always allocated inline (and must therefore have a size). Pointers are never. diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragment.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragment.java index 3e18a4307..c996f2357 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragment.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragment.java @@ -239,9 +239,17 @@ public class AsmFragment { case "!=": return "_neq_"; case "<": - return "_lt_"; + if(operator.getType().equals(Operator.Type.UNARY)) { + return "_lo_"; + } else { + return "_lt_"; + } case ">": - return "_gt_"; + if(operator.getType().equals(Operator.Type.UNARY)) { + return "_hi_"; + } else { + return "_gt_"; + } case "<=": case "=<": return "_le_"; diff --git a/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_hi_zpptrby1.asm b/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_hi_zpptrby1.asm new file mode 100644 index 000000000..8acbb1e30 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_hi_zpptrby1.asm @@ -0,0 +1 @@ +lda >{zpptrby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_lo_zpptrby1.asm b/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_lo_zpptrby1.asm new file mode 100644 index 000000000..1ca7b5f9b --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/fragment/asm/aby=_lo_zpptrby1.asm @@ -0,0 +1 @@ +lda <{zpptrby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/fragment/asm/zpptrby1=coby1.asm b/src/main/java/dk/camelot64/kickc/fragment/asm/zpptrby1=coby1.asm new file mode 100644 index 000000000..22ccee15f --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/fragment/asm/zpptrby1=coby1.asm @@ -0,0 +1,4 @@ +lda #{coby1} +sta {zpptrby1} +lda #0 +sta {zpptrby1}+1 diff --git a/src/main/java/dk/camelot64/kickc/model/Operator.java b/src/main/java/dk/camelot64/kickc/model/Operator.java index 35cfd623b..f32e85e87 100644 --- a/src/main/java/dk/camelot64/kickc/model/Operator.java +++ b/src/main/java/dk/camelot64/kickc/model/Operator.java @@ -74,6 +74,10 @@ public class Operator { return BOOL_NOT; case "*": return STAR; + case "<": + return LOWBYTE; + case ">": + return HIBYTE; default: throw new RuntimeException("Unknown operator " + op); } @@ -90,6 +94,8 @@ public class Operator { public static Operator BOOL_NOT = new Operator("~", Type.UNARY, 2); public static Operator NOT = new Operator("!", Type.UNARY, 2); public static Operator STAR = new Operator("*", Type.UNARY, 2); + 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 MULTIPLY = new Operator("*", Type.BINARY, 3); public static Operator DIVIDE = new Operator("/", Type.BINARY, 3); @@ -117,6 +123,10 @@ public class Operator { return precedence; } + public Type getType() { + return type; + } + @Override public String toString() { return operator; diff --git a/src/main/java/dk/camelot64/kickc/model/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/SymbolTypeInference.java index 6bda5c319..7534bfb94 100644 --- a/src/main/java/dk/camelot64/kickc/model/SymbolTypeInference.java +++ b/src/main/java/dk/camelot64/kickc/model/SymbolTypeInference.java @@ -15,6 +15,12 @@ public class SymbolTypeInference { } else { throw new RuntimeException("Type error: Dereferencing a non-pointer "+subType); } + case "<": + case ">": + if(subType instanceof SymbolTypePointer || SymbolTypeBasic.WORD.equals(subType)) { + return SymbolTypeBasic.BYTE; + + } default: return subType; } @@ -75,6 +81,9 @@ public class SymbolTypeInference { } throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2); case "/": + if (type1 instanceof SymbolTypePointer && SymbolTypeBasic.BYTE.equals(type2)) { + return type1; + } case "&": case "|": case "^": @@ -83,6 +92,7 @@ public class SymbolTypeInference { } else if (SymbolTypeBasic.BYTE.equals(type1) && SymbolTypeBasic.BYTE.equals(type2)) { return SymbolTypeBasic.BYTE; } + throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2); case "<<": case ">>": diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 index 76c560a02..205e1e93a 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 @@ -62,7 +62,7 @@ expr | expr '[' expr ']' #exprArray | ('--' | '++' ) expr #exprPreMod | expr ('--' | '++' )#exprPostMod - | ('+' | '-' | 'not' | '!' | '&' | '*' | '~' ) expr #exprUnary + | ('+' | '-' | 'not' | '!' | '&' | '*' | '~' | '<' | '>') expr #exprUnary | expr ('>>' | '<<' ) expr #exprBinary | expr ('*' | '/' | '%' ) expr #exprBinary | expr ( '+' | '-') expr #exprBinary diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.tokens b/src/main/java/dk/camelot64/kickc/parser/KickC.tokens index cb7395c34..9769128ab 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.tokens +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.tokens @@ -88,19 +88,19 @@ COMMENT_BLOCK=63 '!'=25 '&'=26 '~'=27 -'>>'=28 -'<<'=29 -'/'=30 -'%'=31 -'=='=32 -'!='=33 -'<>'=34 -'<'=35 -'<='=36 -'=<'=37 -'>='=38 -'=>'=39 -'>'=40 +'<'=28 +'>'=29 +'>>'=30 +'<<'=31 +'/'=32 +'%'=33 +'=='=34 +'!='=35 +'<>'=36 +'<='=37 +'=<'=38 +'>='=39 +'=>'=40 '^'=41 '|'=42 'and'=43 diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java index 402bbd091..edcb4647e 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java @@ -49,9 +49,9 @@ public class KickCLexer extends Lexer { private static final String[] _LITERAL_NAMES = { null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['", - "']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'>>'", - "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='", - "'=>'", "'>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'" + "']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'", + "'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'", + "'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -134,10 +134,10 @@ public class KickCLexer extends Lexer { "\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\35\3\36\3\36\3\36\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\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60"+ - "\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u0122\n\60"+ + "\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"+ + "\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u0122\n\60"+ "\3\61\3\61\3\61\3\61\7\61\u0128\n\61\f\61\16\61\u012b\13\61\3\61\3\61"+ "\3\62\3\62\3\62\3\62\5\62\u0133\n\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63"+ "\3\63\3\63\3\63\3\63\5\63\u0140\n\63\3\64\3\64\5\64\u0144\n\64\3\65\3"+ @@ -174,9 +174,9 @@ public class KickCLexer extends Lexer { "\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;\u00dd\3\2\2\2=\u00e0\3\2\2\2?\u00e2\3\2\2\2A\u00e4\3\2\2\2C"+ - "\u00e7\3\2\2\2E\u00ea\3\2\2\2G\u00ed\3\2\2\2I\u00ef\3\2\2\2K\u00f2\3\2"+ - "\2\2M\u00f5\3\2\2\2O\u00f8\3\2\2\2Q\u00fb\3\2\2\2S\u00fd\3\2\2\2U\u00ff"+ + "\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"+ "\3\2\2\2W\u0101\3\2\2\2Y\u0105\3\2\2\2[\u0108\3\2\2\2]\u010b\3\2\2\2_"+ "\u0121\3\2\2\2a\u0123\3\2\2\2c\u012e\3\2\2\2e\u013f\3\2\2\2g\u0143\3\2"+ "\2\2i\u0148\3\2\2\2k\u014f\3\2\2\2m\u0160\3\2\2\2o\u016e\3\2\2\2q\u017f"+ @@ -203,65 +203,65 @@ public class KickCLexer extends Lexer { ".\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\u00dc\7@\2\2\u00dc:\3\2\2\2"+ - "\u00dd\u00de\7>\2\2\u00de\u00df\7>\2\2\u00df<\3\2\2\2\u00e0\u00e1\7\61"+ - "\2\2\u00e1>\3\2\2\2\u00e2\u00e3\7\'\2\2\u00e3@\3\2\2\2\u00e4\u00e5\7?"+ - "\2\2\u00e5\u00e6\7?\2\2\u00e6B\3\2\2\2\u00e7\u00e8\7#\2\2\u00e8\u00e9"+ - "\7?\2\2\u00e9D\3\2\2\2\u00ea\u00eb\7>\2\2\u00eb\u00ec\7@\2\2\u00ecF\3"+ - "\2\2\2\u00ed\u00ee\7>\2\2\u00eeH\3\2\2\2\u00ef\u00f0\7>\2\2\u00f0\u00f1"+ - "\7?\2\2\u00f1J\3\2\2\2\u00f2\u00f3\7?\2\2\u00f3\u00f4\7>\2\2\u00f4L\3"+ - "\2\2\2\u00f5\u00f6\7@\2\2\u00f6\u00f7\7?\2\2\u00f7N\3\2\2\2\u00f8\u00f9"+ - "\7?\2\2\u00f9\u00fa\7@\2\2\u00faP\3\2\2\2\u00fb\u00fc\7@\2\2\u00fcR\3"+ - "\2\2\2\u00fd\u00fe\7`\2\2\u00feT\3\2\2\2\u00ff\u0100\7~\2\2\u0100V\3\2"+ - "\2\2\u0101\u0102\7c\2\2\u0102\u0103\7p\2\2\u0103\u0104\7f\2\2\u0104X\3"+ - "\2\2\2\u0105\u0106\7(\2\2\u0106\u0107\7(\2\2\u0107Z\3\2\2\2\u0108\u0109"+ - "\7q\2\2\u0109\u010a\7t\2\2\u010a\\\3\2\2\2\u010b\u010c\7~\2\2\u010c\u010d"+ - "\7~\2\2\u010d^\3\2\2\2\u010e\u010f\7d\2\2\u010f\u0110\7{\2\2\u0110\u0111"+ - "\7v\2\2\u0111\u0122\7g\2\2\u0112\u0113\7y\2\2\u0113\u0114\7q\2\2\u0114"+ - "\u0115\7t\2\2\u0115\u0122\7f\2\2\u0116\u0117\7d\2\2\u0117\u0118\7q\2\2"+ - "\u0118\u0119\7q\2\2\u0119\u011a\7n\2\2\u011a\u011b\7g\2\2\u011b\u011c"+ - "\7c\2\2\u011c\u0122\7p\2\2\u011d\u011e\7x\2\2\u011e\u011f\7q\2\2\u011f"+ - "\u0120\7k\2\2\u0120\u0122\7f\2\2\u0121\u010e\3\2\2\2\u0121\u0112\3\2\2"+ - "\2\u0121\u0116\3\2\2\2\u0121\u011d\3\2\2\2\u0122`\3\2\2\2\u0123\u0129"+ - "\7$\2\2\u0124\u0125\7^\2\2\u0125\u0128\7$\2\2\u0126\u0128\n\2\2\2\u0127"+ - "\u0124\3\2\2\2\u0127\u0126\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127\3\2"+ - "\2\2\u0129\u012a\3\2\2\2\u012a\u012c\3\2\2\2\u012b\u0129\3\2\2\2\u012c"+ - "\u012d\7$\2\2\u012db\3\2\2\2\u012e\u0132\7)\2\2\u012f\u0130\7^\2\2\u0130"+ - "\u0133\7)\2\2\u0131\u0133\n\3\2\2\u0132\u012f\3\2\2\2\u0132\u0131\3\2"+ - "\2\2\u0133\u0134\3\2\2\2\u0134\u0135\7)\2\2\u0135d\3\2\2\2\u0136\u0137"+ - "\7v\2\2\u0137\u0138\7t\2\2\u0138\u0139\7w\2\2\u0139\u0140\7g\2\2\u013a"+ - "\u013b\7h\2\2\u013b\u013c\7c\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2"+ - "\u013e\u0140\7g\2\2\u013f\u0136\3\2\2\2\u013f\u013a\3\2\2\2\u0140f\3\2"+ - "\2\2\u0141\u0144\5i\65\2\u0142\u0144\5q9\2\u0143\u0141\3\2\2\2\u0143\u0142"+ - "\3\2\2\2\u0144h\3\2\2\2\u0145\u0149\5k\66\2\u0146\u0149\5m\67\2\u0147"+ - "\u0149\5o8\2\u0148\u0145\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0147\3\2\2"+ - "\2\u0149j\3\2\2\2\u014a\u0150\7\'\2\2\u014b\u014c\7\62\2\2\u014c\u0150"+ - "\7d\2\2\u014d\u014e\7\62\2\2\u014e\u0150\7D\2\2\u014f\u014a\3\2\2\2\u014f"+ - "\u014b\3\2\2\2\u014f\u014d\3\2\2\2\u0150\u0154\3\2\2\2\u0151\u0153\5y"+ - "=\2\u0152\u0151\3\2\2\2\u0153\u0156\3\2\2\2\u0154\u0152\3\2\2\2\u0154"+ - "\u0155\3\2\2\2\u0155\u0157\3\2\2\2\u0156\u0154\3\2\2\2\u0157\u0159\7\60"+ - "\2\2\u0158\u015a\5y=\2\u0159\u0158\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u0159"+ - "\3\2\2\2\u015b\u015c\3\2\2\2\u015cl\3\2\2\2\u015d\u015f\5{>\2\u015e\u015d"+ - "\3\2\2\2\u015f\u0162\3\2\2\2\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161"+ - "\u0163\3\2\2\2\u0162\u0160\3\2\2\2\u0163\u0165\7\60\2\2\u0164\u0166\5"+ - "{>\2\u0165\u0164\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0165\3\2\2\2\u0167"+ - "\u0168\3\2\2\2\u0168n\3\2\2\2\u0169\u016f\7&\2\2\u016a\u016b\7\62\2\2"+ - "\u016b\u016f\7z\2\2\u016c\u016d\7\62\2\2\u016d\u016f\7Z\2\2\u016e\u0169"+ - "\3\2\2\2\u016e\u016a\3\2\2\2\u016e\u016c\3\2\2\2\u016f\u0173\3\2\2\2\u0170"+ - "\u0172\5}?\2\u0171\u0170\3\2\2\2\u0172\u0175\3\2\2\2\u0173\u0171\3\2\2"+ - "\2\u0173\u0174\3\2\2\2\u0174\u0176\3\2\2\2\u0175\u0173\3\2\2\2\u0176\u0178"+ - "\7\60\2\2\u0177\u0179\5}?\2\u0178\u0177\3\2\2\2\u0179\u017a\3\2\2\2\u017a"+ - "\u0178\3\2\2\2\u017a\u017b\3\2\2\2\u017bp\3\2\2\2\u017c\u0180\5u;\2\u017d"+ - "\u0180\5w<\2\u017e\u0180\5s:\2\u017f\u017c\3\2\2\2\u017f\u017d\3\2\2\2"+ - "\u017f\u017e\3\2\2\2\u0180r\3\2\2\2\u0181\u0182\7\62\2\2\u0182\u0184\t"+ - "\4\2\2\u0183\u0185\5y=\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186"+ - "\u0184\3\2\2\2\u0186\u0187\3\2\2\2\u0187\u018f\3\2\2\2\u0188\u018a\7\'"+ - "\2\2\u0189\u018b\5y=\2\u018a\u0189\3\2\2\2\u018b\u018c\3\2\2\2\u018c\u018a"+ - "\3\2\2\2\u018c\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u0181\3\2\2\2\u018e"+ - "\u0188\3\2\2\2\u018ft\3\2\2\2\u0190\u0192\5{>\2\u0191\u0190\3\2\2\2\u0192"+ - "\u0193\3\2\2\2\u0193\u0191\3\2\2\2\u0193\u0194\3\2\2\2\u0194v\3\2\2\2"+ - "\u0195\u019b\7&\2\2\u0196\u0197\7\62\2\2\u0197\u019b\7z\2\2\u0198\u0199"+ - "\7\62\2\2\u0199\u019b\7Z\2\2\u019a\u0195\3\2\2\2\u019a\u0196\3\2\2\2\u019a"+ + "\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"+ + "\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"+ + "\7`\2\2\u00feT\3\2\2\2\u00ff\u0100\7~\2\2\u0100V\3\2\2\2\u0101\u0102\7"+ + "c\2\2\u0102\u0103\7p\2\2\u0103\u0104\7f\2\2\u0104X\3\2\2\2\u0105\u0106"+ + "\7(\2\2\u0106\u0107\7(\2\2\u0107Z\3\2\2\2\u0108\u0109\7q\2\2\u0109\u010a"+ + "\7t\2\2\u010a\\\3\2\2\2\u010b\u010c\7~\2\2\u010c\u010d\7~\2\2\u010d^\3"+ + "\2\2\2\u010e\u010f\7d\2\2\u010f\u0110\7{\2\2\u0110\u0111\7v\2\2\u0111"+ + "\u0122\7g\2\2\u0112\u0113\7y\2\2\u0113\u0114\7q\2\2\u0114\u0115\7t\2\2"+ + "\u0115\u0122\7f\2\2\u0116\u0117\7d\2\2\u0117\u0118\7q\2\2\u0118\u0119"+ + "\7q\2\2\u0119\u011a\7n\2\2\u011a\u011b\7g\2\2\u011b\u011c\7c\2\2\u011c"+ + "\u0122\7p\2\2\u011d\u011e\7x\2\2\u011e\u011f\7q\2\2\u011f\u0120\7k\2\2"+ + "\u0120\u0122\7f\2\2\u0121\u010e\3\2\2\2\u0121\u0112\3\2\2\2\u0121\u0116"+ + "\3\2\2\2\u0121\u011d\3\2\2\2\u0122`\3\2\2\2\u0123\u0129\7$\2\2\u0124\u0125"+ + "\7^\2\2\u0125\u0128\7$\2\2\u0126\u0128\n\2\2\2\u0127\u0124\3\2\2\2\u0127"+ + "\u0126\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127\3\2\2\2\u0129\u012a\3\2"+ + "\2\2\u012a\u012c\3\2\2\2\u012b\u0129\3\2\2\2\u012c\u012d\7$\2\2\u012d"+ + "b\3\2\2\2\u012e\u0132\7)\2\2\u012f\u0130\7^\2\2\u0130\u0133\7)\2\2\u0131"+ + "\u0133\n\3\2\2\u0132\u012f\3\2\2\2\u0132\u0131\3\2\2\2\u0133\u0134\3\2"+ + "\2\2\u0134\u0135\7)\2\2\u0135d\3\2\2\2\u0136\u0137\7v\2\2\u0137\u0138"+ + "\7t\2\2\u0138\u0139\7w\2\2\u0139\u0140\7g\2\2\u013a\u013b\7h\2\2\u013b"+ + "\u013c\7c\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2\u013e\u0140\7g\2\2"+ + "\u013f\u0136\3\2\2\2\u013f\u013a\3\2\2\2\u0140f\3\2\2\2\u0141\u0144\5"+ + "i\65\2\u0142\u0144\5q9\2\u0143\u0141\3\2\2\2\u0143\u0142\3\2\2\2\u0144"+ + "h\3\2\2\2\u0145\u0149\5k\66\2\u0146\u0149\5m\67\2\u0147\u0149\5o8\2\u0148"+ + "\u0145\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0147\3\2\2\2\u0149j\3\2\2\2"+ + "\u014a\u0150\7\'\2\2\u014b\u014c\7\62\2\2\u014c\u0150\7d\2\2\u014d\u014e"+ + "\7\62\2\2\u014e\u0150\7D\2\2\u014f\u014a\3\2\2\2\u014f\u014b\3\2\2\2\u014f"+ + "\u014d\3\2\2\2\u0150\u0154\3\2\2\2\u0151\u0153\5y=\2\u0152\u0151\3\2\2"+ + "\2\u0153\u0156\3\2\2\2\u0154\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0157"+ + "\3\2\2\2\u0156\u0154\3\2\2\2\u0157\u0159\7\60\2\2\u0158\u015a\5y=\2\u0159"+ + "\u0158\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3\2"+ + "\2\2\u015cl\3\2\2\2\u015d\u015f\5{>\2\u015e\u015d\3\2\2\2\u015f\u0162"+ + "\3\2\2\2\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0163\3\2\2\2\u0162"+ + "\u0160\3\2\2\2\u0163\u0165\7\60\2\2\u0164\u0166\5{>\2\u0165\u0164\3\2"+ + "\2\2\u0166\u0167\3\2\2\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168"+ + "n\3\2\2\2\u0169\u016f\7&\2\2\u016a\u016b\7\62\2\2\u016b\u016f\7z\2\2\u016c"+ + "\u016d\7\62\2\2\u016d\u016f\7Z\2\2\u016e\u0169\3\2\2\2\u016e\u016a\3\2"+ + "\2\2\u016e\u016c\3\2\2\2\u016f\u0173\3\2\2\2\u0170\u0172\5}?\2\u0171\u0170"+ + "\3\2\2\2\u0172\u0175\3\2\2\2\u0173\u0171\3\2\2\2\u0173\u0174\3\2\2\2\u0174"+ + "\u0176\3\2\2\2\u0175\u0173\3\2\2\2\u0176\u0178\7\60\2\2\u0177\u0179\5"+ + "}?\2\u0178\u0177\3\2\2\2\u0179\u017a\3\2\2\2\u017a\u0178\3\2\2\2\u017a"+ + "\u017b\3\2\2\2\u017bp\3\2\2\2\u017c\u0180\5u;\2\u017d\u0180\5w<\2\u017e"+ + "\u0180\5s:\2\u017f\u017c\3\2\2\2\u017f\u017d\3\2\2\2\u017f\u017e\3\2\2"+ + "\2\u0180r\3\2\2\2\u0181\u0182\7\62\2\2\u0182\u0184\t\4\2\2\u0183\u0185"+ + "\5y=\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u0184\3\2\2\2\u0186"+ + "\u0187\3\2\2\2\u0187\u018f\3\2\2\2\u0188\u018a\7\'\2\2\u0189\u018b\5y"+ + "=\2\u018a\u0189\3\2\2\2\u018b\u018c\3\2\2\2\u018c\u018a\3\2\2\2\u018c"+ + "\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u0181\3\2\2\2\u018e\u0188\3\2"+ + "\2\2\u018ft\3\2\2\2\u0190\u0192\5{>\2\u0191\u0190\3\2\2\2\u0192\u0193"+ + "\3\2\2\2\u0193\u0191\3\2\2\2\u0193\u0194\3\2\2\2\u0194v\3\2\2\2\u0195"+ + "\u019b\7&\2\2\u0196\u0197\7\62\2\2\u0197\u019b\7z\2\2\u0198\u0199\7\62"+ + "\2\2\u0199\u019b\7Z\2\2\u019a\u0195\3\2\2\2\u019a\u0196\3\2\2\2\u019a"+ "\u0198\3\2\2\2\u019b\u019d\3\2\2\2\u019c\u019e\5}?\2\u019d\u019c\3\2\2"+ "\2\u019e\u019f\3\2\2\2\u019f\u019d\3\2\2\2\u019f\u01a0\3\2\2\2\u01a0x"+ "\3\2\2\2\u01a1\u01a2\t\5\2\2\u01a2z\3\2\2\2\u01a3\u01a4\t\6\2\2\u01a4"+ diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens index cb7395c34..9769128ab 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens +++ b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens @@ -88,19 +88,19 @@ COMMENT_BLOCK=63 '!'=25 '&'=26 '~'=27 -'>>'=28 -'<<'=29 -'/'=30 -'%'=31 -'=='=32 -'!='=33 -'<>'=34 -'<'=35 -'<='=36 -'=<'=37 -'>='=38 -'=>'=39 -'>'=40 +'<'=28 +'>'=29 +'>>'=30 +'<<'=31 +'/'=32 +'%'=33 +'=='=34 +'!='=35 +'<>'=36 +'<='=37 +'=<'=38 +'>='=39 +'=>'=40 '^'=41 '|'=42 'and'=43 diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java index 493af0a53..4ae5b5c47 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java @@ -39,9 +39,9 @@ public class KickCParser extends Parser { private static final String[] _LITERAL_NAMES = { null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['", - "']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'>>'", - "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='", - "'=>'", "'>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'" + "']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'", + "'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'", + "'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -194,7 +194,7 @@ public class KickCParser extends Parser { setState(30); _errHandler.sync(this); _la = _input.LA(1); - } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) ); + } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) ); } } catch (RecognitionException re) { @@ -459,7 +459,7 @@ public class KickCParser extends Parser { setState(34); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { setState(33); stmtSeq(); @@ -497,7 +497,7 @@ public class KickCParser extends Parser { setState(46); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (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 << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { { setState(45); stmtSeq(); @@ -663,7 +663,7 @@ public class KickCParser extends Parser { setState(102); _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 << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + 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(101); expr(0); @@ -844,7 +844,7 @@ public class KickCParser extends Parser { setState(119); _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 << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + 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(118); expr(0); @@ -1122,7 +1122,7 @@ public class KickCParser extends Parser { setState(147); _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 << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + 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(146); expr(0); @@ -1224,6 +1224,8 @@ public class KickCParser extends Parser { case T__24: case T__25: case T__26: + case T__27: + case T__28: case STRING: case CHAR: case BOOLEAN: @@ -1767,7 +1769,7 @@ public class KickCParser extends Parser { setState(197); _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 << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) { + 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); parameterList(); @@ -1819,7 +1821,7 @@ public class KickCParser extends Parser { _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))) != 0)) ) { + 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)) ) { _errHandler.recoverInline(this); } else { @@ -1897,7 +1899,7 @@ public class KickCParser extends Parser { if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); setState(217); _la = _input.LA(1); - if ( !(_la==T__27 || _la==T__28) ) { + if ( !(_la==T__29 || _la==T__30) ) { _errHandler.recoverInline(this); } else { @@ -1917,7 +1919,7 @@ public class KickCParser extends Parser { if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); setState(220); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__29) | (1L << T__30))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__31) | (1L << T__32))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -1957,7 +1959,7 @@ public class KickCParser extends Parser { if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); setState(226); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__31) | (1L << T__32) | (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__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)) ) { _errHandler.recoverInline(this); } else { @@ -2242,9 +2244,9 @@ public class KickCParser extends Parser { "\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\35\3\2\36\37\4\2\23\23 !\3\2\30\31\3\2\"*"+ - "\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"+ + "\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"+ diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java index 859a174ac..5742ca07e 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java @@ -158,6 +158,10 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { case "+": case "*": case "/": + case "&": + case "|": + case "<<": + case ">>": return new ConstantBinary(c1, operator, c2); case "*idx": // Pointer dereference - not constant diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftStatic.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftStatic.java index d8333ab2f..43f00ff9c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftStatic.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftStatic.java @@ -50,12 +50,22 @@ public class Pass4RegisterUpliftStatic extends Pass2Base { */ // Clobber combination for scroll-clobber.kc + /* setRegister(combination, "main::c#0", Registers.getRegisterA()); setRegister(combination, "main::c#1", Registers.getRegisterA()); setRegister(combination, "main::c#2", Registers.getRegisterA()); setRegister(combination, "main::i#1", Registers.getRegisterX()); setRegister(combination, "main::i#3", Registers.getRegisterX()); setRegister(combination, "main::nxt#1", new Registers.RegisterZpPointerByte(2)); + */ + + // ALU combination for bitmap-bresenham.kc + 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()); boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm( combination, diff --git a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java index f961e5f36..4b8078a9d 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java +++ b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java @@ -24,6 +24,10 @@ public class TestCompilationOutput extends TestCase { helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/"); } + public void testBitmapBresenham() throws IOException, URISyntaxException { + compileAndCompare("bitmap-bresenham"); + } + public void testScrollClobber() throws IOException, URISyntaxException { compileAndCompare("scroll-clobber"); } diff --git a/src/main/java/dk/camelot64/kickc/test/bitmap-bresenham.kc b/src/main/java/dk/camelot64/kickc/test/bitmap-bresenham.kc new file mode 100644 index 000000000..6e3224af9 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/bitmap-bresenham.kc @@ -0,0 +1,86 @@ +byte* COLS = $d800; +byte* BGCOL = $d020; +byte* FGCOL = $d021; +byte* SCROLL = $d016; +byte* D018 = $d018; + +byte* D011 = $d011; +byte RST8 = %10000000; +byte ECM = %01000000; +byte BMM = %00100000; +byte DEN = %00010000; +byte RSEL = %00001000; + +byte* D016 = $d016; +byte MCM = %00010000; +byte CSEL = %00001000; + +byte* SCREEN = $400; +byte* BITMAP = $2000; + +byte[] plot_xlo = $1000; +byte[] plot_xhi = $1100; +byte[] plot_ylo = $1200; +byte[] plot_yhi = $1300; + +main(); + +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. + initscreen(); + initplottables(); + line(0,0,10,20); + 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; + yoffs = yoffs + 40*8; + } + +} + +void line(byte x0, byte y0, byte x1, byte y1) { + byte* plot_lo = $fd; + byte* plot_hi = $fe; + byte xd = x1-x0; + byte yd = y1-y0; + byte x = x0; + byte y = y0; + byte e = yd<<1; + do { + //plot(x,y); + *plot_lo = plot_xlo[x]+plot_ylo[y]; + *plot_hi = plot_xhi[x]+plot_yhi[y]; + x = x + 1; + e = e+yd; + if(xd