trying not to leak memory
This commit is contained in:
+25
-13
@@ -69,35 +69,47 @@ proc built_in_load(String* file_name) -> Lisp_Object* {
|
||||
}
|
||||
create_generic_error("The file to load '%s' was not found in the load path.",
|
||||
Memory::get_c_str(file_name));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Lisp_Object* result = Memory::nil;
|
||||
Array_List<Lisp_Object*> program;
|
||||
Array_List<Lisp_Object*>* program;
|
||||
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]);
|
||||
}
|
||||
delete program;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
proc built_in_import(String* file_name) -> Lisp_Object* {
|
||||
// create new empty environment
|
||||
Environment* new_env;
|
||||
try new_env = Memory::create_child_environment(get_root_environment());
|
||||
|
||||
new_env = Memory::file_to_env_map.get_object(Memory::get_c_str(file_name));
|
||||
|
||||
if (!new_env) {
|
||||
// create new empty environment
|
||||
try new_env = Memory::create_child_environment(get_root_environment());
|
||||
// TODO(Felix): check absoulute paths in the map, not just
|
||||
// relative ones
|
||||
Memory::file_to_env_map.set_object(Memory::get_c_str(file_name), new_env);
|
||||
push_environment(new_env);
|
||||
defer {
|
||||
pop_environment();
|
||||
};
|
||||
|
||||
Lisp_Object* res;
|
||||
try res = built_in_load(file_name);
|
||||
}
|
||||
|
||||
get_current_environment()->parents.append(new_env);
|
||||
|
||||
push_environment(new_env);
|
||||
defer {
|
||||
pop_environment();
|
||||
};
|
||||
|
||||
Lisp_Object* res = built_in_load(file_name);
|
||||
|
||||
return res;
|
||||
return Memory::nil;
|
||||
}
|
||||
|
||||
proc load_built_ins_into_environment() -> void {
|
||||
|
||||
@@ -128,3 +128,24 @@
|
||||
#define in_caller_env fluid_let( \
|
||||
Globals::Current_Execution::envi_stack.next_index, \
|
||||
Globals::Current_Execution::envi_stack.next_index-1)
|
||||
|
||||
|
||||
/*
|
||||
* iterate over lisp vectors
|
||||
*/
|
||||
#define for_lisp_vector(v) \
|
||||
if (!v); else \
|
||||
if (int it_index = 0); else \
|
||||
for (auto it = v->value.vector.data; \
|
||||
it_index < v->value.vector.length; \
|
||||
it=v->value.vector.data+(++it_index))
|
||||
|
||||
/*
|
||||
* iterate over lisp lists
|
||||
*/
|
||||
#define for_lisp_list(l) \
|
||||
if (!l); else \
|
||||
if (int it_index = 0); else \
|
||||
for (Lisp_Object* head = l, *it; \
|
||||
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
|
||||
head = head->value.pair.rest, ++it_index)
|
||||
|
||||
@@ -16,41 +16,6 @@
|
||||
# define if_linux if constexpr (true)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* iterate over lisp vectors
|
||||
*/
|
||||
#define for_lisp_vector(v) \
|
||||
if (!v); else \
|
||||
if (int it_index = 0); else \
|
||||
for (auto it = v->value.vector.data; \
|
||||
it_index < v->value.vector.length; \
|
||||
it=v->value.vector.data+(++it_index))
|
||||
|
||||
/*
|
||||
* iterate over lisp lists
|
||||
*/
|
||||
#define for_lisp_list(l) \
|
||||
if (!l); else \
|
||||
if (int it_index = 0); else \
|
||||
for (Lisp_Object* head = l, *it; \
|
||||
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
|
||||
head = head->value.pair.rest, ++it_index)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#define assert(cond) \
|
||||
if_debug { \
|
||||
if (!cond) { \
|
||||
if (log_level == Log_Level::Debug) { \
|
||||
printf("Assertion failed: %s %d", __FILE__, __LINE__); \
|
||||
} \
|
||||
debug_break(); \
|
||||
} \
|
||||
} else {} \
|
||||
*/
|
||||
|
||||
|
||||
#define console_normal "\x1B[0m"
|
||||
#define console_red "\x1B[31m"
|
||||
#define console_green "\x1B[32m"
|
||||
|
||||
+3
-3
@@ -259,9 +259,9 @@ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_O
|
||||
result = &function->value.function.args;
|
||||
}
|
||||
|
||||
::new (&(result->positional.symbols)) Array_List<Lisp_Object*>;
|
||||
::new (&(result->keyword.keywords)) Array_List<Lisp_Object*>;
|
||||
::new (&(result->keyword.values)) Array_List<Lisp_Object*>;
|
||||
::new (&result->positional.symbols) Array_List<Lisp_Object*>;
|
||||
::new (&result->keyword.keywords) Array_List<Lisp_Object*>;
|
||||
::new (&result->keyword.values) Array_List<Lisp_Object*>;
|
||||
|
||||
// first init the fields
|
||||
// result->positional = create_positional_argument_list(16);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -39,3 +39,9 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args,
|
||||
args->keywords.append(keyword);
|
||||
args->values.append(default_value);
|
||||
}
|
||||
|
||||
Lisp_Object::~Lisp_Object() {
|
||||
if (Memory::get_type(this) == Lisp_Object_Type::HashMap) {
|
||||
this->value.hashMap.~Hash_Map();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include "libslime.cpp"
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc > 1) {
|
||||
if (Slime::string_equal(argv[1], "--run-tests")) {
|
||||
int res = Slime::run_all_tests();
|
||||
// Slime::interprete_file((char*)"generate-docs.slime");
|
||||
|
||||
_CrtDumpMemoryLeaks();
|
||||
return res ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
+18
-6
@@ -6,6 +6,8 @@ namespace Memory {
|
||||
Hash_Map<char*, Lisp_Object*> global_symbol_table;
|
||||
Hash_Map<char*, Lisp_Object*> global_keyword_table;
|
||||
|
||||
|
||||
Hash_Map<char*, Environment*> file_to_env_map;
|
||||
// ------------------
|
||||
// lisp_objects
|
||||
// ------------------
|
||||
@@ -177,13 +179,23 @@ namespace Memory {
|
||||
free_spots_in_string_memory.next_index = 0;
|
||||
|
||||
|
||||
::new((&global_symbol_table)) Hash_Map<char*, Lisp_Object*>;
|
||||
::new((&global_keyword_table)) Hash_Map<char*, Lisp_Object*>;
|
||||
global_symbol_table.~Hash_Map();
|
||||
global_keyword_table.~Hash_Map();
|
||||
file_to_env_map.~Hash_Map();
|
||||
|
||||
::new(&global_symbol_table) Hash_Map<char*, Lisp_Object*>;
|
||||
::new(&global_keyword_table) Hash_Map<char*, Lisp_Object*>;
|
||||
::new(&file_to_env_map) Hash_Map<char*, Lisp_Object*>;
|
||||
|
||||
try_void Parser::standard_in = create_string("stdin");
|
||||
|
||||
object_memory.reset();
|
||||
environment_memory.reset();
|
||||
|
||||
object_memory.~Bucket_Allocator();
|
||||
// environment_memory.~Bucket_Allocator();
|
||||
|
||||
::new(&object_memory) Bucket_Allocator<Lisp_Object, 1024>;
|
||||
::new(&environment_memory) Bucket_Allocator<Environment, 1024>;
|
||||
|
||||
next_free_spot_in_string_memory = string_memory;
|
||||
|
||||
|
||||
@@ -373,7 +385,7 @@ namespace Memory {
|
||||
return copy_lisp_object(n);
|
||||
}
|
||||
|
||||
proc create_child_environment(Environment* parent) -> Environment* {
|
||||
proc create_child_environment(Environment* parent) -> Environment* {
|
||||
|
||||
Environment* env = environment_memory.allocate();
|
||||
|
||||
@@ -404,7 +416,7 @@ namespace Memory {
|
||||
|
||||
try load_built_ins_into_environment();
|
||||
|
||||
built_in_load(Memory::create_string("pre.slime"));
|
||||
try built_in_load(Memory::create_string("pre.slime"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+7
-8
@@ -98,7 +98,6 @@ namespace Parser {
|
||||
|
||||
// get the atom
|
||||
String* ret = Memory::create_string("", atom_length);
|
||||
// char* atom = (char*)malloc(atom_length*sizeof(char)+1); // plus null char
|
||||
strcpy(&ret->data, text+(*index_in_text));
|
||||
|
||||
// restore the original string
|
||||
@@ -448,7 +447,7 @@ namespace Parser {
|
||||
|
||||
}
|
||||
|
||||
proc write_expanded_file(String* file_name, Array_List<Lisp_Object*> program) -> void {
|
||||
proc write_expanded_file(String* file_name, Array_List<Lisp_Object*>* program) -> void {
|
||||
const char* ext = ".expanded";
|
||||
char* newName = (char*)calloc(10 + file_name->length, sizeof(char));
|
||||
strcpy(newName, Memory::get_c_str(file_name));
|
||||
@@ -465,21 +464,21 @@ namespace Parser {
|
||||
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
|
||||
if (program.data[i] == Memory::nil)
|
||||
if (program->data[i] == Memory::nil)
|
||||
continue;
|
||||
print(program.data[i], true, f);
|
||||
print(program->data[i], true, f);
|
||||
fprintf(f, "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*> {
|
||||
proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*>* {
|
||||
parser_file = file_name;
|
||||
parser_line = 1;
|
||||
parser_col = 0;
|
||||
|
||||
Array_List<Lisp_Object*> program;
|
||||
Array_List<Lisp_Object*>* program = new Array_List<Lisp_Object*>;
|
||||
|
||||
int index_in_text = 0;
|
||||
|
||||
@@ -490,7 +489,7 @@ namespace Parser {
|
||||
try_struct {
|
||||
parsed = parse_expression(text, &index_in_text);
|
||||
}
|
||||
program.append(parsed);
|
||||
program->append(parsed);
|
||||
} break;
|
||||
case ';':
|
||||
case ' ':
|
||||
|
||||
+8
-1
@@ -103,6 +103,11 @@ struct Arguments {
|
||||
struct Environment {
|
||||
Array_List<Environment*> parents;
|
||||
Hash_Map<void*, Lisp_Object*> hm;
|
||||
|
||||
~Environment() {
|
||||
parents.~Array_List();
|
||||
hm.~Hash_Map();
|
||||
}
|
||||
};
|
||||
|
||||
struct Function {
|
||||
@@ -123,7 +128,7 @@ struct Lisp_Object {
|
||||
u64 flags;
|
||||
Lisp_Object* userType; // keyword
|
||||
String* docstring;
|
||||
union {
|
||||
union value {
|
||||
Symbol symbol; // used for symbols and keywords
|
||||
double number;
|
||||
String* string;
|
||||
@@ -134,7 +139,9 @@ struct Lisp_Object {
|
||||
void* pointer;
|
||||
Continuation continuation;
|
||||
Hash_Map<Lisp_Object*, Lisp_Object*> hashMap;
|
||||
~value() {}
|
||||
} value;
|
||||
~Lisp_Object();
|
||||
};
|
||||
|
||||
struct Error {
|
||||
|
||||
+2
-1
@@ -596,7 +596,7 @@ proc test_file(const char* file) -> testresult {
|
||||
pop_environment();
|
||||
};
|
||||
|
||||
built_in_load(Memory::create_string(file));
|
||||
try built_in_load(Memory::create_string(file));
|
||||
assert_no_error();
|
||||
|
||||
return pass;
|
||||
@@ -654,6 +654,7 @@ proc run_all_tests() -> bool {
|
||||
invoke_test_script("automata");
|
||||
invoke_test_script("sicp");
|
||||
invoke_test_script("hashmaps");
|
||||
invoke_test_script("singular_imports");
|
||||
|
||||
// Memory::print_status();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user