From 79fa5935197790bebe170f406462db50351645ef Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Mon, 6 May 2019 12:20:55 +0200 Subject: [PATCH] In the middle of filtering the pairs to draw for the visualization --- bin/visualization.svg | 1973 ++++++++++++++++++++++++++--------------- src/built_ins.cpp | 4 +- src/defines.cpp | 150 ++++ src/eval.cpp | 4 +- src/parse.cpp | 2 +- src/structs.cpp | 4 +- src/testing.cpp | 67 +- src/visualization.cpp | 150 ++-- 8 files changed, 1559 insertions(+), 795 deletions(-) diff --git a/bin/visualization.svg b/bin/visualization.svg index 7702d63..38b9484 100644 --- a/bin/visualization.svg +++ b/bin/visualization.svg @@ -1,1133 +1,1634 @@ + viewBox='-00040 -00040 002200 007842'> - - Date: + + Date: - - 04.05.2019 + + 06.05.2019 - - | + + | - - Time: + + Time: - - 17:25:39 + + 12:17:09 - - | + + | - - String Memory: + + String Memory: - - [allocated chars] + + [allocated chars] - + 65536 - - [free] + + [free] - + 3026 - - [used] + + [used] - + 62510 - - [%free] + + [%free] - + 00004.617310 - - [%used] + + [%used] - + 00095.382690 - - | + + | - - Object Memory: + + Object Memory: - - [#allocated] + + [#allocated] - + 8192000 - - [#free] + + [#free] - + 8191179 - - [#used] + + [#used] - + 821 - - [%free] + + [%free] - + 00099.989975 - - [%used] + + [%used] - + 00000.010022 - - | + + | - - Memory Contents: + + Memory Contents: - - Symbols: + + Symbols: - + 302 - - = + + = - - > + + > - - >= + + >= - - < + + < - - <= + + <= - - + + + + - - - + + - - - * + + * - - / + + / - - ** + + ** - - % + + % - - assert + + assert - - define + + define - - mutate + + mutate - - if + + if - - quote + + quote - - quasiquote + + quasiquote - - and + + and - - or + + or - - not + + not - - while + + while - - let + + let - - lambda + + lambda - - special-lambda + + special-lambda - - eval + + eval - - prog + + prog - - list + + list - - pair + + pair - - first + + first - - rest + + rest - - set-type + + set-type - - delete-type + + delete-type - - type + + type - - info + + info - - show + + show - - print + + print - - read + + read - - exit + + exit - - break + + break - - memstat + + memstat - - try + + try - - load + + load - - import + + import - - copy + + copy - - error + + error - - symbol->keyword + + symbol->keyword - - string->symbol + + string->symbol - - symbol->string + + symbol->string - - concat-strings + + concat-strings - - define-syntax + + define-syntax - - when + + when - - condition + + condition - - body + + body - - if + + if - - condition + + condition - - unquote + + unquote - - pair + + pair - - prog + + prog - - body + + body - - unquote + + unquote - - nil + + nil - - quasiquote + + quasiquote - - prog + + prog - - define-syntax + + define-syntax - - unless + + unless - - condition + + condition - - body + + body - - if + + if - - condition + + condition - - unquote + + unquote - - nil + + nil - - pair + + pair - - prog + + prog - - body + + body - - unquote + + unquote - - quasiquote + + quasiquote - - prog + + prog - - define-syntax + + define-syntax - - cond + + cond - - clauses + + clauses - - define + + define - - rec + + rec - - clauses + + clauses - - if + + if - - = + + = - - nil + + nil - - clauses + + clauses - - nil + + nil - - if + + if - - = + + = - - first + + first - - first + + first - - clauses + + clauses - - else + + else - - quote + + quote - - prog + + prog - - if + + if - - not + + not - - = + + = - - rest + + rest - - clauses + + clauses - - error + + error - - pair + + pair - - prog + + prog - - quote + + quote - - rest + + rest - - first + + first - - clauses + + clauses - - list + + list - - if + + if - - quote + + quote - - first + + first - - first + + first - - clauses + + clauses - - pair + + pair - - prog + + prog - - quote + + quote - - rest + + rest - - first + + first - - clauses + + clauses - - rec + + rec - - rest + + rest - - clauses + + clauses - - rec + + rec - - clauses + + clauses - - prog + + prog - - define + + define - - nil? + + nil? - - x + + x - - = + + = - - x + + x - - nil + + nil - - define + + define - - number? + + number? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - symbol? + + symbol? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - keyword? + + keyword? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - pair? + + pair? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - string? + + string? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - lambda? + + lambda? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - special-lambda? + + special-lambda? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - built-n-function? + + built-n-function? - - x + + x - - = + + = - - type + + type - - x + + x - - define + + define - - apply + + apply - - fun + + fun - - seq + + seq - - eval + + eval - - pair + + pair - - fun + + fun - - seq + + seq - - define + + define - - end + + end - - seq + + seq - - if + + if - - or + + or - - nil? + + nil? - - seq + + seq - - not + + not - - pair? + + pair? - - rest + + rest - - seq + + seq - - seq + + seq - - end + + end - - rest + + rest - - seq + + seq - - define + + define - - last + + last - - seq + + seq - - first + + first - - end + + end - - seq + + seq - - define + + define - - extend + + extend - - seq + + seq - - elem + + elem - - if + + if - - pair? + + pair? - - seq + + seq - - prog + + prog - - define + + define - - e + + e - - end + + end - - seq + + seq - - mutate + + mutate - - e + + e - - pair + + pair - - first + + first - - e + + e - - elem + + elem - - seq + + seq - - elem + + elem - - define + + define - - append + + append - - seq + + seq - - elem + + elem - - extend + + extend - - seq + + seq - - pair + + pair - - elem + + elem - - nil + + nil - - define-syntax + + define-syntax - - extend! + + extend! - - seq + + seq - - elem + + elem - - mutate + + mutate - - seq + + seq - - unquote + + unquote - - extend + + extend - - seq + + seq - - unquote + + unquote - - elem + + elem - - unquote + + unquote - - quasiquote + + quasiquote - - prog + + prog - - define-syntax + + define-syntax - - append! + + append! - - seq + + seq - - elem + + elem - - mutate + + mutate - - seq + + seq - - unquote + + unquote - - append + + append - - seq + + seq - - unquote + + unquote - - elem + + elem - - unquote + + unquote - - quasiquote + + quasiquote - - prog + + prog - - define + + define - - length + + length - - seq + + seq - - if + + if - - nil? + + nil? - - seq + + seq - - + + + + - - length + + length - - rest + + rest - - seq + + seq - - define + + define - - increment + + increment - - val + + val - - + + + + - - val + + val - - define + + define - - decrement + + decrement - - val + + val - - - + + - - - val + + val - - define + + define - - range + + range - - from + + from - - to + + to - - when + + when - - < + + < - - from + + from - - to + + to - - pair + + pair - - from + + from - - range + + range - - + + + + - - from + + from - - to + + to - - condition + + condition - - body + + body - - Keywords: + + Keywords: - + 16 - - : + + : - - rest + + rest - - : + + : - - rest + + rest - - : + + : - - rest + + rest - - : + + : - - number + + number - - : + + : - - symbol + + symbol - - : + + : - - keyword + + keyword - - : + + : - - pair + + pair - - : + + : - - string + + string - - : + + : - - dynamic-function + + dynamic-function - - : + + : - - dynamic-macro + + dynamic-macro - - : + + : - - built-in-function + + built-in-function - - : + + : - - keys + + keys - - : + + : - - defaults-to + + defaults-to - - : + + : - - from + + from - - : + + : - - to + + to - - : + + : - - symbol-undefined + + symbol-undefined - - Numbers: + + Numbers: - + 6 - - Strings: + + 00000.000000 - + + 00001.000000 + + + 00001.000000 + + + 00001.000000 + + + 00000.000000 + + + 00001.000000 + + + Strings: + + 21 - - Pairs: + + "Doc String for 'when'" + + + "There are additional clauses after the else clause!" + + + "Checks if the argument is nil." + + + "Checks if the argument is a number." + + + "Checks if the argument is a symbol." + + + "Checks if the argument is a keyword." + + + "Checks if the argument is a pair." + + + "Checks if the argument is a string." + + + "Checks if the argument is a function." + + + "Checks if the argument is a macro." + + + "Checks if the argument is a built-in function." + + + "Applies the funciton to the sequence, as in calls the function with\nithe se" + + + "Returns the last pair in the sqeuence." + + + "Returns the (first) of the last (pair) of the given sequence." + + + "Extends a list with the given element, by putting it in\nthe (rest) of the l" + + + "Appends an element to a sequence, by extendeing the list\nwith (pair elem ni" + + + "test" + + + "Returns the length of the given sequence." + + + "Adds one to the argument." + + + "Subtracts one from the argument." + + + "Returns a sequence of numbers starting with the number defined\nby the key '" + + + Pairs: - + 420 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/built_ins.cpp b/src/built_ins.cpp index c1a74d2..429fc1e 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -455,7 +455,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { // we modify the body of the function and would bake // in the result... Lisp_Object* newPair; - try newPair = Memory::create_lisp_object_pair(nullptr, nullptr); + try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil); Lisp_Object* newPairHead = newPair; Lisp_Object* head = expr; while (Memory::get_type(head) == Lisp_Object_Type::Pair) { @@ -464,7 +464,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair) break; - try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); + try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil); newPairHead = newPairHead->value.pair.rest; head = head->value.pair.rest; diff --git a/src/defines.cpp b/src/defines.cpp index 63a192b..449d150 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -81,6 +81,10 @@ constexpr bool is_debug_build = false; int next_index; \ }; \ \ + proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \ + arraylist->data[index] = \ + arraylist->data[--arraylist->next_index]; \ + } \ \ proc append_to_array_list(name##_Array_List* arraylist, type element) -> void { \ if (arraylist->next_index == arraylist->length) { \ @@ -91,6 +95,53 @@ constexpr bool is_debug_build = false; arraylist->data[arraylist->next_index++] = element; \ } \ \ + proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \ + int start2 = mid + 1; \ + \ + /* If the direct merge is already sorted */ \ + if ((size_t)arr->data[mid] <= (size_t)arr->data[start2]) { \ + return; \ + } \ + \ + /* Two pointers to maintain start of both arrays to merge */ \ + while (start <= mid && start2 <= end) { \ + if ((size_t)arr->data[start] <= (size_t)arr->data[start2]) { \ + start++; \ + } \ + else { \ + type value = arr->data[start2]; \ + int index = start2; \ + \ + /* Shift all the elements between element 1; element 2, right by 1. */ \ + while (index != start) { \ + arr->data[index] = arr->data[index - 1]; \ + index--; \ + } \ + arr->data[start] = value; \ + \ + /* Update all the pointers */ \ + start++; \ + mid++; \ + start2++; \ + } \ + } \ + } \ + \ + proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \ + if (left == -1) { \ + sort_array_list(arraylist, 0, arraylist->next_index - 1); \ + return; \ + } else if (left == right) { \ + return; \ + } \ + \ + int middle = left + (right-left) / 2; \ + \ + sort_array_list(arraylist, left, middle); \ + sort_array_list(arraylist, middle+1, right); \ + \ + _merge_array_lists(arraylist, left, middle, right); \ + } \ \ proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List* { \ name##_Array_List* ret = new(name##_Array_List); \ @@ -101,6 +152,105 @@ constexpr bool is_debug_build = false; } + + + + + + + + + + + +// struct Int_Array_List { +// int* data; +// int length; +// int next_index; +// }; + +// proc remove_index_from_array_list(Int_Array_List* arraylist, int index) -> void { +// arraylist->data[index] = arraylist->data[--arraylist->next_index]; +// } + +// proc append_to_array_list(Int_Array_List* arraylist, int element) -> void { +// if (arraylist->next_index == arraylist->length) { +// arraylist->length *= 2; +// arraylist->data = +// (int*)realloc(arraylist->data, arraylist->length * sizeof(int)); +// } +// arraylist->data[arraylist->next_index++] = element; +// } + +// proc _merge_array_lists(Int_Array_List* arr, int start, int mid, int end) -> void { +// int start2 = mid + 1; + +// /* If the direct merge is already sorted */ +// if ((size_t)arr->data[mid] <= (size_t)arr->data[start2]) { +// return; +// } + +// /* Two pointers to maintain start of both arrays to merge */ +// while (start <= mid && start2 <= end) { +// if ((size_t)arr->data[start] <= (size_t)arr->data[start2]) { +// start++; +// } +// else { +// int value = arr->data[start2]; +// int index = start2; + +// /* Shift all the elements between element 1; element 2, right by 1. */ +// while (index != start) { +// arr->data[index] = arr->data[index - 1]; +// index--; +// } +// arr->data[start] = value; + +// /* Update all the pointers */ +// start++; +// mid++; +// start2++; +// } +// } +// } + +// proc sort_array_list(Int_Array_List* arraylist, int left=-1, int right=-1) -> void { +// if (left == -1) { +// sort_array_list(arraylist, 0, arraylist->next_index - 1); +// return; +// } else if (left == right) { +// return; +// } + +// int middle = left + (right-left) / 2; + +// sort_array_list(arraylist, left, middle); +// sort_array_list(arraylist, middle+1, right); + +// _merge_array_lists(arraylist, left, middle, right); +// } + +// proc create_Int_array_list(int initial_capacity = 16) -> Int_Array_List* { +// Int_Array_List* ret = new(Int_Array_List); +// ret->data = (int*)malloc(initial_capacity * sizeof(int)); +// ret->next_index = 0; +// ret->length = initial_capacity; +// return ret; +// } + + + + + + + + + + + + + + template class defer_finalizer { F f; diff --git a/src/eval.cpp b/src/eval.cpp index 70fcf5f..70b4554 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -338,7 +338,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments } Lisp_Object* evaluated_arguments; - try evaluated_arguments = Memory::create_lisp_object_pair(nullptr, nullptr); + try evaluated_arguments = Memory::create_lisp_object_pair(Memory::nil, Memory::nil); Lisp_Object* evaluated_arguments_head = evaluated_arguments; Lisp_Object* current_head = arguments; @@ -350,7 +350,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments current_head = current_head->value.pair.rest; if (Memory::get_type(current_head) == Lisp_Object_Type::Pair) { - try evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); + try evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil); evaluated_arguments_head = evaluated_arguments_head->value.pair.rest; } else if (current_head == Memory::nil) { evaluated_arguments_head->value.pair.rest = current_head; diff --git a/src/parse.cpp b/src/parse.cpp index 84991b5..fc801f8 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -357,7 +357,7 @@ namespace Parser { ++(*index_in_text); break; } else { - try head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); + try head->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil); head = head->value.pair.rest; } } diff --git a/src/structs.cpp b/src/structs.cpp index 2a75830..93a93ed 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -26,8 +26,8 @@ typedef uint64_t u64; enum class Lisp_Object_Flags : u64 { - // bits 0 to 5 will be reserved for the type - aliveness = 1 << 6, + // bits 1 to 5 (including) will be reserved for the type + aliveness = 1 << 5, }; enum struct Function_Type { diff --git a/src/testing.cpp b/src/testing.cpp index 6ab3d45..8afc104 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -113,6 +113,67 @@ } \ } +proc test_array_lists_adding_and_removing() -> testresult { + // test adding and removing + Int_Array_List* list = create_Int_array_list(); + append_to_array_list(list, 1); + append_to_array_list(list, 2); + append_to_array_list(list, 3); + append_to_array_list(list, 4); + + assert_equal_int(list->next_index, 4); + + remove_index_from_array_list(list, 0); + + assert_equal_int(list->next_index, 3); + assert_equal_int(list->data[0], 4); + assert_equal_int(list->data[1], 2); + assert_equal_int(list->data[2], 3); + + remove_index_from_array_list(list, 2); + + assert_equal_int(list->next_index, 2); + assert_equal_int(list->data[0], 4); + assert_equal_int(list->data[1], 2); + + return pass; +} + +proc test_array_lists_sorting() -> testresult { + // test adding and removing + Int_Array_List* list = create_Int_array_list(); + append_to_array_list(list, 1); + append_to_array_list(list, 2); + append_to_array_list(list, 3); + append_to_array_list(list, 4); + + sort_array_list(list); + + assert_equal_int(list->next_index, 4); + + assert_equal_int(list->data[0], 1); + assert_equal_int(list->data[1], 2); + assert_equal_int(list->data[2], 3); + assert_equal_int(list->data[3], 4); + + append_to_array_list(list, 0); + append_to_array_list(list, 5); + + assert_equal_int(list->next_index, 6); + + sort_array_list(list); + + assert_equal_int(list->data[0], 0); + assert_equal_int(list->data[1], 1); + assert_equal_int(list->data[2], 2); + assert_equal_int(list->data[3], 3); + assert_equal_int(list->data[4], 4); + assert_equal_int(list->data[5], 5); + + + return pass; +} + proc test_eval_operands() -> testresult { char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))"; Lisp_Object* operands = Parser::parse_single_expression(operands_string); @@ -507,7 +568,11 @@ proc run_all_tests() -> bool { bool result = true; - printf("-- Parsing --\n"); + printf("-- Util --\n"); + invoke_test(test_array_lists_adding_and_removing); + invoke_test(test_array_lists_sorting); + + printf("\n -- Parsing --\n"); invoke_test(test_parse_atom); invoke_test(test_parse_expression); diff --git a/src/visualization.cpp b/src/visualization.cpp index 41071c7..2076841 100644 --- a/src/visualization.cpp +++ b/src/visualization.cpp @@ -7,7 +7,7 @@ proc visualize_lisp_machine() -> void { const int padding = 40; const int margin = 20; - const char* draw_text_template = " \n %s\n \n"; + const char* draw_text_template = " \n %s%s%s\n \n"; const char* draw_integer_template = " \n %d\n \n"; const char* draw_float_template = " \n %012.6f\n \n"; @@ -36,15 +36,18 @@ proc visualize_lisp_machine() -> void { write_x = 0; write_y += 25 * count; }; - proc draw_text = [&](const char* text) { + proc draw_text = [&](const char* text, const char* color = "#000000", bool draw_quotes = false, int max_length = 200) { // take care of escaping sensitive chars int text_length = 0; - int extra_needed_chars = 0; - char* new_text; + int extra_needed_chars = draw_quotes ? 10 : 0; + char* new_text = nullptr; + char char_at_max_length = 0; char source; while ((source = text[text_length++]) != '\0') { switch (source) { + case '\n': + extra_needed_chars += 1; case '<': case '>': extra_needed_chars += 3; @@ -57,6 +60,19 @@ proc visualize_lisp_machine() -> void { extra_needed_chars += 5; } } + // last char was \0 but we don't count it + --text_length; + + if (text_length > max_length) { + char_at_max_length = ((char*)text)[max_length]; + ((char*)text)[max_length] = '\0'; + text_length = max_length; + } + defer { + if (char_at_max_length) + ((char*)text)[max_length] = char_at_max_length; + }; + // if we need to replace some chars if (extra_needed_chars > 0) { new_text = (char*)malloc((text_length + extra_needed_chars) * sizeof(char)); @@ -67,58 +83,28 @@ proc visualize_lisp_machine() -> void { char source; while ((source = text[index_in_text++]) != '\0') { switch (source) { - case '<': - new_text[index_in_new_text++] = '&'; - new_text[index_in_new_text++] = 'l'; - new_text[index_in_new_text++] = 't'; - new_text[index_in_new_text++] = ';'; - break; - case '>': - new_text[index_in_new_text++] = '&'; - new_text[index_in_new_text++] = 'g'; - new_text[index_in_new_text++] = 't'; - new_text[index_in_new_text++] = ';'; - break; - case '&': - new_text[index_in_new_text++] = '&'; - new_text[index_in_new_text++] = 'a'; - new_text[index_in_new_text++] = 'm'; - new_text[index_in_new_text++] = 'p'; - new_text[index_in_new_text++] = ';'; - break; - case '"': - new_text[index_in_new_text++] = '&'; - new_text[index_in_new_text++] = 'q'; - new_text[index_in_new_text++] = 'u'; - new_text[index_in_new_text++] = 'o'; - new_text[index_in_new_text++] = 't'; - new_text[index_in_new_text++] = ';'; - break; - case '\'': - new_text[index_in_new_text++] = '&'; - new_text[index_in_new_text++] = 'a'; - new_text[index_in_new_text++] = 'p'; - new_text[index_in_new_text++] = 'o'; - new_text[index_in_new_text++] = 's'; - new_text[index_in_new_text++] = ';'; - break; - default: - new_text[index_in_new_text++] = source; + case '\n': new_text[index_in_new_text++] = '\\'; new_text[index_in_new_text++] = 'n'; break; + case '<': new_text[index_in_new_text++] = '&'; new_text[index_in_new_text++] = 'l'; new_text[index_in_new_text++] = 't'; new_text[index_in_new_text++] = ';'; break; + case '>': new_text[index_in_new_text++] = '&'; new_text[index_in_new_text++] = 'g'; new_text[index_in_new_text++] = 't'; new_text[index_in_new_text++] = ';'; break; + case '&': new_text[index_in_new_text++] = '&'; new_text[index_in_new_text++] = 'a'; new_text[index_in_new_text++] = 'm'; new_text[index_in_new_text++] = 'p'; new_text[index_in_new_text++] = ';'; break; + case '"': new_text[index_in_new_text++] = '&'; new_text[index_in_new_text++] = 'q'; new_text[index_in_new_text++] = 'u'; new_text[index_in_new_text++] = 'o'; new_text[index_in_new_text++] = 't'; new_text[index_in_new_text++] = ';'; break; + case '\'': new_text[index_in_new_text++] = '&'; new_text[index_in_new_text++] = 'a'; new_text[index_in_new_text++] = 'p'; new_text[index_in_new_text++] = 'o'; new_text[index_in_new_text++] = 's'; new_text[index_in_new_text++] = ';'; break; + default: new_text[index_in_new_text++] = source; } } new_text[index_in_new_text] = '\0'; } - int text_width = 12 * text_length; - + int text_width = 12 * (text_length + (draw_quotes ? 2 : 0)); if (write_x + text_width > max_x) max_x = write_x + text_width; if (write_y > max_y) max_y = write_y; + const char* quote = draw_quotes ? """ : ""; if (extra_needed_chars) { - fprintf(f, draw_text_template, write_x, write_y, new_text); + fprintf(f, draw_text_template, write_x, write_y, color, quote, new_text, quote); free(new_text); } else { - fprintf(f, draw_text_template, write_x, write_y, text); + fprintf(f, draw_text_template, write_x, write_y, color, quote, text, quote, color); } write_x += text_width; @@ -143,7 +129,19 @@ proc visualize_lisp_machine() -> void { write_x += text_width; }; + proc draw_pair = [&](Lisp_Object* pair) { + fprintf(f, + " " + " ", + write_x, write_y, write_x+50, write_y, write_x+50, write_y+50); + if (pair->value.pair.rest == Memory::nil) { + fprintf(f, + " ", + write_x+50, write_y+50, write_x+100, write_y); + } + fprintf(f, "\n"); + }; proc draw_header = [&]() { proc draw_separator = [&]() { draw_margin(); @@ -235,9 +233,7 @@ proc visualize_lisp_machine() -> void { draw_separator(); - draw_new_line(); - draw_new_line(); - draw_new_line(); + draw_new_line(3); }; proc draw_symbols_keywords_and_numbers = [&]() { Lisp_Object_Array_List* symbols = create_Lisp_Object_array_list(); @@ -259,11 +255,31 @@ proc visualize_lisp_machine() -> void { case Lisp_Object_Type::Keyword: append_to_array_list(keywords, Memory::object_memory+i); break; case Lisp_Object_Type::Number : append_to_array_list(numbers, Memory::object_memory+i); break; case Lisp_Object_Type::Pair : append_to_array_list(pairs, Memory::object_memory+i); break; + default: break; } next: ; } + // create the lists-list by filtering the pairs-list. + Lisp_Oject_Array_List* pairs_to_filter = create_Int_array_list(); + Int_Array_List* indices_to_filter = create_Int_array_list(); + + // recursive lambda + std::function filter_pair_and_children; + filter_pair_and_children = [&](Lisp_Object* pair) { + + }; + for (int i = 0; i < pairs->next_index; ++i) { + if (Memory::get_type(pairs->data[i]->value.pair.first) == Lisp_Object_Type::Pair) + filter_pair_and_children(pairs->data[i]->value.pair.first); + + if (Memory::get_type(pairs->data[i]->value.pair.rest) == Lisp_Object_Type::Pair) + filter_pair_and_children(pairs->data[i]->value.pair.rest); + + } + + draw_text("Memory Contents:"); draw_new_line(); draw_new_line(); @@ -273,6 +289,8 @@ proc visualize_lisp_machine() -> void { draw_text("Symbols: "); draw_integer(symbols->next_index); + draw_new_line(); + write_x = start_x; for (int i = 0; i < symbols->next_index; ++i) { draw_new_line(); @@ -287,13 +305,15 @@ proc visualize_lisp_machine() -> void { draw_text("Keywords: "); draw_integer(keywords->next_index); + draw_new_line(); + write_x = start_x + 300; for (int i = 0; i < keywords->next_index; ++i) { draw_new_line(); write_x = start_x + 300; - draw_text(":"); - draw_text(&keywords->data[i]->value.identifier->data); + draw_text(":", "#c61b6e"); + draw_text(&keywords->data[i]->value.identifier->data, "#c61b6e"); } @@ -303,19 +323,46 @@ proc visualize_lisp_machine() -> void { draw_text("Numbers: "); draw_integer(numbers->next_index); + draw_new_line(); + write_x = start_x + 600; + + for (int i = 0; i < numbers->next_index; ++i) { + draw_new_line(); + write_x = start_x + 600; + + draw_float(numbers->data[i]->value.number); + } write_x = start_x + 900; write_y = start_y; draw_text("Strings: "); draw_integer(strings->next_index); + draw_new_line(); + write_x = start_x + 900; + + for (int i = 0; i < strings->next_index; ++i) { + draw_new_line(); + write_x = start_x + 900; + + draw_text(&strings->data[i]->value.string->data, "#2aa198", true, 75); + } - write_x = start_x + 1200; + + write_x = start_x + 2000; write_y = start_y; draw_text("Pairs: "); draw_integer(pairs->next_index); + draw_new_line(); + write_x = start_x + 2000; + for (int i = 0; i < pairs->next_index; ++i) { + draw_new_line(3); + write_x = start_x + 2000; + + draw_pair(pairs->data[i]); + } }; fprintf(f, @@ -327,6 +374,7 @@ proc visualize_lisp_machine() -> void { draw_header(); draw_symbols_keywords_and_numbers(); + // draw_text("DoEun", "#00aaaa", true); fprintf(f, "\n\n");