mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Cleaning up type inference.
This commit is contained in:
parent
49a61ecbdd
commit
65c92716f0
@ -3,43 +3,15 @@ package dk.camelot64.kickc.model.types;
|
|||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.operators.OperatorBinary;
|
import dk.camelot64.kickc.model.operators.OperatorBinary;
|
||||||
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||||
import dk.camelot64.kickc.model.statements.*;
|
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||||
import dk.camelot64.kickc.model.symbols.*;
|
import dk.camelot64.kickc.model.symbols.*;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
import dk.camelot64.kickc.model.values.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type inference of expressions (rValues & unary/binary operators)
|
* Type inference of an RValue
|
||||||
*/
|
*/
|
||||||
public class SymbolTypeInference {
|
public class SymbolTypeInference {
|
||||||
|
|
||||||
/**
|
|
||||||
* Infer the type of a unary operator on a value
|
|
||||||
*
|
|
||||||
* @param programScope The program scope usable for accessing the symbol table
|
|
||||||
* @param operator The unary operator
|
|
||||||
* @param rValue The value
|
|
||||||
* @return The type of the resulting value
|
|
||||||
*/
|
|
||||||
public static SymbolType inferType(ProgramScope programScope, OperatorUnary operator, RValue rValue) {
|
|
||||||
SymbolType valueType = inferType(programScope, rValue);
|
|
||||||
return operator.inferType(valueType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Infer the type of a binary operator on a value
|
|
||||||
*
|
|
||||||
* @param programScope The program scope usable for accessing the symbol table
|
|
||||||
* @param left The left value
|
|
||||||
* @param operator The binary operator
|
|
||||||
* @param rValue The right value
|
|
||||||
* @return The type of the resulting value
|
|
||||||
*/
|
|
||||||
public static SymbolType inferType(ProgramScope programScope, RValue left, OperatorBinary operator, RValue right) {
|
|
||||||
SymbolType leftType = inferType(programScope, left);
|
|
||||||
SymbolType rightType = inferType(programScope, right);
|
|
||||||
return operator.inferType(leftType, rightType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SymbolType inferType(ProgramScope symbols, RValue rValue) {
|
public static SymbolType inferType(ProgramScope symbols, RValue rValue) {
|
||||||
SymbolType type = null;
|
SymbolType type = null;
|
||||||
if(rValue instanceof VariableRef) {
|
if(rValue instanceof VariableRef) {
|
||||||
@ -61,10 +33,13 @@ public class SymbolTypeInference {
|
|||||||
type = SymbolType.BOOLEAN;
|
type = SymbolType.BOOLEAN;
|
||||||
} else if(rValue instanceof ConstantUnary) {
|
} else if(rValue instanceof ConstantUnary) {
|
||||||
ConstantUnary constUnary = (ConstantUnary) rValue;
|
ConstantUnary constUnary = (ConstantUnary) rValue;
|
||||||
return inferType(symbols, constUnary.getOperator(), constUnary.getOperand());
|
SymbolType valueType = inferType(symbols, constUnary.getOperand());
|
||||||
|
return constUnary.getOperator().inferType(valueType);
|
||||||
} else if(rValue instanceof ConstantBinary) {
|
} else if(rValue instanceof ConstantBinary) {
|
||||||
ConstantBinary constBin = (ConstantBinary) rValue;
|
ConstantBinary constBin = (ConstantBinary) rValue;
|
||||||
return inferType(symbols, constBin.getLeft(), constBin.getOperator(), constBin.getRight());
|
SymbolType leftType = inferType(symbols, constBin.getLeft());
|
||||||
|
SymbolType rightType = inferType(symbols, constBin.getRight());
|
||||||
|
return constBin.getOperator().inferType(leftType, rightType);
|
||||||
} else if(rValue instanceof ValueList) {
|
} else if(rValue instanceof ValueList) {
|
||||||
type = inferTypeList(symbols, (ValueList) rValue);
|
type = inferTypeList(symbols, (ValueList) rValue);
|
||||||
} else if(rValue instanceof PointerDereference) {
|
} else if(rValue instanceof PointerDereference) {
|
||||||
@ -103,7 +78,26 @@ public class SymbolTypeInference {
|
|||||||
Procedure procedure = symbols.getProcedure((ProcedureRef) rValue);
|
Procedure procedure = symbols.getProcedure((ProcedureRef) rValue);
|
||||||
return procedure.getType();
|
return procedure.getType();
|
||||||
} else if(rValue instanceof AssignmentRValue) {
|
} else if(rValue instanceof AssignmentRValue) {
|
||||||
return inferTypeRValue(symbols, ((AssignmentRValue) rValue).getAssignment());
|
StatementAssignment assignment = ((AssignmentRValue) rValue).getAssignment();
|
||||||
|
SymbolType rValueType;
|
||||||
|
RValue rValue1 = assignment.getrValue1();
|
||||||
|
RValue rValue2 = assignment.getrValue2();
|
||||||
|
if(assignment.getrValue1() == null && assignment.getOperator() == null) {
|
||||||
|
// Copy assignment
|
||||||
|
rValueType = inferType(symbols, rValue2);
|
||||||
|
} else if(assignment.getrValue1() == null && assignment.getOperator() instanceof OperatorUnary) {
|
||||||
|
// Unary operation assignment
|
||||||
|
SymbolType valueType = inferType(symbols, rValue2);
|
||||||
|
rValueType = ((OperatorUnary) assignment.getOperator()).inferType(valueType);
|
||||||
|
} else if(assignment.getOperator() instanceof OperatorBinary) {
|
||||||
|
// Binary operation assignment
|
||||||
|
SymbolType leftType = inferType(symbols, rValue1);
|
||||||
|
SymbolType rightType = inferType(symbols, rValue2);
|
||||||
|
rValueType = ((OperatorBinary) assignment.getOperator()).inferType(leftType, rightType);
|
||||||
|
} else {
|
||||||
|
throw new CompileError("Cannot infer type of " + assignment.toString());
|
||||||
|
}
|
||||||
|
return rValueType;
|
||||||
}
|
}
|
||||||
if(type == null) {
|
if(type == null) {
|
||||||
throw new RuntimeException("Cannot infer type for " + rValue.toString());
|
throw new RuntimeException("Cannot infer type for " + rValue.toString());
|
||||||
@ -137,20 +131,4 @@ public class SymbolTypeInference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SymbolType inferTypeRValue(ProgramScope symbols, StatementAssignment assignment) {
|
|
||||||
SymbolType rValueType;
|
|
||||||
RValue rValue1 = assignment.getrValue1();
|
|
||||||
RValue rValue2 = assignment.getrValue2();
|
|
||||||
if(assignment.getrValue1() == null && assignment.getOperator() == null) {
|
|
||||||
rValueType = inferType(symbols, rValue2);
|
|
||||||
} else if(assignment.getrValue1() == null && assignment.getOperator() instanceof OperatorUnary) {
|
|
||||||
rValueType = inferType(symbols, (OperatorUnary) assignment.getOperator(), rValue2);
|
|
||||||
} else if(assignment.getOperator() instanceof OperatorBinary) {
|
|
||||||
rValueType = inferType(symbols, rValue1, (OperatorBinary) assignment.getOperator(), rValue2);
|
|
||||||
} else {
|
|
||||||
throw new CompileError("Cannot infer type of " + assignment.toString());
|
|
||||||
}
|
|
||||||
return rValueType;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,9 @@ public class ConstantBinary implements ConstantValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SymbolType getType(ProgramScope scope) {
|
public SymbolType getType(ProgramScope scope) {
|
||||||
return SymbolTypeInference.inferType(scope, left, operator, right);
|
SymbolType leftType = SymbolTypeInference.inferType(scope, left);
|
||||||
|
SymbolType rightType = SymbolTypeInference.inferType(scope, right);
|
||||||
|
return operator.inferType(leftType, rightType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +47,8 @@ public class ConstantUnary implements ConstantValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SymbolType getType(ProgramScope scope) {
|
public SymbolType getType(ProgramScope scope) {
|
||||||
return SymbolTypeInference.inferType(scope, operator, operand);
|
SymbolType valueType = SymbolTypeInference.inferType(scope, operand);
|
||||||
|
return operator.inferType(valueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,6 +9,7 @@ import dk.camelot64.kickc.model.symbols.Scope;
|
|||||||
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||||
|
import dk.camelot64.kickc.model.values.AssignmentRValue;
|
||||||
import dk.camelot64.kickc.model.values.PointerDereferenceIndexed;
|
import dk.camelot64.kickc.model.values.PointerDereferenceIndexed;
|
||||||
import dk.camelot64.kickc.model.values.PointerDereferenceSimple;
|
import dk.camelot64.kickc.model.values.PointerDereferenceSimple;
|
||||||
import dk.camelot64.kickc.model.values.RValue;
|
import dk.camelot64.kickc.model.values.RValue;
|
||||||
@ -35,12 +36,13 @@ public class Pass2DeInlineWordDerefIdx extends Pass2SsaOptimization {
|
|||||||
getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false));
|
getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false));
|
||||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||||
VariableIntermediate tmpVar = currentScope.addVariableIntermediate();
|
VariableIntermediate tmpVar = currentScope.addVariableIntermediate();
|
||||||
SymbolType pointerType = SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue);
|
|
||||||
tmpVar.setType(pointerType);
|
|
||||||
stmtIt.previous();
|
stmtIt.previous();
|
||||||
stmtIt.add(new StatementAssignment(tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS));
|
StatementAssignment tmpVarAssignment = new StatementAssignment(tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||||
|
stmtIt.add(tmpVarAssignment);
|
||||||
stmtIt.next();
|
stmtIt.next();
|
||||||
programValue.set(new PointerDereferenceSimple(tmpVar.getRef()));
|
programValue.set(new PointerDereferenceSimple(tmpVar.getRef()));
|
||||||
|
SymbolType pointerType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(tmpVarAssignment));
|
||||||
|
tmpVar.setType(pointerType);
|
||||||
optimized.set(true);
|
optimized.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user