1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-09 04:25:12 +00:00

Starting work on type system.

This commit is contained in:
jespergravgaard
2019-04-23 20:42:18 +02:00
parent 21d7c6849c
commit 1fa41859b0
5 changed files with 56 additions and 29 deletions

View File

@@ -1,5 +1,6 @@
package dk.camelot64.kickc.model.types; package dk.camelot64.kickc.model.types;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@@ -11,6 +12,7 @@ public class SymbolTypeMulti implements SymbolType {
/** All numeric types. */ /** All numeric types. */
public static final SymbolTypeMulti NUMERIC = new SymbolTypeMulti(Arrays.asList(BYTE, SBYTE, WORD, SWORD, DWORD, SDWORD)); public static final SymbolTypeMulti NUMERIC = new SymbolTypeMulti(Arrays.asList(BYTE, SBYTE, WORD, SWORD, DWORD, SDWORD));
/** /**
* All potential types for the inline constant. * All potential types for the inline constant.
*/ */
@@ -24,6 +26,22 @@ public class SymbolTypeMulti implements SymbolType {
return types; return types;
} }
/**
* Get the multi-type that can contain the passed number.
* @param number The number
* @return The multi-type
*/
public static SymbolType getMultiType(Long number) {
ArrayList<SymbolType> potentialTypes = new ArrayList<>();
for(SymbolTypeInteger typeInteger : SymbolType.getIntegerTypes()) {
if(number >= typeInteger.getMinValue() && number <= typeInteger.getMaxValue()) {
potentialTypes.add(typeInteger);
}
}
return new SymbolTypeMulti(potentialTypes);
}
@Override @Override
public int getSizeBytes() { public int getSizeBytes() {
// Find the minimal sizeof - and return that // Find the minimal sizeof - and return that

View File

@@ -5,17 +5,23 @@ import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeMulti; import dk.camelot64.kickc.model.types.SymbolTypeMulti;
import dk.camelot64.kickc.model.types.SymbolTypeInteger;
import java.util.ArrayList; /** Constant integer value */
/** SSA form constant integer value */
public class ConstantInteger implements ConstantEnumerable<Long> { public class ConstantInteger implements ConstantEnumerable<Long> {
private Long number; private Long number;
public ConstantInteger( Long number) { /** The type of the number. (Either specific or the multi-type)*/
private SymbolType type;
public ConstantInteger(Long number) {
this.number = number; this.number = number;
this.type = SymbolTypeMulti.getMultiType(number);
}
public ConstantInteger(Long number, SymbolType type) {
this.number = number;
this.type = type;
} }
@Override @Override
@@ -32,14 +38,7 @@ public class ConstantInteger implements ConstantEnumerable<Long> {
} }
public SymbolType getType() { public SymbolType getType() {
ArrayList<SymbolType> potentialTypes = new ArrayList<>(); return type;
Long number = getValue();
for(SymbolTypeInteger typeInteger : SymbolType.getIntegerTypes()) {
if(number >= typeInteger.getMinValue() && number <= typeInteger.getMaxValue()) {
potentialTypes.add(typeInteger);
}
}
return new SymbolTypeMulti(potentialTypes);
} }
@Override @Override

View File

@@ -4,7 +4,9 @@ import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.*; import dk.camelot64.kickc.model.operators.OperatorBinary;
import dk.camelot64.kickc.model.operators.OperatorUnary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementPhiBlock; import dk.camelot64.kickc.model.statements.StatementPhiBlock;
@@ -50,7 +52,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
// If the assignment has an operator then replace it with the single constant value // If the assignment has an operator then replace it with the single constant value
if(constVarVal.getAssignment() instanceof StatementAssignment) { if(constVarVal.getAssignment() instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) constVarVal.getAssignment(); StatementAssignment assignment = (StatementAssignment) constVarVal.getAssignment();
if(assignment.getOperator()!=null) { if(assignment.getOperator() != null) {
getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false)); getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false));
assignment.setOperator(null); assignment.setOperator(null);
assignment.setrValue1(null); assignment.setrValue1(null);
@@ -201,6 +203,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
/** /**
* Examine the right side of an assignment and if it is constant then return the constant value. * Examine the right side of an assignment and if it is constant then return the constant value.
*
* @param assignment The assignment to examine * @param assignment The assignment to examine
* @param lValueType The type of the lvalue * @param lValueType The type of the lvalue
* @return The constant value if the right side is constant * @return The constant value if the right side is constant
@@ -259,7 +262,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
} }
if(allConstant && listType != null) { if(allConstant && listType != null) {
// Constant list confirmed! // Constant list confirmed!
return new ConstantArrayList(elements, listType); return new ConstantArrayList(elements, listType);
} }
} }
} else if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1() == null) { } else if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
@@ -307,18 +310,24 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
} }
static ConstantValue createBinary(ConstantValue c1, OperatorBinary operator, ConstantValue c2, ProgramScope programScope) { static ConstantValue createBinary(ConstantValue c1, OperatorBinary operator, ConstantValue c2, ProgramScope programScope) {
// Special handling of string append using +
if(Operators.PLUS.equals(operator) && SymbolType.STRING.equals(c1.getType(programScope))) {
if(c1 instanceof ConstantRef) {
c1 = programScope.getConstant((ConstantRef) c1).getValue();
}
if(c2 instanceof ConstantRef) {
c2 = programScope.getConstant((ConstantRef) c2).getValue();
}
return new ConstantBinary(c1, operator, c2);
}
if(Operators.PLUS.equals(operator)) {
return new ConstantBinary(c1, operator, c2);
}
switch(operator.getOperator()) { switch(operator.getOperator()) {
case "-": case "-":
case "+":
if(SymbolType.STRING.equals(c1.getType(programScope))) {
if(c1 instanceof ConstantRef) {
c1 = programScope.getConstant((ConstantRef) c1).getValue();
}
if(c2 instanceof ConstantRef) {
c2 = programScope.getConstant((ConstantRef) c2).getValue();
}
return new ConstantBinary(c1, operator, c2);
}
case "*": case "*":
case "/": case "/":
case "%": case "%":

View File

@@ -39,7 +39,7 @@ public class TestPrograms {
@Test @Test
public void testTypeIdPlusByteProblem() throws IOException, URISyntaxException { public void testTypeIdPlusByteProblem() throws IOException, URISyntaxException {
compileAndCompare("typeid-plus-byte-problem"); compileAndCompare("typeid-plus-byte-problem", log());
} }
//@Test //@Test

View File

@@ -3,7 +3,8 @@
const byte* SCREEN = $400; const byte* SCREEN = $400;
void main() { void main() {
unsigned byte ubc1 = 250; unsigned byte ubc1 = 12+13+14;
SCREEN[0] = ubc1+250; unsigned byte ubc2 = 250;
SCREEN[0] = ubc1+ubc2;
} }