aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-12-22 18:07:53 +0100
committerBad Diode <bd@badd10de.dev>2021-12-22 18:07:53 +0100
commit7ad32a2a907150e3ce71e89f126ca2a530550158 (patch)
tree2c5db028cd7e5b5244db3d43f7561d7a8327f07a /src/parser.c
parentfd65adf81f6c3e7e94755a83e22f7e0a19f8bd99 (diff)
downloadbdl-7ad32a2a907150e3ce71e89f126ca2a530550158.tar.gz
bdl-7ad32a2a907150e3ce71e89f126ca2a530550158.zip
Add builtin object type
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c62
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;
5static Root *roots = NULL; 5static Root *roots = NULL;
6static Environment **environments = NULL; 6static Environment **environments = NULL;
7 7
8static char *builtins [] = { 8static 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
17static 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
17Token 41Token
18peek_token(const Parser *parser) { 42peek_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
80Object * 104Object *
81parse_symbol(Token tok) { 105parse_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;