In the middle of filtering the pairs to draw for the visualization
This commit is contained in:
+879
-378
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 127 KiB |
+2
-2
@@ -455,7 +455,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
// we modify the body of the function and would bake
|
// we modify the body of the function and would bake
|
||||||
// in the result...
|
// in the result...
|
||||||
Lisp_Object* newPair;
|
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* newPairHead = newPair;
|
||||||
Lisp_Object* head = expr;
|
Lisp_Object* head = expr;
|
||||||
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
|
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)
|
if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair)
|
||||||
break;
|
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;
|
newPairHead = newPairHead->value.pair.rest;
|
||||||
head = head->value.pair.rest;
|
head = head->value.pair.rest;
|
||||||
|
|||||||
+150
@@ -81,6 +81,10 @@ constexpr bool is_debug_build = false;
|
|||||||
int next_index; \
|
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 { \
|
proc append_to_array_list(name##_Array_List* arraylist, type element) -> void { \
|
||||||
if (arraylist->next_index == arraylist->length) { \
|
if (arraylist->next_index == arraylist->length) { \
|
||||||
@@ -91,6 +95,53 @@ constexpr bool is_debug_build = false;
|
|||||||
arraylist->data[arraylist->next_index++] = element; \
|
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* { \
|
proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List* { \
|
||||||
name##_Array_List* ret = new(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<typename F>
|
template<typename F>
|
||||||
class defer_finalizer {
|
class defer_finalizer {
|
||||||
F f;
|
F f;
|
||||||
|
|||||||
+2
-2
@@ -338,7 +338,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* evaluated_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* evaluated_arguments_head = evaluated_arguments;
|
||||||
Lisp_Object* current_head = 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;
|
current_head = current_head->value.pair.rest;
|
||||||
|
|
||||||
if (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
|
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;
|
evaluated_arguments_head = evaluated_arguments_head->value.pair.rest;
|
||||||
} else if (current_head == Memory::nil) {
|
} else if (current_head == Memory::nil) {
|
||||||
evaluated_arguments_head->value.pair.rest = current_head;
|
evaluated_arguments_head->value.pair.rest = current_head;
|
||||||
|
|||||||
+1
-1
@@ -357,7 +357,7 @@ namespace Parser {
|
|||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
break;
|
break;
|
||||||
} else {
|
} 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;
|
head = head->value.pair.rest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -26,8 +26,8 @@ typedef uint64_t u64;
|
|||||||
|
|
||||||
enum class Lisp_Object_Flags : u64
|
enum class Lisp_Object_Flags : u64
|
||||||
{
|
{
|
||||||
// bits 0 to 5 will be reserved for the type
|
// bits 1 to 5 (including) will be reserved for the type
|
||||||
aliveness = 1 << 6,
|
aliveness = 1 << 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Function_Type {
|
enum struct Function_Type {
|
||||||
|
|||||||
+66
-1
@@ -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 {
|
proc test_eval_operands() -> testresult {
|
||||||
char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))";
|
char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))";
|
||||||
Lisp_Object* operands = Parser::parse_single_expression(operands_string);
|
Lisp_Object* operands = Parser::parse_single_expression(operands_string);
|
||||||
@@ -507,7 +568,11 @@ proc run_all_tests() -> bool {
|
|||||||
|
|
||||||
bool result = true;
|
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_atom);
|
||||||
invoke_test(test_parse_expression);
|
invoke_test(test_parse_expression);
|
||||||
|
|
||||||
|
|||||||
+99
-51
@@ -7,7 +7,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
const int padding = 40;
|
const int padding = 40;
|
||||||
const int margin = 20;
|
const int margin = 20;
|
||||||
|
|
||||||
const char* draw_text_template = " <text x='%d' y='%d' font-size='20' font-family='monospace'>\n %s\n </text>\n";
|
const char* draw_text_template = " <text x='%d' y='%d' font-size='20' font-family='monospace' style='fill: %s'>\n %s%s%s\n </text>\n";
|
||||||
const char* draw_integer_template = " <text x='%d' y='%d' font-size='20' font-family='monospace'>\n %d\n </text>\n";
|
const char* draw_integer_template = " <text x='%d' y='%d' font-size='20' font-family='monospace'>\n %d\n </text>\n";
|
||||||
const char* draw_float_template = " <text x='%d' y='%d' font-size='20' font-family='monospace'>\n %012.6f\n </text>\n";
|
const char* draw_float_template = " <text x='%d' y='%d' font-size='20' font-family='monospace'>\n %012.6f\n </text>\n";
|
||||||
|
|
||||||
@@ -36,15 +36,18 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = 0;
|
write_x = 0;
|
||||||
write_y += 25 * count;
|
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
|
// take care of escaping sensitive chars
|
||||||
int text_length = 0;
|
int text_length = 0;
|
||||||
int extra_needed_chars = 0;
|
int extra_needed_chars = draw_quotes ? 10 : 0;
|
||||||
char* new_text;
|
char* new_text = nullptr;
|
||||||
|
char char_at_max_length = 0;
|
||||||
|
|
||||||
char source;
|
char source;
|
||||||
while ((source = text[text_length++]) != '\0') {
|
while ((source = text[text_length++]) != '\0') {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
|
case '\n':
|
||||||
|
extra_needed_chars += 1;
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
extra_needed_chars += 3;
|
extra_needed_chars += 3;
|
||||||
@@ -57,6 +60,19 @@ proc visualize_lisp_machine() -> void {
|
|||||||
extra_needed_chars += 5;
|
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 we need to replace some chars
|
||||||
if (extra_needed_chars > 0) {
|
if (extra_needed_chars > 0) {
|
||||||
new_text = (char*)malloc((text_length + extra_needed_chars) * sizeof(char));
|
new_text = (char*)malloc((text_length + extra_needed_chars) * sizeof(char));
|
||||||
@@ -67,58 +83,28 @@ proc visualize_lisp_machine() -> void {
|
|||||||
char source;
|
char source;
|
||||||
while ((source = text[index_in_text++]) != '\0') {
|
while ((source = text[index_in_text++]) != '\0') {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case '<':
|
case '\n': new_text[index_in_new_text++] = '\\'; new_text[index_in_new_text++] = 'n'; break;
|
||||||
new_text[index_in_new_text++] = '&';
|
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;
|
||||||
new_text[index_in_new_text++] = 'l';
|
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;
|
||||||
new_text[index_in_new_text++] = 't';
|
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;
|
||||||
new_text[index_in_new_text++] = ';';
|
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;
|
||||||
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;
|
||||||
case '>':
|
default: new_text[index_in_new_text++] = source;
|
||||||
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';
|
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_x + text_width > max_x) max_x = write_x + text_width;
|
||||||
if (write_y > max_y) max_y = write_y;
|
if (write_y > max_y) max_y = write_y;
|
||||||
|
|
||||||
|
const char* quote = draw_quotes ? """ : "";
|
||||||
if (extra_needed_chars) {
|
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);
|
free(new_text);
|
||||||
} else {
|
} 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;
|
write_x += text_width;
|
||||||
@@ -143,7 +129,19 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
write_x += text_width;
|
write_x += text_width;
|
||||||
};
|
};
|
||||||
|
proc draw_pair = [&](Lisp_Object* pair) {
|
||||||
|
fprintf(f,
|
||||||
|
" <rect x='%d' y='%d' width='100' height='50' stroke-width='3' stroke='black' fill='white'/>"
|
||||||
|
" <line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='3' stroke='black'/>",
|
||||||
|
write_x, write_y, write_x+50, write_y, write_x+50, write_y+50);
|
||||||
|
if (pair->value.pair.rest == Memory::nil) {
|
||||||
|
fprintf(f,
|
||||||
|
" <line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='3' stroke='black'/>",
|
||||||
|
write_x+50, write_y+50, write_x+100, write_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "\n");
|
||||||
|
};
|
||||||
proc draw_header = [&]() {
|
proc draw_header = [&]() {
|
||||||
proc draw_separator = [&]() {
|
proc draw_separator = [&]() {
|
||||||
draw_margin();
|
draw_margin();
|
||||||
@@ -235,9 +233,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
draw_separator();
|
draw_separator();
|
||||||
|
|
||||||
draw_new_line();
|
draw_new_line(3);
|
||||||
draw_new_line();
|
|
||||||
draw_new_line();
|
|
||||||
};
|
};
|
||||||
proc draw_symbols_keywords_and_numbers = [&]() {
|
proc draw_symbols_keywords_and_numbers = [&]() {
|
||||||
Lisp_Object_Array_List* symbols = create_Lisp_Object_array_list();
|
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::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::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;
|
case Lisp_Object_Type::Pair : append_to_array_list(pairs, Memory::object_memory+i); break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
next: ;
|
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<void(Lisp_Object*)> 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_text("Memory Contents:");
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
@@ -273,6 +289,8 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
draw_text("Symbols: ");
|
draw_text("Symbols: ");
|
||||||
draw_integer(symbols->next_index);
|
draw_integer(symbols->next_index);
|
||||||
|
draw_new_line();
|
||||||
|
write_x = start_x;
|
||||||
|
|
||||||
for (int i = 0; i < symbols->next_index; ++i) {
|
for (int i = 0; i < symbols->next_index; ++i) {
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
@@ -287,13 +305,15 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
draw_text("Keywords: ");
|
draw_text("Keywords: ");
|
||||||
draw_integer(keywords->next_index);
|
draw_integer(keywords->next_index);
|
||||||
|
draw_new_line();
|
||||||
|
write_x = start_x + 300;
|
||||||
|
|
||||||
for (int i = 0; i < keywords->next_index; ++i) {
|
for (int i = 0; i < keywords->next_index; ++i) {
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 300;
|
write_x = start_x + 300;
|
||||||
|
|
||||||
draw_text(":");
|
draw_text(":", "#c61b6e");
|
||||||
draw_text(&keywords->data[i]->value.identifier->data);
|
draw_text(&keywords->data[i]->value.identifier->data, "#c61b6e");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -303,19 +323,46 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
draw_text("Numbers: ");
|
draw_text("Numbers: ");
|
||||||
draw_integer(numbers->next_index);
|
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_x = start_x + 900;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Strings: ");
|
draw_text("Strings: ");
|
||||||
draw_integer(strings->next_index);
|
draw_integer(strings->next_index);
|
||||||
|
draw_new_line();
|
||||||
|
write_x = start_x + 900;
|
||||||
|
|
||||||
write_x = start_x + 1200;
|
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 + 2000;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Pairs: ");
|
draw_text("Pairs: ");
|
||||||
draw_integer(pairs->next_index);
|
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,
|
fprintf(f,
|
||||||
@@ -327,6 +374,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
draw_header();
|
draw_header();
|
||||||
draw_symbols_keywords_and_numbers();
|
draw_symbols_keywords_and_numbers();
|
||||||
|
// draw_text("DoEun", "#00aaaa", true);
|
||||||
|
|
||||||
fprintf(f, "\n\n</svg>");
|
fprintf(f, "\n\n</svg>");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user