1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-10 10:31:27 +00:00

Cleaning up type inference.

This commit is contained in:
jespergravgaard 2019-05-23 00:28:34 +02:00
parent 669064bd37
commit 49a61ecbdd
3 changed files with 6 additions and 27 deletions

View File

@ -137,7 +137,7 @@ public class SymbolTypeInference {
} }
} }
public static SymbolType inferTypeRValue(ProgramScope symbols, StatementAssignment assignment) { private static SymbolType inferTypeRValue(ProgramScope symbols, StatementAssignment assignment) {
SymbolType rValueType; SymbolType rValueType;
RValue rValue1 = assignment.getrValue1(); RValue rValue1 = assignment.getrValue1();
RValue rValue2 = assignment.getrValue2(); RValue rValue2 = assignment.getrValue2();

View File

@ -9,6 +9,7 @@ import dk.camelot64.kickc.model.statements.StatementConditionalJump;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion; import dk.camelot64.kickc.model.types.SymbolTypeConversion;
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.LValue; import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.RValue;
@ -50,7 +51,7 @@ public class Pass2AssertTypeMatch extends Pass2SsaAssertion {
private void checkAssignment(StatementAssignment statement) { private void checkAssignment(StatementAssignment statement) {
LValue lValue = statement.getlValue(); LValue lValue = statement.getlValue();
SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue); SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue);
SymbolType rValueType = SymbolTypeInference.inferTypeRValue(getScope(), statement); SymbolType rValueType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(statement));
if(SymbolTypeConversion.assignmentTypeMatch(lValueType, rValueType)) return; if(SymbolTypeConversion.assignmentTypeMatch(lValueType, rValueType)) return;
// Types do not match // Types do not match
getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false)); getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false));

View File

@ -3,14 +3,12 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError; 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.operators.Operator;
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.*;
import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.AssignmentRValue;
import dk.camelot64.kickc.model.values.LValue; import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.VariableRef; import dk.camelot64.kickc.model.values.VariableRef;
@ -117,28 +115,8 @@ public class PassNTypeInference extends Pass2SsaOptimization {
if(lValue instanceof VariableRef) { if(lValue instanceof VariableRef) {
Variable symbol = programScope.getVariable((VariableRef) lValue); Variable symbol = programScope.getVariable((VariableRef) lValue);
if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())) { if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())) {
// Unresolved symbol - perform inference SymbolType type = SymbolTypeInference.inferType(programScope, new AssignmentRValue(assignment));
Operator operator = assignment.getOperator(); setInferedType(program, assignment, symbol, type);
if(assignment.getrValue1() == null && operator == null) {
// Copy operation
RValue rValue = assignment.getrValue2();
SymbolType type = SymbolTypeInference.inferType(programScope, rValue);
setInferedType(program, assignment, symbol, type);
} else if(assignment.getrValue1() == null && operator instanceof OperatorUnary) {
// Unary operation
RValue rValue = assignment.getrValue2();
SymbolType type = SymbolTypeInference.inferType(programScope, (OperatorUnary) operator, rValue);
setInferedType(program, assignment, symbol, type);
} else if(operator instanceof OperatorBinary) {
// Binary operation
SymbolType type = SymbolTypeInference.inferType(
programScope, assignment.getrValue1(),
(OperatorBinary) assignment.getOperator(),
assignment.getrValue2());
setInferedType(program, assignment, symbol, type);
} else {
throw new CompileError("Cannot infer type of " + assignment);
}
// If the type is an array or a string the symbol is constant // If the type is an array or a string the symbol is constant
if(symbol.getType() instanceof SymbolTypeArray) { if(symbol.getType() instanceof SymbolTypeArray) {
symbol.setDeclaredConstant(true); symbol.setDeclaredConstant(true);