forked from JavaTX/JavaCompilerCore
Translate for loop
This commit is contained in:
parent
b372c6ac1c
commit
5d0d7a6d94
@ -4,20 +4,20 @@ import java.lang.Boolean;
|
|||||||
class For{
|
class For{
|
||||||
Integer m(Integer x){
|
Integer m(Integer x){
|
||||||
var c = x + 2;
|
var c = x + 2;
|
||||||
// Boolean b = true;
|
Boolean b = true;
|
||||||
// c = 5;
|
c = 5;
|
||||||
// c++;
|
c++;
|
||||||
// ++c;
|
++c;
|
||||||
// c--;
|
c--;
|
||||||
// --c;
|
--c;
|
||||||
// while(x<2){
|
while(x<2){
|
||||||
// x = x +1;
|
x = x +1;
|
||||||
// b = false;
|
b = false;
|
||||||
// }
|
}
|
||||||
return c;
|
for(int i = 0; i<10; i++) {
|
||||||
// for(int i = 0;i<10;i++) {
|
x = x + 5;
|
||||||
// x = x + 5;
|
}
|
||||||
// }
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m2(Integer x){
|
// m2(Integer x){
|
||||||
|
@ -866,7 +866,8 @@ public class Codegen {
|
|||||||
state.enterScope();
|
state.enterScope();
|
||||||
var localCounter = state.localCounter;
|
var localCounter = state.localCounter;
|
||||||
if (_for.init() != null)
|
if (_for.init() != null)
|
||||||
generate(state, _for.init());
|
_for.init().forEach(e -> generate(state, e));
|
||||||
|
|
||||||
Label start = new Label();
|
Label start = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
mv.visitLabel(start);
|
mv.visitLabel(start);
|
||||||
@ -885,10 +886,12 @@ public class Codegen {
|
|||||||
state.breakStack.pop();
|
state.breakStack.pop();
|
||||||
|
|
||||||
if (_for.increment() != null) {
|
if (_for.increment() != null) {
|
||||||
generate(state, _for.increment());
|
_for.increment().forEach(e -> {
|
||||||
if (_for.increment().type() != null) {
|
generate(state, e);
|
||||||
popValue(state, _for.increment().type());
|
if (e.type() != null) {
|
||||||
}
|
popValue(state, e.type());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
mv.visitJumpInsn(GOTO, start);
|
mv.visitJumpInsn(GOTO, start);
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
|
@ -11,6 +11,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
@ -96,40 +97,6 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.YieldstmtContext;
|
|||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BoolExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Break;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Switch;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.SwitchBlock;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.SwitchLabel;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Yield;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
@ -522,7 +489,18 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.ForloopContext stmt) {
|
private Statement convert(Java17Parser.ForloopContext stmt) {
|
||||||
throw new NotImplementedException();
|
var control = stmt.forControl();
|
||||||
|
var block = convert(stmt.statement());
|
||||||
|
if (control.enhancedForControl() != null)
|
||||||
|
throw new NotImplementedException();
|
||||||
|
else {
|
||||||
|
return new ForStmt(
|
||||||
|
stmt.getStart(),
|
||||||
|
convert(control.forInit().localVariableDeclaration()),
|
||||||
|
convert(control.expression()), control.forUpdate.expression().stream().map(this::convert).toList(),
|
||||||
|
block
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArgumentList convertArguments(Java17Parser.ExpressionListContext arglist) {
|
private ArgumentList convertArguments(Java17Parser.ExpressionListContext arglist) {
|
||||||
|
@ -163,7 +163,7 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
forStmt.body_Loop_block.accept(this);
|
forStmt.block.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,24 +2,29 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.statement;
|
package de.dhbwstuttgart.syntaxtree.statement;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ForStmt extends Statement
|
public class ForStmt extends Statement
|
||||||
{
|
{
|
||||||
|
public final List<Statement> initializer;
|
||||||
private Expression head_Initializer_1;
|
public final Expression condition;
|
||||||
private Expression head_Condition_1;
|
public final List<Expression> loopExpr;
|
||||||
private Expression head_Loop_expr_1;
|
public final Statement block;
|
||||||
private Expression head_Initializer;
|
|
||||||
private Expression head_Condition;
|
|
||||||
private Expression head_Loop_expr;
|
|
||||||
public Block body_Loop_block;
|
|
||||||
|
|
||||||
public ForStmt(int offset, int variableLength)
|
public ForStmt(Token offset, List<Statement> initializer, Expression condition, List<Expression> loopExpr, Statement block)
|
||||||
{
|
{
|
||||||
super(null,null);
|
super(new Void(new NullToken()), offset);
|
||||||
|
this.initializer = initializer;
|
||||||
|
this.condition = condition;
|
||||||
|
this.loopExpr = loopExpr;
|
||||||
|
this.block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -139,8 +139,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
// TODO Doesn't seem to be fully implemented yet
|
result = new TargetFor(forStmt.initializer.stream().map(converter::convert).toList(), converter.convert(forStmt.condition), forStmt.loopExpr.stream().map(converter::convert).toList(), converter.convert(forStmt.block));
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -63,7 +63,7 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
forStmt.body_Loop_block.accept(this);
|
forStmt.block.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.tree.expression;
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import java.util.List;
|
||||||
|
|
||||||
public record TargetFor(TargetExpression init, TargetExpression termination, TargetExpression increment, TargetExpression body) implements TargetExpression {
|
public record TargetFor(List<TargetExpression> init, TargetExpression termination, List<TargetExpression> increment, TargetExpression body) implements TargetExpression {
|
||||||
}
|
}
|
||||||
|
@ -12,41 +12,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
|
|||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BoolExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Break;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Switch;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.SwitchBlock;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.SwitchLabel;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Yield;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
@ -156,7 +122,10 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
throw new NotImplementedException();
|
forStmt.initializer.forEach(s -> s.accept(this));
|
||||||
|
forStmt.condition.accept(this);
|
||||||
|
forStmt.loopExpr.forEach(e -> e.accept(this));
|
||||||
|
forStmt.block.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -725,6 +725,15 @@ public class TestComplete {
|
|||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
|
||||||
var clazz = classFiles.get("Static");
|
var clazz = classFiles.get("Static");
|
||||||
var m = clazz.getDeclaredMethod("m");
|
var m = clazz.getDeclaredMethod("m");
|
||||||
assertEquals(m.invoke(null), 30);
|
assertEquals(m.invoke(null), 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFor() throws Exception {
|
||||||
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "For.jav");
|
||||||
|
var clazz = classFiles.get("For");
|
||||||
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
var m = clazz.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instance, 10), 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ public class TestCodegen {
|
|||||||
@Test
|
@Test
|
||||||
public void testFor() throws Exception {
|
public void testFor() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0))), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user