Big String refacor: now len+pointer, no String storage anymore
This commit is contained in:
+1
-1
Submodule 3rd/ftb updated: 98aa1450d8...e5cb9ce81d
+9
-7
@@ -1,3 +1,10 @@
|
|||||||
|
;; (remove_when_double_free_is_fixed)
|
||||||
|
;; (remove_when_double_free_is_fixed_2)
|
||||||
|
;; (define (kk (:key ()))
|
||||||
|
;; ())
|
||||||
|
|
||||||
|
;; (kk)
|
||||||
|
|
||||||
(define hm/set! hash-map-set!)
|
(define hm/set! hash-map-set!)
|
||||||
(define hm/get hash-map-get)
|
(define hm/get hash-map-get)
|
||||||
|
|
||||||
@@ -5,12 +12,12 @@
|
|||||||
(mytry (hm/get hm key) ()))
|
(mytry (hm/get hm key) ()))
|
||||||
|
|
||||||
(define-syntax (pe expr)
|
(define-syntax (pe expr)
|
||||||
`((begin
|
`(begin
|
||||||
(print :end " " ',expr "evaluates to")
|
(print :end " " ',expr "evaluates to")
|
||||||
((lambda (e)
|
((lambda (e)
|
||||||
(print e)
|
(print e)
|
||||||
e) ,expr))
|
e) ,expr))
|
||||||
))
|
)
|
||||||
|
|
||||||
(define the-empty-stream ())
|
(define the-empty-stream ())
|
||||||
|
|
||||||
@@ -175,11 +182,6 @@ condition is false."
|
|||||||
|
|
||||||
(rec body))
|
(rec body))
|
||||||
|
|
||||||
;; (define-syntax (apply fun seq)
|
|
||||||
;; "Applies the function to the sequence, as in calls the function with
|
|
||||||
;; ithe sequence as arguemens."
|
|
||||||
;; `(eval (pair ,fun ,seq)))
|
|
||||||
|
|
||||||
(define-syntax (define-typed args . body)
|
(define-syntax (define-typed args . body)
|
||||||
(define (get-arg-names args)
|
(define (get-arg-names args)
|
||||||
(when args
|
(when args
|
||||||
|
|||||||
+2
-2
@@ -33,8 +33,8 @@
|
|||||||
do { \
|
do { \
|
||||||
if (Memory::get_type(_node) != _type) { \
|
if (Memory::get_type(_node) != _type) { \
|
||||||
create_type_missmatch_error( \
|
create_type_missmatch_error( \
|
||||||
Lisp_Object_Type_to_string(_type), \
|
lisp_object_type_to_string(_type), \
|
||||||
Lisp_Object_Type_to_string(Memory::get_type(_node))); \
|
lisp_object_type_to_string(Memory::get_type(_node))); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -178,7 +178,7 @@ namespace Slime {
|
|||||||
inline void push_environment(Environment*);
|
inline void push_environment(Environment*);
|
||||||
inline void pop_environment();
|
inline void pop_environment();
|
||||||
|
|
||||||
const char* Lisp_Object_Type_to_string(Lisp_Object_Type type);
|
const char* lisp_object_type_to_string(Lisp_Object_Type type);
|
||||||
|
|
||||||
void visualize_lisp_machine();
|
void visualize_lisp_machine();
|
||||||
void generate_docs(String* path);
|
void generate_docs(String* path);
|
||||||
|
|||||||
+2
-2
@@ -35,8 +35,8 @@
|
|||||||
char* t = lisp_object_to_string(_node); \
|
char* t = lisp_object_to_string(_node); \
|
||||||
defer { free(t); }; \
|
defer { free(t); }; \
|
||||||
create_type_missmatch_error( \
|
create_type_missmatch_error( \
|
||||||
Lisp_Object_Type_to_string(_type), \
|
lisp_object_type_to_string(_type), \
|
||||||
Lisp_Object_Type_to_string(Memory::get_type(_node)), \
|
lisp_object_type_to_string(Memory::get_type(_node)), \
|
||||||
t); \
|
t); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
+36
-28
@@ -64,12 +64,12 @@ namespace Slime {
|
|||||||
|
|
||||||
proc add_to_load_path(const char* path) -> void {
|
proc add_to_load_path(const char* path) -> void {
|
||||||
using Globals::load_path;
|
using Globals::load_path;
|
||||||
|
|
||||||
load_path.append((void*)path);
|
load_path.append((void*)path);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc built_in_load(String* file_name) -> Lisp_Object* {
|
proc built_in_load(String file_name) -> Lisp_Object* {
|
||||||
profile_with_comment(&file_name->data);
|
profile_with_comment(file_name.data);
|
||||||
char* file_content;
|
char* file_content;
|
||||||
char fullpath[4096];
|
char fullpath[4096];
|
||||||
sprintf(fullpath, "%s", Memory::get_c_str(file_name));
|
sprintf(fullpath, "%s", Memory::get_c_str(file_name));
|
||||||
@@ -98,7 +98,11 @@ namespace Slime {
|
|||||||
|
|
||||||
Lisp_Object* result = Memory::nil;
|
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);
|
String spath = Memory::create_string(fullpath);
|
||||||
|
defer {
|
||||||
|
free(spath.data);
|
||||||
|
};
|
||||||
|
try program = Parser::parse_program(spath, file_content);
|
||||||
|
|
||||||
// NOTE(Felix): deferred so even if the eval failes, it will
|
// NOTE(Felix): deferred so even if the eval failes, it will
|
||||||
// run
|
// run
|
||||||
@@ -114,7 +118,7 @@ namespace Slime {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc built_in_import(String* file_name) -> Lisp_Object* {
|
proc built_in_import(String file_name) -> Lisp_Object* {
|
||||||
profile_this();
|
profile_this();
|
||||||
Environment* new_env;
|
Environment* new_env;
|
||||||
|
|
||||||
@@ -142,8 +146,16 @@ namespace Slime {
|
|||||||
|
|
||||||
proc load_built_ins_into_environment() -> void* {
|
proc load_built_ins_into_environment() -> void* {
|
||||||
profile_this();
|
profile_this();
|
||||||
String* file_name_built_ins = Memory::create_string(__FILE__);
|
String file_name_built_ins = Memory::create_string(__FILE__);
|
||||||
|
defer {
|
||||||
|
free(file_name_built_ins.data);
|
||||||
|
};
|
||||||
|
define((remove_when_double_free_is_fixed (:k1 ()) (:k2 ()) . rest), "") {
|
||||||
|
return Memory::nil;
|
||||||
|
};
|
||||||
|
define((remove_when_double_free_is_fixed_2 (:k1 ()) (:k2 ()) . rest), "") {
|
||||||
|
return Memory::nil;
|
||||||
|
};
|
||||||
define_macro((apply fun fun_args), "TODO") {
|
define_macro((apply fun fun_args), "TODO") {
|
||||||
// NOTE(Felix): is has to be a macro because apply by
|
// NOTE(Felix): is has to be a macro because apply by
|
||||||
// itself cannot return the result, we have to invoke eval
|
// itself cannot return the result, we have to invoke eval
|
||||||
@@ -199,7 +211,7 @@ namespace Slime {
|
|||||||
define_symbol(
|
define_symbol(
|
||||||
Memory::get_symbol("c"),
|
Memory::get_symbol("c"),
|
||||||
Memory::create_lisp_object((double)0));
|
Memory::create_lisp_object((double)0));
|
||||||
String* file_name_built_ins = Memory::create_string(__FILE__);
|
String file_name_built_ins = Memory::create_string(__FILE__);
|
||||||
define((lambda), "") {
|
define((lambda), "") {
|
||||||
fetch(c);
|
fetch(c);
|
||||||
c->value.number++;
|
c->value.number++;
|
||||||
@@ -314,7 +326,8 @@ namespace Slime {
|
|||||||
thing_cons->value.pair.rest != Memory::nil)
|
thing_cons->value.pair.rest != Memory::nil)
|
||||||
{
|
{
|
||||||
// extract docs
|
// extract docs
|
||||||
func->docstring = thing_cons->value.pair.first->value.string;
|
//TODO(Felix): make docs as HM lookup
|
||||||
|
// func->docstring = thing_cons->value.pair.first->value.string;
|
||||||
thing_cons = thing_cons->value.pair.rest;
|
thing_cons = thing_cons->value.pair.rest;
|
||||||
}
|
}
|
||||||
func->value.function->body.lisp_body = maybe_wrap_body_in_begin(thing_cons);
|
func->value.function->body.lisp_body = maybe_wrap_body_in_begin(thing_cons);
|
||||||
@@ -580,15 +593,10 @@ namespace Slime {
|
|||||||
free(string);
|
free(string);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
define_special((define-syntax form (:doc "") . body), "TODO") {
|
define_special((define-syntax form . body), "TODO") {
|
||||||
profile_with_name("(define-syntax)");
|
profile_with_name("(define-syntax)");
|
||||||
fetch(form, doc, body);
|
fetch(form, body);
|
||||||
|
// TODO(Felix): Macros cannot have docs now
|
||||||
try assert_type(doc, Lisp_Object_Type::String);
|
|
||||||
// if no doc string, we dont have to store it
|
|
||||||
if (Memory::get_c_str(doc)[0] == '\0') {
|
|
||||||
doc = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Memory::get_type(form) != Lisp_Object_Type::Pair) {
|
if (Memory::get_type(form) != Lisp_Object_Type::Pair) {
|
||||||
create_parsing_error("You can only create function macros.");
|
create_parsing_error("You can only create function macros.");
|
||||||
@@ -601,8 +609,6 @@ namespace Slime {
|
|||||||
// creating new lisp object and setting type
|
// creating new lisp object and setting type
|
||||||
Lisp_Object* func;
|
Lisp_Object* func;
|
||||||
try func = Memory::create_lisp_object_function(Lisp_Function_Type::Macro);
|
try func = Memory::create_lisp_object_function(Lisp_Function_Type::Macro);
|
||||||
if (doc) func->docstring = doc->value.string;
|
|
||||||
|
|
||||||
in_caller_env {
|
in_caller_env {
|
||||||
// setting parent env
|
// setting parent env
|
||||||
func->value.function->parent_environment = get_current_environment();
|
func->value.function->parent_environment = get_current_environment();
|
||||||
@@ -1017,13 +1023,15 @@ namespace Slime {
|
|||||||
|
|
||||||
printf(" is of type ");
|
printf(" is of type ");
|
||||||
print(type);
|
print(type);
|
||||||
printf(" (internal: %s)", Lisp_Object_Type_to_string(Memory::get_type(val)));
|
printf(" (internal: %s)", lisp_object_type_to_string(Memory::get_type(val)));
|
||||||
printf("\nand is printed as: ");
|
printf("\nand is printed as: ");
|
||||||
print(val);
|
print(val);
|
||||||
printf("\n\ndocs:\n=====\n %s\n\n",
|
printf("\n\ndocs:\n=====\n %s\n\n",
|
||||||
(val->docstring)
|
// TODO(felix): Doc HM lookup
|
||||||
? Memory::get_c_str(val->docstring)
|
// (val->docstring)
|
||||||
: "No docs avaliable");
|
// ? Memory::get_c_str(val->docstring)
|
||||||
|
// :
|
||||||
|
"No docs avaliable");
|
||||||
|
|
||||||
if (Memory::get_type(val) == Lisp_Object_Type::Function)
|
if (Memory::get_type(val) == Lisp_Object_Type::Function)
|
||||||
{
|
{
|
||||||
@@ -1125,7 +1133,7 @@ namespace Slime {
|
|||||||
defer {
|
defer {
|
||||||
free(line);
|
free(line);
|
||||||
};
|
};
|
||||||
String* strLine = Memory::create_string(line);
|
String strLine = Memory::create_string(line);
|
||||||
return Memory::create_lisp_object(strLine);
|
return Memory::create_lisp_object(strLine);
|
||||||
};
|
};
|
||||||
define((exit (:code 0)), "TODO") {
|
define((exit (:code 0)), "TODO") {
|
||||||
@@ -1240,16 +1248,16 @@ namespace Slime {
|
|||||||
int resulting_string_len = 0;
|
int resulting_string_len = 0;
|
||||||
for_lisp_list (strings) {
|
for_lisp_list (strings) {
|
||||||
try assert_type(it, Lisp_Object_Type::String);
|
try assert_type(it, Lisp_Object_Type::String);
|
||||||
resulting_string_len += it->value.string->length;
|
resulting_string_len += it->value.string.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
String* resulting_string = Memory::create_string("", resulting_string_len);
|
String resulting_string = Memory::create_string("", resulting_string_len);
|
||||||
int index_in_string = 0;
|
int index_in_string = 0;
|
||||||
|
|
||||||
for_lisp_list (strings) {
|
for_lisp_list (strings) {
|
||||||
strcpy((&resulting_string->data)+index_in_string,
|
strcpy(resulting_string.data+index_in_string,
|
||||||
Memory::get_c_str(it->value.string));
|
Memory::get_c_str(it->value.string));
|
||||||
index_in_string += it->value.string->length;
|
index_in_string += it->value.string.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Memory::create_lisp_object(resulting_string);
|
return Memory::create_lisp_object(resulting_string);
|
||||||
|
|||||||
+11
-8
@@ -42,7 +42,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define try_struct try_or_else_return({})
|
#define try_struct try_or_else_return({})
|
||||||
#define try_void try_or_else_return()
|
#define try_void try_or_else_return(;)
|
||||||
#define try try_or_else_return(0)
|
#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)
|
||||||
@@ -105,15 +105,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE(Felix): we have to copy the string because we need it to be
|
// NOTE(Felix): we have to copy the string because we need it to be
|
||||||
// mutable for the parser to work, because the parser relys on being
|
// mutable for the parser to work, (#def gives us a const char)
|
||||||
// able to temporaily put in markers in the code and also it will fill
|
// because the parser relys on being able to temporaily put in markers
|
||||||
// out the source code location
|
// in the code and also it will fill out the source code location
|
||||||
#define _define_helper(def, docs, type, ending) \
|
#define _define_helper(def, docs, type, ending) \
|
||||||
Parser::parser_file = file_name_built_ins; \
|
Parser::parser_file = file_name_built_ins; \
|
||||||
Parser::parser_line = __LINE__; \
|
Parser::parser_line = __LINE__; \
|
||||||
Parser::parser_col = 0; \
|
Parser::parser_col = 0; \
|
||||||
auto label(params,__LINE__) = Parser::parse_single_expression( \
|
auto label(params,__LINE__) = Parser::parse_single_expression(#def); \
|
||||||
Memory::get_c_str(Memory::create_string(#def))); \
|
|
||||||
if_error_log_location_and_return(nullptr); \
|
if_error_log_location_and_return(nullptr); \
|
||||||
assert_type(label(params,__LINE__), Lisp_Object_Type::Pair); \
|
assert_type(label(params,__LINE__), Lisp_Object_Type::Pair); \
|
||||||
assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
|
assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
|
||||||
@@ -121,7 +120,7 @@
|
|||||||
auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(type); \
|
auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(type); \
|
||||||
create_arguments_from_lambda_list_and_inject(label(params,__LINE__)->value.pair.rest, label(sfun,__LINE__)); \
|
create_arguments_from_lambda_list_and_inject(label(params,__LINE__)->value.pair.rest, label(sfun,__LINE__)); \
|
||||||
if_error_log_location_and_return(nullptr); \
|
if_error_log_location_and_return(nullptr); \
|
||||||
label(sfun,__LINE__)->docstring = Memory::create_string(docs); \
|
/* TODO(Felix): label(sfun,__LINE__)->docstring = Memory::create_string(docs); */ \
|
||||||
label(sfun,__LINE__)->value.function->parent_environment = get_current_environment(); \
|
label(sfun,__LINE__)->value.function->parent_environment = get_current_environment(); \
|
||||||
define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \
|
define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \
|
||||||
label(sfun,__LINE__)->value.function->body. ending
|
label(sfun,__LINE__)->value.function->body. ending
|
||||||
@@ -154,3 +153,7 @@
|
|||||||
for (Lisp_Object* head = l, *it; \
|
for (Lisp_Object* head = l, *it; \
|
||||||
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
|
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
|
||||||
head = head->value.pair.rest, ++it_index)
|
head = head->value.pair.rest, ++it_index)
|
||||||
|
|
||||||
|
|
||||||
|
#define dbg(thing, format) \
|
||||||
|
printf("%s = " format "\n", #thing, thing)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace Slime {
|
namespace Slime {
|
||||||
proc generate_docs(String* path) -> void {
|
proc generate_docs(String path) -> void {
|
||||||
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 (%s) "
|
create_generic_error("The file for writing the documentation (%s) "
|
||||||
@@ -124,10 +124,11 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(f, "\n - docu :: ");
|
fprintf(f, "\n - docu :: ");
|
||||||
if (value->docstring)
|
// TODO(Felix): make docsting a hashmap lookup
|
||||||
fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
|
// if (value->docstring)
|
||||||
Memory::get_c_str(value->docstring));
|
// fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
|
||||||
else
|
// Memory::get_c_str(value->docstring));
|
||||||
|
// else
|
||||||
fprintf(f, "none\n");
|
fprintf(f, "none\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,11 +1,11 @@
|
|||||||
namespace Slime {
|
namespace Slime {
|
||||||
proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void {
|
proc define_symbol(Lisp_Object* symbol, Lisp_Object* value) -> void {
|
||||||
profile_with_comment(&symbol->value.symbol->data);
|
profile_with_comment(symbol->value.symbol.data);
|
||||||
define_symbol(symbol, value, get_current_environment());
|
define_symbol(symbol, value, get_current_environment());
|
||||||
}
|
}
|
||||||
|
|
||||||
proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void {
|
proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void {
|
||||||
profile_with_comment(&symbol->value.symbol->data);
|
profile_with_comment(symbol->value.symbol.data);
|
||||||
env->hm.set_object((void*)symbol, value);
|
env->hm.set_object((void*)symbol, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||||
profile_with_comment(&node->value.symbol->data);
|
profile_with_comment(node->value.symbol.data);
|
||||||
// print(node);
|
// print(node);
|
||||||
assert_type(node, Lisp_Object_Type::Symbol);
|
assert_type(node, Lisp_Object_Type::Symbol);
|
||||||
|
|
||||||
@@ -85,10 +85,10 @@ namespace Slime {
|
|||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
String* identifier = node->value.symbol;
|
String identifier = node->value.symbol;
|
||||||
print_environment(env);
|
print_environment(env);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
create_symbol_undefined_error("The symbol '%s' is not defined.", &identifier->data);
|
create_symbol_undefined_error("The symbol '%s' is not defined.", identifier.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ namespace Slime {
|
|||||||
|
|
||||||
for_hash_map (env->hm) {
|
for_hash_map (env->hm) {
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
printf("-> %s :: ", &(((Lisp_Object*)key)->value.symbol->data));
|
printf("-> %s :: ", (((Lisp_Object*)key)->value.symbol.data));
|
||||||
print((Lisp_Object*)value);
|
print((Lisp_Object*)value);
|
||||||
printf(" (0x%016llx)", (unsigned long long)value);
|
printf(" (0x%016llx)", (unsigned long long)value);
|
||||||
puts("");
|
puts("");
|
||||||
|
|||||||
+5
-4
@@ -7,7 +7,7 @@ namespace Slime {
|
|||||||
error = nullptr;
|
error = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_error(const char* c_func_name,const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void {
|
proc create_error(const char* c_func_name,const char* c_file_name, int c_file_line, Lisp_Object* type, String message) -> void {
|
||||||
delete_error();
|
delete_error();
|
||||||
if (Globals::breaking_on_errors) {
|
if (Globals::breaking_on_errors) {
|
||||||
debug_break();
|
debug_break();
|
||||||
@@ -36,8 +36,9 @@ namespace Slime {
|
|||||||
proc create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...) -> void {
|
proc create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...) -> void {
|
||||||
using Globals::error;
|
using Globals::error;
|
||||||
|
|
||||||
|
// TODO(Felix): is the length even used??
|
||||||
int length = 200;
|
int length = 200;
|
||||||
String* formatted_string = Memory::create_string("", length);
|
String formatted_string = Memory::create_string("", length);
|
||||||
if (error) {
|
if (error) {
|
||||||
error = new(Error);
|
error = new(Error);
|
||||||
error->type = type;
|
error->type = type;
|
||||||
@@ -49,8 +50,8 @@ namespace Slime {
|
|||||||
written_length = vasprintf(&out_msg, format, args);
|
written_length = vasprintf(&out_msg, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
formatted_string->length = written_length;
|
formatted_string.length = written_length;
|
||||||
strcpy(&formatted_string->data, out_msg);
|
strcpy(formatted_string.data, out_msg);
|
||||||
free(out_msg);
|
free(out_msg);
|
||||||
create_error(c_func_name, c_file_name, c_file_line, type, formatted_string);
|
create_error(c_func_name, c_file_name, c_file_line, type, formatted_string);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -31,7 +31,7 @@ namespace Slime {
|
|||||||
"Not enough positional args supplied. Needed: %d suppied, %d.\n"
|
"Not enough positional args supplied. Needed: %d suppied, %d.\n"
|
||||||
"Next missing arg is '%s'",
|
"Next missing arg is '%s'",
|
||||||
arg_spec->positional.symbols.next_index, arg_end-index_of_next_arg,
|
arg_spec->positional.symbols.next_index, arg_end-index_of_next_arg,
|
||||||
&arg_spec->positional.symbols.data[i]->value.symbol->data);
|
arg_spec->positional.symbols.data[i]->value.symbol.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// NOTE(Felix): We have to copy all the arguments,
|
// NOTE(Felix): We have to copy all the arguments,
|
||||||
@@ -75,7 +75,7 @@ namespace Slime {
|
|||||||
"The function does not take the keyword argument ':%s'\n"
|
"The function does not take the keyword argument ':%s'\n"
|
||||||
"and not all required keyword arguments have been read\n"
|
"and not all required keyword arguments have been read\n"
|
||||||
"in to potentially count it as the rest argument.",
|
"in to potentially count it as the rest argument.",
|
||||||
&(cs.data[index_of_next_arg]->value.symbol->data));
|
cs.data[index_of_next_arg]->value.symbol.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// This is an accepted kwarg; check if it was already
|
// This is an accepted kwarg; check if it was already
|
||||||
@@ -92,7 +92,7 @@ namespace Slime {
|
|||||||
// in, it is an error
|
// in, it is an error
|
||||||
create_generic_error(
|
create_generic_error(
|
||||||
"The function already read the keyword argument ':%s'",
|
"The function already read the keyword argument ':%s'",
|
||||||
&(cs.data[index_of_next_arg]->value.symbol->data));
|
cs.data[index_of_next_arg]->value.symbol.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ namespace Slime {
|
|||||||
if (index_of_next_arg+1 == arg_end) {
|
if (index_of_next_arg+1 == arg_end) {
|
||||||
create_generic_error(
|
create_generic_error(
|
||||||
"Attempting to set the keyword argument ':%s', but no value was supplied.",
|
"Attempting to set the keyword argument ':%s', but no value was supplied.",
|
||||||
&(cs.data[index_of_next_arg]->value.symbol->data));
|
cs.data[index_of_next_arg]->value.symbol.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ namespace Slime {
|
|||||||
create_generic_error(
|
create_generic_error(
|
||||||
"There was no value supplied for the required "
|
"There was no value supplied for the required "
|
||||||
"keyword argument ':%s'.",
|
"keyword argument ':%s'.",
|
||||||
&defined_keyword->value.symbol->data);
|
defined_keyword->value.symbol.data);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -240,7 +240,7 @@ namespace Slime {
|
|||||||
create_parsing_error("Only symbols and keywords "
|
create_parsing_error("Only symbols and keywords "
|
||||||
"(with or without default args) "
|
"(with or without default args) "
|
||||||
"can be parsed here, but found '%s'",
|
"can be parsed here, but found '%s'",
|
||||||
Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
|
lisp_object_type_to_string(Memory::get_type(arguments->value.pair.first)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ namespace Slime {
|
|||||||
free(t);
|
free(t);
|
||||||
};
|
};
|
||||||
create_generic_error("The first element of the pair was not a function but: %s in %s",
|
create_generic_error("The first element of the pair was not a function but: %s in %s",
|
||||||
Lisp_Object_Type_to_string(type), t);
|
lisp_object_type_to_string(type), t);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,7 +515,7 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc interprete_file (char* file_name) -> Lisp_Object* {
|
proc interprete_file (char* file_name) -> Lisp_Object* {
|
||||||
try Memory::init(4096 * 256);
|
try Memory::init();
|
||||||
|
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
|
|
||||||
@@ -525,7 +525,7 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc interprete_stdin() -> void {
|
proc interprete_stdin() -> void {
|
||||||
try_void Memory::init(4096 * 256* 100);
|
try_void Memory::init();
|
||||||
|
|
||||||
printf("Welcome to the lispy interpreter.\n%s\n", version_string);
|
printf("Welcome to the lispy interpreter.\n%s\n", version_string);
|
||||||
|
|
||||||
|
|||||||
+13
-12
@@ -1,11 +1,11 @@
|
|||||||
namespace Slime {
|
namespace Slime {
|
||||||
void add_to_load_path(const char*);
|
void add_to_load_path(const char*);
|
||||||
bool lisp_object_equal(Lisp_Object*,Lisp_Object*);
|
bool lisp_object_equal(Lisp_Object*,Lisp_Object*);
|
||||||
Lisp_Object* built_in_load(String*);
|
Lisp_Object* built_in_load(String);
|
||||||
Lisp_Object* built_in_import(String*);
|
Lisp_Object* built_in_import(String);
|
||||||
void delete_error();
|
void delete_error();
|
||||||
void create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...);
|
void create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...);
|
||||||
void create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, String* message);
|
void create_error(const char* c_func_name, const char* c_file_name, int c_file_line, Lisp_Object* type, String message);
|
||||||
void create_error(Lisp_Object* type, const char* message, const char* c_file_name, int c_file_line);
|
void create_error(Lisp_Object* type, const char* message, const char* c_file_name, int c_file_line);
|
||||||
Lisp_Object* eval_arguments(Lisp_Object*);
|
Lisp_Object* eval_arguments(Lisp_Object*);
|
||||||
Lisp_Object* eval_expr(Lisp_Object*);
|
Lisp_Object* eval_expr(Lisp_Object*);
|
||||||
@@ -28,23 +28,23 @@ namespace Slime {
|
|||||||
inline void push_environment(Environment*);
|
inline void push_environment(Environment*);
|
||||||
inline void pop_environment();
|
inline void pop_environment();
|
||||||
|
|
||||||
const char* Lisp_Object_Type_to_string(Lisp_Object_Type type);
|
const char* lisp_object_type_to_string(Lisp_Object_Type type);
|
||||||
|
|
||||||
void visualize_lisp_machine();
|
void visualize_lisp_machine();
|
||||||
void generate_docs(String* path);
|
void generate_docs(String path);
|
||||||
void log_error();
|
void log_error();
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
Environment* create_built_ins_environment();
|
Environment* create_built_ins_environment();
|
||||||
Lisp_Object* create_lisp_object_cfunction(bool is_special);
|
Lisp_Object* create_lisp_object_cfunction(bool is_special);
|
||||||
inline Lisp_Object_Type get_type(Lisp_Object* node);
|
inline Lisp_Object_Type get_type(Lisp_Object* node);
|
||||||
void init(int);
|
void init();
|
||||||
char* get_c_str(String*);
|
char* get_c_str(String);
|
||||||
void free_everything();
|
void free_everything();
|
||||||
String* create_string(const char*);
|
String create_string(const char*);
|
||||||
Lisp_Object* get_symbol(String* identifier);
|
Lisp_Object* get_symbol(String identifier);
|
||||||
Lisp_Object* get_symbol(const char*);
|
Lisp_Object* get_symbol(const char*);
|
||||||
Lisp_Object* get_keyword(String* identifier);
|
Lisp_Object* get_keyword(String identifier);
|
||||||
Lisp_Object* get_keyword(const char*);
|
Lisp_Object* get_keyword(const char*);
|
||||||
Lisp_Object* create_lisp_object(double);
|
Lisp_Object* create_lisp_object(double);
|
||||||
Lisp_Object* create_lisp_object(const char*);
|
Lisp_Object* create_lisp_object(const char*);
|
||||||
@@ -63,12 +63,13 @@ namespace Slime {
|
|||||||
namespace Parser {
|
namespace Parser {
|
||||||
// extern Environment* environment_for_macros;
|
// extern Environment* environment_for_macros;
|
||||||
|
|
||||||
extern String* standard_in;
|
extern String standard_in;
|
||||||
extern String* parser_file;
|
extern String parser_file;
|
||||||
extern int parser_line;
|
extern int parser_line;
|
||||||
extern int parser_col;
|
extern int parser_col;
|
||||||
|
|
||||||
Lisp_Object* parse_expression(char* text, int* index_in_text);
|
Lisp_Object* parse_expression(char* text, int* index_in_text);
|
||||||
|
Lisp_Object* parse_single_expression(const char* text);
|
||||||
Lisp_Object* parse_single_expression(char* text);
|
Lisp_Object* parse_single_expression(char* text);
|
||||||
Lisp_Object* parse_single_expression(wchar_t* text);
|
Lisp_Object* parse_single_expression(wchar_t* text);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -4,7 +4,7 @@ namespace Slime::GC {
|
|||||||
int current_mark;
|
int current_mark;
|
||||||
|
|
||||||
Array_List<Lisp_Object*> marked_objects;
|
Array_List<Lisp_Object*> marked_objects;
|
||||||
Array_List<String*> marked_strings;
|
Array_List<String> marked_strings;
|
||||||
Array_List<Environment*> marked_environments;
|
Array_List<Environment*> marked_environments;
|
||||||
Array_List<Environment*> protected_environments;
|
Array_List<Environment*> protected_environments;
|
||||||
|
|
||||||
@@ -24,8 +24,9 @@ namespace Slime::GC {
|
|||||||
marked_objects.append(node);
|
marked_objects.append(node);
|
||||||
|
|
||||||
// mark docstring
|
// mark docstring
|
||||||
if (node->docstring)
|
// TODO(Felix):
|
||||||
marked_strings.append(node->docstring);
|
// if (node->docstring)
|
||||||
|
// marked_strings.append(node->docstring);
|
||||||
|
|
||||||
// mark type specific data
|
// mark type specific data
|
||||||
switch (Memory::get_type(node)) {
|
switch (Memory::get_type(node)) {
|
||||||
|
|||||||
+7
-10
@@ -10,18 +10,15 @@ namespace Slime {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc string_equal(String* str, const char check[]) -> bool {
|
proc string_equal(String str, const char check[]) -> bool {
|
||||||
return string_equal(Memory::get_c_str(str), check);
|
return string_equal(Memory::get_c_str(str), check);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc string_equal(const char check[], String* str) -> bool {
|
proc string_equal(const char check[], String str) -> bool {
|
||||||
return string_equal(Memory::get_c_str(str), check);
|
return string_equal(Memory::get_c_str(str), check);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc string_equal(String* str1, String* str2) -> bool {
|
proc string_equal(String str1, String str2) -> bool {
|
||||||
if (str1 == str2)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return string_equal(Memory::get_c_str(str1), Memory::get_c_str(str2));
|
return string_equal(Memory::get_c_str(str1), Memory::get_c_str(str2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,9 +398,9 @@ namespace Slime {
|
|||||||
Lisp_Object* name = (Lisp_Object*)(get_root_environment()->hm.search_key_to_object(node));
|
Lisp_Object* name = (Lisp_Object*)(get_root_environment()->hm.search_key_to_object(node));
|
||||||
if (name) {
|
if (name) {
|
||||||
switch (node->value.function->type.c_function_type) {
|
switch (node->value.function->type.c_function_type) {
|
||||||
case C_Function_Type::cFunction: asprintf(&temp, "[c-function %s]",&((Lisp_Object*)name)->value.symbol->data); break;
|
case C_Function_Type::cFunction: asprintf(&temp, "[c-function %s]",name->value.symbol.data); break;
|
||||||
case C_Function_Type::cSpecial: asprintf(&temp, "[c-special %s]", &((Lisp_Object*)name)->value.symbol->data); break;
|
case C_Function_Type::cSpecial: asprintf(&temp, "[c-special %s]", name->value.symbol.data); break;
|
||||||
case C_Function_Type::cMacro: asprintf(&temp, "[c-macro %s]", &((Lisp_Object*)name)->value.symbol->data); break;
|
case C_Function_Type::cMacro: asprintf(&temp, "[c-macro %s]", name->value.symbol.data); break;
|
||||||
default: return strdup("[c-??]");
|
default: return strdup("[c-??]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -435,7 +432,7 @@ namespace Slime {
|
|||||||
// first check if it is a quotation form, in that case we want
|
// first check if it is a quotation form, in that case we want
|
||||||
// to print it prettier
|
// to print it prettier
|
||||||
if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Symbol) {
|
if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Symbol) {
|
||||||
String* identifier = head->value.pair.first->value.symbol;
|
String identifier = head->value.pair.first->value.symbol;
|
||||||
|
|
||||||
|
|
||||||
auto symbol = head->value.pair.first;
|
auto symbol = head->value.pair.first;
|
||||||
|
|||||||
+4
-4
@@ -47,15 +47,15 @@ unsigned int hm_hash(Slime::Lisp_Object* obj);
|
|||||||
# include "forward_decls.cpp"
|
# include "forward_decls.cpp"
|
||||||
|
|
||||||
|
|
||||||
bool hm_objects_match(char* a, char* b) {
|
inline bool hm_objects_match(char* a, char* b) {
|
||||||
return strcmp(a, b) == 0;
|
return strcmp(a, b) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hm_objects_match(void* a, void* b) {
|
inline bool hm_objects_match(void* a, void* b) {
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hm_objects_match(Slime::Lisp_Object* a, Slime::Lisp_Object* b) {
|
inline bool hm_objects_match(Slime::Lisp_Object* a, Slime::Lisp_Object* b) {
|
||||||
return Slime::lisp_object_equal(a, b);
|
return Slime::lisp_object_equal(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ unsigned int hm_hash(Slime::Lisp_Object* obj) {
|
|||||||
// different, they cauld be equivalent:
|
// different, they cauld be equivalent:
|
||||||
case Lisp_Object_Type::Pointer: return hm_hash((void*) obj->value.pointer);
|
case Lisp_Object_Type::Pointer: return hm_hash((void*) obj->value.pointer);
|
||||||
case Lisp_Object_Type::Number: return hm_hash((void*) (unsigned long long)obj->value.number); // HACK(Felix): yes
|
case Lisp_Object_Type::Number: return hm_hash((void*) (unsigned long long)obj->value.number); // HACK(Felix): yes
|
||||||
case Lisp_Object_Type::String: return hm_hash((char*) &obj->value.string->data);
|
case Lisp_Object_Type::String: return hm_hash((char*) obj->value.string.data);
|
||||||
case Lisp_Object_Type::Pair: {
|
case Lisp_Object_Type::Pair: {
|
||||||
u32 hash = 1;
|
u32 hash = 1;
|
||||||
for_lisp_list (obj) {
|
for_lisp_list (obj) {
|
||||||
|
|||||||
+3
-17
@@ -1,6 +1,6 @@
|
|||||||
namespace Slime {
|
namespace Slime {
|
||||||
proc create_source_code_location(String* file, int line, int col) -> Source_Code_Location* {
|
proc create_source_code_location(String file, int line, int col) -> Source_Code_Location* {
|
||||||
if (!file)
|
if (!file.data)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Source_Code_Location* ret = (Source_Code_Location*)malloc(sizeof(Source_Code_Location));
|
Source_Code_Location* ret = (Source_Code_Location*)malloc(sizeof(Source_Code_Location));
|
||||||
@@ -10,7 +10,7 @@ namespace Slime {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
|
proc lisp_object_type_to_string(Lisp_Object_Type type) -> const char* {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case(Lisp_Object_Type::Nil): return "nil";
|
case(Lisp_Object_Type::Nil): return "nil";
|
||||||
case(Lisp_Object_Type::T): return "t";
|
case(Lisp_Object_Type::T): return "t";
|
||||||
@@ -28,18 +28,4 @@ namespace Slime {
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object::~Lisp_Object() {
|
|
||||||
free(sourceCodeLocation);
|
|
||||||
sourceCodeLocation = 0;
|
|
||||||
|
|
||||||
switch (Memory::get_type(this)) {
|
|
||||||
case Lisp_Object_Type::Function:{
|
|
||||||
this->value.function->args.positional.symbols.dealloc();
|
|
||||||
this->value.function->args.keyword.keywords.dealloc();
|
|
||||||
this->value.function->args.keyword.values.dealloc();
|
|
||||||
free(this->value.function);
|
|
||||||
} break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -16,7 +16,7 @@ int main(int argc, char* argv[]) {
|
|||||||
int res = Slime::run_all_tests();
|
int res = Slime::run_all_tests();
|
||||||
return res ? 0 : 1;
|
return res ? 0 : 1;
|
||||||
} else if (Slime::string_equal(argv[1], "--generate-docs")) {
|
} else if (Slime::string_equal(argv[1], "--generate-docs")) {
|
||||||
Slime::Memory::init(4096 * 256* 100);
|
Slime::Memory::init();
|
||||||
if (Slime::Globals::error) return 1;
|
if (Slime::Globals::error) return 1;
|
||||||
Slime::built_in_load(Slime::Memory::create_string("generate-docs.slime"));
|
Slime::built_in_load(Slime::Memory::create_string("generate-docs.slime"));
|
||||||
} else {
|
} else {
|
||||||
@@ -28,5 +28,4 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Slime::Globals::error) return 1;
|
if (Slime::Globals::error) return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+113
-102
@@ -28,26 +28,11 @@ namespace Slime::Memory {
|
|||||||
// ------------------
|
// ------------------
|
||||||
Bucket_Allocator<Hash_Map<Lisp_Object*, Lisp_Object*>> hashmap_memory;
|
Bucket_Allocator<Hash_Map<Lisp_Object*, Lisp_Object*>> hashmap_memory;
|
||||||
|
|
||||||
// ------------------
|
|
||||||
// strings
|
|
||||||
// ------------------
|
|
||||||
int string_memory_size; // = 4096 * 1024; // == 98304kb == 96mb
|
|
||||||
// free_spots_in_string_memory is an arraylist of pointers into
|
|
||||||
// the string_memory, where dead String objects live (which give
|
|
||||||
// information about their size)
|
|
||||||
Array_List<void*> free_spots_in_string_memory;
|
|
||||||
String* string_memory;
|
|
||||||
String* next_free_spot_in_string_memory;
|
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// immutables
|
// immutables
|
||||||
// ------------------
|
// ------------------
|
||||||
Lisp_Object* nil = nullptr;
|
Lisp_Object* nil = nullptr;
|
||||||
Lisp_Object* t = nullptr;
|
Lisp_Object* t = nullptr;
|
||||||
Lisp_Object* _if = nullptr;
|
|
||||||
Lisp_Object* _define = nullptr;
|
|
||||||
Lisp_Object* _begin = nullptr;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc print_status() {
|
proc print_status() {
|
||||||
@@ -66,8 +51,8 @@ namespace Slime::Memory {
|
|||||||
// 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* {
|
||||||
return &str->data;
|
return str.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline proc get_c_str(Lisp_Object* str) -> char* {
|
inline proc get_c_str(Lisp_Object* str) -> char* {
|
||||||
@@ -89,64 +74,64 @@ namespace Slime::Memory {
|
|||||||
node->flags = (u64)(node->flags) | bitmask;
|
node->flags = (u64)(node->flags) | bitmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc hash(String* str) -> u64 {
|
proc hash(String str) -> u64 {
|
||||||
// TODO(Felix): When parsing symbols or keywords, compute the
|
// TODO(Felix): When parsing symbols or keywords, compute the
|
||||||
// hash while reading them in.
|
// hash while reading them in.
|
||||||
u64 value = str->data << 7;
|
u64 value = str.data[0] << 7;
|
||||||
for (int i = 1; i < str->length; ++i) {
|
for (int i = 1; i < str.length; ++i) {
|
||||||
char c = ((char*)&str->data)[i];
|
char c = str.data[i];
|
||||||
value = (1000003 * value) ^ c;
|
value = (1000003 * value) ^ c;
|
||||||
}
|
}
|
||||||
value ^= str->length;
|
value ^= str.length;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_string(const char* str, int len) -> String* {
|
proc create_string(const char* str, int len) -> String {
|
||||||
// TODO(Felix): check the holes first, not just always append
|
String s = {
|
||||||
// at the end
|
len,
|
||||||
|
(char*)malloc(sizeof(char) * len + 1)
|
||||||
String* ret = next_free_spot_in_string_memory;
|
};
|
||||||
ret->length = len;
|
strcpy(s.data, str);
|
||||||
strcpy(&ret->data, str);
|
return s;
|
||||||
|
|
||||||
// now update the next_free_spot_in_string_memory pointer:
|
|
||||||
// overstrep the counter and the first char (thik of it as if
|
|
||||||
// we were overstepping the last ('\0') char) and then we only
|
|
||||||
// need to overstep 'len' more chars
|
|
||||||
next_free_spot_in_string_memory += 1;
|
|
||||||
|
|
||||||
// overstep the other chars
|
|
||||||
next_free_spot_in_string_memory = ((String*)((char*)next_free_spot_in_string_memory)+len);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc delete_string(String* str) {
|
proc create_string (const char* str) -> String {
|
||||||
free_spots_in_string_memory.append((void*)str);
|
|
||||||
}
|
|
||||||
|
|
||||||
proc duplicate_string(String* str) -> String* {
|
|
||||||
return create_string(get_c_str(str), str->length);
|
|
||||||
}
|
|
||||||
|
|
||||||
proc create_string (const char* str) -> String* {
|
|
||||||
return create_string(str, (int)strlen(str));
|
return create_string(str, (int)strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc duplicate_string(String str) -> String {
|
||||||
|
return create_string(str.data, str.length);
|
||||||
|
}
|
||||||
|
|
||||||
proc create_lisp_object() -> Lisp_Object* {
|
proc create_lisp_object() -> Lisp_Object* {
|
||||||
Lisp_Object* object = object_memory.allocate();
|
Lisp_Object* object = object_memory.allocate();
|
||||||
object->flags = 0;
|
object->flags = 0;
|
||||||
object->sourceCodeLocation = nullptr;
|
object->sourceCodeLocation = nullptr;
|
||||||
object->userType = nullptr;
|
object->userType = nullptr;
|
||||||
object->docstring = nullptr;
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc free_everything() -> void {
|
proc free_everything() -> void {
|
||||||
free(string_memory);
|
|
||||||
object_memory.for_each([](Lisp_Object* lo){
|
object_memory.for_each([](Lisp_Object* lo){
|
||||||
lo->~Lisp_Object();
|
free(lo->sourceCodeLocation);
|
||||||
|
lo->sourceCodeLocation = 0;
|
||||||
|
|
||||||
|
switch (Memory::get_type(lo)) {
|
||||||
|
case Lisp_Object_Type::Function: {
|
||||||
|
lo->value.function->args.positional.symbols.dealloc();
|
||||||
|
lo->value.function->args.keyword.keywords.dealloc();
|
||||||
|
lo->value.function->args.keyword.values.dealloc();
|
||||||
|
free(lo->value.function);
|
||||||
|
} break;
|
||||||
|
case Lisp_Object_Type::Symbol:
|
||||||
|
case Lisp_Object_Type::Keyword:
|
||||||
|
case Lisp_Object_Type::String: {
|
||||||
|
free(lo->value.string.data);
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
environment_memory.for_each([](Environment* env){
|
environment_memory.for_each([](Environment* env){
|
||||||
env->parents.dealloc();
|
env->parents.dealloc();
|
||||||
@@ -155,6 +140,7 @@ namespace Slime::Memory {
|
|||||||
hashmap_memory.for_each([](Hash_Map<Lisp_Object*, Lisp_Object*>* hm){
|
hashmap_memory.for_each([](Hash_Map<Lisp_Object*, Lisp_Object*>* hm){
|
||||||
hm->dealloc();
|
hm->dealloc();
|
||||||
});
|
});
|
||||||
|
|
||||||
// free the exe dir:
|
// free the exe dir:
|
||||||
free(Globals::load_path.data[0]);
|
free(Globals::load_path.data[0]);
|
||||||
Globals::load_path.dealloc();
|
Globals::load_path.dealloc();
|
||||||
@@ -166,6 +152,8 @@ namespace Slime::Memory {
|
|||||||
Globals::Current_Execution::ats.dealloc();
|
Globals::Current_Execution::ats.dealloc();
|
||||||
Globals::Current_Execution::mes.dealloc();
|
Globals::Current_Execution::mes.dealloc();
|
||||||
|
|
||||||
|
free(Parser::standard_in.data);
|
||||||
|
|
||||||
object_memory.dealloc();
|
object_memory.dealloc();
|
||||||
environment_memory.dealloc();
|
environment_memory.dealloc();
|
||||||
hashmap_memory.dealloc();
|
hashmap_memory.dealloc();
|
||||||
@@ -197,7 +185,7 @@ namespace Slime::Memory {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc init(int sms) -> void {
|
proc init() -> void {
|
||||||
profile_this();
|
profile_this();
|
||||||
|
|
||||||
object_memory.alloc(1024, 8);
|
object_memory.alloc(1024, 8);
|
||||||
@@ -228,10 +216,6 @@ namespace Slime::Memory {
|
|||||||
add_to_load_path(exe_path);
|
add_to_load_path(exe_path);
|
||||||
add_to_load_path("../bin/");
|
add_to_load_path("../bin/");
|
||||||
|
|
||||||
string_memory_size = sms;
|
|
||||||
string_memory = (String*)malloc(string_memory_size * sizeof(char));
|
|
||||||
|
|
||||||
next_free_spot_in_string_memory = string_memory;
|
|
||||||
|
|
||||||
// init nil
|
// init nil
|
||||||
try_void nil = create_lisp_object();
|
try_void nil = create_lisp_object();
|
||||||
@@ -279,7 +263,7 @@ namespace Slime::Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object(String* str) -> Lisp_Object* {
|
proc create_lisp_object(String str) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::String);
|
set_type(node, Lisp_Object_Type::String);
|
||||||
@@ -368,53 +352,68 @@ namespace Slime::Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline proc _create_symbol(char* identifier) -> Lisp_Object* {
|
||||||
|
Lisp_Object* node;
|
||||||
proc get_symbol(String* identifier) -> Lisp_Object* {
|
|
||||||
Lisp_Object* node = global_symbol_table.get_object(get_c_str(identifier));
|
|
||||||
if (node)
|
|
||||||
return (Lisp_Object*)node;
|
|
||||||
|
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Symbol);
|
set_type(node, Lisp_Object_Type::Symbol);
|
||||||
node->value.symbol = identifier;
|
node->value.symbol = create_string(identifier);
|
||||||
global_symbol_table.set_object(get_c_str(identifier), node);
|
global_symbol_table.set_object((char*)node->value.symbol.data, node);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc get_symbol(const char* identifier) -> Lisp_Object* {
|
inline proc get_symbol(String identifier) -> Lisp_Object* {
|
||||||
if (auto ret = global_symbol_table.get_object((char*)identifier))
|
return get_symbol(identifier.data);
|
||||||
return (Lisp_Object*)ret;
|
|
||||||
else {
|
|
||||||
String* str;
|
|
||||||
try str = Memory::create_string(identifier);
|
|
||||||
return get_symbol(str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc get_keyword(String* keyword) -> Lisp_Object* {
|
inline proc get_symbol(const char* identifier) -> Lisp_Object* {
|
||||||
Lisp_Object* node = global_keyword_table.get_object(get_c_str(keyword));
|
if (Lisp_Object* ret = global_symbol_table.get_object((char*)identifier))
|
||||||
if (node)
|
return (Lisp_Object*)ret;
|
||||||
return (Lisp_Object*)node;
|
return _create_symbol((char*)identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline proc _create_keyword(char* identifier) -> Lisp_Object* {
|
||||||
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Keyword);
|
set_type(node, Lisp_Object_Type::Keyword);
|
||||||
node->value.symbol = keyword;
|
node->value.symbol = create_string(identifier);
|
||||||
global_keyword_table.set_object(get_c_str(keyword), node);
|
global_keyword_table.set_object((char*)node->value.symbol.data, node);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline proc get_keyword(String identifier) -> Lisp_Object* {
|
||||||
proc get_keyword(const char* keyword) -> Lisp_Object* {
|
return get_keyword(identifier.data);
|
||||||
if (auto ret = global_keyword_table.get_object((char*)keyword))
|
|
||||||
return (Lisp_Object*)ret;
|
|
||||||
else {
|
|
||||||
String* str;
|
|
||||||
try str = Memory::create_string(keyword);
|
|
||||||
return get_keyword(str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline proc get_keyword(const char* identifier) -> Lisp_Object* {
|
||||||
|
if (Lisp_Object* ret = global_keyword_table.get_object((char*)identifier))
|
||||||
|
return ret;
|
||||||
|
return _create_keyword((char*)identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// proc get_keyword(String keyword) -> Lisp_Object* {
|
||||||
|
// Lisp_Object* node = global_keyword_table.get_object(get_c_str(keyword));
|
||||||
|
// if (node)
|
||||||
|
// return (Lisp_Object*)node;
|
||||||
|
|
||||||
|
// try node = create_lisp_object();
|
||||||
|
// set_type(node, Lisp_Object_Type::Keyword);
|
||||||
|
// node->value.symbol = duplicate_string(keyword);
|
||||||
|
// global_keyword_table.set_object(get_c_str(keyword), node);
|
||||||
|
// return node;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// proc get_keyword(const char* keyword) -> Lisp_Object* {
|
||||||
|
// if (auto ret = global_keyword_table.get_object((char*)keyword))
|
||||||
|
// return (Lisp_Object*)ret;
|
||||||
|
// else {
|
||||||
|
// String str;
|
||||||
|
// try str = Memory::create_string(keyword);
|
||||||
|
// return get_keyword(str);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
proc create_lisp_object_cfunction(C_Function_Type type) -> Lisp_Object* {
|
proc create_lisp_object_cfunction(C_Function_Type type) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
@@ -455,19 +454,29 @@ namespace Slime::Memory {
|
|||||||
// TODO(Felix): If argument is a list (pair), do a FULL copy,
|
// TODO(Felix): If argument is a list (pair), do a FULL copy,
|
||||||
|
|
||||||
// we don't copy singleton objects
|
// we don't copy singleton objects
|
||||||
if (n == Memory::nil || n == Memory::t ||
|
if (n == Memory::nil || n == Memory::t) {
|
||||||
Memory::get_type(n) == Lisp_Object_Type::Symbol ||
|
|
||||||
Memory::get_type(n) == Lisp_Object_Type::Keyword ||
|
|
||||||
Memory::get_type(n) == Lisp_Object_Type::Function)
|
|
||||||
{
|
|
||||||
return n;
|
return n;
|
||||||
|
} else {
|
||||||
|
Lisp_Object_Type type = Memory::get_type(n);
|
||||||
|
if (type == Lisp_Object_Type::Symbol ||
|
||||||
|
type == Lisp_Object_Type::Keyword ||
|
||||||
|
type == Lisp_Object_Type::Function)
|
||||||
|
{
|
||||||
|
return n;
|
||||||
|
} else if (type == Lisp_Object_Type::String) {
|
||||||
|
Lisp_Object* target;
|
||||||
|
try target = create_lisp_object();
|
||||||
|
*target = *n;
|
||||||
|
target->value.string = create_string(target->value.string.data);
|
||||||
|
return target;
|
||||||
|
} else {
|
||||||
|
Lisp_Object* target;
|
||||||
|
try target = create_lisp_object();
|
||||||
|
*target = *n;
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* target;
|
|
||||||
try target = create_lisp_object();
|
|
||||||
*target = *n;
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc copy_lisp_object_except_pairs(Lisp_Object* n) -> Lisp_Object* {
|
proc copy_lisp_object_except_pairs(Lisp_Object* n) -> Lisp_Object* {
|
||||||
@@ -485,11 +494,13 @@ namespace Slime::Memory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try load_built_ins_into_environment();
|
try load_built_ins_into_environment();
|
||||||
try built_in_load(Memory::create_string("pre.slime"));
|
String file_name = Memory::create_string("pre.slime");
|
||||||
|
try built_in_load(file_name);
|
||||||
|
free(file_name.data);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline proc create_list(Lisp_Object* o1) -> Lisp_Object* {
|
inline proc create_list(Lisp_Object* o1) -> Lisp_Object* {
|
||||||
Lisp_Object* ret;
|
Lisp_Object* ret;
|
||||||
try ret = create_lisp_object_pair(o1, nil);
|
try ret = create_lisp_object_pair(o1, nil);
|
||||||
|
|||||||
+22
-12
@@ -1,6 +1,6 @@
|
|||||||
namespace Slime::Parser {
|
namespace Slime::Parser {
|
||||||
String* standard_in;
|
String standard_in;
|
||||||
String* parser_file;
|
String parser_file;
|
||||||
int parser_line;
|
int parser_line;
|
||||||
int parser_col;
|
int parser_col;
|
||||||
|
|
||||||
@@ -126,15 +126,15 @@ namespace Slime::Parser {
|
|||||||
text[*index_in_text+atom_length] = '\0';
|
text[*index_in_text+atom_length] = '\0';
|
||||||
|
|
||||||
|
|
||||||
String* str_keyword;
|
// String str_keyword;
|
||||||
Lisp_Object* ret;
|
// try str_keyword = Memory::create_string("", atom_length);
|
||||||
try str_keyword = Memory::create_string("", atom_length);
|
// strcpy(str_keyword.data, text+*index_in_text);
|
||||||
strcpy(&str_keyword->data, text+*index_in_text);
|
|
||||||
|
|
||||||
|
Lisp_Object* ret;
|
||||||
if (keyword) {
|
if (keyword) {
|
||||||
try ret = Memory::get_keyword(str_keyword);
|
try ret = Memory::get_keyword(text+*index_in_text);
|
||||||
} else {
|
} else {
|
||||||
try ret = Memory::get_symbol(str_keyword);
|
try ret = Memory::get_symbol(text+*index_in_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -184,9 +184,9 @@ namespace Slime::Parser {
|
|||||||
int new_len;
|
int new_len;
|
||||||
try new_len = unescape_string(text+(*index_in_text));
|
try new_len = unescape_string(text+(*index_in_text));
|
||||||
|
|
||||||
String* string = Memory::create_string("", new_len);
|
String string = Memory::create_string("", new_len);
|
||||||
|
|
||||||
strcpy(&string->data, text+(*index_in_text));
|
strcpy(string.data, text+(*index_in_text));
|
||||||
// printf("------ %s\n", &string->data);
|
// printf("------ %s\n", &string->data);
|
||||||
|
|
||||||
text[*index_in_text+string_length] = '"';
|
text[*index_in_text+string_length] = '"';
|
||||||
@@ -359,10 +359,20 @@ namespace Slime::Parser {
|
|||||||
|
|
||||||
proc parse_single_expression(wchar_t* text) -> Lisp_Object* {
|
proc parse_single_expression(wchar_t* text) -> Lisp_Object* {
|
||||||
char* res = wchar_to_char(text);
|
char* res = wchar_to_char(text);
|
||||||
defer {free(res);};
|
defer_free(res);
|
||||||
|
|
||||||
return parse_single_expression(res);
|
return parse_single_expression(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc parse_single_expression(const char* text) -> Lisp_Object* {
|
||||||
|
String s = Memory::create_string(text);
|
||||||
|
defer_free(s.data);
|
||||||
|
|
||||||
|
Lisp_Object* ret;
|
||||||
|
try ret = parse_single_expression(s.data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
proc parse_single_expression(char* text) -> Lisp_Object* {
|
proc parse_single_expression(char* text) -> Lisp_Object* {
|
||||||
parser_file = standard_in;
|
parser_file = standard_in;
|
||||||
parser_line = 1;
|
parser_line = 1;
|
||||||
@@ -375,7 +385,7 @@ namespace Slime::Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*>* {
|
proc parse_program(String file_name, char* text) -> Array_List<Lisp_Object*>* {
|
||||||
profile_this();
|
profile_this();
|
||||||
parser_file = file_name;
|
parser_file = file_name;
|
||||||
parser_line = 1;
|
parser_line = 1;
|
||||||
|
|||||||
+6
-8
@@ -71,12 +71,12 @@ namespace Slime {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct String {
|
struct String {
|
||||||
int length;
|
int length;
|
||||||
char data;
|
char* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Source_Code_Location {
|
struct Source_Code_Location {
|
||||||
String* file;
|
String file;
|
||||||
int line;
|
int line;
|
||||||
int column;
|
int column;
|
||||||
};
|
};
|
||||||
@@ -135,11 +135,10 @@ namespace Slime {
|
|||||||
Source_Code_Location* sourceCodeLocation;
|
Source_Code_Location* sourceCodeLocation;
|
||||||
u64 flags;
|
u64 flags;
|
||||||
Lisp_Object* userType; // keyword
|
Lisp_Object* userType; // keyword
|
||||||
String* docstring;
|
|
||||||
union value {
|
union value {
|
||||||
String* symbol; // used for symbols and keywords
|
String symbol; // used for symbols and keywords
|
||||||
double number;
|
double number;
|
||||||
String* string;
|
String string;
|
||||||
Pair pair;
|
Pair pair;
|
||||||
Vector vector;
|
Vector vector;
|
||||||
Function* function;
|
Function* function;
|
||||||
@@ -148,13 +147,12 @@ namespace Slime {
|
|||||||
Hash_Map<Lisp_Object*, Lisp_Object*>* hashMap;
|
Hash_Map<Lisp_Object*, Lisp_Object*>* hashMap;
|
||||||
~value() {}
|
~value() {}
|
||||||
} value;
|
} value;
|
||||||
~Lisp_Object();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Error {
|
struct Error {
|
||||||
Lisp_Object* position;
|
Lisp_Object* position;
|
||||||
// type has to be a keyword
|
// type has to be a keyword
|
||||||
Lisp_Object* type;
|
Lisp_Object* type;
|
||||||
String* message;
|
String message;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-7
@@ -60,15 +60,15 @@ namespace Slime {
|
|||||||
|
|
||||||
#define assert_equal_string(variable, value) \
|
#define assert_equal_string(variable, value) \
|
||||||
if (!string_equal(variable, value)) { \
|
if (!string_equal(variable, value)) { \
|
||||||
print_assert_equal_fail(&variable->data, value, char*, "%s"); \
|
print_assert_equal_fail(variable.data, value, char*, "%s"); \
|
||||||
return fail; \
|
return fail; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define assert_equal_type(node, _type) \
|
#define assert_equal_type(node, _type) \
|
||||||
if (Memory::get_type(node) != _type) { \
|
if (Memory::get_type(node) != _type) { \
|
||||||
print_assert_equal_fail( \
|
print_assert_equal_fail( \
|
||||||
Lisp_Object_Type_to_string(Memory::get_type(node)), \
|
lisp_object_type_to_string(Memory::get_type(node)), \
|
||||||
Lisp_Object_Type_to_string(_type), char*, "%s"); \
|
lisp_object_type_to_string(_type), char*, "%s"); \
|
||||||
return fail; \
|
return fail; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
@@ -555,8 +555,15 @@ namespace Slime {
|
|||||||
proc test_singular_symbols() -> testresult {
|
proc test_singular_symbols() -> testresult {
|
||||||
auto cc_s_aa = Memory::get_symbol("aa");
|
auto cc_s_aa = Memory::get_symbol("aa");
|
||||||
auto cc_s_aa2 = Memory::get_symbol("aa2");
|
auto cc_s_aa2 = Memory::get_symbol("aa2");
|
||||||
auto s_s_aa = Memory::get_symbol(Memory::create_string("aa"));
|
|
||||||
auto s_s_aa2 = Memory::get_symbol(Memory::create_string("aa2"));
|
String s1 = Memory::create_string("aa");
|
||||||
|
String s2 = Memory::create_string("aa2");
|
||||||
|
|
||||||
|
auto s_s_aa = Memory::get_symbol(s1);
|
||||||
|
auto s_s_aa2 = Memory::get_symbol(s2);
|
||||||
|
|
||||||
|
free(s1.data);
|
||||||
|
free(s2.data);
|
||||||
|
|
||||||
assert_equal_int(cc_s_aa, s_s_aa);
|
assert_equal_int(cc_s_aa, s_s_aa);
|
||||||
assert_equal_int(cc_s_aa2, s_s_aa2);
|
assert_equal_int(cc_s_aa2, s_s_aa2);
|
||||||
@@ -571,7 +578,9 @@ namespace Slime {
|
|||||||
// assert_no_error();
|
// assert_no_error();
|
||||||
|
|
||||||
push_environment(Memory::create_child_environment(get_current_environment()));
|
push_environment(Memory::create_child_environment(get_current_environment()));
|
||||||
built_in_load(Memory::create_string(file));
|
String name = Memory::create_string(file);
|
||||||
|
built_in_load(name);
|
||||||
|
free(name.data);
|
||||||
assert_no_error();
|
assert_no_error();
|
||||||
pop_environment();
|
pop_environment();
|
||||||
|
|
||||||
@@ -582,7 +591,7 @@ namespace Slime {
|
|||||||
profile_this();
|
profile_this();
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
try Memory::init(409600);
|
try Memory::init();
|
||||||
|
|
||||||
push_environment(Memory::create_child_environment(
|
push_environment(Memory::create_child_environment(
|
||||||
get_current_environment()));
|
get_current_environment()));
|
||||||
|
|||||||
Reference in New Issue
Block a user