minor implementation for parser
(simple type and defn)
This commit is contained in:
157
src/parse.c
157
src/parse.c
@@ -2,6 +2,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void parser_next(Parser *parser);
|
||||
|
||||
static bool parser_expect(Parser *parser, TokenType type);
|
||||
|
||||
Parser *parser_new(Lexer *lexer) {
|
||||
Parser *parser = malloc(sizeof(Parser));
|
||||
if (parser == NULL) {
|
||||
@@ -25,14 +29,163 @@ static void parser_next(Parser *parser) {
|
||||
parser->peek = lexer_next_token(parser->lexer);
|
||||
}
|
||||
|
||||
static void parser_expect(Parser *parser, TokenType type) {
|
||||
static bool parser_expect(Parser *parser, TokenType type) {
|
||||
if (parser->current.type == type) {
|
||||
parser_next(parser);
|
||||
return true;
|
||||
} else {
|
||||
parser->flag_error = 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
IMPL. PARSER PARSE FUNCTIONS
|
||||
*/
|
||||
*/
|
||||
|
||||
ASTNode *parser_parse_program(Parser *parser) {
|
||||
ASTNode *root = ast_node_program();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ASTNode *parser_parse_defn(Parser *parser) {
|
||||
Token val_tok = parser->current;
|
||||
if (!parser_expect(parser, VAL)) {// must start with VAL
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ASTNode *type_node = parser_parse_type(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;
|
||||
}
|
||||
Token id_tok = parser->current;
|
||||
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;
|
||||
if (expr_node == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
ASTNode *parser_parse_type(Parser *parser) {
|
||||
ASTNode *type_node = NULL;
|
||||
if (parser->current.type == ID) {
|
||||
type_node = parser_parse_type_simple(parser);
|
||||
} else if (parser->current.type == LBRACK) {
|
||||
type_node = parser_parse_type_complex(parser);
|
||||
} else {
|
||||
parser->flag_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
return type_node;
|
||||
}
|
||||
|
||||
ASTNode *parser_parse_type_simple(Parser *parser) {
|
||||
Token token = parser->current;
|
||||
if (!parser_expect(parser, ID)) {
|
||||
return NULL;
|
||||
}
|
||||
ASTNode *type_node = ast_node_type_simple(token);
|
||||
while (parser->current.type == STAR) {
|
||||
Token star_tok = parser->current;
|
||||
parser_next(parser);
|
||||
|
||||
ASTNode *type_star = ast_node_type_star(star_tok);
|
||||
ast_node_add_child(type_node, type_star);
|
||||
}
|
||||
|
||||
return type_node;
|
||||
}
|
||||
|
||||
ASTNode *parser_parse_type_complex(Parser *parser) {
|
||||
Token tok = parser->current;
|
||||
parser_next(parser);
|
||||
|
||||
ASTNode *types[256];
|
||||
ASTNode *type_ret = NULL;
|
||||
size_t cnt = 0;
|
||||
|
||||
ASTNode *ret = NULL;
|
||||
|
||||
while (parser->current.type != RBRACK && parser->current.type != ARROW) {
|
||||
ASTNode *type = parser_parse_type(parser);
|
||||
if (type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
types[cnt++] = type;
|
||||
}
|
||||
|
||||
if (parser->current.type == ARROW) {
|
||||
|
||||
parser_next(parser);
|
||||
|
||||
if (parser->current.type != RBRACK) {
|
||||
type_ret = parser_parse_type(parser);
|
||||
if (type_ret == NULL) return NULL;
|
||||
} else {
|
||||
type_ret = ast_node_type_void(parser);
|
||||
}
|
||||
|
||||
ASTNode * type_param = ast_node_type_param();
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
ast_node_add_child(type_param, types[i]);
|
||||
}
|
||||
|
||||
ASTNode *type_out = ast_node_type_out();
|
||||
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;
|
||||
}
|
||||
if (cnt == 1) {
|
||||
ret = types[0];
|
||||
} else {
|
||||
ret = ast_node_type_void(parser);
|
||||
}
|
||||
} else {
|
||||
parser->flag_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
parser_next(parser);
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user