From 19235b59a39e82d5714ac60d8c5665bd44a0278f Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 8 Jul 2023 20:55:35 +0100 Subject: Parse subtraction --- .../java/org/shedlang/compiler/parser/Parser.java | 36 ++++++++++++++++++++-- .../org/shedlang/compiler/parser/TokenType.java | 1 + .../org/shedlang/compiler/parser/Tokeniser.java | 13 ++++---- 3 files changed, 42 insertions(+), 8 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index dcb06eb0..d6cef7d4 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -21,10 +21,24 @@ public class Parser { private static UntypedExpressionNode parseAdd( UntypedExpressionNode left, TokenIterator tokens + ) { + return parseBinaryOperation( + TokenType.SYMBOL_PLUS, + UntypedBinaryOperator.ADD, + left, + tokens + ); + } + + private static UntypedExpressionNode parseBinaryOperation( + TokenType operatorTokenType, + UntypedBinaryOperator operator, + UntypedExpressionNode left, + TokenIterator tokens ) { var start = left.source().start(); - tokens.skip(TokenType.SYMBOL_PLUS); + tokens.skip(operatorTokenType); // TODO: precedence var right = parseTopLevelExpression(tokens); @@ -33,7 +47,7 @@ public class Parser { var source = start.to(end); return new UntypedBinaryOperationNode( - UntypedBinaryOperator.ADD, + operator, left, right, source @@ -307,6 +321,18 @@ public class Parser { }; } + private static UntypedExpressionNode parseSub( + UntypedExpressionNode left, + TokenIterator tokens + ) { + return parseBinaryOperation( + TokenType.SYMBOL_MINUS, + UntypedBinaryOperator.SUB, + left, + tokens + ); + } + static UntypedExpressionNode parseTopLevelExpression(TokenIterator tokens) { var left = parsePrimaryExpression(tokens); @@ -316,9 +342,15 @@ public class Parser { case SYMBOL_PLUS -> { left = parseAdd(left, tokens); } + + case SYMBOL_MINUS -> { + left = parseSub(left, tokens); + } + case SYMBOL_BANG, SYMBOL_PAREN_OPEN -> { left = parseCall(left, tokens); } + default -> { return left; } diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java index c55f7149..9f439e03 100644 --- a/src/main/java/org/shedlang/compiler/parser/TokenType.java +++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java @@ -20,6 +20,7 @@ public enum TokenType { SYMBOL_COMMA, SYMBOL_DOT, SYMBOL_EQUALS, + SYMBOL_MINUS, SYMBOL_PAREN_OPEN, SYMBOL_PAREN_CLOSE, SYMBOL_PLUS, diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java index c26c512a..2f967452 100644 --- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java +++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java @@ -22,6 +22,11 @@ public class Tokeniser { private static final RegexTokeniser tokeniser = new RegexTokeniser<>( TokenType.UNKNOWN, List.of( + RegexTokeniser.rule(TokenType.IDENTIFIER, "[A-Za-z][A-Za-z0-9]*"), + RegexTokeniser.rule(TokenType.INT, "-?[0-9]+"), + RegexTokeniser.rule(TokenType.STRING, "\"(?:[^\\\\\"\n\r]|\\\\.)*\""), + RegexTokeniser.rule(TokenType.WHITESPACE, "[\r\n\t ]+"), + RegexTokeniser.rule(TokenType.SYMBOL_THIN_ARROW, "->"), RegexTokeniser.rule(TokenType.SYMBOL_BANG, "!"), @@ -31,15 +36,11 @@ public class Tokeniser { RegexTokeniser.rule(TokenType.SYMBOL_COMMA, ","), RegexTokeniser.rule(TokenType.SYMBOL_DOT, "\\."), RegexTokeniser.rule(TokenType.SYMBOL_EQUALS, "="), + RegexTokeniser.rule(TokenType.SYMBOL_MINUS, "-"), RegexTokeniser.rule(TokenType.SYMBOL_PAREN_OPEN, "\\("), RegexTokeniser.rule(TokenType.SYMBOL_PAREN_CLOSE, "\\)"), RegexTokeniser.rule(TokenType.SYMBOL_PLUS, "\\+"), - RegexTokeniser.rule(TokenType.SYMBOL_SEMICOLON, ";"), - - RegexTokeniser.rule(TokenType.IDENTIFIER, "[A-Za-z][A-Za-z0-9]*"), - RegexTokeniser.rule(TokenType.INT, "-?[0-9]+"), - RegexTokeniser.rule(TokenType.STRING, "\"(?:[^\\\\\"\n\r]|\\\\.)*\""), - RegexTokeniser.rule(TokenType.WHITESPACE, "[\r\n\t ]+") + RegexTokeniser.rule(TokenType.SYMBOL_SEMICOLON, ";") ) ); -- cgit v1.2.3