From 00e5a5c4657ae09f8129777b67e268e2f103a4ce Mon Sep 17 00:00:00 2001 From: Alexander Goussas Date: Wed, 30 Oct 2024 23:06:38 -0500 Subject: [PATCH] feat: start parsing call expressions --- ast.c | 7 +++++++ lexer.c | 28 ++++++++++++++++++++++++++++ lexer.h | 2 ++ parser.c | 42 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/ast.c b/ast.c index 2f564d9..392be59 100644 --- a/ast.c +++ b/ast.c @@ -2,6 +2,7 @@ #include #include #include +#include so_expr *create_string_node(const char *s) { @@ -53,6 +54,8 @@ void print_ast(so_expr *e) case SO_EXPR_CALL: printf("CALL %s (%d)\n", e->as.call.name, e->as.call.nargs); break; + default: + assert(0 && "unhandled case in print_ast"); } } @@ -68,6 +71,10 @@ void free_ast(so_expr *e) case SO_EXPR_LOAD: free(e->as.load.name); break; + case SO_EXPR_CALL: + free(e->as.call.name); + for (int i = 0; i < e->as.call.nargs; i++) + free_ast(e->as.call.args[i]); } free(e); } diff --git a/lexer.c b/lexer.c index 29dd618..54e4f1a 100644 --- a/lexer.c +++ b/lexer.c @@ -15,6 +15,34 @@ void so_token_deinit(so_token *t) t->type = SO_TT_INVALID; } +void so_token_type_to_string(so_token_type tt, char buffer[], int size) +{ + switch (tt) + { + case SO_TT_USE: + strncpy(buffer, "USE", size); + break; + case SO_TT_CALL: + strncpy(buffer, "CALL", size); + break; + case SO_TT_BARE: + strncpy(buffer, "BAREWORD", size); + break; + case SO_TT_STRING: + strncpy(buffer, "STRING", size); + break; + case SO_TT_INTEGER: + strncpy(buffer, "INTEGER", size); + break; + case SO_TT_EOF: + strncpy(buffer, "EOF", size); + break; + case SO_TT_INVALID: + strncpy(buffer, "INVALID", size); + break; + } +} + static char so_lexer_advance(so_lexer *l) { if (l->current >= l->source_length) diff --git a/lexer.h b/lexer.h index 8aafe79..cc140fe 100644 --- a/lexer.h +++ b/lexer.h @@ -12,6 +12,8 @@ typedef enum SO_TT_INVALID, } so_token_type; +void so_token_type_to_string(so_token_type tt, char buffer[], int size); + typedef struct { so_token_type type; diff --git a/parser.c b/parser.c index 4f51343..e902410 100644 --- a/parser.c +++ b/parser.c @@ -6,6 +6,7 @@ static void so_parse_call(so_parser *); static void so_parse_load(so_parser *); +static so_expr *so_parser_parse_simple_expression(so_parser *); static so_token so_parser_advance(so_parser *p) { @@ -17,7 +18,9 @@ static int so_parser_expect(so_parser *p, so_token_type tt) { if (p->current.type != tt) { - fprintf(stderr, "warning: expected a different type of token\n"); + char buffer[20] = {0}; + so_token_type_to_string(tt, buffer, sizeof(buffer)); + fprintf(stderr, "warning: expected a different type of token: %s\n", buffer); return 0; } return 1; @@ -74,7 +77,40 @@ void so_parser_parse(so_parser *p) void so_parse_call(so_parser *p) { + if (!so_parser_expect(p, SO_TT_CALL)) + { + so_token_deinit(&p->current); + return; + } + so_token_deinit(&p->current); + so_parser_advance(p); + + if (!so_parser_expect(p, SO_TT_BARE)) + { + so_token_deinit(&p->current); + return; + } + + so_token name = p->current; + so_expr *args[MAX_CALL_ARGS]; + int nargs = 0; + + while (so_parser_advance(p).type != SO_TT_EOF && nargs < MAX_CALL_ARGS) + args[nargs++] = so_parser_parse_simple_expression(p); + + if (!so_parser_expect(p, SO_TT_EOF)) + { + fprintf(stderr, "warning: expected EOF"); + so_token_deinit(&p->current); + return; + } + + so_expr *e = create_call_node(name.lexeme, nargs, args); + add_command(p, e); + + so_token_deinit(&p->current); + so_token_deinit(&name); } void so_parse_load(so_parser *p) @@ -101,3 +137,7 @@ void so_parse_load(so_parser *p) so_token_deinit(&use); so_token_deinit(&p->current); } + +so_expr *so_parser_parse_simple_expression(so_parser *p) +{ +} -- 2.43.0