1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +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);
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
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);
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
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);
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
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);
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
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;
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.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer;
import dk.camelot64.kickc.model.values.ConstantString;
/** Unary get high operator (>b) */
public class OperatorGetHigh extends OperatorUnary {
@ -26,6 +28,8 @@ public class OperatorGetHigh extends OperatorUnary {
}
} else if(operand instanceof ConstantPointer) {
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 );
}
@ -36,6 +40,8 @@ public class OperatorGetHigh extends OperatorUnary {
return SymbolType.BYTE;
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
return SymbolType.WORD;
} else if(SymbolType.STRING.equals(operandType)) {
return SymbolType.BYTE;
}
throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType);
}

View File

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

View File

@ -34,7 +34,9 @@ public class SymbolTypeInference {
if(rValue instanceof ConstantValue) {
// Calculate resulting constant literal
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);
} catch(ConstantNotLiteral e) {
// Value literal cannot be calculated

View File

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