Compare commits
2 Commits
ebd4f7ca4e
...
5a66ce97ca
Author | SHA1 | Date | |
---|---|---|---|
|
5a66ce97ca | ||
|
fdae734452 |
@ -79,40 +79,6 @@ public class Compiler {
|
|||||||
System.out.println(refType.name);
|
System.out.println(refType.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// List<FieldDecl> fieldDecls = new ArrayList<>();
|
|
||||||
//
|
|
||||||
// FieldDecl fieldDecl = new FieldDecl("int", "i");
|
|
||||||
// fieldDecls.add(fieldDecl);
|
|
||||||
//
|
|
||||||
//// FieldDecl fieldDecl2 = new FieldDecl("char", "i");
|
|
||||||
//// fieldDecls.add(fieldDecl2);
|
|
||||||
//
|
|
||||||
// List<MethodDecl> methodDecls = new ArrayList<>();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// MethodDecl methodDecl = new MethodDecl("ClassA", "int", "m", new ParameterList(new ArrayList<>()), new BlockStatement(new ArrayList<>(), "void"));
|
|
||||||
// methodDecls.add(methodDecl);
|
|
||||||
//
|
|
||||||
//// MethodDecl methodDecl2 = new MethodDecl("ClassA", "int", "m", new ArrayList<>(), new ArrayList<>());
|
|
||||||
//// methodDecls.add(methodDecl2);
|
|
||||||
//
|
|
||||||
// abstractSyntaxTree.classes.add(new RefType("MyClass", fieldDecls, methodDecls, false));
|
|
||||||
//
|
|
||||||
// System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes with identifiers/names:");
|
|
||||||
// for (RefType refType : abstractSyntaxTree.classes) {
|
|
||||||
// System.out.println(refType.name);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
IfElseStatement c = (IfElseStatement) abstractSyntaxTree.classes.get(0).methodDecls.get(0).codeBlock.statements.get(2);
|
|
||||||
InstVarExpression d = (InstVarExpression) c.condition;
|
|
||||||
d.classRef = abstractSyntaxTree.classes.get(0);
|
|
||||||
|
|
||||||
|
|
||||||
AssignStatementExpression a = (AssignStatementExpression) abstractSyntaxTree.classes.get(0).methodDecls.get(0).codeBlock.statements.get(1);
|
|
||||||
InstVarExpression b = (InstVarExpression) a.left;
|
|
||||||
b.classRef = abstractSyntaxTree.classes.get(0);
|
|
||||||
abstractSyntaxTree.typeCheck();
|
abstractSyntaxTree.typeCheck();
|
||||||
|
|
||||||
abstractSyntaxTree.codeGen();
|
abstractSyntaxTree.codeGen();
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
class Example {
|
class Example1 {
|
||||||
int i;
|
int i;
|
||||||
boolean b;
|
boolean b;
|
||||||
char c;
|
char c;
|
||||||
int m(int n){
|
int m(int n){
|
||||||
int localA;
|
Example e = new Example();
|
||||||
this.b = true;
|
e.m(1);
|
||||||
if(this.b){
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Example {
|
||||||
|
int i;
|
||||||
|
boolean b;
|
||||||
|
char c;
|
||||||
|
int m(int a){
|
||||||
|
int localA = 0;
|
||||||
|
boolean localB = true;
|
||||||
|
if(localB){
|
||||||
localA = 7;
|
localA = 7;
|
||||||
}else{
|
}else{}
|
||||||
localA = 5;
|
|
||||||
}
|
|
||||||
return localA;
|
return localA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
src/main/java/TypeCheck/TypeCheckException.java
Normal file
7
src/main/java/TypeCheck/TypeCheckException.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package TypeCheck;
|
||||||
|
|
||||||
|
public class TypeCheckException extends Exception {
|
||||||
|
public TypeCheckException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -4,23 +4,19 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class TypeCheckHelper {
|
public class TypeCheckHelper {
|
||||||
public String upperBound(String type1, String type2) throws Exception{
|
public String upperBound(String type1, String type2) throws TypeCheckException{
|
||||||
if(Objects.equals(type1, "boolean"))
|
boolean type1Primitiv = Objects.equals(type1, "boolean") || Objects.equals(type1, "int") || Objects.equals(type1, "char");
|
||||||
type1 = "bool";
|
boolean type2Primitiv = Objects.equals(type2, "boolean") || Objects.equals(type2, "int") || Objects.equals(type2, "char");
|
||||||
if (Objects.equals(type2, "boolean"))
|
|
||||||
type2 = "bool";
|
|
||||||
boolean type1Primitiv = Objects.equals(type1, "bool") || Objects.equals(type1, "int") || Objects.equals(type1, "char");
|
|
||||||
boolean type2Primitiv = Objects.equals(type2, "bool") || Objects.equals(type2, "int") || Objects.equals(type2, "char");
|
|
||||||
|
|
||||||
String result;
|
String result;
|
||||||
if(type1Primitiv && type2Primitiv){
|
if(type1Primitiv && type2Primitiv){
|
||||||
if(Objects.equals(type1, type2)){
|
if(Objects.equals(type1, type2)){
|
||||||
result = type1;
|
result = type1;
|
||||||
}else{
|
}else{
|
||||||
throw new Exception("no upper bound");
|
throw new TypeCheckException("There is no upper bound.");
|
||||||
}
|
}
|
||||||
}else if(type1Primitiv || type2Primitiv){
|
}else if(type1Primitiv || type2Primitiv){
|
||||||
throw new Exception("no upper bound");
|
throw new TypeCheckException("There is no upper bound.");
|
||||||
}else{
|
}else{
|
||||||
result = "class";
|
result = "class";
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Class;
|
package abstractSyntaxTree.Class;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
@ -23,7 +24,7 @@ public class FieldDecl extends AbstractType implements Node {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, String>> typeContext) throws TypeCheckException {
|
||||||
|
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Class;
|
package abstractSyntaxTree.Class;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
import abstractSyntaxTree.Parameter.Parameter;
|
import abstractSyntaxTree.Parameter.Parameter;
|
||||||
@ -33,7 +34,7 @@ public class MethodDecl implements Node {
|
|||||||
this.localVars = new LinkedHashMap<>();
|
this.localVars = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
// 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
|
||||||
List<Parameter> parametersList = parameters.parameterList;
|
List<Parameter> parametersList = parameters.parameterList;
|
||||||
for(Parameter parameter : parametersList){
|
for(Parameter parameter : parametersList){
|
||||||
@ -43,7 +44,7 @@ public class MethodDecl implements Node {
|
|||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
String CodeBlockType = codeBlock.typeCheck(methodContext, typeContext, localVars).type;
|
String CodeBlockType = codeBlock.typeCheck(methodContext, typeContext, localVars).type;
|
||||||
if(!Objects.equals(this.returnType, CodeBlockType))
|
if(!Objects.equals(this.returnType, CodeBlockType))
|
||||||
throw new Exception("TypeCheck Exception: Method retruns wrong type");
|
throw new TypeCheckException("Method returns " + CodeBlockType + ", but should retrun " + this.returnType + ". ");
|
||||||
result.type = codeBlock.returnType;
|
result.type = codeBlock.returnType;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Class;
|
package abstractSyntaxTree.Class;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
@ -34,14 +35,14 @@ public class RefType extends AbstractType implements Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
// check if field with the same identifier is defined more than once
|
// check if field with the same identifier is defined more than once
|
||||||
List<String> discoveredFieldIdentifiers = new ArrayList<>();
|
List<String> discoveredFieldIdentifiers = new ArrayList<>();
|
||||||
for (FieldDecl fieldDecl : fieldDecls) {
|
for (FieldDecl fieldDecl : fieldDecls) {
|
||||||
if(discoveredFieldIdentifiers.contains(fieldDecl.identifier)){
|
if(discoveredFieldIdentifiers.contains(fieldDecl.identifier)){
|
||||||
throw new Exception("A field with the identifier " + fieldDecl.identifier + " was defined more than once in the same class.");
|
throw new TypeCheckException("A field with the identifier " + fieldDecl.identifier + " was defined more than once in the class " + this.name + ". ");
|
||||||
}
|
}
|
||||||
discoveredFieldIdentifiers.add(fieldDecl.identifier);
|
discoveredFieldIdentifiers.add(fieldDecl.identifier);
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ public class RefType extends AbstractType implements Node {
|
|||||||
|
|
||||||
if (discoveredMethods.containsKey(methodDecl.returnType)) {
|
if (discoveredMethods.containsKey(methodDecl.returnType)) {
|
||||||
if(discoveredMethods.get(methodDecl.returnType).equals(methodDecl.name)){
|
if(discoveredMethods.get(methodDecl.returnType).equals(methodDecl.name)){
|
||||||
throw new Exception("A method with the name " + methodDecl.name + " and return type " + methodDecl.returnType + " was defined more than once in the same class.");
|
throw new TypeCheckException("A method with the name " + methodDecl.name + " and return type " + methodDecl.returnType + " was defined more than once in the same class.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
discoveredMethods.put(methodDecl.returnType, methodDecl.name);
|
discoveredMethods.put(methodDecl.returnType, methodDecl.name);
|
||||||
|
@ -17,10 +17,10 @@ public class BoolDatatype extends AbstractType implements IDatatype{
|
|||||||
return (Objects.equals(value, boolDatatype.value));
|
return (Objects.equals(value, boolDatatype.value));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
result.type = "bool";
|
result.type = "boolean";
|
||||||
|
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -10,7 +10,7 @@ public class CharDatatype extends AbstractType implements IDatatype{
|
|||||||
char value;
|
char value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
result.type = "char";
|
result.type = "char";
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package abstractSyntaxTree.Datatype;
|
package abstractSyntaxTree.Datatype;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public interface IDatatype {
|
public interface IDatatype {
|
||||||
// typeCheck method
|
// typeCheck method
|
||||||
TypeCheckResult typeCheck() throws Exception;
|
TypeCheckResult typeCheck() throws TypeCheckException;
|
||||||
|
|
||||||
// visit method for code generation
|
// visit method for code generation
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import java.util.Objects;
|
|||||||
public class IntDatatype extends AbstractType implements IDatatype{
|
public class IntDatatype extends AbstractType implements IDatatype{
|
||||||
int value;
|
int value;
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
result.type = "int";
|
result.type = "int";
|
||||||
@ -19,9 +19,6 @@ public class IntDatatype extends AbstractType implements IDatatype{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit method for code generation
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
@ -24,7 +25,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckHelper helper = new TypeCheckHelper();
|
TypeCheckHelper helper = new TypeCheckHelper();
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unknown operator: " + operator);
|
throw new TypeCheckException("The operator " + operator + " is not known.");
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitLabel(operationFalse);
|
mv.visitLabel(operationFalse);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@ -16,9 +17,9 @@ public class BooleanConstantExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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) {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = "bool";
|
result.type = "boolean";
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public class CharConstantExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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) {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = "char";
|
result.type = "char";
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
@ -11,7 +12,7 @@ import java.util.LinkedHashMap;
|
|||||||
public interface IExpression extends Node {
|
public interface IExpression extends Node {
|
||||||
// typeCheck method
|
// typeCheck method
|
||||||
//TypeCheckResult typeCheck() throws Exception;
|
//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 Exception;
|
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
|
// visit method for code generation
|
||||||
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
|
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Class.RefType;
|
import abstractSyntaxTree.Class.RefType;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
@ -30,10 +31,11 @@ public class InstVarExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
|
|
||||||
//todo ///////////////////
|
|
||||||
String varType = typeContext.get(classRef.name).get(fieldName);
|
String varType = typeContext.get(classRef.name).get(fieldName);
|
||||||
|
if (varType == null) {
|
||||||
|
throw new TypeCheckException("Field " + fieldName + " was not found in class " + classRef.name + ".");
|
||||||
|
}
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = varType;
|
result.type = varType;
|
||||||
return result;
|
return result;
|
||||||
|
@ -18,7 +18,7 @@ public class IntConstantExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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) {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = "int";
|
result.type = "int";
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
@ -25,12 +26,12 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
if (localVars.containsKey(identifier)) {
|
if (localVars.containsKey(identifier)) {
|
||||||
result.type = localVars.get(identifier);
|
result.type = localVars.get(identifier);
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("TypeCheck Exception: Local var " + identifier + " does not exist.");
|
throw new TypeCheckException("Local var " + identifier + " does not exist.");
|
||||||
}
|
}
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Datatype.IDatatype;
|
import abstractSyntaxTree.Datatype.IDatatype;
|
||||||
@ -20,7 +21,7 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
this.operand = operand;
|
this.operand = operand;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult operandTypeCheckResult = operand.typeCheck();
|
TypeCheckResult operandTypeCheckResult = operand.typeCheck();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree;
|
package abstractSyntaxTree;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
import abstractSyntaxTree.Class.MethodDecl;
|
import abstractSyntaxTree.Class.MethodDecl;
|
||||||
@ -27,7 +28,7 @@ public class Program implements Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TypeCheckResult typeCheck() throws Exception{
|
public TypeCheckResult typeCheck() throws TypeCheckException {
|
||||||
this.typeContext = new HashMap<>();
|
this.typeContext = new HashMap<>();
|
||||||
this.methodContext = new HashMap<>();
|
this.methodContext = new HashMap<>();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
@ -28,7 +29,7 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
|
||||||
HashMap<String, HashMap<String, String>> typeContext,
|
HashMap<String, HashMap<String, String>> typeContext,
|
||||||
HashMap<String, String> localVars) throws Exception {
|
HashMap<String, String> localVars) throws TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
this.localVars = localVars;
|
this.localVars = localVars;
|
||||||
@ -54,10 +55,10 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
|
|
||||||
if (!firstType.equals(this.returnType) || !firstType.equals(this.returnType)) {
|
if (!firstType.equals(this.returnType) || !firstType.equals(this.returnType)) {
|
||||||
if (!firstType.equals("void") && this.returnType != null) {
|
if (!firstType.equals("void") && this.returnType != null) {
|
||||||
throw new Exception("TypeCheck Exception: if paths return wrong type");
|
throw new TypeCheckException("The if-Path returns the wrong type.");
|
||||||
}
|
}
|
||||||
if (!secondType.equals("void") && this.returnType != null) {
|
if (!secondType.equals("void") && this.returnType != null) {
|
||||||
throw new Exception("TypeCheck Exception: else paths return wrong type");
|
throw new TypeCheckException("The else-path returns the wrong type.");
|
||||||
}
|
}
|
||||||
boolean firstIsVoid = firstType.equals("void");
|
boolean firstIsVoid = firstType.equals("void");
|
||||||
|
|
||||||
@ -78,11 +79,9 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
this.returnType = typeOfCurrentStatement.type;
|
this.returnType = typeOfCurrentStatement.type;
|
||||||
|
|
||||||
if (!typeOfCurrentStatement.type.equals(this.returnType))
|
if (!typeOfCurrentStatement.type.equals(this.returnType))
|
||||||
throw new Exception("TypeCheck Exception: Block returns the wrong type.");
|
throw new TypeCheckException("At least some statements of the block returns the wrong type or missing return statement.");
|
||||||
}
|
}
|
||||||
result.type = this.returnType;
|
result.type = this.returnType;
|
||||||
// todo check if the block returns the needed return type in every case
|
|
||||||
// todo ignore unreachable statements?
|
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import java.util.Objects;
|
|||||||
public class EmptyStatement extends AbstractType implements IStatement{
|
public class EmptyStatement extends AbstractType implements IStatement{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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) {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = "void";
|
result.type = "void";
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
@ -11,7 +12,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(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException;
|
||||||
|
|
||||||
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
|
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
|
||||||
TypeCheckResult getTypeCheckResult();
|
TypeCheckResult getTypeCheckResult();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -24,13 +25,13 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
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("should be boolean");
|
throw new TypeCheckException("The condition of a if statement is " + conditionType.type + ", but should be boolean.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
|
||||||
@ -38,7 +39,7 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
|
|
||||||
if (!ifStatementType.type.equals(elseStatementType.type)) {
|
if (!ifStatementType.type.equals(elseStatementType.type)) {
|
||||||
if(ifStatementType.type != "void" && elseStatementType.type != "void")
|
if(ifStatementType.type != "void" && elseStatementType.type != "void")
|
||||||
throw new IllegalArgumentException("TypeCeck Exception: if and else have different types");
|
throw new TypeCheckException("If- and else-path return different not-void types.");
|
||||||
}
|
}
|
||||||
|
|
||||||
result.type = ifStatementType.type + "," + elseStatementType.type;
|
result.type = ifStatementType.type + "," + elseStatementType.type;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -23,13 +24,13 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
|
||||||
if (!conditionType.equals("bool")) {
|
if (!conditionType.type.equals("boolean")) {
|
||||||
throw new Exception("TypeCheck Exception: Condition of If-Statement should be bool.");
|
throw new TypeCheckException("Condition of If-Statement should is " + conditionType.type + ", but should be boolean.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
@ -17,7 +18,7 @@ public class LocalVarDecl extends AbstractType implements IStatement{
|
|||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckHelper.typeExists(this.type, new ArrayList<>(methodContext.keySet()));
|
TypeCheckHelper.typeExists(this.type, new ArrayList<>(methodContext.keySet()));
|
||||||
|
|
||||||
localVars.put(this.identifier, this.type);
|
localVars.put(this.identifier, this.type);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -19,7 +20,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
@ -45,7 +46,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
//TODO: Resolve how do we get the type of the expression
|
//TODO: Resolve how do we get the type of the expression
|
||||||
String type = expression.getTypeCheckResult().type;
|
String type = expression.getTypeCheckResult().type;
|
||||||
|
|
||||||
if (type.equals("int") || type.equals("bool") || type.equals("char")) {
|
if (type.equals("int") || type.equals("boolean") || type.equals("char")) {
|
||||||
mv.visitInsn(Opcodes.IRETURN);
|
mv.visitInsn(Opcodes.IRETURN);
|
||||||
} else {
|
} else {
|
||||||
mv.visitInsn(Opcodes.ARETURN);
|
mv.visitInsn(Opcodes.ARETURN);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -21,12 +22,12 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
// check condition
|
// check condition
|
||||||
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
|
||||||
if (!conditionType.equals("bool")) {
|
if (!conditionType.type.equals("boolean")) {
|
||||||
throw new IllegalArgumentException("Expected boolean");
|
throw new IllegalArgumentException("Expected boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.StatementExpression;
|
package abstractSyntaxTree.StatementExpression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -28,7 +29,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
TypeCheckHelper helper = new TypeCheckHelper();
|
TypeCheckHelper helper = new TypeCheckHelper();
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
if(Objects.equals(leftType.type, "boolean"))
|
if(Objects.equals(leftType.type, "boolean"))
|
||||||
leftType.type = "bool";
|
leftType.type = "bool";
|
||||||
if (!Objects.equals(upperbound, leftType.type)) {
|
if (!Objects.equals(upperbound, leftType.type)) {
|
||||||
throw new Exception("TypeCheck Exception: upper bound of assignment is not left type");
|
throw new TypeCheckException("The upper bound of assignment is not the left type.");
|
||||||
}
|
}
|
||||||
result.type = "void";
|
result.type = "void";
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package abstractSyntaxTree.StatementExpression;
|
package abstractSyntaxTree.StatementExpression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
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.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@ -28,7 +30,8 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
@Override
|
||||||
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
RefType searchMethodHere;
|
RefType searchMethodHere;
|
||||||
@ -41,18 +44,12 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
List<MethodDecl> methods = searchMethodHere.methodDecls;
|
List<MethodDecl> methods = searchMethodHere.methodDecls;
|
||||||
|
|
||||||
if(!methods.contains(methodName)){
|
if(!methods.contains(methodName)){
|
||||||
throw new Exception("method not found");
|
throw new TypeCheckException("The method " + methodName + " is called, but does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Errors occur due to the change in parameter in the RefType class
|
//Errors occur due to the change in parameter in the RefType class
|
||||||
// I need the methodContext here to get the method descriptor
|
// I need the methodContext here to get the method descriptor
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package abstractSyntaxTree.StatementExpression;
|
package abstractSyntaxTree.StatementExpression;
|
||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
@ -26,14 +27,16 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> 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 TypeCheckException {
|
||||||
|
//todo testen wenn in ast vorhanden
|
||||||
if(!TypeCheckHelper.typeExists(className, new ArrayList<>(typeContext.keySet()))){
|
if(!TypeCheckHelper.typeExists(className, new ArrayList<>(typeContext.keySet()))){
|
||||||
throw new Exception("TypeCheck Exception: An instance of " + className + " is created, but the type does not exist.");
|
throw new TypeCheckException("An instance of " + className + " is created, but the type does not exist.");
|
||||||
}
|
}
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
result.type = className;
|
result.type = className;
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
package abstractSyntaxTree.StatementExpression;
|
package abstractSyntaxTree.StatementExpression;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckException;
|
||||||
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
import abstractSyntaxTree.Expression.InstVarExpression;
|
import abstractSyntaxTree.Expression.InstVarExpression;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
public class Receiver implements Node {
|
public class Receiver implements Node {
|
||||||
boolean thisExpression;
|
boolean thisExpression;
|
||||||
@ -24,6 +33,7 @@ public class Receiver implements Node {
|
|||||||
public Receiver(String identifier) {
|
public Receiver(String identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user