moved tables out of constructor and fixed some type check

This commit is contained in:
Krauß, Josefine 2024-05-09 16:49:53 +02:00
parent 85282ff90c
commit 9ec583b17f
8 changed files with 64 additions and 48 deletions

View File

@ -25,7 +25,7 @@ public class Compiler {
// String content = new String(Files.readAllBytes(Paths.get(filePath)));
// CharArrayReader charStream = new CharArrayReader(content.toCharArray());
CharStream codeCharStream = CharStreams.fromString("class Example { }");
CharStream codeCharStream = CharStreams.fromString("class Example { int i; }");
DecafLexer lexer = new DecafLexer(codeCharStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
@ -36,7 +36,7 @@ public class Compiler {
StringBuilder stringBuilder = new StringBuilder();
for (Token token : tokenList) {
stringBuilder.append(token.toString()).append(" ");
stringBuilder.append(token.getText()).append(" ");
}
String readableTokens = stringBuilder.toString().trim();
@ -53,9 +53,6 @@ public class Compiler {
Program abstractSyntaxTree = new Program(new ArrayList<>());
List<FieldDecl> emptyFieldDecl = new ArrayList<>();
List<MethodDecl> emptyMethodDecl = new ArrayList<>();
abstractSyntaxTree.classes.add(new RefType(emptyFieldDecl, emptyMethodDecl, null, null, "MyClass"));
abstractSyntaxTree.typeCheck();

View File

@ -1,2 +1,3 @@
class EmptyClass {
}

View File

@ -21,12 +21,12 @@ public class TypeCheckHelper {
}
return result;
}
public static boolean typeExists(String type, List<String> typeslist) {
public static boolean typeExists(String type, List<String> customTypeslist) {
if(type.equals("int") || type.equals("bool") || type.equals("char")){
return true;
}
return typeslist.contains(type);
return customTypeslist.contains(type);
}
}

View File

@ -12,21 +12,19 @@ import java.util.List;
public class FieldDecl extends AbstractType implements IClass{
private HashMap<String, HashMap<String, String>> typeContext; // form class from program
public String type; // from parser
public String identifier; // from parser
public FieldDecl(HashMap<String, HashMap<String, String>> typeContext){
this.typeContext = typeContext;
public FieldDecl(String type, String identifier){
this.type = type;
this.identifier = identifier;
}
public TypeCheckResult typeCheck(List<FieldDecl> classFieldsIdentifier) throws Exception {
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, String>> typeContext) throws Exception {
TypeCheckResult result = new TypeCheckResult();
if (classFieldsIdentifier.contains(this.identifier)){
throw new Exception("field already defined");
} else {
classFieldsIdentifier.add(this);
}
//TypeCheckHelper.typeExists(type, ) // need all types of classes
TypeCheckHelper.typeExists(this.type, typeContext.keySet().stream().toList());
result.type = this.type;
setTypeCheckResult(result);
return result;
@ -34,7 +32,6 @@ public class FieldDecl extends AbstractType implements IClass{
//write field table
}
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<MethodDecl> fieldsOrMethods) throws Exception {
return null;
}

View File

@ -10,7 +10,6 @@ import java.util.List;
public interface IClass {
// visit method for code generation
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<MethodDecl> fieldsOrMethods) throws Exception;
void codeGen(ClassWriter cw) throws Exception;
}

View File

@ -2,6 +2,7 @@ package abstractSyntaxTree.Class;
import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Program;
import abstractSyntaxTree.Statement.IStatement;
import org.objectweb.asm.ClassWriter;
import java.util.HashMap;
@ -13,15 +14,20 @@ public class MethodDecl implements IClass {
public String name;
public List<String> parameters;
public String returnType;
public List<IStatement> codeBlock;
// save localvars
//TODO: Move this into the typeCheck
private HashMap<String, String> localVars; // (type, identifier) // add content here
public MethodDecl(String classThatContainsMethod, String returnType, String name, List<String> parameters, List<IStatement> codeBlock){
this.classThatContainsMethod = classThatContainsMethod;
this.returnType = returnType;
this.name = name;
this.parameters = parameters;
this.codeBlock = codeBlock;
}
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<MethodDecl> fieldsOrMethods) throws Exception {
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
// write localvars
// jede methode als block statement aufrufen
return null;
}

View File

@ -2,15 +2,10 @@ package abstractSyntaxTree.Class;
import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Class.FieldDecl;
import abstractSyntaxTree.Class.MethodDecl;
import abstractSyntaxTree.Datatype.IDatatype;
import abstractSyntaxTree.Program;
import jdk.jshell.spi.ExecutionControl;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -19,37 +14,56 @@ public class RefType extends AbstractType implements IClass {
public String name;
public List<FieldDecl> fieldDecls;
public List<MethodDecl> methodDecls;
private HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
public HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext; // (class, (returntype, (identifier, parameter)))
private boolean hasMain;
public RefType(List<FieldDecl> fieldDecls,
public RefType(String name,
List<FieldDecl> fieldDecls,
List<MethodDecl> methodDecls,
HashMap<String, HashMap<String, String>> typeContext,
HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, String name){
boolean hasMain
){
this.name = name;
this.fieldDecls = fieldDecls;
this.methodDecls = methodDecls;
this.typeContext = typeContext;
this.methodContext = methodContext;
this.hasMain = hasMain;
}
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext,
HashMap<String, HashMap<String, String>> typeContext, List<MethodDecl> fieldsOrMethods) throws Exception {
HashMap<String, HashMap<String, String>> typeContext) throws Exception {
TypeCheckResult result = new TypeCheckResult();
// check if field with the same identifier is defined more than once
List<String> discoveredFieldIdentifiers = new ArrayList<>();
for (FieldDecl fieldDecl : fieldDecls) {
fieldDecl.typeCheck(fieldDecls);
if(discoveredFieldIdentifiers.contains(fieldDecl.identifier)){
throw new Exception("A field with the identifier " + fieldDecl.identifier + " was defined more than once in the same class.");
}
discoveredFieldIdentifiers.add(fieldDecl.identifier);
}
// typecheck each field
for (FieldDecl fieldDecl : fieldDecls) {
fieldDecl.typeCheck(typeContext);
}
// check if any methods have the same name and return type (overloaded methods are not allowed here)
HashMap<String, String> discoveredMethods = new HashMap<>(); // returntype, identifier
for (MethodDecl methodDecl : methodDecls) {
methodDecl.typeCheck(methodContext, typeContext, methodDecls);
if (discoveredMethods.containsKey(methodDecl.returnType)) {
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.");
}
}
discoveredMethods.put(methodDecl.returnType, methodDecl.name);
}
result.type = "class";
// type check each method
for (MethodDecl methodDecl : methodDecls) {
methodDecl.typeCheck(methodContext, typeContext);
}
result.type = this.name;
setTypeCheckResult(result);
return result;
}

View File

@ -23,13 +23,15 @@ public class Program {
public Program(List<RefType> classes){
this.classes = classes;
this.typeContext = new HashMap<>();
this.methodContext = new HashMap<>();
}
public TypeCheckResult typeCheck() throws Exception{
for(RefType oneClass : classes){
// build type context
this.typeContext = new HashMap<>();
HashMap<String, String> classVars = new HashMap<>();
for (FieldDecl fieldDecl: oneClass.fieldDecls){
classVars.put(fieldDecl.type, fieldDecl.identifier);
@ -42,10 +44,10 @@ public class Program {
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
}
this.methodContext = new HashMap<>();
methodContext.put(oneClass.name, returnTypeAndMethod);
oneClass.typeCheck(methodContext, typeContext, oneClass.methodDecls);
oneClass.typeCheck(methodContext, typeContext);
}
return null;
}