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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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 "%":
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user