This commit is contained in:
laurenz 2024-05-16 17:46:06 +02:00
commit 9aedcd646d
35 changed files with 2472 additions and 189 deletions

View File

@ -99,7 +99,8 @@ public class Compiler {
public static void main(String[] args) {
generateByteCodeFileFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructor.java",
"src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"),
List.of("ClassWithConstructor","ClassWithConstructorAndMethodCall"));
"src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java",
"src/main/resources/JavaTestfiles/ComplexClass.java"),
List.of("ClassWithConstructor","ClassWithConstructorAndMethodCall","ComplexClass"));
}
}

View File

@ -130,7 +130,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
DecafParser.RecipientContext ctx = ctxList.get(lastElement);
ctxList.remove(lastElement);
if (ctx.id() != null) {
return new FieldVarAccess(false, generateRecursiveOwnerChain(ctxList, recipient), ctx.id().IDENTIFIER().getText());
return new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient), ctx.id().IDENTIFIER().getText());
}
if (ctx.methName() != null) {
List<Expression> args = new ArrayList<>();

View File

@ -6,11 +6,13 @@ import org.objectweb.asm.ClassWriter;
@Data
public class ClassContext {
private Type name;
private String name;
private Type type;
private ClassWriter cw;
public ClassContext(String name, ClassWriter cw) {
this.name = Type.REFERENCE(name);
this.name = name;
type = Type.REFERENCE(name);
this.cw = cw;
}
}

View File

@ -8,14 +8,14 @@ import java.util.List;
public class CodeGenUtils {
public static String generateDescriptor(List<TypedParameter> arguments, Type returnType) {
public static String generateDescriptor(List<Type> argTypes, Type returnType) {
if (returnType == null) {
returnType = Type.VOID;
}
StringBuilder builder = new StringBuilder();
builder.append('(');
arguments.forEach(type -> builder.append(type.getType().getDescriptor()));
argTypes.forEach(type -> builder.append(type.getDescriptor()));
builder.append(')');
builder.append(returnType.getDescriptor());
return builder.toString();

View File

@ -34,7 +34,7 @@ public class TypedExpressionHelp {
}
else if (expression instanceof MethodCall methodCall) {
TypedMethodCall typedMethodCall = new TypedMethodCall( typedProgram, methodCall);
typedMethodCall.typeCheck( typedProgram);
typedMethodCall.typeCheck(typedProgram);
return typedMethodCall;
}
else if (expression instanceof New newStmt) {

View File

@ -7,11 +7,12 @@ import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Stack;
@Getter
public class MethodContext {
private record LocalVariable(String name, int index, Type type) {
public record LocalVariable(String name, int index, Type type) {
}
private Label startLabel;
@ -28,7 +29,7 @@ public class MethodContext {
endLabel = new Label();
this.mv = mv;
this.classContext = classContext;
registerVariable("this", classContext.getName());
registerVariable("this", classContext.getType());
mv.visitCode();
mv.visitLabel(startLabel);
}
@ -39,12 +40,9 @@ public class MethodContext {
variableIndex.put(name, new LocalVariable(name, index, type));
}
public int getVariableIndex(String name) {
int index = variableIndex.get(name).index;
if (index == -1) {
throw new RuntimeException("Variable not declared");
}
return index;
public Optional<LocalVariable> getLocalVar(String name) {
LocalVariable index = variableIndex.get(name);
return Optional.ofNullable(index);
}
public void pushStack(String varName) {
@ -58,6 +56,22 @@ public class MethodContext {
} else {
mv.visitVarInsn(Opcodes.ILOAD, localVariable.index);
}
System.out.println("Pushed " + variableIndex.get(varName) + " to stack");
}
public void pushAnonToStack() {
stack.push(localVarIndex);
if (stack.size() > maxStack) {
maxStack = stack.size();
}
System.out.println("Pushed anon to stack");
}
public void pushInstantToStack () {
stack.push(localVarIndex);
if (stack.size() > maxStack) {
maxStack = stack.size();
}
}
public void popStack() {
@ -66,6 +80,7 @@ public class MethodContext {
public void wrapUp() {
mv.visitLabel(endLabel);
System.out.println("maxStack: " + maxStack + " localVarIndex: " + localVarIndex);
mv.visitMaxs(maxStack, localVarIndex);
mv.visitEnd();
}

View File

@ -25,31 +25,13 @@ public class TypedAssignment implements TypedStatement {
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(typedProgram, untyped.location());
location.typeCheck(typedProgram);
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
Type typeLeft = null;
if (typedProgram.getCurrentClass().isThereField(location.getName())) {
typeLeft = typedProgram.getCurrentClass().getFieldType(location.getName());
} else {
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(location.getName())) {
typeLeft = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(location.getName());
} else {
throw new RuntimeException("Variable " + location.getName() + " not declared in method");
}
}
if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(location.getName())) {
typeLeft = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(location.getName());
} else {
throw new RuntimeException("Variable " + location.getName() + " not declared in constructor");
}
}
}
Type typeLeft = getTypeLeft(typedProgram);
Type typeRight = value.typeCheck(typedProgram);
if (typeLeft.equals(typeRight)) {
@ -59,11 +41,82 @@ public class TypedAssignment implements TypedStatement {
throw new RuntimeException("type of left not equals with type of right");
}
private Type getTypeLeft(TypedProgram typedProgram) {
String name = location.getName();
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isThereField(name) && location.getField()) {
return currentClass.getFieldType(name);
}
if (currentClass.isCurrentMethodPresent() && !currentClass.isCurrentConstructorPresent()) {
return getTypeFromMethodOrField(currentClass.getCurrentMethod(), name, currentClass);
}
if (!currentClass.isCurrentMethodPresent() && currentClass.isCurrentConstructorPresent()) {
return getTypeFromConstructorOrField(currentClass.getCurrentConstructor(), name, currentClass);
}
throw new RuntimeException("Variable " + name + " not declared");
}
private Type getTypeFromMethodOrField(TypedMethod currentMethod, String name, TypedClass currentClass) {
if (currentMethod.isLocalVariableInMethod(name)) {
return currentMethod.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
return currentClass.getFieldType(name);
} else {
throw new RuntimeException("Variable " + name + " not declared in method");
}
}
private Type getTypeFromConstructorOrField(TypedConstructor currentConstructor, String name, TypedClass currentClass) {
if (currentConstructor.isLocalVariableInConstructor(name)) {
return currentConstructor.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
return currentClass.getFieldType(name);
} else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
}
}
@Override
public void codeGen(MethodContext ctx) {
if (value instanceof TypedIntLiteral) {
ctx.getMv().visitIntInsn(Opcodes.BIPUSH, ((TypedIntLiteral) value).getValue());
ctx.getMv().visitVarInsn(Opcodes.ISTORE, ctx.getLocalVarIndex());
if(value instanceof TypedNew) {
value.codeGen(ctx);
getOwnerChain(ctx);
} else {
ctx.pushStack("this");
getOwnerChain(ctx);
value.codeGen(ctx);
}
//save value in field
if (location.getField()) {
String receiver = ctx.getClassContext().getName();
if (location.getRecursiveOwnerChain() != null) {
receiver = location.getRecursiveOwnerChain().getType().getReference();
}
ctx.getMv().visitFieldInsn(Opcodes.PUTFIELD, receiver, location.getName(), value.getType().getDescriptor());
System.out.println("PUTFIELD: " + receiver + " " + location.getName() + " " + value.getType().getDescriptor());
} else {
if(value.getType().getKind() == Type.Kind.REFERENCE) {
System.out.println("ASTORE " + ctx.getLocalVar(location.getName()).get().index());
ctx.getMv().visitVarInsn(Opcodes.ASTORE, ctx.getLocalVar(location.getName()).get().index());
} else {
ctx.getMv().visitVarInsn(Opcodes.ISTORE, ctx.getLocalVar(location.getName()).get().index());
}
}
//ctx.popStack();
//ctx.popStack();
}
private void getOwnerChain(MethodContext ctx) {
if (location.getRecursiveOwnerChain() != null) {
location.getRecursiveOwnerChain().codeGen(ctx);
ctx.pushAnonToStack();
}
}
}

View File

@ -8,6 +8,11 @@ import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -67,6 +72,139 @@ public class TypedBinary implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
if (op == Operator.AND) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IFNE, returnFalse);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IFNE, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.OR) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IFNE, returnTrue);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IFNE, returnTrue);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnFalse);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.EQ) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPNE, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.GT) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPLE, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.LT) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPGE, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.GE) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPLT, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.LE) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPGT, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else if (op == Operator.NE) {
Label end = new Label();
Label returnTrue = new Label();
Label returnFalse = new Label();
left.codeGen(ctx);
right.codeGen(ctx);
ctx.getMv().visitJumpInsn(Opcodes.IF_ICMPEQ, returnFalse);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, returnTrue);
ctx.getMv().visitLabel(returnFalse);
ctx.getMv().visitInsn(Opcodes.ICONST_0);
ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
ctx.getMv().visitLabel(returnTrue);
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitLabel(end);
} else {
left.codeGen(ctx);
right.codeGen(ctx);
if (op == Operator.ADD) {
ctx.getMv().visitInsn(Opcodes.IADD);
} else if (op == Operator.SUB) {
ctx.getMv().visitInsn(Opcodes.ISUB);
} else if (op == Operator.MUL) {
ctx.getMv().visitInsn(Opcodes.IMUL);
}
}
ctx.popStack();
}
}

View File

@ -103,12 +103,12 @@ public class TypedBlock implements TypedNode {
Type chekType = null;
for (TypedStatement stmt : stmts) {
stmt.typeCheck(typedProgram);
if(stmt instanceof TypedReturn returnStmt) {
if (stmt instanceof TypedReturn returnStmt) {
chekType = returnStmt.getType();
}
}
if(chekType == null) {
if (chekType == null) {
chekType = Type.VOID;
}
type = chekType;
@ -117,7 +117,7 @@ public class TypedBlock implements TypedNode {
public void codeGen(MethodContext ctx) {
for (TypedLocalVariable var : vars) {
//var.codeGen(ctx);
ctx.registerVariable(var.getName(), var.getType());
}
for (TypedStatement stmt : stmts) {
stmt.codeGen(ctx);

View File

@ -4,12 +4,14 @@ import de.maishai.ast.records.BoolLiteral;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Opcodes;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedBoolLiteral implements TypedExpression {
private Boolean value;
@ -32,10 +34,11 @@ public class TypedBoolLiteral implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
if(value){
if (value) {
ctx.getMv().visitInsn(Opcodes.ICONST_1);
}else{
} else {
ctx.getMv().visitInsn(Opcodes.ICONST_0);
}
ctx.pushInstantToStack();
}
}

View File

@ -10,10 +10,6 @@ import lombok.Data;
public class TypedBreak implements TypedStatement {
private Type type = Type.VOID;
public TypedBreak convertToTypedBreak(TypedClass clas, Break unTypedBreak) {
return this;
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
return type;

View File

@ -4,9 +4,11 @@ import de.maishai.ast.records.CharLiteral;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class TypedCharLiteral implements TypedExpression {
private char value;
private Type type;
@ -29,5 +31,6 @@ public class TypedCharLiteral implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
ctx.getMv().visitLdcInsn(value);
ctx.pushInstantToStack();
}
}

View File

@ -28,13 +28,11 @@ public class TypedClass implements TypedNode {
private TypedConstructor currentConstructor;
private Type type;
public TypedClass(TypedProgram typedProgram, Class c) {
public TypedClass(Class c) {
className = c.classname();
type = Type.REFERENCE(className);
convertMethodsAndConstructorsAndFields(typedProgram, c);
}
public boolean isParameterNameInCurrentConstructor(String parameterName) {
if (currentConstructor == null) {
return false;
@ -47,7 +45,7 @@ public class TypedClass implements TypedNode {
return false;
}
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c){
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
// damit die Methoden verwendet werden können, bevor deren Blöcke ausgeführt werden
for (Declaration declaration : c.fieldDeclarations()) {
@ -62,7 +60,7 @@ public class TypedClass implements TypedNode {
}
}
public void covertBlocksOfConstructorsAndMethods(TypedProgram typedProgram, Class c){
public void covertBlocksOfConstructorsAndMethods(TypedProgram typedProgram, Class c) {
// Hier werden die Blöcke der Konstruktoren ausgeführt
int i = 0;
for (Constructor constructor : c.constructors()) {
@ -119,6 +117,24 @@ public class TypedClass implements TypedNode {
return null;
}
public boolean isMethodOfCurrentClass(String methodName) {
for (TypedMethod m : typedMethods) {
if (m.getName().equals(methodName)) {
return true;
}
}
return false;
}
public Type getMethodType(String methodName) {
for (TypedMethod m : typedMethods) {
if (m.getName().equals(methodName)) {
return m.getReturnType();
}
}
return null;
}
public Type getParameterTypeInCurrentConstructor(String parameterName) {
for (TypedParameter p : currentConstructor.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {

View File

@ -53,11 +53,20 @@ public class TypedConstructor implements TypedNode {
name = unTypedConstructor.className();
for (Parameter param : unTypedConstructor.params()) {
typedParameters.add(new TypedParameter(typedProgram, param));
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
}
type = Type.VOID;
}
public void checkIfParameterExists(String paraName) {
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
throw new RuntimeException("Parameter " + paraName + " already exists");
}
}
public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
typeCheck(typedProgram);
@ -76,12 +85,15 @@ public class TypedConstructor implements TypedNode {
public void codeGen(ClassContext ctx) {
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, "<init>", CodeGenUtils.generateDescriptor(typedParameters, Type.VOID), null, null);
MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, "<init>", CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID), null, null);
System.out.println("Visiting method: " + "<init>" + CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID));
MethodContext mctx = new MethodContext(ctx, mv);
typedParameters.forEach(param -> mctx.registerVariable(param.getParaName(), param.getType()));
//super();
mctx.pushStack("this");
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
System.out.println("INVOKESPECIAL: " + "java/lang/Object" + " " + "<init>" + " " + "()V");
mctx.popStack();
typedBlock.codeGen(mctx);

View File

@ -9,7 +9,6 @@ import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data
@AllArgsConstructor
@ -30,27 +29,17 @@ public final class TypedDeclaration implements TypedNode {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (type.getReference() != null && !typedProgram.getCurrentClass().getClassName().equals(type.getReference())) {
if (!typedProgram.isTypedClassPresent(type.getReference())) {
throw new RuntimeException("Type " + type.getReference() + " not found");
}
}
if (typedProgram.getCurrentClass().isThereField(name)) {
throw new RuntimeException("Field " + name + " already declared");
}
if (type.getKind() == REFERENCE) {
if (!type.getReference().equals(typedProgram.getCurrentClass().getClassName())) {
throw new RuntimeException("Field " + name + " has wrong type");
}
}
return type;
}
/*
public void codeGen(MethodVisitor mv, MethodContext ctx) {
System.out.println("Generating code for local variable " + name);
int index = ctx.addVariable(name);
mv.visitLocalVariable(name, type.getDescriptor(), null, ctx.getStartLabel(), ctx.getEndLabel(), index);
}
*/
public void codeGen(ClassWriter cw) {
int access = Opcodes.ACC_PUBLIC; // laut Andi ist es ok, dass alle Felder public sind
cw.visitField(access, name, type.getDescriptor(), null, null).visitEnd();

View File

@ -7,6 +7,10 @@ import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -32,49 +36,88 @@ public class TypedFieldVarAccess implements TypedExpression {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (field) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
return typedProgram.getCurrentClass().getFieldType(name);
}else{
throw new RuntimeException("Field " + name + " not declared ");
}
type = checkFieldOrMethodType(typedProgram);
return type;
} else {
if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
return type;
} else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
return type;
} else if(typedProgram.getCurrentClass().isThereField(name)){
type = typedProgram.getCurrentClass().getFieldType(name);
return type;
}
else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
}
} else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
return type;
} else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
return type;
} else if(typedProgram.getCurrentClass().isThereField(name)){
type = typedProgram.getCurrentClass().getFieldType(name);
return type;
}
else {
throw new RuntimeException("Variable " + name + " not declared in method");
}
}
throw new RuntimeException("Variable " + name + " not declared ");
type = checkVariableType(typedProgram);
return type;
}
}
private Type checkFieldOrMethodType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
return type;
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
return type;
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
return type;
} else {
throw new RuntimeException("Field " + name + " not declared");
}
}
private Type checkVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
return checkConstructorVariableType(typedProgram);
} else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
return checkMethodVariableType(typedProgram);
} else {
throw new RuntimeException("Variable " + name + " not declared");
}
}
private Type checkConstructorVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
} else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
}
return type;
}
private Type checkMethodVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
} else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
}
return type;
}
private Type checkFieldOrMethodOrRecursiveType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
} else {
throw new RuntimeException("Variable " + name + " not declared");
}
return type;
}
@Override
public void codeGen(MethodContext ctx) {
if (recursiveOwnerChain != null) {
recursiveOwnerChain.codeGen(ctx);
}
if (field && recursiveOwnerChain == null) {
ctx.pushStack("this");
}
if (field) {
ctx.getMv().visitFieldInsn(Opcodes.GETFIELD, recursiveOwnerChain.getType().getReference(), name, type.getDescriptor());
} else {
int loadOpcode = type.getKind() == Type.Kind.REFERENCE ? Opcodes.ALOAD : Opcodes.ILOAD;
ctx.getMv().visitVarInsn(loadOpcode, ctx.getLocalVar(name).get().index());
System.out.println(loadOpcode == Opcodes.ALOAD ? "ALOAD " + ctx.getLocalVar(name).get().index() : "ILOAD " + ctx.getLocalVar(name).get().index());
}
}
}

View File

@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Label;
@ -11,6 +12,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedIfElse implements TypedStatement {
private TypedExpression typedCon;
private TypedBlock ifTypedBlock;

View File

@ -7,6 +7,10 @@ import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
@Data
@AllArgsConstructor
@ -37,6 +41,16 @@ public class TypedIntLiteral implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
ctx.getMv().visitLdcInsn(value);
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
ctx.getMv().visitIntInsn(Opcodes.BIPUSH, value);
System.out.println("BIPUSH " + value);
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
ctx.getMv().visitIntInsn(Opcodes.SIPUSH, value);
System.out.println("SIPUSH " + value);
} else {
ctx.getMv().visitLdcInsn(value);
System.out.println("LDC " + value);
}
ctx.pushInstantToStack();
}
}

View File

@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Method;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
@ -12,6 +13,7 @@ import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedMethod implements TypedNode {
private String name;
private Type returnType;
@ -28,7 +30,10 @@ public class TypedMethod implements TypedNode {
name = unTypedMethod.methodName();
returnType = unTypedMethod.type();
for (var parameter : unTypedMethod.params()) {
typedParameters.add(new TypedParameter(typedProgram, parameter));
TypedParameter typedParameter = new TypedParameter(typedProgram, parameter);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
}
typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
@ -38,6 +43,12 @@ public class TypedMethod implements TypedNode {
});
}
public void checkIfParameterExists(String parameterName) {
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName))) {
throw new RuntimeException("Parameter " + parameterName + " already exists");
}
}
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
typeCheck(typedProgram);
@ -109,7 +120,7 @@ public class TypedMethod implements TypedNode {
public void codeGen(ClassContext ctx) {
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, name,
CodeGenUtils.generateDescriptor(typedParameters, returnType), null, null);
CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), returnType), null, null);
MethodContext context = new MethodContext(ctx, mv);
typedParameters.forEach(param -> context.registerVariable(param.getParaName(), param.getType()));

View File

@ -3,18 +3,20 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Expression;
import de.maishai.ast.records.MethodCall;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
//TODO: test this after fixing error from parser
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedMethodCall implements TypedExpression, TypedStatement {
private TypedFieldVarAccess recipient;
private List<TypedExpression> args = new ArrayList<>();
@ -26,38 +28,60 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
public void convertToTypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
recipient = new TypedFieldVarAccess(typedProgram, unTypedMethodCall.recipient());
for (Expression arg : unTypedMethodCall.args()) {
args.add(convertExpression(typedProgram, arg));
}
recipient.typeCheck(typedProgram);
for (Expression arg : unTypedMethodCall.args()) {
args.add(convertExpression(typedProgram, arg));
}
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
String ownerChainName = null;
if (recipient.getRecursiveOwnerChain() != null) {
ownerChainName = recipient.getRecursiveOwnerChain().getType().getReference();
}
List<TypedMethod> methods = typedProgram.getCurrentClass().getTypedMethods().stream()
.filter(method -> method.getName().equals(recipient.getName()))
.toList();
for (TypedMethod method : methods) {
if (method.getTypedParameters().size() == args.size()) {
boolean allMatch = true;
for (int i = 0; i < args.size(); i++) {
if (!args.get(i).typeCheck(typedProgram).equals(method.getTypedParameters().get(i).getType())) {
allMatch = false;
break;
}
}
if (allMatch) {
type = method.getReturnType();
return type;
}
}
if (!typedProgram.getCurrentClass().getClassName().equals(ownerChainName) && ownerChainName != null) {
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getTypedClass(ownerChainName), recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
return type;
}
}
if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getCurrentClass(), recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
return type;
}
}
throw new RuntimeException("Method not found");
}
public Optional<Type> findMatchingMethod(TypedClass ownerChain, String methodName) {
List<TypedMethod> methods = ownerChain.getTypedMethods().stream()
.filter(method -> method.getName().equals(methodName))
.toList();
for (TypedMethod method : methods) {
if (method.getTypedParameters().size() == args.size()) {
boolean allMatch = true;
for (int i = 0; i < args.size(); i++) {
if (!args.get(i).getType().equals(method.getTypedParameters().get(i).getType())) {
allMatch = false;
break;
}
}
if (allMatch) {
return Optional.of(method.getReturnType());
}
}
}
return Optional.empty();
}
@Override
public void codeGen(MethodContext ctx) {

View File

@ -3,7 +3,10 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Expression;
import de.maishai.ast.records.New;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
@ -11,6 +14,7 @@ import java.util.List;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@AllArgsConstructor
public class TypedNew implements TypedExpression, TypedStatement {
private Type type;
private List<TypedExpression> args = new ArrayList<>();
@ -28,6 +32,11 @@ public class TypedNew implements TypedExpression, TypedStatement {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.isTypedClassPresent(type.getReference())) {
return Type.REFERENCE(type.getReference());
}
for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
if (constructor.getTypedParameters().size() == args.size()) {
boolean valid = true;
@ -48,6 +57,21 @@ public class TypedNew implements TypedExpression, TypedStatement {
@Override
public void codeGen(MethodContext ctx) {
//pop the stack
//ctx.popStack();
//ctx.getMv().visitInsn(Opcodes.POP);
//System.out.println("Popped stack");
ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference());
System.out.println("NEW " + type.getReference());
ctx.pushAnonToStack();
ctx.getMv().visitInsn(Opcodes.DUP);
System.out.println("DUP");
ctx.pushAnonToStack();
for (TypedExpression arg : args) {
arg.codeGen(ctx);
}
ctx.getMv().visitMethodInsn(Opcodes.INVOKESPECIAL, type.getReference(), "<init>", CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID), false);
System.out.println("INVOKESPECIAL " + type.getReference() + "<init> " + CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID));
}
}

View File

@ -19,16 +19,23 @@ public class TypedProgram {
public void startConversion(Program program) {
// Initialisiere die Klassen nur mit den Klassennamen und deren Typ
for (var clas : program.classes()) {
typedClasses.add(new TypedClass(clas));
}
// Konvertiere die Methoden, Konstruktoren und Felder von den jeweiligen Klassen
int k = 0;
for (var clas : program.classes()) {
enterCurrentClass(typedClasses.get(k));
typedClasses.add(new TypedClass(this, clas));
typedClasses.get(k).convertMethodsAndConstructorsAndFields(this, clas);
exitCurrentClass();
k++;
}
// Konvertiere die Blöcke der Konstruktoren und Methoden von den jeweiligen Klassen
int i = 0;
for(var clas : program.classes()){
for (var clas : program.classes()) {
enterCurrentClass(typedClasses.get(i));
typedClasses.get(i).covertBlocksOfConstructorsAndMethods(this, clas);
exitCurrentClass();
@ -40,8 +47,8 @@ public class TypedProgram {
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
}
public boolean isCurrentClassPresent() {
return currentClass != null;
public boolean isTypedClassPresent(String className) {
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
}
public void enterCurrentClass(TypedClass clas) {
@ -52,4 +59,18 @@ public class TypedProgram {
currentClass = null;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
TypedProgram other = (TypedProgram) obj;
if(typedClasses.equals(other.typedClasses) &&
(currentClass == null && other.currentClass == null
|| currentClass.equals(other.currentClass))) {
return true;
} else {
System.out.println("TypedPrograms are not equal:\n" + this.typedClasses + "\n" + other.typedClasses + "\n");
return false;
}
}
}

View File

@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Opcodes;
@ -11,6 +12,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedReturn implements TypedStatement {
private TypedExpression ret;
private Type type;
@ -21,9 +23,9 @@ public class TypedReturn implements TypedStatement {
public void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
ret = convertExpression(typedProgram, unTypedReturn.ret());
if(ret == null){
if (ret == null) {
type = Type.VOID;
}else{
} else {
type = ret.getType();
}
}
@ -48,6 +50,7 @@ public class TypedReturn implements TypedStatement {
if (ret == null) {
ctx.getMv().visitInsn(Opcodes.RETURN);
} else {
System.out.println("return: " + ret);
ret.codeGen(ctx);
if (ret.getType().getKind() != Type.Kind.REFERENCE) {
ctx.getMv().visitInsn(Opcodes.IRETURN);

View File

@ -47,11 +47,11 @@ public class TypedUnary implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
right.codeGen(ctx);
if(op == UnaryOperator.NOT){
if (op == UnaryOperator.NOT) {
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitInsn(Opcodes.IXOR);
}
if(op == UnaryOperator.SUB){
if (op == UnaryOperator.SUB) {
ctx.getMv().visitInsn(Opcodes.INEG);
}
}

View File

@ -165,7 +165,6 @@ public class AbstractSyntax_ClassWithConstructor {
localVariables,
statementList
);
return new Constructor(
"ClassWithConstructor",
parameters,

View File

@ -0,0 +1,902 @@
//public class ComplexClass {
//
// int x;
// int y;
// ComplexClass b;
// ComplexClass c;
//
// public ComplexClass() {
// this.y = 10;
// this.x = 2;
// int i;
// for (i = 0; i < (this.y + 1); i = i + 1) {
// int j;
// for (j = 0; j < this.y; j += 1) {
// this.x = this.x * this.x;
// if (this.x == 100) {
// break;
// }
// }
// }
// this.y = 2;
// do {
// this.y = this.y + 1;
// } while (this.y < 10);
//
// int k;
// k = 0;
// for (k = 0; k < 10; k = k + 1) {
// if (k == 5) {
// return this;
// }
// }
//
// }
//
// public ComplexClass(int x) {
// this.b = new ComplexClass();
// this.c = new ComplexClass();
// this.x = x;
// this.b.x = 7;
// this.b.y = 13;
// this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
// this.c.y = 25;
// }
//
// public ComplexClass(int x, int y) {
// this.x = x;
// this.y = y;
// }
//
// public ComplexClass initComplexClass(int x) {
// int a;
// a = 10;
// this.b = new ComplexClass(x);
// this.b.x = 10 + a;
// this.b.y = 20;
// this.b.c.x = 20 + a;
// if (methodCall()) {
// this.b.getC().b.y = this.b.x;
// }
// return this.b;
// }
//
// public ComplexClass init(int x, int y) {
// return new ComplexClass(x, y);
// }
//
// public ComplexClass(int x, int y, char z) {
// this.x = x;
// this.y = y;
// }
//
// public int getX(char z) {
// return this.x;
// }
//
// public ComplexClass getC() {
// return this.c;
// }
//
// public int getX() {
// return this.x;
// }
//
// public boolean methodCall() {
// return false;
// }
//
//}
import de.maishai.ast.Operator;
import de.maishai.ast.records.*;
import de.maishai.ast.records.Class;
import de.maishai.typedast.Type;
import java.util.List;
@SuppressWarnings("DuplicateExpressions")
public class AbstractSyntax_ComplexClass {
public static Program get() {
List<Declaration> declarationList = List.of(
new Declaration(
"x",
Type.INT
),
new Declaration(
"y",
Type.INT
),
new Declaration(
"b",
Type.REFERENCE("ComplexClass")
),
new Declaration(
"c",
Type.REFERENCE("ComplexClass")
)
);
List<Method> methodList = getMethods();
List<Constructor> constructorList = getConstructors();
return new Program(
List.of(
new Class(
"ComplexClass",
declarationList,
methodList,
constructorList
)
)
);
}
private static List<Constructor> getConstructors() {
return List.of(
getConstructor1(),
getConstructor2(),
getConstructor3(),
getConstructor4()
);
}
private static Constructor getConstructor1() {
Block block = new Block(
List.of(
new Declaration(
"i",
Type.INT
),
new Declaration(
"k",
Type.INT
)
),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new IntLiteral(2)
),
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"i"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"i"),
Operator.LT,
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.ADD,
new IntLiteral(1)
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"i"),
new Binary(
new FieldVarAccess(
false,
null,
"i"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(
new Declaration(
"j",
Type.INT
)
),
List.of(
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"j"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"j"),
Operator.LT,
new FieldVarAccess(
true,
null,
"y"
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"j"),
new Binary(
new FieldVarAccess(
false,
null,
"j"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new Binary(
new FieldVarAccess(
true,
null,
"x"),
Operator.MUL,
new FieldVarAccess(
true,
null,
"x"
)
)
),
new IfElse(
new Binary(
new FieldVarAccess(
true,
null,
"x"),
Operator.EQ,
new IntLiteral(100)
),
new Block(
List.of(),
List.of(
new Break()
)
),
null
)
)
)
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new IntLiteral(2)
),
new DoWhile(
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.ADD,
new IntLiteral(1)
)
)
)
),
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.LT,
new IntLiteral(10)
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new IntLiteral(0)
),
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.LT,
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(),
List.of(
new IfElse(
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.EQ,
new IntLiteral(5)
),
new Block(
List.of(),
List.of(
new Return(
new This()
)
)
),
null
)
)
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(),
block
);
}
private static Constructor getConstructor2() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"b"),
new New(
Type.REFERENCE("ComplexClass"),
List.of()
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"c"),
new New(
Type.REFERENCE("ComplexClass"),
List.of()
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"x"),
new IntLiteral(7)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"),
new IntLiteral(13)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"c"),
"x"),
new Binary(
new Binary(
new MethodCall(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"getX"
),
List.of()
),
Operator.MUL,
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"
)
),
Operator.MUL,
new MethodCall(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"getX"
),
List.of(
new CharLiteral('g')
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"c"),
"y"),
new IntLiteral(25)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
)
),
block
);
}
private static Constructor getConstructor3() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new FieldVarAccess(
false,
null,
"y"
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
)
),
block
);
}
private static Constructor getConstructor4() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new FieldVarAccess(
false,
null,
"y"
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
),
new Parameter(
"z",
Type.CHAR
)
),
block
);
}
private static List<Method> getMethods() {
return List.of(
getMethod1(),
getMethod2(),
getMethod3(),
getMethod4(),
getMethod5(),
getMethod6()
);
}
private static Method getMethod1() {
Block block = new Block(
List.of(
new Declaration(
"a",
Type.INT
)
),
List.of(
new Assignment(
new FieldVarAccess(
false,
null,
"a"),
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
true,
null,
"b"),
new New(
Type.REFERENCE("ComplexClass"),
List.of(
new FieldVarAccess(
false,
null,
"x"
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"x"),
new Binary(
new IntLiteral(10),
Operator.ADD,
new FieldVarAccess(
false,
null,
"a"
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"),
new IntLiteral(20)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
new FieldVarAccess(
false,
null,
"b"),
"c"),
"x"),
new Binary(
new IntLiteral(20),
Operator.ADD,
new FieldVarAccess(
false,
null,
"a"
)
)
),
new IfElse(
new MethodCall(
new FieldVarAccess(
false,
null,
"methodCall"),
List.of()
),
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
new MethodCall(
new FieldVarAccess(
false,
new FieldVarAccess(
false,
null,
"b"
),
"getC"
),
List.of()
),
"b"),
"y"),
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"
),
"x"
)
)
)
),
null
),
new Return(
new FieldVarAccess(
true,
null,
"b"
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"initComplexClass",
List.of(
new Parameter(
"x",
Type.INT
)
),
block
);
}
private static Method getMethod2() {
Block block = new Block(
List.of(),
List.of(
new Return(
new New(
Type.REFERENCE("ComplexClass"),
List.of(
new FieldVarAccess(
false,
null,
"x"
),
new FieldVarAccess(
false,
null,
"y"
)
)
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"init",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
)
),
block
);
}
private static Method getMethod3() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"x"
)
)
)
);
return new Method(
Type.INT,
"getX",
List.of(
new Parameter(
"z",
Type.CHAR
)
),
block
);
}
private static Method getMethod4() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"c"
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"getC",
List.of(),
block
);
}
private static Method getMethod5() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"x"
)
)
)
);
return new Method(
Type.INT,
"getX",
List.of(),
block
);
}
private static Method getMethod6() {
Block block = new Block(
List.of(),
List.of(
new Return(
new BoolLiteral(false)
)
)
);
return new Method(
Type.BOOL,
"methodCall",
List.of(),
block
);
}
}

View File

@ -0,0 +1,19 @@
public class ClassCanBeTyped{
public int c;
public ClassCanBeTyped d;
public int x;
public ClassCanBeTyped() {
}
public ClassCanBeTyped(int x) {
this.x = x;
}
public ClassCanBeTyped test(int i) {
ClassCanBeTyped a;
a = new ClassCanBeTyped(i);
return a;
}
}

View File

@ -4,44 +4,21 @@ public class ComplexClass {
int y;
ComplexClass b;
ComplexClass c;
public ComplexClass(int x) {
this.x = x;
}
public ComplexClass(int x, int y) {
this.x = x;
this.y = y;
}
public ComplexClass initComplexClass(int x) {
int a;
a = 10;
b = new ComplexClass(x);
b.x = 10 + a;
b.y = 20;
b.c.x = 20 + a;
b.c.b.y = b.x;
return b;
}
public ComplexClass init(int x, int y) {
return new ComplexClass(x, y);
}
public ComplexClass(int x) {
this.x = x;
int i;
b = b.getX().c.getC();
i = b.getX().c.getX();
}
public ComplexClass() {
this.x = 10;
this.y = 10;
this.x = 2;
int i;
for (i = 0; i < (x + 1); i = i + 1) {
for (i = 0; i < (this.y + 1); i = i + 1) {
int j;
for (j = 0; j < this.x; j += 1) {
for (j = 0; j < this.y; j += 1) {
this.x = this.x * this.x;
break;
if (this.x == 100) {
break;
}
}
}
this.y = 2;
do {
this.y = this.y + 1;
} while (this.y < 10);
@ -50,12 +27,44 @@ public class ComplexClass {
k = 0;
for (k = 0; k < 10; k = k + 1) {
if (k == 5) {
return;
return this;
}
}
}
public ComplexClass(int x) {
this.b = new ComplexClass();
this.c = new ComplexClass();
this.x = x;
this.b.x = 7;
this.b.y = 13;
this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
this.c.y = 25;
}
public ComplexClass(int x, int y) {
this.x = x;
this.y = y;
}
public ComplexClass initComplexClass(int x) {
int a;
a = 10;
this.b = new ComplexClass(x);
this.b.x = 10 + a;
this.b.y = 20;
this.b.c.x = 20 + a;
if (methodCall()) {
this.b.getC().b.y = this.b.x;
}
return this.b;
}
public ComplexClass init(int x, int y) {
return new ComplexClass(x, y);
}
public ComplexClass(int x, int y, char z) {
this.x = x;
this.y = y;
@ -66,16 +75,15 @@ public class ComplexClass {
}
public ComplexClass getC() {
return c;
return this.c;
}
public int getX() {
return x;
return this.x;
}
public boolean methodCall() {
return false;
}
}

View File

@ -35,9 +35,10 @@ public class TypedAbstractSyntax_ClassWithConstructor {
getConstructors(),
null,
null,
Type.REFERENCE("ClassWithField")
Type.REFERENCE("ClassWithConstructor")
)
)
),
null
);
}
@ -203,20 +204,20 @@ public class TypedAbstractSyntax_ClassWithConstructor {
Type.INT
)
),
Type.INT
Type.VOID
),
Type.INT
Type.VOID
)
),
Type.INT
Type.VOID
),
Type.INT
Type.VOID
)
);
TypedBlock typedBlock = new TypedBlock(
typedLocalVariables,
typedStatementList,
Type.INT
Type.VOID
);
return new TypedConstructor(

View File

@ -38,7 +38,8 @@ public class TypedAbstractSyntax_ClassWithField {
null,
Type.REFERENCE("ClassWithField")
)
)
),
null
);
}
}

View File

@ -0,0 +1,960 @@
//public class ComplexClass {
//
// int x;
// int y;
// ComplexClass b;
// ComplexClass c;
//
// public ComplexClass() {
// this.y = 10;
// this.x = 2;
// int i;
// for (i = 0; i < (this.y + 1); i = i + 1) {
// int j;
// for (j = 0; j < this.y; j += 1) {
// this.x = this.x * this.x;
// if (this.x == 100) {
// break;
// }
// }
// }
// this.y = 2;
// do {
// this.y = this.y + 1;
// } while (this.y < 10);
//
// int k;
// k = 0;
// for (k = 0; k < 10; k = k + 1) {
// if (k == 5) {
// return this;
// }
// }
//
// }
//
// public ComplexClass(int x) {
// this.b = new ComplexClass();
// this.c = new ComplexClass();
// this.x = x;
// this.b.x = 7;
// this.b.y = 13;
// this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
// this.c.y = 25;
// }
//
// public ComplexClass(int x, int y) {
// this.x = x;
// this.y = y;
// }
//
// public ComplexClass initComplexClass(int x) {
// int a;
// a = 10;
// this.b = new ComplexClass(x);
// this.b.x = 10 + a;
// this.b.y = 20;
// this.b.c.x = 20 + a;
// if (methodCall()) {
// this.b.getC().b.y = this.b.x;
// }
// return this.b;
// }
//
// public ComplexClass init(int x, int y) {
// return new ComplexClass(x, y);
// }
//
// public ComplexClass(int x, int y, char z) {
// this.x = x;
// this.y = y;
// }
//
// public int getX(char z) {
// return this.x;
// }
//
// public ComplexClass getC() {
// return this.c;
// }
//
// public int getX() {
// return this.x;
// }
//
// public boolean methodCall() {
// return false;
// }
//
//}
import de.maishai.ast.Operator;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*;
import java.util.List;
public class TypedAbstractSyntax_ComplexClass {
public static TypedProgram get() {
return new TypedProgram(
getClasses(),
null
);
}
private static List<TypedClass> getClasses() {
return List.of(
getClass1()
);
}
private static TypedClass getClass1() {
return new TypedClass(
"ComplexClass",
getFields(),
getMethods(),
getConstructors(),
null,
null,
Type.REFERENCE("ComplexClass")
);
}
private static List<TypedDeclaration> getFields() {
return List.of(
new TypedDeclaration("x", Type.INT),
new TypedDeclaration("y", Type.INT),
new TypedDeclaration("b", Type.REFERENCE("ComplexClass")),
new TypedDeclaration("c", Type.REFERENCE("ComplexClass"))
);
}
private static List<TypedConstructor> getConstructors() {
return List.of(
getConstructor1(),
getConstructor2(),
getConstructor3(),
getConstructor4()
);
}
private static TypedConstructor getConstructor1() {
TypedBlock block = new TypedBlock(
List.of(
new TypedLocalVariable("i", Type.INT),
new TypedLocalVariable("k", Type.INT)
),
List.of(
new TypedAssignment(
new TypedIntLiteral(10),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(2),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedFor(
new TypedAssignment(
new TypedIntLiteral(0),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Type.INT
),
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Operator.LT,
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Operator.ADD,
new TypedIntLiteral(1),
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Operator.ADD,
new TypedIntLiteral(1),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Type.INT
),
new TypedBlock(
List.of(
new TypedLocalVariable(
"j",
Type.INT
)
),
List.of(
new TypedFor(
new TypedAssignment(
new TypedIntLiteral(0),
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT),
Type.INT
),
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT),
Operator.LT,
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(1),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT
),
Type.INT
),
new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Operator.MUL,
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedIfElse(
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Operator.EQ,
new TypedIntLiteral(100),
Type.BOOL
),
new TypedBlock(
List.of(),
List.of(
new TypedBreak()
)
),
null,
Type.VOID
)
)
),
Type.VOID
)
)
),
Type.VOID
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(),
block
);
}
private static TypedConstructor getConstructor2() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of()
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of()
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(7),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(13),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedBinary(
new TypedBinary(
new TypedMethodCall(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getX",
Type.INT
),
List.of(),
Type.INT
),
Operator.MUL,
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
Operator.MUL,
new TypedMethodCall(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getX",
Type.INT
),
List.of(
new TypedCharLiteral(
'g',
Type.CHAR
)
),
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"c",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(25),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"c",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
)
),
block
);
}
private static TypedConstructor getConstructor3() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
)
),
block
);
}
private static TypedConstructor getConstructor4() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
),
new TypedParameter(
"z",
Type.CHAR
)
),
block
);
}
private static List<TypedMethod> getMethods() {
return List.of(
getMethod1(),
getMethod2(),
getMethod3(),
getMethod4(),
getMethod5(),
getMethod6()
);
}
private static TypedMethod getMethod1() {
TypedBlock block = new TypedBlock(
List.of(
new TypedLocalVariable("a", Type.INT)
),
List.of(
new TypedAssignment(
new TypedIntLiteral(10),
new TypedFieldVarAccess(
false,
null,
"a",
Type.REFERENCE("ComplexClass")
),
Type.INT
),
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
)
)
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(10),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"a",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(20),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(20),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"a",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"c",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedIfElse(
new TypedMethodCall(
new TypedFieldVarAccess(
false,
null,
"methodCall",
Type.BOOL
),
List.of(),
Type.BOOL
),
new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
new TypedMethodCall(
new TypedFieldVarAccess(
false,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getC",
Type.REFERENCE("ComplexClass")
),
List.of(),
Type.REFERENCE("ComplexClass")
),
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
)
)
),
null,
Type.VOID
),
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"initComplexClass",
Type.REFERENCE("ComplexClass"),
List.of(
new TypedParameter(
"x",
Type.INT
)
),
List.of(),
block
);
}
private static TypedMethod getMethod2() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
)
)
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"init",
Type.REFERENCE("ComplexClass"),
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
)
),
List.of(),
block
);
}
private static TypedMethod getMethod3() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
)
)
);
return new TypedMethod(
"getX",
Type.INT,
List.of(
new TypedParameter(
"z",
Type.CHAR
)
),
List.of(),
block
);
}
private static TypedMethod getMethod4() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"c",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"getC",
Type.REFERENCE("ComplexClass"),
List.of(),
List.of(),
block
);
}
private static TypedMethod getMethod5() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
)
)
);
return new TypedMethod(
"getX",
Type.INT,
List.of(),
List.of(),
block
);
}
private static TypedMethod getMethod6() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedBoolLiteral(
false,
Type.BOOL
),
Type.BOOL
)
)
);
return new TypedMethod(
"methodCall",
Type.BOOL,
List.of(),
List.of(),
block
);
}
}

View File

@ -31,7 +31,8 @@ public class TypedAbstractSyntax_PublicClass {
null,
Type.REFERENCE("PublicClass")
)
)
),
null
);
}
}

View File

@ -0,0 +1,16 @@
import de.maishai.Compiler;
import de.maishai.ast.records.Program;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CodegeneratorTests {
// @Test
// public void testPublicClass() {
// byte[] resultBytecode = Compiler.generateByteCodeArrayFromTypedAst();
// assertEquals(AbstractSyntax_PublicClass.get(), resultBytecode);
// }
}

View File

@ -59,6 +59,6 @@ public class ScannerParserTests {
@Test
public void testComplexClass() {
Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ComplexClass.java"));
assertEquals(AbstractSyntax_ClassWithConstructorAndMethodCall.get(), resultAst);
assertEquals(TypedAbstractSyntax_ComplexClass.get(), resultAst);
}
}

View File

@ -23,4 +23,10 @@ public class TypingTests {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ClassWithConstructor.get());
assertEquals(TypedAbstractSyntax_ClassWithConstructor.get(), resultTypedAst);
}
@Test
public void testComplexClass() {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ComplexClass.get());
assertEquals(TypedAbstractSyntax_ComplexClass.get(), resultTypedAst);
}
}