From 9c946630454e93418e3728fe7b668b9a3794f818 Mon Sep 17 00:00:00 2001 From: yenru0 Date: Tue, 25 Nov 2025 23:29:57 +0900 Subject: [PATCH] minor implementation basic expr parsing (not complex like compound, lambda) --- include/ast_util.h | 29 ++++++++++++- include/globals.h | 13 +++--- src/ast_util.c | 104 ++++++++++++++++++++++++++++++++++++++++++--- src/parse.c | 83 ++++++++++++++++++++++++++++++------ test2.cval | 7 ++- 5 files changed, 209 insertions(+), 27 deletions(-) diff --git a/include/ast_util.h b/include/ast_util.h index b051a0a..cdc34bd 100644 --- a/include/ast_util.h +++ b/include/ast_util.h @@ -6,7 +6,6 @@ #include "globals.h" - void ast_node_add_child(ASTNode *parent, ASTNode *child); void ast_node_free(ASTNode *node); @@ -33,4 +32,30 @@ ASTNode *ast_node_type_star(Token tok_star); ASTNode *ast_node_type_void(); -ASTNode *ast_node_id(Token id); \ No newline at end of file +ASTNode *ast_node_id(Token id); + +ASTNode *ast_node_num(Token num); + +ASTNode *ast_node_str(Token str); + +ASTNode *ast_node_star(Token star); + +ASTNode *ast_node_andref(Token andref); + +ASTNode *ast_node_expr(Token caller); + +ASTNode *ast_node_param_list(Token tok_lparen); + +ASTNode *ast_node_param(Token id, ASTNode *type); + +ASTNode *ast_node_compound(Token tok_lcurly); + +ASTNode *ast_node_lambda(ASTNode *param_list, ASTNode *body); + +ASTNode *ast_node_stmt_return(Token tok_return, ASTNode *expr); + +ASTNode *ast_node_stmt_expr(ASTNode *expr); + +ASTNode *ast_node_stmt_if(Token tok_if, ASTNode *condition, ASTNode *then_branch, ASTNode *else_branch); + +ASTNode *ast_node_stmt_set(Token tok_dollar, ASTNode *id, ASTNode *expr); diff --git a/include/globals.h b/include/globals.h index 336e565..a8119d7 100644 --- a/include/globals.h +++ b/include/globals.h @@ -33,11 +33,10 @@ typedef enum { EOF_TOKEN, ERROR, // for parser use - + PARSER_USE, VOID, - } TokenType; @@ -67,8 +66,12 @@ typedef enum { NODE_TYPE_STAR, NODE_EXPR, - NODE_NUM, + NODE_ID, + NODE_NUM, + NODE_STR, + NODE_STAR, + NODE_ANDREF, NODE_PARAM_LIST, NODE_PARAM, @@ -78,9 +81,9 @@ typedef enum { NODE_STMT_RETURN, NODE_STMT_EXPR, + NODE_STMT_SET, + NODE_STMT_IF, - - } NodeKind; typedef struct ASTNode { diff --git a/src/ast_util.c b/src/ast_util.c index 6ff52f4..799b596 100644 --- a/src/ast_util.c +++ b/src/ast_util.c @@ -133,16 +133,110 @@ ASTNode *ast_node_type_star(Token tok_star) { return node; } - ASTNode *ast_node_type_void() { ASTNode *node = - ast_node_new(NODE_TYPE_SIMPLE, (Token) { .type = VOID, .line = 0, .data = {0} }); + ast_node_new(NODE_TYPE_SIMPLE, (Token) {.type = VOID, .line = 0, .data = {0}}); return node; } - -ASTNode *ast_node_id(Token id) { +ASTNode *ast_node_id(Token id) { ASTNode *node = ast_node_new(NODE_ID, id); return node; -} \ No newline at end of file +} + +ASTNode *ast_node_num(Token num) { + ASTNode *node = + ast_node_new(NODE_NUM, num); + return node; +} + +ASTNode *ast_node_str(Token str) { + ASTNode *node = + ast_node_new(NODE_STR, str); + return node; +} + +ASTNode *ast_node_star(Token star) { + ASTNode *node = + ast_node_new(NODE_STAR, star); + return node; +} + +ASTNode *ast_node_andref(Token andref) { + ASTNode *node = + ast_node_new(NODE_ANDREF, andref); + return node; +} + +ASTNode *ast_node_expr(Token caller) { + ASTNode *node = + ast_node_new(NODE_EXPR, caller); + return node; +} + +ASTNode *ast_node_param_list(Token tok_lparen) { + ASTNode *node = + ast_node_new(NODE_PARAM_LIST, tok_lparen); + return node; +} + +ASTNode *ast_node_param(Token id, ASTNode *type) { + ASTNode *node = + ast_node_new(NODE_PARAM, id); + ast_node_add_child(node, type); + return node; +} + +ASTNode *ast_node_compound(Token tok_lcurly) { + ASTNode *node = + ast_node_new(NODE_COMPOUND, tok_lcurly); + return node; +} + +ASTNode *ast_node_lambda(ASTNode *param_list, ASTNode *body) { + ASTNode *node = + ast_node_new(NODE_LAMBDA, param_list->token); + ast_node_add_child(node, param_list); + ast_node_add_child(node, body); + return node; +} + +ASTNode *ast_node_stmt_return(Token tok_return, ASTNode *expr) { + ASTNode *node = + ast_node_new(NODE_STMT_RETURN, tok_return); + if (expr != NULL) { + ast_node_add_child(node, expr); + } + return node; +} + +ASTNode *ast_node_stmt_expr(ASTNode *expr) { + ASTNode *node = + ast_node_new(NODE_STMT_EXPR, expr->token); + ast_node_add_child(node, expr); + return node; +} + +ASTNode *ast_node_stmt_if( + Token tok_if, + ASTNode *cond, /* compound */ + ASTNode *then_branch, /* compound */ + ASTNode *else_branch /* compound */) { + ASTNode *node = + ast_node_new(NODE_STMT_IF, tok_if); + ast_node_add_child(node, cond); + ast_node_add_child(node, then_branch); + if (else_branch != NULL) { + ast_node_add_child(node, else_branch); + } + return node; +} + +ASTNode *ast_node_stmt_set(Token dollar, ASTNode *id, ASTNode *expr) { + ASTNode *node = + ast_node_new(NODE_STMT_SET, dollar); + ast_node_add_child(node, id); + ast_node_add_child(node, expr); + return node; +} \ No newline at end of file diff --git a/src/parse.c b/src/parse.c index 02cc25e..75323a2 100644 --- a/src/parse.c +++ b/src/parse.c @@ -48,14 +48,13 @@ ASTNode *parser_parse_program(Parser *parser) { while (parser->current.type == VAL) { ASTNode *defn_node = parser_parse_defn(parser); - + if (defn_node == NULL) { ast_node_free(root); parser->flag_error = 1; return NULL; } ast_node_add_child(root, defn_node); - printf(":%zu\n", root->capacity); } return root; @@ -71,8 +70,6 @@ ASTNode *parser_parse_defn(Parser *parser) { if (type_node == NULL) { return NULL; } - printf("%d", type_node->kind); - printf("rogally%d\n", parser->current.type); if (parser->current.type != ID) { parser->flag_error = 1; return NULL; @@ -81,28 +78,26 @@ ASTNode *parser_parse_defn(Parser *parser) { ASTNode *id_node = ast_node_id(id_tok); parser_next(parser); - printf("%d", id_node->kind); - ASTNode *expr_node = NULL; - printf("rogally%d\n", parser->current.type); if (parser->current.type != SEMI) { - perror("Parsing expression in definition not implemented yet.\n"); - //expr_node = parser_parse_expr(parser); - return NULL; + expr_node = parser_parse_expr(parser); if (expr_node == NULL) { + parser->flag_error = 1; return NULL; } } - printf("rogally\n"); if (!parser_expect(parser, SEMI)) { return NULL; } - printf("rogally\n"); ASTNode *defn_node = ast_node_defn(val_tok, type_node, id_node, expr_node); return defn_node; } +/* + PARSING TYPE +*/ + ASTNode *parser_parse_type(Parser *parser) { ASTNode *type_node = NULL; if (parser->current.type == ID) { @@ -163,7 +158,7 @@ ASTNode *parser_parse_type_complex(Parser *parser) { type_ret = ast_node_type_void(parser); } - ASTNode * type_param = ast_node_type_param(); + ASTNode *type_param = ast_node_type_param(); for (size_t i = 0; i < cnt; i++) { ast_node_add_child(type_param, types[i]); } @@ -172,7 +167,7 @@ ASTNode *parser_parse_type_complex(Parser *parser) { ast_node_add_child(type_out, type_ret); ret = ast_node_type_complex(tok, type_param, type_out); } else if (parser->current.type == RBRACK) { - + if (cnt >= 2) { parser->flag_error = 1;// too many args return NULL; @@ -188,4 +183,64 @@ ASTNode *parser_parse_type_complex(Parser *parser) { } parser_next(parser); return ret; +} + +/* + PARSING EXPR +*/ + +ASTNode *parser_parse_expr(Parser *parser) { + ASTNode *atoms[256]; + size_t cnt = 1; + ASTNode *atom_head = parser_parse_atom(parser); + if (atom_head == NULL) { + parser->flag_error = 1; + return NULL; + } + atoms[0] = atom_head; + + ASTNode *atom; + while (true) { + atom = parser_parse_atom(parser); + if (atom == NULL) { + break; + } + atoms[cnt] = atom; + cnt++; + } + + ASTNode *node = ast_node_expr(atom_head->token); + for (size_t i = 0; i < cnt; i++) { + ast_node_add_child(node, atoms[i]); + } + + return node; +} + +ASTNode *parser_parse_atom(Parser *parser) { + if (parser->current.type == NUM) { + Token num_tok = parser->current; + parser_next(parser); + return ast_node_num(num_tok); + } else if (parser->current.type == ID) { + Token id_tok = parser->current; + parser_next(parser); + return ast_node_id(id_tok); + } else if (parser->current.type == STRING_LITERAL) { + Token str_tok = parser->current; + parser_next(parser); + return ast_node_str(str_tok); + } else if (parser->current.type == STAR) { + Token star_tok = parser->current; + parser_next(parser); + return ast_node_star(star_tok); + } else if (parser->current.type == ANDREF) { + Token andref_tok = parser->current; + parser_next(parser); + return ast_node_andref(andref_tok); + } + + else { + return NULL; + } } \ No newline at end of file diff --git a/test2.cval b/test2.cval index 3244143..336e114 100644 --- a/test2.cval +++ b/test2.cval @@ -1,2 +1,7 @@ val [->int] main; -val int n; \ No newline at end of file + +val char* line; + +val size_t line get_line_ptr stdin line; + +val char first *line; \ No newline at end of file