diff --git a/.idea/.gitignore b/.idea/.gitignore index 13566b8..a9d7db9 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -6,3 +6,5 @@ # Datasource local storage ignored files /dataSources/ /dataSources.local.xml +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/.idea/copilot/chatSessions/00000000000.xd b/.idea/copilot/chatSessions/00000000000.xd index 16799c9..a3122a8 100644 Binary files a/.idea/copilot/chatSessions/00000000000.xd and b/.idea/copilot/chatSessions/00000000000.xd differ diff --git a/.idea/copilot/chatSessions/xd.lck b/.idea/copilot/chatSessions/xd.lck index 88b7cff..744d48d 100644 --- a/.idea/copilot/chatSessions/xd.lck +++ b/.idea/copilot/chatSessions/xd.lck @@ -1,4 +1,4 @@ -Private property of Exodus: 36669@Simon-Lenovo-Ubuntu +Private property of Exodus: 41264@Simon-Lenovo-Ubuntu jetbrains.exodus.io.LockingManager.lock(LockingManager.kt:88) jetbrains.exodus.io.LockingManager.lock(LockingManager.kt:39) @@ -33,7 +33,7 @@ com.intellij.util.messages.impl.MessageBusImplKt.deliverMessage(MessageBusImpl.k com.intellij.util.messages.impl.MessageBusImplKt.pumpWaiting(MessageBusImpl.kt:402) com.intellij.util.messages.impl.MessageBusImplKt.access$pumpWaiting(MessageBusImpl.kt:1) com.intellij.util.messages.impl.MessagePublisher.invoke(MessageBusImpl.kt:461) -jdk.proxy7/jdk.proxy7.$Proxy158.onCopilotStatus(Unknown Source) +jdk.proxy6/jdk.proxy6.$Proxy166.onCopilotStatus(Unknown Source) com.github.copilot.status.CopilotStatusService.notifyApplication(CopilotStatusService.java:76) com.github.copilot.status.CopilotStatusService.notifyApplication(CopilotStatusService.java:64) com.github.copilot.github.GitHubAuthStartupActivity.handleAuthNotifications(GitHubAuthStartupActivity.java:54) diff --git a/src/main/java/de/dhbw/horb/ASTGenerator.java b/src/main/java/de/dhbw/horb/ASTGenerator.java index 90eb5df..ca13d9b 100644 --- a/src/main/java/de/dhbw/horb/ASTGenerator.java +++ b/src/main/java/de/dhbw/horb/ASTGenerator.java @@ -1,47 +1,28 @@ package de.dhbw.horb; import de.dhbw.horb.antlr.DecafParser; -import de.dhbw.horb.ast.Function; -import de.dhbw.horb.ast.Program; -import de.dhbw.horb.ast.Type; -import de.dhbw.horb.ast.Variable; +import de.dhbw.horb.ast.*; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; public class ASTGenerator { - public static Program generateAST(DecafParser.ProgramContext parseTree){ - List variables = new ArrayList<>(); - for(DecafParser.VarContext varCtx : parseTree.var()){ - variables.add(generateVariable(varCtx)); - } - List funcs = new ArrayList<>(); - for(DecafParser.FuncContext fctx : parseTree.func()){ - funcs.add(generateFunc(fctx)); - } + public static Program generateAST(DecafParser.ProgramContext parseTree) { + List variables = parseTree.var().stream().map(var -> new Variable(var.id().getText(), Type.mapType(var.type().getText()))).toList(); + List funcs = parseTree.func().stream().map(ASTGenerator::generateFunc).toList(); return new Program(variables, funcs); } - public static Variable generateVariable(DecafParser.VarContext ctx) { - return new Variable(ctx.id().getText(), getType(ctx.type())); - } - - public static Variable generateVariable(DecafParser.ParamContext ctx) { - return new Variable(ctx.id().getText(), getType(ctx.type())); - } - public static Function generateFunc(DecafParser.FuncContext ctx) { - throw new RuntimeException("TODO"); - } - - public static Type getType(DecafParser.TypeContext ctx){ - if(ctx.INT() != null) - return Type.INT; - if(ctx.BOOL() != null) - return Type.BOOL; - if(ctx.VOID() != null) - return Type.VOID; - throw new RuntimeException(); + Type t = Type.mapType(ctx.type().getText()); + String id = ctx.id().getText(); + List params = Optional.ofNullable(ctx.params()) + .map(p -> p.param().stream().map(param -> new Variable(param.getText(), Type.mapType(param.type().getText()))).collect(Collectors.toList())) + .orElseGet(ArrayList::new); + Block block = new BlockGenerator().visit(ctx.block()); + return new Function(t, id, params, block); } } diff --git a/src/main/java/de/dhbw/horb/BlockGenerator.java b/src/main/java/de/dhbw/horb/BlockGenerator.java new file mode 100644 index 0000000..6119b77 --- /dev/null +++ b/src/main/java/de/dhbw/horb/BlockGenerator.java @@ -0,0 +1,21 @@ +package de.dhbw.horb; + +import de.dhbw.horb.antlr.DecafBaseVisitor; +import de.dhbw.horb.antlr.DecafParser; +import de.dhbw.horb.ast.Block; +import de.dhbw.horb.ast.Statement; +import de.dhbw.horb.ast.Type; +import de.dhbw.horb.ast.Variable; + +import java.util.List; + +public class BlockGenerator extends DecafBaseVisitor { + + @Override + public Block visitBlock(DecafParser.BlockContext ctx) { + List vars = ctx.var().stream().map(var -> new Variable(var.id().getText(), Type.mapType(var.type().getText()))).toList(); + List stmts = ctx.stmt().stream().map(stmt -> new StatementGenerator().visit(stmt)).toList(); + return new Block(vars, stmts); + } + +} diff --git a/src/main/java/de/dhbw/horb/StatementGenerator.java b/src/main/java/de/dhbw/horb/StatementGenerator.java index 48ca10e..3679c62 100644 --- a/src/main/java/de/dhbw/horb/StatementGenerator.java +++ b/src/main/java/de/dhbw/horb/StatementGenerator.java @@ -2,42 +2,47 @@ package de.dhbw.horb; import de.dhbw.horb.antlr.DecafBaseVisitor; import de.dhbw.horb.antlr.DecafParser; -import de.dhbw.horb.ast.Statement; +import de.dhbw.horb.ast.*; + +import java.util.ArrayList; public class StatementGenerator extends DecafBaseVisitor { @Override public Statement visitAssign(DecafParser.AssignContext ctx) { - throw new RuntimeException("TODO"); + return new Assignment(new Location(ctx.loc().getText()), new ExpressionGenerator().visit(ctx.expr())); } @Override public Statement visitIf(DecafParser.IfContext ctx) { - throw new RuntimeException("TODO"); + Block elseBlock = new Block(new ArrayList<>(), new ArrayList<>()); + if (ctx.block().size() > 1) + elseBlock = new BlockGenerator().visit(ctx.block(1)); + return new IfElse(new ExpressionGenerator().visit(ctx.expr()), new BlockGenerator().visit(ctx.block(0)), elseBlock); } @Override public Statement visitWhile(DecafParser.WhileContext ctx) { - throw new RuntimeException("TODO"); + return new While(new ExpressionGenerator().visit(ctx.expr()), new BlockGenerator().visit(ctx.block())); } @Override public Statement visitReturn(DecafParser.ReturnContext ctx) { - throw new RuntimeException("TODO"); + return new Return(new ExpressionGenerator().visit(ctx.expr())); } @Override public Statement visitReturnVoid(DecafParser.ReturnVoidContext ctx) { - throw new RuntimeException("TODO"); + return new ReturnVoid(); } @Override public Statement visitBreak(DecafParser.BreakContext ctx) { - throw new RuntimeException("TODO"); + return new Break(); } @Override public Statement visitContinue(DecafParser.ContinueContext ctx) { - throw new RuntimeException("TODO"); + return new Continue(); } } diff --git a/src/main/java/de/dhbw/horb/ast/Type.java b/src/main/java/de/dhbw/horb/ast/Type.java index 3004d76..ab35d97 100644 --- a/src/main/java/de/dhbw/horb/ast/Type.java +++ b/src/main/java/de/dhbw/horb/ast/Type.java @@ -3,5 +3,14 @@ package de.dhbw.horb.ast; public enum Type { INT, BOOL, - VOID + VOID; + + public static Type mapType(String type){ + return switch (type) { + case "int" -> Type.INT; + case "bool" -> Type.BOOL; + case "void" -> Type.VOID; + default -> throw new RuntimeException("Unknown type: " + type); + }; + } } diff --git a/src/test/java/de/dhbw/horb/CompilerTest.java b/src/test/java/de/dhbw/horb/CompilerTest.java index 79d1049..b89cd8b 100644 --- a/src/test/java/de/dhbw/horb/CompilerTest.java +++ b/src/test/java/de/dhbw/horb/CompilerTest.java @@ -1,5 +1,6 @@ package de.dhbw.horb; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import de.dhbw.horb.ast.Program; @@ -8,14 +9,12 @@ import org.junit.Test; /** * Unit test for simple App. */ -public class CompilerTest -{ +public class CompilerTest { /** * Rigorous Test :-) */ @Test - public void generateASTTest() - { + public void generateASTTest() { String inputString = "def int add(int x, int y)\n" + "{\n" + "return x + y;\n" + @@ -27,6 +26,6 @@ public class CompilerTest "return add(a, 2);\n" + "}"; Program ast = Compiler.generateAST(inputString); - assertTrue( ast.methods().size() == 2 ); + assertEquals(2, ast.methods().size()); } } diff --git a/src/test/java/de/dhbw/horb/ExpressionGeneratorTest.java b/src/test/java/de/dhbw/horb/ExpressionGeneratorTest.java index eaf7de5..6f7b361 100644 --- a/src/test/java/de/dhbw/horb/ExpressionGeneratorTest.java +++ b/src/test/java/de/dhbw/horb/ExpressionGeneratorTest.java @@ -8,6 +8,7 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** @@ -36,8 +37,8 @@ public class ExpressionGeneratorTest { Expression mCall = generateExpression("m(x,y)"); assertTrue(mCall instanceof FunctionCall); - assertTrue(((FunctionCall) mCall).name().equals("m")); - assertTrue(((FunctionCall) mCall).args().size() == 2); + assertEquals("m", ((FunctionCall) mCall).name()); + assertEquals(2, ((FunctionCall) mCall).args().size()); } @Test diff --git a/src/test/java/de/dhbw/horb/StatementGeneratorTest.java b/src/test/java/de/dhbw/horb/StatementGeneratorTest.java index 2a659bb..3f10d2e 100644 --- a/src/test/java/de/dhbw/horb/StatementGeneratorTest.java +++ b/src/test/java/de/dhbw/horb/StatementGeneratorTest.java @@ -8,24 +8,63 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Unit test for AST Generation of Expressions. */ -public class StatementGeneratorTest -{ +public class StatementGeneratorTest { @Test - public void whileTest() - { + public void whileTest() { Statement whileStmt = generateStatement("while(true){}"); assertTrue(whileStmt instanceof While); - assertTrue( ((While) whileStmt).block().stmts().size() == 0); + assertEquals(0, ((While) whileStmt).block().stmts().size()); } - private Statement generateStatement(String from){ - String inputString = from; - CharStream input = CharStreams.fromString(inputString); + @Test + public void whileTest2() { + Statement whileStmt = generateStatement("while(true){int x; x= 3;}"); + assertTrue(whileStmt instanceof While); + assertEquals(1, ((While) whileStmt).block().vars().size()); + assertEquals(1, ((While) whileStmt).block().stmts().size()); + } + + @Test + public void ifTest() { + Statement ifStmt = generateStatement("if(true){}"); + assertTrue(ifStmt instanceof IfElse); + assertTrue(((IfElse) ifStmt).ifBlock().stmts().isEmpty()); + } + + @Test + public void ifTest2() { + Statement ifStmt = generateStatement("if(true){bool cool; cool = true;}"); + assertTrue(ifStmt instanceof IfElse); + assertEquals(1, ((IfElse) ifStmt).ifBlock().vars().size()); + assertEquals(1, ((IfElse) ifStmt).ifBlock().stmts().size()); + } + + @Test + public void ifElseTest() { + Statement ifElseStmt = generateStatement("if(true){}else{}"); + assertTrue(ifElseStmt instanceof IfElse); + assertTrue(((IfElse) ifElseStmt).ifBlock().stmts().isEmpty()); + assertTrue(((IfElse) ifElseStmt).elseBlock().stmts().isEmpty()); + } + + @Test + public void ifElseTest2() { + Statement ifElseStmt = generateStatement("if(true){int x; x = 3;}else{int y; y = 4;}"); + assertTrue(ifElseStmt instanceof IfElse); + assertEquals(1, ((IfElse) ifElseStmt).ifBlock().vars().size()); + assertEquals(1, ((IfElse) ifElseStmt).ifBlock().stmts().size()); + assertEquals(1, ((IfElse) ifElseStmt).elseBlock().vars().size()); + assertEquals(1, ((IfElse) ifElseStmt).elseBlock().stmts().size()); + } + + private Statement generateStatement(String from) { + CharStream input = CharStreams.fromString(from); DecafLexer lexer = new DecafLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); DecafParser parser = new DecafParser(tokens);