struct node *parse_statements(struct compiler *compiler) { skip_seps(compiler); if(is_expression(compiler)) { struct node *result = parse_statement(compiler); if (is_sep(compiler)) { skip_seps(compiler); if(is_expression(compiler)) { struct node *node = alloc_node(compiler, N_STATEMENTS); node->left = result; node->right = parse_statements(compiler); return node; } } return result; } else return &nil_node; }
/* block -> lstatement | '{' statements '}' */ ast_node* parse_block() { ast_node* block = ast_block_init(); if (match(T_L_BRACE, T_UNDEF)) { parse_statements(block); expect(T_R_BRACE); } else if (parse_lstatement(block)); else syntax_error("'ID', 'skip', 'if', 'while' or 'await'"); return block; }
struct node *parse_main(struct compiler *compiler) { struct block *block; struct node *result = alloc_scope(compiler, &block, S_MAIN); block->owner = block; result->right = parse_statements(compiler); lexer_match(compiler, T_EOF); return result; }
/* process -> statements */ void parse_process(ast_node* block) { parse_statements(block); }
int length = strlen(main_function_opening) + strlen(statements) + strlen(main_function_closening) + 1; char *program = malloc(length); sprintf(program, "%s%s%s", main_function_opening, statements, main_function_closening); res = parse_string(program, tree); free(program); return res; } begin_example(statement_parser, should_parse_the_empty_statement) char *statement = "{}"; ast *tree; should_pass(parse_statements(statement, &tree)) delete_parser(tree); end_example begin_example(statement_parser, should_fail_when_missing_rigth_curly_bracket) char *statement = "{"; ast *tree; should_fail(parse_statements(statement, &tree)) delete_parser(tree); end_example begin_example(statement_parser, should_fail_when_missing_left_curly_bracket) char *statement = "}"; ast *tree; should_fail(parse_statements(statement, &tree)) delete_parser(tree);
struct node *parse_factor(struct compiler *compiler) { switch (lexer_current(compiler)) { case T_BEGIN: return parse_begin(compiler); case T_IF: return parse_if(compiler); case T_UNLESS: return parse_unless(compiler); case T_CASE: return parse_case(compiler); case T_CLASS: return parse_class(compiler); case T_MODULE: return parse_module(compiler); case T_DEF: return parse_method(compiler); case T_YIELD: return parse_yield(compiler); case T_RETURN: return parse_return(compiler); case T_BREAK: return parse_break(compiler); case T_NEXT: return parse_next(compiler); case T_REDO: return parse_redo(compiler); case T_SQUARE_OPEN: { struct node *result = alloc_node(compiler, N_ARRAY); lexer_next(compiler); if(lexer_current(compiler) == T_SQUARE_CLOSE) result->left = 0; else result->left = parse_array_element(compiler); lexer_match(compiler, T_SQUARE_CLOSE); return result; } case T_STRING: { struct node *result = alloc_node(compiler, N_STRING); result->left = (void *)lexer_token(compiler)->start; lexer_next(compiler); return result; } case T_STRING_START: { struct node *result = alloc_node(compiler, N_STRING_CONTINUE); result->left = 0; result->middle = (void *)lexer_token(compiler)->start; lexer_next(compiler); result->right = parse_statements(compiler); while(lexer_current(compiler) == T_STRING_CONTINUE) { struct node *node = alloc_node(compiler, N_STRING_CONTINUE); node->left = result; node->middle = (void *)lexer_token(compiler)->start; lexer_next(compiler); node->right = parse_statements(compiler); result = node; } if(lexer_require(compiler, T_STRING_END)) { struct node *node = alloc_node(compiler, N_STRING_START); node->left = result; node->right = (void *)lexer_token(compiler)->start; lexer_next(compiler); return node; } return result; } case T_SELF: { lexer_next(compiler); return &self_node; } case T_TRUE: { lexer_next(compiler); return alloc_node(compiler, N_TRUE); } case T_FALSE: { lexer_next(compiler); return alloc_node(compiler, N_FALSE); } case T_NIL: { lexer_next(compiler); return &nil_node; } case T_NUMBER: { struct node *result = alloc_node(compiler, N_NUMBER); char *text = get_token_str(lexer_token(compiler)); result->left = (void* )atoi(text); lexer_next(compiler); return result; } case T_IVAR: { rt_value symbol = rt_symbol_from_lexer(compiler); lexer_next(compiler); switch (lexer_current(compiler)) { case T_ASSIGN_ADD: case T_ASSIGN_SUB: case T_ASSIGN_MUL: case T_ASSIGN_DIV: { struct node *result; enum token_type op_type = lexer_current(compiler) - OP_TO_ASSIGN; lexer_next(compiler); result = alloc_node(compiler, N_IVAR_ASSIGN); result->right = alloc_node(compiler, N_BINARY_OP); result->right->op = op_type; result->right->left = alloc_node(compiler, N_IVAR); result->right->left->left = (void *)symbol; result->right->right = parse_expression(compiler); result->left = (void *)symbol; return result; } case T_ASSIGN: { struct node *result; lexer_next(compiler); result = alloc_node(compiler, N_IVAR_ASSIGN); result->left = (void *)symbol; result->right = parse_expression(compiler); return result; } default: { struct node *result = alloc_node(compiler, N_IVAR); result->left = (void *)symbol; return result; } } } case T_IDENT: return parse_identifier(compiler); case T_EXT_IDENT: return parse_call(compiler, 0, &self_node, false); case T_PARAM_OPEN: { lexer_next(compiler); struct node *result = parse_statements(compiler); lexer_match(compiler, T_PARAM_CLOSE); return result; } default: { COMPILER_ERROR(compiler, "Expected expression but found %s", token_type_names[lexer_current(compiler)]); lexer_next(compiler); return 0; } } }