moved tables out of constructor and fixed some type check
This commit is contained in:
parent
85282ff90c
commit
9ec583b17f
@ -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();
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
class EmptyClass {
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user