aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/craftinginterpreters/lox/AstPrinter.java
blob: 8f7be7876231ea6760ffd717335bf4c2c2fab3ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.craftinginterpreters.lox;

import java.util.List;

/**
 * AstPrinter
 */
class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
    String print(Expr expr) {
        return expr.accept(this);
    }

    @Override
    public String visitBinaryExpr(Expr.Binary expr) {
        return parenthesize(expr.operator.lexeme, expr.left, expr.right);
    }

    @Override
    public String visitGroupingExpr(Expr.Grouping expr) {
        return parenthesize("group", expr.expression);
    }

    @Override
    public String visitLiteralExpr(Expr.Literal expr) {
        if (expr.value == null)
            return "nil";
        return expr.value.toString();
    }

    @Override
    public String visitLogicalExpr(Expr.Logical expr) {
        return parenthesize(expr.operator.type.toString(), expr.left, expr.right);
    }

    @Override
    public String visitUnaryExpr(Expr.Unary expr) {
        return parenthesize(expr.operator.lexeme, expr.right);
    }

    @Override
    public String visitVariableExpr(Expr.Variable expr) {
        return expr.name.lexeme;
    }

    @Override
    public String visitAssignExpr(Expr.Assign expression) {
        return parenthesize(expression.name.lexeme + " = ", expression.value);
    }

    @Override
    public String visitVarStmt(Stmt.Var statement) {
        return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
    }

    @Override
    public String visitPrintStmt(Stmt.Print statement) {
        return parenthesize("print", statement.expression);
    }

    @Override
    public String visitExpressionStmt(Stmt.Expression expression) {
        return expression.expression.accept(this);
    }

    @Override
    public String visitIfStmt(Stmt.If stmt) {
        StringBuilder builder = new StringBuilder();

        builder.append("(");
        builder.append(parenthesize("if", stmt.condition));
        builder.append(parenthesize("then", stmt.thenBranch));

        if (stmt.elseBranch != null) {
            builder.append(parenthesize("else", stmt.elseBranch));
        }
        return builder.toString();
    }

    @Override
    public String visitBlockStmt(Stmt.Block block) {
        return parenthesize("", block.statements);
    }

    private String parenthesize(String name, Expr... exprs) {
        StringBuilder builder = new StringBuilder();

        builder.append("(").append(name);
        for (Expr expr : exprs) {
            builder.append(" ");
            builder.append(expr.accept(this));
        }
        builder.append(")");

        return builder.toString();
    }

    private String parenthesize(String name, List<Stmt> statements) {
        StringBuilder builder = new StringBuilder();

        builder.append("(").append(name);
        for (Stmt statement : statements) {
            builder.append(" ");
            builder.append(statement.accept(this));
        }
        builder.append(")");

        return builder.toString();
    }

    private String parenthesize(String name, Stmt... statements) {
        return parenthesize(name, statements);
    }

    public static void main(String[] args) {
        Expr expression = new Expr.Binary(
                new Expr.Unary(new Token(TokenType.MINUS, "-", null, 1), new Expr.Literal(123)),
                new Token(TokenType.STAR, "*", null, 1), new Expr.Grouping(new Expr.Literal(45.67)));

        System.out.println(new AstPrinter().print(expression));
    }
}