1
0
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:
jespergravgaard 2019-05-23 00:38:35 +02:00
parent 49a61ecbdd
commit 65c92716f0
4 changed files with 37 additions and 54 deletions

View File

@ -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;
}
} }

View File

@ -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

View File

@ -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

View File

@ -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);
} }
} }