Skip to content
Snippets Groups Projects
Unverified Commit 5c7f8b77 authored by Recolic Keghart's avatar Recolic Keghart
Browse files

type: BinaryExpr

parent e7b412ff
No related branches found
No related tags found
No related merge requests found
Pipeline #19 passed with stages
in 24 minutes
...@@ -147,3 +147,7 @@ tramp ...@@ -147,3 +147,7 @@ tramp
Session.vim Session.vim
.netrwhist .netrwhist
*~ *~
### recolic
*.gi
...@@ -4,11 +4,9 @@ import chocopy.common.analysis.AbstractNodeAnalyzer; ...@@ -4,11 +4,9 @@ import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable; import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.types.SymbolType; import chocopy.common.analysis.types.SymbolType;
import chocopy.common.analysis.types.ValueType; import chocopy.common.analysis.types.ValueType;
import chocopy.common.astnodes.Declaration; import chocopy.common.astnodes.*;
import chocopy.common.astnodes.Errors;
import chocopy.common.astnodes.Identifier; import javax.management.RuntimeErrorException;
import chocopy.common.astnodes.Program;
import chocopy.common.astnodes.VarDef;
/** /**
* Analyzes declarations to create a top-level symbol table. * Analyzes declarations to create a top-level symbol table.
...@@ -59,7 +57,78 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> { ...@@ -59,7 +57,78 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> {
@Override @Override
public SymbolType analyze(VarDef varDef) { public SymbolType analyze(VarDef varDef) {
return ValueType.annotationToValueType(varDef.var.type); return analyze(varDef.var);
}
@Override
public SymbolType analyze(TypedVar node) {
return ValueType.annotationToValueType(node.type);
}
@Override
public SymbolType analyze(BinaryExpr node) {
String op = node.operator;
// Check operand type.
SymbolType left_type = node.left.getInferredType();
SymbolType right_type = node.left.getInferredType();
switch(op) {
case "-":
case "*":
case "//":
case "%":
case ">":
case "<":
case ">=":
case "<=":
if(left_type != ValueType.INT_TYPE || right_type != ValueType.INT_TYPE)
throw new RuntimeException("Syntax Error: operand should be INT");
break;
case "and":
case "or":
if(left_type != ValueType.BOOL_TYPE || right_type != ValueType.BOOL_TYPE)
throw new RuntimeException("Syntax Error: operand should be BOOL");
break;
case "+":
if(left_type != ValueType.INT_TYPE && left_type != ValueType.STR_TYPE && ! left_type.isListType())
throw new RuntimeException("Syntax Error: operand of + should be INT or STR or LIST");
// fallthrough
case "==":
case "!=":
case "is":
if(node.left.getInferredType() != node.right.getInferredType())
throw new RuntimeException("Syntax Error: binary operator operand type mismatch");
break;
default:
throw new RuntimeException("Syntax Error: binary operator operand type not supported.");
}
// Now set target type.
SymbolType result_type = ValueType.NONE_TYPE;
switch(op) {
case "-":
case "*":
case "//":
case "%":
case "and":
case "or":
case "+":
result_type = left_type;
break;
case ">":
case "<":
case ">=":
case "<=":
case "==":
case "!=":
case "is":
result_type = ValueType.BOOL_TYPE;
break;
default:
throw new RuntimeException("Logic error");
}
return result_type;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment