diff options
author | Bad Diode <bd@badd10de.dev> | 2021-12-22 18:07:53 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-12-22 18:07:53 +0100 |
commit | 7ad32a2a907150e3ce71e89f126ca2a530550158 (patch) | |
tree | 2c5db028cd7e5b5244db3d43f7561d7a8327f07a /src/parser.c | |
parent | fd65adf81f6c3e7e94755a83e22f7e0a19f8bd99 (diff) | |
download | bdl-7ad32a2a907150e3ce71e89f126ca2a530550158.tar.gz bdl-7ad32a2a907150e3ce71e89f126ca2a530550158.zip |
Add builtin object type
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 62 |
1 files changed, 46 insertions, 16 deletions
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; | |||
5 | static Root *roots = NULL; | 5 | static Root *roots = NULL; |
6 | static Environment **environments = NULL; | 6 | static Environment **environments = NULL; |
7 | 7 | ||
8 | static char *builtins [] = { | 8 | static char *builtin_names[] = { |
9 | "+", "-", "*", "/", "%", | 9 | "+", "-", "*", "/", "%", |
10 | "=", "<", ">", "<=", ">=", | 10 | "=", "<", ">", "<=", ">=", |
11 | "not", "and", "or", | 11 | "not", "and", "or", |
@@ -14,6 +14,30 @@ static char *builtins [] = { | |||
14 | "cons", "car", "cdr", | 14 | "cons", "car", "cdr", |
15 | }; | 15 | }; |
16 | 16 | ||
17 | static Object builtins[] = { | ||
18 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_ADD } , | ||
19 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_SUB } , | ||
20 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_MUL } , | ||
21 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_DIV } , | ||
22 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_MOD } , | ||
23 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_EQ } , | ||
24 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_LT } , | ||
25 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_GT } , | ||
26 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_LE } , | ||
27 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_GE } , | ||
28 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_NOT } , | ||
29 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_AND } , | ||
30 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_OR } , | ||
31 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_NIL } , | ||
32 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_ZERO } , | ||
33 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_FIXNUM } , | ||
34 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_BOOL } , | ||
35 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_PRINT } , | ||
36 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CONS } , | ||
37 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CAR } , | ||
38 | { .type = OBJ_TYPE_BUILTIN, .builtin = BUILTIN_IS_CDR } , | ||
39 | }; | ||
40 | |||
17 | Token | 41 | Token |
18 | peek_token(const Parser *parser) { | 42 | peek_token(const Parser *parser) { |
19 | if (parser->current >= array_size(parser->tokens)) { | 43 | if (parser->current >= array_size(parser->tokens)) { |
@@ -79,6 +103,16 @@ parse_string(Token tok) { | |||
79 | 103 | ||
80 | Object * | 104 | Object * |
81 | parse_symbol(Token tok) { | 105 | parse_symbol(Token tok) { |
106 | // Check if symbol is a builtin procedure. | ||
107 | size_t n_builtins = sizeof(builtin_names) / sizeof(char*); | ||
108 | for (size_t i = 0; i < n_builtins; ++i) { | ||
109 | char *str = builtin_names[i]; | ||
110 | size_t str_n = strlen(str); | ||
111 | if (sv_equal(&tok.value, &(StringView){str, str_n})) { | ||
112 | return &builtins[i]; | ||
113 | } | ||
114 | } | ||
115 | |||
82 | Object *ret = object_alloc(tok, OBJ_TYPE_SYMBOL); | 116 | Object *ret = object_alloc(tok, OBJ_TYPE_SYMBOL); |
83 | ret->text = tok.value; | 117 | ret->text = tok.value; |
84 | return ret; | 118 | return ret; |
@@ -352,7 +386,9 @@ parse_list(Parser *parser, Errors *errors) { | |||
352 | } | 386 | } |
353 | 387 | ||
354 | if (first) { | 388 | if (first) { |
355 | if (!IS_SYMBOL(current->head) && !IS_LAMBDA(current->head)) { | 389 | if (!IS_SYMBOL(current->head) && |
390 | !IS_LAMBDA(current->head) && | ||
391 | !IS_BUILTIN(current->head)) { | ||
356 | error_push(errors, (Error){ | 392 | error_push(errors, (Error){ |
357 | .type = ERR_TYPE_PARSER, | 393 | .type = ERR_TYPE_PARSER, |
358 | .value = ERR_NOT_CALLABLE, | 394 | .value = ERR_NOT_CALLABLE, |
@@ -613,20 +649,8 @@ parse(Token *tokens, Errors *errors) { | |||
613 | array_push(roots, root); | 649 | array_push(roots, root); |
614 | } | 650 | } |
615 | 651 | ||
616 | // Prepare global environment of builtin functions. | 652 | // Prepare global environment. |
617 | Environment *global_env = env_alloc(NULL); | 653 | Environment *env = env_alloc(NULL); |
618 | Environment *env = env_alloc(global_env); | ||
619 | size_t n_builtins = sizeof(builtins) / sizeof(char*); | ||
620 | for (size_t i = 0; i < n_builtins; i++) { | ||
621 | // Prepare builtin symbol. | ||
622 | char *str = builtins[i]; | ||
623 | size_t str_n = strlen(str); | ||
624 | Object *symbol = object_alloc((Token){0}, OBJ_TYPE_SYMBOL); | ||
625 | symbol->text = (StringView){str, str_n}; | ||
626 | |||
627 | // Insert in global table. | ||
628 | insert_local(global_env, symbol, symbol); | ||
629 | } | ||
630 | 654 | ||
631 | // Perform semantic analysis: | 655 | // Perform semantic analysis: |
632 | // 1. Populate symbol tables and ensure symbols are in scope when used. | 656 | // 1. Populate symbol tables and ensure symbols are in scope when used. |
@@ -807,6 +831,9 @@ object_display(Object *obj) { | |||
807 | object_display(obj->var_expr); | 831 | object_display(obj->var_expr); |
808 | printf(" }"); | 832 | printf(" }"); |
809 | } break; | 833 | } break; |
834 | case OBJ_TYPE_BUILTIN: { | ||
835 | printf("%s", builtin_names[obj->builtin]); | ||
836 | } break; | ||
810 | } | 837 | } |
811 | return; | 838 | return; |
812 | } | 839 | } |
@@ -828,6 +855,9 @@ object_equal(Object *a, Object *b) { | |||
828 | case OBJ_TYPE_STRING: { | 855 | case OBJ_TYPE_STRING: { |
829 | return sv_equal(&a->text, &b->text); | 856 | return sv_equal(&a->text, &b->text); |
830 | } break; | 857 | } break; |
858 | case OBJ_TYPE_BUILTIN: { | ||
859 | return a->builtin = b->builtin; | ||
860 | } break; | ||
831 | default: break; | 861 | default: break; |
832 | } | 862 | } |
833 | return false; | 863 | return false; |