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:
parent
21d7c6849c
commit
1fa41859b0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 "%":
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user