added symbols to visualization
This commit is contained in:
+1123
-4
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 30 KiB |
@@ -3,6 +3,7 @@
|
|||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_DEPRECATE
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|||||||
+289
-12
@@ -1,7 +1,17 @@
|
|||||||
proc visualize_lisp_machine() -> void {
|
proc visualize_lisp_machine() -> void {
|
||||||
const int padding = 30;
|
fprintf(stderr, "Drawing visualization...");
|
||||||
|
defer {
|
||||||
|
fprintf(stderr, "Done!\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
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_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";
|
||||||
|
|
||||||
|
|
||||||
FILE *f = fopen("visualization.svg", "w");
|
FILE *f = fopen("visualization.svg", "w");
|
||||||
defer {
|
defer {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@@ -18,27 +28,293 @@ proc visualize_lisp_machine() -> void {
|
|||||||
write_x = 0,
|
write_x = 0,
|
||||||
write_y = 0;
|
write_y = 0;
|
||||||
|
|
||||||
|
|
||||||
|
proc draw_margin = [&](int count = 1) {
|
||||||
|
write_x += margin * count;
|
||||||
|
};
|
||||||
|
proc draw_new_line = [&](int count = 1) {
|
||||||
|
write_x = 0;
|
||||||
|
write_y += 25 * count;
|
||||||
|
};
|
||||||
proc draw_text = [&](const char* text) {
|
proc draw_text = [&](const char* text) {
|
||||||
int text_width = 12 * strlen(text);
|
// take care of escaping sensitive chars
|
||||||
int text_height = 12;
|
int text_length = 0;
|
||||||
|
int extra_needed_chars = 0;
|
||||||
|
char* new_text;
|
||||||
|
|
||||||
|
char source;
|
||||||
|
while ((source = text[text_length++]) != '\0') {
|
||||||
|
switch (source) {
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
extra_needed_chars += 3;
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
extra_needed_chars += 4;
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
case '"':
|
||||||
|
extra_needed_chars += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we need to replace some chars
|
||||||
|
if (extra_needed_chars > 0) {
|
||||||
|
new_text = (char*)malloc((text_length + extra_needed_chars) * sizeof(char));
|
||||||
|
|
||||||
|
int index_in_text = 0,
|
||||||
|
index_in_new_text = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_text[index_in_new_text] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_width = 12 * text_length;
|
||||||
|
|
||||||
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,
|
if (extra_needed_chars) {
|
||||||
" <text x='%d' y='%d' font-size='20' "
|
fprintf(f, draw_text_template, write_x, write_y, new_text);
|
||||||
"font-family='monospace'>\n"
|
free(new_text);
|
||||||
" %s"
|
} else {
|
||||||
"\n </text>\n", write_x, write_y, text);
|
fprintf(f, draw_text_template, write_x, write_y, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_x += text_width;
|
||||||
|
};
|
||||||
|
proc draw_integer = [&](int number) {
|
||||||
|
int text_width = 12 * ((int)log10(number)+1);
|
||||||
|
|
||||||
|
if (write_x + text_width > max_x) max_x = write_x + text_width;
|
||||||
|
if (write_y > max_y) max_y = write_y;
|
||||||
|
|
||||||
|
fprintf(f, draw_integer_template, write_x, write_y, number);
|
||||||
|
|
||||||
|
write_x += text_width;
|
||||||
|
};
|
||||||
|
proc draw_float = [&](float number) {
|
||||||
|
int text_width = 12 * 12;
|
||||||
|
|
||||||
|
if (write_x + text_width > max_x) max_x = write_x + text_width;
|
||||||
|
if (write_y > max_y) max_y = write_y;
|
||||||
|
|
||||||
|
fprintf(f, draw_float_template, write_x, write_y, number);
|
||||||
|
|
||||||
write_x += text_width;
|
write_x += text_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
proc draw_header = [&](){
|
proc draw_header = [&]() {
|
||||||
|
proc draw_separator = [&]() {
|
||||||
|
draw_margin();
|
||||||
|
draw_text("|");
|
||||||
|
draw_margin();
|
||||||
|
};
|
||||||
|
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm tm = *localtime(&t);
|
||||||
|
|
||||||
write_y = 12;
|
write_y = 12;
|
||||||
// draw_text("ASD");
|
|
||||||
// write_x += margin;
|
// -------------------
|
||||||
draw_text("doeun");
|
// Date
|
||||||
|
// -------------------
|
||||||
|
char date[12];
|
||||||
|
snprintf(date, 12, "%02d.%02d.%d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
||||||
|
|
||||||
|
draw_text("Date: ");
|
||||||
|
draw_text(date);
|
||||||
|
|
||||||
|
draw_separator();
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Time
|
||||||
|
// -------------------
|
||||||
|
char time[12];
|
||||||
|
snprintf(time, 12, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||||
|
|
||||||
|
draw_text("Time: ");
|
||||||
|
draw_text(time);
|
||||||
|
|
||||||
|
draw_separator();
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// String Memory
|
||||||
|
// -------------------
|
||||||
|
draw_new_line();
|
||||||
|
|
||||||
|
int free_string_memory = Memory::next_free_spot_in_string_memory - Memory::string_memory;
|
||||||
|
for (int i = 0; i < Memory::free_spots_in_string_memory->next_index; ++i) {
|
||||||
|
free_string_memory += ((String*)(Memory::free_spots_in_string_memory->data[i]))->length;
|
||||||
|
}
|
||||||
|
int used_string_memory = Memory::string_memory_size - free_string_memory;
|
||||||
|
|
||||||
|
draw_text("String Memory:");
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[allocated chars] ");
|
||||||
|
draw_integer(Memory::string_memory_size);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[free] ");
|
||||||
|
draw_integer(free_string_memory);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[used] ");
|
||||||
|
draw_integer(used_string_memory);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[%free] ");
|
||||||
|
draw_float(100.0f * free_string_memory / Memory::string_memory_size);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[%used] ");
|
||||||
|
draw_float(100.0f * used_string_memory / Memory::string_memory_size);
|
||||||
|
|
||||||
|
draw_separator();
|
||||||
|
draw_new_line();
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Object Memory
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
draw_text("Object Memory:");
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[#allocated] ");
|
||||||
|
draw_integer(Memory::object_memory_size);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[#free] ");
|
||||||
|
draw_integer(free_object_memory_cells);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[#used] ");
|
||||||
|
draw_integer(used_object_memory_cells);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[%free] ");
|
||||||
|
draw_float(100.0f * free_object_memory_cells / Memory::object_memory_size);
|
||||||
|
draw_margin();
|
||||||
|
draw_text("[%used] ");
|
||||||
|
draw_float(100.0f * used_object_memory_cells / Memory::object_memory_size);
|
||||||
|
|
||||||
|
draw_separator();
|
||||||
|
|
||||||
|
draw_new_line();
|
||||||
|
draw_new_line();
|
||||||
|
draw_new_line();
|
||||||
|
};
|
||||||
|
proc draw_symbols_keywords_and_numbers = [&]() {
|
||||||
|
Lisp_Object_Array_List* symbols = create_Lisp_Object_array_list();
|
||||||
|
Lisp_Object_Array_List* keywords = 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* pairs = create_Lisp_Object_array_list();
|
||||||
|
|
||||||
|
// loop over all used memory
|
||||||
|
for (int i = 0; i < Memory::next_index_in_object_memory; ++i) {
|
||||||
|
for (int j = 0; j < Memory::free_spots_in_object_memory->next_index; ++j) {
|
||||||
|
if (i == Memory::free_spots_in_object_memory->data[j])
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Memory::get_type(Memory::object_memory+i)) {
|
||||||
|
case Lisp_Object_Type::Symbol: append_to_array_list(symbols, Memory::object_memory+i); break;
|
||||||
|
case Lisp_Object_Type::String: append_to_array_list(strings, 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::Pair : append_to_array_list(pairs, Memory::object_memory+i); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
next: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_text("Memory Contents:");
|
||||||
|
draw_new_line();
|
||||||
|
draw_new_line();
|
||||||
|
|
||||||
|
int start_x = write_x,
|
||||||
|
start_y = write_y;
|
||||||
|
|
||||||
|
draw_text("Symbols: ");
|
||||||
|
draw_integer(symbols->next_index);
|
||||||
|
|
||||||
|
for (int i = 0; i < symbols->next_index; ++i) {
|
||||||
|
draw_new_line();
|
||||||
|
write_x = start_x;
|
||||||
|
|
||||||
|
draw_text(&symbols->data[i]->value.identifier->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
write_x = start_x + 300;
|
||||||
|
write_y = start_y;
|
||||||
|
|
||||||
|
draw_text("Keywords: ");
|
||||||
|
draw_integer(keywords->next_index);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
write_x = start_x + 600;
|
||||||
|
write_y = start_y;
|
||||||
|
|
||||||
|
draw_text("Numbers: ");
|
||||||
|
draw_integer(numbers->next_index);
|
||||||
|
|
||||||
|
write_x = start_x + 900;
|
||||||
|
write_y = start_y;
|
||||||
|
|
||||||
|
draw_text("Strings: ");
|
||||||
|
draw_integer(strings->next_index);
|
||||||
|
|
||||||
|
write_x = start_x + 1200;
|
||||||
|
write_y = start_y;
|
||||||
|
|
||||||
|
draw_text("Pairs: ");
|
||||||
|
draw_integer(pairs->next_index);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,6 +326,7 @@ proc visualize_lisp_machine() -> void {
|
|||||||
">\n\n", -padding, -padding, 0, 0);
|
">\n\n", -padding, -padding, 0, 0);
|
||||||
|
|
||||||
draw_header();
|
draw_header();
|
||||||
|
draw_symbols_keywords_and_numbers();
|
||||||
|
|
||||||
fprintf(f, "\n\n</svg>");
|
fprintf(f, "\n\n</svg>");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user