mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 17:08:03 +00:00
make new work
This commit is contained in:
parent
a3d7c1da7e
commit
017014c0ce
@ -106,9 +106,11 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
|
|||||||
public Expression visitNew(DecafParser.NewContext ctx) {
|
public Expression visitNew(DecafParser.NewContext ctx) {
|
||||||
Type type = ASTGenerator.getType(ctx.type());
|
Type type = ASTGenerator.getType(ctx.type());
|
||||||
List<Expression> args = new ArrayList<>();
|
List<Expression> args = new ArrayList<>();
|
||||||
for (var expr : ctx.args().expr()) {
|
if (ctx.args() != null) {
|
||||||
Expression astExpr = expr.accept(this);
|
for (var expr : ctx.args().expr()) {
|
||||||
args.add(astExpr);
|
Expression astExpr = expr.accept(this);
|
||||||
|
args.add(astExpr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new New(type, args);
|
return new New(type, args);
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,14 @@ import java.util.List;
|
|||||||
|
|
||||||
public class CodeGenUtils {
|
public class CodeGenUtils {
|
||||||
|
|
||||||
public static String generateDescriptor(List<TypedParameter> arguments, Type returnType) {
|
public static String generateDescriptor(List<Type> argTypes, Type returnType) {
|
||||||
if (returnType == null) {
|
if (returnType == null) {
|
||||||
returnType = Type.VOID;
|
returnType = Type.VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append('(');
|
builder.append('(');
|
||||||
arguments.forEach(type -> builder.append(type.getType().getDescriptor()));
|
argTypes.forEach(type -> builder.append(type.getDescriptor()));
|
||||||
builder.append(')');
|
builder.append(')');
|
||||||
builder.append(returnType.getDescriptor());
|
builder.append(returnType.getDescriptor());
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
|
@ -59,12 +59,19 @@ public class MethodContext {
|
|||||||
System.out.println("Pushed " + variableIndex.get(varName) + " to stack");
|
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 () {
|
public void pushInstantToStack () {
|
||||||
stack.push(localVarIndex);
|
stack.push(localVarIndex);
|
||||||
if (stack.size() > maxStack) {
|
if (stack.size() > maxStack) {
|
||||||
maxStack = stack.size();
|
maxStack = stack.size();
|
||||||
}
|
}
|
||||||
System.out.println("Pushed instant to stack");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void popStack() {
|
public void popStack() {
|
||||||
|
@ -64,24 +64,41 @@ public class TypedAssignment implements TypedStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
public void codeGen(MethodContext ctx) {
|
||||||
ctx.pushStack("this");
|
if(value instanceof TypedNew) {
|
||||||
System.out.println("left: " + location);
|
value.codeGen(ctx);
|
||||||
System.out.println("right: " + value);
|
getOwnerChain(ctx);
|
||||||
// load location recursively on stack
|
} else {
|
||||||
location.codeGen(ctx);
|
ctx.pushStack("this");
|
||||||
|
getOwnerChain(ctx);
|
||||||
|
value.codeGen(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
// put value on stack (WIP!!)
|
|
||||||
//ctx.pushStack("x");
|
|
||||||
value.codeGen(ctx);
|
|
||||||
|
|
||||||
//save value in field
|
//save value in field
|
||||||
String receiver = ctx.getClassContext().getName();
|
if (location.getField()) {
|
||||||
if (location.getRecursiveOwnerChain() != null) {
|
|
||||||
receiver = location.getRecursiveOwnerChain().getType().getReference();
|
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();
|
||||||
}
|
}
|
||||||
ctx.getMv().visitFieldInsn(Opcodes.PUTFIELD, receiver, location.getName(), value.getType().getDescriptor());
|
|
||||||
ctx.popStack();
|
|
||||||
ctx.popStack();
|
|
||||||
System.out.println("PUTFIELD: " + receiver + " " + location.getName() + " " + value.getType().getDescriptor());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,8 @@ public class TypedConstructor implements TypedNode {
|
|||||||
|
|
||||||
public void codeGen(ClassContext ctx) {
|
public void codeGen(ClassContext ctx) {
|
||||||
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
|
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, Type.VOID));
|
System.out.println("Visiting method: " + "<init>" + CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID));
|
||||||
MethodContext mctx = new MethodContext(ctx, mv);
|
MethodContext mctx = new MethodContext(ctx, mv);
|
||||||
typedParameters.forEach(param -> mctx.registerVariable(param.getParaName(), param.getType()));
|
typedParameters.forEach(param -> mctx.registerVariable(param.getParaName(), param.getType()));
|
||||||
//super();
|
//super();
|
||||||
|
@ -77,17 +77,18 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
public void codeGen(MethodContext ctx) {
|
||||||
if (!field && recursiveOwnerChain == null && ctx.getLocalVar(name).isPresent() && ctx.getLocalVar(name).get().type().equals(type)) {
|
|
||||||
// load local variable
|
|
||||||
ctx.pushStack(name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (recursiveOwnerChain != null) {
|
if (recursiveOwnerChain != null) {
|
||||||
recursiveOwnerChain.codeGen(ctx);
|
recursiveOwnerChain.codeGen(ctx);
|
||||||
}
|
}
|
||||||
if (!field) {
|
if (field && recursiveOwnerChain == null) {
|
||||||
ctx.getMv().visitFieldInsn(Opcodes.GETFIELD, ctx.getClassContext().getName(), name, type.getDescriptor());
|
ctx.pushStack("this");
|
||||||
System.out.println("GETFIELD: " + ctx.getClassContext().getName() + " " + name + " " + type.getDescriptor());
|
}
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -41,7 +42,16 @@ public class TypedIntLiteral implements TypedExpression {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
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();
|
ctx.pushInstantToStack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ public class TypedMethod implements TypedNode {
|
|||||||
public void codeGen(ClassContext ctx) {
|
public void codeGen(ClassContext ctx) {
|
||||||
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
|
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
|
||||||
MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, name,
|
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);
|
MethodContext context = new MethodContext(ctx, mv);
|
||||||
typedParameters.forEach(param -> context.registerVariable(param.getParaName(), param.getType()));
|
typedParameters.forEach(param -> context.registerVariable(param.getParaName(), param.getType()));
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import de.maishai.ast.records.New;
|
|||||||
import de.maishai.typedast.*;
|
import de.maishai.typedast.*;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -50,6 +51,21 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
public class ClassCanBeTyped {
|
|
||||||
public ClassCanBeTyped p;
|
public class ClassCanBeTyped{
|
||||||
|
public int c;
|
||||||
|
public ClassCanBeTyped d;
|
||||||
public int x;
|
public int x;
|
||||||
public boolean y;
|
|
||||||
|
|
||||||
|
public ClassCanBeTyped() {
|
||||||
|
}
|
||||||
|
|
||||||
public int test(boolean b, boolean c) {
|
public ClassCanBeTyped(int x) {
|
||||||
int y;
|
this.x = x;
|
||||||
y = 0;
|
}
|
||||||
if (b && c) {
|
|
||||||
y = 12;
|
public ClassCanBeTyped test(int i) {
|
||||||
}
|
ClassCanBeTyped a;
|
||||||
return y;
|
a = new ClassCanBeTyped(i);
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user