| @@ -1,189 +1,188 @@ | |||
| (import "cxr.slime") | |||
| ;; alist: | |||
| ;; [ |/] | |||
| ;; | | |||
| ;; V | |||
| ;; [ | ]------------->[ | ]-------------> ... | |||
| ;; | | | |||
| ;; V V | |||
| ;; [ | ]->value1 [ | ]->value2 | |||
| ;; | | | |||
| ;; V V | |||
| ;; key1 key2 | |||
| ;; | |||
| ;; '(((key1 . value1) (key2 . value2))) | |||
| ;; plist: | |||
| ;; [ |/] | |||
| ;; | | |||
| ;; V | |||
| ;; [ | ]------------->[ | ]-------------> ... | |||
| ;; | | | |||
| ;; V V | |||
| ;; :key1 value1 | |||
| ;; | |||
| ;; '((:key1 value1 :key2 value2)) | |||
| (define key-not-found-index -1) | |||
| (define (make-alist) | |||
| (set-type! | |||
| '(()) | |||
| :alist)) | |||
| (define (make-plist) | |||
| (set-type! | |||
| '(()) | |||
| :plist)) | |||
| (define (pprint-alist alist) | |||
| (let ((associations (first alist))) | |||
| (define (pprint-intern associations) | |||
| (when associations | |||
| (print " " | |||
| (caar associations) "->" | |||
| (cdar associations)) | |||
| (pprint-intern (rest associations)))) | |||
| (print "(") | |||
| (when associations | |||
| (print "\n") | |||
| (pprint-intern associations)) | |||
| (print ")\n"))) | |||
| (define (pprint-plist plist) | |||
| (let ((props (first plist))) | |||
| (define (pprint-intern props) | |||
| (when props | |||
| (print " " | |||
| (car props) "->" | |||
| (cadr props)) | |||
| (pprint-intern (cddr props)))) | |||
| (print "(") | |||
| (when props | |||
| (print "\n") | |||
| (pprint-intern props)) | |||
| (print ")\n"))) | |||
| (define (alist-get alist key) | |||
| (let ((associations (first alist))) | |||
| (define (alist-get-intern associations key) | |||
| (cond ((null? associations) | |||
| (error "key was not found in alist")) | |||
| ((= (caar associations) key) | |||
| (cdar associations)) | |||
| (else (alist-get-intern (rest associations) key)))) | |||
| (alist-get-intern associations key))) | |||
| (define (alist-find alist key) | |||
| (let ((associations (first alist))) | |||
| (define (alist-find-intern associations key current-index) | |||
| (cond ((null? associations) key-not-found-index) | |||
| ((= (caar associations) key) current-index) | |||
| (else (alist-find-intern (rest associations) | |||
| key | |||
| (+ 1 current-index))))) | |||
| (alist-find-intern associations key 0))) | |||
| (define (alist-key-exists? alist key) | |||
| (not (= (alist-find alist key) | |||
| key-not-found-index))) | |||
| (define (alist-remove! alist key) | |||
| (let ((index (alist-find alist key))) | |||
| (define (alist-remove!-internal asociations index) | |||
| ;; reminder: we only get called if we are not replacing the | |||
| ;; first element in the alist | |||
| ;; reminder2: we know that the key exists | |||
| (if (= index 1) | |||
| ;; we want to remove the next one, so we set our | |||
| ;; cdr to the next next one | |||
| (mutate associations (pair (first associations) | |||
| (rest (rest associations)))) | |||
| ;; else cdr-recurse | |||
| (alist-remove!-internal (rest asociations) (- index 1)))) | |||
| (cond ((= index key-not-found-index) (error "key to remove was not found")) | |||
| ((= index 0) (mutate alist (pair (cdar alist) ()))) | |||
| (else (alist-remove!-internal alist index)))) | |||
| alist) | |||
| (define (alist-set! alist key value) | |||
| (mutate alist (set-type! (pair (pair (pair key value) | |||
| (car alist)) | |||
| ()) | |||
| :alist))) | |||
| (define (alist-set-overwrite! alist key value) | |||
| (let ((associations (first alist))) | |||
| (define (alist-set-overwrite-intern associations key value) | |||
| (cond ((= (caar associations) key) | |||
| (mutate (car associations) (pair key value))) | |||
| ((null? associations) (alist-set! alist key value)) | |||
| (else (alist-set-overwrite-intern | |||
| (rest associations) key value)))) | |||
| (alist-set-overwrite-intern associations key value)) | |||
| alist) | |||
| (define (plist-get plist prop) | |||
| (let ((props (first plist))) | |||
| (define (plist-get-intern props prop) | |||
| (cond ((null? props) | |||
| (error "property was not found in plist")) | |||
| ((= (car props) prop) | |||
| (cadr props)) | |||
| (else (plist-get-intern (cddr props) prop)))) | |||
| (plist-get-intern props prop))) | |||
| (define (plist-set! plist prop value) | |||
| (mutate plist (set-type! (pair (pair prop (pair value (first plist))) ()) | |||
| :plist))) | |||
| (define (plist-set-overwrite! plist prop value) | |||
| (let ((props (first plist))) | |||
| (define (plist-set-overwrite-intern props prop value) | |||
| (cond ((= (car props) prop) | |||
| (mutate (cdr props) (pair value (cddr props)))) | |||
| ((null? props) (plist-set! plist prop value)) | |||
| (else (plist-set-overwrite-intern | |||
| (cddr props) prop value)))) | |||
| (plist-set-overwrite-intern props prop value)) | |||
| plist) | |||
| (define (plist-find plist prop) | |||
| (let ((props (first plist))) | |||
| (define (plist-find-intern props prop current-index) | |||
| (cond ((null? props) key-not-found-index) | |||
| ((= (car props) prop) current-index) | |||
| (else (plist-find-intern (cddr props) prop | |||
| (+ 1 current-index))))) | |||
| (plist-find-intern props prop 0))) | |||
| (define (plist-prop-exists? plist prop) | |||
| (not (= (plist-find plist prop) | |||
| key-not-found-index))) | |||
| (define (plist-remove! plist prop) | |||
| (let ((index (plist-find plist prop))) | |||
| (define (plist-remove!-internal props index) | |||
| ;; reminder: we only get called if we are not replacing the | |||
| ;; first element in the alist | |||
| ;; reminder2: we know that the key exists | |||
| (if (= index 1) | |||
| ;; we want to remove the next one, so we set our | |||
| ;; cdr to the next next one | |||
| (mutate (cdar props) (pair (cadar props) ;; xD nice meme dude!!! | |||
| (cdr (cdr (cdr (cdar props)))))) | |||
| ;; else cdr-recurse | |||
| (plist-remove!-internal (cddr props) (- index 1)))) | |||
| (cond ((= index key-not-found-index) (error "prop to remove was not found")) | |||
| ((= index 0) (mutate plist (pair (cddar plist) ()))) | |||
| (else (plist-remove!-internal plist index)))) | |||
| plist) | |||
| (define-module ds | |||
| :exports | |||
| (alist::make alist::print alist::get alist::find alist::key-exists? alist::remove! alist::set! alist::set-overwrite! | |||
| plist::make plist::print plist::get plist::find plist::prop-exists? plist::remove! plist::set! plist::set-overwrite!) | |||
| (define key-not-found-index -1) | |||
| (define-module alist | |||
| :imports ("cxr.slime") | |||
| :exports (make print get find key-exists? remove! set! set-overwrite!) | |||
| (define (make) | |||
| (set-type! | |||
| '(()) | |||
| :alist)) | |||
| (define (print alist) | |||
| (let ((associations (first alist))) | |||
| (define (pprint-intern associations) | |||
| (when associations | |||
| (print " " | |||
| (caar associations) "->" | |||
| (cdar associations)) | |||
| (pprint-intern (rest associations)))) | |||
| (print "(") | |||
| (when associations | |||
| (print "\n") | |||
| (pprint-intern associations)) | |||
| (print ")\n"))) | |||
| (define (get alist key) | |||
| (let ((associations (first alist))) | |||
| (define (alist-get-intern associations key) | |||
| (cond ((null? associations) | |||
| (error "key was not found in alist")) | |||
| ((= (caar associations) key) | |||
| (cdar associations)) | |||
| (else (alist-get-intern (rest associations) key)))) | |||
| (alist-get-intern associations key))) | |||
| (define (find alist key) | |||
| (let ((associations (first alist))) | |||
| (define (alist-find-intern associations key current-index) | |||
| (cond ((null? associations) key-not-found-index) | |||
| ((= (caar associations) key) current-index) | |||
| (else (alist-find-intern (rest associations) | |||
| key | |||
| (+ 1 current-index))))) | |||
| (alist-find-intern associations key 0))) | |||
| (define (key-exists? alist key) | |||
| (not (= (alist-find alist key) | |||
| key-not-found-index))) | |||
| (define (remove! alist key) | |||
| (let ((index (alist-find alist key))) | |||
| (define (alist-remove!-internal asociations index) | |||
| ;; reminder: we only get called if we are not replacing the | |||
| ;; first element in the alist | |||
| ;; reminder2: we know that the key exists | |||
| (if (= index 1) | |||
| ;; we want to remove the next one, so we set our | |||
| ;; cdr to the next next one | |||
| (mutate associations (pair (first associations) | |||
| (rest (rest associations)))) | |||
| ;; else cdr-recurse | |||
| (alist-remove!-internal (rest asociations) (- index 1)))) | |||
| (cond ((= index key-not-found-index) (error "key to remove was not found")) | |||
| ((= index 0) (mutate alist (pair (cdar alist) ()))) | |||
| (else (alist-remove!-internal alist index)))) | |||
| alist) | |||
| (define (set! alist key value) | |||
| (mutate alist (set-type! (pair (pair (pair key value) | |||
| (car alist)) | |||
| ()) | |||
| :alist))) | |||
| (define (set-overwrite! alist key value) | |||
| (let ((associations (first alist))) | |||
| (define (alist-set-overwrite-intern associations key value) | |||
| (cond ((= (caar associations) key) | |||
| (mutate (car associations) (pair key value))) | |||
| ((null? associations) (alist-set! alist key value)) | |||
| (else (alist-set-overwrite-intern | |||
| (rest associations) key value)))) | |||
| (alist-set-overwrite-intern associations key value)) | |||
| alist) | |||
| ) | |||
| (define-module plist | |||
| :imports ("cxr.slime") | |||
| :exports (make print get find prop-exists? remove! set! set-overwrite!) | |||
| ;; plist: | |||
| ;; [ |/] | |||
| ;; | | |||
| ;; V | |||
| ;; [ | ]------------->[ | ]-------------> ... | |||
| ;; | | | |||
| ;; V V | |||
| ;; :key1 value1 | |||
| ;; | |||
| ;; '((:key1 value1 :key2 value2)) | |||
| (define (make) | |||
| (set-type! | |||
| '(()) | |||
| :plist)) | |||
| (define (print plist) | |||
| (let ((props (first plist))) | |||
| (define (pprint-intern props) | |||
| (when props | |||
| (print " " | |||
| (car props) "->" | |||
| (cadr props)) | |||
| (pprint-intern (cddr props)))) | |||
| (print "(") | |||
| (when props | |||
| (print "\n") | |||
| (pprint-intern props)) | |||
| (print ")\n"))) | |||
| (define (get plist prop) | |||
| (let ((props (first plist))) | |||
| (define (plist-get-intern props prop) | |||
| (cond ((null? props) | |||
| (error "property was not found in plist")) | |||
| ((= (car props) prop) | |||
| (cadr props)) | |||
| (else (plist-get-intern (cddr props) prop)))) | |||
| (plist-get-intern props prop))) | |||
| (define (set plist prop value) | |||
| (mutate plist (set-type! (pair (pair prop (pair value (first plist))) ()) | |||
| :plist))) | |||
| (define (set-overwrite! plist prop value) | |||
| (let ((props (first plist))) | |||
| (define (plist-set-overwrite-intern props prop value) | |||
| (cond ((= (car props) prop) | |||
| (mutate (cdr props) (pair value (cddr props)))) | |||
| ((null? props) (plist-set! plist prop value)) | |||
| (else (plist-set-overwrite-intern | |||
| (cddr props) prop value)))) | |||
| (plist-set-overwrite-intern props prop value)) | |||
| plist) | |||
| (define (find plist prop) | |||
| (let ((props (first plist))) | |||
| (define (plist-find-intern props prop current-index) | |||
| (cond ((null? props) key-not-found-index) | |||
| ((= (car props) prop) current-index) | |||
| (else (plist-find-intern (cddr props) prop | |||
| (+ 1 current-index))))) | |||
| (plist-find-intern props prop 0))) | |||
| (define (prop-exists? plist prop) | |||
| (not (= (plist-find plist prop) | |||
| key-not-found-index))) | |||
| (define (remove! plist prop) | |||
| (let ((index (plist-find plist prop))) | |||
| (define (plist-remove!-internal props index) | |||
| ;; reminder: we only get called if we are not replacing the | |||
| ;; first element in the alist | |||
| ;; reminder2: we know that the key exists | |||
| (if (= index 1) | |||
| ;; we want to remove the next one, so we set our | |||
| ;; cdr to the next next one | |||
| (mutate (cdar props) (pair (cadar props) ;; xD nice meme dude!!! | |||
| (cdr (cdr (cdr (cdar props)))))) | |||
| ;; else cdr-recurse | |||
| (plist-remove!-internal (cddr props) (- index 1)))) | |||
| (cond ((= index key-not-found-index) (error "prop to remove was not found")) | |||
| ((= index 0) (mutate plist (pair (cddar plist) ()))) | |||
| (else (plist-remove!-internal plist index)))) | |||
| plist) | |||
| ) | |||
| ) | |||
| @@ -42,7 +42,6 @@ | |||
| (lambda (t) | |||
| (point-lerp (lerper1 t) | |||
| (lerper2 t) t)))) | |||
| ) | |||
| @@ -1,8 +1,7 @@ | |||
| (define-module set | |||
| :imports ("cxr.slime") | |||
| :exports (make find contains? insert!) | |||
| (import "cxr.slime") | |||
| (define key-not-found-index -1) | |||
| (define (make . vals) | |||
| @@ -4,7 +4,7 @@ pushd $SCRIPTPATH > /dev/null | |||
| # _DEBUG | |||
| # time g++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| time clang++ -D_DEBUG -D_PROFILING -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| time clang++ -D_DEBUG -D_PROFILING src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| echo "" | |||
| pushd ./bin > /dev/null | |||
| @@ -301,7 +301,6 @@ proc load_built_ins_into_environment() -> void { | |||
| define((* . args), "TODO") | |||
| { | |||
| fetch(args); | |||
| if (args == Memory::nil) { | |||
| return Memory::create_lisp_object_number(1); | |||
| } | |||
| @@ -951,7 +950,7 @@ proc load_built_ins_into_environment() -> void { | |||
| define((generate-docs file_name), "TODO") { | |||
| fetch(file_name); | |||
| try assert_type(file_name, Lisp_Object_Type::String); | |||
| try generate_docs(file_name->value.string); | |||
| // try generate_docs(file_name->value.string); | |||
| return Memory::t; | |||
| }; | |||
| define((print (:sep " ") (:end "\n") . things), "TODO") { | |||
| @@ -1,157 +1,157 @@ | |||
| proc generate_docs(String* path) -> void { | |||
| FILE *f = fopen(Memory::get_c_str(path), "w"); | |||
| if (!f) { | |||
| create_generic_error("The file for writing the documentation (%s) " | |||
| "could not be opened for writing.", Memory::get_c_str(path)); | |||
| return; | |||
| } | |||
| defer { | |||
| fclose(f); | |||
| }; | |||
| // proc generate_docs(String* path) -> void { | |||
| // FILE *f = fopen(Memory::get_c_str(path), "w"); | |||
| // if (!f) { | |||
| // create_generic_error("The file for writing the documentation (%s) " | |||
| // "could not be opened for writing.", Memory::get_c_str(path)); | |||
| // return; | |||
| // } | |||
| // defer { | |||
| // fclose(f); | |||
| // }; | |||
| Environment_Array_List visited = create_Environment_array_list(); | |||
| // Environment_Array_List visited = create_Environment_array_list(); | |||
| // recursive inner funciton | |||
| std::function<void(Environment*, char* prefix)> print_this_env; | |||
| print_this_env = [&](Environment* env, char* prefix) -> void { | |||
| bool we_already_printed = false; | |||
| // TODO(Felix): Make a generic array_list_contains function | |||
| for_array_list(visited) { | |||
| if (it == env) { | |||
| we_already_printed = true; | |||
| break; | |||
| } | |||
| } | |||
| if (!we_already_printed) { | |||
| printf("Working ion env::::"); | |||
| print_environment(env); | |||
| printf("\n--------------------------------\n"); | |||
| append_to_array_list(&visited, env); | |||
| // // recursive inner funciton | |||
| // std::function<void(Environment*, char* prefix)> print_this_env; | |||
| // print_this_env = [&](Environment* env, char* prefix) -> void { | |||
| // bool we_already_printed = false; | |||
| // // TODO(Felix): Make a generic array_list_contains function | |||
| // for_array_list(visited) { | |||
| // if (it == env) { | |||
| // we_already_printed = true; | |||
| // break; | |||
| // } | |||
| // } | |||
| // if (!we_already_printed) { | |||
| // printf("Working ion env::::"); | |||
| // print_environment(env); | |||
| // printf("\n--------------------------------\n"); | |||
| // append_to_array_list(&visited, env); | |||
| push_environment(env); | |||
| defer { | |||
| pop_environment(); | |||
| }; | |||
| // push_environment(env); | |||
| // defer { | |||
| // pop_environment(); | |||
| // }; | |||
| for (int i = 0; i < env->next_index; ++i) { | |||
| fprintf(f, "\\hrule\n* =%s%s= \n" | |||
| // " :PROPERTIES:\n" | |||
| // " :UNNUMBERED: t\n" | |||
| // " :END:" | |||
| ,prefix, env->keys[i]); | |||
| /* | |||
| * sourcecodeLocation | |||
| */ | |||
| if (env->values[i]->sourceCodeLocation) { | |||
| try_void fprintf(f, "\n - defined in :: =%s:%d:%d=", | |||
| Memory::get_c_str(env->values[i]->sourceCodeLocation->file), | |||
| env->values[i]->sourceCodeLocation->line, | |||
| env->values[i]->sourceCodeLocation->column); | |||
| } | |||
| /* | |||
| * type | |||
| */ | |||
| Lisp_Object_Type type = Memory::get_type(env->values[i]); | |||
| Lisp_Object* LOtype; | |||
| try_void LOtype = eval_expr(Memory::create_list( | |||
| Memory::get_or_create_lisp_object_symbol("type"), | |||
| env->values[i])); | |||
| // for (int i = 0; i < env->next_index; ++i) { | |||
| // fprintf(f, "\\hrule\n* =%s%s= \n" | |||
| // // " :PROPERTIES:\n" | |||
| // // " :UNNUMBERED: t\n" | |||
| // // " :END:" | |||
| // ,prefix, env->keys[i]); | |||
| // /* | |||
| // * sourcecodeLocation | |||
| // */ | |||
| // if (env->values[i]->sourceCodeLocation) { | |||
| // try_void fprintf(f, "\n - defined in :: =%s:%d:%d=", | |||
| // Memory::get_c_str(env->values[i]->sourceCodeLocation->file), | |||
| // env->values[i]->sourceCodeLocation->line, | |||
| // env->values[i]->sourceCodeLocation->column); | |||
| // } | |||
| // /* | |||
| // * type | |||
| // */ | |||
| // Lisp_Object_Type type = Memory::get_type(env->values[i]); | |||
| // Lisp_Object* LOtype; | |||
| // try_void LOtype = eval_expr(Memory::create_list( | |||
| // Memory::get_or_create_lisp_object_symbol("type"), | |||
| // env->values[i])); | |||
| fprintf(f, "\n - type :: ="); | |||
| print(LOtype, true, f); | |||
| fprintf(f, "="); | |||
| // fprintf(f, "\n - type :: ="); | |||
| // print(LOtype, true, f); | |||
| // fprintf(f, "="); | |||
| /* | |||
| * if printable value -> print it | |||
| */ | |||
| switch (type) { | |||
| case(Lisp_Object_Type::Nil): | |||
| case(Lisp_Object_Type::T): | |||
| case(Lisp_Object_Type::Number): | |||
| case(Lisp_Object_Type::String): | |||
| case(Lisp_Object_Type::Pair): | |||
| case(Lisp_Object_Type::Symbol): | |||
| case(Lisp_Object_Type::Keyword): { | |||
| fprintf(f, "\n - value :: ="); | |||
| print(env->values[i], true, f); | |||
| fprintf(f, "="); | |||
| } break; | |||
| default: break; | |||
| } | |||
| /* | |||
| * if function then print arguments | |||
| */ | |||
| if (type == Lisp_Object_Type::Function) { | |||
| Lisp_Object* fun = env->values[i]; | |||
| bool printed_at_least_some_args = false; | |||
| fprintf(f, "\n - arguments :: "); | |||
| if (fun->value.function.args.positional.symbols.next_index != 0) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - postitional :: "); | |||
| try_void fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier)); | |||
| for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) { | |||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier)); | |||
| } | |||
| } | |||
| if (fun->value.function.args.keyword.values.next_index != 0) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - keyword :: "); | |||
| fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier)); | |||
| if (fun->value.function.args.keyword.values.data[0]) { | |||
| fprintf(f, " =("); | |||
| print(fun->value.function.args.keyword.values.data[0], true, f); | |||
| fprintf(f, ")="); | |||
| } | |||
| for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) { | |||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier)); | |||
| if (fun->value.function.args.keyword.values.data[i]) { | |||
| fprintf(f, " =("); | |||
| print(fun->value.function.args.keyword.values.data[i], true, f); | |||
| fprintf(f, ")="); | |||
| } | |||
| } | |||
| } | |||
| if (fun->value.function.args.rest) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.args.rest->value.symbol.identifier)); | |||
| } | |||
| // if no args at all | |||
| if (fun->value.function.args.positional.symbols.next_index == 0 && | |||
| fun->value.function.args.keyword.values.next_index == 0 && | |||
| !fun->value.function.args.rest) | |||
| { | |||
| fprintf(f, "none."); | |||
| } | |||
| } | |||
| fprintf(f, "\n - docu :: "); | |||
| if (env->values[i]->docstring) | |||
| fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n", | |||
| Memory::get_c_str(env->values[i]->docstring)); | |||
| else | |||
| fprintf(f, "none\n"); | |||
| // /* | |||
| // * if printable value -> print it | |||
| // */ | |||
| // switch (type) { | |||
| // case(Lisp_Object_Type::Nil): | |||
| // case(Lisp_Object_Type::T): | |||
| // case(Lisp_Object_Type::Number): | |||
| // case(Lisp_Object_Type::String): | |||
| // case(Lisp_Object_Type::Pair): | |||
| // case(Lisp_Object_Type::Symbol): | |||
| // case(Lisp_Object_Type::Keyword): { | |||
| // fprintf(f, "\n - value :: ="); | |||
| // print(env->values[i], true, f); | |||
| // fprintf(f, "="); | |||
| // } break; | |||
| // default: break; | |||
| // } | |||
| // /* | |||
| // * if function then print arguments | |||
| // */ | |||
| // if (type == Lisp_Object_Type::Function) { | |||
| // Lisp_Object* fun = env->values[i]; | |||
| // bool printed_at_least_some_args = false; | |||
| // fprintf(f, "\n - arguments :: "); | |||
| // if (fun->value.function.args.positional.symbols.next_index != 0) { | |||
| // if (!printed_at_least_some_args) | |||
| // fprintf(f, ":"); | |||
| // fprintf(f, "\n - postitional :: "); | |||
| // try_void fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier)); | |||
| // for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) { | |||
| // fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier)); | |||
| // } | |||
| // } | |||
| // if (fun->value.function.args.keyword.values.next_index != 0) { | |||
| // if (!printed_at_least_some_args) | |||
| // fprintf(f, ":"); | |||
| // fprintf(f, "\n - keyword :: "); | |||
| // fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier)); | |||
| // if (fun->value.function.args.keyword.values.data[0]) { | |||
| // fprintf(f, " =("); | |||
| // print(fun->value.function.args.keyword.values.data[0], true, f); | |||
| // fprintf(f, ")="); | |||
| // } | |||
| // for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) { | |||
| // fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier)); | |||
| // if (fun->value.function.args.keyword.values.data[i]) { | |||
| // fprintf(f, " =("); | |||
| // print(fun->value.function.args.keyword.values.data[i], true, f); | |||
| // fprintf(f, ")="); | |||
| // } | |||
| // } | |||
| // } | |||
| // if (fun->value.function.args.rest) { | |||
| // if (!printed_at_least_some_args) | |||
| // fprintf(f, ":"); | |||
| // fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.args.rest->value.symbol.identifier)); | |||
| // } | |||
| // // if no args at all | |||
| // if (fun->value.function.args.positional.symbols.next_index == 0 && | |||
| // fun->value.function.args.keyword.values.next_index == 0 && | |||
| // !fun->value.function.args.rest) | |||
| // { | |||
| // fprintf(f, "none."); | |||
| // } | |||
| // } | |||
| // fprintf(f, "\n - docu :: "); | |||
| // if (env->values[i]->docstring) | |||
| // fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n", | |||
| // Memory::get_c_str(env->values[i]->docstring)); | |||
| // else | |||
| // fprintf(f, "none\n"); | |||
| // if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function && | |||
| // env->values[i]->userType && | |||
| // (string_equal(env->values[i]->userType->value.symbol.identifier, "package") || | |||
| // string_equal(env->values[i]->userType->value.symbol.identifier, "constructor"))) | |||
| // { | |||
| // char new_prefix[200]; | |||
| // strcpy(new_prefix, prefix); | |||
| // strcat(new_prefix, env->keys[i]); | |||
| // strcat(new_prefix, " "); | |||
| // print_this_env(env->values[i]->value.function.parent_environment, new_prefix); | |||
| // } | |||
| } | |||
| } | |||
| // // if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function && | |||
| // // env->values[i]->userType && | |||
| // // (string_equal(env->values[i]->userType->value.symbol.identifier, "package") || | |||
| // // string_equal(env->values[i]->userType->value.symbol.identifier, "constructor"))) | |||
| // // { | |||
| // // char new_prefix[200]; | |||
| // // strcpy(new_prefix, prefix); | |||
| // // strcat(new_prefix, env->keys[i]); | |||
| // // strcat(new_prefix, " "); | |||
| // // print_this_env(env->values[i]->value.function.parent_environment, new_prefix); | |||
| // // } | |||
| // } | |||
| // } | |||
| for (int i = 0; i < env->parents.next_index; ++i) { | |||
| print_this_env(env->parents.data[i], prefix); | |||
| } | |||
| }; | |||
| // for (int i = 0; i < env->parents.next_index; ++i) { | |||
| // print_this_env(env->parents.data[i], prefix); | |||
| // } | |||
| // }; | |||
| print_this_env(get_current_environment(), (char*)""); | |||
| } | |||
| // print_this_env(get_current_environment(), (char*)""); | |||
| // } | |||
| @@ -1,27 +1,10 @@ | |||
| proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void { | |||
| // NOTE(Felix): right now we are simply adding the symol at the | |||
| // back of the list without checking if it already exists but are | |||
| // also searching for thesymbol from the back, so we will find the | |||
| // latest defined one first, but a bit messy. Later we should use | |||
| // a hashmap here. @refactor | |||
| Environment* env = get_current_environment(); | |||
| if (env->next_index == env->capacity) { | |||
| env->capacity *= 2; | |||
| env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*)); | |||
| env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*)); | |||
| } | |||
| env->keys [env->next_index] = Memory::get_c_str(symbol->value.symbol.identifier); | |||
| env->values[env->next_index] = value; | |||
| ++env->next_index; | |||
| hm_set(env->hm, Memory::get_c_str(symbol->value.symbol.identifier), value); | |||
| } | |||
| proc lookup_symbol_in_this_envt(String* identifier, Environment* env) -> Lisp_Object* { | |||
| for (int i = env->next_index - 1; i >= 0; --i) | |||
| if (string_equal(env->keys[i], Memory::get_c_str(identifier))) | |||
| return env->values[i]; | |||
| return nullptr; | |||
| inline proc lookup_symbol_in_this_envt(String* identifier, Environment* env) -> Lisp_Object* { | |||
| return (Lisp_Object*)hm_get_object(env->hm, Memory::get_c_str(identifier)); | |||
| } | |||
| proc environment_binds_symbol(String* identifier, Environment* env) -> bool { | |||
| @@ -112,19 +95,20 @@ proc print_environment_indent(Environment* env, int indent) -> void { | |||
| printf("[built-ins]-Environment (%lld)\n", (long long)env); | |||
| return; | |||
| } | |||
| for (int i = 0; i < env->next_index; ++i) { | |||
| print_indent(indent); | |||
| printf("-> %s :: ", env->keys[i]); | |||
| print(env->values[i]); | |||
| printf(" (%lld)", (long long)env->values[i]); | |||
| puts(""); | |||
| } | |||
| for (int i = 0; i < env->parents.next_index; ++i) { | |||
| print_indent(indent); | |||
| printf("parent (%lld)", (long long)env->parents.data[i]); | |||
| puts(":"); | |||
| print_environment_indent(env->parents.data[i], indent+4); | |||
| } | |||
| printf("TODO\n"); | |||
| // for (int i = 0; i < env->next_index; ++i) { | |||
| // print_indent(indent); | |||
| // printf("-> %s :: ", env->keys[i]); | |||
| // print(env->values[i]); | |||
| // printf(" (%lld)", (long long)env->values[i]); | |||
| // puts(""); | |||
| // } | |||
| // for (int i = 0; i < env->parents.next_index; ++i) { | |||
| // print_indent(indent); | |||
| // printf("parent (%lld)", (long long)env->parents.data[i]); | |||
| // puts(":"); | |||
| // print_environment_indent(env->parents.data[i], indent+4); | |||
| // } | |||
| } | |||
| proc print_environment(Environment* env) -> void { | |||
| @@ -1 +1 @@ | |||
| Subproject commit 2b00885ba250a2a186e7399f9df6d36db8608cf1 | |||
| Subproject commit b9de82c0d84384a7ab78e2cb7dd368612efa50f9 | |||
| @@ -68,10 +68,10 @@ namespace GC { | |||
| maybe_mark(it); | |||
| } | |||
| Lisp_Object* it = env->values[0]; | |||
| for (int i = 0; i < env->next_index; it = env->values[++i]) { | |||
| maybe_mark(it); | |||
| } | |||
| // Lisp_Object* it = env->values[0]; | |||
| // for (int i = 0; i < env->next_index; it = env->values[++i]) { | |||
| // maybe_mark(it); | |||
| // } | |||
| } | |||
| proc garbage_collect() -> void { | |||
| @@ -379,10 +379,7 @@ namespace Memory { | |||
| if (parent) | |||
| append_to_array_list(&env->parents, parent); | |||
| env->capacity = start_capacity; | |||
| env->next_index = 0; | |||
| env->keys = (char**)malloc(start_capacity * sizeof(char*)); | |||
| env->values = (Lisp_Object**)malloc(start_capacity * sizeof(Lisp_Object*)); | |||
| env->hm = create_hashmap(); | |||
| return env; | |||
| } | |||
| @@ -26,6 +26,7 @@ | |||
| #include "./ftb/macros.hpp" | |||
| #include "./ftb/profiler.hpp" | |||
| #include "./ftb/hashmap.hpp" | |||
| namespace Slime { | |||
| # include "./defines.cpp" | |||
| @@ -111,12 +111,13 @@ struct Arguments { | |||
| struct Environment { | |||
| Environment_Array_List parents; | |||
| int capacity; | |||
| int next_index; | |||
| StringHashMap* hm; | |||
| // int capacity; | |||
| // int next_index; | |||
| // TODO(Felix): Use a hashmap here. | |||
| char** keys; | |||
| Lisp_Object** values; | |||
| // // TODO(Felix): Use a hashmap here. | |||
| // char** keys; | |||
| // Lisp_Object** values; | |||
| }; | |||
| struct Function { | |||