151 lines
3.4 KiB
C
151 lines
3.4 KiB
C
#ifndef _ast_h_
|
|
#define _ast_h_
|
|
|
|
#include "pre.h"
|
|
#include "datatype.h"
|
|
#include "symbol.h"
|
|
#include "location.h"
|
|
|
|
#define ast_node_is_atom(nk) \
|
|
(nk == AST_IDENT || nk == AST_NUMBER || nk == AST_STRLIT || nk == AST_PROCCALL)
|
|
#define ast_node_is_unary(nk) \
|
|
(nk == AST_UNARY || ast_node_is_atom(nk))
|
|
#define ast_node_is_expr(nk) \
|
|
(nk == AST_BINEXPR || ast_node_is_unary(nk))
|
|
|
|
enum AstType
|
|
{
|
|
AST_INVALID, /* For use as a placeholder until the actual type is decided */
|
|
AST_NUMBER, /* number */
|
|
AST_IDENT, /* ident */
|
|
AST_STRLIT, /* strlit */
|
|
AST_PROCDEF, /* proc */
|
|
AST_PROCCALL, /* call */
|
|
AST_PROCCALL_ARGS, /* */
|
|
AST_VARDECL, /* var */
|
|
AST_VARASSIGN, /* varassgn */
|
|
AST_IF, /* ifse */
|
|
AST_RETURN, /* ret */
|
|
AST_BREAK,
|
|
AST_LOOP, /* loop */
|
|
AST_STMTS, /* stmts */
|
|
AST_EXPRS, /* exprs */
|
|
AST_BINEXPR, /* bin */
|
|
AST_UNARY, /* unary */
|
|
AST_PRAGMA, /* pragma */
|
|
AST_DISCARD,
|
|
};
|
|
|
|
typedef struct Ast Ast;
|
|
|
|
typedef struct {
|
|
Str op;
|
|
Ast *left, *right;
|
|
DataType *type; /* filled in by sema */
|
|
} AstBinop;
|
|
|
|
typedef struct {
|
|
Str op;
|
|
Ast *atom;
|
|
DataType *type; /* filled in by sema */
|
|
} AstUnary;
|
|
|
|
typedef struct {
|
|
Str ident;
|
|
Str dtype;
|
|
/* Symbol kind for this parameter, `SymVar` would represent a mutable
|
|
* parameter and `SymLet` a immutable one. */
|
|
enum SymbolKind kind;
|
|
Location ident_loc, dtype_loc;
|
|
} AstIdentTypePair;
|
|
|
|
typedef struct {
|
|
Str name;
|
|
bool ispublic;
|
|
Ast *body;
|
|
Vec(AstIdentTypePair) args;
|
|
Ast *rettype;
|
|
|
|
DataType *type;
|
|
} AstProc;
|
|
|
|
typedef struct {
|
|
Str name;
|
|
Ast *args;
|
|
} AstProcCall;
|
|
|
|
typedef struct {
|
|
Str name;
|
|
/* Data type, nil if no type was explicitly stated, meaning that
|
|
* type deduction must be made from the expression, also implying that
|
|
* if this field is nil, `expr` MUSN'T be nil. */
|
|
Ast *datatype;
|
|
Ast *expr; /* if the declaration assigns a value */
|
|
enum SymbolKind kind; /* whether is a let, var or const... */
|
|
DataType *type; /* filled in by sema */
|
|
} AstVarDecl;
|
|
|
|
typedef struct {
|
|
Str name;
|
|
Ast *expr;
|
|
} AstVarAssign;
|
|
|
|
typedef struct {
|
|
u64 n;
|
|
DataType *type; /* filled in by the sema */
|
|
} AstNumber;
|
|
|
|
typedef struct {
|
|
Ast *cond;
|
|
Ast *body;
|
|
} AstElif;
|
|
|
|
typedef struct {
|
|
Ast *cond;
|
|
Ast *true_body;
|
|
Ast *false_body;
|
|
Vec(AstElif) elifs;
|
|
} AstIf;
|
|
|
|
/* Abstract representation of a loop, providing a pre and post condition.
|
|
* `while` loops are modelled as a loop with a precondition only.
|
|
* For infinite loops both `precond` and `postcond` are nil. */
|
|
typedef struct {
|
|
Ast *precond, *postcond, *body;
|
|
} AstLoop;
|
|
|
|
typedef struct {
|
|
/* Attributes for now can only be identifiers */
|
|
Vec(Str) attrs;
|
|
Ast *node; /* The decorated node */
|
|
} AstPragma;
|
|
|
|
typedef struct {
|
|
Ast *expr;
|
|
} AstDiscard;
|
|
|
|
struct Ast {
|
|
enum AstType type;
|
|
union {
|
|
AstBinop bin; /* binary expression */
|
|
AstUnary unary; /* unary operator */
|
|
AstNumber number; /* number (this is an atom) */
|
|
Str ident; /* identifier (this is an atom too) */
|
|
AstProc proc; /* procedure definition */
|
|
AstProcCall call; /* procedure call */
|
|
AstVarDecl var; /* variable declaration */
|
|
AstVarAssign varassgn;
|
|
Ast *ret; /* return statement, this points to its expression (if any) */
|
|
AstIf ifse; /* if statement/expression */
|
|
AstLoop loop;
|
|
Vec(Ast *) stmts;
|
|
Vec(Ast *) exprs;
|
|
Str strlit; /* String literal */
|
|
AstPragma pragma;
|
|
AstDiscard discard;
|
|
};
|
|
Location loc; /* location in the source code of this node */
|
|
};
|
|
_Static_assert(sizeof(Ast) <= 512, "AST node got too bloated");
|
|
|
|
#endif
|