minor implementation
basic expr parsing (not complex like compound, lambda)
This commit is contained in:
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
|
|
||||||
void ast_node_add_child(ASTNode *parent, ASTNode *child);
|
void ast_node_add_child(ASTNode *parent, ASTNode *child);
|
||||||
|
|
||||||
void ast_node_free(ASTNode *node);
|
void ast_node_free(ASTNode *node);
|
||||||
@@ -34,3 +33,29 @@ ASTNode *ast_node_type_star(Token tok_star);
|
|||||||
ASTNode *ast_node_type_void();
|
ASTNode *ast_node_type_void();
|
||||||
|
|
||||||
ASTNode *ast_node_id(Token id);
|
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);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ typedef enum {
|
|||||||
|
|
||||||
VOID,
|
VOID,
|
||||||
|
|
||||||
|
|
||||||
} TokenType;
|
} TokenType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -67,8 +66,12 @@ typedef enum {
|
|||||||
NODE_TYPE_STAR,
|
NODE_TYPE_STAR,
|
||||||
|
|
||||||
NODE_EXPR,
|
NODE_EXPR,
|
||||||
NODE_NUM,
|
|
||||||
NODE_ID,
|
NODE_ID,
|
||||||
|
NODE_NUM,
|
||||||
|
NODE_STR,
|
||||||
|
NODE_STAR,
|
||||||
|
NODE_ANDREF,
|
||||||
|
|
||||||
NODE_PARAM_LIST,
|
NODE_PARAM_LIST,
|
||||||
NODE_PARAM,
|
NODE_PARAM,
|
||||||
@@ -78,8 +81,8 @@ typedef enum {
|
|||||||
|
|
||||||
NODE_STMT_RETURN,
|
NODE_STMT_RETURN,
|
||||||
NODE_STMT_EXPR,
|
NODE_STMT_EXPR,
|
||||||
|
NODE_STMT_SET,
|
||||||
|
NODE_STMT_IF,
|
||||||
|
|
||||||
} NodeKind;
|
} NodeKind;
|
||||||
|
|
||||||
|
|||||||
100
src/ast_util.c
100
src/ast_util.c
@@ -133,16 +133,110 @@ ASTNode *ast_node_type_star(Token tok_star) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ASTNode *ast_node_type_void() {
|
ASTNode *ast_node_type_void() {
|
||||||
ASTNode *node =
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ASTNode *ast_node_id(Token id) {
|
ASTNode *ast_node_id(Token id) {
|
||||||
ASTNode *node =
|
ASTNode *node =
|
||||||
ast_node_new(NODE_ID, id);
|
ast_node_new(NODE_ID, id);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
79
src/parse.c
79
src/parse.c
@@ -55,7 +55,6 @@ ASTNode *parser_parse_program(Parser *parser) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ast_node_add_child(root, defn_node);
|
ast_node_add_child(root, defn_node);
|
||||||
printf(":%zu\n", root->capacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
@@ -71,8 +70,6 @@ ASTNode *parser_parse_defn(Parser *parser) {
|
|||||||
if (type_node == NULL) {
|
if (type_node == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("%d", type_node->kind);
|
|
||||||
printf("rogally%d\n", parser->current.type);
|
|
||||||
if (parser->current.type != ID) {
|
if (parser->current.type != ID) {
|
||||||
parser->flag_error = 1;
|
parser->flag_error = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -81,28 +78,26 @@ ASTNode *parser_parse_defn(Parser *parser) {
|
|||||||
ASTNode *id_node = ast_node_id(id_tok);
|
ASTNode *id_node = ast_node_id(id_tok);
|
||||||
parser_next(parser);
|
parser_next(parser);
|
||||||
|
|
||||||
printf("%d", id_node->kind);
|
|
||||||
|
|
||||||
ASTNode *expr_node = NULL;
|
ASTNode *expr_node = NULL;
|
||||||
printf("rogally%d\n", parser->current.type);
|
|
||||||
if (parser->current.type != SEMI) {
|
if (parser->current.type != SEMI) {
|
||||||
perror("Parsing expression in definition not implemented yet.\n");
|
expr_node = parser_parse_expr(parser);
|
||||||
//expr_node = parser_parse_expr(parser);
|
|
||||||
return NULL;
|
|
||||||
if (expr_node == NULL) {
|
if (expr_node == NULL) {
|
||||||
|
parser->flag_error = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("rogally\n");
|
|
||||||
if (!parser_expect(parser, SEMI)) {
|
if (!parser_expect(parser, SEMI)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("rogally\n");
|
|
||||||
|
|
||||||
ASTNode *defn_node = ast_node_defn(val_tok, type_node, id_node, expr_node);
|
ASTNode *defn_node = ast_node_defn(val_tok, type_node, id_node, expr_node);
|
||||||
return defn_node;
|
return defn_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
PARSING TYPE
|
||||||
|
*/
|
||||||
|
|
||||||
ASTNode *parser_parse_type(Parser *parser) {
|
ASTNode *parser_parse_type(Parser *parser) {
|
||||||
ASTNode *type_node = NULL;
|
ASTNode *type_node = NULL;
|
||||||
if (parser->current.type == ID) {
|
if (parser->current.type == ID) {
|
||||||
@@ -163,7 +158,7 @@ ASTNode *parser_parse_type_complex(Parser *parser) {
|
|||||||
type_ret = ast_node_type_void(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++) {
|
for (size_t i = 0; i < cnt; i++) {
|
||||||
ast_node_add_child(type_param, types[i]);
|
ast_node_add_child(type_param, types[i]);
|
||||||
}
|
}
|
||||||
@@ -189,3 +184,63 @@ ASTNode *parser_parse_type_complex(Parser *parser) {
|
|||||||
parser_next(parser);
|
parser_next(parser);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,7 @@
|
|||||||
val [->int] main;
|
val [->int] main;
|
||||||
val int n;
|
|
||||||
|
val char* line;
|
||||||
|
|
||||||
|
val size_t line get_line_ptr stdin line;
|
||||||
|
|
||||||
|
val char first *line;
|
||||||
Reference in New Issue
Block a user