Merge branch 'master' of https://gitea.hb.dhbw-stuttgart.de/i22022/NichtHaskell
This commit is contained in:
commit
4b36453ff3
20
Examples/Fakultaet.java
Normal file
20
Examples/Fakultaet.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class Fakultaet {
|
||||||
|
public int fak(int number) {
|
||||||
|
if (number < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int factorial = 1;
|
||||||
|
int i = 1;
|
||||||
|
while(i <= number){
|
||||||
|
factorial = factorial * i;
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return factorial;
|
||||||
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Fakultaet f = new Fakultaet();
|
||||||
|
int result = f.fak(5);
|
||||||
|
print(result);
|
||||||
|
}
|
||||||
|
}
|
40
Examples/FieldAccessAndMethodCalls.java
Normal file
40
Examples/FieldAccessAndMethodCalls.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
class FieldAccessAndMethodCalls {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Class1 c1 = new Class1();
|
||||||
|
int i = c1.c2.c3.m3(1).m2().m1();
|
||||||
|
print(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class1{
|
||||||
|
int i1;
|
||||||
|
Class2 c2;
|
||||||
|
public Class1() {
|
||||||
|
this.c2 = new Class2();
|
||||||
|
}
|
||||||
|
public int m1(){
|
||||||
|
return i1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class2{
|
||||||
|
int i2;
|
||||||
|
Class3 c3;
|
||||||
|
public Class2(){
|
||||||
|
this.c3 = new Class3();
|
||||||
|
}
|
||||||
|
public Class1 m2(){
|
||||||
|
Class1 c1 = new Class1();
|
||||||
|
c1.i1 = i2;
|
||||||
|
return c1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class3{
|
||||||
|
int i3;
|
||||||
|
public Class2 m3(int i){
|
||||||
|
Class2 c2 = new Class2();
|
||||||
|
c2.i2 = i;
|
||||||
|
return c2;
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import org.antlr.v4.runtime.CommonTokenStream;
|
|||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
import org.antlr.v4.runtime.tree.ParseTree;
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -18,16 +19,15 @@ public class Compiler {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception{
|
public static void main(String[] args) throws Exception{
|
||||||
|
|
||||||
// todo code für jar
|
|
||||||
// if (args.length < 1) {
|
|
||||||
// System.out.println("Usage: java -jar Compiler.jar <file_path> [--suppress-details]");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//String filePath = args[0];
|
if (args.length < 1) {
|
||||||
String filePath = "src/main/java/TestClass.java";
|
System.out.println("Usage: java -jar Compiler.jar <file_path> [--suppress-details]");
|
||||||
// TODO false setzen für jar-Build
|
return;
|
||||||
boolean suppressDetails = true;
|
}
|
||||||
|
|
||||||
|
String filePath = args[0];
|
||||||
|
|
||||||
|
boolean suppressDetails = false;
|
||||||
|
|
||||||
if (args.length > 1 && args[1].equals("--suppress-details")) {
|
if (args.length > 1 && args[1].equals("--suppress-details")) {
|
||||||
suppressDetails = true;
|
suppressDetails = true;
|
||||||
@ -64,7 +64,7 @@ public class Compiler {
|
|||||||
}
|
}
|
||||||
String readableTokens = stringBuilder.toString().trim();
|
String readableTokens = stringBuilder.toString().trim();
|
||||||
|
|
||||||
System.out.println("The tokens of your input are: \n" + readableTokens);
|
System.out.println("The tokens of your input are: \n" + readableTokens + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,26 +80,34 @@ public class Compiler {
|
|||||||
if(!suppressDetails) {
|
if(!suppressDetails) {
|
||||||
System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes: ");
|
System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes: ");
|
||||||
abstractSyntaxTree.classes.forEach(refType -> {
|
abstractSyntaxTree.classes.forEach(refType -> {
|
||||||
System.out.print(refType.name);
|
System.out.println("\t" + refType.name);
|
||||||
if (abstractSyntaxTree.classes.indexOf(refType) < abstractSyntaxTree.classes.size() - 1) {
|
});
|
||||||
System.out.print(", ");
|
|
||||||
} else {
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
try {
|
||||||
// try {
|
|
||||||
// abstractSyntaxTree.typeCheck();
|
|
||||||
// }catch(TypeCheckException e){
|
|
||||||
// System.out.println("A TypeCheck error occurred. The compilation was stopped.");
|
|
||||||
// System.out.println(e);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
abstractSyntaxTree.typeCheck();
|
abstractSyntaxTree.typeCheck();
|
||||||
|
}catch(TypeCheckException e){
|
||||||
|
System.out.println("A TypeCheck error was found in you input. Your input was not compiled.");
|
||||||
|
System.out.println(e);
|
||||||
|
return;
|
||||||
|
}catch (Exception e){
|
||||||
|
System.out.println("A unexpected error occurred in TypeCheck.");
|
||||||
|
System.out.println(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!suppressDetails)
|
if(!suppressDetails)
|
||||||
System.out.println("No TypeCheck errors found.");
|
System.out.println("No TypeCheck errors found.");
|
||||||
|
|
||||||
|
abstractSyntaxTree.codeGen();//todo remove
|
||||||
|
try {
|
||||||
abstractSyntaxTree.codeGen();
|
abstractSyntaxTree.codeGen();
|
||||||
System.out.println("Your input was compiled. You can find the output at ???");// todo wo output? überhaupt hinschreiben?
|
}catch (Exception e){
|
||||||
|
System.out.println("A error occurred during code generation. Your input was not compiled.");
|
||||||
|
System.out.println(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println("Your input was compiled. You can find the output in your current working directory.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ New : 'new';
|
|||||||
|
|
||||||
|
|
||||||
//Values
|
//Values
|
||||||
IntValue : ('+'|'-')*[0-9]+;
|
IntValue : ('+'|'-')?[0-9]+;
|
||||||
CharValue: '\''~[\r\n]?'\'';
|
CharValue: '\''~[\r\n]?'\'';
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,40 @@
|
|||||||
class Example1b {
|
class FieldAccessAndMethodCalls {
|
||||||
public int fak(int number){
|
public static void main(String[] args) {
|
||||||
if(number < 0){
|
Class1 c1 = new Class1();
|
||||||
return 1;
|
int i = c1.c2.c3.m3(1).m2().m1();
|
||||||
}
|
System.out.println(i);
|
||||||
int factorial = 1;
|
}
|
||||||
int i = 0;
|
}
|
||||||
while(i < number){
|
|
||||||
factorial = factorial * i;
|
class Class1{
|
||||||
}
|
int i1;
|
||||||
return factorial;
|
Class2 c2;
|
||||||
|
public Class1() {
|
||||||
|
this.c2 = new Class2();
|
||||||
|
}
|
||||||
|
public int m1(){
|
||||||
|
return i1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class2{
|
||||||
|
int i2;
|
||||||
|
Class3 c3;
|
||||||
|
public Class2(){
|
||||||
|
this.c3 = new Class3();
|
||||||
|
}
|
||||||
|
public Class1 m2(){
|
||||||
|
Class1 c1 = new Class1();
|
||||||
|
c1.i1 = i2;
|
||||||
|
return c1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class3{
|
||||||
|
int i3;
|
||||||
|
public Class2 m3(int i){
|
||||||
|
Class2 c2 = new Class2();
|
||||||
|
c2.i2 = i;
|
||||||
|
return c2;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,9 +18,9 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class FieldDecl extends AbstractType implements Node {
|
public class FieldDecl extends AbstractType implements Node {
|
||||||
|
|
||||||
public String type; // from parser
|
public String type;
|
||||||
public String identifier;// from parser
|
public String identifier;
|
||||||
public IExpression expression; // value of the field
|
public IExpression expression;
|
||||||
|
|
||||||
public FieldDecl(String type, String identifier, IExpression expression){
|
public FieldDecl(String type, String identifier, IExpression expression){
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@ -44,8 +44,6 @@ public class FieldDecl extends AbstractType implements Node {
|
|||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
//write field table
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void codeGen(ClassWriter cw) {
|
public void codeGen(ClassWriter cw) {
|
||||||
|
@ -35,7 +35,6 @@ public class MethodDecl implements Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws TypeCheckException {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws TypeCheckException {
|
||||||
// jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben
|
|
||||||
List<Parameter> parametersList = parameters.parameterList;
|
List<Parameter> parametersList = parameters.parameterList;
|
||||||
for(Parameter parameter : parametersList){
|
for(Parameter parameter : parametersList){
|
||||||
localVars.put(parameter.identifier, parameter.type);
|
localVars.put(parameter.identifier, parameter.type);
|
||||||
|
@ -68,7 +68,6 @@ public class RefType extends AbstractType implements Node {
|
|||||||
|
|
||||||
// type check each method
|
// type check each method
|
||||||
for (MethodDecl methodDecl : methodDecls) {
|
for (MethodDecl methodDecl : methodDecls) {
|
||||||
// methodDecl.classThatContainsMethod = this.name;
|
|
||||||
methodDecl.typeCheck(methodContext, typeContext);
|
methodDecl.typeCheck(methodContext, typeContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,9 @@ import TypeCheck.TypeCheckResult;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public interface IDatatype {
|
public interface IDatatype {
|
||||||
// typeCheck method
|
|
||||||
TypeCheckResult typeCheck() throws TypeCheckException;
|
TypeCheckResult typeCheck() throws TypeCheckException;
|
||||||
|
|
||||||
// visit method for code generation
|
|
||||||
|
|
||||||
void codeGen(MethodVisitor mv) throws Exception;
|
void codeGen(MethodVisitor mv) throws Exception;
|
||||||
|
|
||||||
TypeCheckResult getTypeCheckResult();
|
TypeCheckResult getTypeCheckResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Check if we need to differentiate between primitive types and reference types --> for example in "=="
|
|
@ -58,9 +58,6 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
result.type = "int";
|
result.type = "int";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case "&" ist für logisches und auf bit level
|
|
||||||
//case "|" ist für logisches oder auf bit level
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
@ -10,11 +10,7 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
public interface IExpression extends Node {
|
public interface IExpression extends Node {
|
||||||
// typeCheck method
|
|
||||||
//TypeCheckResult typeCheck() throws Exception;
|
|
||||||
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException;
|
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException;
|
||||||
|
|
||||||
// visit method for code generation
|
|
||||||
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception;
|
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception;
|
||||||
|
|
||||||
TypeCheckResult getTypeCheckResult();
|
TypeCheckResult getTypeCheckResult();
|
||||||
|
@ -87,7 +87,6 @@ public class Program implements Node {
|
|||||||
typeContext.put(oneClass.name, classVars);
|
typeContext.put(oneClass.name, classVars);
|
||||||
|
|
||||||
// build method context
|
// build method context
|
||||||
|
|
||||||
HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>();
|
HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>();
|
||||||
for (MethodDecl methodDecl : oneClass.methodDecls){
|
for (MethodDecl methodDecl : oneClass.methodDecls){
|
||||||
if(methodDecl.returnType == null) continue;
|
if(methodDecl.returnType == null) continue;
|
||||||
@ -98,8 +97,8 @@ public class Program implements Node {
|
|||||||
methodContext.put(oneClass.name, identifierAndMethod);
|
methodContext.put(oneClass.name, identifierAndMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mainCounter = 0;
|
|
||||||
// check if main exists
|
// check if main exists
|
||||||
|
int mainCounter = 0;
|
||||||
for(RefType oneClass : classes){
|
for(RefType oneClass : classes){
|
||||||
if(oneClass.hasMain)
|
if(oneClass.hasMain)
|
||||||
mainCounter++;
|
mainCounter++;
|
||||||
|
@ -17,13 +17,10 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BlockStatement extends AbstractType implements IStatement {
|
public class BlockStatement extends AbstractType implements IStatement {
|
||||||
|
|
||||||
//We will need a parameter which holds the symbol table
|
|
||||||
HashMap<String, String> localVars;
|
HashMap<String, String> localVars;
|
||||||
public String returnType; // "not" --> not void
|
public String returnType;
|
||||||
public List<IStatement> statements;
|
public List<IStatement> statements;
|
||||||
public String thisClass;
|
public String thisClass;
|
||||||
// do we need expression, statementexpression
|
|
||||||
|
|
||||||
public BlockStatement(List<IStatement> statements, String returnType) {
|
public BlockStatement(List<IStatement> statements, String returnType) {
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
|
@ -14,8 +14,6 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class IfStatement extends AbstractType implements IStatement{
|
public class IfStatement extends AbstractType implements IStatement{
|
||||||
public IExpression condition;
|
public IExpression condition;
|
||||||
|
|
||||||
//Do we need a block statement here?
|
|
||||||
IStatement ifStatement;
|
IStatement ifStatement;
|
||||||
public String thisClass;
|
public String thisClass;
|
||||||
|
|
||||||
|
@ -60,9 +60,13 @@ public class PrintStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
// If not a localVar, maybe a class field of this class
|
||||||
if (index == -1){
|
if (index == -1){
|
||||||
throw new Exception("Variable " + variableName + " not found");
|
String typeOfField = typeContext.get(thisClass).get(variableName);
|
||||||
|
if (typeOfField == null){
|
||||||
|
throw new Exception("Variable " + variableName + " not found in local variables or class fields.");
|
||||||
|
}
|
||||||
|
mv.visitFieldInsn(Opcodes.GETSTATIC, thisClass, variableName, "I");
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, index);
|
mv.visitVarInsn(Opcodes.ILOAD, index);
|
||||||
|
@ -5,6 +5,7 @@ import TypeCheck.TypeCheckResult;
|
|||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
import abstractSyntaxTree.Expression.InstVarExpression;
|
import abstractSyntaxTree.Expression.InstVarExpression;
|
||||||
|
import abstractSyntaxTree.Expression.LocalVarIdentifier;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression;
|
import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
@ -33,6 +34,8 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
methodCallStatementExpression.thisClass = this.thisClass;
|
methodCallStatementExpression.thisClass = this.thisClass;
|
||||||
else if(expression instanceof InstVarExpression instVarExpression)
|
else if(expression instanceof InstVarExpression instVarExpression)
|
||||||
instVarExpression.thisClass = this.thisClass;
|
instVarExpression.thisClass = this.thisClass;
|
||||||
|
else if(expression instanceof LocalVarIdentifier localVarIdentifier)
|
||||||
|
localVarIdentifier.thisClass = this.thisClass;
|
||||||
TypeCheckResult typedExpression = expression.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult typedExpression = expression.typeCheck(methodContext, typeContext, localVars);
|
||||||
result.type = typedExpression.type;
|
result.type = typedExpression.type;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
// check condition
|
// check condition
|
||||||
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
||||||
if (!conditionType.type.equals("boolean")) {
|
if (!conditionType.type.equals("boolean")) {
|
||||||
throw new IllegalArgumentException("Expected boolean");
|
throw new TypeCheckException("Condition of while-statement is of type " + conditionType.type + " but should be boolean.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check code block
|
// check code block
|
||||||
|
@ -36,6 +36,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
TypeCheckResult leftType;
|
TypeCheckResult leftType;
|
||||||
|
|
||||||
if (left instanceof LocalVarIdentifier localVarIdentifier) {
|
if (left instanceof LocalVarIdentifier localVarIdentifier) {
|
||||||
|
localVarIdentifier.thisClass = thisClass;
|
||||||
leftType = new TypeCheckResult();
|
leftType = new TypeCheckResult();
|
||||||
String identifier = localVarIdentifier.getIdentifier();
|
String identifier = localVarIdentifier.getIdentifier();
|
||||||
leftType.type = localVars.get(identifier);
|
leftType.type = localVars.get(identifier);
|
||||||
@ -51,6 +52,8 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
if(right instanceof MethodCallStatementExpression methodCallStatementExpression)
|
if(right instanceof MethodCallStatementExpression methodCallStatementExpression)
|
||||||
methodCallStatementExpression.thisClass = this.thisClass;
|
methodCallStatementExpression.thisClass = this.thisClass;
|
||||||
|
if(right instanceof LocalVarIdentifier localVarIdentifierRight)
|
||||||
|
localVarIdentifierRight.thisClass = this.thisClass;
|
||||||
|
|
||||||
TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
|
|
||||||
String classToSearchMethodIn = thisClass;
|
String classToSearchMethodIn = thisClass;
|
||||||
|
|
||||||
//method is called on something that is not this ???
|
|
||||||
if (this.receiver != null) {
|
if (this.receiver != null) {
|
||||||
if (!receiver.thisExpression) {
|
if (!receiver.thisExpression) {
|
||||||
classToSearchMethodIn = localVars.get(receiver.identifier);
|
classToSearchMethodIn = localVars.get(receiver.identifier);
|
||||||
@ -51,11 +50,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
receiver.instVarExpression.thisClass = this.thisClass;
|
receiver.instVarExpression.thisClass = this.thisClass;
|
||||||
String typeOfSubreceiver = receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars).type;
|
String typeOfSubreceiver = receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars).type;
|
||||||
|
|
||||||
String lastField = receiver.instVarExpression.fieldName;
|
|
||||||
|
|
||||||
currentType = typeOfSubreceiver;
|
currentType = typeOfSubreceiver;
|
||||||
|
|
||||||
//currentType = typeContext.get(receiver.instVarExpression.getTypeCheckResult().type).get(mostLeftField);
|
|
||||||
} else {
|
} else {
|
||||||
currentType = classToSearchMethodIn;
|
currentType = classToSearchMethodIn;
|
||||||
}
|
}
|
||||||
@ -63,16 +58,11 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
currentType = thisClass;
|
currentType = thisClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if classToSearchMethodIn does not contain method, throw exception. go through list and check each
|
|
||||||
|
|
||||||
for (int i = 0; i < receivingMethods.size(); i++) {
|
for (int i = 0; i < receivingMethods.size(); i++) {
|
||||||
currentType = (String) methodContext.get(currentType).get(receivingMethods.get(i).methodName).keySet().toArray()[0];
|
currentType = (String) methodContext.get(currentType).get(receivingMethods.get(i).methodName).keySet().toArray()[0];
|
||||||
if (currentType == null)
|
if (currentType == null)
|
||||||
throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + ".");
|
throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + ".");
|
||||||
receivingMethods.get(i).thisClass = this.thisClass;
|
receivingMethods.get(i).thisClass = this.thisClass;
|
||||||
|
|
||||||
// currentType = return type
|
|
||||||
// ThisClass = class von methode
|
|
||||||
receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars);
|
receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars);
|
||||||
}
|
}
|
||||||
currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0];
|
currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0];
|
||||||
|
@ -19,7 +19,7 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
|
|
||||||
public String thisClass;
|
public String thisClass;
|
||||||
private String className;
|
private String className;
|
||||||
private List<IExpression> arguments; //These need to have a TypeCheckResult
|
private List<IExpression> arguments;
|
||||||
|
|
||||||
public NewStatementExpression(String className, List<IExpression> arguments) {
|
public NewStatementExpression(String className, List<IExpression> arguments) {
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
@ -32,27 +32,27 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
List<FieldDecl> fieldDecls = new ArrayList<>();
|
List<FieldDecl> fieldDecls = new ArrayList<>();
|
||||||
List<MethodDecl> methodDecls = new ArrayList<>();
|
List<MethodDecl> methodDecls = new ArrayList<>();
|
||||||
boolean hasMain;
|
boolean hasMain;
|
||||||
if(ctx.MainMethodDecl() != null) {
|
if (ctx.MainMethodDecl() != null) {
|
||||||
hasMain = true;
|
hasMain = true;
|
||||||
MethodDecl mainMethod = new MethodDecl(name, "void", "main", new ParameterList(new ArrayList<>()),(BlockStatement) visitBlock(ctx.block()));
|
MethodDecl mainMethod = new MethodDecl(name, "void", "main", new ParameterList(new ArrayList<>()), (BlockStatement) visitBlock(ctx.block()));
|
||||||
methodDecls.add(mainMethod);
|
methodDecls.add(mainMethod);
|
||||||
} else {
|
} else {
|
||||||
hasMain = false;
|
hasMain = false;
|
||||||
}
|
}
|
||||||
for (DecafParser.LocalVarDeclContext fieldDecl: ctx.localVarDecl()) {
|
for (DecafParser.LocalVarDeclContext fieldDecl : ctx.localVarDecl()) {
|
||||||
fieldDecls.add((FieldDecl) generateFieldDecl(fieldDecl));
|
fieldDecls.add((FieldDecl) generateFieldDecl(fieldDecl));
|
||||||
}
|
}
|
||||||
for (DecafParser.ConstuctorDeclContext constDecl: ctx.constuctorDecl()) {
|
for (DecafParser.ConstuctorDeclContext constDecl : ctx.constuctorDecl()) {
|
||||||
MethodDecl constructor = ((MethodDecl) visit(constDecl));
|
MethodDecl constructor = ((MethodDecl) visit(constDecl));
|
||||||
constructor.classThatContainsMethod = name;
|
constructor.classThatContainsMethod = name;
|
||||||
methodDecls.add(constructor);
|
methodDecls.add(constructor);
|
||||||
}
|
}
|
||||||
for (DecafParser.MethodDeclContext methodDecl: ctx.methodDecl()) {
|
for (DecafParser.MethodDeclContext methodDecl : ctx.methodDecl()) {
|
||||||
MethodDecl method = (MethodDecl) visit(methodDecl);
|
MethodDecl method = (MethodDecl) visit(methodDecl);
|
||||||
method.classThatContainsMethod = name;
|
method.classThatContainsMethod = name;
|
||||||
methodDecls.add(method);
|
methodDecls.add(method);
|
||||||
}
|
}
|
||||||
return new RefType(name,fieldDecls, methodDecls, hasMain);
|
return new RefType(name, fieldDecls, methodDecls, hasMain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node generateFieldDecl(DecafParser.LocalVarDeclContext ctx) {
|
public Node generateFieldDecl(DecafParser.LocalVarDeclContext ctx) {
|
||||||
@ -99,7 +99,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
} else {
|
} else {
|
||||||
type = ctx.type().getText();
|
type = ctx.type().getText();
|
||||||
}
|
}
|
||||||
return new MethodDecl("", type , name, parameterList, block);
|
return new MethodDecl("", type, name, parameterList, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -110,7 +110,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
@Override
|
@Override
|
||||||
public Node visitParameterList(DecafParser.ParameterListContext ctx) {
|
public Node visitParameterList(DecafParser.ParameterListContext ctx) {
|
||||||
List<Parameter> parameters = new ArrayList<>();
|
List<Parameter> parameters = new ArrayList<>();
|
||||||
for (DecafParser.ParameterContext parameter: ctx.parameter()) {
|
for (DecafParser.ParameterContext parameter : ctx.parameter()) {
|
||||||
parameters.add((Parameter) visit(parameter));
|
parameters.add((Parameter) visit(parameter));
|
||||||
}
|
}
|
||||||
return new ParameterList(parameters);
|
return new ParameterList(parameters);
|
||||||
@ -151,7 +151,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
@Override
|
@Override
|
||||||
public Node visitBlock(DecafParser.BlockContext ctx) {
|
public Node visitBlock(DecafParser.BlockContext ctx) {
|
||||||
List<IStatement> stmts = new ArrayList<>();
|
List<IStatement> stmts = new ArrayList<>();
|
||||||
for (DecafParser.StatementContext stmt: ctx.statement()) {
|
for (DecafParser.StatementContext stmt : ctx.statement()) {
|
||||||
Node statement = visitStatement(stmt);
|
Node statement = visitStatement(stmt);
|
||||||
stmts.add((IStatement) statement);
|
stmts.add((IStatement) statement);
|
||||||
}
|
}
|
||||||
@ -211,7 +211,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
public Node visitAssign(DecafParser.AssignContext ctx) {
|
public Node visitAssign(DecafParser.AssignContext ctx) {
|
||||||
Node right = visitExpression(ctx.expression());
|
Node right = visitExpression(ctx.expression());
|
||||||
Node left = visitAssignableExpr(ctx.assignableExpr());
|
Node left = visitAssignableExpr(ctx.assignableExpr());
|
||||||
return new AssignStatementExpression(ctx.Assign().getText(),(IExpression) left, (IExpression) right);
|
return new AssignStatementExpression(ctx.Assign().getText(), (IExpression) left, (IExpression) right);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -219,7 +219,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
String methodName = ctx.Identifier().getText();
|
String methodName = ctx.Identifier().getText();
|
||||||
List<IExpression> arguments = generateExpressions(ctx.argumentList());
|
List<IExpression> arguments = generateExpressions(ctx.argumentList());
|
||||||
List<ReceivingMethod> receivingMethods = new ArrayList<>();
|
List<ReceivingMethod> receivingMethods = new ArrayList<>();
|
||||||
for(DecafParser.ReceivingMethodContext receivingMethod: ctx.receivingMethod()) {
|
for (DecafParser.ReceivingMethodContext receivingMethod : ctx.receivingMethod()) {
|
||||||
receivingMethods.add((ReceivingMethod) visit(receivingMethod));
|
receivingMethods.add((ReceivingMethod) visit(receivingMethod));
|
||||||
}
|
}
|
||||||
if (ctx.receiver() != null) {
|
if (ctx.receiver() != null) {
|
||||||
@ -320,14 +320,14 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
if (ctx.IntValue() != null) {
|
if (ctx.IntValue() != null) {
|
||||||
int value = Integer.parseInt(ctx.IntValue().getText());
|
int value = Integer.parseInt(ctx.IntValue().getText());
|
||||||
return new IntConstantExpression(value);
|
return new IntConstantExpression(value);
|
||||||
} else if(ctx.Identifier() != null) {
|
} else if (ctx.Identifier() != null) {
|
||||||
String identifier = ctx.Identifier().getText();
|
String identifier = ctx.Identifier().getText();
|
||||||
return new LocalVarIdentifier(identifier);
|
return new LocalVarIdentifier(identifier);
|
||||||
} else if(ctx.instVar() != null) {
|
} else if (ctx.instVar() != null) {
|
||||||
return visitInstVar(ctx.instVar());
|
return visitInstVar(ctx.instVar());
|
||||||
} else if(ctx.methodCall() != null) {
|
} else if (ctx.methodCall() != null) {
|
||||||
return visitMethodCall(ctx.methodCall());
|
return visitMethodCall(ctx.methodCall());
|
||||||
} else if(ctx.calcExpr() != null) {
|
} else if (ctx.calcExpr() != null) {
|
||||||
return visitCalcExpr(ctx.calcExpr());
|
return visitCalcExpr(ctx.calcExpr());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -336,7 +336,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
@Override
|
@Override
|
||||||
public Node visitNonCalcExpr(DecafParser.NonCalcExprContext ctx) {
|
public Node visitNonCalcExpr(DecafParser.NonCalcExprContext ctx) {
|
||||||
String operator;
|
String operator;
|
||||||
if(ctx.nonCalcOperator().LogicalOpertor() != null) {
|
if (ctx.nonCalcOperator().LogicalOpertor() != null) {
|
||||||
operator = ctx.nonCalcOperator().LogicalOpertor().getText();
|
operator = ctx.nonCalcOperator().LogicalOpertor().getText();
|
||||||
} else {
|
} else {
|
||||||
operator = ctx.nonCalcOperator().ComparisonOperator().getText();
|
operator = ctx.nonCalcOperator().ComparisonOperator().getText();
|
||||||
@ -373,10 +373,10 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
List<SubReceiver> receivers = new ArrayList<>();
|
List<SubReceiver> receivers = new ArrayList<>();
|
||||||
List<ReceivingMethod> receivingMethods = new ArrayList<>();
|
List<ReceivingMethod> receivingMethods = new ArrayList<>();
|
||||||
String fieldName = ctx.Identifier().getText();
|
String fieldName = ctx.Identifier().getText();
|
||||||
for(DecafParser.SubReceiverContext subReceiver : ctx.subReceiver()) {
|
for (DecafParser.SubReceiverContext subReceiver : ctx.subReceiver()) {
|
||||||
receivers.add((SubReceiver) visit(subReceiver));
|
receivers.add((SubReceiver) visit(subReceiver));
|
||||||
}
|
}
|
||||||
for(DecafParser.ReceivingMethodContext receivingMethod: ctx.receivingMethod()) {
|
for (DecafParser.ReceivingMethodContext receivingMethod : ctx.receivingMethod()) {
|
||||||
receivingMethods.add((ReceivingMethod) visit(receivingMethod));
|
receivingMethods.add((ReceivingMethod) visit(receivingMethod));
|
||||||
}
|
}
|
||||||
return new InstVarExpression(receivers, receivingMethods, fieldName);
|
return new InstVarExpression(receivers, receivingMethods, fieldName);
|
||||||
|
Loading…
Reference in New Issue
Block a user