diff --git a/src/main/java/ASTGenerator.java b/src/main/java/ASTGenerator.java index 0d9570f..8629671 100644 --- a/src/main/java/ASTGenerator.java +++ b/src/main/java/ASTGenerator.java @@ -1,5 +1,4 @@ import abstractSyntaxTree.Class.FieldDecl; -import abstractSyntaxTree.Class.IClass; import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Expression.BinaryExpression; @@ -11,7 +10,6 @@ import abstractSyntaxTree.Statement.*; import gen.DecafBaseVisitor; import gen.DecafParser; -import java.beans.Expression; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/Compiler.java b/src/main/java/Compiler.java index 28e65da..8d3fd73 100644 --- a/src/main/java/Compiler.java +++ b/src/main/java/Compiler.java @@ -1,5 +1,14 @@ import abstractSyntaxTree.Class.RefType; +import abstractSyntaxTree.Datatype.BoolDatatype; +import abstractSyntaxTree.Datatype.IntDatatype; +import abstractSyntaxTree.Expression.InstVarExpression; +import abstractSyntaxTree.Expression.LocalVarIdentifier; +import abstractSyntaxTree.Expression.UnaryExpression; import abstractSyntaxTree.Program; +import abstractSyntaxTree.Statement.IStatement; +import abstractSyntaxTree.Statement.LocalVarDecl; +import abstractSyntaxTree.Statement.ReturnStatement; +import abstractSyntaxTree.StatementExpression.AssignStatementExpression; import gen.DecafLexer; import gen.DecafParser; import org.antlr.v4.runtime.CharStream; @@ -81,6 +90,15 @@ public class Compiler { // System.out.println(refType.name); // } + abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.returnType = "int"; + List statementsList = abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements; + statementsList.add(new LocalVarDecl("int", "localInt")); + statementsList.add(new LocalVarDecl("bool", "localBool")); + statementsList.add(new LocalVarDecl("char", "localChar")); + statementsList.add(new AssignStatementExpression("=", new LocalVarIdentifier("localInt"), new UnaryExpression("", new IntDatatype()))); + //statementsList.add(new AssignStatementExpression("=", new InstVarExpression(abstractSyntaxTree.classes.get(1)), new UnaryExpression("instVarBool", new BoolDatatype()))); + + abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements.add(new ReturnStatement(new UnaryExpression("", new IntDatatype()))); abstractSyntaxTree.typeCheck(); abstractSyntaxTree.codeGen(); diff --git a/src/main/java/Input.java b/src/main/java/Input.java index 034e89e..ea16d77 100644 --- a/src/main/java/Input.java +++ b/src/main/java/Input.java @@ -5,7 +5,9 @@ class Example { } class Example2 { - int i; - boolean j; + boolean instVarBool; + void m(int i){ + return; + } } diff --git a/src/main/java/TestClass.java b/src/main/java/TestClass.java new file mode 100644 index 0000000..39c1383 --- /dev/null +++ b/src/main/java/TestClass.java @@ -0,0 +1,6 @@ +public class TestClass { + public static void main(String[] args){ + new Example(); + new Example2(); + } +} diff --git a/src/main/java/TypeCheck/TypeCheckHelper.java b/src/main/java/TypeCheck/TypeCheckHelper.java index 5d487d8..b62cd43 100644 --- a/src/main/java/TypeCheck/TypeCheckHelper.java +++ b/src/main/java/TypeCheck/TypeCheckHelper.java @@ -12,8 +12,9 @@ public class TypeCheckHelper { if(type1Primitiv && type2Primitiv){ if(Objects.equals(type1, type2)){ result = type1; + }else{ + throw new Exception("no upper bound"); } - throw new Exception("no upper bound"); }else if(type1Primitiv || type2Primitiv){ throw new Exception("no upper bound"); }else{ diff --git a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java index 0e2e0c1..54c0951 100644 --- a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java @@ -13,7 +13,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -public class FieldDecl extends AbstractType implements IClass, Node { +public class FieldDecl extends AbstractType implements Node { public String type; // from parser public String identifier; // from parser @@ -39,7 +39,6 @@ public class FieldDecl extends AbstractType implements IClass, Node { return null; } - @Override public void codeGen(ClassWriter cw) { //TODO: Do we have fields with initial values? FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, identifier, getFieldDescriptor(), null, null); diff --git a/src/main/java/abstractSyntaxTree/Class/IClass.java b/src/main/java/abstractSyntaxTree/Class/IClass.java deleted file mode 100644 index e71c991..0000000 --- a/src/main/java/abstractSyntaxTree/Class/IClass.java +++ /dev/null @@ -1,16 +0,0 @@ -package abstractSyntaxTree.Class; - -import TypeCheck.TypeCheckResult; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.TypeReference; - -import java.util.HashMap; -import java.util.List; - -public interface IClass { - // visit method for code generation - - - void codeGen(ClassWriter cw) throws Exception; - -} diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index a1fc503..9348e38 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Stack; -public class MethodDecl implements IClass, Node { +public class MethodDecl implements Node { //Class Name public String classThatContainsMethod; @@ -36,14 +36,15 @@ public class MethodDecl implements IClass, Node { this.localVars = new HashMap<>(); } - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext) throws Exception { // jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben - codeBlock.typeCheck(methodContext, typeContext); - return null; + TypeCheckResult result = new TypeCheckResult(); + codeBlock.typeCheck(methodContext, typeContext, localVars); + result.type = codeBlock.returnType; + return result; } - @Override public void codeGen(ClassWriter cw) throws Exception { localVars.put("this", classThatContainsMethod); diff --git a/src/main/java/abstractSyntaxTree/Class/RefType.java b/src/main/java/abstractSyntaxTree/Class/RefType.java index 7702d36..83ef3a2 100644 --- a/src/main/java/abstractSyntaxTree/Class/RefType.java +++ b/src/main/java/abstractSyntaxTree/Class/RefType.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Class; import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -10,7 +11,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -public class RefType extends AbstractType implements IClass, Node { +public class RefType extends AbstractType implements Node { //Class Name public String name; @@ -29,7 +30,7 @@ public class RefType extends AbstractType implements IClass, Node { this.hasMain = hasMain; } - public TypeCheckResult typeCheck(HashMap>>> methodContext, + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext) throws Exception { TypeCheckResult result = new TypeCheckResult(); @@ -72,7 +73,7 @@ public class RefType extends AbstractType implements IClass, Node { // Method for code generation which iterates over all the field declarations // and method declarations and calls their CodeGen methods - @Override + public void codeGen(ClassWriter cw) throws Exception { cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, diff --git a/src/main/java/abstractSyntaxTree/Expression/VarRefExpression.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java similarity index 52% rename from src/main/java/abstractSyntaxTree/Expression/VarRefExpression.java rename to src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index 9276930..7c1888a 100644 --- a/src/main/java/abstractSyntaxTree/Expression/VarRefExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -1,15 +1,19 @@ package abstractSyntaxTree.Expression; +import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import org.objectweb.asm.MethodVisitor; -import java.util.Map; +public class LocalVarIdentifier implements IExpression{ -public class VarRefExpression implements IExpression{ + String identifier; + public LocalVarIdentifier(String identifier){ + this.identifier = identifier; + } - //Parameters that are needed here - private String varName; - private Map localVars; + public String getIdentifier() { + return identifier; + } @Override public TypeCheckResult typeCheck() throws Exception { @@ -18,6 +22,6 @@ public class VarRefExpression implements IExpression{ @Override public void codeGen(MethodVisitor mv) throws Exception { - throw new Exception("CodeGen not implemented for VarRefExpression"); + } } diff --git a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java index 4acdc53..6fb57f9 100644 --- a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java @@ -12,6 +12,10 @@ import java.util.Objects; public class UnaryExpression extends AbstractType implements IExpression{ public String operator; public IDatatype operand; + public UnaryExpression(String operator, IDatatype operand){ + this.operator = operator; + this.operand = operand; + } @Override public TypeCheckResult typeCheck() throws Exception { TypeCheckResult result = new TypeCheckResult(); @@ -29,12 +33,13 @@ public class UnaryExpression extends AbstractType implements IExpression{ } case "-": - case "+": + case "": + case "+":{ if (Objects.equals(operandType, "int")){ result.type = "int"; } break; - + } } setTypeCheckResult(result); diff --git a/src/main/java/abstractSyntaxTree/Program.java b/src/main/java/abstractSyntaxTree/Program.java index ed2750e..95ba437 100644 --- a/src/main/java/abstractSyntaxTree/Program.java +++ b/src/main/java/abstractSyntaxTree/Program.java @@ -4,6 +4,8 @@ import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.FieldDecl; import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.RefType; +import abstractSyntaxTree.Parameter.Parameter; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -18,7 +20,7 @@ import java.util.jar.JarOutputStream; public class Program implements Node { public List classes; public HashMap> typeContext; // (class, (type, identifier)) - public HashMap>>> methodContext; // (class, (returntype, (identifier, parameter))) + public HashMap>> methodContext; // (class, (returntype, (identifier, parameter))) public Program(List classes){ this.classes = classes; @@ -39,11 +41,11 @@ public class Program implements Node { typeContext.put(oneClass.name, classVars); // build method context - HashMap> methodIdentifierAndParameter = new HashMap<>(); - HashMap>> returnTypeAndMethod = new HashMap<>(); + HashMap methodIdentifierAndParameter = new HashMap<>(); + HashMap> returnTypeAndMethod = new HashMap<>(); for (MethodDecl methodDecl : oneClass.methodDecls){ - methodIdentifierAndParameter.put(methodDecl.name, (List) methodDecl.parameters); + methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters); returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter); } methodContext.put(oneClass.name, returnTypeAndMethod); diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index 039abbb..f0e3645 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -2,6 +2,8 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; +import abstractSyntaxTree.Class.FieldDecl; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; @@ -11,8 +13,8 @@ public class BlockStatement extends AbstractType implements IStatement{ //We will need a parameter which holds the symbol table HashMap localVars; - String returnType; - List statements; + public String returnType; + public List statements; // do we need expression, statementexpression public BlockStatement(List statements, String returnType){ @@ -21,31 +23,24 @@ public class BlockStatement extends AbstractType implements IStatement{ } @Override - public TypeCheckResult typeCheck() throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, + HashMap> typeContext, + HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); if(statements.size() == 0){ result.type = "void"; } - TypeCheckResult blockType = new TypeCheckResult(); for (IStatement statement : statements) { TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars); - if (!typeOfCurrentStatement.equals(this.returnType) && !blockType.equals("void")) { - throw new IllegalArgumentException("Block returns type that it should not return"); + if (!typeOfCurrentStatement.type.equals(this.returnType)) { + if(!typeOfCurrentStatement.type.equals("void")) + throw new Exception("TypeCheck Exception: Block returns the wrong type."); } } + result.type = this.returnType; // todo check if the block returns the needed return type in every case // todo ignore unreadchable statements? return result; diff --git a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java index 774e0b7..a7ad544 100644 --- a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java @@ -2,26 +2,16 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.MethodVisitor; import java.util.HashMap; import java.util.List; public class EmptyStatement extends AbstractType implements IStatement{ - @Override - public TypeCheckResult typeCheck() throws Exception { - TypeCheckResult result = new TypeCheckResult(); - result.type = "void"; - return result; - } @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return typeCheck(methodContext, typeContext); - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); result.type = "void"; return result; diff --git a/src/main/java/abstractSyntaxTree/Statement/IStatement.java b/src/main/java/abstractSyntaxTree/Statement/IStatement.java index 85918b5..2225532 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IStatement.java @@ -2,6 +2,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.MethodVisitor; import java.util.HashMap; @@ -9,15 +10,7 @@ import java.util.List; public interface IStatement extends Node { - - - TypeCheckResult typeCheck() throws Exception; - - TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception; - - - TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception; - + TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception; void codeGen(MethodVisitor mv, HashMap localVars) throws Exception; } diff --git a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java index b28086b..0a07c93 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; @@ -19,8 +20,9 @@ public class IfElseStatement extends AbstractType implements IStatement{ this.elseStatement = elseStatement; } + @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult conditionType = condition.typeCheck(); @@ -29,8 +31,8 @@ public class IfElseStatement extends AbstractType implements IStatement{ throw new IllegalArgumentException("should be boolean"); } - TypeCheckResult ifStatementType = ifStatement.typeCheck(); - TypeCheckResult elseStatementType = elseStatement.typeCheck(); + TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars); + TypeCheckResult elseStatementType = elseStatement.typeCheck(methodContext, typeContext, localVars); if (!ifStatementType.equals(elseStatementType)) { throw new IllegalArgumentException("if and else have different types"); @@ -40,16 +42,6 @@ public class IfElseStatement extends AbstractType implements IStatement{ return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { - return null; - } - @Override public void codeGen(MethodVisitor mv, HashMap localVars) throws Exception { diff --git a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java index b51fe74..fc8c22d 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; @@ -18,8 +19,9 @@ public class IfStatement extends AbstractType implements IStatement{ this.condition = condition; this.ifStatement = ifStatement; } + @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult conditionType = condition.typeCheck(); @@ -28,21 +30,11 @@ public class IfStatement extends AbstractType implements IStatement{ throw new Exception("TypeCheck Exception: Condition of If-Statement should be bool."); } - TypeCheckResult ifStatementType = ifStatement.typeCheck(); + TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars); result.type = ifStatementType.type; return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { - return null; - } - @Override public void codeGen(MethodVisitor mv, HashMap localVars) throws Exception { diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java new file mode 100644 index 0000000..4fd73a4 --- /dev/null +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -0,0 +1,35 @@ +package abstractSyntaxTree.Statement; + +import TypeCheck.TypeCheckHelper; +import TypeCheck.TypeCheckResult; +import abstractSyntaxTree.Parameter.ParameterList; +import org.objectweb.asm.MethodVisitor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class LocalVarDecl implements IStatement{ + String type; + String identifier; + public LocalVarDecl(String type, String identifier) { + this.type = type; + this.identifier = identifier; + } + @Override + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + TypeCheckHelper.typeExists(this.type, new ArrayList<>(methodContext.keySet())); + + localVars.put(this.identifier, this.type); + + TypeCheckResult result = new TypeCheckResult(); + result.type = "void"; + return result; + } + + @Override + public void codeGen(MethodVisitor mv, HashMap localVars) throws Exception { + + } +} diff --git a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java index 8e324d7..358ee25 100644 --- a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; @@ -16,7 +17,7 @@ public class ReturnStatement extends AbstractType implements IStatement{ } @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); if (expression == null) { @@ -29,17 +30,6 @@ public class ReturnStatement extends AbstractType implements IStatement{ return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { - return null; - } - - //TODO: We do not differentiate between primitive types and reference types // This is a problem at "BinaryExpression" and here because we need to know the type to return // At this point in time we can either return reference types or have an error message diff --git a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java index b312be3..02d19e3 100644 --- a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; @@ -18,7 +19,7 @@ public class WhileStatement extends AbstractType implements IStatement { } @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult conditionType = condition.typeCheck(); @@ -27,22 +28,12 @@ public class WhileStatement extends AbstractType implements IStatement { throw new IllegalArgumentException("Expected boolean"); } - TypeCheckResult statementType = statement.typeCheck(); + TypeCheckResult statementType = statement.typeCheck(methodContext, typeContext, localVars); result.type = statementType.type; return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { - return null; - } - @Override public void codeGen(MethodVisitor mv, HashMap localVars) throws Exception { Label conditionFalse = new Label(); diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java index 8d96ae6..369557f 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java @@ -5,12 +5,12 @@ import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.InstVarExpression; -import abstractSyntaxTree.Expression.VarRefExpression; +import abstractSyntaxTree.Expression.LocalVarIdentifier; +import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; import org.objectweb.asm.*; import java.util.HashMap; -import java.util.List; import java.util.Objects; public class AssignStatementExpression extends AbstractType implements IExpression, IStatement { @@ -18,12 +18,27 @@ public class AssignStatementExpression extends AbstractType implements IExpressi public IExpression left; public IExpression right; + public AssignStatementExpression(String operator, IExpression leftExpression, IExpression rightExpression){ + this.operator = operator; + this.left = leftExpression; + this.right = rightExpression; + } + @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { TypeCheckHelper helper = new TypeCheckHelper(); TypeCheckResult result = new TypeCheckResult(); TypeCheckResult leftType = left.typeCheck(); + if(leftType == null){ //left expression is the identifier of a var + leftType = new TypeCheckResult(); + if (left instanceof LocalVarIdentifier) { + LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left; + String identifier = localVarIdentifier.getIdentifier(); + leftType.type = localVars.get(identifier); + } + // not local var + } TypeCheckResult rightType = right.typeCheck(); String upperbound = helper.upperBound(leftType.type, rightType.type); @@ -34,21 +49,16 @@ public class AssignStatementExpression extends AbstractType implements IExpressi return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { - return null; - } - @Override public void codeGen(MethodVisitor mv, HashMap localVars) throws Exception { } + @Override + public TypeCheckResult typeCheck() throws Exception { + return null; + } + @Override public void codeGen(MethodVisitor mv) throws Exception { left.codeGen(mv); diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index 1e6598a..0540422 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -5,6 +5,7 @@ import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; @@ -44,13 +45,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr return result; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { return null; } diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java index 63b7743..da19394 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.StatementExpression; import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; +import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; import org.objectweb.asm.MethodVisitor; @@ -15,13 +16,10 @@ public class NewStatementExpression extends AbstractType implements IExpression, return null; } - @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } + @Override - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { return null; }