87 lines
3.1 KiB
Java
87 lines
3.1 KiB
Java
package abstractSyntaxTree;
|
|
|
|
import TypeCheck.TypeCheckResult;
|
|
import abstractSyntaxTree.Class.FieldDecl;
|
|
import abstractSyntaxTree.Class.MethodDecl;
|
|
import org.objectweb.asm.MethodVisitor;
|
|
import abstractSyntaxTree.Class.RefType;
|
|
import org.objectweb.asm.ClassWriter;
|
|
import org.objectweb.asm.Opcodes;
|
|
|
|
import java.util.*;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.jar.JarEntry;
|
|
import java.util.jar.JarOutputStream;
|
|
|
|
public class Program {
|
|
public List<RefType> classes;
|
|
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
|
|
public HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext; // (class, (returntype, (identifier, parameter)))
|
|
|
|
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){
|
|
HashMap<String, String> classVars = new HashMap<>();
|
|
for (FieldDecl fieldDecl: oneClass.fieldDecls){
|
|
classVars.put(fieldDecl.type, fieldDecl.identifier);
|
|
}
|
|
typeContext.put(oneClass.name, classVars);
|
|
|
|
HashMap<String, List<String>> methodIdentifierAndParameter = new HashMap<>();
|
|
HashMap<String, HashMap<String, List<String >>> returnTypeAndMethod = new HashMap<>();
|
|
for (MethodDecl methodDecl : oneClass.methodDecls){
|
|
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
|
|
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
|
}
|
|
|
|
methodContext.put(oneClass.name, returnTypeAndMethod);
|
|
|
|
oneClass.typeCheck(methodContext, typeContext, oneClass.methodDecls);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void codeGen() throws Exception{
|
|
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("output.jar"))) {
|
|
for (RefType oneClass : classes) {
|
|
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
|
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null);
|
|
|
|
oneClass.codeGen(cw);
|
|
|
|
cw.visitEnd();
|
|
byte[] bytecode = cw.toByteArray();
|
|
|
|
// Write the bytecode to a .class file in the .jar file
|
|
JarEntry entry = new JarEntry(oneClass.name + ".class");
|
|
jos.putNextEntry(entry);
|
|
jos.write(bytecode);
|
|
jos.closeEntry();
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
/*
|
|
for(RefType oneClass : classes){
|
|
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
|
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC,oneClass.name, null,
|
|
"java/lang/Object", null);
|
|
oneClass.codeGen(cw);
|
|
|
|
cw.visitEnd();
|
|
byte[] bytecode = cw.toByteArray();
|
|
}
|
|
*/
|
|
}
|
|
}
|