From 9ec583b17f0859dfc9c4fb302d5832c50d7ccdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krau=C3=9F=2C=20Josefine?= Date: Thu, 9 May 2024 16:49:53 +0200 Subject: [PATCH] moved tables out of constructor and fixed some type check --- Source/Compiler.java | 7 +-- Source/EmptyClass.java | 1 + Source/TypeCheck/TypeCheckHelper.java | 4 +- .../abstractSyntaxTree/Class/FieldDecl.java | 19 +++---- Source/abstractSyntaxTree/Class/IClass.java | 1 - .../abstractSyntaxTree/Class/MethodDecl.java | 16 ++++-- Source/abstractSyntaxTree/Class/RefType.java | 54 ++++++++++++------- Source/abstractSyntaxTree/Program.java | 10 ++-- 8 files changed, 64 insertions(+), 48 deletions(-) diff --git a/Source/Compiler.java b/Source/Compiler.java index d993d97..871cc22 100644 --- a/Source/Compiler.java +++ b/Source/Compiler.java @@ -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 emptyFieldDecl = new ArrayList<>(); - List emptyMethodDecl = new ArrayList<>(); - abstractSyntaxTree.classes.add(new RefType(emptyFieldDecl, emptyMethodDecl, null, null, "MyClass")); abstractSyntaxTree.typeCheck(); diff --git a/Source/EmptyClass.java b/Source/EmptyClass.java index a3496cf..2a388fa 100644 --- a/Source/EmptyClass.java +++ b/Source/EmptyClass.java @@ -1,2 +1,3 @@ class EmptyClass { + } diff --git a/Source/TypeCheck/TypeCheckHelper.java b/Source/TypeCheck/TypeCheckHelper.java index bd4aa58..5d487d8 100644 --- a/Source/TypeCheck/TypeCheckHelper.java +++ b/Source/TypeCheck/TypeCheckHelper.java @@ -21,12 +21,12 @@ public class TypeCheckHelper { } return result; } - public static boolean typeExists(String type, List typeslist) { + public static boolean typeExists(String type, List customTypeslist) { if(type.equals("int") || type.equals("bool") || type.equals("char")){ return true; } - return typeslist.contains(type); + return customTypeslist.contains(type); } } diff --git a/Source/abstractSyntaxTree/Class/FieldDecl.java b/Source/abstractSyntaxTree/Class/FieldDecl.java index a02fb36..355a9fb 100644 --- a/Source/abstractSyntaxTree/Class/FieldDecl.java +++ b/Source/abstractSyntaxTree/Class/FieldDecl.java @@ -12,21 +12,19 @@ import java.util.List; public class FieldDecl extends AbstractType implements IClass{ - private HashMap> typeContext; // form class from program public String type; // from parser public String identifier; // from parser - public FieldDecl(HashMap> typeContext){ - this.typeContext = typeContext; + public FieldDecl(String type, String identifier){ + this.type = type; + this.identifier = identifier; } - public TypeCheckResult typeCheck(List classFieldsIdentifier) throws Exception { + public TypeCheckResult typeCheck(HashMap> 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>>> methodContext, HashMap> typeContext, List fieldsOrMethods) throws Exception { return null; } diff --git a/Source/abstractSyntaxTree/Class/IClass.java b/Source/abstractSyntaxTree/Class/IClass.java index cfd14e3..dae625a 100644 --- a/Source/abstractSyntaxTree/Class/IClass.java +++ b/Source/abstractSyntaxTree/Class/IClass.java @@ -10,7 +10,6 @@ import java.util.List; public interface IClass { // visit method for code generation - TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, List fieldsOrMethods) throws Exception; void codeGen(ClassWriter cw) throws Exception; } diff --git a/Source/abstractSyntaxTree/Class/MethodDecl.java b/Source/abstractSyntaxTree/Class/MethodDecl.java index 6e12a51..ef7181f 100644 --- a/Source/abstractSyntaxTree/Class/MethodDecl.java +++ b/Source/abstractSyntaxTree/Class/MethodDecl.java @@ -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 parameters; public String returnType; + public List codeBlock; + // save localvars - //TODO: Move this into the typeCheck - private HashMap localVars; // (type, identifier) // add content here + public MethodDecl(String classThatContainsMethod, String returnType, String name, List parameters, List codeBlock){ + this.classThatContainsMethod = classThatContainsMethod; + this.returnType = returnType; + this.name = name; + this.parameters = parameters; + this.codeBlock = codeBlock; + } - public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext, List fieldsOrMethods) throws Exception { + public TypeCheckResult typeCheck(HashMap>>> methodContext, HashMap> typeContext) throws Exception { // write localvars - - // jede methode als block statement aufrufen return null; } diff --git a/Source/abstractSyntaxTree/Class/RefType.java b/Source/abstractSyntaxTree/Class/RefType.java index 3018ec7..0b5f977 100644 --- a/Source/abstractSyntaxTree/Class/RefType.java +++ b/Source/abstractSyntaxTree/Class/RefType.java @@ -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 fieldDecls; public List methodDecls; - private HashMap> typeContext; // (class, (type, identifier)) - public HashMap>>> methodContext; // (class, (returntype, (identifier, parameter))) private boolean hasMain; - public RefType(List fieldDecls, + public RefType(String name, + List fieldDecls, List methodDecls, - HashMap> typeContext, - HashMap>>> 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>>> methodContext, - HashMap> typeContext, List fieldsOrMethods) throws Exception { + HashMap> typeContext) throws Exception { TypeCheckResult result = new TypeCheckResult(); + // check if field with the same identifier is defined more than once + List 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 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; } diff --git a/Source/abstractSyntaxTree/Program.java b/Source/abstractSyntaxTree/Program.java index 659ad47..792d689 100644 --- a/Source/abstractSyntaxTree/Program.java +++ b/Source/abstractSyntaxTree/Program.java @@ -23,13 +23,15 @@ public class Program { public Program(List 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 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; }