Compilerbau2024AbsolutNicht.../src/main/java/de/maishai/ASTGenerator.java
2024-05-30 23:58:01 +02:00

93 lines
3.5 KiB
Java

package de.maishai;
import de.maishai.antlr.DecafParser;
import de.maishai.ast.records.Block;
import de.maishai.ast.records.Class;
import de.maishai.ast.records.Constructor;
import de.maishai.ast.records.Declaration;
import de.maishai.ast.records.Method;
import de.maishai.ast.records.Parameter;
import de.maishai.typedast.Type;
import java.util.ArrayList;
import java.util.List;
public class ASTGenerator {
public static Class generateAST(DecafParser.ClassContext ctx) {
List<Declaration> declarations = new ArrayList<>();
if (ctx.field() != null) {
declarations = ctx.field().stream().map(ASTGenerator::generateFieldVariable).toList();
}
List<Constructor> constructors = new ArrayList<>();
if (ctx.constructor() != null && !ctx.constructor().isEmpty()) {
constructors = ctx.constructor().stream().map(ASTGenerator::generateConstructor).toList();
}
else {
constructors.add(new Constructor(ctx.id().IDENTIFIER().getText(), List.of(), new Block(List.of())));
}
Block mainmeth = null;
if (!ctx.mainmeth().isEmpty()) {
if (ctx.mainmeth().size() > 1) {
throw new RuntimeException("Only one main method allowed!");
}
mainmeth = new BlockGenerator().visit(ctx.mainmeth().get(0).block());
}
List<Method> meths = new ArrayList<>();
if (ctx.meth() != null) {
meths = ctx.meth().stream().map(ASTGenerator::generateMethod).toList();
}
return new Class(ctx.id().IDENTIFIER().getText(), mainmeth, declarations, meths, constructors);
}
public static Declaration generateFieldVariable(DecafParser.FieldContext ctx) {
Type type = ASTGenerator.getType(ctx.type());
return new Declaration(ctx.id().IDENTIFIER().getText(), type);
}
public static Parameter generateParameter(DecafParser.ParamContext ctx) {
return new Parameter(ctx.id().IDENTIFIER().getText(), getType(ctx.type()));
}
public static Method generateMethod(DecafParser.MethContext ctx) {
List<Parameter> params = new ArrayList<>();
if (ctx.params() != null) {
params = ctx.params().param().stream().map(ASTGenerator::generateParameter).toList();
}
Block block = new BlockGenerator().visit(ctx.block());
return new Method(getType(ctx.returntype()), ctx.id().IDENTIFIER().getText(), params, block);
}
public static Constructor generateConstructor(DecafParser.ConstructorContext ctx) {
List<Parameter> params = new ArrayList<>();
if (ctx.params() != null) {
params = ctx.params().param().stream().map(ASTGenerator::generateParameter).toList();
}
Block block = new BlockGenerator().visit(ctx.block());
return new Constructor( ctx.id().getText(), params, block);
}
public static Type getType(DecafParser.TypeContext ctx) {
if (ctx.INT() != null)
return Type.INT;
if (ctx.BOOL() != null)
return Type.BOOL;
if (ctx.CHAR() != null)
return Type.CHAR;
if (ctx.id() != null) {
return Type.REFERENCE(ctx.id().getText());
}
throw new RuntimeException("No type found!");
}
public static Type getType(DecafParser.ReturntypeContext ctx) {
if (ctx.type() != null){
return getType(ctx.type());
}
if (ctx.VOID() != null){
return Type.VOID;
}
throw new RuntimeException("No type found!");
}
}