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)));
|
// String content = new String(Files.readAllBytes(Paths.get(filePath)));
|
||||||
// CharArrayReader charStream = new CharArrayReader(content.toCharArray());
|
// 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);
|
DecafLexer lexer = new DecafLexer(codeCharStream);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ public class Compiler {
|
|||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
for (Token token : tokenList) {
|
for (Token token : tokenList) {
|
||||||
stringBuilder.append(token.toString()).append(" ");
|
stringBuilder.append(token.getText()).append(" ");
|
||||||
}
|
}
|
||||||
String readableTokens = stringBuilder.toString().trim();
|
String readableTokens = stringBuilder.toString().trim();
|
||||||
|
|
||||||
@ -53,9 +53,6 @@ public class Compiler {
|
|||||||
|
|
||||||
|
|
||||||
Program abstractSyntaxTree = new Program(new ArrayList<>());
|
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();
|
abstractSyntaxTree.typeCheck();
|
||||||
|
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
class EmptyClass {
|
class EmptyClass {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,12 @@ public class TypeCheckHelper {
|
|||||||
}
|
}
|
||||||
return result;
|
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")){
|
if(type.equals("int") || type.equals("bool") || type.equals("char")){
|
||||||
return true;
|
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{
|
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 type; // from parser
|
||||||
public String identifier; // from parser
|
public String identifier; // from parser
|
||||||
|
|
||||||
public FieldDecl(HashMap<String, HashMap<String, String>> typeContext){
|
public FieldDecl(String type, String identifier){
|
||||||
this.typeContext = typeContext;
|
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();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
if (classFieldsIdentifier.contains(this.identifier)){
|
|
||||||
throw new Exception("field already defined");
|
TypeCheckHelper.typeExists(this.type, typeContext.keySet().stream().toList());
|
||||||
} else {
|
result.type = this.type;
|
||||||
classFieldsIdentifier.add(this);
|
|
||||||
}
|
|
||||||
//TypeCheckHelper.typeExists(type, ) // need all types of classes
|
|
||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -34,7 +32,6 @@ public class FieldDecl extends AbstractType implements IClass{
|
|||||||
//write field table
|
//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 {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import java.util.List;
|
|||||||
public interface IClass {
|
public interface IClass {
|
||||||
// visit method for code generation
|
// 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;
|
void codeGen(ClassWriter cw) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package abstractSyntaxTree.Class;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Program;
|
import abstractSyntaxTree.Program;
|
||||||
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,15 +14,20 @@ public class MethodDecl implements IClass {
|
|||||||
public String name;
|
public String name;
|
||||||
public List<String> parameters;
|
public List<String> parameters;
|
||||||
public String returnType;
|
public String returnType;
|
||||||
|
public List<IStatement> codeBlock;
|
||||||
|
|
||||||
|
// save localvars
|
||||||
|
|
||||||
//TODO: Move this into the typeCheck
|
public MethodDecl(String classThatContainsMethod, String returnType, String name, List<String> parameters, List<IStatement> codeBlock){
|
||||||
private HashMap<String, String> localVars; // (type, identifier) // add content here
|
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
|
// write localvars
|
||||||
|
|
||||||
|
|
||||||
// jede methode als block statement aufrufen
|
// jede methode als block statement aufrufen
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,10 @@ package abstractSyntaxTree.Class;
|
|||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckResult;
|
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.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -19,37 +14,56 @@ public class RefType extends AbstractType implements IClass {
|
|||||||
public String name;
|
public String name;
|
||||||
public List<FieldDecl> fieldDecls;
|
public List<FieldDecl> fieldDecls;
|
||||||
public List<MethodDecl> methodDecls;
|
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;
|
private boolean hasMain;
|
||||||
|
|
||||||
public RefType(List<FieldDecl> fieldDecls,
|
public RefType(String name,
|
||||||
|
List<FieldDecl> fieldDecls,
|
||||||
List<MethodDecl> methodDecls,
|
List<MethodDecl> methodDecls,
|
||||||
HashMap<String, HashMap<String, String>> typeContext,
|
boolean hasMain
|
||||||
HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, String name){
|
){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.fieldDecls = fieldDecls;
|
this.fieldDecls = fieldDecls;
|
||||||
this.methodDecls = methodDecls;
|
this.methodDecls = methodDecls;
|
||||||
this.typeContext = typeContext;
|
this.hasMain = hasMain;
|
||||||
this.methodContext = methodContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext,
|
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();
|
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) {
|
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) {
|
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);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,15 @@ public class Program {
|
|||||||
|
|
||||||
public Program(List<RefType> classes){
|
public Program(List<RefType> classes){
|
||||||
this.classes = classes;
|
this.classes = classes;
|
||||||
this.typeContext = new HashMap<>();
|
|
||||||
this.methodContext = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TypeCheckResult typeCheck() throws Exception{
|
public TypeCheckResult typeCheck() throws Exception{
|
||||||
for(RefType oneClass : classes){
|
for(RefType oneClass : classes){
|
||||||
|
|
||||||
|
// build type context
|
||||||
|
this.typeContext = new HashMap<>();
|
||||||
|
|
||||||
HashMap<String, String> classVars = new HashMap<>();
|
HashMap<String, String> classVars = new HashMap<>();
|
||||||
for (FieldDecl fieldDecl: oneClass.fieldDecls){
|
for (FieldDecl fieldDecl: oneClass.fieldDecls){
|
||||||
classVars.put(fieldDecl.type, fieldDecl.identifier);
|
classVars.put(fieldDecl.type, fieldDecl.identifier);
|
||||||
@ -42,10 +44,10 @@ public class Program {
|
|||||||
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
|
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
|
||||||
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
||||||
}
|
}
|
||||||
|
this.methodContext = new HashMap<>();
|
||||||
methodContext.put(oneClass.name, returnTypeAndMethod);
|
methodContext.put(oneClass.name, returnTypeAndMethod);
|
||||||
|
|
||||||
oneClass.typeCheck(methodContext, typeContext, oneClass.methodDecls);
|
oneClass.typeCheck(methodContext, typeContext);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user