浏览代码

Big String refacor: now len+pointer, no String storage anymore

master
Felix Brendel 6 年前
父节点
当前提交
9295d57a8e
共有 21 个文件被更改,包括 275 次插入248 次删除
  1. +1
    -1
      3rd/ftb
  2. +9
    -7
      bin/pre.slime
  3. +2
    -2
      include/assert.hpp
  4. +1
    -1
      include/libslime.h
  5. +2
    -2
      src/assert.hpp
  6. +36
    -28
      src/built_ins.cpp
  7. +11
    -8
      src/define_macros.hpp
  8. +6
    -5
      src/docgeneration.cpp
  9. +6
    -6
      src/env.cpp
  10. +5
    -4
      src/error.cpp
  11. +9
    -9
      src/eval.cpp
  12. +13
    -12
      src/forward_decls.cpp
  13. +4
    -3
      src/gc.cpp
  14. +7
    -10
      src/io.cpp
  15. +4
    -4
      src/libslime.cpp
  16. +3
    -17
      src/lisp_object.cpp
  17. +1
    -2
      src/main.cpp
  18. +111
    -100
      src/memory.cpp
  19. +22
    -12
      src/parse.cpp
  20. +6
    -8
      src/structs.cpp
  21. +16
    -7
      src/testing.cpp

+ 1
- 1
3rd/ftb

@@ -1 +1 @@
Subproject commit 98aa1450d8e63046d3260ea7fb4ff12c9c7e2629
Subproject commit e5cb9ce81d822fee56bdef1f44b3f8d1a29618de

+ 9
- 7
bin/pre.slime 查看文件

@@ -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
include/assert.hpp 查看文件

@@ -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(Memory::get_type(_node))); \
lisp_object_type_to_string(_type), \
lisp_object_type_to_string(Memory::get_type(_node))); \
} \ } \
} while(0) } while(0)


+ 1
- 1
include/libslime.h 查看文件

@@ -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
src/assert.hpp 查看文件

@@ -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(Memory::get_type(_node)), \
lisp_object_type_to_string(_type), \
lisp_object_type_to_string(Memory::get_type(_node)), \
t); \ t); \
} \ } \
} while(0) } while(0)


+ 36
- 28
src/built_ins.cpp 查看文件

@@ -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* {
profile_with_comment(&file_name->data);
proc built_in_load(String file_name) -> Lisp_Object* {
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);
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;
}
fetch(form, body);
// TODO(Felix): Macros cannot have docs now
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)
? Memory::get_c_str(val->docstring)
: "No docs avaliable");
// TODO(felix): Doc HM lookup
// (val->docstring)
// ? 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
src/define_macros.hpp 查看文件

@@ -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
// able to temporaily put in markers in the code and also it will fill
// out the source code location
#define _define_helper(def, docs, type, ending) \
// mutable for the parser to work, (#def gives us a const char)
// because the parser relys on being able to temporaily put in markers
// in the code and also it will fill out the source code location
#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( \
Memory::get_c_str(Memory::create_string(#def))); \
auto label(params,__LINE__) = Parser::parse_single_expression(#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)

+ 6
- 5
src/docgeneration.cpp 查看文件

@@ -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)
fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
Memory::get_c_str(value->docstring));
else
// TODO(Felix): make docsting a hashmap lookup
// if (value->docstring)
// fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
// Memory::get_c_str(value->docstring));
// else
fprintf(f, "none\n"); fprintf(f, "none\n");
} }
} }


+ 6
- 6
src/env.cpp 查看文件

@@ -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
src/error.cpp 查看文件

@@ -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;
strcpy(&formatted_string->data, out_msg);
formatted_string.length = written_length;
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
src/eval.cpp 查看文件

@@ -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
src/forward_decls.cpp 查看文件

@@ -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_import(String*);
Lisp_Object* built_in_load(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);
char* get_c_str(String*);
void init();
char* get_c_str(String);
void free_everything(); void free_everything();
String* create_string(const char*);
Lisp_Object* get_symbol(String* identifier);
String create_string(const char*);
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* parser_file;
extern String standard_in;
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
src/gc.cpp 查看文件

@@ -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)
marked_strings.append(node->docstring);
// TODO(Felix):
// 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
src/io.cpp 查看文件

@@ -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 {
if (str1 == str2)
return true;
proc string_equal(String str1, String str2) -> bool {
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::cSpecial: asprintf(&temp, "[c-special %s]", &((Lisp_Object*)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::cFunction: asprintf(&temp, "[c-function %s]",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]", 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
src/libslime.cpp 查看文件

@@ -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
src/lisp_object.cpp 查看文件

@@ -1,6 +1,6 @@
namespace Slime { namespace Slime {
proc create_source_code_location(String* file, int line, int col) -> Source_Code_Location* {
if (!file)
proc create_source_code_location(String file, int line, int col) -> Source_Code_Location* {
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
src/main.cpp 查看文件

@@ -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;
} }

+ 111
- 100
src/memory.cpp 查看文件

@@ -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* {
return &str->data;
inline proc get_c_str(String str) -> char* {
return str.data;
} }
inline proc get_c_str(Lisp_Object* str) -> char* { inline proc get_c_str(Lisp_Object* str) -> char* {
@@ -89,49 +74,35 @@ 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;
for (int i = 1; i < str->length; ++i) {
char c = ((char*)&str->data)[i];
u64 value = str.data[0] << 7;
for (int i = 1; i < str.length; ++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* {
// TODO(Felix): check the holes first, not just always append
// at the end
String* ret = next_free_spot_in_string_memory;
ret->length = len;
strcpy(&ret->data, str);
// 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) {
free_spots_in_string_memory.append((void*)str);
proc create_string(const char* str, int len) -> String {
String s = {
len,
(char*)malloc(sizeof(char) * len + 1)
};
strcpy(s.data, str);
return s;
} }
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));
} }
proc create_string (const char* str) -> String* {
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* {
@@ -139,14 +110,28 @@ namespace Slime::Memory {
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;
} }
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;
inline proc _create_symbol(char* identifier) -> Lisp_Object* {
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;
global_symbol_table.set_object(get_c_str(identifier), node);
node->value.symbol = create_string(identifier);
global_symbol_table.set_object((char*)node->value.symbol.data, node);
return node; return node;
} }
proc get_symbol(const char* identifier) -> Lisp_Object* {
if (auto ret = global_symbol_table.get_object((char*)identifier))
return (Lisp_Object*)ret;
else {
String* str;
try str = Memory::create_string(identifier);
return get_symbol(str);
}
inline proc get_symbol(String identifier) -> Lisp_Object* {
return get_symbol(identifier.data);
} }
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;
inline proc get_symbol(const char* identifier) -> Lisp_Object* {
if (Lisp_Object* ret = global_symbol_table.get_object((char*)identifier))
return (Lisp_Object*)ret;
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;
global_keyword_table.set_object(get_c_str(keyword), node);
node->value.symbol = create_string(identifier);
global_keyword_table.set_object((char*)node->value.symbol.data, node);
return node; return node;
} }
inline proc get_keyword(String identifier) -> Lisp_Object* {
return get_keyword(identifier.data);
}
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);
}
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 ||
Memory::get_type(n) == Lisp_Object_Type::Symbol ||
Memory::get_type(n) == Lisp_Object_Type::Keyword ||
Memory::get_type(n) == Lisp_Object_Type::Function)
{
if (n == Memory::nil || n == Memory::t) {
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
src/parse.cpp 查看文件

@@ -1,6 +1,6 @@
namespace Slime::Parser { namespace Slime::Parser {
String* standard_in;
String* parser_file;
String standard_in;
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;
Lisp_Object* ret;
try str_keyword = Memory::create_string("", atom_length);
strcpy(&str_keyword->data, text+*index_in_text);
// String str_keyword;
// try str_keyword = Memory::create_string("", atom_length);
// 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
src/structs.cpp 查看文件

@@ -71,12 +71,12 @@ namespace Slime {
}; };


struct String { struct String {
int length;
char data;
int length;
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
src/testing.cpp 查看文件

@@ -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(_type), char*, "%s"); \
lisp_object_type_to_string(Memory::get_type(node)), \
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()));


正在加载...
取消
保存