From 7ad32a2a907150e3ce71e89f126ca2a530550158 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 22 Dec 2021 18:07:53 +0100 Subject: Add builtin object type --- src/parser.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c index e72675f..298220a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,7 +5,7 @@ static Object **objects = NULL; static Root *roots = NULL; static Environment **environments = NULL; -static char *builtins [] = { +static char *builtin_names[] = { "+", "-", "*", "/", "%", "=", "<", ">", "<=", ">=", "not", "and", "or", @@ -14,6 +14,30 @@ static char *builtins [] = { "cons", "car", "cdr", }; +static Object builtins[] = { + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_ADD } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_SUB } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_MUL } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_DIV } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_MOD } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_EQ } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_LT } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_GT } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_LE } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_GE } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_NOT } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_AND } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_OR } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_NIL } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_ZERO } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_FIXNUM } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_BOOL } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_PRINT } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CONS } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CAR } , + { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CDR } , +}; + Token peek_token(const Parser *parser) { if (parser->current >= array_size(parser->tokens)) { @@ -79,6 +103,16 @@ parse_string(Token tok) { Object * parse_symbol(Token tok) { + // Check if symbol is a builtin procedure. + size_t n_builtins = sizeof(builtin_names) / sizeof(char*); + for (size_t i = 0; i < n_builtins; ++i) { + char *str = builtin_names[i]; + size_t str_n = strlen(str); + if (sv_equal(&tok.value, &(StringView){str, str_n})) { + return &builtins[i]; + } + } + Object *ret = object_alloc(tok, OBJ_TYPE_SYMBOL); ret->text = tok.value; return ret; @@ -352,7 +386,9 @@ parse_list(Parser *parser, Errors *errors) { } if (first) { - if (!IS_SYMBOL(current->head) && !IS_LAMBDA(current->head)) { + if (!IS_SYMBOL(current->head) && + !IS_LAMBDA(current->head) && + !IS_BUILTIN(current->head)) { error_push(errors, (Error){ .type = ERR_TYPE_PARSER, .value = ERR_NOT_CALLABLE, @@ -613,20 +649,8 @@ parse(Token *tokens, Errors *errors) { array_push(roots, root); } - // Prepare global environment of builtin functions. - Environment *global_env = env_alloc(NULL); - Environment *env = env_alloc(global_env); - size_t n_builtins = sizeof(builtins) / sizeof(char*); - for (size_t i = 0; i < n_builtins; i++) { - // Prepare builtin symbol. - char *str = builtins[i]; - size_t str_n = strlen(str); - Object *symbol = object_alloc((Token){0}, OBJ_TYPE_SYMBOL); - symbol->text = (StringView){str, str_n}; - - // Insert in global table. - insert_local(global_env, symbol, symbol); - } + // Prepare global environment. + Environment *env = env_alloc(NULL); // Perform semantic analysis: // 1. Populate symbol tables and ensure symbols are in scope when used. @@ -807,6 +831,9 @@ object_display(Object *obj) { object_display(obj->var_expr); printf(" }"); } break; + case OBJ_TYPE_BUILTIN: { + printf("%s", builtin_names[obj->builtin]); + } break; } return; } @@ -828,6 +855,9 @@ object_equal(Object *a, Object *b) { case OBJ_TYPE_STRING: { return sv_equal(&a->text, &b->text); } break; + case OBJ_TYPE_BUILTIN: { + return a->builtin = b->builtin; + } break; default: break; } return false; -- cgit v1.2.1