finish StatmentGenerator
This commit is contained in:
parent
f69e5df5e7
commit
e7ab233f1e
@ -2,6 +2,7 @@ package de.dhbw.horb;
|
|||||||
|
|
||||||
import de.dhbw.horb.ast.*;
|
import de.dhbw.horb.ast.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
|
public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
|
||||||
@ -34,7 +35,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
|
|||||||
|
|
||||||
public static FunctionCall generateFunctionCall(DecafParser.FuncCallContext ctx) {
|
public static FunctionCall generateFunctionCall(DecafParser.FuncCallContext ctx) {
|
||||||
String name = ctx.id().getText();
|
String name = ctx.id().getText();
|
||||||
List<DecafParser.ExprContext> expressions = ctx.args().expr();
|
List<DecafParser.ExprContext> expressions = ctx.args() == null ? Collections.emptyList() : ctx.args().expr();
|
||||||
List<Expression> args = expressions.stream()
|
List<Expression> args = expressions.stream()
|
||||||
.map(exp -> new ExpressionGenerator().visit(exp)).toList();
|
.map(exp -> new ExpressionGenerator().visit(exp)).toList();
|
||||||
return new FunctionCall(name, args);
|
return new FunctionCall(name, args);
|
||||||
|
@ -2,43 +2,74 @@ package de.dhbw.horb;
|
|||||||
|
|
||||||
import de.dhbw.horb.ast.*;
|
import de.dhbw.horb.ast.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class StatementGenerator extends DecafBaseVisitor<Statement> {
|
public class StatementGenerator extends DecafBaseVisitor<Statement> {
|
||||||
@Override
|
@Override
|
||||||
public Statement visitAssign(DecafParser.AssignContext ctx) {
|
public Statement visitAssign(DecafParser.AssignContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
Location loc = ExpressionGenerator.generateLocation(ctx.loc());
|
||||||
|
Expression exp = ctx.expr().accept(new ExpressionGenerator());
|
||||||
|
return new Assignment(loc, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement visitFunctionCall(DecafParser.FunctionCallContext ctx) {
|
||||||
|
return ExpressionGenerator.generateFunctionCall(ctx.funcCall());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitIf(DecafParser.IfContext ctx) {
|
public Statement visitIf(DecafParser.IfContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
Expression exp = ctx.accept(new ExpressionGenerator());
|
||||||
|
Block ifBlock = generateBlock(ctx.block(0));
|
||||||
|
Block elseBlock = ctx.block().size() > 1 ?
|
||||||
|
generateBlock(ctx.block(1)) :
|
||||||
|
new Block(Collections.emptyList(), Collections.emptyList());
|
||||||
|
return new IfElse(exp, ifBlock, elseBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitWhile(DecafParser.WhileContext ctx) {
|
public Statement visitWhile(DecafParser.WhileContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
return new While(ctx.expr().accept(new ExpressionGenerator()), generateBlock(ctx.block()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitReturn(DecafParser.ReturnContext ctx) {
|
public Statement visitReturn(DecafParser.ReturnContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
return new Return(ctx.expr().accept(new ExpressionGenerator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitReturnVoid(DecafParser.ReturnVoidContext ctx) {
|
public Statement visitReturnVoid(DecafParser.ReturnVoidContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
return new ReturnVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitBreak(DecafParser.BreakContext ctx) {
|
public Statement visitBreak(DecafParser.BreakContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
return new Break();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement visitContinue(DecafParser.ContinueContext ctx) {
|
public Statement visitContinue(DecafParser.ContinueContext ctx) {
|
||||||
throw new RuntimeException("TODO");
|
return new Continue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Block generateBlock(DecafParser.BlockContext ctx) {
|
||||||
|
List<Variable> vars = ctx.var().stream().map(StatementGenerator::generateVariable).toList();
|
||||||
|
List<Statement> stmt = ctx.stmt().stream().map(this::visit).toList();
|
||||||
|
return new Block(vars, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Variable generateVariable(DecafParser.VarContext ctx) {
|
||||||
|
Type type;
|
||||||
|
if (ctx.type().INT() != null) {
|
||||||
|
type = Type.INT;
|
||||||
|
} else if (ctx.type().BOOL() != null) {
|
||||||
|
type = Type.BOOL;
|
||||||
|
} else if (ctx.type().VOID() != null) {
|
||||||
|
type = Type.VOID;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unknown Type");
|
||||||
|
}
|
||||||
|
return new Variable(ctx.id().getText(), type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ package de.dhbw.horb.ast;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public record FunctionCall(String name, List<Expression> args) implements Expression {
|
public record FunctionCall(String name, List<Expression> args) implements Expression, Statement {
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package de.dhbw.horb.ast;
|
package de.dhbw.horb.ast;
|
||||||
|
|
||||||
public sealed interface Statement extends Node permits Assignment, VoidFunctionCall, IfElse, While, Return, ReturnVoid, Break, Continue {
|
public sealed interface Statement extends Node permits Assignment, Break, Continue, FunctionCall, IfElse, Return, ReturnVoid, VoidFunctionCall, While {
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,40 @@ import org.antlr.v4.runtime.CommonTokenStream;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test for AST Generation of Expressions.
|
* Unit test for AST Generation of Expressions.
|
||||||
*/
|
*/
|
||||||
public class StatementGeneratorTest
|
public class StatementGeneratorTest
|
||||||
{
|
{
|
||||||
|
@Test
|
||||||
|
public void ifTest() {
|
||||||
|
Statement stmt = generateStatement("if (true) { break; }");
|
||||||
|
assertTrue(stmt instanceof IfElse);
|
||||||
|
IfElse ifElse = (IfElse) stmt;
|
||||||
|
assertEquals(0, (ifElse.elseBlock().stmts().size()));
|
||||||
|
assertTrue(ifElse.ifBlock().stmts().get(0) instanceof Break);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifElseTest() {
|
||||||
|
Statement stmt = generateStatement("if (true) { int x; } else { return; }");
|
||||||
|
assertTrue(stmt instanceof IfElse);
|
||||||
|
IfElse ifElse = (IfElse) stmt;
|
||||||
|
assertEquals("x", ifElse.ifBlock().vars().get(0).name());
|
||||||
|
assertTrue(ifElse.elseBlock().stmts().get(0) instanceof ReturnVoid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void methodCall() {
|
||||||
|
Statement stmt = generateStatement("foo();");
|
||||||
|
assertTrue(stmt instanceof FunctionCall);
|
||||||
|
FunctionCall functionCall = (FunctionCall) stmt;
|
||||||
|
assertEquals(0, functionCall.args().size());
|
||||||
|
assertEquals("foo", functionCall.name());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whileTest()
|
public void whileTest()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user