1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-20 02:32:36 +00:00

Working on fixing test errors.

This commit is contained in:
jespergravgaard 2019-05-07 18:52:01 +02:00
parent 87e6fecb8f
commit 47aa623f25
8 changed files with 55 additions and 34 deletions

View File

@ -11,11 +11,10 @@ import dk.camelot64.kickc.model.values.RValue;
/**
* Rules for converting integer types.
*
* <p>
* Integer conversion implements C99 6.3.1.8 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=70
*
* <p>
* The special number type is converted as described here https://gitlab.com/camelot/kickc/issues/181
*
*/
public class SymbolTypeConversion {
@ -37,19 +36,19 @@ public class SymbolTypeConversion {
if(type1.equals(type2))
return type1;
// C99 6.3.1.8 b. If both are signed or both are unsigned then the smallest type is converted to the size of the large type (byte->word->sword, sbyte->sword->sdword)
if(fixed1.isSigned()==fixed2.isSigned())
return (fixed1.getBits()>fixed2.getBits()) ? fixed1 : fixed2;
if(fixed1.isSigned() == fixed2.isSigned())
return (fixed1.getBits() > fixed2.getBits()) ? fixed1 : fixed2;
// C99 6.3.1.8 c. One is signed and one unsigned.
// If the signed type can contain all values of the unsigned type then the unsigned value is converted to the signed type. (byte->sword, byte->sdword, word->sdword).
SymbolTypeIntegerFixed typeS, typeU;
if(fixed1.isSigned()) {
typeS = fixed1;
typeU = fixed2;
} else {
} else {
typeS = fixed2;
typeU = fixed1;
}
if(typeS.getBits()>typeU.getBits())
if(typeS.getBits() > typeU.getBits())
return typeS;
// C99 6.3.1.8 d. The unsigned type is the same size as or larger than the signed type.
// The signed value is first converted to the size of the unsigned type and then converted to unsigned changing the sign and the value
@ -59,6 +58,7 @@ public class SymbolTypeConversion {
/**
* Find the integer type that results from a binary operator according to the special number type conversion https://gitlab.com/camelot/kickc/issues/181
*
* @param left The left value
* @param right The right value
* @param symbols The program scope symbols (used for looking up symbols and constants)
@ -92,7 +92,8 @@ public class SymbolTypeConversion {
fixedType = (SymbolTypeIntegerFixed) leftType;
} else {
// Binary operator combining number and non-integer
throw new CompileError("Error! Incompatible operands " + left.toString() + " and " + right.toString(), currentStmt);
return null;
//throw new CompileError("Error! Incompatible operands " + left.toString() + " and " + right.toString(), currentStmt);
}
if(numberVal instanceof ConstantValue) {

View File

@ -0,0 +1,31 @@
package dk.camelot64.kickc.model.types;
/** Container for function checking if types of an assignment match up */
public class SymbolTypeMatch {
/**
* Determines if the types of an assignment match up properly
* @param lValueType The type of the LValue
* @param rValueType The type of the RValue
* @return true if the types match up
*/
public static boolean assignmentTypeMatch(SymbolType lValueType, SymbolType rValueType) {
if(lValueType.equals(rValueType)) {
return true;
}
if(SymbolType.NUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) {
// L-value is still a number - constants are probably not done being identified & typed
return true;
}
if(SymbolType.STRING.equals(rValueType) && lValueType instanceof SymbolTypePointer && ((SymbolTypePointer) lValueType).getElementType().equals(SymbolType.BYTE)) {
// String value can be assigned into a pointer
return true;
}
if(lValueType instanceof SymbolTypePointer && rValueType instanceof SymbolTypePointer && assignmentTypeMatch(((SymbolTypePointer) lValueType).getElementType(), ((SymbolTypePointer) rValueType).getElementType())) {
// Pointer types assigned from each other
// TODO: Maybe handle sizes
return true;
}
return false;
}
}

View File

@ -8,7 +8,7 @@ import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeMatch;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.RValue;
@ -51,17 +51,7 @@ public class Pass2AssertTypeMatch extends Pass2SsaAssertion {
LValue lValue = statement.getlValue();
SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue);
SymbolType rValueType = SymbolTypeInference.inferTypeRValue(getScope(), statement);
if(lValueType.equals(rValueType)) {
return;
}
if(SymbolType.NUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) {
// L-value is still a number - constants are probably not done being identified & typed
return;
}
if(lValueType instanceof SymbolTypePointer && SymbolType.STRING.equals(rValueType) && ((SymbolTypePointer) lValueType).getElementType().equals(SymbolType.BYTE)) {
// String value can be assigned into a pointer
return;
}
if(SymbolTypeMatch.assignmentTypeMatch(lValueType, rValueType)) return;
// Types do not match
getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false));
throw new CompileError("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false), statement.getSource());

View File

@ -15,11 +15,14 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypeMatch;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Compiler Pass propagating constants in expressions eliminating constant variables
@ -69,24 +72,19 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
ConstantValue constVal = constVarVal.getConstantValue();
SymbolType valueType = SymbolTypeInference.inferType(getScope(), constVal);
SymbolType variableType = variable.getType();
SymbolType constType = variableType;
if(!valueType.equals(variableType)) {
if(variableType.equals(valueType)) {
constType = variableType;
} else {
if(!SymbolTypeMatch.assignmentTypeMatch(variableType, valueType)) {
throw new CompileError(
"Constant variable has a non-matching type \n variable: " + variable.toString(getProgram()) +
"\n value: (" + valueType.toString() + ") " + constVal.calculateLiteral(getScope()) +
"\n value definition: " + constVal.toString(getProgram())
);
}
}
ConstantVar constantVar = new ConstantVar(
variable.getName(),
constScope,
constType,
variableType,
constVal);
constantVar.setDeclaredAlignment(variable.getDeclaredAlignment());
constantVar.setDeclaredRegister(variable.getDeclaredRegister());

View File

@ -16,7 +16,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* Compiler Pass consolidating L-values that are constant into a single {@link ConstantValue}
* Compiler Pass consolidating R-values that are constant into a single {@link ConstantValue}
*/
public class Pass2ConstantRValueConsolidation extends Pass2SsaOptimization {

View File

@ -76,12 +76,12 @@ public class Pass2SizeOfSimplification extends Pass2SsaOptimization {
SymbolTypeArray arrayType = (SymbolTypeArray) symbolType;
RValue arraySize = arrayType.getSize();
if(arraySize instanceof ConstantValue) {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary((ConstantValue) arraySize, Operators.MULTIPLY, sizeOfConstantVar));
modified.set(true);
} else if(constant.getValue() instanceof ConstantArrayList) {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
int size = ((ConstantArrayList) constant.getValue()).getElements().size();
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary(new ConstantInteger((long) size), Operators.MULTIPLY, sizeOfConstantVar));
@ -97,6 +97,7 @@ public class Pass2SizeOfSimplification extends Pass2SsaOptimization {
if(stringLiteral instanceof ConstantString) {
ConstantString constString = (ConstantString) stringLiteral;
int length = constString.getString().length();
getLog().append("Resolving string sizeof() " + unary.toString(getProgram()));
ConstantRef sizeOfChar = OperatorSizeOf.getSizeOfConstantVar(getScope(), SymbolType.BYTE);
programValue.set(new ConstantBinary(new ConstantInteger((long) length), Operators.MULTIPLY, sizeOfChar));
modified.set(true);

View File

@ -34,7 +34,7 @@ public class TestPrograms {
@Test
public void testHelloWorld0() throws IOException, URISyntaxException {
compileAndCompare("helloworld0", log());
compileAndCompare("helloworld0");
}
@Test

View File

@ -1,6 +1,6 @@
// Tests minimal hello world
byte[] msg = "hello world";
byte[] msg = "hello world!";
byte* SCREEN = 0x0400;
void main() {