diff --git a/tahini/app/src/main/java/com/tahini/lang/Expr.java b/tahini/app/src/main/java/com/tahini/lang/Expr.java index c393845..7bbdc5a 100644 --- a/tahini/app/src/main/java/com/tahini/lang/Expr.java +++ b/tahini/app/src/main/java/com/tahini/lang/Expr.java @@ -13,6 +13,7 @@ interface Visitor { R visitTernaryExpr(Ternary expr); R visitVariableExpr(Variable expr); R visitLogicalExpr(Logical expr); + R visitTahiniListExpr(TahiniList expr); } static class Assign extends Expr { Assign(Token name, Expr value) { @@ -142,6 +143,18 @@ R accept(Visitor visitor) { final Token operator; final Expr right; } + static class TahiniList extends Expr { + TahiniList(List elements) { + this.elements = elements; + } + + @Override + R accept(Visitor visitor) { + return visitor.visitTahiniListExpr(this); + } + + final List elements; + } abstract R accept(Visitor visitor); } diff --git a/tahini/app/src/main/java/com/tahini/lang/Interpreter.java b/tahini/app/src/main/java/com/tahini/lang/Interpreter.java index 51c8925..2066fc0 100644 --- a/tahini/app/src/main/java/com/tahini/lang/Interpreter.java +++ b/tahini/app/src/main/java/com/tahini/lang/Interpreter.java @@ -76,6 +76,15 @@ private String stringify(Object object) { return object.toString(); } + @Override + public Object visitTahiniListExpr(Expr.TahiniList expr) { + List tahiniList = new ArrayList<>(); + for (Expr element : expr.elements) { + tahiniList.add(evaluate(element)); + } + return tahiniList; + } + @Override public Object visitLiteralExpr(Expr.Literal expr) { return expr.value; diff --git a/tahini/app/src/main/java/com/tahini/lang/Parser.java b/tahini/app/src/main/java/com/tahini/lang/Parser.java index 2c5db2b..d18cde9 100644 --- a/tahini/app/src/main/java/com/tahini/lang/Parser.java +++ b/tahini/app/src/main/java/com/tahini/lang/Parser.java @@ -542,6 +542,17 @@ private Expr primary() { return new Expr.Grouping(expr); } + if (match(TokenType.LEFT_SQUARE)) { + List elements = new ArrayList<>(); + if (!check(TokenType.RIGHT_SQUARE)) { + do { + elements.add(expression()); + } while (match(TokenType.COMMA)); + } + consume(TokenType.RIGHT_SQUARE, "Expect ']' after list elements."); + return new Expr.TahiniList(elements); + } + // Error production for binary operator without left-hand operand if (match(TokenType.PLUS, TokenType.MINUS, TokenType.STAR, TokenType.SLASH, TokenType.EQUAL_EQUAL, TokenType.BANG_EQUAL, TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.LESS, TokenType.LESS_EQUAL)) { Token operator = previous(); diff --git a/tahini/app/src/main/java/com/tahini/lang/Scanner.java b/tahini/app/src/main/java/com/tahini/lang/Scanner.java index f74439a..fed9d50 100644 --- a/tahini/app/src/main/java/com/tahini/lang/Scanner.java +++ b/tahini/app/src/main/java/com/tahini/lang/Scanner.java @@ -73,6 +73,10 @@ private void scanToken() { addToken(TokenType.LEFT_BRACE); case '}' -> addToken(TokenType.RIGHT_BRACE); + case '[' -> + addToken(TokenType.LEFT_SQUARE); + case ']' -> + addToken(TokenType.RIGHT_SQUARE); case ',' -> addToken(TokenType.COMMA); case '.' -> diff --git a/tahini/app/src/main/java/com/tahini/lang/TokenType.java b/tahini/app/src/main/java/com/tahini/lang/TokenType.java index 73968ad..a00224e 100644 --- a/tahini/app/src/main/java/com/tahini/lang/TokenType.java +++ b/tahini/app/src/main/java/com/tahini/lang/TokenType.java @@ -2,7 +2,7 @@ enum TokenType { // Single-character tokens. - LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, + LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, LEFT_SQUARE, RIGHT_SQUARE, COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR, QUESTION_MARK, COLON, // One or two character tokens. BANG, BANG_EQUAL, diff --git a/tahini/app/src/main/java/com/tahini/tool/GenerateAst.java b/tahini/app/src/main/java/com/tahini/tool/GenerateAst.java index 509fbc3..758f6b8 100644 --- a/tahini/app/src/main/java/com/tahini/tool/GenerateAst.java +++ b/tahini/app/src/main/java/com/tahini/tool/GenerateAst.java @@ -23,7 +23,8 @@ public static void main(String[] args) throws IOException { "Unary : Token operator, Expr right", "Ternary : Expr condition, Expr left, Expr right", "Variable : Token name", - "Logical : Expr left, Token operator, Expr right" + "Logical : Expr left, Token operator, Expr right", + "TahiniList : List elements" )); defineAst(outputDir, "Stmt", Arrays.asList(