mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-27 07:18:03 +00:00
Merge branch 'refs/heads/main' into testsuites
This commit is contained in:
commit
a3990ebbcd
@ -11,7 +11,7 @@
|
||||
- Laura Schleicher: Grammatik entwickeln, Records, Statements als Liste zurückgeben, Generator, Syntactic Sugar auflösen
|
||||
- Julian Kraus: Grammatik entwickeln, Generator, Syntactic Sugar auflösen, Parser Exceptions sammeln
|
||||
- Ahmad Juha: Typcheck
|
||||
- Simon Wittmann: Codegen und Tool für ASM
|
||||
- Simon Wittmann: Codegen, Logging, CommandLine Nutzung
|
||||
- Jonathan Fleischmann:
|
||||
- Schreiben von Tests, die die einzelnen Features abdecken
|
||||
- Umwandlung der Testfiles in AST und TypedAST
|
||||
|
@ -5,6 +5,7 @@ import de.maishai.antlr.DecafParser;
|
||||
import de.maishai.ast.records.Class;
|
||||
import de.maishai.ast.records.Program;
|
||||
import de.maishai.typedast.CodeGenUtils;
|
||||
import de.maishai.typedast.MethodContext;
|
||||
import de.maishai.typedast.typedclass.TypedClass;
|
||||
import de.maishai.typedast.typedclass.TypedProgram;
|
||||
import org.antlr.v4.runtime.*;
|
||||
@ -13,6 +14,8 @@ import org.apache.commons.cli.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -21,11 +24,11 @@ public class Compiler {
|
||||
private static final String JAVA_FILE_EXTENSION = ".java";
|
||||
private static final Logger LOGGER = Logger.getLogger(Compiler.class.getName());
|
||||
|
||||
public static Program generateAST(List<String> fromSources) {
|
||||
public static Program generateAST(List<String> sourcePaths) {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
CollectingErrorListener errorListener = new CollectingErrorListener();
|
||||
for (String fromSource : fromSources) {
|
||||
CharStream input = CharStreams.fromString(fromSource);
|
||||
for (String sourcePath : sourcePaths) {
|
||||
CharStream input = CharStreams.fromString(sourcePath);
|
||||
|
||||
DecafLexer lexer = new DecafLexer(input);
|
||||
//add custom error listener
|
||||
@ -109,7 +112,12 @@ public class Compiler {
|
||||
Logger rootLog = Logger.getLogger("");
|
||||
rootLog.setLevel( Level.FINEST );
|
||||
rootLog.getHandlers()[0].setLevel( Level.FINEST );
|
||||
LOGGER.finest("Debug logging enabled");
|
||||
Formatter logFormatter = new LogFormatter();
|
||||
for (Handler handler : rootLog.getHandlers()) {
|
||||
handler.setFormatter(logFormatter);
|
||||
}
|
||||
MethodContext.DEBUG = true;
|
||||
LOGGER.info("Debug logging enabled");
|
||||
}
|
||||
|
||||
if (cmd.getArgs().length == 0) {
|
||||
|
18
src/main/java/de/maishai/LogFormatter.java
Normal file
18
src/main/java/de/maishai/LogFormatter.java
Normal file
@ -0,0 +1,18 @@
|
||||
package de.maishai;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
public class LogFormatter extends Formatter {
|
||||
@Override
|
||||
public String format(LogRecord logRecord) {
|
||||
String formattedMessage = MessageFormat.format(logRecord.getMessage(), logRecord.getParameters());
|
||||
|
||||
if (logRecord.getLevel() == Level.FINEST) {
|
||||
return formattedMessage + "\n";
|
||||
}
|
||||
return logRecord.getLevel() + ": " + formattedMessage + "\n";
|
||||
}
|
||||
}
|
@ -6,14 +6,16 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class LoggingMethodVisitor extends MethodVisitor {
|
||||
private static final Logger LOGGER = Logger.getLogger(LoggingMethodVisitor.class.getName());
|
||||
private final Map<Label, String> labelNames = new HashMap<>();
|
||||
private int labelCounter = 0;
|
||||
|
||||
public LoggingMethodVisitor(MethodVisitor methodVisitor) {
|
||||
super(Opcodes.ASM9, methodVisitor);
|
||||
System.out.println("\n--- Visiting Method ---");
|
||||
}
|
||||
|
||||
private String getLabelName(Label label) {
|
||||
@ -22,7 +24,7 @@ public class LoggingMethodVisitor extends MethodVisitor {
|
||||
|
||||
@Override
|
||||
public void visitJumpInsn(int opcode, Label label) {
|
||||
System.out.println("visitJumpInsn: " + opcodeToString(opcode) + ", " + getLabelName(label));
|
||||
LOGGER.log(Level.FINEST, "visitJumpInsn: {0}, {1}", new Object[]{opcodeToString(opcode), getLabelName(label)});
|
||||
super.visitJumpInsn(opcode, label);
|
||||
}
|
||||
|
||||
@ -41,63 +43,63 @@ public class LoggingMethodVisitor extends MethodVisitor {
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
|
||||
System.out.println("visitMethodInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor + ", " + isInterface);
|
||||
LOGGER.log(Level.FINEST, "visitMethodInsn: {0}, {1}, {2}, {3}, {4}", new Object[]{opcodeToString(opcode), owner, name, descriptor, isInterface});
|
||||
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVarInsn(int opcode, int varIndex) {
|
||||
System.out.println("visitVarInsn: " + opcodeToString(opcode) + ", " + varIndex);
|
||||
LOGGER.log(Level.FINEST, "visitVarInsn: {0}, {1}", new Object[]{opcodeToString(opcode), varIndex});
|
||||
super.visitVarInsn(opcode, varIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeInsn(int opcode, String type) {
|
||||
System.out.println("visitTypeInsn: " + opcodeToString(opcode) + ", " + type);
|
||||
LOGGER.log(Level.FINEST, "visitTypeInsn: {0}, {1}", new Object[]{opcodeToString(opcode), type});
|
||||
super.visitTypeInsn(opcode, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInsn(int opcode) {
|
||||
System.out.println("visitInsn: " + opcodeToString(opcode));
|
||||
LOGGER.log(Level.FINEST, "visitInsn: {0}", opcodeToString(opcode));
|
||||
super.visitInsn(opcode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
|
||||
System.out.println("visitMethodInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor);
|
||||
LOGGER.log(Level.FINEST, "visitMethodInsn: {0}, {1}, {2}, {3}", new Object[]{opcodeToString(opcode), owner, name, descriptor});
|
||||
super.visitMethodInsn(opcode, owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
|
||||
System.out.println("visitFieldInsn: " + opcodeToString(opcode) + ", " + owner + ", " + name + ", " + descriptor);
|
||||
LOGGER.log(Level.FINEST, "visitFieldInsn: {0}, {1}, {2}, {3}", new Object[]{opcodeToString(opcode), owner, name, descriptor});
|
||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMaxs(int maxStack, int maxLocals) {
|
||||
System.out.println("visitMaxs: " + maxStack + ", " + maxLocals);
|
||||
LOGGER.log(Level.FINEST, "visitMaxs: {0}, {1}", new Object[]{maxStack, maxLocals});
|
||||
super.visitMaxs(maxStack, maxLocals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitIntInsn(int opcode, int operand) {
|
||||
String opcodeString = opcode == Opcodes.BIPUSH ? "BIPUSH" : "SIPUSH";
|
||||
System.out.println("visitIntInsn: " + opcodeString + ", " + operand);
|
||||
LOGGER.log(Level.FINEST, "visitIntInsn: {0}, {1}", new Object[]{opcodeString, operand});
|
||||
super.visitIntInsn(opcode, operand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLabel(Label label) {
|
||||
String labelName = getLabelName(label);
|
||||
System.out.println("visitLabel: " + labelName);
|
||||
LOGGER.log(Level.FINEST, "visitLabel: {0}", labelName);
|
||||
super.visitLabel(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object value) {
|
||||
System.out.println("visitLdcInsn: " + value);
|
||||
LOGGER.log(Level.FINEST, "visitLdcInsn: {0}", value);
|
||||
super.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import java.util.logging.Logger;
|
||||
@Getter
|
||||
public class MethodContext {
|
||||
private static final Logger LOGGER = Logger.getLogger(MethodContext.class.getName());
|
||||
public static boolean DEBUG = false;
|
||||
public record LocalVariable(String name, int index, Type type) {
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ public class MethodContext {
|
||||
private final Deque<Label> continueLabels = new ArrayDeque<>();
|
||||
|
||||
public MethodContext(ClassContext classContext, MethodVisitor mv, Type returnType) {
|
||||
if (Objects.equals(System.getenv("DEBUG"), "true")) {
|
||||
if (DEBUG) {
|
||||
this.mv = new LoggingMethodVisitor(mv);
|
||||
} else {
|
||||
this.mv = mv;
|
||||
|
@ -10,7 +10,6 @@ import lombok.Data;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static de.maishai.typedast.Util.TypedExpressionUtil.convertExpression;
|
||||
@ -28,7 +27,7 @@ public class TypedAssignment implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
|
||||
private void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
|
||||
value = convertExpression(typedProgram, untyped.value());
|
||||
location = new TypedFieldVarAccess(typedProgram, untyped.location());
|
||||
}
|
||||
@ -37,7 +36,7 @@ public class TypedAssignment implements TypedStatement {
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
|
||||
if (currentClass.isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null) {
|
||||
if (Boolean.TRUE.equals(currentClass.isCurrentMainMethodPresent() && location.getField()) && location.getRecursiveOwnerChain() == null) {
|
||||
throw new RuntimeException("Main Method, is not allowed to have fields, they are not static");
|
||||
}
|
||||
|
||||
@ -107,7 +106,6 @@ public class TypedAssignment implements TypedStatement {
|
||||
receiver = location.getRecursiveOwnerChain().getType().getReference();
|
||||
}
|
||||
ctx.getMv().visitFieldInsn(Opcodes.PUTFIELD, receiver, location.getName(), value.getType().getDescriptor());
|
||||
LOGGER.log(Level.FINEST, "PUTFIELD: {0} {1} {2}", new Object[]{receiver, location.getName(), value.getType().getDescriptor()});
|
||||
ctx.popStack();
|
||||
} else {
|
||||
Optional<MethodContext.LocalVariable> localVariableOptional = ctx.getLocalVar(location.getName());
|
||||
@ -117,10 +115,8 @@ public class TypedAssignment implements TypedStatement {
|
||||
}
|
||||
MethodContext.LocalVariable localVariable = localVariableOptional.get();
|
||||
if (value.getType().getKind() == Type.Kind.REFERENCE) {
|
||||
LOGGER.finest("ASTORE " + localVariable.index());
|
||||
ctx.getMv().visitVarInsn(Opcodes.ASTORE, localVariable.index());
|
||||
} else {
|
||||
LOGGER.finest("ISTORE " + localVariable.index());
|
||||
ctx.getMv().visitVarInsn(Opcodes.ISTORE, localVariable.index());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class TypedBinary implements TypedExpression {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
|
||||
private void convertToTypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
|
||||
left = convertExpression(typedProgram, unTypedBinary.left());
|
||||
right = convertExpression(typedProgram, unTypedBinary.right());
|
||||
op = unTypedBinary.op();
|
||||
|
@ -31,7 +31,7 @@ public class TypedBlock implements TypedNode {
|
||||
this.stmts = stmts;
|
||||
}
|
||||
|
||||
public void convertToTypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
|
||||
private void convertToTypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
|
||||
|
||||
if (unTypedBlock == null) {
|
||||
return;
|
||||
|
@ -21,7 +21,7 @@ public class TypedBoolLiteral implements TypedExpression {
|
||||
convertToTypedBoolLiteral(unTypedBoolLiteral);
|
||||
}
|
||||
|
||||
public void convertToTypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
|
||||
private void convertToTypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
|
||||
value = unTypedBoolLiteral.value();
|
||||
type = Type.BOOL;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class TypedCharLiteral implements TypedExpression {
|
||||
convertToCharLiteral(unTypedCharLiteral);
|
||||
}
|
||||
|
||||
public void convertToCharLiteral(CharLiteral unTypedCharLiteral) {
|
||||
private void convertToCharLiteral(CharLiteral unTypedCharLiteral) {
|
||||
value = unTypedCharLiteral.value();
|
||||
type = Type.CHAR;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class TypedClass implements TypedNode {
|
||||
typedDeclarations.add(new TypedDeclaration(typedProgram, declaration));
|
||||
}
|
||||
for (Constructor constructor : c.constructors()) {
|
||||
typedConstructors.add(new TypedConstructor(typedProgram, constructor, this.className));
|
||||
typedConstructors.add(new TypedConstructor(constructor, this.className));
|
||||
}
|
||||
|
||||
for (Method method : c.methods()) {
|
||||
|
@ -32,28 +32,33 @@ public class TypedConstructor implements TypedNode {
|
||||
this.typedParameters = typedParameters;
|
||||
this.typedBlock = typedBlock;
|
||||
}
|
||||
public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor, String className) {
|
||||
convertToTypedConstructor(typedProgram, unTypedConstructor, className);
|
||||
public TypedConstructor(Constructor unTypedConstructor, String className) {
|
||||
convertToTypedConstructor(unTypedConstructor, className);
|
||||
}
|
||||
|
||||
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor, String className) {
|
||||
private void convertToTypedConstructor(Constructor unTypedConstructor, String className) {
|
||||
if(!unTypedConstructor.className().equals(className)) {
|
||||
throw new RuntimeException("Constructor name "+ unTypedConstructor.className() +" must be the same as class name" + className);
|
||||
}
|
||||
name = unTypedConstructor.className();
|
||||
convertToTypedParameter(typedProgram, unTypedConstructor.params());
|
||||
convertToTypedParameter(unTypedConstructor.params());
|
||||
type = Type.VOID;
|
||||
}
|
||||
|
||||
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
|
||||
private void convertToTypedParameter(List<Parameter> params) {
|
||||
for (Parameter param : params) {
|
||||
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
|
||||
TypedParameter typedParameter = new TypedParameter(param);
|
||||
checkIfParameterExists(typedParameter.getParaName());
|
||||
typedParameters.add(typedParameter);
|
||||
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
||||
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
type = typedBlock.typeCheck(typedProgram);
|
||||
@ -64,8 +69,6 @@ public class TypedConstructor implements TypedNode {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isLocalVariablePresent(String localVarName) {
|
||||
return localVariables.stream().anyMatch(localVariable -> localVariable.getName().equals(localVarName));
|
||||
}
|
||||
@ -88,11 +91,6 @@ public class TypedConstructor implements TypedNode {
|
||||
}
|
||||
}
|
||||
|
||||
public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
||||
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void deleteLocalVariableInConstructor(String localVarName) {
|
||||
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
|
||||
}
|
||||
@ -108,7 +106,6 @@ public class TypedConstructor implements TypedNode {
|
||||
//super();
|
||||
mctx.pushStack("this");
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", CONSTRUCTOR_METHOD_NAME, "()V", false);
|
||||
LOGGER.finest("INVOKESPECIAL: " + "java/lang/Object" + " " + CONSTRUCTOR_METHOD_NAME + " " + "()V");
|
||||
mctx.popStack();
|
||||
|
||||
typedBlock.codeGen(mctx);
|
||||
|
@ -19,22 +19,20 @@ public final class TypedDeclaration implements TypedNode {
|
||||
|
||||
public TypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
|
||||
convertToTypedDeclaration(typedProgram, declaration);
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
|
||||
private void convertToTypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
|
||||
name = declaration.name();
|
||||
type = declaration.type();
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
|
||||
if (type.getReference() != null && !currentClass.getClassName().equals(type.getReference())) {
|
||||
if (!typedProgram.isTypedClassPresent(type.getReference())) {
|
||||
if (type.getReference() != null && !currentClass.getClassName().equals(type.getReference()) && !typedProgram.isTypedClassPresent(type.getReference())) {
|
||||
throw new RuntimeException("Type " + type.getReference() + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
if (currentClass.isThereField(name)) {
|
||||
|
@ -21,7 +21,7 @@ public class TypedDoWhile implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
|
||||
private void convertToTypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
|
||||
typedBlock = new TypedBlock(typedProgram, unTypedDoWhile.block());
|
||||
cond = convertExpression(typedProgram, unTypedDoWhile.cond());
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class TypedFieldVarAccess implements TypedExpression {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
|
||||
private void convertToTypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
|
||||
field = unTypedFieldVarAccess.field();
|
||||
recursiveOwnerChain = convertExpression(typedProgram, unTypedFieldVarAccess.recursiveOwnerChain());
|
||||
name = unTypedFieldVarAccess.id();
|
||||
@ -163,13 +163,11 @@ public class TypedFieldVarAccess implements TypedExpression {
|
||||
int loadOpcode = type.getKind() == Type.Kind.REFERENCE ? Opcodes.ALOAD : Opcodes.ILOAD;
|
||||
Optional<MethodContext.LocalVariable> localVariableOptional = ctx.getLocalVar(name);
|
||||
if (localVariableOptional.isEmpty()) {
|
||||
LOGGER.log(Level.FINEST, "Variable {0} not declared", name);
|
||||
LOGGER.log(Level.SEVERE, "Variable {0} not declared", name);
|
||||
return;
|
||||
}
|
||||
MethodContext.LocalVariable localVariable = localVariableOptional.get();
|
||||
ctx.getMv().visitVarInsn(loadOpcode, localVariable.index());
|
||||
String opcode = loadOpcode == Opcodes.ALOAD ? "ALOAD " : "ILOAD ";
|
||||
LOGGER.log(Level.FINEST, "{0} {1}", new Object[]{opcode, localVariable.index()});
|
||||
}
|
||||
ctx.pushAnonToStack();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class TypedFor implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedFor(TypedProgram typedProgram, For unTypedFor) {
|
||||
private void convertToTypedFor(TypedProgram typedProgram, For unTypedFor) {
|
||||
assign = new TypedAssignment(typedProgram, unTypedFor.assign());
|
||||
cond = convertExpression(typedProgram, unTypedFor.cond());
|
||||
inc = new TypedAssignment(typedProgram, unTypedFor.inc());
|
||||
|
@ -24,7 +24,7 @@ public class TypedIfElse implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
|
||||
private void convertToTypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
|
||||
ifTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.ifBlock());
|
||||
elseTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.elseBlock());
|
||||
typedCon = convertExpression(typedProgram, unTypedIfElse.cond());
|
||||
|
@ -9,14 +9,10 @@ import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
public class TypedIntLiteral implements TypedExpression {
|
||||
private static final Logger LOGGER = Logger.getLogger(TypedIntLiteral.class.getName());
|
||||
private Integer value;
|
||||
private Type type;
|
||||
|
||||
@ -24,7 +20,7 @@ public class TypedIntLiteral implements TypedExpression {
|
||||
convertToTypedIntLiteral(unTypedIntLiteral);
|
||||
}
|
||||
|
||||
public void convertToTypedIntLiteral(IntLiteral unTypedIntLiteral) {
|
||||
private void convertToTypedIntLiteral(IntLiteral unTypedIntLiteral) {
|
||||
value = unTypedIntLiteral.value();
|
||||
type = Type.INT;
|
||||
}
|
||||
@ -43,13 +39,10 @@ public class TypedIntLiteral implements TypedExpression {
|
||||
public void codeGen(MethodContext ctx) {
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
||||
ctx.getMv().visitIntInsn(Opcodes.BIPUSH, value);
|
||||
LOGGER.log(Level.FINEST, "BIPUSH {0}", value);
|
||||
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
|
||||
ctx.getMv().visitIntInsn(Opcodes.SIPUSH, value);
|
||||
LOGGER.log(Level.FINEST, "SIPUSH {0}", value);
|
||||
} else {
|
||||
ctx.getMv().visitLdcInsn(value);
|
||||
LOGGER.log(Level.FINEST, "LDC {0}", value);
|
||||
}
|
||||
ctx.pushInstantToStack();
|
||||
}
|
||||
|
@ -17,13 +17,13 @@ public final class TypedLocalVariable implements TypedNode {
|
||||
private Type type;
|
||||
|
||||
public TypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
|
||||
convertToTypedLocalVariable(typedProgram, declaration);
|
||||
convertToTypedLocalVariable(declaration);
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
|
||||
private void convertToTypedLocalVariable(Declaration declaration) {
|
||||
name = declaration.name();
|
||||
type = declaration.type();
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,18 +26,24 @@ public class TypedMethod implements TypedNode {
|
||||
convertToTypedMethod(typedProgram, unTypedMethod);
|
||||
}
|
||||
|
||||
public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
|
||||
private void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
|
||||
name = unTypedMethod.methodName();
|
||||
returnType = unTypedMethod.type();
|
||||
convertToTypedParameter(typedProgram, unTypedMethod.params());
|
||||
convertToTypedParameter(unTypedMethod.params());
|
||||
currentClass.checkMethodExists(this);
|
||||
}
|
||||
|
||||
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
|
||||
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
|
||||
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
|
||||
typeCheck(typedProgram);
|
||||
localVariables.clear();
|
||||
}
|
||||
|
||||
private void convertToTypedParameter(List<Parameter> params) {
|
||||
for (Parameter param : params) {
|
||||
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
|
||||
TypedParameter typedParameter = new TypedParameter(param);
|
||||
checkIfParameterExists(typedParameter.getParaName());
|
||||
typedParameters.add(typedParameter);
|
||||
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
||||
@ -51,12 +57,6 @@ public class TypedMethod implements TypedNode {
|
||||
}
|
||||
|
||||
|
||||
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
|
||||
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
|
||||
typeCheck(typedProgram);
|
||||
localVariables.clear();
|
||||
}
|
||||
|
||||
public boolean isLocalVariablePresent(String localVarName) {
|
||||
return localVariables.stream().anyMatch(localVariable -> localVariable.getName().equals(localVarName));
|
||||
}
|
||||
|
@ -11,8 +11,6 @@ import org.objectweb.asm.Opcodes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static de.maishai.typedast.Util.TypedExpressionUtil.convertExpression;
|
||||
|
||||
@ -21,7 +19,6 @@ import static de.maishai.typedast.Util.TypedExpressionUtil.convertExpression;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
private static final Logger LOGGER = Logger.getLogger(TypedMethodCall.class.getName());
|
||||
private TypedFieldVarAccess recipient;
|
||||
private List<TypedExpression> args = new ArrayList<>();
|
||||
private Type type;
|
||||
@ -31,9 +28,8 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
|
||||
private void convertToTypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
|
||||
recipient = new TypedFieldVarAccess(typedProgram, unTypedMethodCall.recipient());
|
||||
//recipient.typeCheck(typedProgram);
|
||||
for (Expression arg : unTypedMethodCall.args()) {
|
||||
args.add(convertExpression(typedProgram, arg));
|
||||
}
|
||||
@ -43,6 +39,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
String ownerChainName = null;
|
||||
|
||||
if (currentClass.isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
|
||||
throw new RuntimeException("Main Method, is not allowed to have methods, they are not static");
|
||||
}
|
||||
@ -107,7 +104,6 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
methodOwnerClass = recipient.getRecursiveOwnerChain().getType().getReference();
|
||||
}
|
||||
ctx.getMv().visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodOwnerClass, recipient.getName(), descriptor, false);
|
||||
LOGGER.log(Level.FINEST, "INVOKEVIRTUAL {0} {1} {2}", new Object[]{methodOwnerClass, recipient.getName(), descriptor});
|
||||
ctx.popStack();
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
ctx.popStack();
|
||||
|
@ -9,15 +9,12 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static de.maishai.typedast.Util.TypedExpressionUtil.convertExpression;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class TypedNew implements TypedExpression, TypedStatement {
|
||||
private static final Logger LOGGER = Logger.getLogger(TypedNew.class.getName());
|
||||
private Type type;
|
||||
private List<TypedExpression> args = new ArrayList<>();
|
||||
|
||||
@ -26,7 +23,7 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedNew(TypedProgram typedProgram, New unTypedNew) {
|
||||
private void convertToTypedNew(TypedProgram typedProgram, New unTypedNew) {
|
||||
type = unTypedNew.type();
|
||||
for (Expression arg : unTypedNew.args()) {
|
||||
args.add(convertExpression(typedProgram, arg));
|
||||
@ -35,8 +32,6 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
||||
|
||||
@Override
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
|
||||
if (typedProgram.isTypedClassPresent(type.getReference())) {
|
||||
return Type.REFERENCE(type.getReference());
|
||||
}
|
||||
@ -68,10 +63,8 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
||||
@Override
|
||||
public void codeGen(MethodContext ctx) {
|
||||
ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference());
|
||||
LOGGER.log(Level.FINEST, "NEW {0}", type.getReference());
|
||||
ctx.pushAnonToStack();
|
||||
ctx.getMv().visitInsn(Opcodes.DUP);
|
||||
LOGGER.finest("DUP");
|
||||
ctx.pushAnonToStack();
|
||||
for (TypedExpression arg : args) {
|
||||
arg.codeGen(ctx);
|
||||
@ -79,7 +72,6 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
||||
String descriptor = CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID);
|
||||
ctx.getMv().visitMethodInsn(Opcodes.INVOKESPECIAL, type.getReference(), "<init>", descriptor, false);
|
||||
ctx.popStack();
|
||||
LOGGER.log(Level.FINEST, "INVOKESPECIAL {0} <init> {1}", new Object[]{type.getReference(), descriptor});
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
ctx.popStack();
|
||||
}
|
||||
|
@ -12,25 +12,14 @@ public class TypedParameter implements TypedNode {
|
||||
private String paraName;
|
||||
private Type type;
|
||||
|
||||
public TypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
|
||||
convertToTypedParameter(typedProgram, unTypedParameter);
|
||||
public TypedParameter(Parameter unTypedParameter) {
|
||||
convertToTypedParameter(unTypedParameter);
|
||||
}
|
||||
|
||||
public void convertToTypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
|
||||
private void convertToTypedParameter(Parameter unTypedParameter) {
|
||||
paraName = unTypedParameter.name();
|
||||
type = unTypedParameter.type();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TypedParameter) {
|
||||
TypedParameter other = (TypedParameter) obj;
|
||||
return paraName.equals(other.paraName) && type.equals(other.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
|
||||
@ -47,5 +36,14 @@ public class TypedParameter implements TypedNode {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TypedParameter) {
|
||||
TypedParameter other = (TypedParameter) obj;
|
||||
return paraName.equals(other.paraName) && type.equals(other.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -60,11 +60,11 @@ public class TypedProgram {
|
||||
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
|
||||
}
|
||||
|
||||
public void enterCurrentClass(TypedClass clas) {
|
||||
private void enterCurrentClass(TypedClass clas) {
|
||||
currentClass = clas;
|
||||
}
|
||||
|
||||
public void exitCurrentClass() {
|
||||
private void exitCurrentClass() {
|
||||
currentClass = null;
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,22 @@
|
||||
package de.maishai.typedast.typedclass;
|
||||
|
||||
|
||||
import de.maishai.ast.records.*;
|
||||
import de.maishai.typedast.*;
|
||||
import de.maishai.ast.records.Return;
|
||||
import de.maishai.typedast.MethodContext;
|
||||
import de.maishai.typedast.Type;
|
||||
import de.maishai.typedast.TypedExpression;
|
||||
import de.maishai.typedast.TypedStatement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static de.maishai.typedast.Util.TypedExpressionUtil.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TypedReturn implements TypedStatement {
|
||||
private static final Logger LOGGER = Logger.getLogger(TypedReturn.class.getName());
|
||||
private TypedExpression ret;
|
||||
private Type type;
|
||||
|
||||
@ -25,7 +25,7 @@ public class TypedReturn implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
|
||||
private void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
|
||||
ret = convertExpression(typedProgram, unTypedReturn.ret());
|
||||
if (ret == null) {
|
||||
type = Type.VOID;
|
||||
@ -39,8 +39,7 @@ public class TypedReturn implements TypedStatement {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
TypedMethod currentMethod = currentClass.getCurrentMethod();
|
||||
|
||||
if (currentClass.isCurrentMethodPresent()) {
|
||||
if (currentMethod.getReturnType().getKind() != this.type.getKind()) {
|
||||
if (currentClass.isCurrentMethodPresent() && currentMethod.getReturnType().getKind() != this.type.getKind()) {
|
||||
StringBuilder exp = new StringBuilder();
|
||||
exp.append("\nMismatched return type: ");
|
||||
exp.append("\nExpected: ").append(currentMethod.getReturnType().getKind());
|
||||
@ -48,7 +47,7 @@ public class TypedReturn implements TypedStatement {
|
||||
exp.append("\nMethod name: ").append(currentMethod.getName());
|
||||
throw new RuntimeException(exp.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -56,15 +55,12 @@ public class TypedReturn implements TypedStatement {
|
||||
public void codeGen(MethodContext ctx) {
|
||||
if (ret == null) {
|
||||
ctx.getMv().visitInsn(Opcodes.RETURN);
|
||||
LOGGER.finest("RETURN");
|
||||
} else {
|
||||
ret.codeGen(ctx);
|
||||
if (ret.getType().getKind() != Type.Kind.REFERENCE) {
|
||||
ctx.getMv().visitInsn(Opcodes.IRETURN);
|
||||
LOGGER.finest("IRETURN");
|
||||
} else {
|
||||
ctx.getMv().visitInsn(Opcodes.ARETURN);
|
||||
LOGGER.finest("ARETURN");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class TypedUnary implements TypedExpression {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
|
||||
private void convertToTypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
|
||||
op = unTypedUnary.op();
|
||||
right = convertExpression(typedProgram, unTypedUnary.right());
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class TypedWhile implements TypedStatement {
|
||||
typeCheck(typedProgram);
|
||||
}
|
||||
|
||||
public void convertToTypedWhile(TypedProgram typedProgram, While unTypedWhile) {
|
||||
private void convertToTypedWhile(TypedProgram typedProgram, While unTypedWhile) {
|
||||
cond = convertExpression(typedProgram, unTypedWhile.cond());
|
||||
typedBlock = new TypedBlock(typedProgram, unTypedWhile.block());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user