ast.hpp 6.61 KB
Newer Older
lyz's avatar
lyz committed
1 2
#pragma once

lxq's avatar
lxq committed
3
#include <cstdarg>
lyz's avatar
lyz committed
4 5 6 7
extern "C" {
#include "syntax_tree.h"
extern syntax_tree *parse(const char *input);
}
lxq's avatar
lxq committed
8
#include "User.hpp"
lyz's avatar
lyz committed
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
#include <memory>
#include <string>
#include <vector>

enum CminusType { TYPE_INT, TYPE_FLOAT, TYPE_VOID };

enum RelOp {
    // <=
    OP_LE,
    // <
    OP_LT,
    // >
    OP_GT,
    // >=
    OP_GE,
    // ==
    OP_EQ,
    // !=
    OP_NEQ
};

enum AddOp {
    // +
    OP_PLUS,
    // -
    OP_MINUS
};

enum MulOp {
    // *
    OP_MUL,
    // /
    OP_DIV
};

class AST;

struct ASTNode;
struct ASTProgram;
struct ASTDeclaration;
struct ASTNum;
struct ASTVarDeclaration;
struct ASTFunDeclaration;
struct ASTParam;

struct ASTCompoundStmt;
struct ASTStatement;
struct ASTExpressionStmt;
struct ASTSelectionStmt;
struct ASTIterationStmt;
struct ASTReturnStmt;
struct ASTFactor;
struct ASTExpression;
struct ASTVar;
struct ASTAssignExpression;
struct ASTSimpleExpression;
struct ASTAdditiveExpression;
struct ASTTerm;
struct ASTCall;

class ASTVisitor;

class AST {
  public:
    AST() = delete;
    AST(syntax_tree *);
    AST(AST &&tree) {
        root = tree.root;
        tree.root = nullptr;
    };
    ASTProgram *get_root() { return root.get(); }
    void run_visitor(ASTVisitor &visitor);

  private:
    ASTNode *transform_node_iter(syntax_tree_node *);
    std::shared_ptr<ASTProgram> root = nullptr;
};

struct ASTNode {
lxq's avatar
lxq committed
88
    virtual Value* accept(ASTVisitor &) = 0;
lyz's avatar
lyz committed
89 90 91 92
    virtual ~ASTNode() = default;
};

struct ASTProgram : ASTNode {
lxq's avatar
lxq committed
93
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
    virtual ~ASTProgram() = default;
    std::vector<std::shared_ptr<ASTDeclaration>> declarations;
};

struct ASTDeclaration : ASTNode {
    virtual ~ASTDeclaration() = default;
    CminusType type;
    std::string id;
};

struct ASTFactor : ASTNode {
    virtual ~ASTFactor() = default;
};

struct ASTNum : ASTFactor {
lxq's avatar
lxq committed
109
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
110 111 112 113 114 115 116 117
    CminusType type;
    union {
        int i_val;
        float f_val;
    };
};

struct ASTVarDeclaration : ASTDeclaration {
lxq's avatar
lxq committed
118
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
119 120 121 122
    std::shared_ptr<ASTNum> num;
};

struct ASTFunDeclaration : ASTDeclaration {
lxq's avatar
lxq committed
123
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
124 125 126 127 128
    std::vector<std::shared_ptr<ASTParam>> params;
    std::shared_ptr<ASTCompoundStmt> compound_stmt;
};

struct ASTParam : ASTNode {
lxq's avatar
lxq committed
129
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
130 131 132 133 134 135 136 137 138 139 140
    CminusType type;
    std::string id;
    // true if it is array param
    bool isarray;
};

struct ASTStatement : ASTNode {
    virtual ~ASTStatement() = default;
};

struct ASTCompoundStmt : ASTStatement {
lxq's avatar
lxq committed
141
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
142 143 144 145 146
    std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
    std::vector<std::shared_ptr<ASTStatement>> statement_list;
};

struct ASTExpressionStmt : ASTStatement {
lxq's avatar
lxq committed
147
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
148 149 150 151
    std::shared_ptr<ASTExpression> expression;
};

struct ASTSelectionStmt : ASTStatement {
lxq's avatar
lxq committed
152
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
153 154 155 156 157 158 159
    std::shared_ptr<ASTExpression> expression;
    std::shared_ptr<ASTStatement> if_statement;
    // should be nullptr if no else structure exists
    std::shared_ptr<ASTStatement> else_statement;
};

struct ASTIterationStmt : ASTStatement {
lxq's avatar
lxq committed
160
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
161 162 163 164 165
    std::shared_ptr<ASTExpression> expression;
    std::shared_ptr<ASTStatement> statement;
};

struct ASTReturnStmt : ASTStatement {
lxq's avatar
lxq committed
166
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
167 168 169 170 171 172 173
    // should be nullptr if return void
    std::shared_ptr<ASTExpression> expression;
};

struct ASTExpression : ASTFactor {};

struct ASTAssignExpression : ASTExpression {
lxq's avatar
lxq committed
174
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
175 176 177 178 179
    std::shared_ptr<ASTVar> var;
    std::shared_ptr<ASTExpression> expression;
};

struct ASTSimpleExpression : ASTExpression {
lxq's avatar
lxq committed
180
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
181 182 183 184 185 186
    std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
    std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
    RelOp op;
};

struct ASTVar : ASTFactor {
lxq's avatar
lxq committed
187
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
188 189 190 191 192 193
    std::string id;
    // nullptr if var is of int type
    std::shared_ptr<ASTExpression> expression;
};

struct ASTAdditiveExpression : ASTNode {
lxq's avatar
lxq committed
194
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
195 196 197 198 199 200
    std::shared_ptr<ASTAdditiveExpression> additive_expression;
    AddOp op;
    std::shared_ptr<ASTTerm> term;
};

struct ASTTerm : ASTNode {
lxq's avatar
lxq committed
201
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
202 203 204 205 206 207
    std::shared_ptr<ASTTerm> term;
    MulOp op;
    std::shared_ptr<ASTFactor> factor;
};

struct ASTCall : ASTFactor {
lxq's avatar
lxq committed
208
    virtual Value* accept(ASTVisitor &) override final;
lyz's avatar
lyz committed
209 210 211 212 213 214
    std::string id;
    std::vector<std::shared_ptr<ASTExpression>> args;
};

class ASTVisitor {
  public:
lxq's avatar
lxq committed
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
    virtual Value* visit(ASTProgram &) = 0;
    virtual Value* visit(ASTNum &) = 0;
    virtual Value* visit(ASTVarDeclaration &) = 0;
    virtual Value* visit(ASTFunDeclaration &) = 0;
    virtual Value* visit(ASTParam &) = 0;
    virtual Value* visit(ASTCompoundStmt &) = 0;
    virtual Value* visit(ASTExpressionStmt &) = 0;
    virtual Value* visit(ASTSelectionStmt &) = 0;
    virtual Value* visit(ASTIterationStmt &) = 0;
    virtual Value* visit(ASTReturnStmt &) = 0;
    virtual Value* visit(ASTAssignExpression &) = 0;
    virtual Value* visit(ASTSimpleExpression &) = 0;
    virtual Value* visit(ASTAdditiveExpression &) = 0;
    virtual Value* visit(ASTVar &) = 0;
    virtual Value* visit(ASTTerm &) = 0;
    virtual Value* visit(ASTCall &) = 0;
lyz's avatar
lyz committed
231 232 233 234
};

class ASTPrinter : public ASTVisitor {
  public:
lxq's avatar
lxq committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    virtual Value* visit(ASTProgram &) override final;
    virtual Value* visit(ASTNum &) override final;
    virtual Value* visit(ASTVarDeclaration &) override final;
    virtual Value* visit(ASTFunDeclaration &) override final;
    virtual Value* visit(ASTParam &) override final;
    virtual Value* visit(ASTCompoundStmt &) override final;
    virtual Value* visit(ASTExpressionStmt &) override final;
    virtual Value* visit(ASTSelectionStmt &) override final;
    virtual Value* visit(ASTIterationStmt &) override final;
    virtual Value* visit(ASTReturnStmt &) override final;
    virtual Value* visit(ASTAssignExpression &) override final;
    virtual Value* visit(ASTSimpleExpression &) override final;
    virtual Value* visit(ASTAdditiveExpression &) override final;
    virtual Value* visit(ASTVar &) override final;
    virtual Value* visit(ASTTerm &) override final;
    virtual Value* visit(ASTCall &) override final;
lyz's avatar
lyz committed
251 252 253 254 255 256
    void add_depth() { depth += 2; }
    void remove_depth() { depth -= 2; }

  private:
    int depth = 0;
};