#ifndef _AST_EXPR_EXPR_H_ #define _AST_EXPR_EXPR_H_ #include "../ctx.h" #include "../node.h" #include struct ivy_ast_node; struct ivy_ast_msg_node; enum expr_type { EXPR_TYPE_NONE = 0, /* if-else, while/for, match, etc (any expression that ends with an * 'end' keyword */ EXPR_TYPE_STMT, /* arithmetic and message-sending expressions (any expression that ends * implicitly or with an expression separator */ EXPR_TYPE_ARITH, }; enum expr_subtype { EXPR_SUBTYPE_NONE = 0, /* generic parenthesis-enclosed arithmetic expressions */ EXPR_SUBTYPE_PAREN, /* any kind of message */ EXPR_SUBTYPE_MSG, /* keyword messages */ EXPR_SUBTYPE_KEYWORD_MSG, /* expression delimited by labels */ EXPR_SUBTYPE_KEYWORD_ARG, /* complex messages */ EXPR_SUBTYPE_COMPLEX_MSG, /* message cascade operation */ EXPR_SUBTYPE_CASCADE, }; enum expr_component { EXPR_CMP_NONE = 0, EXPR_CMP_OPERATOR, EXPR_CMP_OPERAND, EXPR_CMP_MSG, }; struct expr_parser_state { struct parser_state s_base; enum expr_type s_type; enum expr_subtype s_sub_type; /* this is a return statement (prefixed with a caret) */ bool s_return; /* for arithmetic expressions, this records whether the previous * component (either a token or parenthesised group of tokens) is an * operator, operand, or message */ enum expr_component s_prev_component; /* the token type/keyword type/symbol type of the last token that was * encountered */ unsigned int s_prev_token; /* if this is an arithmetic expression, this variable is the depth * of parentheses that this sub-expression is at */ unsigned int s_paren_depth; /* if this expression is parsing a sub-component of a larger expression, * the depth of the expression is recorded here. */ unsigned int s_subexpr_depth; /* when this is set, the expression will be terminated when the * specified token is encountered. the token that terminated the * expression will not be consumed. */ unsigned int s_terminator; b_queue s_output_queue; b_queue s_operator_stack; /* these variables are for keyword-message expressions */ struct ivy_ast_node *s_recipient; struct ivy_ast_msg_node *s_msg; b_queue s_labels; union { /* for keyword-messages, this is a list of arg values. */ b_queue s_args; /* for cascade operators, this is a list of messages to send to the recipient. */ b_queue s_cascade_msg; }; }; /* general functions */ extern struct token_parse_result expr_finalise( struct ivy_parser *ctx, struct expr_parser_state *state, enum ivy_operator_precedence min_precedence, struct ivy_ast_node **expr); extern struct token_parse_result expr_finalise_and_return( struct ivy_parser *ctx, struct expr_parser_state *state); /* arithmetic parser callbacks */ extern void arith_push_operator( struct expr_parser_state *state, struct ivy_ast_node *node); extern enum ivy_status arith_push_operand( struct expr_parser_state *state, struct ivy_token *tok); extern enum ivy_status arith_add_child( struct parser_state *parent, struct ivy_ast_node *child); extern struct token_parse_result arith_parse_ident( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_operand( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_operator( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_label( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_left_paren( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_right_paren( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_semicolon( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_dot( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_bang( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_caret( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_comma( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_equal_right_angle( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_in( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_do( struct ivy_parser *ctx, struct ivy_token *tok); /* statement parser callbacks */ extern struct token_parse_result stmt_parse_for( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result stmt_parse_while( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result stmt_parse_match( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result stmt_parse_if( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result stmt_parse_then( struct ivy_parser *ctx, struct ivy_token *tok); struct token_parse_result stmt_parse_else( struct ivy_parser *ctx, struct ivy_token *tok); struct token_parse_result stmt_parse_end( struct ivy_parser *ctx, struct ivy_token *tok); #endif