From 018a80b0f78ead5ddb63aa801625777eb8449d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Tue, 3 Jun 2025 22:39:32 +0200 Subject: [PATCH] Added until statement --- .gitignore | 1 - prg/test.pins25 | 10 ++++++++++ src/pins25/common/Token.java | 4 ++++ src/pins25/phase/LexAn.java | 1 + src/pins25/phase/SynAn.java | 15 +++++++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 prg/test.pins25 diff --git a/.gitignore b/.gitignore index 585d773..5545717 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ out/ *.zip prg/**/*.ast prg/**/*.out -prg/**/*.pins25 \ No newline at end of file diff --git a/prg/test.pins25 b/prg/test.pins25 new file mode 100644 index 0000000..c88a2f4 --- /dev/null +++ b/prg/test.pins25 @@ -0,0 +1,10 @@ +var i = 0 + +fun main() = + until i >= 10 do + putint(i), + i = i + 1 + end, + 0 + +fun putint(n) \ No newline at end of file diff --git a/src/pins25/common/Token.java b/src/pins25/common/Token.java index 2685303..30f8f3b 100644 --- a/src/pins25/common/Token.java +++ b/src/pins25/common/Token.java @@ -57,6 +57,10 @@ public record Token(Report.Location location, Symbol symbol, String lexeme) impl * Kljucna beseda {@code while}. */ WHILE, + /** + * Kljucna beseda {@code until}. + */ + UNTIL, /** * Kljucna beseda {@code do}. */ diff --git a/src/pins25/phase/LexAn.java b/src/pins25/phase/LexAn.java index 888f692..83d1e82 100644 --- a/src/pins25/phase/LexAn.java +++ b/src/pins25/phase/LexAn.java @@ -315,6 +315,7 @@ public class LexAn implements AutoCloseable { case "then" -> Token.Symbol.THEN; case "else" -> Token.Symbol.ELSE; case "while" -> Token.Symbol.WHILE; + case "until" -> Token.Symbol.UNTIL; case "do" -> Token.Symbol.DO; case "let" -> Token.Symbol.LET; case "in" -> Token.Symbol.IN; diff --git a/src/pins25/phase/SynAn.java b/src/pins25/phase/SynAn.java index e4f2304..0f6d118 100644 --- a/src/pins25/phase/SynAn.java +++ b/src/pins25/phase/SynAn.java @@ -227,6 +227,21 @@ public class SynAn implements AutoCloseable { return whileStmt; } + case UNTIL: { + // statement -> until expression do statements end + Token untilT = check(Token.Symbol.UNTIL); + AST.Expr cond = parseExpression(); + check(Token.Symbol.DO); + List stmts = parseStatements(); + Token end = check(Token.Symbol.END); + + AST.Expr negCond = new AST.UnExpr(AST.UnExpr.Oper.NOT, cond); + + AST.WhileStmt whileStmt = new AST.WhileStmt(negCond, stmts); + attrLoc.put(whileStmt, new Report.Location(untilT, end)); + return whileStmt; + } + case LET: { // statement -> let definition reststmtdefs in statements end Token let = check(Token.Symbol.LET);