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_DEPRECATE
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <ctype.h>
|
||||
|
||||
+288
-11
@@ -1,7 +1,17 @@
|
||||
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 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");
|
||||
defer {
|
||||
fclose(f);
|
||||
@@ -18,27 +28,293 @@ proc visualize_lisp_machine() -> void {
|
||||
write_x = 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) {
|
||||
int text_width = 12 * strlen(text);
|
||||
int text_height = 12;
|
||||
// take care of escaping sensitive chars
|
||||
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_y > max_y) max_y = write_y;
|
||||
|
||||
fprintf(f,
|
||||
" <text x='%d' y='%d' font-size='20' "
|
||||
"font-family='monospace'>\n"
|
||||
" %s"
|
||||
"\n </text>\n", write_x, write_y, text);
|
||||
if (extra_needed_chars) {
|
||||
fprintf(f, draw_text_template, write_x, write_y, new_text);
|
||||
free(new_text);
|
||||
} else {
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
// 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);
|
||||
|
||||
draw_header();
|
||||
draw_symbols_keywords_and_numbers();
|
||||
|
||||
fprintf(f, "\n\n</svg>");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user