Просмотр исходного кода

better arguments struct, arraylists as values, fixed docgen

master
Felix Brendel 7 лет назад
Родитель
Сommit
5a117d94ee
21 измененных файлов: 1243 добавлений и 425 удалений
  1. +4
    -11
      build.bat
  2. +873
    -56
      manual/built-in-docs.org
  3. +30
    -25
      src/built_ins.cpp
  4. +25
    -25
      src/defines.cpp
  5. +52
    -55
      src/docgeneration.cpp
  6. +12
    -12
      src/env.cpp
  7. +4
    -2
      src/error.cpp
  8. +33
    -30
      src/eval.cpp
  9. +7
    -3
      src/forward_decls.cpp
  10. +20
    -8
      src/gc.cpp
  11. +4
    -4
      src/io.cpp
  12. +10
    -16
      src/lisp_object.cpp
  13. +3
    -1
      src/main.cpp
  14. +31
    -31
      src/memory.cpp
  15. +12
    -12
      src/parse.cpp
  16. +0
    -0
     
  17. +0
    -1
      src/slime.h
  18. +18
    -26
      src/structs.cpp
  19. +46
    -52
      src/testing.cpp
  20. +55
    -55
      src/visualization.cpp
  21. +4
    -0
      vs/slime.vcxproj

+ 4
- 11
build.bat Просмотреть файл

@@ -1,28 +1,21 @@
@echo off @echo off
@setlocal @setlocal
pushd %~dp0
pushd %~dp0\bin


set exeName=slime.exe set exeName=slime.exe


pushd bin

taskkill /F /IM %exeName% > NUL 2> NUL taskkill /F /IM %exeName% > NUL 2> NUL


echo ---------- Compiling ---------- echo ---------- Compiling ----------
call ..\timecmd cl ../src/main.cpp /D_DEBUG /Zi /std:c++latest /Fe%exeName% /W3 /wd4003 /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib
call ..\timecmd cl ../src/main.cpp /D_PROFILING /D_DEBUG /D_DONT_BREAK_ON_ERRORS /Zi /std:c++latest /Fe%exeName% /W3 /wd4003 /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib
rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc


popd
if %errorlevel% == 0 ( if %errorlevel% == 0 (
echo. echo.
echo ---- Running Tests ---- echo ---- Running Tests ----
echo. echo.
call timecmd bin\slime.exe --run-tests
echo.
echo ---- Genderating Docs ----
echo.
call timecmd bin\slime generate-docs.slime

call timecmd slime.exe --run-tests
) else ( ) else (
echo. echo.
echo Fuckin' ell echo Fuckin' ell


+ 873
- 56
manual/built-in-docs.org
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 30
- 25
src/built_ins.cpp Просмотреть файл

@@ -54,19 +54,24 @@ proc built_in_load(String* file_name) -> Lisp_Object* {
file_content = read_entire_file(fullpath); file_content = read_entire_file(fullpath);


if (!file_content) { if (!file_content) {
create_generic_error("The file '%s' was not found "
"(neither in the cwd nor in slime's bin dir)",
Memory::get_c_str(file_name));
char* cwd = get_cwd();
defer {
free(cwd);
};
create_generic_error("The file to load '%s' was not found: "
"neither in the cwd (%s) "
"nor in slime's exe dir (%s)",
Memory::get_c_str(file_name), cwd, fullpath);
return nullptr; return nullptr;
} }
} }


Lisp_Object* result = Memory::nil; Lisp_Object* result = Memory::nil;
Lisp_Object_Array_List* program;
Lisp_Object_Array_List program;
try program = Parser::parse_program(Memory::create_string(fullpath), file_content); try program = Parser::parse_program(Memory::create_string(fullpath), file_content);


for (int i = 0; i < program->next_index; ++i) {
try result = eval_expr(program->data[i]);
for (int i = 0; i < program.next_index; ++i) {
try result = eval_expr(program.data[i]);
} }
return result; return result;
} }
@@ -75,7 +80,7 @@ proc built_in_import(String* file_name) -> Lisp_Object* {
// create new empty environment // create new empty environment
Environment* new_env; Environment* new_env;
try new_env = Memory::create_child_environment(get_root_environment()); try new_env = Memory::create_child_environment(get_root_environment());
append_to_array_list(get_current_environment()->parents, new_env);
append_to_array_list(&get_current_environment()->parents, new_env);


push_environment(new_env); push_environment(new_env);
defer { defer {
@@ -130,9 +135,9 @@ proc load_built_ins_into_environment() -> void {
parse_argument_list(arguments->value.pair.first, &ret->value.function); parse_argument_list(arguments->value.pair.first, &ret->value.function);
} }
} else { } else {
ret->value.function.positional_arguments = create_positional_argument_list(1);
ret->value.function.keyword_arguments = create_keyword_argument_list(1);
ret->value.function.rest_argument = nullptr;
ret->value.function.args.positional = create_positional_argument_list(1);
ret->value.function.args.keyword = create_keyword_argument_list(1);
ret->value.function.args.rest = nullptr;
} }


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
@@ -948,39 +953,39 @@ proc load_built_ins_into_environment() -> void {


printf("Arguments:\n==========\n"); printf("Arguments:\n==========\n");
printf("Postitional: {"); printf("Postitional: {");
if (fun->value.function.positional_arguments->next_index != 0) {
if (fun->value.function.args.positional.symbols.next_index != 0) {
printf("%s", printf("%s",
Memory::get_c_str(fun->value.function.positional_arguments->symbols[0]->value.symbol.identifier));
for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) {
Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier));
for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) {
printf(", %s", printf(", %s",
Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier));
Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier));
} }
} }
printf("}\n"); printf("}\n");
printf("Keyword: {"); printf("Keyword: {");
if (fun->value.function.keyword_arguments->values->next_index != 0) {
if (fun->value.function.args.keyword.values.next_index != 0) {
printf("%s", printf("%s",
Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[0]->value.symbol.identifier));
if (fun->value.function.keyword_arguments->values->data[0]) {
Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier));
if (fun->value.function.args.keyword.values.data[0]) {
printf(" ("); printf(" (");
print(fun->value.function.keyword_arguments->values->data[0]);
print(fun->value.function.args.keyword.values.data[0]);
printf(")"); printf(")");
} }
for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) {
for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) {
printf(", %s", printf(", %s",
Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier));
if (fun->value.function.keyword_arguments->values->data[i]) {
Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier));
if (fun->value.function.args.keyword.values.data[i]) {
printf(" ("); printf(" (");
print(fun->value.function.keyword_arguments->values->data[i]);
print(fun->value.function.args.keyword.values.data[i]);
printf(")"); printf(")");
} }
} }
} }
printf("}\n"); printf("}\n");
printf("Rest: {"); printf("Rest: {");
if (fun->value.function.rest_argument)
if (fun->value.function.args.rest)
printf("%s", printf("%s",
Memory::get_c_str(fun->value.function.rest_argument));
Memory::get_c_str(fun->value.function.args.rest));
printf("}\n"); printf("}\n");


} }
@@ -1014,7 +1019,7 @@ proc load_built_ins_into_environment() -> void {
try assert_arguments_length(1, arguments_length); try assert_arguments_length(1, arguments_length);
try assert_type(arguments->value.pair.first, Lisp_Object_Type::String); try assert_type(arguments->value.pair.first, Lisp_Object_Type::String);


generate_docs(arguments->value.pair.first->value.string);
try generate_docs(arguments->value.pair.first->value.string);


return Memory::t; return Memory::t;
}); });


+ 25
- 25
src/defines.cpp Просмотреть файл

@@ -37,8 +37,9 @@
} \ } \
else label(body,__LINE__): else label(body,__LINE__):


#define try_void try_or_else_return()
#define try try_or_else_return(0)
#define try_struct try_or_else_return({})
#define try_void try_or_else_return()
#define try try_or_else_return(0)


#define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false)
#define ignore_logging fluid_let(Globals::log_level, Log_Level::None) #define ignore_logging fluid_let(Globals::log_level, Log_Level::None)
@@ -53,16 +54,17 @@
\ \
proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \ proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \
arraylist->data[index] = \ arraylist->data[index] = \
arraylist->data[--arraylist->next_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) { \
arraylist->length *= 2; \
arraylist->data = \
if (arraylist->next_index == arraylist->length) { \
arraylist->length *= 2; \
arraylist->data = \
(type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \ (type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
} \ } \
arraylist->data[arraylist->next_index++] = element; \
arraylist->data[arraylist->next_index] = element; \
arraylist->next_index++; \
} \ } \
\ \
proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \ proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \
@@ -99,7 +101,7 @@
\ \
proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \ proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \
if (left == -1) { \ if (left == -1) { \
sort_array_list(arraylist, 0, arraylist->next_index - 1); \
sort_array_list(arraylist, 0, arraylist->next_index - 1); \
return; \ return; \
} else if (left == right) { \ } else if (left == right) { \
return; \ return; \
@@ -107,17 +109,17 @@
\ \
int middle = left + (right-left) / 2; \ int middle = left + (right-left) / 2; \
\ \
sort_array_list(arraylist, left, middle); \
sort_array_list(arraylist, middle+1, right); \
sort_array_list(arraylist, left, middle); \
sort_array_list(arraylist, middle+1, right); \
\ \
_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 { \ proc sorted_array_list_find(name##_Array_List* arraylist, type elem, int left=-1, int right=-1) -> int { \
if (left == -1) { \ if (left == -1) { \
return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \ return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \
} else if (left == right) { \ } else if (left == right) { \
if ((size_t)arraylist->data[left] == (size_t)elem) \
if ((size_t)arraylist->data[left] == (size_t)elem) \
return left; \ return left; \
return -1; \ return -1; \
} else if (right < left) \ } else if (right < left) \
@@ -125,18 +127,18 @@
\ \
int middle = left + (right-left) / 2; \ int middle = left + (right-left) / 2; \
\ \
if ((size_t)arraylist->data[middle] < (size_t)elem) \
if ((size_t)arraylist->data[middle] < (size_t)elem) \
return sorted_array_list_find(arraylist, elem, middle+1, right); \ return sorted_array_list_find(arraylist, elem, middle+1, right); \
if ((size_t)arraylist->data[middle] > (size_t)elem) \
if ((size_t)arraylist->data[middle] > (size_t)elem) \
return sorted_array_list_find(arraylist, elem, left, middle-1); \ return sorted_array_list_find(arraylist, elem, left, middle-1); \
return middle; \ return middle; \
} \ } \
\ \
proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List* { \
name##_Array_List* ret = new(name##_Array_List); \
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
ret->next_index = 0; \
ret->length = initial_capacity; \
proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List { \
name##_Array_List ret; \
ret.data = (type*)malloc(initial_capacity * sizeof(type)); \
ret.next_index = 0; \
ret.length = initial_capacity; \
return ret; \ return ret; \
} }


@@ -145,13 +147,11 @@
* iterate over array lists * iterate over array lists
*/ */
#define for_array_list(l) \ #define for_array_list(l) \
if (!l); \
if (int it_index = 0); \
else \ else \
if (int it_index = 0); \
else \
for (auto it = l->data[0]; \
it_index < l->next_index; \
it=l->data[++it_index])
for (auto it = (l).data[0]; \
it_index < (l).next_index; \
it=(l).data[++it_index])


/* /*
* iterate over lisp vectors * iterate over lisp vectors


+ 52
- 55
src/docgeneration.cpp Просмотреть файл

@@ -1,41 +1,38 @@
proc generate_docs(String* path) -> void { proc generate_docs(String* path) -> void {
// save the current working directory
char* cwd = get_cwd();
// get the direction of the exe
char* exe_path = get_exe_dir();
change_cwd(exe_path);

defer {
// switch back to the users directory
change_cwd(cwd);
free(exe_path);
free(cwd);
};

FILE *f = fopen(Memory::get_c_str(path), "w"); FILE *f = fopen(Memory::get_c_str(path), "w");
if (!f) { if (!f) {
create_generic_error("The file for writing the documentation "
"could not be opened for writing.");
create_generic_error("The file for writing the documentation (%s) "
"could not be opened for writing.", Memory::get_c_str(path));
return; return;
} }
defer { defer {
fclose(f); fclose(f);
}; };


Environment_Array_List* visited = create_Environment_array_list();
Environment_Array_List visited = create_Environment_array_list();


// recursive inner funciton
std::function<void(Environment*, char* prefix)> print_this_env; std::function<void(Environment*, char* prefix)> print_this_env;
print_this_env = [&](Environment* env, char* prefix) -> void { print_this_env = [&](Environment* env, char* prefix) -> void {
bool we_already_printed = false; bool we_already_printed = false;
// TODO(Felix): Make a generic array_list_contains function // TODO(Felix): Make a generic array_list_contains function
for (int i = 0; i < visited->next_index; ++i) {
if (visited->data[i] == env) {
for_array_list(visited) {
if (it == env) {
we_already_printed = true; we_already_printed = true;
break; break;
} }
} }
if (!we_already_printed) { if (!we_already_printed) {
append_to_array_list(visited, env);
printf("Working ion env::::");
print_environment(env);
printf("\n--------------------------------\n");
append_to_array_list(&visited, env);

push_environment(env);
defer {
pop_environment();
};

for (int i = 0; i < env->next_index; ++i) { for (int i = 0; i < env->next_index; ++i) {
fprintf(f, "\\hrule\n* =%s%s= \n" fprintf(f, "\\hrule\n* =%s%s= \n"
// " :PROPERTIES:\n" // " :PROPERTIES:\n"
@@ -46,10 +43,10 @@ proc generate_docs(String* path) -> void {
* sourcecodeLocation * sourcecodeLocation
*/ */
if (env->values[i]->sourceCodeLocation) { if (env->values[i]->sourceCodeLocation) {
fprintf(f, "\n - defined in :: =%s:%d:%d=",
Memory::get_c_str(env->values[i]->sourceCodeLocation->file),
env->values[i]->sourceCodeLocation->line,
env->values[i]->sourceCodeLocation->column);
try_void fprintf(f, "\n - defined in :: =%s:%d:%d=",
Memory::get_c_str(env->values[i]->sourceCodeLocation->file),
env->values[i]->sourceCodeLocation->line,
env->values[i]->sourceCodeLocation->column);
} }
/* /*
* type * type
@@ -57,8 +54,8 @@ proc generate_docs(String* path) -> void {
Lisp_Object_Type type = Memory::get_type(env->values[i]); Lisp_Object_Type type = Memory::get_type(env->values[i]);
Lisp_Object* LOtype; Lisp_Object* LOtype;
try_void LOtype = eval_expr(Memory::create_list( try_void LOtype = eval_expr(Memory::create_list(
Memory::get_or_create_lisp_object_symbol("type"),
env->values[i]));
Memory::get_or_create_lisp_object_symbol("type"),
env->values[i]));


fprintf(f, "\n - type :: ="); fprintf(f, "\n - type :: =");
print(LOtype, true, f); print(LOtype, true, f);
@@ -89,43 +86,43 @@ proc generate_docs(String* path) -> void {
Lisp_Object* fun = env->values[i]; Lisp_Object* fun = env->values[i];
bool printed_at_least_some_args = false; bool printed_at_least_some_args = false;
fprintf(f, "\n - arguments :: "); fprintf(f, "\n - arguments :: ");
if (fun->value.function.positional_arguments->next_index != 0) {
if (fun->value.function.args.positional.symbols.next_index != 0) {
if (!printed_at_least_some_args) if (!printed_at_least_some_args)
fprintf(f, ":"); fprintf(f, ":");
fprintf(f, "\n - postitional :: "); fprintf(f, "\n - postitional :: ");
fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[0]->value.symbol.identifier));
for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) {
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier));
try_void fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier));
for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) {
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier));
} }
} }
if (fun->value.function.keyword_arguments->values->next_index != 0) {
if (fun->value.function.args.keyword.values.next_index != 0) {
if (!printed_at_least_some_args) if (!printed_at_least_some_args)
fprintf(f, ":"); fprintf(f, ":");
fprintf(f, "\n - keyword :: "); fprintf(f, "\n - keyword :: ");
fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[0]->value.symbol.identifier));
if (fun->value.function.keyword_arguments->values->data[0]) {
fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier));
if (fun->value.function.args.keyword.values.data[0]) {
fprintf(f, " =("); fprintf(f, " =(");
print(fun->value.function.keyword_arguments->values->data[0], true, f);
print(fun->value.function.args.keyword.values.data[0], true, f);
fprintf(f, ")="); fprintf(f, ")=");
} }
for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) {
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier));
if (fun->value.function.keyword_arguments->values->data[i]) {
for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) {
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier));
if (fun->value.function.args.keyword.values.data[i]) {
fprintf(f, " =("); fprintf(f, " =(");
print(fun->value.function.keyword_arguments->values->data[i], true, f);
print(fun->value.function.args.keyword.values.data[i], true, f);
fprintf(f, ")="); fprintf(f, ")=");
} }
} }
} }
if (fun->value.function.rest_argument) {
if (fun->value.function.args.rest) {
if (!printed_at_least_some_args) if (!printed_at_least_some_args)
fprintf(f, ":"); fprintf(f, ":");
fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument));
fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.args.rest->value.symbol.identifier));
} }
// if no args at all // if no args at all
if (fun->value.function.positional_arguments->next_index == 0 &&
fun->value.function.keyword_arguments->values->next_index == 0 &&
!fun->value.function.rest_argument)
if (fun->value.function.args.positional.symbols.next_index == 0 &&
fun->value.function.args.keyword.values.next_index == 0 &&
!fun->value.function.args.rest)
{ {
fprintf(f, "none."); fprintf(f, "none.");
} }
@@ -137,22 +134,22 @@ proc generate_docs(String* path) -> void {
else else
fprintf(f, "none\n"); fprintf(f, "none\n");


if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function &&
env->values[i]->userType &&
(string_equal(env->values[i]->userType->value.symbol.identifier, "package") ||
string_equal(env->values[i]->userType->value.symbol.identifier, "constructor")))
{
char new_prefix[200];
strcpy(new_prefix, prefix);
strcat(new_prefix, env->keys[i]);
strcat(new_prefix, " ");
print_this_env(env->values[i]->value.function.parent_environment, new_prefix);
}
// if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function &&
// env->values[i]->userType &&
// (string_equal(env->values[i]->userType->value.symbol.identifier, "package") ||
// string_equal(env->values[i]->userType->value.symbol.identifier, "constructor")))
// {
// char new_prefix[200];
// strcpy(new_prefix, prefix);
// strcat(new_prefix, env->keys[i]);
// strcat(new_prefix, " ");
// print_this_env(env->values[i]->value.function.parent_environment, new_prefix);
// }
} }
} }


for (int i = 0; i < env->parents->next_index; ++i) {
print_this_env(env->parents->data[i], prefix);
for (int i = 0; i < env->parents.next_index; ++i) {
print_this_env(env->parents.data[i], prefix);
} }
}; };




+ 12
- 12
src/env.cpp Просмотреть файл

@@ -31,9 +31,9 @@ proc environment_binds_symbol(String* identifier, Environment* env) -> bool {
proc find_binding_environment(String* identifier, Environment* env) -> Environment* { proc find_binding_environment(String* identifier, Environment* env) -> Environment* {
if (environment_binds_symbol(identifier, env)) if (environment_binds_symbol(identifier, env))
return env; return env;
for (int i = 0; i < env->parents->next_index; ++i) {
if (environment_binds_symbol(identifier, env->parents->data[i]))
return env->parents->data[i];
for (int i = 0; i < env->parents.next_index; ++i) {
if (environment_binds_symbol(identifier, env->parents.data[i]))
return env->parents.data[i];
} }
return get_root_environment(); return get_root_environment();
} }
@@ -46,8 +46,8 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
if (result) if (result)
return result; return result;


for (int i = 0; i < env->parents->next_index; ++i) {
result = try_lookup_symbol(node, env->parents->data[i]);
for (int i = 0; i < env->parents.next_index; ++i) {
result = try_lookup_symbol(node, env->parents.data[i]);


if (result) if (result)
return result; return result;
@@ -65,22 +65,22 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {


inline proc push_environment(Environment* env) -> void { inline proc push_environment(Environment* env) -> void {
using namespace Globals::Current_Execution; using namespace Globals::Current_Execution;
append_to_array_list(envi_stack, env);
append_to_array_list(&envi_stack, env);
} }


inline proc pop_environment() -> void { inline proc pop_environment() -> void {
using namespace Globals::Current_Execution; using namespace Globals::Current_Execution;
--envi_stack->next_index;
--envi_stack.next_index;
} }


inline proc get_root_environment() -> Environment* { inline proc get_root_environment() -> Environment* {
using namespace Globals::Current_Execution; using namespace Globals::Current_Execution;
return envi_stack->data[0];
return envi_stack.data[0];
} }


inline proc get_current_environment() -> Environment* { inline proc get_current_environment() -> Environment* {
using namespace Globals::Current_Execution; using namespace Globals::Current_Execution;
return envi_stack->data[envi_stack->next_index-1];
return envi_stack.data[envi_stack.next_index-1];
} }


proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
@@ -115,11 +115,11 @@ proc print_environment_indent(Environment* env, int indent) -> void {
printf(" (%lld)", (long long)env->values[i]); printf(" (%lld)", (long long)env->values[i]);
puts(""); puts("");
} }
for (int i = 0; i < env->parents->next_index; ++i) {
for (int i = 0; i < env->parents.next_index; ++i) {
print_indent(indent); print_indent(indent);
printf("parent (%lld)", (long long)env->parents->data[i]);
printf("parent (%lld)", (long long)env->parents.data[i]);
puts(":"); puts(":");
print_environment_indent(env->parents->data[i], indent+4);
print_environment_indent(env->parents.data[i], indent+4);
} }
} }




+ 4
- 2
src/error.cpp Просмотреть файл

@@ -9,8 +9,10 @@ proc delete_error() -> void {


proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void { proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void {


if (Globals::log_level > Log_Level::None)
printf("Error created in:\n%s:%d\n", c_file_name, c_file_line);
if (Globals::log_level > Log_Level::None) {
printf("Error created in:\n %s:%d\n", c_file_name, c_file_line);
printf(" -> %s\n", Memory::get_c_str(message));
}


delete_error(); delete_error();
if (Globals::breaking_on_errors) { if (Globals::breaking_on_errors) {


+ 33
- 30
src/eval.cpp Просмотреть файл

@@ -9,19 +9,19 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
}; };


Lisp_Object* sym, *val; // used as temp storage to use `try` Lisp_Object* sym, *val; // used as temp storage to use `try`
String_Array_List* read_in_keywords;
String_Array_List read_in_keywords;
int obligatory_keywords_count = 0; int obligatory_keywords_count = 0;
int read_obligatory_keywords_count = 0; int read_obligatory_keywords_count = 0;


proc read_positional_args = [&]() -> void { proc read_positional_args = [&]() -> void {
for (int i = 0; i < function->positional_arguments->next_index; ++i) {
for (int i = 0; i < function->args.positional.symbols.next_index; ++i) {
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) { if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i);
create_wrong_number_of_arguments_error(function->args.positional.symbols.next_index, i);
return; return;
} }
// NOTE(Felix): We have to copy all the arguments, otherwise // NOTE(Felix): We have to copy all the arguments, otherwise
// we change the program code. // we change the program code.
try_void sym = function->positional_arguments->symbols[i];
try_void sym = function->args.positional.symbols.data[i];
define_symbol( define_symbol(
sym, sym,
Memory::copy_lisp_object_except_pairs(arguments->value.pair.first)); Memory::copy_lisp_object_except_pairs(arguments->value.pair.first));
@@ -41,8 +41,8 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
return; return;


// find out how many keyword args we /have/ to read // find out how many keyword args we /have/ to read
for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) {
if (function->keyword_arguments->values->data[i] == nullptr)
for (int i = 0; i < function->args.keyword.values.next_index; ++i) {
if (function->args.keyword.values.data[i] == nullptr)
++obligatory_keywords_count; ++obligatory_keywords_count;
else else
break; break;
@@ -52,10 +52,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) { while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
// check if this one is even an accepted keyword // check if this one is even an accepted keyword
bool accepted = false; bool accepted = false;
for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) {
for (int i = 0; i < function->args.keyword.values.next_index; ++i) {
if (string_equal( if (string_equal(
arguments->value.pair.first->value.symbol.identifier, arguments->value.pair.first->value.symbol.identifier,
function->keyword_arguments->keywords->data[i]->value.symbol.identifier))
function->args.keyword.keywords.data[i]->value.symbol.identifier))
{ {
accepted = true; accepted = true;
break; break;
@@ -77,10 +77,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
} }


// check if it was already read in // check if it was already read in
for (int i = 0; i < read_in_keywords->next_index; ++i) {
for (int i = 0; i < read_in_keywords.next_index; ++i) {
if (string_equal( if (string_equal(
arguments->value.pair.first->value.symbol.identifier, arguments->value.pair.first->value.symbol.identifier,
read_in_keywords->data[i]))
read_in_keywords.data[i]))
{ {
// NOTE(Felix): if we are actually done with all the // NOTE(Felix): if we are actually done with all the
// necessary keywords then we have to count the rest // necessary keywords then we have to count the rest
@@ -112,7 +112,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
sym, sym,
Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first)); Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first));


append_to_array_list(read_in_keywords, arguments->value.pair.first->value.symbol.identifier);
append_to_array_list(&read_in_keywords, arguments->value.pair.first->value.symbol.identifier);
++read_obligatory_keywords_count; ++read_obligatory_keywords_count;


// overstep both for next one // overstep both for next one
@@ -126,20 +126,20 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->


proc check_keyword_args = [&]() -> void { proc check_keyword_args = [&]() -> void {
// check if all necessary keywords have been read in // check if all necessary keywords have been read in
for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) {
String* defined_keyword = function->keyword_arguments->keywords->data[i]->value.symbol.identifier;
for (int i = 0; i < function->args.keyword.values.next_index; ++i) {
String* defined_keyword = function->args.keyword.keywords.data[i]->value.symbol.identifier;
bool was_set = false; bool was_set = false;
for (int j = 0; j < read_in_keywords->next_index; ++j) {
for (int j = 0; j < read_in_keywords.next_index; ++j) {
// TODO(Felix): Later compare the keywords, not their strings!! // TODO(Felix): Later compare the keywords, not their strings!!
if (string_equal( if (string_equal(
read_in_keywords->data[j],
read_in_keywords.data[j],
defined_keyword)) defined_keyword))
{ {
was_set = true; was_set = true;
break; break;
} }
} }
if (function->keyword_arguments->values->data[i] == nullptr) {
if (function->args.keyword.values.data[i] == nullptr) {
// if this one does not have a default value // if this one does not have a default value
if (!was_set) { if (!was_set) {
create_generic_error( create_generic_error(
@@ -153,7 +153,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
// to use it or if the user supplied his own // to use it or if the user supplied his own
if (!was_set) { if (!was_set) {
try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword); try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword);
try_void val = Memory::copy_lisp_object_except_pairs(function->keyword_arguments->values->data[i]);
try_void val = Memory::copy_lisp_object_except_pairs(function->args.keyword.values.data[i]);
define_symbol(sym, val); define_symbol(sym, val);
} }
} }
@@ -162,13 +162,13 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->


proc read_rest_arg = [&]() -> void { proc read_rest_arg = [&]() -> void {
if (arguments == Memory::nil) { if (arguments == Memory::nil) {
if (function->rest_argument) {
define_symbol(function->rest_argument, Memory::nil);
if (function->args.rest) {
define_symbol(function->args.rest, Memory::nil);
} }
} else { } else {
if (function->rest_argument) {
if (function->args.rest) {
define_symbol( define_symbol(
function->rest_argument,
function->args.rest,
// NOTE(Felix): arguments will be a list, and I THINK // NOTE(Felix): arguments will be a list, and I THINK
// we do not need to copy it... // we do not need to copy it...
arguments); arguments);
@@ -201,9 +201,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
*/ */
proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
// first init the fields // first init the fields
function->positional_arguments = create_positional_argument_list(16);
function->keyword_arguments = create_keyword_argument_list(16);
function->rest_argument = nullptr;
function->args.positional = create_positional_argument_list(16);
function->args.keyword = create_keyword_argument_list(16);
function->args.rest = nullptr;


// okay let's try to read some positional arguments // okay let's try to read some positional arguments
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
@@ -228,7 +228,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {


// okay wow we found an actual symbol // okay wow we found an actual symbol
append_to_positional_argument_list( append_to_positional_argument_list(
function->positional_arguments,
&function->args.positional,
arguments->value.pair.first); arguments->value.pair.first);


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
@@ -294,7 +294,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
pop_environment(); pop_environment();
}; };
try_void ret = eval_expr(next->value.pair.first); try_void ret = eval_expr(next->value.pair.first);
append_to_keyword_argument_list(function->keyword_arguments,
append_to_keyword_argument_list(&function->args.keyword,
arguments->value.pair.first, arguments->value.pair.first,
ret); ret);
arguments = next->value.pair.rest; arguments = next->value.pair.rest;
@@ -304,7 +304,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
} }
} else { } else {
// No :defaults-to, so just add it to the list // No :defaults-to, so just add it to the list
append_to_keyword_argument_list(function->keyword_arguments,
append_to_keyword_argument_list(&function->args.keyword,
arguments->value.pair.first, arguments->value.pair.first,
nullptr); nullptr);
arguments = next; arguments = next;
@@ -331,7 +331,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
create_parsing_error("After the 'rest' marker there must follow a symbol."); create_parsing_error("After the 'rest' marker there must follow a symbol.");
return; return;
} }
function->rest_argument = arguments->value.pair.first;
function->args.rest = arguments->value.pair.first;
if (arguments->value.pair.rest != Memory::nil) { if (arguments->value.pair.rest != Memory::nil) {
create_parsing_error("The lambda list must end after the rest symbol"); create_parsing_error("The lambda list must end after the rest symbol");
} }
@@ -362,6 +362,7 @@ proc list_length(Lisp_Object* node) -> int {
} }


proc eval_arguments(Lisp_Object* arguments, int *out_arguments_length) -> Lisp_Object* { proc eval_arguments(Lisp_Object* arguments, int *out_arguments_length) -> Lisp_Object* {
profile_this;
int my_out_arguments_length = 0; int my_out_arguments_length = 0;
if (arguments == Memory::nil) { if (arguments == Memory::nil) {
*(out_arguments_length) = 0; *(out_arguments_length) = 0;
@@ -396,15 +397,17 @@ proc eval_arguments(Lisp_Object* arguments, int *out_arguments_length) -> Lisp_O
} }


proc eval_expr(Lisp_Object* node) -> Lisp_Object* { proc eval_expr(Lisp_Object* node) -> Lisp_Object* {
profile_this;

using namespace Globals::Current_Execution; using namespace Globals::Current_Execution;
append_to_array_list(call_stack, node);
append_to_array_list(&call_stack, node);
defer { defer {
// NOTE(Felix): We only delete the current entry from the call // NOTE(Felix): We only delete the current entry from the call
// stack, if we did not encounter an error, otherwise we neet // stack, if we did not encounter an error, otherwise we neet
// to preserve the callstack to print it later. it will be // to preserve the callstack to print it later. it will be
// cleared in log_error(). // cleared in log_error().
if (!Globals::error) if (!Globals::error)
--call_stack->next_index;
--call_stack.next_index;
}; };


switch (Memory::get_type(node)) { switch (Memory::get_type(node)) {


+ 7
- 3
src/forward_decls.cpp Просмотреть файл

@@ -39,14 +39,18 @@ namespace Parser {
} }


namespace Globals { namespace Globals {
char* bin_path = nullptr;
Log_Level log_level = Log_Level::Debug; Log_Level log_level = Log_Level::Debug;


namespace Current_Execution { namespace Current_Execution {
Lisp_Object_Array_List* call_stack = create_Lisp_Object_array_list();
Environment_Array_List* envi_stack = create_Environment_array_list();
Lisp_Object_Array_List call_stack = create_Lisp_Object_array_list();
Environment_Array_List envi_stack = create_Environment_array_list();
} }


#ifdef _DONT_BREAK_ON_ERRORS
bool breaking_on_errors = false;
#else
bool breaking_on_errors = true; bool breaking_on_errors = true;
#endif
Error* error = nullptr; Error* error = nullptr;

} }

+ 20
- 8
src/gc.cpp Просмотреть файл

@@ -3,10 +3,10 @@ namespace GC {


int current_mark; int current_mark;


Lisp_Object_Array_List* marked_objects;
String_Array_List* marked_strings;
Environment_Array_List* marked_environments;
Environment_Array_List* protected_environments;
Lisp_Object_Array_List marked_objects;
String_Array_List marked_strings;
Environment_Array_List marked_environments;
Environment_Array_List protected_environments;


proc marked(Lisp_Object* node) -> bool { proc marked(Lisp_Object* node) -> bool {
return false; return false;
@@ -20,8 +20,14 @@ namespace GC {
if (marked(node)) if (marked(node))
return; return;


append_to_array_list(marked_objects, node);
// mark object itself
append_to_array_list(&marked_objects, node);


// mark docstring
if (node->docstring)
append_to_array_list(&marked_strings, node->docstring);

// mark type specific data
switch (Memory::get_type(node)) { switch (Memory::get_type(node)) {
case Lisp_Object_Type::Pair: { case Lisp_Object_Type::Pair: {
for_lisp_list (node) { for_lisp_list (node) {
@@ -34,11 +40,18 @@ namespace GC {
} }
} break; } break;
case Lisp_Object_Type::String: { case Lisp_Object_Type::String: {
append_to_array_list(marked_strings, node->value.string);
append_to_array_list(&marked_strings, node->value.string);
} break; } break;
case Lisp_Object_Type::Function: { case Lisp_Object_Type::Function: {
// NOTE(Felix): We dont have to mark the symbols, keywords
// for parameter names, as symbols and keywords are never
// garbage collected
maybe_mark(node->value.function.parent_environment); maybe_mark(node->value.function.parent_environment);
maybe_mark(node->value.function.body); maybe_mark(node->value.function.body);
// mark the default arguemnt values:
for_array_list (node->value.function.args.keyword.values) {
if (it) maybe_mark(it);
}
} break; } break;
} }


@@ -48,7 +61,7 @@ namespace GC {
if (marked(env)) if (marked(env))
return; return;


append_to_array_list(marked_environments, env);
append_to_array_list(&marked_environments, env);


for_array_list (env->parents) { for_array_list (env->parents) {
maybe_mark(it); maybe_mark(it);
@@ -66,7 +79,6 @@ namespace GC {


for_array_list (protected_environments) maybe_mark(it); for_array_list (protected_environments) maybe_mark(it);
for_array_list (Globals::Current_Execution::envi_stack) maybe_mark(it); for_array_list (Globals::Current_Execution::envi_stack) maybe_mark(it);

} }


proc gc_init_and_go() -> void { proc gc_init_and_go() -> void {


+ 4
- 4
src/io.cpp Просмотреть файл

@@ -393,10 +393,10 @@ proc print_single_call(Lisp_Object* obj) -> void {
proc print_call_stack() -> void { proc print_call_stack() -> void {
using Globals::Current_Execution::call_stack; using Globals::Current_Execution::call_stack;


printf("callstack [%d] (most recent call last):\n", call_stack->next_index);
for (int i = 0; i < call_stack->next_index; ++i) {
printf("callstack [%d] (most recent call last):\n", call_stack.next_index);
for (int i = 0; i < call_stack.next_index; ++i) {
printf("%2d -> ", i); printf("%2d -> ", i);
print_single_call(call_stack->data[i]);
print_single_call(call_stack.data[i]);
printf("\n"); printf("\n");
} }
} }
@@ -410,5 +410,5 @@ proc log_error() -> void {
print_call_stack(); print_call_stack();
puts(console_normal); puts(console_normal);


Globals::Current_Execution::call_stack->next_index = 0;
Globals::Current_Execution::call_stack.next_index = 0;
} }

+ 10
- 16
src/lisp_object.cpp Просмотреть файл

@@ -26,26 +26,20 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
return "unknown"; return "unknown";
} }


proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* {
Positional_Arguments* ret = new(Positional_Arguments);
ret->symbols = (Lisp_Object**)malloc(initial_capacity * sizeof(Lisp_Object*));
ret->next_index = 0;
ret->length = initial_capacity;
proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments {
Positional_Arguments ret;
ret.symbols = create_Lisp_Object_array_list(initial_capacity);
return ret; return ret;
} }


proc append_to_positional_argument_list(Positional_Arguments* args, Lisp_Object* sym) -> void { proc append_to_positional_argument_list(Positional_Arguments* args, Lisp_Object* sym) -> void {
if (args->next_index == args->length) {
args->length *= 2;
args->symbols = (Lisp_Object**)realloc(args->symbols, args->length * sizeof(Lisp_Object*));
}
args->symbols[args->next_index++] = sym;
append_to_array_list(&args->symbols, sym);
} }


proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
Keyword_Arguments* ret = new(Keyword_Arguments);
ret->keywords = create_Lisp_Object_array_list(initial_capacity);
ret->values = create_Lisp_Object_array_list(initial_capacity);
proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments {
Keyword_Arguments ret;
ret.keywords = create_Lisp_Object_array_list(initial_capacity);
ret.values = create_Lisp_Object_array_list(initial_capacity);
return ret; return ret;
} }


@@ -53,6 +47,6 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args,
Lisp_Object* keyword, Lisp_Object* keyword,
Lisp_Object* default_value) -> void Lisp_Object* default_value) -> void
{ {
append_to_array_list(args->keywords, keyword);
append_to_array_list(args->values, default_value);
append_to_array_list(&args->keywords, keyword);
append_to_array_list(&args->values, default_value);
} }

+ 3
- 1
src/main.cpp Просмотреть файл

@@ -3,7 +3,9 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc > 1) { if (argc > 1) {
if (Slime::string_equal(argv[1], "--run-tests")) { if (Slime::string_equal(argv[1], "--run-tests")) {
return Slime::run_all_tests() ? 0 : 1;
int res = Slime::run_all_tests();
Slime::interprete_file("generate-docs.slime");
return res ? 0 : 1;
} }


Slime::interprete_file(argv[1]); Slime::interprete_file(argv[1]);


+ 31
- 31
src/memory.cpp Просмотреть файл

@@ -4,7 +4,7 @@ namespace Memory {
// lisp_objects // lisp_objects
// ------------------ // ------------------
int object_memory_size; int object_memory_size;
Int_Array_List* free_spots_in_object_memory;
Int_Array_List free_spots_in_object_memory;
Lisp_Object* object_memory; Lisp_Object* object_memory;
int next_index_in_object_memory = 0; int next_index_in_object_memory = 0;


@@ -12,7 +12,7 @@ namespace Memory {
// environments // environments
// ------------------ // ------------------
int environment_memory_size; int environment_memory_size;
Int_Array_List* free_spots_in_environment_memory;
Int_Array_List free_spots_in_environment_memory;
Environment* environment_memory; Environment* environment_memory;
int next_index_in_environment_memory = 0; int next_index_in_environment_memory = 0;


@@ -23,7 +23,7 @@ namespace Memory {
// free_spots_in_string_memory is an arraylist of pointers into // free_spots_in_string_memory is an arraylist of pointers into
// the string_memory, where dead String objects live (which give // the string_memory, where dead String objects live (which give
// information about their size) // information about their size)
Void_Ptr_Array_List* free_spots_in_string_memory;
Void_Ptr_Array_List free_spots_in_string_memory;
String* string_memory; String* string_memory;
String* next_free_spot_in_string_memory; String* next_free_spot_in_string_memory;


@@ -38,15 +38,15 @@ namespace Memory {
" - %f%% of the object_memory is used\n" " - %f%% of the object_memory is used\n"
" - %d of %d total Lisp_Objects are in use\n" " - %d of %d total Lisp_Objects are in use\n"
" - %d holes in used memory (fragmentation)\n", " - %d holes in used memory (fragmentation)\n",
(1.0*next_index_in_object_memory - free_spots_in_object_memory->next_index)/object_memory_size,
next_index_in_object_memory - free_spots_in_object_memory->next_index, object_memory_size,
free_spots_in_object_memory->next_index);
(1.0*next_index_in_object_memory - free_spots_in_object_memory.next_index)/object_memory_size,
next_index_in_object_memory - free_spots_in_object_memory.next_index, object_memory_size,
free_spots_in_object_memory.next_index);


printf("Memory Status:\n" printf("Memory Status:\n"
" - %f%% of the string_memory is used\n" " - %f%% of the string_memory is used\n"
" - %d holes in used memory (fragmentation)\n", " - %d holes in used memory (fragmentation)\n",
(1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size, (1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size,
free_spots_in_string_memory->next_index);
free_spots_in_string_memory.next_index);
} }


inline proc get_c_str(String* str) -> char* { inline proc get_c_str(String* str) -> char* {
@@ -106,7 +106,7 @@ namespace Memory {
} }


proc delete_string(String* str) { proc delete_string(String* str) {
append_to_array_list(free_spots_in_string_memory, (void*)str);
append_to_array_list(&free_spots_in_string_memory, (void*)str);
} }


proc duplicate_string(String* str) -> String* { proc duplicate_string(String* str) -> String* {
@@ -136,7 +136,7 @@ namespace Memory {
proc create_lisp_object() -> Lisp_Object* { proc create_lisp_object() -> Lisp_Object* {
int index; int index;
// if we have no free spots then append at the end // if we have no free spots then append at the end
if (free_spots_in_object_memory->next_index == 0) {
if (free_spots_in_object_memory.next_index == 0) {
// if we still have space // if we still have space
if (object_memory_size == next_index_in_object_memory) { if (object_memory_size == next_index_in_object_memory) {
create_out_of_memory_error( create_out_of_memory_error(
@@ -149,7 +149,7 @@ namespace Memory {
index = next_index_in_object_memory++; index = next_index_in_object_memory++;
} else { } else {
// else fill a free spot, and remove the free spot // else fill a free spot, and remove the free spot
index = free_spots_in_object_memory->data[free_spots_in_object_memory->next_index--];
index = free_spots_in_object_memory.data[free_spots_in_object_memory.next_index--];
} }
Lisp_Object* object = object_memory+index; Lisp_Object* object = object_memory+index;
object->flags = 0; object->flags = 0;
@@ -184,22 +184,22 @@ namespace Memory {


try_void Parser::standard_in = create_string("stdin"); try_void Parser::standard_in = create_string("stdin");


try_void Globals::Current_Execution::envi_stack->data[0] = create_built_ins_environment();
try_void Globals::Current_Execution::envi_stack->next_index = 1;
try_void Globals::Current_Execution::envi_stack.data[0] = create_built_ins_environment();
try_void Globals::Current_Execution::envi_stack.next_index = 1;
} }


proc reset() -> void { proc reset() -> void {
free_spots_in_object_memory->next_index = 0;
free_spots_in_environment_memory->next_index = 0;
free_spots_in_string_memory->next_index = 0;
free_spots_in_object_memory.next_index = 0;
free_spots_in_environment_memory.next_index = 0;
free_spots_in_string_memory.next_index = 0;


// because t and nil are always there we start the index at 2 // because t and nil are always there we start the index at 2
next_index_in_object_memory = 2; next_index_in_object_memory = 2;
next_index_in_environment_memory = 0; next_index_in_environment_memory = 0;
next_free_spot_in_string_memory = string_memory; next_free_spot_in_string_memory = string_memory;


try_void Globals::Current_Execution::envi_stack->data[0] = create_built_ins_environment();
try_void Globals::Current_Execution::envi_stack->next_index = 1;
try_void Globals::Current_Execution::envi_stack.data[0] = create_built_ins_environment();
try_void Globals::Current_Execution::envi_stack.next_index = 1;
} }


proc create_lisp_object_number(double number) -> Lisp_Object* { proc create_lisp_object_number(double number) -> Lisp_Object* {
@@ -353,7 +353,7 @@ namespace Memory {


int index; int index;
// if we have no free spots then append at the end // if we have no free spots then append at the end
if (free_spots_in_environment_memory->next_index == 0) {
if (free_spots_in_environment_memory.next_index == 0) {
// if we still have space // if we still have space
if (environment_memory_size == next_index_in_environment_memory) { if (environment_memory_size == next_index_in_environment_memory) {
create_out_of_memory_error( create_out_of_memory_error(
@@ -366,7 +366,7 @@ namespace Memory {
index = next_index_in_environment_memory++; index = next_index_in_environment_memory++;
} else { } else {
// else fill a free spot, and remove the free spot // else fill a free spot, and remove the free spot
index = free_spots_in_environment_memory->data[free_spots_in_environment_memory->next_index--];
index = free_spots_in_environment_memory.data[free_spots_in_environment_memory.next_index--];
} }




@@ -376,7 +376,7 @@ namespace Memory {
env->parents = create_Environment_array_list(); env->parents = create_Environment_array_list();


if (parent) if (parent)
append_to_array_list(env->parents, parent);
append_to_array_list(&env->parents, parent);


env->capacity = start_capacity; env->capacity = start_capacity;
env->next_index = 0; env->next_index = 0;
@@ -402,17 +402,17 @@ namespace Memory {


load_built_ins_into_environment(); load_built_ins_into_environment();


// save the current working directory
char* cwd = get_cwd();
defer {
change_cwd(cwd);
free(cwd);
};
// get the direction of the exe
char* exe_path = get_exe_dir();
change_cwd(exe_path);
free(exe_path);
// // save the current working directory
// char* cwd = get_cwd();
// defer {
// change_cwd(cwd);
// free(cwd);
// };
// // get the direction of the exe
// char* exe_path = get_exe_dir();
// change_cwd(exe_path);
// free(exe_path);


built_in_load(Memory::create_string("pre.slime")); built_in_load(Memory::create_string("pre.slime"));




+ 12
- 12
src/parse.cpp Просмотреть файл

@@ -403,9 +403,9 @@ namespace Parser {
try assert_type(arguments, Lisp_Object_Type::Pair); try assert_type(arguments, Lisp_Object_Type::Pair);
try parse_argument_list(arguments, &macro->value.function); try parse_argument_list(arguments, &macro->value.function);
} else { } else {
macro->value.function.positional_arguments = create_positional_argument_list(1);
macro->value.function.keyword_arguments = create_keyword_argument_list(1);
macro->value.function.rest_argument = nullptr;
macro->value.function.args.positional = create_positional_argument_list(1);
macro->value.function.args.keyword = create_keyword_argument_list(1);
macro->value.function.args.rest = nullptr;
} }


// arguments = arguments->value.pair.rest; // arguments = arguments->value.pair.rest;
@@ -556,7 +556,7 @@ namespace Parser {


} }


proc write_expanded_file(String* file_name, Lisp_Object_Array_List* program) -> void {
proc write_expanded_file(String* file_name, Lisp_Object_Array_List program) -> void {
const char* ext = ".expanded"; const char* ext = ".expanded";
char* newName = (char*)calloc(10 + file_name->length, sizeof(char)); char* newName = (char*)calloc(10 + file_name->length, sizeof(char));
strcpy(newName, Memory::get_c_str(file_name)); strcpy(newName, Memory::get_c_str(file_name));
@@ -573,21 +573,21 @@ namespace Parser {
exit(1); exit(1);
} }


for (int i = 0; i < program->next_index; ++i) {
for (int i = 0; i < program.next_index; ++i) {
// a macro will parse as nil for now, so we skip those // a macro will parse as nil for now, so we skip those
if (program->data[i] == Memory::nil)
if (program.data[i] == Memory::nil)
continue; continue;
print(program->data[i], true, f);
print(program.data[i], true, f);
fprintf(f, "\n\n"); fprintf(f, "\n\n");
} }
} }


proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List* {
proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List {
parser_file = file_name; parser_file = file_name;
parser_line = 1; parser_line = 1;
parser_col = 0; parser_col = 0;


Lisp_Object_Array_List* program = create_Lisp_Object_array_list();
Lisp_Object_Array_List program = create_Lisp_Object_array_list();


int index_in_text = 0; int index_in_text = 0;


@@ -595,10 +595,10 @@ namespace Parser {
switch (text[index_in_text]) { switch (text[index_in_text]) {
case '(': { case '(': {
Lisp_Object* parsed; Lisp_Object* parsed;
try {
try_struct {
parsed = parse_expression(text, &index_in_text); parsed = parse_expression(text, &index_in_text);
} }
append_to_array_list(program, parsed);
append_to_array_list(&program, parsed);
} break; } break;
case ';': case ';':
case ' ': case ' ':
@@ -611,7 +611,7 @@ namespace Parser {
/* syntax error */ /* syntax error */
create_parsing_error("Garbage in file scope at %s:%d:%d", create_parsing_error("Garbage in file scope at %s:%d:%d",
parser_file, parser_line, parser_col); parser_file, parser_line, parser_col);
return nullptr;
return {};
} }
} }





+ 0
- 1
src/slime.h Просмотреть файл

@@ -32,7 +32,6 @@ namespace Slime {
# include "./platform.cpp" # include "./platform.cpp"
# include "./structs.cpp" # include "./structs.cpp"
# include "./forward_decls.cpp" # include "./forward_decls.cpp"
# include "./profiler.cpp"
# include "./memory.cpp" # include "./memory.cpp"
# include "./gc.cpp" # include "./gc.cpp"
# include "./lisp_object.cpp" # include "./lisp_object.cpp"


+ 18
- 26
src/structs.cpp Просмотреть файл

@@ -8,7 +8,6 @@ define_array_list(String*, String);
define_array_list(int, Int); define_array_list(int, Int);
define_array_list(void*, Void_Ptr); define_array_list(void*, Void_Ptr);



enum struct Thread_Type { enum struct Thread_Type {
Main, Main,
GarbageCollection GarbageCollection
@@ -91,37 +90,40 @@ struct Vector {
}; };


struct Positional_Arguments { struct Positional_Arguments {
Lisp_Object** symbols; // Array of Pointers to Lisp_Object<Symbol>
int next_index;
int length;
Lisp_Object_Array_List symbols;
}; };


struct Keyword_Arguments { struct Keyword_Arguments {
// Array of Pointers to Lisp_Object<Keyword> // Array of Pointers to Lisp_Object<Keyword>
Lisp_Object_Array_List* keywords;
Lisp_Object_Array_List keywords;
// NOTE(Felix): values[i] will be nullptr if no defalut value was // NOTE(Felix): values[i] will be nullptr if no defalut value was
// declared for key identifiers[i] // declared for key identifiers[i]
Lisp_Object_Array_List* values;
Lisp_Object_Array_List values;
}; };


struct Arguments { struct Arguments {
Positional_Arguments positional;
Keyword_Arguments keyword;
// NOTE(Felix): rest_argument will be nullptr if no rest argument // NOTE(Felix): rest_argument will be nullptr if no rest argument
// is declared otherwise its a symbol // is declared otherwise its a symbol
Lisp_Object* rest_argument;
Keyword_Arguments keyword_arguments;
Positional_Arguments positional_arguments;
Lisp_Object* rest;
}; };


struct Environment {
Environment_Array_List parents;
int capacity;
int next_index;

// TODO(Felix): Use a hashmap here.
char** keys;
Lisp_Object** values;
};


struct Function { struct Function {
Function_Type type; Function_Type type;
Positional_Arguments* positional_arguments;
Keyword_Arguments* keyword_arguments;
// NOTE(Felix): rest_argument will be nullptr if no rest argument
// is declared otherwise its a symbol
Lisp_Object* rest_argument;
Arguments args;
Lisp_Object* body; // implicit begin Lisp_Object* body; // implicit begin
Environment* parent_environment; // we are doing closures now!!
Environment* parent_environment; // we are doing closures now!!
}; };


struct cFunction { struct cFunction {
@@ -131,7 +133,7 @@ struct cFunction {
struct Lisp_Object { struct Lisp_Object {
Source_Code_Location* sourceCodeLocation; Source_Code_Location* sourceCodeLocation;
u64 flags; u64 flags;
Lisp_Object* userType;
Lisp_Object* userType; // keyword
String* docstring; String* docstring;
union { union {
Symbol symbol; // used for symbols and keywords Symbol symbol; // used for symbols and keywords
@@ -145,16 +147,6 @@ struct Lisp_Object {
} value; } value;
}; };


struct Environment {
Environment_Array_List* parents;
int capacity;
int next_index;

// TODO(Felix): Use a hashmap here.
char** keys;
Lisp_Object** values;
};

struct Error { struct Error {
Lisp_Object* position; Lisp_Object* position;
// type has to be a keyword // type has to be a keyword


+ 46
- 52
src/testing.cpp Просмотреть файл

@@ -115,79 +115,79 @@


proc test_array_lists_adding_and_removing() -> testresult { proc test_array_lists_adding_and_removing() -> testresult {
// test adding and removing // 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);
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);
assert_equal_int(list.next_index, 4);


remove_index_from_array_list(list, 0);
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);
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);
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);
assert_equal_int(list.next_index, 2);
assert_equal_int(list.data[0], 4);
assert_equal_int(list.data[1], 2);


return pass; return pass;
} }


proc test_array_lists_sorting() -> testresult { proc test_array_lists_sorting() -> testresult {
// test adding and removing // 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);
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);
sort_array_list(&list);


assert_equal_int(list->next_index, 4);
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);
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);
append_to_array_list(&list, 0);
append_to_array_list(&list, 5);


assert_equal_int(list->next_index, 6);
assert_equal_int(list.next_index, 6);


sort_array_list(list);
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);
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; return pass;
} }


proc test_array_lists_searching() -> testresult { 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_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);
int index = sorted_array_list_find(&list, 3);
assert_equal_int(index, 2); assert_equal_int(index, 2);


index = sorted_array_list_find(list, 1);
index = sorted_array_list_find(&list, 1);
assert_equal_int(index, 0); assert_equal_int(index, 0);


index = sorted_array_list_find(list, 5);
index = sorted_array_list_find(&list, 5);
assert_equal_int(index, -1); assert_equal_int(index, -1);


return pass; return pass;
@@ -595,14 +595,6 @@ proc test_file(const char* file) -> testresult {
} }


proc run_all_tests() -> bool { proc run_all_tests() -> bool {
Memory::init(4096 * 2000, 1024 * 32, 4096 * 16 * 10);

// get the direction of the exe
char* exe_path = get_exe_dir();

// switch to the exe directory for loading pre.slime
change_cwd(exe_path);
free(exe_path);


bool result = true; bool result = true;


@@ -611,6 +603,8 @@ proc run_all_tests() -> bool {
invoke_test(test_array_lists_sorting); invoke_test(test_array_lists_sorting);
invoke_test(test_array_lists_searching); invoke_test(test_array_lists_searching);


Memory::init(4096 * 2000, 1024 * 32, 4096 * 16 * 10);

printf("\n -- Parsing --\n"); printf("\n -- Parsing --\n");
invoke_test(test_parse_atom); invoke_test(test_parse_atom);
invoke_test(test_parse_expression); invoke_test(test_parse_expression);


+ 55
- 55
src/visualization.cpp Просмотреть файл

@@ -305,8 +305,8 @@ proc visualize_lisp_machine() -> void {
draw_new_line(); draw_new_line();


int free_string_memory = (int)(Memory::next_free_spot_in_string_memory - Memory::string_memory); int free_string_memory = (int)(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;
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; int used_string_memory = Memory::string_memory_size - free_string_memory;


@@ -334,8 +334,8 @@ proc visualize_lisp_machine() -> void {
// Object Memory // 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;
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;


write_x += draw_text("Object Memory:").width; write_x += draw_text("Object Memory:").width;
draw_margin(); draw_margin();
@@ -359,26 +359,26 @@ proc visualize_lisp_machine() -> void {
draw_new_line(3); draw_new_line(3);
}; };
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* 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();
Lisp_Object_Array_List* lists = create_Lisp_Object_array_list();
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();
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) {
for (int j = 0; j < Memory::free_spots_in_object_memory->next_index; ++j) {
if (i == Memory::free_spots_in_object_memory->data[j])
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; goto next;
} }


switch (Memory::get_type(Memory::object_memory+i)) { 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;
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;
default: break; default: break;
} }


@@ -386,36 +386,36 @@ proc visualize_lisp_machine() -> void {
} }


// create the lists-list by filtering the pairs-list. // create the lists-list by filtering the pairs-list.
Lisp_Object_Array_List* pairs_to_filter = create_Lisp_Object_array_list();
Lisp_Object_Array_List pairs_to_filter = create_Lisp_Object_array_list();


// helper lambda: // helper lambda:
proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List* list) -> void {
if (list->next_index == 0)
proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List list) -> void {
if (list.next_index == 0)
return; return;


sort_array_list(list);
Int_Array_List* indices_to_filter = create_Int_array_list();
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);
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 else
last = (size_t)list->data[i];
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]);
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 again as removing items destroys the order
sort_array_list(list);
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);
append_to_array_list(&pairs_to_filter, pair);


if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair) if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair)
filter_pair_and_children(pair->value.pair.first); filter_pair_and_children(pair->value.pair.first);
@@ -423,12 +423,12 @@ proc visualize_lisp_machine() -> void {
if (Memory::get_type(pair->value.pair.rest) == Lisp_Object_Type::Pair) if (Memory::get_type(pair->value.pair.rest) == Lisp_Object_Type::Pair)
filter_pair_and_children(pair->value.pair.rest); filter_pair_and_children(pair->value.pair.rest);
}; };
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);
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);
if (Memory::get_type(pairs.data[i]->value.pair.rest) == Lisp_Object_Type::Pair)
filter_pair_and_children(pairs.data[i]->value.pair.rest);


} }


@@ -436,9 +436,9 @@ proc visualize_lisp_machine() -> void {
// fprintf(stderr, "removing %d pairs\n", pairs_to_filter->next_index); // fprintf(stderr, "removing %d pairs\n", pairs_to_filter->next_index);
// okay, so pairs_to_filter now only the pairs once each that // okay, so pairs_to_filter now only the pairs once each that
// we want to filter from the pairs list // 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]);
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]);
} }
} }


@@ -450,15 +450,15 @@ proc visualize_lisp_machine() -> void {
start_y = write_y; start_y = write_y;


write_x += draw_text("Symbols: ").width; 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;


for (int i = 0; i < symbols->next_index; ++i) {
for (int i = 0; i < symbols.next_index; ++i) {
draw_new_line(); draw_new_line();
write_x = start_x; write_x = start_x;


draw_text(&symbols->data[i]->value.symbol.identifier->data);
draw_text(&symbols.data[i]->value.symbol.identifier->data);
} }




@@ -466,15 +466,15 @@ proc visualize_lisp_machine() -> void {
write_y = start_y; write_y = start_y;


write_x += draw_text("Keywords: ").width; 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;


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_lisp_object(keywords->data[i]);
draw_lisp_object(keywords.data[i]);
} }




@@ -483,30 +483,30 @@ proc visualize_lisp_machine() -> void {
write_y = start_y; write_y = start_y;


write_x += draw_text("Numbers: ").width; 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;


for (int i = 0; i < numbers->next_index; ++i) {
for (int i = 0; i < numbers.next_index; ++i) {
draw_new_line(); draw_new_line();
write_x = start_x + 600; write_x = start_x + 600;


draw_float((float)(numbers->data[i]->value.number));
draw_float((float)(numbers.data[i]->value.number));
} }


write_x = start_x + 900; write_x = start_x + 900;
write_y = start_y; write_y = start_y;


write_x += draw_text("Strings: ").width; 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;


for (int i = 0; i < strings->next_index; ++i) {
for (int i = 0; i < strings.next_index; ++i) {
draw_new_line(); draw_new_line();
write_x = start_x + 900; write_x = start_x + 900;


draw_text(&strings->data[i]->value.string->data, "#2aa198", true, 75);
draw_text(&strings.data[i]->value.string->data, "#2aa198", true, 75);
} }




@@ -514,17 +514,17 @@ proc visualize_lisp_machine() -> void {
write_y = start_y; write_y = start_y;


write_x += draw_text("Lists, Pairs: ").width; write_x += draw_text("Lists, Pairs: ").width;
write_x += draw_integer(lists->next_index).width;
write_x += draw_integer(lists.next_index).width;
draw_margin(); 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 < lists->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;


write_y += draw_pair(lists->data[i]).height;
write_y += draw_pair(lists.data[i]).height;
} }
}; };




+ 4
- 0
vs/slime.vcxproj Просмотреть файл

@@ -96,6 +96,9 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@@ -135,6 +138,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpplatest</LanguageStandard> <LanguageStandard>stdcpplatest</LanguageStandard>
<PreprocessorDefinitions>_PROFILING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<Profile>true</Profile> <Profile>true</Profile>


Загрузка…
Отмена
Сохранить