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

Fixed problem where inline string is used only in hi/lo operator. Closes #103

This commit is contained in:
jespergravgaard 2018-04-22 09:59:08 +02:00
parent b2f1e1abe3
commit 13249cd744
5 changed files with 44 additions and 38 deletions

View File

@ -96,7 +96,7 @@ public class AsmFormat {
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
return getAsmConstant(program, operand, outerPrecedence, codeScope); return getAsmConstant(program, operand, outerPrecedence, codeScope);
} else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer) { } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
return "<" + getAsmConstant(program, operand, outerPrecedence, codeScope); return "<" + getAsmConstant(program, operand, outerPrecedence, codeScope);
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope); return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope);
@ -107,7 +107,7 @@ public class AsmFormat {
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
return getAsmConstant(program, new ConstantInteger(0l), outerPrecedence, codeScope); return getAsmConstant(program, new ConstantInteger(0l), outerPrecedence, codeScope);
} else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer) { } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
return ">" + getAsmConstant(program, operand, outerPrecedence, codeScope); return ">" + getAsmConstant(program, operand, outerPrecedence, codeScope);
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long)16)), outerPrecedence, codeScope); return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long)16)), outerPrecedence, codeScope);

View File

@ -1,12 +1,14 @@
package dk.camelot64.kickc.model.operators; package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer; import dk.camelot64.kickc.model.values.ConstantPointer;
import dk.camelot64.kickc.model.values.ConstantString;
/** Unary get high operator (>b) */ /** Unary get high operator (>b) */
public class OperatorGetHigh extends OperatorUnary { public class OperatorGetHigh extends OperatorUnary {
@ -26,6 +28,8 @@ public class OperatorGetHigh extends OperatorUnary {
} }
} else if(operand instanceof ConstantPointer) { } else if(operand instanceof ConstantPointer) {
return new ConstantInteger(((ConstantPointer) operand).getLocation()>>8); return new ConstantInteger(((ConstantPointer) operand).getLocation()>>8);
} else if(operand instanceof ConstantString) {
throw new ConstantNotLiteral("address of string is not literal");
} }
throw new CompileError("Calculation not implemented " + getOperator() + " " + operand ); throw new CompileError("Calculation not implemented " + getOperator() + " " + operand );
} }
@ -36,6 +40,8 @@ public class OperatorGetHigh extends OperatorUnary {
return SymbolType.BYTE; return SymbolType.BYTE;
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
return SymbolType.WORD; return SymbolType.WORD;
} else if(SymbolType.STRING.equals(operandType)) {
return SymbolType.BYTE;
} }
throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType); throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType);
} }

View File

@ -1,12 +1,14 @@
package dk.camelot64.kickc.model.operators; package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer; import dk.camelot64.kickc.model.values.ConstantPointer;
import dk.camelot64.kickc.model.values.ConstantString;
/** Unary get low operator (<b) */ /** Unary get low operator (<b) */
public class OperatorGetLow extends OperatorUnary { public class OperatorGetLow extends OperatorUnary {
@ -26,6 +28,8 @@ public class OperatorGetLow extends OperatorUnary {
} }
} else if(operand instanceof ConstantPointer) { } else if(operand instanceof ConstantPointer) {
return new ConstantInteger(((ConstantPointer) operand).getLocation()&0xff); return new ConstantInteger(((ConstantPointer) operand).getLocation()&0xff);
} else if(operand instanceof ConstantString) {
throw new ConstantNotLiteral("address of string is not literal");
} }
throw new CompileError("Calculation not implemented " + getOperator() + " " + operand ); throw new CompileError("Calculation not implemented " + getOperator() + " " + operand );
} }
@ -36,6 +40,8 @@ public class OperatorGetLow extends OperatorUnary {
return SymbolType.BYTE; return SymbolType.BYTE;
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
return SymbolType.WORD; return SymbolType.WORD;
} else if(SymbolType.STRING.equals(operandType)) {
return SymbolType.BYTE;
} }
throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType); throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType);
} }

View File

@ -34,7 +34,9 @@ public class SymbolTypeInference {
if(rValue instanceof ConstantValue) { if(rValue instanceof ConstantValue) {
// Calculate resulting constant literal // Calculate resulting constant literal
try { try {
ConstantValue value = operator.calculateLiteral(((ConstantValue) rValue).calculateLiteral(programScope)); ConstantValue constRValue = (ConstantValue) rValue;
ConstantLiteral literalRValue = constRValue.calculateLiteral(programScope);
ConstantValue value = operator.calculateLiteral(literalRValue);
return value.getType(programScope); return value.getType(programScope);
} catch(ConstantNotLiteral e) { } catch(ConstantNotLiteral e) {
// Value literal cannot be calculated // Value literal cannot be calculated

View File

@ -14,7 +14,6 @@ import org.junit.Test;
import java.io.*; import java.io.*;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ConcurrentModificationException;
import static junit.framework.TestCase.fail; import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -45,6 +44,22 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false); AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
} }
@Test
public void testVarForwardProblem() throws IOException, URISyntaxException {
try {
compileAndCompare("var-forward-problem");
} catch(CompileError e) {
// ignore & return
return;
}
fail("Expected compile error.");
}
@Test
public void testInlineString3() throws IOException, URISyntaxException {
compileAndCompare("inline-string-3");
}
@Test @Test
public void testEmptyBlockError() throws IOException, URISyntaxException { public void testEmptyBlockError() throws IOException, URISyntaxException {
compileAndCompare("emptyblock-error"); compileAndCompare("emptyblock-error");
@ -66,17 +81,6 @@ public class TestPrograms {
compileAndCompare("bool-vars"); compileAndCompare("bool-vars");
} }
@Test
public void testInlineString3() throws IOException, URISyntaxException {
try {
compileAndCompare("inline-string-3");
} catch(CompileError e) {
// ignore & return
return;
}
fail("Expected compile error.");
}
@Test @Test
public void testC64DtvBlitterMin() throws IOException, URISyntaxException { public void testC64DtvBlitterMin() throws IOException, URISyntaxException {
compileAndCompare("c64dtv-blittermin"); compileAndCompare("c64dtv-blittermin");
@ -102,17 +106,6 @@ public class TestPrograms {
compileAndCompare("inline-string-2"); compileAndCompare("inline-string-2");
} }
@Test
public void testVarForwardProblem() throws IOException, URISyntaxException {
try {
compileAndCompare("var-forward-problem");
} catch(CompileError e) {
// ignore & return
return;
}
fail("Expected compile error.");
}
@Test @Test
public void testLoopProblem2() throws IOException, URISyntaxException { public void testLoopProblem2() throws IOException, URISyntaxException {
compileAndCompare("loop-problem2"); compileAndCompare("loop-problem2");
@ -711,10 +704,10 @@ public class TestPrograms {
private void assertError(String kcFile, String expectError) throws IOException, URISyntaxException { private void assertError(String kcFile, String expectError) throws IOException, URISyntaxException {
try { try {
compileAndCompare(kcFile); compileAndCompare(kcFile);
} catch (CompileError e) { } catch(CompileError e) {
System.out.println("Got error: "+e.getMessage()); System.out.println("Got error: " + e.getMessage());
// expecting error! // expecting error!
assertTrue("Error message expected '"+expectError+"' - was:"+e.getMessage(), e.getMessage().contains(expectError)); assertTrue("Error message expected '" + expectError + "' - was:" + e.getMessage(), e.getMessage().contains(expectError));
return; return;
} }
fail("Expected compile error."); fail("Expected compile error.");
@ -739,7 +732,7 @@ public class TestPrograms {
success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program)); success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program));
success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program)); success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program));
success &= helper.testOutput(fileName, ".log", program.getLog().toString()); success &= helper.testOutput(fileName, ".log", program.getLog().toString());
if (!success) { if(!success) {
//System.out.println("\nCOMPILE LOG"); //System.out.println("\nCOMPILE LOG");
//System.out.println(program.getLog().toString()); //System.out.println(program.getLog().toString());
fail("Output does not match reference!"); fail("Output does not match reference!");
@ -755,8 +748,8 @@ public class TestPrograms {
System.setOut(new PrintStream(kickAssOut)); System.setOut(new PrintStream(kickAssOut));
int asmRes = KickAssembler.main2(new String[]{asmFile.getAbsolutePath(), "-log", asmLogFile.getAbsolutePath(), "-o", asmPrgFile.getAbsolutePath(), "-vicesymbols", "-showmem"}); int asmRes = KickAssembler.main2(new String[]{asmFile.getAbsolutePath(), "-log", asmLogFile.getAbsolutePath(), "-o", asmPrgFile.getAbsolutePath(), "-vicesymbols", "-showmem"});
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
if(asmRes!=0) { if(asmRes != 0) {
fail("KickAssembling file failed! "+kickAssOut.toString()); fail("KickAssembling file failed! " + kickAssOut.toString());
} }
} }
@ -787,5 +780,4 @@ public class TestPrograms {
} }
} }