diff options
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 73 |
1 files changed, 31 insertions, 42 deletions
diff --git a/src/parser.c b/src/parser.c index b89f07d..a274cd8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,13 +1,9 @@ #include "all.h" #include <stdlib.h> -static inline lex_tok_e peek(parser_t *p) { - return iv_get(&p->lx->tokens, p->pos); -} +static inline char peek(const char **p) { return **p; } -static inline lex_tok_e advance(parser_t *p) { - return iv_get(&p->lx->tokens, p->pos++); -} +static inline char advance(const char **p) { return *(*p)++; } static ast_node_t *new_node(ast_type_e type, int val) { ast_node_t *n = malloc(sizeof(ast_node_t)); @@ -18,106 +14,99 @@ static ast_node_t *new_node(ast_type_e type, int val) { return n; } -static ast_node_t *parse_block(parser_t *p); +static ast_node_t *parse_block(const char **p); -static ast_node_t *parse_single(parser_t *p) { - lex_tok_e t = peek(p); +static ast_node_t *parse_single(const char **p) { + char c = peek(p); - switch (t) { + switch (c) { - case LEX_PINC: { + case '+': { int count = 0; - while (peek(p) == LEX_PINC) { + while (peek(p) == '+') { advance(p); count++; } return new_node(AST_INC, count); } - case LEX_PDEC: { + case '-': { int count = 0; - while (peek(p) == LEX_PDEC) { + while (peek(p) == '-') { advance(p); count++; } return new_node(AST_DEC, count); } - case LEX_VINC: { + case '>': { int count = 0; - while (peek(p) == LEX_VINC) { + while (peek(p) == '>') { advance(p); count++; } return new_node(AST_PTR_INC, count); } - case LEX_VDEC: { + case '<': { int count = 0; - while (peek(p) == LEX_VDEC) { + while (peek(p) == '<') { advance(p); count++; } return new_node(AST_PTR_DEC, count); } - case LEX_OUT: + case '.': advance(p); return new_node(AST_OUT, 1); - case LEX_IN: + case ',': advance(p); return new_node(AST_IN, 1); - case LEX_LB: - advance(p); // consume '[' + case '[': + advance(p); return parse_block(p); - case LEX_RB: - return NULL; - - case LEX_EOF: + case ']': + case '\0': return NULL; default: - advance(p); + advance(p); // ignore garbage return NULL; } } -static ast_node_t *parse_block(parser_t *p) { +static ast_node_t *parse_block(const char **p) { ast_node_t *loop = new_node(AST_LOOP, 1); - while (1) { - lex_tok_e t = peek(p); + while (**p) { - if (t == LEX_EOF) { - break; - } - - if (t == LEX_RB) { - advance(p); // consume ']' + if (**p == ']') { + advance(p); break; } ast_node_t *child = parse_single(p); - if (child) { + + if (child) node_vec_push(&loop->children, child); - } } return loop; } -parser_t parser_init(lexer_t *lx) { return (parser_t){.lx = lx, .pos = 0}; } +ast_node_t *parse(const char *src) { + const char *p = src; -ast_node_t *parse_program(parser_t *p) { ast_node_t *head = NULL; ast_node_t *tail = NULL; - while (peek(p) != LEX_EOF) { + while (*p) { - ast_node_t *node = parse_single(p); + ast_node_t *node = parse_single(&p); if (!node) continue; |
