diff options
| -rw-r--r-- | grammar.bnf | 5 | ||||
| -rw-r--r-- | orang/src/main/java/lv/enes/orang/Main.java | 4 | ||||
| -rw-r--r-- | parser/src/main/java/lv/enes/orang/parser/Parser.java | 27 |
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 | ||
| 3 | program ::= (statement ';'?)*; | 3 | program ::= (statement ';'?)*; |
| 4 | statement ::= definition | expression; | 4 | statement ::= definition; |
| 5 | definition ::= 'def' def-spec '=' expression | 5 | definition ::= 'def' def-spec '=' expression |
| 6 | | 'def' '_' '=' expression; | 6 | | 'def' '_' '=' expression; |
| 7 | def-spec ::= IDENTIFIER arg-spec*; | 7 | def-spec ::= IDENTIFIER arg-spec*; |
| @@ -31,3 +31,6 @@ let-in-expression ::= 'let' def-spec '=' expression ('and' def-spec '=' expressi | |||
| 31 | fn-expression ::= 'fn' arg-spec+ '->' expression | 31 | fn-expression ::= 'fn' arg-spec+ '->' expression |
| 32 | | 'fn' arg-spec+ do-expression; | 32 | | 'fn' arg-spec+ do-expression; |
| 33 | do-expression ::= 'do' expression (';' expression)* 'end'; | 33 | do-expression ::= 'do' expression (';' expression)* 'end'; |
| 34 | |||
| 35 | repl-program ::= (repl-statement ';'?)* '\n'; // currently, hard-limited by the newline :sweat_smile: | ||
| 36 | repl-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; | |||
| 10 | import static lv.enes.orang.State.STDOUT; | 10 | import static lv.enes.orang.State.STDOUT; |
| 11 | 11 | ||
| 12 | public class Main { | 12 | public 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 { |