diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-05-20 18:41:54 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-05-20 18:41:54 +0300 |
| commit | 5ffc39352ef0195697953e9318b8a17c79e7ae84 (patch) | |
| tree | 0ce445c5268dd34a809d85d0085ce43a8efe3f73 | |
| parent | 08788af6d50bf3f8a6b69b88a144597c3a997e8b (diff) | |
| download | ek-5ffc39352ef0195697953e9318b8a17c79e7ae84.tar.gz ek-5ffc39352ef0195697953e9318b8a17c79e7ae84.zip | |
document ast.h
| -rw-r--r-- | include/ek/ast.h | 793 | ||||
| -rw-r--r-- | src/ast.c | 15 | ||||
| -rw-r--r-- | src/parser_helper.c | 1 |
3 files changed, 762 insertions, 47 deletions
diff --git a/include/ek/ast.h b/include/ek/ast.h index 6d0f2b1..fa9f0c2 100644 --- a/include/ek/ast.h +++ b/include/ek/ast.h @@ -10,584 +10,1301 @@ * Abstract syntax tree handling. */ +/** Binary operands, that is they take two arguments and produce a result. */ enum ast_binops { + /** Add, \c + */ AST_ADD, + /** Subtract, \c - */ AST_SUB, + /** Multiply, \ * */ AST_MUL, + /** Divide, \c \ */ AST_DIV, + /** Remainder, \c % */ AST_REM, + /** Bitwise exclusive or, \c ^ */ AST_XOR, + /** Raise to power \c ^^ (likely not necessary) */ AST_POW, + /** Bitwise and, \c & */ AST_AND, + /** Logical and, \c && */ AST_LAND, + /** Bitwise or, \c | */ AST_OR, + /** Logical or, \c ||*/ AST_LOR, + /** Left shift (logical), \c << @todo add arithmetic shifts? */ AST_LSHIFT, + /** Right shift (logical), \c >> */ AST_RSHIFT, + /** Assigning add, \c += */ AST_ASSIGN_ADD, + /** Assigning subtraction, \c -= */ AST_ASSIGN_SUB, + /** Assigning multiplication, \c *= */ AST_ASSIGN_MUL, + /** Assigning division, \c /= */ AST_ASSIGN_DIV, + /** Assigning remainder, \c %= */ AST_ASSIGN_REM, + /** Assigning bitwise and, \c &= */ AST_ASSIGN_AND, + /** Assigning bitwise or, \c |= */ AST_ASSIGN_OR, + /** Assigning bitwise exclusive or, \c ^= */ AST_ASSIGN_XOR, + /** Assigning logical left shift, \c >>= */ AST_ASSIGN_LSHIFT, + /** Assigning logical right shift, \c <<= */ AST_ASSIGN_RSHIFT, + /** Less than, \c < */ AST_LT, + /** Greater than, \c > */ AST_GT, + /** Less than or equal, \c <= */ AST_LE, + /** Greater than or equal, \c >= */ AST_GE, + /** Not equal, \c != */ AST_NE, + /** Equal, \c == */ AST_EQ, }; +/** Unary operations, that is they take one argument and produce a result. */ enum ast_unops { + /** Negation, \c - */ AST_NEG, + /** Logical negation, \c ! */ AST_LNOT, + /** Referencing, \c & */ AST_REF, + /** Dereferencing, \c ' */ AST_DEREF, + /** Bitwise negation, i.e. inverting bits, \c ~ */ AST_NOT }; -/* should this also have file name? Probably? */ +/** Represents a source location, spanning over some bit of code. */ struct src_loc { + /** First line of interesting text. */ int first_line; + /** Last line of interesting text. */ int last_line; + /** First column in first line of interesting text. */ int first_col; + /** Last column in last line of interesting text. */ int last_col; }; +/** Possible AST node types. We reserve node 0 as an illegal value. */ enum ast_node_type { + /** Binary operation. */ AST_BINOP = 1, + /** Unary operation. */ AST_UNOP, + /** Fetch enum constant. */ AST_FETCH, + /** Value initialization. */ AST_INIT, + /** Assignment. */ AST_ASSIGN, + /** Call. We don't know to what yet: macro, array or procedure.*/ AST_CALL, + /** Sizeof. */ AST_SIZEOF, + /** Cast. */ AST_CAST, + /** Defer. */ AST_DEFER, + /** Macro definition. */ AST_MACRO, + /** Reference to previous expression, i.e. \c @ */ AST_LAST, + /** Procedure definition. */ AST_PROC, + /** Goto. */ AST_GOTO, + /** Goto label. */ AST_LABEL, + /** Variable declaration/definition. */ AST_VAR, + /** Lambda declaration/definition. */ AST_LAMBDA, + /** For loop. */ AST_FOR, + /** Embed file contents. */ AST_EMBED, + /** Dot. \c a.b; */ AST_DOT, + /** + * While loop, both \c do and \c while. + * \c AST_DELAYED is active for \c do loops. + */ AST_WHILE, + /** Control statement, \c break or \c continue. */ AST_CTRL, + /** Return. */ AST_RETURN, + /** Alias definition. */ AST_ALIAS, + /** More like trait. @todo really come up with consistent naming. */ AST_TEMPLATE, + /** Structure definition. */ AST_STRUCT, + /** If. */ AST_IF, + /** Special 'meta' node that represents a type. */ AST_TYPE, + /** Block. E.g. \c {} */ AST_BLOCK, + /** Import. */ AST_IMPORT, + /** Enum definition. */ AST_ENUM, + /** Union definition. */ AST_UNION, + /** Enum constant value. */ AST_VAL, + /** Switch. */ AST_SWITCH, + /** Switch case. */ AST_CASE, + /** Constant value. */ AST_CONST, + /** Any ID, variable or whatever. */ AST_ID, + /** As statement, used to determine types. */ AST_AS, + /** Empty. Essentially noop. */ AST_EMPTY, }; +/** Whether \c AST_CTRL is break or continue. */ enum ast_ctrl_kind { + /** Break. */ AST_CTRL_BREAK, + /** Continue. */ AST_CTRL_CONTINUE }; +/** Constant value kind. */ enum ast_const_kind { + /** Integer, u64 */ AST_CONST_INTEGER, + /** String. */ AST_CONST_STRING, + /** Float, f64. */ AST_CONST_FLOAT, }; +/** Type representation. */ enum ast_type_kind { + /** ID, can refer to pretty much anything. */ AST_TYPE_ID, + /** Array. */ AST_TYPE_ARR, + /** Typeof expression. */ AST_TYPE_TYPEOF, + /** Trait. */ AST_TYPE_TEMPLATE, + /** Alias. */ AST_TYPE_ALIAS, + /** Member, that is type element of some structure. */ AST_TYPE_MEMBER, + /** Pointer to a type. */ AST_TYPE_POINTER, + /** Union. */ AST_TYPE_UNION, + /** Lambda. */ AST_TYPE_LAMBDA, + /** Procedure, mainly used in trait definition. */ AST_TYPE_PROC, + /** Structure. */ AST_TYPE_STRUCT, + /** Type with type arguments. */ AST_TYPE_GENERIC, + /** Enum. */ AST_TYPE_ENUM, + /** Signature, i.e. procedure signature. */ AST_TYPE_SIGN, }; +/** Whether typedef makes an alias on trait. */ enum ast_typedef_kind { + /** Alias. */ AST_TYPEDEF_ALIAS, + /** Trait. */ AST_TYPEDEF_TEMPLATE, }; +/** Flags an AST node can have. */ enum ast_flag { + /** Node is mutable. Mostly used for variables. */ AST_FLAG_MUTABLE = (1 << 0), + /** Value is constant. Constant if, for, etc. */ AST_FLAG_CONST = (1 << 1), + /** External definition. Disables generic support. */ AST_FLAG_EXTERN = (1 << 2), + /** Variadic procedures and macros. */ AST_FLAG_VARIADIC = (1 << 3), + /** Delayed execution. Mainly \c do loops. */ AST_FLAG_DELAYED = (1 << 4), + /** Public node, should be propagated to parent scopes. */ AST_FLAG_PUBLIC = (1 << 5), - /* Is untyped necessary? It's fairly easy to just look at the type of an - * expression... */ + /** + * Untyped node. + * @todo Is untyped necessary? It's fairly easy to just look at the type of an + * expression... + */ AST_FLAG_UNTYPED = (1 << 6), + /** Switch case should fall through. */ AST_FLAG_FALLTHROUGH = (1 << 7), + /** Block is unhygienic. */ AST_FLAG_UNHYGIENIC = (1 << 8), + /** Node has been actualized, types expanded etc. */ AST_FLAG_ACTUAL = (1 << 9), + /** Actualization has been initialized. Used to detect type loops. */ AST_FLAG_INIT = (1 << 10), + /** Whether a struct/union initialization is index or name based. */ AST_FLAG_MEMBER = (1 << 11), + /** AST node has several owners, requires special destruction handling. */ AST_FLAG_SHARED = (1 << 12), + /** Struct/union is generic. */ AST_FLAG_GENERIC = (1 << 13), }; struct ast_node; +/** + * AST if node. + * + * \verbatim + * if cond {body} [els] + * \endverbatim + */ struct ast_if { + /** Conditional block. */ struct ast_node *cond; + /** Body. */ struct ast_node *body; + /** Else block. */ struct ast_node *els; }; +/** AST fetch enum member node. */ struct ast_fetch { + /** Name of member to fetch. */ struct ast_node *id; + /** Enum type to fetch from. */ struct ast_node *type; }; +/** Goto label. */ struct ast_label { + /** Label name. */ struct ast_node *id; + /** + * List of active defers. + * Used to determine which defer statements should be executed + * when a goto jumps to this label. + */ struct ast_node *defers; }; +/** Goto node. */ struct ast_goto { + /** Name of label to jump to. */ struct ast_node *label; + /** + * List of active defers. + * With the list in the corresponding label, we can detect which + * defers should be triggered and which ones shouldn't. + * See actualize_goto_defers(). + */ struct ast_node *defers; }; +/** Alias definition. */ struct ast_alias { + /** Name of alias. */ struct ast_node *id; + /** Type to alias. */ struct ast_node *type; }; +/** List of types that implements the template list belongs to. */ struct template_implemented { + /** A type that implements the template. */ struct ast_node *type; + /** Next type that implements the template. */ struct template_implemented *next; }; -/* should templates take decls or should it just be for structures? */ +/** + * A trait declaration. + * + * @todo should templates take decls or should it just be for structures? + */ struct ast_template { + /** Name of trait. */ struct ast_node *id; + /** Body of trait. */ struct ast_node *body; - + /** List of types that implement this trait. */ struct template_implemented *impl_by; }; +/** Cast. */ struct ast_cast { + /** Expression. */ struct ast_node *expr; + /** Type to cast expression result to. */ struct ast_node *type; }; +/** Binary operation. */ struct ast_binop { + /** Which operation. */ enum ast_binops op; + /** Left operand. */ struct ast_node *left; + /** Right operand. */ struct ast_node *right; }; +/** Unary operation. */ struct ast_unop { + /** Which operation. */ enum ast_unops op; + /** Expression. */ struct ast_node *expr; }; +/** A call. */ struct ast_call { + /** Name to call, whatever it may be. */ struct ast_node *id; + /** List of arguments to call. */ struct ast_node *args; }; +/** Defer. */ struct ast_defer { + /** Expression to defer. */ struct ast_node *expr; }; +/** Macro definition. */ struct ast_macro { + /** Name of macro. */ struct ast_node *id; + /** Parameters macro takes. */ struct ast_node *params; + /** Macro body. */ struct ast_node *body; }; +/** Procedure definition. */ struct ast_proc { + /** Procedure name. */ struct ast_node *id; + /** Procedure signature. */ struct ast_node *sign; + /** Procedure body. */ struct ast_node *body; }; +/** Dot. */ struct ast_dot { + /** Expression to do dot operation on. */ struct ast_node *expr; + /** Name to dot. */ struct ast_node *id; }; +/** As. */ struct ast_as { + /** Type to use for resolution. */ struct ast_node *type; }; +/** Sizeof. */ struct ast_sizeof { + /** Expression to get type of. */ struct ast_node *expr; }; +/** Variable declaration. */ struct ast_var { + /** Name of variable. */ struct ast_node *id; + /** Type of variable. */ struct ast_node *type; + /** Initialization expression. */ struct ast_node *init; }; +/** Lambda definition. */ struct ast_lambda { + /** Which variables to capture from the context. */ struct ast_node *captures; + /** Signature of lambda. */ struct ast_node *sign; + /** Body of lambda. */ struct ast_node *body; }; +/** + * For loop. + * + * \verbatim + * for (pre; cond; post) {body} + * \endverbatim + */ struct ast_for { + /** Initialization. */ struct ast_node *pre; + /** Condition. */ struct ast_node *cond; + /** Iteration. */ struct ast_node *post; + /** Body. */ struct ast_node *body; }; +/** While loop. */ struct ast_while { + /** Condition. */ struct ast_node *cond; + /** Body. */ struct ast_node *body; }; +/** Control. */ struct ast_ctrl { + /** Break or continue. */ enum ast_ctrl_kind kind; + /** + * List of active defers. + * Similarly to goto, used to figure out which defers to trigger. + */ struct ast_node *defers; }; +/** Return. */ struct ast_return { + /** Expression to return. */ struct ast_node *expr; + /** List of active defers. */ struct ast_node *defers; }; +/** + * Type. + * I'm not entirely happy with the current type system, for one + * some parts are only used until they get initialized, which makes it + * sort of difficult to follow what each kind means. + * + * @todo Could be better to have separate type nodes instead of co-opting + * AST nodes. + */ struct ast_type { + /** Type kind. */ enum ast_type_kind kind; + /** + * Next type element in whole type. I.e. 'u32 is two elements, one + * AST_TYPE_POINTER and one AST_TYPE_ID. + */ struct ast_node *next; + /** Data relevant to kind. */ union { + /** Name of a type. */ struct ast_node *id; - + /** Array type. */ struct { + /** Size of array. @todo element size? */ struct ast_node *size; } arr; - + /** Typeof. */ struct { + /** Expression to take type of. */ struct ast_node *expr; + /** Type expression resolves to. */ struct ast_node *actual; } typeo; - + /** Procedure. */ struct { + /** Name. */ struct ast_node *id; + /** Parameters. */ struct ast_node *params; + /** Return type. */ struct ast_node *ret; } proc; - + /** Alias. */ struct { + /** Alias definition. */ struct ast_node *alias; + /** Type alias resolves to. */ struct ast_node *actual; } alias; - + /** Enum member. */ struct { + /** Name of member. */ struct ast_node *id; + /** Expression to try to get member from. */ struct ast_node *expr; } member; - + /** Trait. */ struct { + /** Trait definition. */ struct ast_node *template; + /** Type trait 'resolves' to. */ struct ast_node *actual; } template; - + /** Lambda. @todo add captures? */ struct { + /** Parameter types. */ struct ast_node *params; + /** Return type. */ struct ast_node *ret; } lambda; - + /** Generic struct before actualization. */ struct { + /** Name of struct. */ struct ast_node *id; + /** Type arguments. @todo should this be parameters? */ struct ast_node *args; } generic; - + /** Structure. */ struct { + /** Name of structure. */ struct ast_node *id; + /** Arguments for type parameters. */ struct ast_node *impls; } struc; - + /** Enumeration. */ struct { + /** Name of enum. */ struct ast_node *id; + /** Type enum is convertible to. */ struct ast_node *type; } enu; - + /** Union. */ struct { + /** Name of union. */ struct ast_node *id; + /** Arguments for type parameters. */ struct ast_node *impls; } unio; - - /* a signature can be either a procedure or a lambda, to be - * determined later. */ + /** + * Signature. + * Can be either a procedure or a lambda, to be + * determined later. + */ struct { + /** Parameter types. */ struct ast_node *params; + /** Return type. */ struct ast_node *ret; } sign; - - struct { - struct ast_node *id; - struct ast_node *types; - } impl; }; }; +/** Block. */ struct ast_block { + /** Body of block. */ struct ast_node *body; + /** List of defers. */ struct ast_node *defers; }; +/** Import. */ struct ast_import { + /** File to import. */ const char *file; }; +/** Embed. @todo figure out how embedding should be done, just *u8? */ struct ast_embed { + /** File to embed. */ const char *file; }; -struct ast_paste { - struct ast_node *id1; - struct ast_node *id2; -}; - +/** Enum definition. */ struct ast_enum { + /** Name of enum. */ struct ast_node *id; + /** Type enum is convertible to/from. */ struct ast_node *type; + /** Body. */ struct ast_node *body; }; +/** Structure definition. */ struct ast_struct { + /** Name of structure. */ struct ast_node *id; + /** List of type parameters, if any. */ struct ast_node *generics; + /** Body. */ struct ast_node *body; }; +/** Union definition. */ struct ast_union { + /** Name of union. */ struct ast_node *id; + /** List of type parameters, if any. */ struct ast_node *generics; + /** Body. */ struct ast_node *body; }; +/** Enum member constant value. */ struct ast_val { + /** Name of member. */ struct ast_node *id; + /** Constant value of member. */ struct ast_node *val; }; +/** Switch. */ struct ast_switch { + /** Condition. */ struct ast_node *cond; + /** List of cases. */ struct ast_node *cases; }; +/** Switch case. */ struct ast_case { + /** Condition. */ struct ast_node *cond; + /** Body. */ struct ast_node *body; }; +/** Constant value. */ struct ast_const { + /** Constant kind. */ enum ast_const_kind kind; union { + /** Integer. */ long long integer; + /** String. */ const char *str; + /** Float. */ double dbl; }; }; +/** Value initialization. */ struct ast_init { + /** Body. @todo maybe come up with a better name? */ struct ast_node *body; }; +/** Assignment. */ struct ast_assign { + /** Where to assign to. */ struct ast_node *to; + /** What to assign from. */ struct ast_node *from; }; +/** + * An ID. + * @todo One optimization would be to reduce number of ast_ids, + * replacing them with raw strings. + */ struct ast_id { + /** Actual ID. */ const char *id; }; +/** Empty node. */ struct ast_empty { }; +/** AST node. */ struct ast_node { + /** Node type. */ enum ast_node_type node_type; + /** Node flags. */ enum ast_flag flags; + /** Next node, when applicable. I.e. body statements. */ struct ast_node *next; - + /** Source location. */ struct src_loc loc; - - /* scope ast node belongs to */ + /** Scope node belongs to. */ struct scope *scope; - /* type of ast node */ + /** Ek type. */ struct ast_node *type; + /** Data relevant to kind. */ union { + /** Binary operation. */ struct ast_binop _binop; + /** Unary operation. */ struct ast_unop _unop; + /** Call. */ struct ast_call _call; + /** Cast. */ struct ast_cast _cast; + /** Macro definition. */ struct ast_macro _macro; + /** Procedure definition. */ struct ast_proc _proc; + /** Goto. */ struct ast_goto _goto; + /** Goto label. */ struct ast_label _label; + /** Variable. */ struct ast_var _var; + /** Lambda. */ struct ast_lambda _lambda; + /** If. */ struct ast_if _if; + /** For. */ struct ast_for _for; + /** While. */ struct ast_while _while; + /** Break/continue. */ struct ast_ctrl _ctrl; + /** Defer. */ struct ast_defer _defer; + /** Type. */ struct ast_type _type; + /** Dot. */ struct ast_dot _dot; + /** Block. */ struct ast_block _block; + /** Import. */ struct ast_import _import; + /** Embed. */ struct ast_embed _embed; + /** Return. */ struct ast_return _return; + /** Switch. */ struct ast_switch _switch; - struct ast_paste _paste; + /** Alias. */ struct ast_alias _alias; + /** Trait definition. */ struct ast_template _template; + /** Enum definition. */ struct ast_enum _enum; + /** Structure definition. */ struct ast_struct _struct; + /** Union definition. */ struct ast_union _union; + /** Enum value. */ struct ast_val _val; + /** Switch case. */ struct ast_case _case; + /** Constant value. */ struct ast_const _const; + /** Initialization. */ struct ast_init _init; + /** Assignment. */ struct ast_assign _assign; + /** ID. */ struct ast_id _id; + /** As type. */ struct ast_as _as; + /** Sizeof. */ struct ast_sizeof _sizeof; + /** Fetch enum member. */ struct ast_fetch _fetch; + /** Empty. */ struct ast_empty _empty; }; }; +/** + * Generate binary operation node. + * + * @param op Which operation. + * @param left Left operand. + * @param right Right operand. + * @return Corresponding AST node. + */ struct ast_node *gen_binop(enum ast_binops op, struct ast_node *left, struct ast_node *right); +/** + * Generate unary operation. + * + * @param op Which operation. + * @param expr Expression. + * @return Corresponding AST node. + */ struct ast_node *gen_unop(enum ast_unops op, struct ast_node *expr); +/** + * Generate call. + * + * @param id ID to call. + * @param args Arguments to call. + * @return Corresponding AST node. + */ struct ast_node *gen_call(struct ast_node *id, struct ast_node *args); +/** + * Generate ID. + * + * @param id ID. + * @return Corresponding AST node. + */ struct ast_node *gen_id(const char *id); +/** + * Generate constant integer. + * + * @param integer Integer. + * @return Corresponding AST node. + */ struct ast_node *gen_int(long long integer); + +/** + * Generate constant string. + * + * @param str String. + * @return Corresponding AST node. + */ struct ast_node *gen_string(const char *str); + +/** + * Generate constant float. + * + * @param dbl Double. + * @return Corresponding AST node. + */ struct ast_node *gen_float(double dbl); +/** + * Generate assignment. + * + * @param to Where to assign to. + * @param from Where to assign from. + * @return Corresponding AST node. + */ struct ast_node *gen_assign(struct ast_node *to, struct ast_node *from); + +/** + * Generate initialization. + * + * @param body Body of initialization. + * @return Corresponding AST node. + */ struct ast_node *gen_init(struct ast_node *body); +/** + * Generate while loop. + * + * @param cond Condition. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_while(struct ast_node *cond, struct ast_node *body); +/** + * Generate for loop. + * + * @param pre Pre condition. + * @param cond Condition. + * @param post Post condition. + * @param body Loop body. + * @return Corresponding AST node. + */ struct ast_node *gen_for(struct ast_node *pre, struct ast_node *cond, struct ast_node *post, struct ast_node *body); +/** + * Generate return. + * + * @param expr Expression. + * @return Corresponding AST node. + */ struct ast_node *gen_return(struct ast_node *expr); +/** + * Generate control statement. + * @note Some generators take source location info, which is then + * propagated to higher level nodes. + * + * @todo not sure where to best place the note about location + * + * @param kind Break or continue. + * @param loc Source location. + * @return Corresponding AST node. + */ struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc); +/** + * Generate macro definition. + * + * @param id Macro name. + * @param params Macro parameters. + * @param body Macro body. + * @return Corresponding AST node. + */ struct ast_node *gen_macro(struct ast_node *id, struct ast_node *params, struct ast_node *body); +/** + * Generate if. + * + * @param cond Condition. + * @param body Body. + * @param els Else. + * @return Corresponding AST node. + */ struct ast_node *gen_if(struct ast_node *cond, struct ast_node *body, struct ast_node *els); +/** + * Generate switch. + * + * @param cond Condition. + * @param cases List of cases. + * @return Corresponding AST node. + */ struct ast_node *gen_switch(struct ast_node *cond, struct ast_node *cases); +/** + * Generate switch case. + * + * @param expr Condition. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_case(struct ast_node *expr, struct ast_node *body); +/** + * Generate Ek type. + * + * @param kind Type kind. + * @param id Name of type. + * @param decl List of parameters, when applicable. + * @param rets Return type, when applicable. + * @return Corresponding AST node. + */ struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *id, struct ast_node *decl, struct ast_node *rets); +/** + * Generate block. + * + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_block(struct ast_node *body); +/** + * Generate variable. + * + * @param id Name of variable. + * @param type Type of varibable. + * @param init Initialization, when applicable. + * @return Corresponding AST node. + */ struct ast_node *gen_var(struct ast_node *id, struct ast_node *type, struct ast_node *init); +/** + * Generate lambda. + * + * @param captures List of captures. + * @param type Signature of lambda. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_lambda(struct ast_node *captures, - struct ast_node *type, struct ast_node * body); + struct ast_node *type, struct ast_node *body); +/** + * Generate procedure definition. + * + * @param id Name of procedure. + * @param type Signature of procedure. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_proc(struct ast_node *id, struct ast_node *type, struct ast_node *body); +/** + * Generate dot operation. + * + * @param expr Expression to do dot operation to. + * @param id Name to do dot with. + * @return Corresponding AST node. + */ struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id); +/** + * Generate enum definition. + * + * @param id Name of enumeration type. + * @param type Type of enum. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_enum(struct ast_node *id, struct ast_node *type, struct ast_node *body); +/** + * Generate enum member value. + * + * @param id Name of enumeration member. + * @param val Value of enumeration member. + * @return Corresponding AST node. + */ struct ast_node *gen_val(struct ast_node *id, struct ast_node *val); +/** + * Generate alias definition. + * + * @param id Name of alias. + * @param type Type to alias. + * @return Corresponding AST node. + */ struct ast_node *gen_alias(struct ast_node *id, struct ast_node *type); +/** + * Generate trait definition. + * + * @param id Name of trait. + * @param body Body. + * @return Corresponding AST node. + */ struct ast_node *gen_template(struct ast_node *id, struct ast_node *body); +/** + * Generate import; + * + * @param file File to import. + * @return Corresponding AST node. + */ struct ast_node *gen_import(const char *file); +/** + * Generate cast. + * + * @param expr Expression. + * @param type Type to cast expression result to. + * @return Corresponding AST node. + */ struct ast_node *gen_cast(struct ast_node *expr, struct ast_node *type); +/** + * Generate embed. + * + * @param file File to embed. + * @return Corresponding AST node. + */ struct ast_node *gen_embed(const char *file); +/** + * Generate goto. + * + * @param label Name of label to jump to. + * @return Corresponding AST node. + */ struct ast_node *gen_goto(struct ast_node *label); +/** + * Generate goto label. + * + * @param id Name of label. + * @return Corresponding AST node. + */ struct ast_node *gen_label(struct ast_node *id); +/** + * Generate defer. + * + * @param expr Expression to defer. + * @return Corresponding AST node. + */ struct ast_node *gen_defer(struct ast_node *expr); +/** + * Generate as. + * + * @param type Type to resolve with. + * @return Corresponding AST node. + */ struct ast_node *gen_as(struct ast_node *type); +/** + * Generate sizeof. + * + * @param expr Expression to take type of. + * @return Corresponding AST node. + */ struct ast_node *gen_sizeof(struct ast_node *expr); +/** + * Generate structure definition. + * + * @param id Name of structure. + * @param generics List of type parameters. + * @param body Body of structure. + * @return Corresponding AST node. + */ struct ast_node *gen_struct(struct ast_node *id, struct ast_node *generics, struct ast_node *body); +/** + * Generate union definition. + * + * @param id Name of union. + * @param generics List of type parameters. + * @param body Body of structure. + * @return Corresponding AST node. + */ struct ast_node *gen_union(struct ast_node *id, struct ast_node *generics, struct ast_node *body); +/** + * Generate enum member fetch. + * + * @param id Name of enum member to fetch. + * @param type Enum type to fetch from. + * @return Corresponding AST node. + */ struct ast_node *gen_fetch(struct ast_node *id, struct ast_node *type); -/* might have to come up with a better name for this */ +/** + * Generate last element. + * @todo might have to come up with a better name for this + * + * @return Corresponding AST node. + */ struct ast_node *gen_last(); +/** + * Generate empty AST node. + * + * @return Corresponding AST node. + */ struct ast_node *gen_empty(); +/** + * Clone AST node. + * + * @param node Node to clone. + * @return A clone of \p node. + */ struct ast_node *clone_ast_node(struct ast_node *node); + +/** + * Check if two nodes are identical. + * + * @param exact Ignore some less important checks, such as flags, location and + * scope. + * @param left One AST node to compare. + * @param right Other AST node to compare. + * @return \c 0 if nodes aren't identical, \c 1 otherwise. + */ int identical_ast_nodes(int exact, struct ast_node *left, struct ast_node *right); +/** + * Destroy AST node. + * Frees members of AST node as well, but not \c next nodes. + * + * @param node AST node to destroy. + */ void destroy_ast_node(struct ast_node *node); + +/** + * Destroy AST tree. + * Frees members and \c next nodes. + * + * @param root AST tree to destroy. + */ void destroy_ast_tree(struct ast_node *root); +/** + * Dump textual representation of AST to stdout. + * + * @param depth How many spaces to prepend. + * @param root AST node to dump. + */ void dump_ast(int depth, struct ast_node *root); + +/** + * Add \p elem to end of \p list. + * + * @param list List of AST nodes. + * @param elem Add to end of \p list. + */ void ast_append(struct ast_node *list, struct ast_node *elem); + +/** + * Set AST node flags. + * + * @param node Node to set flags for. + * @param flags Flags to set. + */ void ast_set_flags(struct ast_node *node, enum ast_flag flags); + +/** + * Clear AST node flags. + * + * @param node Node to clear flags for. + * @param flags Flags to set. + */ void ast_clear_flags(struct ast_node *node, enum ast_flag flags); + +/** + * Check if \p node has \p flags set. + * All flags have to be set. + * + * @param node Node to check flags for. + * @param flags Flags to check. + * @return \c 1 if all \p flags are set, \c 0 othewise. + */ int ast_flags(struct ast_node *node, enum ast_flag flags); +/** + * Call external callback on all nodes in tree. + * + * @param call Callback to call. + * @param node Node whose all subnodes should be passed to \p call. + * @param data Extra data to pass to \p call. + * @return Whatever \p call returns. + */ int ast_call_on(int (*call)(struct ast_node *node, void *data), struct ast_node *node, void *data); +/** + * Number of elements in AST list. + * + * @param list List whose elements to count. + * @return Number of elements in \p list. + */ size_t ast_list_len(struct ast_node *list); -struct ast_node *ast_last_node(struct ast_node *node); -struct ast_node *ast_block_last(struct ast_node *node); + +/** + * Get last nose in ASt list. + * + * @param list List whose last element to get. + * @return Last node in \p list. + */ +struct ast_node *ast_last_node(struct ast_node *list); + +/** + * Get last element in block. + * + * @param block Block whose last element to get. + * @return Last node in block. + */ +struct ast_node *ast_block_last(struct ast_node *block); #endif /* AST_H */ @@ -3027,23 +3027,22 @@ size_t ast_list_len(struct ast_node *node) return count; } -struct ast_node *ast_last_node(struct ast_node *n) +struct ast_node *ast_last_node(struct ast_node *list) { - if (!n) + if (!list) return NULL; - while (n->next) - n = n->next; + while (list->next) + list = list->next; - return n; + return list; } -struct ast_node *ast_block_last(struct ast_node *n) +struct ast_node *ast_block_last(struct ast_node *block) { - struct ast_node *b = ast_last_node(n); + struct ast_node *b = ast_last_node(block); if (b && b->node_type == AST_BLOCK) return ast_block_last(b->_block.body); return b; } - diff --git a/src/parser_helper.c b/src/parser_helper.c index 5a90df8..2ac3f0d 100644 --- a/src/parser_helper.c +++ b/src/parser_helper.c @@ -28,7 +28,6 @@ void parse(struct parser *p, const char *fname, const char *buf) p->fname = fname; p->buf = buf; - p->buf_offset = 0; p->comment_nesting = 0; p->failed = false; |
