Source

arana-main / arana / ast.h

Full commit
/*
 * ast.h
 *
 * The abstract syntax tree which is used for evaluation.
 *
 * (c) Copyright 2009 by Armin Ronacher.
 */

#ifndef _ARANA_AST_H
#define _ARANA_HAS_H

#define AR_AST_NODE_HEAD const char *filename; int lineno; ArAstType type;
#define AR_AST_BINARY_HEAD AR_AST_NODE_HEAD; ArAstNode *left, ArAstNode *right;
#define AR_AST(type, ...) arana_ast_##type(AR_ISIG, __VA_ARGS__)
#define AR_AST_SET_STORE_CTX(node) arana_ast_set_store_ctx(AR_ISIG, node)
#define AR_AST_TYPE(x) ((ArAstNode *)(x))->type
#define AR_AST_IS(x, t) (AR_AST_TYPE(x) == AR_AST_##t)

#define AR_AST_SEQ_NEW(tp, target, cnt) {                               \
        Ar##tp##Seq *_seq = AR_ALLOCTE(Ar##tp##Seq, sizeof(ArAstNode *)*cnt); \
        if (!_seq) AR_RAISE_OOM();                                      \
        _seq->count = 0;                                                \
        _seq->free = cnt;                                               \
        target = _seq;                                                  \
    }
#define AR_AST_SEQ_NEW1(tp, target, val) {                              \
        Ar##tp##Seq *_seq = AR_ALLOCTE(Ar##tp##Seq, sizeof(ArAstNode *)*5); \
        if (!_seq) AR_RAISE_OOM();                                      \
        _seq->count = 1;                                                \
        _seq->free = 4;                                                 \
        _seq->items[0] = val;                                           \
        target = _seq;                                                  \
    }
#define AR_AST_SEQ_ADD(tp, target, seq, val) {                          \
        if (seq->free == 0) {                                           \
            seq = AR_REALLOCTE(seq, Ar##tp##Seq,                        \
                               sizeof(ArAstNode *)*(seq->count*2));     \
            if (!seq) arana_out_of_memory(ps->AI, ps->CF);              \
            seq->free = seq->count;                                     \
            seq->count *= 2;                                            \
        }                                                               \
        seq->items[seq->count++] = val;                                 \
        seq->free--;                                                    \
        target = seq;                                                   \
    }

#define AR_AST_MAYBE_TUPLE(target, seq, ctx) {                          \
        if (seq->count == 1) {                                          \
            target = seq->items[0];                                     \
        } else {                                                        \
            target = AR_AST(Tuple, seq, ctx);                           \
        }                                                               \
    }

typedef enum _ArAstType {
    AR_AST_Module,

    AR_AST_Compound,
    AR_AST_ExprStmt,
    AR_AST_If,
    AR_AST_For,
    AR_AST_Def,

    AR_AST_Assign,
    AR_AST_AugAssign,
    AR_AST_BinaryOp,
    AR_AST_UnaryOp,
    AR_AST_Call,
    AR_AST_Attribute,
    AR_AST_Subscript,
    AR_AST_List,
    AR_AST_Tuple,
    AR_AST_Interpolation,
    AR_AST_Name,
    AR_AST_Literal
} ArAstType;

/* if you change this, adapt augops[] in compile.c! */
typedef enum _ArAstOp {
    AR_ASTOP_AND,
    AR_ASTOP_OR,
    AR_ASTOP_EQ,
    AR_ASTOP_NEQ,
    AR_ASTOP_GT,
    AR_ASTOP_GTE,
    AR_ASTOP_LT,
    AR_ASTOP_LTE,
    AR_ASTOP_CONCAT,
    AR_ASTOP_ADD,
    AR_ASTOP_SUB,
    AR_ASTOP_MUL,
    AR_ASTOP_DIV,
    AR_ASTOP_MOD,
    AR_ASTOP_POW,
    AR_ASTOP_POS,
    AR_ASTOP_NEG,
    AR_ASTOP_NOT
} ArAstOp;

typedef enum {
    AR_CTX_Load,
    AR_CTX_Store
} ArAstCtx;

typedef struct _ArAstNode ArAstNode;
typedef struct _ArToplevelNode ArToplevelNode;
typedef struct _ArExprNode ArExprNode;
typedef struct _ArStmtNode ArStmtNode;

typedef struct {
    int count;
    int free;
    ArStmtNode *items[];
} ArStmtSeq;

typedef struct {
    int count;
    int free;
    ArExprNode *items[];
} ArExprSeq;


struct _ArAstNode {
    AR_AST_NODE_HEAD;
};

struct _ArToplevelNode {
    AR_AST_NODE_HEAD;
    union {
        struct {
            ArStmtSeq *stmts;
        } Module;
    } v;
};

struct _ArStmtNode {
    AR_AST_NODE_HEAD;
    union {
        struct {
            ArStmtSeq *stmts;
        } Compound;
        struct {
            ArExprNode *expr;
        } ExprStmt;
        struct {
            ArExprNode *test;
            ArStmtNode *body;
            ArStmtNode *else_;
        } If;
        struct {
            ArExprNode *target;
            ArExprNode *seq;
            ArStmtNode *body;
        } For;
        struct {
            const char *name;
            ArExprSeq *args;
            ArExprSeq *defaults;
            Ar_size_t arg_count;
            Ar_size_t default_count;
            ArStmtNode *body;
        } Def;
    } v;
};

struct _ArExprNode {
    AR_AST_NODE_HEAD;
    union {
        struct {
            ArExprNode *target;
            ArExprNode *expr;
        } Assign;
        struct {
            ArExprNode *target;
            ArExprNode *expr;
            ArAstOp op;
        } AugAssign;
        struct {
            ArExprNode *left;
            ArExprNode *right;
            ArAstOp op;
        } BinaryOp;
        struct {
            ArExprNode *expr;
            ArAstOp op;
        } UnaryOp;
        struct {
            ArExprNode *expr;
            ArExprNode *args;
        } Call;
        struct {
            ArExprNode *expr;
            ArExprNode *attr;
            ArAstCtx ctx;
        } Attribute;
        struct {
            ArExprNode *expr;
            ArExprNode *index;
            ArAstCtx ctx;
        } Subscript;
        struct {
            ArExprSeq *items;
            ArAstCtx ctx;
        } List;
        struct {
            ArExprSeq *items;
            ArAstCtx ctx;
        } Tuple;
        struct {
            ArExprSeq *items;
        } Interpolation;
        struct {
            const char *ident;
            ArAstCtx ctx;
        } Name;
        struct {
            AR value;
        } Literal;
    } v;
};

typedef int (*ArAstVisitFunc)(AR_SIG, ArAstNode *node, void *closure);

AR_API_FUNC(ArToplevelNode *) arana_ast_Module(AR_SIG, ArStmtSeq *stmts);

AR_API_FUNC(ArStmtNode *) arana_ast_Compound(AR_SIG, ArStmtSeq *stmts);
AR_API_FUNC(ArStmtNode *) arana_ast_ExprStmt(AR_SIG, ArExprNode *expr);
AR_API_FUNC(ArStmtNode *) arana_ast_If(AR_SIG, ArExprNode *test,
                                       ArStmtNode *body, ArStmtNode *else_);
AR_API_FUNC(ArStmtNode *) arana_ast_For(AR_SIG, ArExprNode *target,
                                        ArExprNode *seq, ArStmtNode *body);
AR_API_FUNC(ArStmtNode *) arana_ast_Def(AR_SIG, const char *name,
                                        ArExprSeq *args,
                                        ArExprSeq *defaults,
                                        Ar_size_t arg_count,
                                        Ar_size_t default_count,
                                        ArStmtNode *body);

AR_API_FUNC(ArExprNode *) arana_ast_Assign(AR_SIG, ArExprNode *target,
                                           ArExprNode *expr);
AR_API_FUNC(ArExprNode *) arana_ast_AugAssign(AR_SIG, ArExprNode *target,
                                              ArExprNode *expr, ArAstOp op);
AR_API_FUNC(ArExprNode *) arana_ast_BinaryOp(AR_SIG, ArExprNode *left,
                                             ArExprNode *right, ArAstOp op);
AR_API_FUNC(ArExprNode *) arana_ast_UnaryOp(AR_SIG, ArExprNode *expr, ArAstOp op);
AR_API_FUNC(ArExprNode *) arana_ast_Call(AR_SIG, ArExprNode *expr,
                                         ArExprNode *args);
AR_API_FUNC(ArExprNode *) arana_ast_Attribute(AR_SIG, ArExprNode *expr,
                                              ArExprNode *attr, ArAstCtx ctx);
AR_API_FUNC(ArExprNode *) arana_ast_Subscript(AR_SIG, ArExprNode *expr,
                                              ArExprNode *index, ArAstCtx ctx);
AR_API_FUNC(ArExprNode *) arana_ast_List(AR_SIG, ArExprSeq *items);
AR_API_FUNC(ArExprNode *) arana_ast_Tuple(AR_SIG, ArExprSeq *items, ArAstCtx ctx);
AR_API_FUNC(ArExprNode *) arana_ast_Interpolation(AR_SIG, ArExprSeq *items);
AR_API_FUNC(ArExprNode *) arana_ast_Name(AR_SIG, const char *ident, ArAstCtx ctx);
AR_API_FUNC(ArExprNode *) arana_ast_Literal(AR_SIG, AR value);

AR_API_FUNC(void) arana_ast_visit(AR_SIG, ArAstNode *node, ArAstVisitFunc pre,
                                  ArAstVisitFunc post, void *closure);
AR_API_FUNC(void) arana_ast_set_store_ctx(AR_SIG, ArExprNode *node);
AR_API_FUNC(void) arana_ast_set_filename(AR_SIG, ArAstNode *node,
                                         const char *filename);
AR_API_FUNC(void) arana_ast_optimize(AR_SIG, ArAstNode *node);
AR_API_FUNC(void) arana_ast_dump(AR_SIG, ArAstNode *node, FILE *fp);

#endif /* _ARANA_AST_H */