diff --git a/lang/ast.c b/lang/ast.c new file mode 100644 index 0000000..e69de29 diff --git a/lang/include/ivy/lang/ast.h b/lang/include/ivy/lang/ast.h index e69de29..44792e2 100644 --- a/lang/include/ivy/lang/ast.h +++ b/lang/include/ivy/lang/ast.h @@ -0,0 +1,223 @@ +#ifndef IVY_LANG_AST_H_ +#define IVY_LANG_AST_H_ + +#include + +struct ivy_token; + +enum ivy_ast_node_type { + IVY_AST_NONE = 0x00, + IVY_AST_UNIT, + IVY_AST_OP, + IVY_AST_MSG, + IVY_AST_CLASS, + IVY_AST_MSGH, + IVY_AST_PROPERTY, + IVY_AST_LAMBDA, + IVY_AST_UNIT_PACKAGE, + IVY_AST_UNIT_IMPORT, + IVY_AST_INT, + IVY_AST_DOUBLE, + IVY_AST_STRING, + IVY_AST_FSTRING, + IVY_AST_ATOM, + IVY_AST_IDENT, + IVY_AST_FOR_LOOP, + IVY_AST_WHILE_LOOP, + IVY_AST_COND_GROUP, + IVY_AST_COND, + IVY_AST_TUPLE, + IVY_AST_DO, +}; + +enum ivy_ast_op { + IVY_OP_NONE = 0, + IVY_OP_ASSIGN, + IVY_OP_ADD, + IVY_OP_SUBTRACT, + IVY_OP_MULTIPLY, + IVY_OP_DIVIDE, + IVY_OP_LESS_THAN, + IVY_OP_GREATER_THAN, + IVY_OP_EQUAL, + IVY_OP_NOT_EQUAL, + IVY_OP_LESS_EQUAL, + IVY_OP_GREATER_EQUAL, + IVY_OP_AND, + IVY_OP_OR, + IVY_OP_IS, + IVY_OP_NOT, +}; + +enum ivy_ast_msgh_recipient_type { + IVY_AST_MSGH_NONE = 0, + IVY_AST_MSGH_OBJECT, + IVY_AST_MSGH_CLASS, +}; + +struct ivy_ast_node { + enum ivy_ast_node_type n_type; + b_queue_entry n_entry; +}; + +struct ivy_ast_unit_node { + struct ivy_ast_node n_base; +}; + +struct ivy_ast_op_node { + struct ivy_ast_node n_base; + enum ivy_ast_op n_op; + struct ivy_ast_node *n_left; // NULL for unary operators. + struct ivy_ast_node *n_right; +}; + +struct ivy_ast_selector_node { + struct ivy_ast_node n_base; + /* NULL for keyword messages. */ + struct ivy_token *n_msg_name; + /* queue of struct ivy_token; empty for unary messages. */ + b_queue n_args; +}; + +struct ivy_ast_msg_node { + struct ivy_ast_node n_base; + struct ivy_ast_node *n_recipient; + struct ivy_ast_selector_node *n_sel; + /* queue of struct ivy_ast_node; empty for unary messages. */ + b_queue n_arg; +}; + +struct ivy_ast_class_node { + struct ivy_ast_node n_base; + + struct ivy_token *n_ident; + + /* queue of struct ivy_ast_property_node */ + b_queue n_properties; + /* queue of struct ivy_ast_msgh_node */ + b_queue n_msg_handlers; +}; + +struct ivy_ast_msgh_node { + struct ivy_ast_node n_base; + enum ivy_ast_msgh_recipient_type n_recipient; + struct ivy_ast_selector_node *n_sel; + /* queue of struct ivy_ast_node; expressions to evaluate when message handler is executed. */ + b_queue n_body; +}; + +struct ivy_ast_property_node { + struct ivy_ast_node n_base; + struct ivy_token *n_ident; + /* one of either: + * a) a lambda. the lambda is executed to get the property value; or, + * b) a constant value. the constant is returned as the property value. + * c) NULL. the property is write-only. + */ + struct ivy_ast_node *n_get; + /* one of either: + * a) a lambda. the lambda is executed with the provided value as a parameter to set the property value; or, + * b) NULL. the property is read-only. + */ + struct ivy_ast_node *n_set; +}; + +struct ivy_ast_lambda_node { + struct ivy_ast_node n_base; + /* queue of struct lex_token; contains the names of the lambda parameters. */ + b_queue n_arg; + /* queue of struct ivy_ast_node; expressions to evaluate when lambda is executed. */ + b_queue n_body; +}; + +struct ivy_ast_unit_package_node { + struct ivy_ast_node n_base; + /* queue of struct ivy_token; list of multi-part identifier parts. */ + b_queue n_ident; +}; + +struct ivy_ast_unit_use_node { + struct ivy_ast_node n_base; + /* queue of struct ivy_token; list of multi-part identifier parts. */ + b_queue n_ident; +}; + +struct ivy_ast_int_node { + struct ivy_ast_node n_base; + /* lex token of type IVY_TOK_INT. */ + struct ivy_token *n_value; +}; + +struct ivy_ast_double_node { + struct ivy_ast_node n_base; + /* lex token of type IVY_TOK_DOUBLE. */ + struct ivy_token *n_value; +}; + +struct ivy_ast_string_node { + struct ivy_ast_node n_base; + /* lex token of type IVY_TOK_STRING. */ + struct ivy_token *n_value; +}; + +struct ivy_ast_fstring_node { + struct ivy_ast_node n_base; + /* list of struct ivy_ast_node. nodes are evaluated and combined in-order into a string. */ + b_queue n_value; +}; + +struct ivy_ast_atom_node { + struct ivy_ast_node n_base; + struct ivy_token *n_content; +}; + +struct ivy_ast_ident_node { + struct ivy_ast_node n_base; + struct ivy_token *n_content; +}; + +struct ivy_ast_for_loop_node { + struct ivy_ast_node n_base; + /* the interation 'counter', could be an identifier or a tuple. */ + struct ivy_ast_node *n_iterator; + /* the object being iterated over, an expression that evaluates to an object that can be iterated. */ + struct ivy_ast_node *n_iterable; + /* queue of struct ivy_ast_node. expressions to evaluate as part of the loop. */ + b_queue n_body; +}; + +struct ivy_ast_while_loop_node { + struct ivy_ast_node n_base; + /* the expression to check before each loop iteration. */ + struct ivy_ast_node *n_cond; + /* queue of struct ivy_ast_node. expressions to evaluate as part of the loop. */ + b_queue n_body; +}; + +struct ivy_ast_cond_group_node { + struct ivy_ast_node n_base; + /* queue of struct ivy_ast_cond_node. */ + b_queue n_branches; +}; + +struct ivy_ast_cond_node { + struct ivy_ast_node n_base; + /* expression. must evaluate to true for the condition body to be evaluated. NULL for unconditional (else). */ + struct ivy_ast_node *n_cond; + /* queue of struct ivy_ast_node. expressions to evaluate if the condition is true. */ + b_queue n_body; +}; + +struct ivy_ast_tuple_node { + struct ivy_ast_node n_base; + /* queue of struct ivy_ast_node. each can be either an identifier, a constant, or a tuple. */ + b_queue n_members; +}; + +struct ivy_ast_do_node { + struct ivy_ast_node n_base; + /* queue of struct ivy_ast_node. expressions to evaluate when the do node itself is evaluated. */ + b_queue n_members; +}; + +#endif \ No newline at end of file