|
|
|
@@ -7,7 +7,7 @@ proc visualize_lisp_machine() -> void { |
|
|
|
const int padding = 40; |
|
|
|
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_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_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, |
|
|
|
" <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_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<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_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</svg>"); |
|
|
|
|
|
|
|
|