diff options
-rw-r--r-- | src/compiler.h | 39 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/parser.c | 5 |
3 files changed, 39 insertions, 7 deletions
diff --git a/src/compiler.h b/src/compiler.h index fe36ecf..023a039 100644 --- a/src/compiler.h +++ b/src/compiler.h | |||
@@ -23,6 +23,7 @@ do { \ | |||
23 | array_insert(current_context, buf, n_chars); \ | 23 | array_insert(current_context, buf, n_chars); \ |
24 | } while(false); | 24 | } while(false); |
25 | 25 | ||
26 | static Environment *current_env = NULL; | ||
26 | 27 | ||
27 | // TODO: Separate c/h files | 28 | // TODO: Separate c/h files |
28 | // TODO: Create a "driver.c" file with the (display) function for external | 29 | // TODO: Create a "driver.c" file with the (display) function for external |
@@ -51,7 +52,7 @@ do { \ | |||
51 | void compile_object(Object *obj); | 52 | void compile_object(Object *obj); |
52 | void compile_fixnum(Object *obj); | 53 | void compile_fixnum(Object *obj); |
53 | void compile_proc_call(Object *obj); | 54 | void compile_proc_call(Object *obj); |
54 | void compile(Root *roots); | 55 | void compile(Program program); |
55 | 56 | ||
56 | char * | 57 | char * |
57 | generate_label(char *prefix) { | 58 | generate_label(char *prefix) { |
@@ -506,6 +507,25 @@ compile_lambda(Object *obj) { | |||
506 | } | 507 | } |
507 | 508 | ||
508 | void | 509 | void |
510 | compile_def(Object *obj) { | ||
511 | context_printf(" ;; --> compile_def\n"); | ||
512 | compile_object(obj->var_expr); | ||
513 | ssize_t idx = find_local_index(current_env->locals, obj->var_name); | ||
514 | context_printf(" pop rax\n"); | ||
515 | context_printf(" mov [rbp + %ld], rax\n", 8 * (idx + 1)); | ||
516 | context_printf(" ;; <-- compile_def\n"); | ||
517 | } | ||
518 | |||
519 | void | ||
520 | compile_symbol(Object *obj) { | ||
521 | context_printf(" ;; --> compile_symbol\n"); | ||
522 | ssize_t idx = find_local_index(current_env->locals, obj); | ||
523 | context_printf(" mov rax, [rbp + %ld]\n", 8 * (idx + 1)); | ||
524 | context_printf(" push rax\n"); | ||
525 | context_printf(" ;; <-- compile_symbol\n"); | ||
526 | } | ||
527 | |||
528 | void | ||
509 | compile_object(Object *obj) { | 529 | compile_object(Object *obj) { |
510 | switch (obj->type) { | 530 | switch (obj->type) { |
511 | case OBJ_TYPE_NIL: { compile_nil(); } break; | 531 | case OBJ_TYPE_NIL: { compile_nil(); } break; |
@@ -516,6 +536,8 @@ compile_object(Object *obj) { | |||
516 | case OBJ_TYPE_STRING: { compile_string(obj); } break; | 536 | case OBJ_TYPE_STRING: { compile_string(obj); } break; |
517 | case OBJ_TYPE_IF: { compile_if(obj); } break; | 537 | case OBJ_TYPE_IF: { compile_if(obj); } break; |
518 | case OBJ_TYPE_LAMBDA: { compile_lambda(obj); } break; | 538 | case OBJ_TYPE_LAMBDA: { compile_lambda(obj); } break; |
539 | case OBJ_TYPE_DEF: { compile_def(obj); } break; | ||
540 | case OBJ_TYPE_SYMBOL: { compile_symbol(obj); } break; | ||
519 | default: break; | 541 | default: break; |
520 | } | 542 | } |
521 | } | 543 | } |
@@ -555,16 +577,17 @@ emit_data_section(void) { | |||
555 | } | 577 | } |
556 | 578 | ||
557 | void | 579 | void |
558 | compile(Root *roots) { | 580 | compile(Program program) { |
559 | // Prepare compilation variables. | 581 | // Prepare compilation variables. |
560 | array_init(constants, 0); | 582 | array_init(constants, 0); |
561 | array_init(labels, 0); | 583 | array_init(labels, 0); |
562 | array_init(procedures, 0); | 584 | array_init(procedures, 0); |
563 | array_init(current_context, 0); | 585 | array_init(current_context, 0); |
586 | current_env = program.env; | ||
564 | 587 | ||
565 | // Compile program. | 588 | // Compile program. |
566 | for (size_t i = 0; i < array_size(roots); i++) { | 589 | for (size_t i = 0; i < array_size(program.roots); i++) { |
567 | Object *root = roots[i]; | 590 | Object *root = program.roots[i]; |
568 | compile_object(root); | 591 | compile_object(root); |
569 | } | 592 | } |
570 | 593 | ||
@@ -604,7 +627,15 @@ compile(Root *roots) { | |||
604 | printf("alignb 8\n"); | 627 | printf("alignb 8\n"); |
605 | printf("global _start\n"); | 628 | printf("global _start\n"); |
606 | printf("_start:\n"); | 629 | printf("_start:\n"); |
630 | |||
631 | // Initialize heap pointer. | ||
607 | printf(" mov r15, bdl_heap\n"); | 632 | printf(" mov r15, bdl_heap\n"); |
633 | |||
634 | // Initialize main locals. | ||
635 | printf(" sub rsp, %zu\n", 8 * array_size(program.env->locals)); | ||
636 | printf(" mov rbp, rsp\n"); | ||
637 | |||
638 | // Keep the bottom stack value set as NIL_VAL for a default return value. | ||
608 | printf(" push NIL_VAL\n"); | 639 | printf(" push NIL_VAL\n"); |
609 | for (size_t i = 0; i < array_size(current_context); i++) { | 640 | for (size_t i = 0; i < array_size(current_context); i++) { |
610 | putchar(current_context[i]); | 641 | putchar(current_context[i]); |
@@ -45,7 +45,7 @@ process_source(const StringView *source, const char *file_name) { | |||
45 | // TODO: Optimization. | 45 | // TODO: Optimization. |
46 | 46 | ||
47 | // Compilation. | 47 | // Compilation. |
48 | compile(program.roots); | 48 | compile(program); |
49 | 49 | ||
50 | // Free resources. | 50 | // Free resources. |
51 | free_objects(); | 51 | free_objects(); |
diff --git a/src/parser.c b/src/parser.c index 100916b..2bf95d4 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -569,6 +569,7 @@ parse(Token *tokens, Errors *errors) { | |||
569 | 569 | ||
570 | // Prepare global environment of builtin functions. | 570 | // Prepare global environment of builtin functions. |
571 | Environment *global_env = env_alloc(NULL); | 571 | Environment *global_env = env_alloc(NULL); |
572 | Environment *env = env_alloc(global_env); | ||
572 | size_t n_builtins = sizeof(builtins) / sizeof(char*); | 573 | size_t n_builtins = sizeof(builtins) / sizeof(char*); |
573 | for (size_t i = 0; i < n_builtins; i++) { | 574 | for (size_t i = 0; i < n_builtins; i++) { |
574 | // Prepare builtin symbol. | 575 | // Prepare builtin symbol. |
@@ -600,7 +601,7 @@ parse(Token *tokens, Errors *errors) { | |||
600 | } | 601 | } |
601 | } | 602 | } |
602 | array_push(final_roots, root); | 603 | array_push(final_roots, root); |
603 | semantic_analysis(global_env, root, errors); | 604 | semantic_analysis(env, root, errors); |
604 | if (errors->n != 0) { | 605 | if (errors->n != 0) { |
605 | array_free(final_roots); | 606 | array_free(final_roots); |
606 | return (Program){0}; | 607 | return (Program){0}; |
@@ -614,7 +615,7 @@ parse(Token *tokens, Errors *errors) { | |||
614 | // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons). | 615 | // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons). |
615 | // We can't be sure when we have functions unless the return type is known. | 616 | // We can't be sure when we have functions unless the return type is known. |
616 | 617 | ||
617 | return (Program){roots, global_env}; | 618 | return (Program){roots, env}; |
618 | } | 619 | } |
619 | 620 | ||
620 | Environment * | 621 | Environment * |