#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
so_expr *create_string_node(const char *s)
{
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");
}
}
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);
}
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)
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)
{
{
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;
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)
so_token_deinit(&use);
so_token_deinit(&p->current);
}
+
+so_expr *so_parser_parse_simple_expression(so_parser *p)
+{
+}