mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 04:49:27 +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.operators.OperatorBinary;
|
||||
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.values.*;
|
||||
|
||||
/**
|
||||
* Type inference of expressions (rValues & unary/binary operators)
|
||||
* Type inference of an RValue
|
||||
*/
|
||||
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) {
|
||||
SymbolType type = null;
|
||||
if(rValue instanceof VariableRef) {
|
||||
@ -61,10 +33,13 @@ public class SymbolTypeInference {
|
||||
type = SymbolType.BOOLEAN;
|
||||
} else if(rValue instanceof ConstantUnary) {
|
||||
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) {
|
||||
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) {
|
||||
type = inferTypeList(symbols, (ValueList) rValue);
|
||||
} else if(rValue instanceof PointerDereference) {
|
||||
@ -103,7 +78,26 @@ public class SymbolTypeInference {
|
||||
Procedure procedure = symbols.getProcedure((ProcedureRef) rValue);
|
||||
return procedure.getType();
|
||||
} 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) {
|
||||
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
|
||||
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
|
||||
|
@ -47,7 +47,8 @@ public class ConstantUnary implements ConstantValue {
|
||||
|
||||
@Override
|
||||
public SymbolType getType(ProgramScope scope) {
|
||||
return SymbolTypeInference.inferType(scope, operator, operand);
|
||||
SymbolType valueType = SymbolTypeInference.inferType(scope, operand);
|
||||
return operator.inferType(valueType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,6 +9,7 @@ import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
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.PointerDereferenceSimple;
|
||||
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));
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
VariableIntermediate tmpVar = currentScope.addVariableIntermediate();
|
||||
SymbolType pointerType = SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue);
|
||||
tmpVar.setType(pointerType);
|
||||
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();
|
||||
programValue.set(new PointerDereferenceSimple(tmpVar.getRef()));
|
||||
SymbolType pointerType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(tmpVarAssignment));
|
||||
tmpVar.setType(pointerType);
|
||||
optimized.set(true);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user