interface changes, added localvaridentifier, removed iclass interface, some type check for statements, delete varrefexpression
This commit is contained in:
parent
87cde5e048
commit
2f549e31e9
@ -1,5 +1,4 @@
|
|||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
import abstractSyntaxTree.Class.IClass;
|
|
||||||
import abstractSyntaxTree.Class.MethodDecl;
|
import abstractSyntaxTree.Class.MethodDecl;
|
||||||
import abstractSyntaxTree.Class.RefType;
|
import abstractSyntaxTree.Class.RefType;
|
||||||
import abstractSyntaxTree.Expression.BinaryExpression;
|
import abstractSyntaxTree.Expression.BinaryExpression;
|
||||||
@ -11,7 +10,6 @@ import abstractSyntaxTree.Statement.*;
|
|||||||
import gen.DecafBaseVisitor;
|
import gen.DecafBaseVisitor;
|
||||||
import gen.DecafParser;
|
import gen.DecafParser;
|
||||||
|
|
||||||
import java.beans.Expression;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import abstractSyntaxTree.Class.RefType;
|
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.Program;
|
||||||
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import abstractSyntaxTree.Statement.LocalVarDecl;
|
||||||
|
import abstractSyntaxTree.Statement.ReturnStatement;
|
||||||
|
import abstractSyntaxTree.StatementExpression.AssignStatementExpression;
|
||||||
import gen.DecafLexer;
|
import gen.DecafLexer;
|
||||||
import gen.DecafParser;
|
import gen.DecafParser;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
@ -81,6 +90,15 @@ public class Compiler {
|
|||||||
// System.out.println(refType.name);
|
// System.out.println(refType.name);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.returnType = "int";
|
||||||
|
List<IStatement> 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.typeCheck();
|
||||||
|
|
||||||
abstractSyntaxTree.codeGen();
|
abstractSyntaxTree.codeGen();
|
||||||
|
@ -5,7 +5,9 @@ class Example {
|
|||||||
|
|
||||||
}
|
}
|
||||||
class Example2 {
|
class Example2 {
|
||||||
int i;
|
boolean instVarBool;
|
||||||
boolean j;
|
void m(int i){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
6
src/main/java/TestClass.java
Normal file
6
src/main/java/TestClass.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
public class TestClass {
|
||||||
|
public static void main(String[] args){
|
||||||
|
new Example();
|
||||||
|
new Example2();
|
||||||
|
}
|
||||||
|
}
|
@ -12,8 +12,9 @@ public class TypeCheckHelper {
|
|||||||
if(type1Primitiv && type2Primitiv){
|
if(type1Primitiv && type2Primitiv){
|
||||||
if(Objects.equals(type1, type2)){
|
if(Objects.equals(type1, type2)){
|
||||||
result = type1;
|
result = type1;
|
||||||
|
}else{
|
||||||
|
throw new Exception("no upper bound");
|
||||||
}
|
}
|
||||||
throw new Exception("no upper bound");
|
|
||||||
}else if(type1Primitiv || type2Primitiv){
|
}else if(type1Primitiv || type2Primitiv){
|
||||||
throw new Exception("no upper bound");
|
throw new Exception("no upper bound");
|
||||||
}else{
|
}else{
|
||||||
|
@ -13,7 +13,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
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 type; // from parser
|
||||||
public String identifier; // from parser
|
public String identifier; // from parser
|
||||||
@ -39,7 +39,6 @@ public class FieldDecl extends AbstractType implements IClass, Node {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void codeGen(ClassWriter cw) {
|
public void codeGen(ClassWriter cw) {
|
||||||
//TODO: Do we have fields with initial values?
|
//TODO: Do we have fields with initial values?
|
||||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, identifier, getFieldDescriptor(), null, null);
|
FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, identifier, getFieldDescriptor(), null, 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;
|
|
||||||
|
|
||||||
}
|
|
@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
public class MethodDecl implements IClass, Node {
|
public class MethodDecl implements Node {
|
||||||
|
|
||||||
//Class Name
|
//Class Name
|
||||||
public String classThatContainsMethod;
|
public String classThatContainsMethod;
|
||||||
@ -36,14 +36,15 @@ public class MethodDecl implements IClass, Node {
|
|||||||
this.localVars = new HashMap<>();
|
this.localVars = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
// jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben
|
// jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben
|
||||||
|
|
||||||
codeBlock.typeCheck(methodContext, typeContext);
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
return null;
|
codeBlock.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
result.type = codeBlock.returnType;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void codeGen(ClassWriter cw) throws Exception {
|
public void codeGen(ClassWriter cw) throws Exception {
|
||||||
|
|
||||||
localVars.put("this", classThatContainsMethod);
|
localVars.put("this", classThatContainsMethod);
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Class;
|
|||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RefType extends AbstractType implements IClass, Node {
|
public class RefType extends AbstractType implements Node {
|
||||||
|
|
||||||
//Class Name
|
//Class Name
|
||||||
public String name;
|
public String name;
|
||||||
@ -29,7 +30,7 @@ public class RefType extends AbstractType implements IClass, Node {
|
|||||||
this.hasMain = hasMain;
|
this.hasMain = hasMain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext,
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
|
||||||
HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
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
|
// Method for code generation which iterates over all the field declarations
|
||||||
// and method declarations and calls their CodeGen methods
|
// and method declarations and calls their CodeGen methods
|
||||||
@Override
|
|
||||||
public void codeGen(ClassWriter cw) throws Exception {
|
public void codeGen(ClassWriter cw) throws Exception {
|
||||||
|
|
||||||
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null,
|
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null,
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
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
|
public String getIdentifier() {
|
||||||
private String varName;
|
return identifier;
|
||||||
private Map<String, Integer> localVars;
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
@ -18,6 +22,6 @@ public class VarRefExpression implements IExpression{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
throw new Exception("CodeGen not implemented for VarRefExpression");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,6 +12,10 @@ import java.util.Objects;
|
|||||||
public class UnaryExpression extends AbstractType implements IExpression{
|
public class UnaryExpression extends AbstractType implements IExpression{
|
||||||
public String operator;
|
public String operator;
|
||||||
public IDatatype operand;
|
public IDatatype operand;
|
||||||
|
public UnaryExpression(String operator, IDatatype operand){
|
||||||
|
this.operator = operator;
|
||||||
|
this.operand = operand;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
@ -29,12 +33,13 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "-":
|
case "-":
|
||||||
case "+":
|
case "":
|
||||||
|
case "+":{
|
||||||
if (Objects.equals(operandType, "int")){
|
if (Objects.equals(operandType, "int")){
|
||||||
result.type = "int";
|
result.type = "int";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
@ -4,6 +4,8 @@ import TypeCheck.TypeCheckResult;
|
|||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
import abstractSyntaxTree.Class.MethodDecl;
|
import abstractSyntaxTree.Class.MethodDecl;
|
||||||
import abstractSyntaxTree.Class.RefType;
|
import abstractSyntaxTree.Class.RefType;
|
||||||
|
import abstractSyntaxTree.Parameter.Parameter;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ import java.util.jar.JarOutputStream;
|
|||||||
public class Program implements Node {
|
public class Program implements Node {
|
||||||
public List<RefType> classes;
|
public List<RefType> classes;
|
||||||
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
|
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
|
||||||
public HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext; // (class, (returntype, (identifier, parameter)))
|
public HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext; // (class, (returntype, (identifier, parameter)))
|
||||||
|
|
||||||
public Program(List<RefType> classes){
|
public Program(List<RefType> classes){
|
||||||
this.classes = classes;
|
this.classes = classes;
|
||||||
@ -39,11 +41,11 @@ public class Program implements Node {
|
|||||||
typeContext.put(oneClass.name, classVars);
|
typeContext.put(oneClass.name, classVars);
|
||||||
|
|
||||||
// build method context
|
// build method context
|
||||||
HashMap<String, List<String>> methodIdentifierAndParameter = new HashMap<>();
|
HashMap<String, ParameterList> methodIdentifierAndParameter = new HashMap<>();
|
||||||
HashMap<String, HashMap<String, List<String >>> returnTypeAndMethod = new HashMap<>();
|
HashMap<String, HashMap<String, ParameterList>> returnTypeAndMethod = new HashMap<>();
|
||||||
for (MethodDecl methodDecl : oneClass.methodDecls){
|
for (MethodDecl methodDecl : oneClass.methodDecls){
|
||||||
|
|
||||||
methodIdentifierAndParameter.put(methodDecl.name, (List<String>) methodDecl.parameters);
|
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
|
||||||
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
||||||
}
|
}
|
||||||
methodContext.put(oneClass.name, returnTypeAndMethod);
|
methodContext.put(oneClass.name, returnTypeAndMethod);
|
||||||
|
@ -2,6 +2,8 @@ package abstractSyntaxTree.Statement;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
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
|
//We will need a parameter which holds the symbol table
|
||||||
HashMap<String, String > localVars;
|
HashMap<String, String > localVars;
|
||||||
String returnType;
|
public String returnType;
|
||||||
List<IStatement> statements;
|
public List<IStatement> statements;
|
||||||
// do we need expression, statementexpression
|
// do we need expression, statementexpression
|
||||||
|
|
||||||
public BlockStatement(List<IStatement> statements, String returnType){
|
public BlockStatement(List<IStatement> statements, String returnType){
|
||||||
@ -21,31 +23,24 @@ public class BlockStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
|
||||||
return null;
|
HashMap<String, HashMap<String, String>> typeContext,
|
||||||
}
|
HashMap<String, String> localVars) throws Exception {
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
if(statements.size() == 0){
|
if(statements.size() == 0){
|
||||||
result.type = "void";
|
result.type = "void";
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCheckResult blockType = new TypeCheckResult();
|
|
||||||
for (IStatement statement : statements) {
|
for (IStatement statement : statements) {
|
||||||
TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
|
||||||
if (!typeOfCurrentStatement.equals(this.returnType) && !blockType.equals("void")) {
|
if (!typeOfCurrentStatement.type.equals(this.returnType)) {
|
||||||
throw new IllegalArgumentException("Block returns type that it should not return");
|
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 check if the block returns the needed return type in every case
|
||||||
// todo ignore unreadchable statements?
|
// todo ignore unreadchable statements?
|
||||||
return result;
|
return result;
|
||||||
|
@ -2,26 +2,16 @@ package abstractSyntaxTree.Statement;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EmptyStatement extends AbstractType implements IStatement{
|
public class EmptyStatement extends AbstractType implements IStatement{
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
|
||||||
result.type = "void";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
return typeCheck(methodContext, typeContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = "void";
|
result.type = "void";
|
||||||
return result;
|
return result;
|
||||||
|
@ -2,6 +2,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -9,15 +10,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public interface IStatement extends Node {
|
public interface IStatement extends Node {
|
||||||
|
|
||||||
|
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception;
|
||||||
|
|
||||||
TypeCheckResult typeCheck() throws Exception;
|
|
||||||
|
|
||||||
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception;
|
void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -19,8 +20,9 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
this.elseStatement = elseStatement;
|
this.elseStatement = elseStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult conditionType = condition.typeCheck();
|
TypeCheckResult conditionType = condition.typeCheck();
|
||||||
@ -29,8 +31,8 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
throw new IllegalArgumentException("should be boolean");
|
throw new IllegalArgumentException("should be boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCheckResult ifStatementType = ifStatement.typeCheck();
|
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
|
||||||
TypeCheckResult elseStatementType = elseStatement.typeCheck();
|
TypeCheckResult elseStatementType = elseStatement.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
|
||||||
if (!ifStatementType.equals(elseStatementType)) {
|
if (!ifStatementType.equals(elseStatementType)) {
|
||||||
throw new IllegalArgumentException("if and else have different types");
|
throw new IllegalArgumentException("if and else have different types");
|
||||||
@ -40,16 +42,6 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -18,8 +19,9 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.ifStatement = ifStatement;
|
this.ifStatement = ifStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult conditionType = condition.typeCheck();
|
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.");
|
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;
|
result.type = ifStatementType.type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
||||||
|
|
||||||
|
35
src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java
Normal file
35
src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java
Normal file
@ -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<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> 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<String, String> localVars) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -16,7 +17,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
@ -29,17 +30,6 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: We do not differentiate between primitive types and reference types
|
//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
|
// 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
|
// At this point in time we can either return reference types or have an error message
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -18,7 +19,7 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult conditionType = condition.typeCheck();
|
TypeCheckResult conditionType = condition.typeCheck();
|
||||||
@ -27,22 +28,12 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
throw new IllegalArgumentException("Expected boolean");
|
throw new IllegalArgumentException("Expected boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCheckResult statementType = statement.typeCheck();
|
TypeCheckResult statementType = statement.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
|
||||||
result.type = statementType.type;
|
result.type = statementType.type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
||||||
Label conditionFalse = new Label();
|
Label conditionFalse = new Label();
|
||||||
|
@ -5,12 +5,12 @@ import TypeCheck.TypeCheckHelper;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
import abstractSyntaxTree.Expression.InstVarExpression;
|
import abstractSyntaxTree.Expression.InstVarExpression;
|
||||||
import abstractSyntaxTree.Expression.VarRefExpression;
|
import abstractSyntaxTree.Expression.LocalVarIdentifier;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class AssignStatementExpression extends AbstractType implements IExpression, IStatement {
|
public class AssignStatementExpression extends AbstractType implements IExpression, IStatement {
|
||||||
@ -18,12 +18,27 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
public IExpression left;
|
public IExpression left;
|
||||||
public IExpression right;
|
public IExpression right;
|
||||||
|
|
||||||
|
public AssignStatementExpression(String operator, IExpression leftExpression, IExpression rightExpression){
|
||||||
|
this.operator = operator;
|
||||||
|
this.left = leftExpression;
|
||||||
|
this.right = rightExpression;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
TypeCheckHelper helper = new TypeCheckHelper();
|
TypeCheckHelper helper = new TypeCheckHelper();
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult leftType = left.typeCheck();
|
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();
|
TypeCheckResult rightType = right.typeCheck();
|
||||||
|
|
||||||
String upperbound = helper.upperBound(leftType.type, rightType.type);
|
String upperbound = helper.upperBound(leftType.type, rightType.type);
|
||||||
@ -34,21 +49,16 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
public void codeGen(MethodVisitor mv, HashMap<String, String> localVars) throws Exception {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
left.codeGen(mv);
|
left.codeGen(mv);
|
||||||
|
@ -5,6 +5,7 @@ import TypeCheck.TypeCheckResult;
|
|||||||
import abstractSyntaxTree.Class.MethodDecl;
|
import abstractSyntaxTree.Class.MethodDecl;
|
||||||
import abstractSyntaxTree.Class.RefType;
|
import abstractSyntaxTree.Class.RefType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@ -44,13 +45,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.StatementExpression;
|
|||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
@ -15,13 +16,10 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user