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{
|
||||
Integer m(Integer x){
|
||||
var c = x + 2;
|
||||
// Boolean b = true;
|
||||
// c = 5;
|
||||
// c++;
|
||||
// ++c;
|
||||
// c--;
|
||||
// --c;
|
||||
// while(x<2){
|
||||
// x = x +1;
|
||||
// b = false;
|
||||
// }
|
||||
return c;
|
||||
// for(int i = 0;i<10;i++) {
|
||||
// x = x + 5;
|
||||
// }
|
||||
Boolean b = true;
|
||||
c = 5;
|
||||
c++;
|
||||
++c;
|
||||
c--;
|
||||
--c;
|
||||
while(x<2){
|
||||
x = x +1;
|
||||
b = false;
|
||||
}
|
||||
for(int i = 0; i<10; i++) {
|
||||
x = x + 5;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// m2(Integer x){
|
||||
|
@ -866,7 +866,8 @@ public class Codegen {
|
||||
state.enterScope();
|
||||
var localCounter = state.localCounter;
|
||||
if (_for.init() != null)
|
||||
generate(state, _for.init());
|
||||
_for.init().forEach(e -> generate(state, e));
|
||||
|
||||
Label start = new Label();
|
||||
Label end = new Label();
|
||||
mv.visitLabel(start);
|
||||
@ -885,10 +886,12 @@ public class Codegen {
|
||||
state.breakStack.pop();
|
||||
|
||||
if (_for.increment() != null) {
|
||||
generate(state, _for.increment());
|
||||
if (_for.increment().type() != null) {
|
||||
popValue(state, _for.increment().type());
|
||||
}
|
||||
_for.increment().forEach(e -> {
|
||||
generate(state, e);
|
||||
if (e.type() != null) {
|
||||
popValue(state, e.type());
|
||||
}
|
||||
});
|
||||
}
|
||||
mv.visitJumpInsn(GOTO, start);
|
||||
mv.visitLabel(end);
|
||||
|
@ -11,6 +11,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
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.JavaClassName;
|
||||
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.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
@ -522,7 +489,18 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -163,7 +163,7 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
forStmt.body_Loop_block.accept(this);
|
||||
forStmt.block.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,24 +2,29 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ForStmt extends Statement
|
||||
{
|
||||
|
||||
private Expression head_Initializer_1;
|
||||
private Expression head_Condition_1;
|
||||
private Expression head_Loop_expr_1;
|
||||
private Expression head_Initializer;
|
||||
private Expression head_Condition;
|
||||
private Expression head_Loop_expr;
|
||||
public Block body_Loop_block;
|
||||
public final List<Statement> initializer;
|
||||
public final Expression condition;
|
||||
public final List<Expression> loopExpr;
|
||||
public final Statement 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
|
||||
|
@ -139,8 +139,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
// TODO Doesn't seem to be fully implemented yet
|
||||
throw new NotImplementedException();
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,7 +63,7 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
forStmt.body_Loop_block.accept(this);
|
||||
forStmt.block.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
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.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
@ -156,7 +122,10 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@ -725,6 +725,15 @@ public class TestComplete {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
|
||||
var clazz = classFiles.get("Static");
|
||||
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
|
||||
public void testFor() throws Exception {
|
||||
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());
|
||||
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user