| @@ -125,7 +125,7 @@ TODO | |||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =set!= | |||||
| * =vector-length= | |||||
| - defined in :: =src/./built_ins.cpp:449:0= | - defined in :: =src/./built_ins.cpp:449:0= | ||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| @@ -134,157 +134,154 @@ TODO | |||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =set-car!= | |||||
| * =vector-ref= | |||||
| - defined in :: =src/./built_ins.cpp:471:0= | |||||
| - defined in :: =src/./built_ins.cpp:457:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =set-cdr!= | |||||
| * =vector-set!= | |||||
| - defined in :: =src/./built_ins.cpp:482:0= | |||||
| - defined in :: =src/./built_ins.cpp:474:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =if= | |||||
| * =set!= | |||||
| - defined in :: =src/./built_ins.cpp:493:0= | |||||
| - defined in :: =src/./built_ins.cpp:494:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =quote= | |||||
| * =set-car!= | |||||
| - defined in :: =src/./built_ins.cpp:513:0= | |||||
| - defined in :: =src/./built_ins.cpp:516:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =quasiquote= | |||||
| * =set-cdr!= | |||||
| - defined in :: =src/./built_ins.cpp:518:0= | |||||
| - defined in :: =src/./built_ins.cpp:527:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =and= | |||||
| * =if= | |||||
| - defined in :: =src/./built_ins.cpp:614:0= | |||||
| - defined in :: =src/./built_ins.cpp:538:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =or= | |||||
| * =quote= | |||||
| - defined in :: =src/./built_ins.cpp:625:0= | |||||
| - defined in :: =src/./built_ins.cpp:558:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =not= | |||||
| * =quasiquote= | |||||
| - defined in :: =src/./built_ins.cpp:636:0= | |||||
| - defined in :: =src/./built_ins.cpp:563:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =while= | |||||
| * =and= | |||||
| - defined in :: =src/./built_ins.cpp:646:0= | |||||
| - defined in :: =src/./built_ins.cpp:659:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =lambda= | |||||
| * =or= | |||||
| - defined in :: =src/./built_ins.cpp:724:0= | |||||
| - defined in :: =src/./built_ins.cpp:670:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =special-lambda= | |||||
| * =not= | |||||
| - defined in :: =src/./built_ins.cpp:736:0= | |||||
| - defined in :: =src/./built_ins.cpp:681:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =eval= | |||||
| * =while= | |||||
| - defined in :: =src/./built_ins.cpp:744:0= | |||||
| - defined in :: =src/./built_ins.cpp:691:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =begin= | |||||
| * =lambda= | |||||
| - defined in :: =src/./built_ins.cpp:756:0= | |||||
| - defined in :: =src/./built_ins.cpp:769:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =list= | |||||
| * =special-lambda= | |||||
| - defined in :: =src/./built_ins.cpp:772:0= | |||||
| - defined in :: =src/./built_ins.cpp:781:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =vector= | |||||
| * =eval= | |||||
| - defined in :: =src/./built_ins.cpp:776:0= | |||||
| - defined in :: =src/./built_ins.cpp:789:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =pair= | |||||
| * =begin= | |||||
| - defined in :: =src/./built_ins.cpp:782:0= | |||||
| - defined in :: =src/./built_ins.cpp:801:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | #+END: | ||||
| \hrule | \hrule | ||||
| * =first= | |||||
| * =list= | |||||
| - defined in :: =src/./built_ins.cpp:792:0= | |||||
| - defined in :: =src/./built_ins.cpp:817:0= | |||||
| - type :: =:cfunction= | - type :: =:cfunction= | ||||
| - docu :: | - docu :: | ||||
| #+BEGIN: | #+BEGIN: | ||||
| TODO | TODO | ||||
| #+END: | |||||
| \hrule | |||||
| * = | |||||
| @@ -446,6 +446,51 @@ proc load_built_ins_into_environment() -> void { | |||||
| *target = *source; | *target = *source; | ||||
| return target; | return target; | ||||
| }); | }); | ||||
| defun("vector-length", "TODO", __LINE__, cLambda { | |||||
| try evaluated_arguments = eval_arguments(arguments, &arguments_length); | |||||
| try assert_arguments_length(1, arguments_length); | |||||
| Lisp_Object* vec = evaluated_arguments->value.pair.first; | |||||
| assert_type(vec, Lisp_Object_Type::Vector); | |||||
| return Memory::create_lisp_object_number((double)vec->value.vector.length); | |||||
| }); | |||||
| defun("vector-ref", "TODO", __LINE__, cLambda { | |||||
| try evaluated_arguments = eval_arguments(arguments, &arguments_length); | |||||
| try assert_arguments_length(2, arguments_length); | |||||
| Lisp_Object* vec = evaluated_arguments->value.pair.first; | |||||
| Lisp_Object* idx = evaluated_arguments->value.pair.rest->value.pair.first; | |||||
| try assert_type(vec, Lisp_Object_Type::Vector); | |||||
| try assert_type(idx, Lisp_Object_Type::Number); | |||||
| int int_idx = ((size_t)idx->value.number); | |||||
| try assert(int_idx >= 0); | |||||
| try assert(int_idx < vec->value.vector.length); | |||||
| return vec->value.vector.data+int_idx; | |||||
| }); | |||||
| defun("vector-set!", "TODO", __LINE__, cLambda { | |||||
| try evaluated_arguments = eval_arguments(arguments, &arguments_length); | |||||
| try assert_arguments_length(3, arguments_length); | |||||
| Lisp_Object* vec = evaluated_arguments->value.pair.first; | |||||
| Lisp_Object* idx = evaluated_arguments->value.pair.rest->value.pair.first; | |||||
| Lisp_Object* val = evaluated_arguments->value.pair.rest->value.pair.rest->value.pair.first; | |||||
| try assert_type(vec, Lisp_Object_Type::Vector); | |||||
| try assert_type(idx, Lisp_Object_Type::Number); | |||||
| int int_idx = ((size_t)idx->value.number); | |||||
| try assert(int_idx >= 0); | |||||
| try assert(int_idx < vec->value.vector.length); | |||||
| vec->value.vector.data[int_idx] = *val; | |||||
| return val; | |||||
| }); | |||||
| defun("set!", "TODO", __LINE__, cLambda { | defun("set!", "TODO", __LINE__, cLambda { | ||||
| try assert_arguments_length(2, list_length(arguments)); | try assert_arguments_length(2, list_length(arguments)); | ||||
| Lisp_Object* target_symbol = arguments->value.pair.first; | Lisp_Object* target_symbol = arguments->value.pair.first; | ||||
| @@ -912,17 +957,17 @@ proc load_built_ins_into_environment() -> void { | |||||
| } | } | ||||
| printf("}\n"); | printf("}\n"); | ||||
| printf("Keyword: {"); | printf("Keyword: {"); | ||||
| if (fun->value.function.keyword_arguments->next_index != 0) { | |||||
| if (fun->value.function.keyword_arguments->values->next_index != 0) { | |||||
| printf("%s", | printf("%s", | ||||
| Memory::get_c_str(fun->value.function.keyword_arguments->keywords[0]->value.symbol.identifier)); | |||||
| Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[0]->value.symbol.identifier)); | |||||
| if (fun->value.function.keyword_arguments->values->data[0]) { | if (fun->value.function.keyword_arguments->values->data[0]) { | ||||
| printf(" ("); | printf(" ("); | ||||
| print(fun->value.function.keyword_arguments->values->data[0]); | print(fun->value.function.keyword_arguments->values->data[0]); | ||||
| printf(")"); | printf(")"); | ||||
| } | } | ||||
| for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) { | |||||
| for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) { | |||||
| printf(", %s", | printf(", %s", | ||||
| Memory::get_c_str(fun->value.function.keyword_arguments->keywords[i]->value.symbol.identifier)); | |||||
| Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier)); | |||||
| if (fun->value.function.keyword_arguments->values->data[i]) { | if (fun->value.function.keyword_arguments->values->data[i]) { | ||||
| printf(" ("); | printf(" ("); | ||||
| print(fun->value.function.keyword_arguments->values->data[i]); | print(fun->value.function.keyword_arguments->values->data[i]); | ||||
| @@ -98,18 +98,18 @@ proc generate_docs(String* path) -> void { | |||||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier)); | fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier)); | ||||
| } | } | ||||
| } | } | ||||
| if (fun->value.function.keyword_arguments->next_index != 0) { | |||||
| if (fun->value.function.keyword_arguments->values->next_index != 0) { | |||||
| if (!printed_at_least_some_args) | if (!printed_at_least_some_args) | ||||
| fprintf(f, ":"); | fprintf(f, ":"); | ||||
| fprintf(f, "\n - keyword :: "); | fprintf(f, "\n - keyword :: "); | ||||
| fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[0]->value.symbol.identifier)); | |||||
| fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[0]->value.symbol.identifier)); | |||||
| if (fun->value.function.keyword_arguments->values->data[0]) { | if (fun->value.function.keyword_arguments->values->data[0]) { | ||||
| fprintf(f, " =("); | fprintf(f, " =("); | ||||
| print(fun->value.function.keyword_arguments->values->data[0], true, f); | print(fun->value.function.keyword_arguments->values->data[0], true, f); | ||||
| fprintf(f, ")="); | fprintf(f, ")="); | ||||
| } | } | ||||
| for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) { | |||||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[i]->value.symbol.identifier)); | |||||
| for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) { | |||||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier)); | |||||
| if (fun->value.function.keyword_arguments->values->data[i]) { | if (fun->value.function.keyword_arguments->values->data[i]) { | ||||
| fprintf(f, " =("); | fprintf(f, " =("); | ||||
| print(fun->value.function.keyword_arguments->values->data[i], true, f); | print(fun->value.function.keyword_arguments->values->data[i], true, f); | ||||
| @@ -124,7 +124,7 @@ proc generate_docs(String* path) -> void { | |||||
| } | } | ||||
| // if no args at all | // if no args at all | ||||
| if (fun->value.function.positional_arguments->next_index == 0 && | if (fun->value.function.positional_arguments->next_index == 0 && | ||||
| fun->value.function.keyword_arguments->next_index == 0 && | |||||
| fun->value.function.keyword_arguments->values->next_index == 0 && | |||||
| !fun->value.function.rest_argument) | !fun->value.function.rest_argument) | ||||
| { | { | ||||
| fprintf(f, "none."); | fprintf(f, "none."); | ||||
| @@ -43,7 +43,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||||
| return; | return; | ||||
| // find out how many keyword args we /have/ to read | // find out how many keyword args we /have/ to read | ||||
| for (int i = 0; i < function->keyword_arguments->next_index; ++i) { | |||||
| for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { | |||||
| if (function->keyword_arguments->values->data[i] == nullptr) | if (function->keyword_arguments->values->data[i] == nullptr) | ||||
| ++obligatory_keywords_count; | ++obligatory_keywords_count; | ||||
| else | else | ||||
| @@ -54,10 +54,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||||
| while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) { | while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) { | ||||
| // check if this one is even an accepted keyword | // check if this one is even an accepted keyword | ||||
| bool accepted = false; | bool accepted = false; | ||||
| for (int i = 0; i < function->keyword_arguments->next_index; ++i) { | |||||
| for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { | |||||
| if (string_equal( | if (string_equal( | ||||
| arguments->value.pair.first->value.symbol.identifier, | arguments->value.pair.first->value.symbol.identifier, | ||||
| function->keyword_arguments->keywords[i]->value.symbol.identifier)) | |||||
| function->keyword_arguments->keywords->data[i]->value.symbol.identifier)) | |||||
| { | { | ||||
| accepted = true; | accepted = true; | ||||
| break; | break; | ||||
| @@ -128,10 +128,11 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||||
| proc check_keyword_args = [&]() -> void { | proc check_keyword_args = [&]() -> void { | ||||
| // check if all necessary keywords have been read in | // check if all necessary keywords have been read in | ||||
| for (int i = 0; i < function->keyword_arguments->next_index; ++i) { | |||||
| String* defined_keyword = function->keyword_arguments->keywords[i]->value.symbol.identifier; | |||||
| for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { | |||||
| String* defined_keyword = function->keyword_arguments->keywords->data[i]->value.symbol.identifier; | |||||
| bool was_set = false; | bool was_set = false; | ||||
| for (int j = 0; j < read_in_keywords->next_index; ++j) { | for (int j = 0; j < read_in_keywords->next_index; ++j) { | ||||
| // TODO(Felix): Later compare the keywords, not their strings!! | |||||
| if (string_equal( | if (string_equal( | ||||
| read_in_keywords->data[j], | read_in_keywords->data[j], | ||||
| defined_keyword)) | defined_keyword)) | ||||
| @@ -44,10 +44,8 @@ proc append_to_positional_argument_list(Positional_Arguments* args, Lisp_Object* | |||||
| proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* { | proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* { | ||||
| Keyword_Arguments* ret = new(Keyword_Arguments); | Keyword_Arguments* ret = new(Keyword_Arguments); | ||||
| ret->keywords = (Lisp_Object**)malloc(initial_capacity * sizeof(Lisp_Object*)); | |||||
| ret->values = create_Lisp_Object_array_list(initial_capacity); | |||||
| ret->next_index = 0; | |||||
| ret->length = initial_capacity; | |||||
| ret->keywords = create_Lisp_Object_array_list(initial_capacity); | |||||
| ret->values = create_Lisp_Object_array_list(initial_capacity); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -55,11 +53,6 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args, | |||||
| Lisp_Object* keyword, | Lisp_Object* keyword, | ||||
| Lisp_Object* default_value) -> void | Lisp_Object* default_value) -> void | ||||
| { | { | ||||
| if (args->next_index == args->length) { | |||||
| args->length *= 2; | |||||
| args->keywords = (Lisp_Object**)realloc(args->keywords, args->length * sizeof(Lisp_Object*)); | |||||
| } | |||||
| args->keywords[args->next_index++] = keyword; | |||||
| append_to_array_list(args->keywords, keyword); | |||||
| append_to_array_list(args->values, default_value); | append_to_array_list(args->values, default_value); | ||||
| } | } | ||||
| @@ -227,13 +227,8 @@ namespace Memory { | |||||
| } | } | ||||
| proc allocate_vector(int size) -> Lisp_Object* { | proc allocate_vector(int size) -> Lisp_Object* { | ||||
| /* | |||||
| int object_memory_size; | |||||
| Int_Array_List* free_spots_in_object_memory; | |||||
| Lisp_Object* object_memory; | |||||
| int next_index_in_object_memory = 0; | |||||
| */ | |||||
| // NOTE(Felix): Vectors are now only allocated at the back of | |||||
| // the memory, we don't check the free list at all right now | |||||
| if (object_memory_size - next_index_in_object_memory < size) { | if (object_memory_size - next_index_in_object_memory < size) { | ||||
| create_out_of_memory_error( | create_out_of_memory_error( | ||||
| @@ -243,6 +238,7 @@ namespace Memory { | |||||
| "calling Memory::init()"); | "calling Memory::init()"); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| int start = next_index_in_object_memory; | int start = next_index_in_object_memory; | ||||
| next_index_in_object_memory += size; | next_index_in_object_memory += size; | ||||
| return object_memory+start; | return object_memory+start; | ||||
| @@ -268,27 +268,18 @@ namespace Parser { | |||||
| } | } | ||||
| Lisp_Object* ret = nullptr; | Lisp_Object* ret = nullptr; | ||||
| // TODO(Felix): use Memory::create_list() here | |||||
| if (quoteType == '\'') | if (quoteType == '\'') | ||||
| try ret = Memory::create_lisp_object_pair( | |||||
| Memory::get_or_create_lisp_object_symbol("quote"), | |||||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||||
| try ret = Memory::create_list(Memory::get_or_create_lisp_object_symbol("quote"), result); | |||||
| else if (quoteType == '`') | else if (quoteType == '`') | ||||
| try ret = Memory::create_lisp_object_pair( | |||||
| Memory::get_or_create_lisp_object_symbol("quasiquote"), | |||||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||||
| try ret = Memory::create_list(Memory::get_or_create_lisp_object_symbol("quasiquote"), result); | |||||
| else if (quoteType == ',') | else if (quoteType == ',') | ||||
| try ret = Memory::create_lisp_object_pair( | |||||
| Memory::get_or_create_lisp_object_symbol("unquote"), | |||||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||||
| try ret = Memory::create_list(Memory::get_or_create_lisp_object_symbol("unquote"), result); | |||||
| else if (quoteType == '@') { | else if (quoteType == '@') { | ||||
| try ret = Memory::create_lisp_object_pair( | |||||
| Memory::get_or_create_lisp_object_symbol("unquote-splicing"), | |||||
| Memory::create_lisp_object_pair(result, Memory::nil)); | |||||
| } | |||||
| if (ret) { | |||||
| inject_scl(ret); | |||||
| try ret = Memory::create_list(Memory::get_or_create_lisp_object_symbol("unquote-splicing"), result); | |||||
| } | } | ||||
| if (ret) inject_scl(ret); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -89,13 +89,11 @@ struct Positional_Arguments { | |||||
| }; | }; | ||||
| struct Keyword_Arguments { | struct Keyword_Arguments { | ||||
| Lisp_Object** keywords; // Array of Pointers to Lisp_Object<Keyword> | |||||
| // Array of Pointers to Lisp_Object<Keyword> | |||||
| Lisp_Object_Array_List* keywords; | |||||
| // NOTE(Felix): values[i] will be nullptr if no defalut value was | // NOTE(Felix): values[i] will be nullptr if no defalut value was | ||||
| // declared for key identifiers[i] | // declared for key identifiers[i] | ||||
| Lisp_Object_Array_List* values; | Lisp_Object_Array_List* values; | ||||
| // TODO(Felix): Why do we use a Array list here?? | |||||
| int next_index; | |||||
| int length; | |||||
| }; | }; | ||||
| struct Function { | struct Function { | ||||