Skip to content
Snippets Groups Projects
Verified Commit 1b4d9b43 authored by Recolic Keghart's avatar Recolic Keghart
Browse files

adding more expr

parent c4d5f8be
No related branches found
No related tags found
No related merge requests found
Pipeline #32 passed with warnings with stages
in 12 minutes and 20 seconds
......@@ -82,6 +82,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> {
sym.put(name, type);
}
// function scope ends.. backtracking...
sym = sym.getParent();
if(sym == null)
throw new RuntimeException("logic error: sym parent is null while returning..");
return new FuncType(ValueType.annotationToValueType(funcDef.returnType));
}
......
......@@ -2,17 +2,14 @@ package chocopy.pa2;
import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.types.FuncType;
import chocopy.common.analysis.types.ListValueType;
import chocopy.common.analysis.types.SymbolType;
import chocopy.common.analysis.types.ValueType;
import chocopy.common.astnodes.BinaryExpr;
import chocopy.common.astnodes.Declaration;
import chocopy.common.astnodes.Errors;
import chocopy.common.astnodes.ExprStmt;
import chocopy.common.astnodes.Identifier;
import chocopy.common.astnodes.IntegerLiteral;
import chocopy.common.astnodes.Node;
import chocopy.common.astnodes.Program;
import chocopy.common.astnodes.Stmt;
import chocopy.common.astnodes.*;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import static chocopy.common.analysis.types.SymbolType.INT_TYPE;
import static chocopy.common.analysis.types.SymbolType.OBJECT_TYPE;
......@@ -63,6 +60,48 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
public SymbolType analyze(IntegerLiteral i) {
return i.setInferredType(SymbolType.INT_TYPE);
}
@Override
public SymbolType analyze(StringLiteral node) {
return node.setInferredType(SymbolType.STR_TYPE);
}
@Override
public SymbolType analyze(NoneLiteral node) {
return node.setInferredType(SymbolType.NONE_TYPE);
}
@Override
public SymbolType analyze(BooleanLiteral node) {
return node.setInferredType(SymbolType.BOOL_TYPE);
}
@Override
public SymbolType analyze(AssignStmt node) {
SymbolType right_type = node.value.dispatch(this);
if(right_type == null)
right_type = ValueType.NONE_TYPE;
if(node.targets.size() == 1) {
String target = node.targets.get(0).toString();
System.out.println("debug: assign to target " + target);
SymbolType left_type = sym.get(target);
if(left_type == null) {
err(node, "Syntax error: assign to non-declared variable.");
return OBJECT_TYPE;
}
if(!left_type.equals(right_type)) {
err(node, "Syntax error: implicit type convertion not allowed.");
}
return right_type;
}
else {
if(!right_type.isListType()) {
err(node, "Syntax error: assign non-list type to list targets");
return OBJECT_TYPE;
}
ListValueType right_ls_type = (ListValueType) right_type;
// TODO: assign list to list
err(node, "Not implemented error: assign list to list");
return OBJECT_TYPE;
}
}
@Override
public SymbolType analyze(BinaryExpr node) {
......@@ -70,23 +109,6 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
SymbolType left_type = node.left.dispatch(this);
SymbolType right_type = node.right.dispatch(this);
//switch (e.operator) {
//case "-":
//case "*":
//case "//":
//case "%":
// if (INT_TYPE.equals(t1) && INT_TYPE.equals(t2)) {
// return e.setInferredType(INT_TYPE);
// } else {
// err(e, "Cannot apply operator `%s` on types `%s` and `%s`",
// e.operator, t1, t2);
// return e.setInferredType(INT_TYPE);
// }
//default:
// return e.setInferredType(OBJECT_TYPE);
//}
switch(op) {
case "-":
case "*":
......@@ -96,26 +118,31 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
case "<":
case ">=":
case "<=":
if(left_type != ValueType.INT_TYPE || right_type != ValueType.INT_TYPE)
if(left_type != ValueType.INT_TYPE || right_type != ValueType.INT_TYPE) {
err(node, "Syntax Error: operand should be INT");
}
break;
case "and":
case "or":
if(left_type != ValueType.BOOL_TYPE || right_type != ValueType.BOOL_TYPE)
if(left_type != ValueType.BOOL_TYPE || right_type != ValueType.BOOL_TYPE) {
err(node, "Syntax Error: operand should be BOOL");
}
break;
case "+":
if(left_type != ValueType.INT_TYPE && left_type != ValueType.STR_TYPE && ! left_type.isListType())
if(left_type != ValueType.INT_TYPE && left_type != ValueType.STR_TYPE && ! left_type.isListType()) {
err(node, "Syntax Error: operand of + should be INT or STR or LIST");
}
// fallthrough
case "==":
case "!=":
case "is":
if(node.left.getInferredType() != node.right.getInferredType())
if(node.left.getInferredType() != node.right.getInferredType()) {
err(node, "Syntax Error: binary operator operand type mismatch");
}
break;
default:
err(node, "Syntax Error: binary operator operand type not supported.");
return OBJECT_TYPE;
}
// Now set target type.
......@@ -146,6 +173,28 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return node.setInferredType(result_type);
}
@Override
public SymbolType analyze(CallExpr node) {
SymbolType funcType = sym.get(node.function.name);
if(funcType == null) {
err(node, "calling undeclared function " + node.function.name);
return OBJECT_TYPE;
}
if(!funcType.isFuncType()) {
err(node, "calling non-function variable " + node.function.name);
return OBJECT_TYPE;
}
FuncType fType = (FuncType)funcType;
List<SymbolType> args_type = new ArrayList<SymbolType>();
for(Expr arg : node.args) {
args_type.add(arg.dispatch(this));
}
if(!fType.parameters.equals(args_type)) {
err(node, "function parameter type list mismatch: " + node.function.name + ". Expected " + fType.parameters.toString() + ", got " + args_type.toString());
}
return node.setInferredType(fType.returnType);
}
@Override
public SymbolType analyze(Identifier id) {
String varName = id.name;
......
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