mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 23:48:03 +00:00
93 lines
3.5 KiB
Java
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!");
|
|
}
|
|
}
|