summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.bnf5
-rw-r--r--orang/src/main/java/lv/enes/orang/Main.java4
-rw-r--r--parser/src/main/java/lv/enes/orang/parser/Parser.java27
3 files changed, 26 insertions, 10 deletions
diff --git a/grammar.bnf b/grammar.bnf
index 0ac58f9..a9e21cb 100644
--- a/grammar.bnf
+++ b/grammar.bnf
@@ -1,7 +1,7 @@
1// Comments are introduced by # and terminated by newline 1// Comments are introduced by # and terminated by newline
2 2
3program ::= (statement ';'?)*; 3program ::= (statement ';'?)*;
4statement ::= definition | expression; 4statement ::= definition;
5definition ::= 'def' def-spec '=' expression 5definition ::= 'def' def-spec '=' expression
6 | 'def' '_' '=' expression; 6 | 'def' '_' '=' expression;
7def-spec ::= IDENTIFIER arg-spec*; 7def-spec ::= IDENTIFIER arg-spec*;
@@ -31,3 +31,6 @@ let-in-expression ::= 'let' def-spec '=' expression ('and' def-spec '=' expressi
31fn-expression ::= 'fn' arg-spec+ '->' expression 31fn-expression ::= 'fn' arg-spec+ '->' expression
32 | 'fn' arg-spec+ do-expression; 32 | 'fn' arg-spec+ do-expression;
33do-expression ::= 'do' expression (';' expression)* 'end'; 33do-expression ::= 'do' expression (';' expression)* 'end';
34
35repl-program ::= (repl-statement ';'?)* '\n'; // currently, hard-limited by the newline :sweat_smile:
36repl-statement ::= statement | expression; \ No newline at end of file
diff --git a/orang/src/main/java/lv/enes/orang/Main.java b/orang/src/main/java/lv/enes/orang/Main.java
index eb4bfcc..7175dac 100644
--- a/orang/src/main/java/lv/enes/orang/Main.java
+++ b/orang/src/main/java/lv/enes/orang/Main.java
@@ -10,7 +10,7 @@ import static lv.enes.orang.State.STDIN;
10import static lv.enes.orang.State.STDOUT; 10import static lv.enes.orang.State.STDOUT;
11 11
12public class Main { 12public class Main {
13 public static final String PROMPT = ">> "; 13 public static final String PROMPT = "orang-user> ";
14 14
15 public static void main() throws IOException { 15 public static void main() throws IOException {
16 repl(); 16 repl();
@@ -66,7 +66,7 @@ public class Main {
66 } 66 }
67 67
68 try { 68 try {
69 var prog = Parser.parseProgram(line); 69 var prog = Parser.parseReplProgram(line);
70 evaluator = evaluator.visitProgram(prog); 70 evaluator = evaluator.visitProgram(prog);
71 if (evaluator.lastResult() != null) { 71 if (evaluator.lastResult() != null) {
72 STDOUT.print("-> "); 72 STDOUT.print("-> ");
diff --git a/parser/src/main/java/lv/enes/orang/parser/Parser.java b/parser/src/main/java/lv/enes/orang/parser/Parser.java
index 3a2e931..9103123 100644
--- a/parser/src/main/java/lv/enes/orang/parser/Parser.java
+++ b/parser/src/main/java/lv/enes/orang/parser/Parser.java
@@ -27,9 +27,9 @@ public class Parser {
27 return parser.parseProgram(); 27 return parser.parseProgram();
28 } 28 }
29 29
30 public static Program parseProgram(String in) throws ParserException { 30 public static Program parseReplProgram(String in) throws ParserException {
31 var parser = new Parser(in); 31 var parser = new Parser(in);
32 return parser.parseProgram(); 32 return parser.parseReplProgram();
33 } 33 }
34 34
35 private final PeekableStream<Token> input; 35 private final PeekableStream<Token> input;
@@ -59,6 +59,15 @@ public class Parser {
59 return new Program(Collections.unmodifiableList(statements)); 59 return new Program(Collections.unmodifiableList(statements));
60 } 60 }
61 61
62 public Program parseReplProgram() throws ParserException {
63 var statements = new ArrayList<Statement>();
64 while (!maybeConsumeToken(Token.Type.EOF)) {
65 statements.add(parseReplLine());
66 maybeConsumeToken(Token.Type.SEMICOLON);
67 }
68 return new Program(Collections.unmodifiableList(statements));
69 }
70
62 private static boolean isNotBinaryOp(Token token) { 71 private static boolean isNotBinaryOp(Token token) {
63 return switch (token.type()) { 72 return switch (token.type()) {
64 case ASTERISK, SLASH, PLUS, MINUS, QUESTION_EQUAL, SLASH_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL 73 case ASTERISK, SLASH, PLUS, MINUS, QUESTION_EQUAL, SLASH_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL
@@ -275,6 +284,14 @@ public class Parser {
275 return new LetInExpression(Collections.unmodifiableList(bindings), body); 284 return new LetInExpression(Collections.unmodifiableList(bindings), body);
276 } 285 }
277 286
287 private Statement parseReplLine() throws ParserException {
288 if (input.peek().type() == Token.Type.DEF) {
289 return parseStatement();
290 } else {
291 return new ExpressionStatement(parseExpression());
292 }
293 }
294
278 private Expression parseSimpleExpression() throws ParserException { 295 private Expression parseSimpleExpression() throws ParserException {
279 return switch (input.peek().type()) { 296 return switch (input.peek().type()) {
280 case PAREN_LEFT -> { 297 case PAREN_LEFT -> {
@@ -307,11 +324,7 @@ public class Parser {
307 } 324 }
308 325
309 private Statement parseStatement() throws ParserException { 326 private Statement parseStatement() throws ParserException {
310 if (input.peek().type() == Token.Type.DEF) { 327 return parseDefinition();
311 return parseDefinition();
312 } else {
313 return new ExpressionStatement(parseExpression());
314 }
315 } 328 }
316 329
317 private Expression parseString() throws ParserException { 330 private Expression parseString() throws ParserException {