]> git.frustrated-labs.net Git - so-test.git/commitdiff
feat: start parsing call expressions
authorAlexander Goussas <[email protected]>
Thu, 31 Oct 2024 04:06:38 +0000 (23:06 -0500)
committerAlexander Goussas <[email protected]>
Thu, 31 Oct 2024 04:06:38 +0000 (23:06 -0500)
ast.c
lexer.c
lexer.h
parser.c

diff --git a/ast.c b/ast.c
index 2f564d9108bee16208adfa38a79066089bede350..392be59cf13c805773e352764535c4d90fbde8c6 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <assert.h>
 
 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 29dd618aead2fc8684c8c885ae3639d33bc7cc98..54e4f1a49236c5ec7a90f7167410da529d19b56c 100644 (file)
--- 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 8aafe791a6a47edaf2fb49fb44410f52676a65af..cc140fea3fb06bd4b7a34e6f159a0dbdf3fc7d3e 100644 (file)
--- 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;
index 4f51343b304ed076b0d644c5a4fbaf52a27d041f..e902410280df91cb3976183a6f11a9cb596f9bca 100644 (file)
--- 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)
+{
+}