1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-20 02:32:36 +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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -11,6 +12,7 @@ public class SymbolTypeMulti implements SymbolType {
/** All numeric types. */
public static final SymbolTypeMulti NUMERIC = new SymbolTypeMulti(Arrays.asList(BYTE, SBYTE, WORD, SWORD, DWORD, SDWORD));
/**
* All potential types for the inline constant.
*/
@ -24,6 +26,22 @@ public class SymbolTypeMulti implements SymbolType {
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
public int getSizeBytes() {
// 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.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeMulti;
import dk.camelot64.kickc.model.types.SymbolTypeInteger;
import java.util.ArrayList;
/** SSA form constant integer value */
/** Constant integer value */
public class ConstantInteger implements ConstantEnumerable<Long> {
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.type = SymbolTypeMulti.getMultiType(number);
}
public ConstantInteger(Long number, SymbolType type) {
this.number = number;
this.type = type;
}
@Override
@ -32,14 +38,7 @@ public class ConstantInteger implements ConstantEnumerable<Long> {
}
public SymbolType getType() {
ArrayList<SymbolType> potentialTypes = new ArrayList<>();
Long number = getValue();
for(SymbolTypeInteger typeInteger : SymbolType.getIntegerTypes()) {
if(number >= typeInteger.getMinValue() && number <= typeInteger.getMaxValue()) {
potentialTypes.add(typeInteger);
}
}
return new SymbolTypeMulti(potentialTypes);
return type;
}
@Override

View File

@ -4,7 +4,9 @@ import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
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.StatementAssignment;
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(constVarVal.getAssignment() instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) constVarVal.getAssignment();
if(assignment.getOperator()!=null) {
if(assignment.getOperator() != null) {
getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false));
assignment.setOperator(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.
*
* @param assignment The assignment to examine
* @param lValueType The type of the lvalue
* @return The constant value if the right side is constant
@ -259,7 +262,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
}
if(allConstant && listType != null) {
// Constant list confirmed!
return new ConstantArrayList(elements, listType);
return new ConstantArrayList(elements, listType);
}
}
} 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) {
// 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()) {
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 "%":

View File

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

View File

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