aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/src/parser.c b/src/parser.c
index e16fc4a..2429f68 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -3,7 +3,13 @@
3 3
4static Object **objects = NULL; 4static Object **objects = NULL;
5static Root *roots = NULL; 5static Root *roots = NULL;
6static Environment **environments = NULL;
6 7
8static char *builtins [] = {
9 "+", "-", "*", "/", "%",
10 "=", "<", ">", "<=", ">=",
11 "not", "and", "or",
12};
7 13
8uint64_t 14uint64_t
9symbol_hash(const HashTable *table, void *key) { 15symbol_hash(const HashTable *table, void *key) {
@@ -382,9 +388,16 @@ parse_tree(Parser *parser, Errors *errors) {
382 return NULL; 388 return NULL;
383} 389}
384 390
391void
392scope_check(Environment *env) {
393 // STUB
394}
395
385Root * 396Root *
386parse(Token *tokens, Errors *errors) { 397parse(Token *tokens, Errors *errors) {
387 array_init(roots, 0); 398 array_init(roots, 0);
399 array_init(objects, 0);
400 array_init(environments, 0);
388 Parser parser = { 401 Parser parser = {
389 .tokens = tokens, 402 .tokens = tokens,
390 .current = 0, 403 .current = 0,
@@ -400,27 +413,39 @@ parse(Token *tokens, Errors *errors) {
400 array_push(roots, root); 413 array_push(roots, root);
401 } 414 }
402 415
403 // TEST INSERTION/LOOKUP. 416 // Prepare global environment of builtin functions.
404 HashTable *table = ht_init(symbol_hash, object_equal); 417 Environment *global_env = env_alloc(NULL);
405 ht_insert(table, &roots[0][0], &roots[1][0]); 418 size_t n_builtins = sizeof(builtins) / sizeof(char*);
406 ht_insert(table, &roots[2][0], &roots[3][0]); 419 for (size_t i = 0; i < n_builtins; i++) {
407 Object *val = ht_lookup(table, &roots[2][0]); 420 // Prepare builtin symbol.
408 object_display(val); 421 char *str = builtins[i];
409 val = ht_lookup(table, &roots[0][0]); 422 size_t str_n = strlen(str);
410 object_display(val); 423 Object *symbol = object_alloc((Token){0}, OBJ_TYPE_SYMBOL);
411 ht_free(table); 424 array_init(symbol->text, str_n);
425 array_insert(symbol->text, str, str_n);
426
427 // Insert in global table.
428 ht_insert(global_env->table, symbol, symbol);
429 }
412 430
413 // Perform semantic analysis. 431 // Perform semantic analysis.
432 scope_check(global_env);
414 // TODO: Check that symbols are defined before usage. 433 // TODO: Check that symbols are defined before usage.
415 // TODO: Remove unnecessary statements. 434 // TODO: Remove unnecessary statements.
416 return roots; 435 return roots;
417} 436}
418 437
438Environment *
439env_alloc(Environment *parent) {
440 Environment *env = malloc(sizeof(Environment));
441 env->table = ht_init(symbol_hash, (EqFunc*)object_equal);
442 env->parent = parent;
443 array_push(environments, env);
444 return env;
445}
446
419Object * 447Object *
420object_alloc(Token tok, ObjectType type) { 448object_alloc(Token tok, ObjectType type) {
421 if (objects == NULL) {
422 array_init(objects, 0);
423 }
424 Object *node = malloc(sizeof(Object)); 449 Object *node = malloc(sizeof(Object));
425 node->line = tok.line; 450 node->line = tok.line;
426 node->col = tok.col; 451 node->col = tok.col;
@@ -452,6 +477,14 @@ free_objects(void) {
452 } 477 }
453 array_free(objects); 478 array_free(objects);
454 } 479 }
480 if (environments != NULL) {
481 for (size_t i = 0; i < array_size(environments); i++) {
482 Environment *env = environments[i];
483 ht_free(env->table);
484 free(env);
485 }
486 array_free(environments);
487 }
455 array_free(roots); 488 array_free(roots);
456} 489}
457 490