visualizations have nice boxes and arrows diagrams for lists
This commit is contained in:
+2208
-826
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 277 KiB |
+19
-99
@@ -143,6 +143,25 @@ constexpr bool is_debug_build = false;
|
|||||||
_merge_array_lists(arraylist, left, middle, right); \
|
_merge_array_lists(arraylist, left, middle, right); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
proc sorted_array_list_find(name##_Array_List* arraylist, type elem, int left=-1, int right=-1) -> int { \
|
||||||
|
if (left == -1) { \
|
||||||
|
return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \
|
||||||
|
} else if (left == right) { \
|
||||||
|
if ((size_t)arraylist->data[left] == (size_t)elem) \
|
||||||
|
return left; \
|
||||||
|
return -1; \
|
||||||
|
} else if (right < left) \
|
||||||
|
return -1; \
|
||||||
|
\
|
||||||
|
int middle = left + (right-left) / 2; \
|
||||||
|
\
|
||||||
|
if ((size_t)arraylist->data[middle] < (size_t)elem) \
|
||||||
|
return sorted_array_list_find(arraylist, elem, middle+1, right); \
|
||||||
|
if ((size_t)arraylist->data[middle] > (size_t)elem) \
|
||||||
|
return sorted_array_list_find(arraylist, elem, left, middle-1); \
|
||||||
|
return middle; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
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); \
|
||||||
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
|
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
|
||||||
@@ -152,105 +171,6 @@ 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;
|
||||||
|
|||||||
@@ -174,6 +174,25 @@ proc test_array_lists_sorting() -> testresult {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc test_array_lists_searching() -> testresult {
|
||||||
|
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);
|
||||||
|
|
||||||
|
int index = sorted_array_list_find(list, 3);
|
||||||
|
assert_equal_int(index, 2);
|
||||||
|
|
||||||
|
index = sorted_array_list_find(list, 1);
|
||||||
|
assert_equal_int(index, 0);
|
||||||
|
|
||||||
|
index = sorted_array_list_find(list, 5);
|
||||||
|
assert_equal_int(index, -1);
|
||||||
|
|
||||||
|
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);
|
||||||
@@ -571,6 +590,7 @@ proc run_all_tests() -> bool {
|
|||||||
printf("-- Util --\n");
|
printf("-- Util --\n");
|
||||||
invoke_test(test_array_lists_adding_and_removing);
|
invoke_test(test_array_lists_adding_and_removing);
|
||||||
invoke_test(test_array_lists_sorting);
|
invoke_test(test_array_lists_sorting);
|
||||||
|
invoke_test(test_array_lists_searching);
|
||||||
|
|
||||||
printf("\n -- Parsing --\n");
|
printf("\n -- Parsing --\n");
|
||||||
invoke_test(test_parse_atom);
|
invoke_test(test_parse_atom);
|
||||||
|
|||||||
+196
-51
@@ -1,4 +1,11 @@
|
|||||||
proc visualize_lisp_machine() -> void {
|
proc visualize_lisp_machine() -> void {
|
||||||
|
struct Drawn_Area {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
fprintf(stderr, "Drawing visualization...");
|
fprintf(stderr, "Drawing visualization...");
|
||||||
defer {
|
defer {
|
||||||
fprintf(stderr, "Done!\n");
|
fprintf(stderr, "Done!\n");
|
||||||
@@ -29,14 +36,20 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_y = 0;
|
write_y = 0;
|
||||||
|
|
||||||
|
|
||||||
proc draw_margin = [&](int count = 1) {
|
proc draw_margin = [&](int count = 1) -> Drawn_Area {
|
||||||
write_x += margin * count;
|
write_x += margin * count;
|
||||||
|
return {
|
||||||
|
write_x - margin * count,
|
||||||
|
write_y,
|
||||||
|
margin * count,
|
||||||
|
write_y
|
||||||
|
};
|
||||||
};
|
};
|
||||||
proc draw_new_line = [&](int count = 1) {
|
proc draw_new_line = [&](int count = 1) {
|
||||||
write_x = 0;
|
write_x = 0;
|
||||||
write_y += 25 * count;
|
write_y += 25 * count;
|
||||||
};
|
};
|
||||||
proc draw_text = [&](const char* text, const char* color = "#000000", bool draw_quotes = false, int max_length = 200) {
|
proc draw_text = [&](const char* text, const char* color = "#000000", bool draw_quotes = false, int max_length = 200) -> Drawn_Area {
|
||||||
// take care of escaping sensitive chars
|
// take care of escaping sensitive chars
|
||||||
int text_length = 0;
|
int text_length = 0;
|
||||||
int extra_needed_chars = draw_quotes ? 10 : 0;
|
int extra_needed_chars = draw_quotes ? 10 : 0;
|
||||||
@@ -97,50 +110,140 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
int text_width = 12 * (text_length + (draw_quotes ? 2 : 0));
|
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 + 12 > max_y) max_y = write_y + 12;
|
||||||
|
|
||||||
const char* quote = draw_quotes ? """ : "";
|
const char* quote = draw_quotes ? """ : "";
|
||||||
if (extra_needed_chars) {
|
if (extra_needed_chars) {
|
||||||
fprintf(f, draw_text_template, write_x, write_y, color, quote, new_text, quote);
|
fprintf(f, draw_text_template, write_x, write_y+12, color, quote, new_text, quote);
|
||||||
free(new_text);
|
free(new_text);
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, draw_text_template, write_x, write_y, color, quote, text, quote, color);
|
fprintf(f, draw_text_template, write_x, write_y+12, color, quote, text, quote, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_x += text_width;
|
// write_x += text_width;
|
||||||
|
|
||||||
|
return {
|
||||||
|
write_x - text_width,
|
||||||
|
write_y,
|
||||||
|
text_width,
|
||||||
|
12
|
||||||
|
};
|
||||||
};
|
};
|
||||||
proc draw_integer = [&](int number) {
|
proc draw_integer = [&](int number) -> Drawn_Area {
|
||||||
int text_width = 12 * ((int)log10(number)+1);
|
int text_width = 12 * ((int)log10(number)+1);
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
fprintf(f, draw_integer_template, write_x, write_y, number);
|
fprintf(f, draw_integer_template, write_x, write_y+12, number);
|
||||||
|
|
||||||
write_x += text_width;
|
return {
|
||||||
|
write_x,
|
||||||
|
write_y,
|
||||||
|
text_width,
|
||||||
|
12
|
||||||
|
};
|
||||||
};
|
};
|
||||||
proc draw_float = [&](float number) {
|
proc draw_float = [&](float number) -> Drawn_Area {
|
||||||
int text_width = 12 * 12;
|
int text_width = 12 * 12;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
fprintf(f, draw_float_template, write_x, write_y, number);
|
fprintf(f, draw_float_template, write_x, write_y+12, number);
|
||||||
|
|
||||||
write_x += text_width;
|
return {
|
||||||
|
write_x,
|
||||||
|
write_y,
|
||||||
|
text_width,
|
||||||
|
12
|
||||||
|
};
|
||||||
};
|
};
|
||||||
proc draw_pair = [&](Lisp_Object* pair) {
|
std::function<Drawn_Area(Lisp_Object*)> draw_pair;
|
||||||
|
proc draw_lisp_object = [&](Lisp_Object* obj) -> Drawn_Area {
|
||||||
|
switch (Memory::get_type(obj)) {
|
||||||
|
case Lisp_Object_Type::T: return draw_text("t");
|
||||||
|
case Lisp_Object_Type::Nil: return draw_text("()");
|
||||||
|
case Lisp_Object_Type::Pair: return draw_pair(obj);
|
||||||
|
case Lisp_Object_Type::Number: return draw_float(obj->value.number);
|
||||||
|
case Lisp_Object_Type::Symbol: return draw_text(&obj->value.string->data);
|
||||||
|
case Lisp_Object_Type::Keyword: {
|
||||||
|
Drawn_Area colon = draw_text(":", "#c61b6e");
|
||||||
|
write_x += colon.width;
|
||||||
|
Drawn_Area text = draw_text(&obj->value.identifier->data, "#c61b6e");
|
||||||
|
write_x -= colon.width;
|
||||||
|
return {
|
||||||
|
colon.x,
|
||||||
|
colon.y,
|
||||||
|
colon.width + text.width,
|
||||||
|
colon.height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case Lisp_Object_Type::String: return draw_text(&obj->value.string->data, "#2aa198", true, 20);
|
||||||
|
default: return {0};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
draw_pair = [&](Lisp_Object* pair) -> Drawn_Area {
|
||||||
|
Drawn_Area ret;
|
||||||
|
Drawn_Area child;
|
||||||
|
|
||||||
|
ret.x = write_x;
|
||||||
|
ret.y = write_y;
|
||||||
|
ret.width = 100;
|
||||||
|
ret.height = 100;
|
||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" <rect x='%d' y='%d' width='100' height='50' stroke-width='3' stroke='black' fill='white'/>"
|
" <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'/>",
|
" <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);
|
write_x, write_y, write_x+50, write_y, write_x+50, write_y+50);
|
||||||
|
|
||||||
|
// arrow to first
|
||||||
|
fprintf(f,
|
||||||
|
" <line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='3' stroke='black'/>",
|
||||||
|
write_x+25, write_y+25, write_x+25, write_y+100);
|
||||||
|
|
||||||
|
write_y += 110;
|
||||||
|
child = draw_lisp_object(pair->value.pair.first);
|
||||||
|
if (ret.width < child.width)
|
||||||
|
ret.width = child.width;
|
||||||
|
if (ret.height < child.height)
|
||||||
|
ret.height = child.height;
|
||||||
|
|
||||||
|
write_y -= 110;
|
||||||
|
|
||||||
if (pair->value.pair.rest == Memory::nil) {
|
if (pair->value.pair.rest == Memory::nil) {
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" <line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='3' stroke='black'/>",
|
" <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);
|
write_x+50, write_y+50, write_x+100, write_y);
|
||||||
|
} else {
|
||||||
|
// arrow to rest
|
||||||
|
int x_offset = 150;
|
||||||
|
if (child.width+margin > x_offset)
|
||||||
|
x_offset = child.width+margin;
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
" <line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='3' stroke='black'/>",
|
||||||
|
write_x+75, write_y+25, write_x+75+x_offset, write_y+25);
|
||||||
|
|
||||||
|
write_x += x_offset;
|
||||||
|
ret.width += 50;
|
||||||
|
|
||||||
|
child = draw_lisp_object(pair->value.pair.rest);
|
||||||
|
ret.width += child.width;
|
||||||
|
if (ret.height < 70 + child.height)
|
||||||
|
ret.height = 70 + child.height;
|
||||||
|
|
||||||
|
write_x -= x_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
|
|
||||||
|
if (max_x < ret.x + ret.width)
|
||||||
|
max_x = ret.x + ret.width;
|
||||||
|
if (max_y < ret.y + ret.height)
|
||||||
|
max_y = ret.y + ret.height;
|
||||||
|
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
proc draw_header = [&]() {
|
proc draw_header = [&]() {
|
||||||
proc draw_separator = [&]() {
|
proc draw_separator = [&]() {
|
||||||
@@ -160,8 +263,8 @@ proc visualize_lisp_machine() -> void {
|
|||||||
char date[12];
|
char date[12];
|
||||||
snprintf(date, 12, "%02d.%02d.%d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
snprintf(date, 12, "%02d.%02d.%d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
||||||
|
|
||||||
draw_text("Date: ");
|
write_x += draw_text("Date: ").width;
|
||||||
draw_text(date);
|
write_x += draw_text(date).width;
|
||||||
|
|
||||||
draw_separator();
|
draw_separator();
|
||||||
|
|
||||||
@@ -171,8 +274,8 @@ proc visualize_lisp_machine() -> void {
|
|||||||
char time[12];
|
char time[12];
|
||||||
snprintf(time, 12, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
|
snprintf(time, 12, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||||
|
|
||||||
draw_text("Time: ");
|
write_x += draw_text("Time: ").width;
|
||||||
draw_text(time);
|
write_x += draw_text(time).width;
|
||||||
|
|
||||||
draw_separator();
|
draw_separator();
|
||||||
|
|
||||||
@@ -187,22 +290,22 @@ proc visualize_lisp_machine() -> void {
|
|||||||
}
|
}
|
||||||
int used_string_memory = Memory::string_memory_size - free_string_memory;
|
int used_string_memory = Memory::string_memory_size - free_string_memory;
|
||||||
|
|
||||||
draw_text("String Memory:");
|
write_x += draw_text("String Memory:").width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[allocated chars] ");
|
write_x += draw_text("[allocated chars] ").width;
|
||||||
draw_integer(Memory::string_memory_size);
|
write_x += draw_integer(Memory::string_memory_size).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[free] ");
|
write_x += draw_text("[free] ").width;
|
||||||
draw_integer(free_string_memory);
|
write_x += draw_integer(free_string_memory).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[used] ");
|
write_x += draw_text("[used] ").width;
|
||||||
draw_integer(used_string_memory);
|
write_x += draw_integer(used_string_memory).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[%free] ");
|
write_x += draw_text("[%free] ").width;
|
||||||
draw_float(100.0f * free_string_memory / Memory::string_memory_size);
|
write_x += draw_float(100.0f * free_string_memory / Memory::string_memory_size).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[%used] ");
|
write_x += draw_text("[%used] ").width;
|
||||||
draw_float(100.0f * used_string_memory / Memory::string_memory_size);
|
write_x += draw_float(100.0f * used_string_memory / Memory::string_memory_size).width;
|
||||||
|
|
||||||
draw_separator();
|
draw_separator();
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
@@ -214,22 +317,22 @@ proc visualize_lisp_machine() -> void {
|
|||||||
int free_object_memory_cells = Memory::object_memory_size - (Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index);
|
int free_object_memory_cells = Memory::object_memory_size - (Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index);
|
||||||
int used_object_memory_cells = Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index;
|
int used_object_memory_cells = Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index;
|
||||||
|
|
||||||
draw_text("Object Memory:");
|
write_x += draw_text("Object Memory:").width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[#allocated] ");
|
write_x += draw_text("[#allocated] ").width;
|
||||||
draw_integer(Memory::object_memory_size);
|
write_x += draw_integer(Memory::object_memory_size).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[#free] ");
|
write_x += draw_text("[#free] ").width;
|
||||||
draw_integer(free_object_memory_cells);
|
write_x += draw_integer(free_object_memory_cells).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[#used] ");
|
write_x += draw_text("[#used] ").width;
|
||||||
draw_integer(used_object_memory_cells);
|
write_x += draw_integer(used_object_memory_cells).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[%free] ");
|
write_x += draw_text("[%free] ").width;
|
||||||
draw_float(100.0f * free_object_memory_cells / Memory::object_memory_size);
|
write_x += draw_float(100.0f * free_object_memory_cells / Memory::object_memory_size).width;
|
||||||
draw_margin();
|
draw_margin();
|
||||||
draw_text("[%used] ");
|
write_x += draw_text("[%used] ").width;
|
||||||
draw_float(100.0f * used_object_memory_cells / Memory::object_memory_size);
|
write_x += draw_float(100.0f * used_object_memory_cells / Memory::object_memory_size).width;
|
||||||
|
|
||||||
draw_separator();
|
draw_separator();
|
||||||
|
|
||||||
@@ -241,6 +344,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
Lisp_Object_Array_List* numbers = create_Lisp_Object_array_list();
|
Lisp_Object_Array_List* numbers = create_Lisp_Object_array_list();
|
||||||
Lisp_Object_Array_List* strings = create_Lisp_Object_array_list();
|
Lisp_Object_Array_List* strings = create_Lisp_Object_array_list();
|
||||||
Lisp_Object_Array_List* pairs = create_Lisp_Object_array_list();
|
Lisp_Object_Array_List* pairs = create_Lisp_Object_array_list();
|
||||||
|
Lisp_Object_Array_List* lists = create_Lisp_Object_array_list();
|
||||||
|
|
||||||
// loop over all used memory
|
// loop over all used memory
|
||||||
for (int i = 0; i < Memory::next_index_in_object_memory; ++i) {
|
for (int i = 0; i < Memory::next_index_in_object_memory; ++i) {
|
||||||
@@ -262,13 +366,43 @@ proc visualize_lisp_machine() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the lists-list by filtering the pairs-list.
|
// create the lists-list by filtering the pairs-list.
|
||||||
Lisp_Oject_Array_List* pairs_to_filter = create_Int_array_list();
|
Lisp_Object_Array_List* pairs_to_filter = create_Lisp_Object_array_list();
|
||||||
Int_Array_List* indices_to_filter = create_Int_array_list();
|
Int_Array_List* indices_to_filter = create_Int_array_list();
|
||||||
|
|
||||||
|
// helper lambda:
|
||||||
|
proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List* list) -> void {
|
||||||
|
if (list->next_index == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sort_array_list(list);
|
||||||
|
Int_Array_List* indices_to_filter = create_Int_array_list();
|
||||||
|
|
||||||
|
size_t last = (size_t)list->data[0];
|
||||||
|
for (int i = 1; i < list->next_index; ++i) {
|
||||||
|
if ((size_t)list->data[i] == last)
|
||||||
|
append_to_array_list(indices_to_filter, i);
|
||||||
|
else
|
||||||
|
last = (size_t)list->data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = indices_to_filter->next_index; i >= 0; --i) {
|
||||||
|
remove_index_from_array_list(list, indices_to_filter->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort again as removing items destroys the order
|
||||||
|
sort_array_list(list);
|
||||||
|
};
|
||||||
|
|
||||||
// recursive lambda
|
// recursive lambda
|
||||||
std::function<void(Lisp_Object*)> filter_pair_and_children;
|
std::function<void(Lisp_Object*)> filter_pair_and_children;
|
||||||
filter_pair_and_children = [&](Lisp_Object* pair) {
|
filter_pair_and_children = [&](Lisp_Object* pair) {
|
||||||
|
append_to_array_list(pairs_to_filter, pair);
|
||||||
|
|
||||||
|
if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair)
|
||||||
|
filter_pair_and_children(pair->value.pair.first);
|
||||||
|
|
||||||
|
if (Memory::get_type(pair->value.pair.rest) == Lisp_Object_Type::Pair)
|
||||||
|
filter_pair_and_children(pair->value.pair.rest);
|
||||||
};
|
};
|
||||||
for (int i = 0; i < pairs->next_index; ++i) {
|
for (int i = 0; i < pairs->next_index; ++i) {
|
||||||
if (Memory::get_type(pairs->data[i]->value.pair.first) == Lisp_Object_Type::Pair)
|
if (Memory::get_type(pairs->data[i]->value.pair.first) == Lisp_Object_Type::Pair)
|
||||||
@@ -279,6 +413,15 @@ proc visualize_lisp_machine() -> void {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_doubles_from_lisp_object_array_list(pairs_to_filter);
|
||||||
|
fprintf(stderr, "removing %d pairs\n", pairs_to_filter->next_index);
|
||||||
|
// okay, so pairs_to_filter now only the pairs once each that
|
||||||
|
// we want to filter from the pairs list
|
||||||
|
for (int i = 0; i < pairs->next_index; ++i) {
|
||||||
|
if (sorted_array_list_find(pairs_to_filter, pairs->data[i]) == -1) {
|
||||||
|
append_to_array_list(lists, pairs->data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draw_text("Memory Contents:");
|
draw_text("Memory Contents:");
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
@@ -287,7 +430,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
int start_x = write_x,
|
int start_x = write_x,
|
||||||
start_y = write_y;
|
start_y = write_y;
|
||||||
|
|
||||||
draw_text("Symbols: ");
|
write_x += draw_text("Symbols: ").width;
|
||||||
draw_integer(symbols->next_index);
|
draw_integer(symbols->next_index);
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x;
|
write_x = start_x;
|
||||||
@@ -303,7 +446,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = start_x + 300;
|
write_x = start_x + 300;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Keywords: ");
|
write_x += draw_text("Keywords: ").width;
|
||||||
draw_integer(keywords->next_index);
|
draw_integer(keywords->next_index);
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 300;
|
write_x = start_x + 300;
|
||||||
@@ -312,8 +455,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 300;
|
write_x = start_x + 300;
|
||||||
|
|
||||||
draw_text(":", "#c61b6e");
|
draw_lisp_object(keywords->data[i]);
|
||||||
draw_text(&keywords->data[i]->value.identifier->data, "#c61b6e");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -321,7 +463,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = start_x + 600;
|
write_x = start_x + 600;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Numbers: ");
|
write_x += draw_text("Numbers: ").width;
|
||||||
draw_integer(numbers->next_index);
|
draw_integer(numbers->next_index);
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 600;
|
write_x = start_x + 600;
|
||||||
@@ -336,7 +478,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = start_x + 900;
|
write_x = start_x + 900;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Strings: ");
|
write_x += draw_text("Strings: ").width;
|
||||||
draw_integer(strings->next_index);
|
draw_integer(strings->next_index);
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 900;
|
write_x = start_x + 900;
|
||||||
@@ -352,16 +494,18 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = start_x + 2000;
|
write_x = start_x + 2000;
|
||||||
write_y = start_y;
|
write_y = start_y;
|
||||||
|
|
||||||
draw_text("Pairs: ");
|
write_x += draw_text("Lists, Pairs: ").width;
|
||||||
|
write_x += draw_integer(lists->next_index).width;
|
||||||
|
draw_margin();
|
||||||
draw_integer(pairs->next_index);
|
draw_integer(pairs->next_index);
|
||||||
draw_new_line();
|
draw_new_line();
|
||||||
write_x = start_x + 2000;
|
write_x = start_x + 2000;
|
||||||
|
|
||||||
for (int i = 0; i < pairs->next_index; ++i) {
|
for (int i = 0; i < lists->next_index; ++i) {
|
||||||
draw_new_line(3);
|
draw_new_line(3);
|
||||||
write_x = start_x + 2000;
|
write_x = start_x + 2000;
|
||||||
|
|
||||||
draw_pair(pairs->data[i]);
|
write_y += draw_pair(lists->data[i]).height;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -369,7 +513,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
"<svg xmlns='http://www.w3.org/2000/svg'\n"
|
"<svg xmlns='http://www.w3.org/2000/svg'\n"
|
||||||
" version='1.1' baseProfile='full'\n"
|
" version='1.1' baseProfile='full'\n"
|
||||||
" viewBox='%06d %06d %06d %06d'"
|
" viewBox='%012d %012d %012d %012d'"
|
||||||
">\n\n", -padding, -padding, 0, 0);
|
">\n\n", -padding, -padding, 0, 0);
|
||||||
|
|
||||||
draw_header();
|
draw_header();
|
||||||
@@ -385,6 +529,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
"<svg xmlns='http://www.w3.org/2000/svg'\n"
|
"<svg xmlns='http://www.w3.org/2000/svg'\n"
|
||||||
" version='1.1' baseProfile='full'\n"
|
" version='1.1' baseProfile='full'\n"
|
||||||
" viewBox='%06d %06d %06d %06d'", -padding, -padding, max_x + 2*padding, max_y + 2*padding);
|
" viewBox='%012d %012d %012d %012d'"
|
||||||
|
">", -padding, -padding, max_x + 2*padding, max_y + 2*padding);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user