1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added explicit casting - started testing it on byte / signed byte.

This commit is contained in:
jespergravgaard 2017-11-24 23:25:16 +01:00
parent d348365010
commit 0efe62585b
26 changed files with 186 additions and 139 deletions

View File

@ -92,21 +92,30 @@ public class AsmFragmentManager {
synths.add(new FragmentSynthesis("(.*)=(.*)_(band|bor|plus)_(ys?by)", ".*=[axy]s?by_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new FragmentSynthesis("xby=(.*)", null, null, "aby=$1", "tax\n", null));
synths.add(new FragmentSynthesis("xsby=(.*)", null, null, "asby=$1", "tax\n", null));
synths.add(new FragmentSynthesis("yby=(.*)", null, null, "aby=$1", "tay\n", null));
synths.add(new FragmentSynthesis("zpby1=(.*)", ".*=.*zps?by1.*", null, "aby=$1", "sta {zpby1}\n", mapZpby));
synths.add(new FragmentSynthesis("zpsby1=(.*)", ".*=.*zps?by1.*", null, "asby=$1", "sta {zpsby1}\n", mapZpsby));
synths.add(new FragmentSynthesis("ysby=(.*)", null, null, "asby=$1", "tay\n", null));
synths.add(new FragmentSynthesis("zpby1=(.*)", ".*=.*zpby1.*", null, "aby=$1", "sta {zpby1}\n", mapZpby));
synths.add(new FragmentSynthesis("zpsby1=(.*)", ".*=.*zpsby1.*", null, "asby=$1", "sta {zpsby1}\n", mapZpsby));
synths.add(new FragmentSynthesis("_deref_cowo1=(.*)", null, null, "aby=$1", "sta {cowo1}\n", mapConst));
synths.add(new FragmentSynthesis("_deref_zpptrby1=(.*)", ".*=.*zpptrs?by1.*", null, "aby=$1", "ldy #0\n" + "sta ({zpptrby1}),y\n", mapZpptrby));
synths.add(new FragmentSynthesis("_deref_zpptrby1=(.*)", ".*=.*zpptrby1.*", null, "aby=$1", "ldy #0\n" + "sta ({zpptrby1}),y\n", mapZpptrby));
synths.add(new FragmentSynthesis("(.*)=xby(.*)", ".*=.*as?by.*", "txa\n", "$1=aby$2", null, null));
synths.add(new FragmentSynthesis("(.*)=yby(.*)", ".*=.*as?by.*", "tya\n", "$1=aby$2", null, null));
synths.add(new FragmentSynthesis("(.*)=zpby1(.*)", ".*=.*as?by.*|zps?by1=.*", "lda {zpby1}\n", "$1=aby$2", null, mapZpby));
synths.add(new FragmentSynthesis("(.*)=zpsby1(.*)", ".*=.*as?by.*|zps?by1=.*", "lda {zpsby1}\n", "$1=aby$2", null, mapZpsby));
synths.add(new FragmentSynthesis("(.*)=zpby1(.*)", ".*=.*as?by.*|zpby1=.*", "lda {zpby1}\n", "$1=aby$2", null, mapZpby));
synths.add(new FragmentSynthesis("(.*)=zpsby1(.*)", ".*=.*as?by.*|zpsby1=.*", "lda {zpsby1}\n", "$1=aby$2", null, mapZpsby));
synths.add(new FragmentSynthesis("(.*)=_deref_cowo1(.*)", ".*=.*as?by.*", "lda {cowo1}\n", "$1=aby$2", null, mapConst));
synths.add(new FragmentSynthesis("(.*)=_deref_zpptrby1(.*)", ".*=.*as?by.*|.*=.*ys?by.*", "ldy #0\n"+"lda ({zpptrby1}),y\n", "$1=aby$2", null, mapZpptrby));
synths.add(new FragmentSynthesis("(.*)=(.*)_xby", ".*=[ax]s?by.*xs?by", "txa\n", "$1=$2_aby", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_xsby", ".*=[ax]s?by.*xs?by", "txa\n", "$1=$2_asby", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_yby", ".*=[ay]s?by.*ys?by", "tya\n", "$1=$2_aby", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_ysby", ".*=[ay]s?by.*ys?by", "tya\n", "$1=$2_asby", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_zpby1", ".*=.*as?by.*", "lda {zpby1}\n", "$1=$2_aby", null, mapZpby));
synths.add(new FragmentSynthesis("(.*)=(.*)_zpsby1", ".*=.*as?by.*", "lda {zpsby1}\n", "$1=$2_asby", null, mapZpsby));
synths.add(new FragmentSynthesis("zpby1=zpby1(.*)", ".*=.*as?by.*", "lda {zpby1}\n", "aby=aby$1", "sta {zpby1}\n", mapZpby));
synths.add(new FragmentSynthesis("zpsby1=zpsby1(.*)", ".*=.*as?by.*", "lda {zpsby1}\n", "aby=aby$1", "sta {zpsby1}\n", mapZpby));
synths.add(new FragmentSynthesis("zpsby1=zpsby1(.*)", ".*=.*as?by.*", "lda {zpsby1}\n", "asby=asby$1", "sta {zpsby1}\n", mapZpby));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_aby", ".*=.*ys?by.*", "tay\n", "$1=$2_derefidx_yby", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_aby", ".*=.*xs?by.*", "tax\n", "$1=$2_derefidx_xby", null, null));

View File

@ -5,19 +5,29 @@ import dk.camelot64.kickc.model.*;
import java.util.LinkedHashMap;
import java.util.Map;
/** A fragment signature generated from a {@link Statement} used to load/synthesize an AsmFragent for creating ASM code for the statement*/
/**
* A fragment signature generated from a {@link Statement} used to load/synthesize an AsmFragent for creating ASM code for the statement
*/
public class AsmFragmentSignature {
/** The symbol table. */
/**
* The symbol table.
*/
private Program program;
/** The string signature/name of the fragment fragment. */
/**
* The string signature/name of the fragment fragment.
*/
private String signature;
/** Binding of named values in the fragment to values (constants, variables, ...) . */
/**
* Binding of named values in the fragment to values (constants, variables, ...) .
*/
private Map<String, Value> bindings;
/** The scope containing the fragment. Used when referencing symbols defined in other scopes. */
/**
* The scope containing the fragment. Used when referencing symbols defined in other scopes.
*/
private ScopeRef codeScopeRef;
public AsmFragmentSignature(
@ -161,68 +171,7 @@ public class AsmFragmentSignature {
}
private static String getOperatorFragmentName(Operator operator) {
String op = operator.getOperator();
switch (op) {
case "*":
if(operator.getType().equals(Operator.Type.UNARY)) {
return "_deref_";
} else {
return "_mul_";
}
case "*idx":
return "_derefidx_";
case "+":
return "_plus_";
case "++":
return "_inc_";
case "--":
return "_dec_";
case "-":
return "_minus_";
case "==":
return "_eq_";
case "<>":
case "!=":
return "_neq_";
case "<":
if(operator.getType().equals(Operator.Type.UNARY)) {
return "_lo_";
} else {
return "_lt_";
}
case ">":
if(operator.getType().equals(Operator.Type.UNARY)) {
return "_hi_";
} else {
return "_gt_";
}
case "<=":
case "=<":
return "_le_";
case ">=":
case "=>":
return "_ge_";
case ">>":
return "_ror_";
case "<<":
return "_rol_";
case "&":
return "_band_";
case "|":
return "_bor_";
case "^":
return "_bxor_";
case "!":
return "_not_";
case "~":
return "_bnot_";
case "lo=":
return "_setlo_";
case "hi=":
return "_sethi_";
default:
return op;
}
return operator.getAsmOperator();
}
public String getSignature() {
@ -364,7 +313,7 @@ public class AsmFragmentSignature {
bindings.put(name, value);
return name;
}
} else if(value instanceof ConstantValue) {
} else if (value instanceof ConstantValue) {
SymbolType type = SymbolTypeInference.inferType(program.getScope(), (ConstantValue) value);
if (SymbolTypeBasic.BYTE.equals(type)) {
String name = "coby" + nextConstByteIdx++;

View File

@ -0,0 +1 @@
// Do nothing: casting signed byte to byte

View File

@ -0,0 +1,3 @@
eor #$ff
clc
adc #{coby1}+1

View File

@ -0,0 +1,4 @@
stx $ff
lda #{coby1}
sec
sbc $ff

View File

@ -0,0 +1,4 @@
sty $ff
lda #{coby1}
sec
sbc $ff

View File

@ -0,0 +1,3 @@
eor #$ff
clc
adc #$01

View File

@ -0,0 +1 @@
// casting byte to sbyte - do nothing

View File

@ -0,0 +1 @@
txa

View File

@ -0,0 +1 @@
tya

View File

@ -0,0 +1 @@
// Do nothing: casting signed byte to byte

View File

@ -0,0 +1 @@
// casting - do nothing

View File

@ -0,0 +1 @@
ldx {zpby1}

View File

@ -0,0 +1 @@
// Do nothing: casting signed byte to byte

View File

@ -0,0 +1 @@
// casting - do nothing

View File

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

View File

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

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.model;
/** An Operator. The operation performed on the rvalues in a Statement. */
/**
* An Operator. The operation performed on the rvalues in a Statement.
*/
public class Operator {
private String operator;
@ -9,10 +11,13 @@ public class Operator {
private Type type;
public Operator(String operator, Type type, int precedence) {
private String asmOperator;
public Operator(String operator, String asmOperator, Type type, int precedence) {
this.operator = operator;
this.precedence = precedence;
this.type = type;
this.asmOperator = asmOperator;
}
public static Operator getBinary(String op) {
@ -38,7 +43,7 @@ public class Operator {
case ">=":
return GE;
case "*idx":
return STAR_IDX;
return DEREF_IDX;
case "&&":
return LOGIC_AND;
case "||":
@ -77,7 +82,7 @@ public class Operator {
case "~":
return BOOL_NOT;
case "*":
return STAR;
return DEREF;
case "<":
return LOWBYTE;
case ">":
@ -87,39 +92,58 @@ public class Operator {
}
}
public static enum Type {
public static Operator getCastUnary(SymbolType castType) {
if (SymbolTypeBasic.BYTE.equals(castType)) {
return CAST_BYTE;
} else if (SymbolTypeBasic.SBYTE.equals(castType)) {
return CAST_SBYTE;
} else if (SymbolTypeBasic.WORD.equals(castType)) {
return CAST_WORD;
} else if (SymbolTypeBasic.SWORD.equals(castType)) {
return CAST_SWORD;
} else {
throw new RuntimeException("Unknown cast type " + castType);
}
}
public enum Type {
UNARY, BINARY
}
public static Operator INCREMENT = new Operator("++", Type.UNARY, 1);
public static Operator DECREMENT = new Operator("--", Type.UNARY, 1);
public static Operator UNARY_PLUS = new Operator("+", Type.UNARY, 2);
public static Operator UNARY_MINUS = new Operator("-", Type.UNARY, 2);
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 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);
public static Operator MINUS = new Operator("-", Type.BINARY, 4);
public static Operator SHIFT_LEFT = new Operator("<<", Type.BINARY, 5);
public static Operator SHIFT_RIGHT = new Operator(">>", Type.BINARY, 5);
public static Operator LT = new Operator("<", Type.BINARY, 6);
public static Operator LE = new Operator("<=", Type.BINARY, 6);
public static Operator GT = new Operator(">", Type.BINARY, 6);
public static Operator GE = new Operator(">=", Type.BINARY, 6);
public static Operator EQ = new Operator("==", Type.BINARY, 7);
public static Operator NEQ = new Operator("!=", Type.BINARY, 7);
public static Operator BOOL_AND = new Operator("&", Type.BINARY, 8);
public static Operator BOOL_XOR = new Operator("^", Type.BINARY, 9);
public static Operator BOOL_OR = new Operator("|", Type.BINARY, 10);
public static Operator LOGIC_AND = new Operator("&&", Type.BINARY, 11);
public static Operator LOGIC_OR = new Operator("||", Type.BINARY, 12);
public static final Operator INCREMENT = new Operator("++", "_inc_", Type.UNARY, 1);
public static final Operator DECREMENT = new Operator("--", "_dec_", Type.UNARY, 1);
public static final Operator UNARY_PLUS = new Operator("+", "_pos_", Type.UNARY, 2);
public static final Operator UNARY_MINUS = new Operator("-", "_neg_", Type.UNARY, 2);
public static final Operator BOOL_NOT = new Operator("~", "_not_", Type.UNARY, 2);
public static final Operator NOT = new Operator("!", "_not_", Type.UNARY, 2);
public static final Operator DEREF = new Operator("*", "_deref_", Type.UNARY, 2);
public static final Operator LOWBYTE = new Operator("<", "_lo_", Type.UNARY, 2);
public static final Operator HIBYTE = new Operator(">", "_hi_", Type.UNARY, 2);
public static final Operator DEREF_IDX = new Operator("*idx", "_derefidx_", Type.BINARY, 2);
public static final Operator SET_LOWBYTE = new Operator("lo=", "_setlo_", Type.BINARY, 2);
public static final Operator SET_HIBYTE = new Operator("hi=", "_sethi_", Type.BINARY, 2);
public static final Operator CAST_BYTE = new Operator("_byte_", "_byte_", Type.UNARY, 2);
public static final Operator CAST_SBYTE = new Operator("_sbyte_", "_sbyte_", Type.UNARY, 2);
public static final Operator CAST_WORD = new Operator("_word_", "_word_", Type.UNARY, 2);
public static final Operator CAST_SWORD = new Operator("_sword_", "_sword_", Type.UNARY, 2);
public static final Operator MULTIPLY = new Operator("*", "_mul_", Type.BINARY, 3);
public static final Operator DIVIDE = new Operator("/", "_div_", Type.BINARY, 3);
public static final Operator PLUS = new Operator("+", "_plus_", Type.BINARY, 4);
public static final Operator MINUS = new Operator("-", "_minus_", Type.BINARY, 4);
public static final Operator SHIFT_LEFT = new Operator("<<", "_rol_", Type.BINARY, 5);
public static final Operator SHIFT_RIGHT = new Operator(">>", "_ror_", Type.BINARY, 5);
public static final Operator LT = new Operator("<", "_lt_", Type.BINARY, 6);
public static final Operator LE = new Operator("<=", "_le_", Type.BINARY, 6);
public static final Operator GT = new Operator(">", "_gt_", Type.BINARY, 6);
public static final Operator GE = new Operator(">=", "_ge_", Type.BINARY, 6);
public static final Operator EQ = new Operator("==", "_eq_", Type.BINARY, 7);
public static final Operator NEQ = new Operator("!=", "_neq_", Type.BINARY, 7);
public static final Operator BOOL_AND = new Operator("&", "_band_", Type.BINARY, 8);
public static final Operator BOOL_XOR = new Operator("^", "_bxor_", Type.BINARY, 9);
public static final Operator BOOL_OR = new Operator("|", "_bor_", Type.BINARY, 10);
public static final Operator LOGIC_AND = new Operator("&&", "_and_", Type.BINARY, 11);
public static final Operator LOGIC_OR = new Operator("||", "_or_", Type.BINARY, 12);
public String getOperator() {
return operator;
@ -133,6 +157,10 @@ public class Operator {
return type;
}
public String getAsmOperator() {
return asmOperator;
}
@Override
public String toString() {
return operator;

View File

@ -10,6 +10,7 @@ public class SymbolTypeBasic implements SymbolType {
public static final SymbolTypeBasic SBYTE = new SymbolTypeBasic("signed byte");
public static final SymbolTypeBasic WORD = new SymbolTypeBasic("word");
public static final SymbolTypeBasic SWORD = new SymbolTypeBasic("signed word");
public static final SymbolTypeBasic STRING = new SymbolTypeBasic("string");
public static final SymbolTypeBasic BOOLEAN = new SymbolTypeBasic("boolean");
@ -38,6 +39,7 @@ public class SymbolTypeBasic implements SymbolType {
case "byte": return BYTE;
case "signed byte": return SBYTE;
case "word": return WORD;
case "signed word": return SWORD;
case "string": return STRING;
case "boolean": return BOOLEAN;
case "void": return VOID;

View File

@ -1,29 +1,40 @@
package dk.camelot64.kickc.model;
/** Type inference of expressions (rValues & unary/binary operators) */
/**
* Type inference of expressions (rValues & unary/binary operators)
*/
public class SymbolTypeInference {
public static SymbolType inferType(Operator operator, SymbolType subType) {
if(operator==null) {
if (operator == null) {
return subType;
}
String op = operator.getOperator();
switch (op) {
case "*":
if(subType instanceof SymbolTypePointer) {
return ((SymbolTypePointer) subType).getElementType();
} 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;
if (Operator.DEREF.equals(operator)) {
if (subType instanceof SymbolTypePointer) {
return ((SymbolTypePointer) subType).getElementType();
} else {
throw new RuntimeException("Type error: Dereferencing a non-pointer " + subType);
}
} else if (Operator.LOWBYTE.equals(operator)) {
if (subType instanceof SymbolTypePointer || SymbolTypeBasic.WORD.equals(subType)) {
return SymbolTypeBasic.BYTE;
}
} else if (Operator.HIBYTE.equals(operator)) {
if (subType instanceof SymbolTypePointer || SymbolTypeBasic.WORD.equals(subType)) {
return SymbolTypeBasic.BYTE;
}
} else if (Operator.CAST_BYTE.equals(operator)) {
return SymbolTypeBasic.BYTE;
} else if (Operator.CAST_SBYTE.equals(operator)) {
return SymbolTypeBasic.SBYTE;
} else if (Operator.CAST_WORD.equals(operator)) {
return SymbolTypeBasic.WORD;
} else if (Operator.CAST_SWORD.equals(operator)) {
return SymbolTypeBasic.SWORD;
} else {
return subType;
}
throw new RuntimeException("Type inference problem unary " + operator + " " + subType);
}
public static SymbolType inferType(SymbolType type1, Operator operator, SymbolType type2) {
@ -47,8 +58,8 @@ public class SymbolTypeInference {
if (type1.equals(SymbolTypeBasic.STRING) && SymbolTypeBasic.BYTE.equals(type2)) {
return SymbolTypeBasic.STRING;
} else if (type1.equals(SymbolTypeBasic.STRING) && SymbolTypeBasic.STRING.equals(type2)) {
return SymbolTypeBasic.STRING;
}
return SymbolTypeBasic.STRING;
}
case "-":
// Also continues "+"
if (type1 instanceof SymbolTypePointer && (type2.equals(SymbolTypeBasic.BYTE) || type2.equals(SymbolTypeBasic.WORD))) {
@ -68,7 +79,7 @@ public class SymbolTypeInference {
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "*":
if(type1==null && type2 instanceof SymbolTypePointer) {
if (type1 == null && type2 instanceof SymbolTypePointer) {
return ((SymbolTypePointer) type2).getElementType();
}
if (SymbolTypeBasic.WORD.equals(type1) || SymbolTypeBasic.WORD.equals(type2)) {
@ -80,7 +91,7 @@ public class SymbolTypeInference {
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "*idx":
if(type1 instanceof SymbolTypePointer) {
if (type1 instanceof SymbolTypePointer) {
return ((SymbolTypePointer) type1).getElementType();
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
@ -140,12 +151,12 @@ public class SymbolTypeInference {
SymbolType leftType = inferType(programScope, constBin.getLeft());
SymbolType rightType = inferType(programScope, constBin.getRight());
return inferType(leftType, constBin.getOperator(), rightType);
} else if(rValue instanceof PointerDereferenceSimple) {
} else if (rValue instanceof PointerDereferenceSimple) {
SymbolType pointerType = inferType(programScope, ((PointerDereferenceSimple) rValue).getPointer());
if(pointerType instanceof SymbolTypePointer) {
if (pointerType instanceof SymbolTypePointer) {
return ((SymbolTypePointer) pointerType).getElementType();
} else {
throw new RuntimeException("Cannot infer pointer element type from pointer type "+pointerType);
throw new RuntimeException("Cannot infer pointer element type from pointer type " + pointerType);
}
}
if (type == null) {

View File

@ -438,7 +438,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public SymbolType visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) {
return SymbolTypeBasic.get("signed "+ctx.SIMPLETYPE().getText());
return SymbolTypeBasic.get("signed " + ctx.SIMPLETYPE().getText());
}
@Override
@ -464,8 +464,14 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
program.getLog().append("Cast type ignored!");
return (RValue) visit(ctx.expr());
RValue child = (RValue) this.visit(ctx.expr());
SymbolType castType = (SymbolType) this.visit(ctx.typeDecl());
Operator operator = Operator.getCastUnary(castType);
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
sequence.addStatement(stmt);
return tmpVarRef;
}
@Override
@ -497,7 +503,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public RValue visitExprArray(KickCParser.ExprArrayContext ctx) {
RValue array = (LValue) visit(ctx.expr(0));
RValue index = (RValue) visit(ctx.expr(1));
Operator operator = Operator.STAR_IDX;
Operator operator = Operator.DEREF_IDX;
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, array, operator, index);
@ -550,7 +556,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
RValue child = (RValue) this.visit(ctx.expr());
String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText();
Operator operator = Operator.getUnary(op);
if (Operator.STAR.equals(operator)) {
if (Operator.DEREF.equals(operator)) {
return new PointerDereferenceSimple(child);
} else {
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();

View File

@ -88,7 +88,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
ConstantValue idxConstant = (ConstantValue) assignment.getrValue2();
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
assignment.setrValue1(null);
assignment.setOperator(Operator.STAR);
assignment.setOperator(Operator.DEREF);
assignment.setrValue2(newPtr);
getLog().append("Consolidated referenced array index constant in assignment " + assignment.getlValue());
return true;

View File

@ -24,6 +24,10 @@ public class TestPrograms extends TestCase {
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
}
public void testCasting() throws IOException, URISyntaxException {
compileAndCompare("casting");
}
public void testSignedBytes() throws IOException, URISyntaxException {
compileAndCompare("signed-bytes");
}

View File

@ -0,0 +1,13 @@
byte* SCREEN = $0400;
byte* SCREEN2 = $0600;
void main() {
for( byte b: 0..100) {
byte b2 = 100-b;
SCREEN2[b] = b2;
signed byte sb = - (signed byte)b;
SCREEN[b] = (byte)sb;
}
}