Docs is stored external to the lisp objects in a hashmap now
This commit is contained in:
@@ -52,7 +52,7 @@ echo ""
|
|||||||
echo "----------------------"
|
echo "----------------------"
|
||||||
echo " running profile "
|
echo " running profile "
|
||||||
echo "----------------------"
|
echo "----------------------"
|
||||||
time ./slime_p --run-tests || exit 1
|
time ./slime_p --run-tests > /dev/null || exit 1
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "------------------------"
|
echo "------------------------"
|
||||||
|
|||||||
+2
-2
@@ -31,12 +31,12 @@
|
|||||||
|
|
||||||
#define assert_type(_node, _type) \
|
#define assert_type(_node, _type) \
|
||||||
do { \
|
do { \
|
||||||
if (Memory::get_type(_node) != _type) { \
|
if (_node->type != _type) { \
|
||||||
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(_node->type), \
|
||||||
t); \
|
t); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
+34
-30
@@ -2,10 +2,10 @@ namespace Slime {
|
|||||||
proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
||||||
if (n1 == n2)
|
if (n1 == n2)
|
||||||
return true;
|
return true;
|
||||||
if (Memory::get_type(n1) != Memory::get_type(n2))
|
if (n1->type != n2->type)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (Memory::get_type(n1)) {
|
switch (n1->type) {
|
||||||
|
|
||||||
case Lisp_Object_Type::T:
|
case Lisp_Object_Type::T:
|
||||||
case Lisp_Object_Type::Nil:
|
case Lisp_Object_Type::Nil:
|
||||||
@@ -299,7 +299,7 @@ namespace Slime {
|
|||||||
Lisp_Object* thing = form->value.pair.first;
|
Lisp_Object* thing = form->value.pair.first;
|
||||||
Lisp_Object* thing_cons = form;
|
Lisp_Object* thing_cons = form;
|
||||||
form = form->value.pair.rest;
|
form = form->value.pair.rest;
|
||||||
Lisp_Object_Type type = Memory::get_type(definee);
|
Lisp_Object_Type type = definee->type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Lisp_Object_Type::Symbol: {
|
case Lisp_Object_Type::Symbol: {
|
||||||
if (form != Memory::nil) {
|
if (form != Memory::nil) {
|
||||||
@@ -322,12 +322,14 @@ namespace Slime {
|
|||||||
try_void func = Memory::create_lisp_object_function(Lisp_Function_Type::Lambda);
|
try_void func = Memory::create_lisp_object_function(Lisp_Function_Type::Lambda);
|
||||||
func->value.function->parent_environment = get_current_environment();
|
func->value.function->parent_environment = get_current_environment();
|
||||||
create_arguments_from_lambda_list_and_inject(definee->value.pair.rest, func);
|
create_arguments_from_lambda_list_and_inject(definee->value.pair.rest, func);
|
||||||
if (Memory::get_type(thing_cons->value.pair.first) == Lisp_Object_Type::String &&
|
if (thing_cons->value.pair.first->type == Lisp_Object_Type::String &&
|
||||||
thing_cons->value.pair.rest != Memory::nil)
|
thing_cons->value.pair.rest != Memory::nil)
|
||||||
{
|
{
|
||||||
// extract docs
|
// extract docs
|
||||||
//TODO(Felix): make docs as HM lookup
|
Globals::docs.set_object(
|
||||||
// func->docstring = thing_cons->value.pair.first->value.string;
|
func,
|
||||||
|
Memory::duplicate_string(
|
||||||
|
thing_cons->value.pair.first->value.string).data);
|
||||||
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);
|
||||||
@@ -560,7 +562,7 @@ namespace Slime {
|
|||||||
profile_with_name("(gensym)");
|
profile_with_name("(gensym)");
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = Memory::create_lisp_object();
|
try node = Memory::create_lisp_object();
|
||||||
Memory::set_type(node, Lisp_Object_Type::Symbol);
|
node->type = Lisp_Object_Type::Symbol;
|
||||||
node->value.symbol = Memory::create_string("gensym");
|
node->value.symbol = Memory::create_string("gensym");
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
@@ -598,7 +600,7 @@ namespace Slime {
|
|||||||
fetch(form, body);
|
fetch(form, body);
|
||||||
// TODO(Felix): Macros cannot have docs now
|
// TODO(Felix): Macros cannot have docs now
|
||||||
|
|
||||||
if (Memory::get_type(form) != Lisp_Object_Type::Pair) {
|
if (form->type != Lisp_Object_Type::Pair) {
|
||||||
create_parsing_error("You can only create function macros.");
|
create_parsing_error("You can only create function macros.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -624,16 +626,16 @@ namespace Slime {
|
|||||||
|
|
||||||
if (target == Memory::nil ||
|
if (target == Memory::nil ||
|
||||||
target == Memory::t ||
|
target == Memory::t ||
|
||||||
Memory::get_type(target) == Lisp_Object_Type::Keyword ||
|
target->type == Lisp_Object_Type::Keyword ||
|
||||||
Memory::get_type(target) == Lisp_Object_Type::Symbol)
|
target->type == Lisp_Object_Type::Symbol)
|
||||||
{
|
{
|
||||||
create_generic_error("You cannot mutate to nil, t, keywords or symbols because they have to be unique");
|
create_generic_error("You cannot mutate to nil, t, keywords or symbols because they have to be unique");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source == Memory::nil ||
|
if (source == Memory::nil ||
|
||||||
source == Memory::t ||
|
source == Memory::t ||
|
||||||
Memory::get_type(source) == Lisp_Object_Type::Keyword ||
|
source->type == Lisp_Object_Type::Keyword ||
|
||||||
Memory::get_type(source) == Lisp_Object_Type::Symbol)
|
source->type == Lisp_Object_Type::Symbol)
|
||||||
{
|
{
|
||||||
create_generic_error("You cannot mutate nil, t, keywords or symbols");
|
create_generic_error("You cannot mutate nil, t, keywords or symbols");
|
||||||
}
|
}
|
||||||
@@ -731,7 +733,7 @@ namespace Slime {
|
|||||||
// a recursive lambda
|
// a recursive lambda
|
||||||
const auto unquoteSomeExpressions = [&] (const auto & self, Lisp_Object* expr) -> Lisp_Object* {
|
const auto unquoteSomeExpressions = [&] (const auto & self, Lisp_Object* expr) -> Lisp_Object* {
|
||||||
// if it is an atom, return it
|
// if it is an atom, return it
|
||||||
if (Memory::get_type(expr) != Lisp_Object_Type::Pair)
|
if (expr->type != Lisp_Object_Type::Pair)
|
||||||
return Memory::copy_lisp_object(expr);
|
return Memory::copy_lisp_object(expr);
|
||||||
|
|
||||||
// it is a pair!
|
// it is a pair!
|
||||||
@@ -766,10 +768,10 @@ namespace Slime {
|
|||||||
Lisp_Object* newPairHead = newPair;
|
Lisp_Object* newPairHead = newPair;
|
||||||
Lisp_Object* head = expr;
|
Lisp_Object* head = expr;
|
||||||
|
|
||||||
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
|
while (head->type == Lisp_Object_Type::Pair) {
|
||||||
// if it is ,@ we have to actually do more work
|
// if it is ,@ we have to actually do more work
|
||||||
// and inline the result
|
// and inline the result
|
||||||
if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Pair &&
|
if (head->value.pair.first->type == Lisp_Object_Type::Pair &&
|
||||||
head->value.pair.first->value.pair.first == unquote_splicing_sym)
|
head->value.pair.first->value.pair.first == unquote_splicing_sym)
|
||||||
{
|
{
|
||||||
Lisp_Object* spliced = self(self, head->value.pair.first);
|
Lisp_Object* spliced = self(self, head->value.pair.first);
|
||||||
@@ -947,24 +949,27 @@ namespace Slime {
|
|||||||
profile_with_name("(set-type!)");
|
profile_with_name("(set-type!)");
|
||||||
fetch(node, new_type);
|
fetch(node, new_type);
|
||||||
try assert_type(new_type, Lisp_Object_Type::Keyword);
|
try assert_type(new_type, Lisp_Object_Type::Keyword);
|
||||||
node->userType = new_type;
|
// TODO(Felix): Enable again when we have user types again:
|
||||||
|
// node->userType = new_type;
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
define((delete-type! n), "TODO") {
|
define((delete-type! n), "TODO") {
|
||||||
profile_with_name("(delete-type!)");
|
profile_with_name("(delete-type!)");
|
||||||
fetch(n);
|
fetch(n);
|
||||||
n->userType = nullptr;
|
// TODO(Felix): Enable again when we have user types again:
|
||||||
|
// n->userType = nullptr;
|
||||||
return Memory::t;
|
return Memory::t;
|
||||||
};
|
};
|
||||||
define((type n), "TODO") {
|
define((type n), "TODO") {
|
||||||
profile_with_name("(type)");
|
profile_with_name("(type)");
|
||||||
fetch(n);
|
fetch(n);
|
||||||
|
|
||||||
if (n->userType) {
|
// TODO(Felix): Enable again when we have user types again:
|
||||||
return n->userType;
|
// if (n->userType) {
|
||||||
}
|
// return n->userType;
|
||||||
|
// }
|
||||||
|
|
||||||
Lisp_Object_Type type = Memory::get_type(n);
|
Lisp_Object_Type type = n->type;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Lisp_Object_Type::Continuation: return Memory::get_keyword("continuation");
|
case Lisp_Object_Type::Continuation: return Memory::get_keyword("continuation");
|
||||||
@@ -995,6 +1000,8 @@ namespace Slime {
|
|||||||
case Lisp_Object_Type::Symbol: return Memory::get_keyword("symbol");
|
case Lisp_Object_Type::Symbol: return Memory::get_keyword("symbol");
|
||||||
case Lisp_Object_Type::T: return Memory::get_keyword("t");
|
case Lisp_Object_Type::T: return Memory::get_keyword("t");
|
||||||
case Lisp_Object_Type::Vector: return Memory::get_keyword("vector");
|
case Lisp_Object_Type::Vector: return Memory::get_keyword("vector");
|
||||||
|
case(Lisp_Object_Type::Invalid_Garbage_Collected): return Memory::get_keyword("Invalid: Garbage Collected");
|
||||||
|
case(Lisp_Object_Type::Invalid_Under_Construction): return Memory::get_keyword("Invalid: Under Construction");
|
||||||
}
|
}
|
||||||
return Memory::get_keyword("unknown");
|
return Memory::get_keyword("unknown");
|
||||||
};
|
};
|
||||||
@@ -1023,17 +1030,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(val->type));
|
||||||
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",
|
||||||
// TODO(felix): Doc HM lookup
|
(Globals::docs.get_object(val))
|
||||||
// (val->docstring)
|
? Globals::docs.get_object(val)
|
||||||
// ? Memory::get_c_str(val->docstring)
|
: "No docs avaliable");
|
||||||
// :
|
|
||||||
"No docs avaliable");
|
|
||||||
|
|
||||||
if (Memory::get_type(val) == Lisp_Object_Type::Function)
|
if (val->type == Lisp_Object_Type::Function)
|
||||||
{
|
{
|
||||||
Arguments* args = &val->value.function->args;
|
Arguments* args = &val->value.function->args;
|
||||||
|
|
||||||
@@ -1094,8 +1099,7 @@ namespace Slime {
|
|||||||
define((addr-of var), "TODO") {
|
define((addr-of var), "TODO") {
|
||||||
profile_with_name("(addr-of-var)");
|
profile_with_name("(addr-of-var)");
|
||||||
fetch(var);
|
fetch(var);
|
||||||
return Memory::create_lisp_object(
|
return Memory::create_lisp_object(&var);
|
||||||
(float)((u64)&(var)));
|
|
||||||
};
|
};
|
||||||
define((generate-docs file_name), "TODO") {
|
define((generate-docs file_name), "TODO") {
|
||||||
profile_with_name("(generate-docs)");
|
profile_with_name("(generate-docs)");
|
||||||
|
|||||||
+14
-14
@@ -108,7 +108,7 @@
|
|||||||
// mutable for the parser to work, (#def gives us a const char)
|
// mutable for the parser to work, (#def gives us a const char)
|
||||||
// because the parser relys on being able to temporaily put in markers
|
// 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
|
// in the code and also it will fill out the source code location
|
||||||
#define _define_helper(def, docs, type, ending) \
|
#define _define_helper(def, docstring, 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; \
|
||||||
@@ -118,9 +118,9 @@
|
|||||||
assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
|
assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
|
||||||
auto label(sym,__LINE__) = label(params,__LINE__)->value.pair.first; \
|
auto label(sym,__LINE__) = label(params,__LINE__)->value.pair.first; \
|
||||||
auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(type); \
|
auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(type); \
|
||||||
|
Globals::docs.set_object(label(sfun,__LINE__), Memory::create_string(docstring).data); \
|
||||||
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); \
|
||||||
/* 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
|
||||||
@@ -137,22 +137,22 @@
|
|||||||
/*
|
/*
|
||||||
* iterate over lisp vectors
|
* iterate over lisp vectors
|
||||||
*/
|
*/
|
||||||
#define for_lisp_vector(v) \
|
#define for_lisp_vector(v) \
|
||||||
if (!v); else \
|
if (!v); else \
|
||||||
if (int it_index = 0); else \
|
if (int it_index = 0); else \
|
||||||
for (auto it = v->value.vector.data; \
|
for (auto it = v->value.vector.data; \
|
||||||
it_index < v->value.vector.length; \
|
it_index < v->value.vector.length; \
|
||||||
it=v->value.vector.data+(++it_index))
|
it=v->value.vector.data+(++it_index))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iterate over lisp lists
|
* iterate over lisp lists
|
||||||
*/
|
*/
|
||||||
#define for_lisp_list(l) \
|
#define for_lisp_list(l) \
|
||||||
if (!l); else \
|
if (!l); else \
|
||||||
if (int it_index = 0); else \
|
if (int it_index = 0); else \
|
||||||
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); \
|
head->type == 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) \
|
#define dbg(thing, format) \
|
||||||
|
|||||||
@@ -44,16 +44,18 @@ namespace Slime {
|
|||||||
/*
|
/*
|
||||||
* sourcecodeLocation
|
* sourcecodeLocation
|
||||||
*/
|
*/
|
||||||
if (value->sourceCodeLocation) {
|
// TODO(Felix): Enable again when we have SCL again:
|
||||||
try_void fprintf(f, "\n - defined in :: =%s:%d:%d=",
|
|
||||||
Memory::get_c_str(value->sourceCodeLocation->file),
|
// if (value->sourceCodeLocation) {
|
||||||
value->sourceCodeLocation->line,
|
// try_void fprintf(f, "\n - defined in :: =%s:%d:%d=",
|
||||||
value->sourceCodeLocation->column);
|
// Memory::get_c_str(value->sourceCodeLocation->file),
|
||||||
}
|
// value->sourceCodeLocation->line,
|
||||||
|
// value->sourceCodeLocation->column);
|
||||||
|
// }
|
||||||
/*
|
/*
|
||||||
* type
|
* type
|
||||||
*/
|
*/
|
||||||
Lisp_Object_Type type = Memory::get_type(value);
|
Lisp_Object_Type type = value->type;
|
||||||
Lisp_Object* LOtype;
|
Lisp_Object* LOtype;
|
||||||
Lisp_Object* type_expr = Memory::create_list(Memory::get_symbol("type"), value);
|
Lisp_Object* type_expr = Memory::create_list(Memory::get_symbol("type"), value);
|
||||||
try_void LOtype = eval_expr(type_expr);
|
try_void LOtype = eval_expr(type_expr);
|
||||||
|
|||||||
+16
-40
@@ -56,7 +56,7 @@ namespace Slime {
|
|||||||
++obligatory_keywords_count;
|
++obligatory_keywords_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Memory::get_type(cs.data[index_of_next_arg]) == Lisp_Object_Type::Keyword) {
|
while (cs.data[index_of_next_arg]->type == Lisp_Object_Type::Keyword) {
|
||||||
// check if this one is even an accepted keyword
|
// check if this one is even an accepted keyword
|
||||||
bool accepted = false;
|
bool accepted = false;
|
||||||
for (int i = 0; i < arg_spec->keyword.keywords.next_index; ++i) {
|
for (int i = 0; i < arg_spec->keyword.keywords.next_index; ++i) {
|
||||||
@@ -190,30 +190,6 @@ namespace Slime {
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc apply_arguments_to_function(Lisp_Object* arguments, Lisp_Object* function, bool should_evaluate_args) -> Lisp_Object* {
|
|
||||||
// profile_this();
|
|
||||||
// Environment* new_env;
|
|
||||||
// Lisp_Object* result;
|
|
||||||
|
|
||||||
// try new_env = create_extended_environment_for_function_application(arguments, function, should_evaluate_args);
|
|
||||||
// push_environment(new_env);
|
|
||||||
// defer {
|
|
||||||
// pop_environment();
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
// if (Memory::get_type(function) == Lisp_Object_Type::CFunction)
|
|
||||||
// // if c function:
|
|
||||||
// try result = function->value.cFunction->body();
|
|
||||||
// else
|
|
||||||
// // if lisp function
|
|
||||||
// try result = eval_expr(function->value.function->body);
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void {
|
proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void {
|
||||||
/* NOTE This parses the argument specification of funcitons
|
/* NOTE This parses the argument specification of funcitons
|
||||||
* into their Function struct. It does this by allocating new
|
* into their Function struct. It does this by allocating new
|
||||||
@@ -226,21 +202,21 @@ namespace Slime {
|
|||||||
result->rest = nullptr;
|
result->rest = nullptr;
|
||||||
|
|
||||||
// okay let's try to read some positional arguments
|
// okay let's try to read some positional arguments
|
||||||
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
|
while (arguments->type == Lisp_Object_Type::Pair) {
|
||||||
// if we encounter a keyword or a list (for keywords with
|
// if we encounter a keyword or a list (for keywords with
|
||||||
// defualt args), the positionals are done
|
// defualt args), the positionals are done
|
||||||
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword ||
|
if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword ||
|
||||||
Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
|
arguments->value.pair.first->type == Lisp_Object_Type::Pair) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we encounter something that is neither a symbol nor a
|
// if we encounter something that is neither a symbol nor a
|
||||||
// keyword arg, it's an error
|
// keyword arg, it's an error
|
||||||
if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
|
if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||||
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(arguments->value.pair.first->type));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,20 +228,20 @@ namespace Slime {
|
|||||||
|
|
||||||
// if we reach here, we are on a keyword or a pair wher a keyword
|
// if we reach here, we are on a keyword or a pair wher a keyword
|
||||||
// should be in first
|
// should be in first
|
||||||
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
|
while ((arguments->type) == Lisp_Object_Type::Pair) {
|
||||||
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
|
if ((arguments->value.pair.first->type) == Lisp_Object_Type::Keyword) {
|
||||||
// if we are on a actual keyword (with no default arg)
|
// if we are on a actual keyword (with no default arg)
|
||||||
auto keyword = arguments->value.pair.first;
|
auto keyword = arguments->value.pair.first;
|
||||||
result->keyword.keywords.append(keyword);
|
result->keyword.keywords.append(keyword);
|
||||||
result->keyword.values.append(nullptr);
|
result->keyword.values.append(nullptr);
|
||||||
} else if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
|
} else if ((arguments->value.pair.first->type) == Lisp_Object_Type::Pair) {
|
||||||
// if we are on a keyword with a default value
|
// if we are on a keyword with a default value
|
||||||
|
|
||||||
auto keyword = arguments->value.pair.first->value.pair.first;
|
auto keyword = arguments->value.pair.first->value.pair.first;
|
||||||
if (Memory::get_type(keyword) != Lisp_Object_Type::Keyword) {
|
if ((keyword->type) != Lisp_Object_Type::Keyword) {
|
||||||
create_parsing_error("Default args must be keywords");
|
create_parsing_error("Default args must be keywords");
|
||||||
}
|
}
|
||||||
if (Memory::get_type(arguments->value.pair.first->value.pair.rest)
|
if ((arguments->value.pair.first->value.pair.rest->type)
|
||||||
!= Lisp_Object_Type::Pair)
|
!= Lisp_Object_Type::Pair)
|
||||||
{
|
{
|
||||||
create_parsing_error("Default args must be a list of 2.");
|
create_parsing_error("Default args must be a list of 2.");
|
||||||
@@ -284,10 +260,10 @@ namespace Slime {
|
|||||||
|
|
||||||
// Now we are also done with keyword arguments, lets check for
|
// Now we are also done with keyword arguments, lets check for
|
||||||
// if there is a rest argument
|
// if there is a rest argument
|
||||||
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
|
if (arguments->type != Lisp_Object_Type::Pair) {
|
||||||
if (arguments == Memory::nil)
|
if (arguments == Memory::nil)
|
||||||
return;
|
return;
|
||||||
if (Memory::get_type(arguments) == Lisp_Object_Type::Symbol)
|
if (arguments->type == Lisp_Object_Type::Symbol)
|
||||||
result->rest = arguments;
|
result->rest = arguments;
|
||||||
else
|
else
|
||||||
create_parsing_error("The rest argument must be a symbol.");
|
create_parsing_error("The rest argument must be a symbol.");
|
||||||
@@ -303,7 +279,7 @@ namespace Slime {
|
|||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
while (Memory::get_type(node) == Lisp_Object_Type::Pair) {
|
while (node->type == Lisp_Object_Type::Pair) {
|
||||||
++len;
|
++len;
|
||||||
node = node->value.pair.rest;
|
node = node->value.pair.rest;
|
||||||
if (node == Memory::nil)
|
if (node == Memory::nil)
|
||||||
@@ -382,7 +358,7 @@ namespace Slime {
|
|||||||
} break;
|
} break;
|
||||||
case NasAction::Eval: {
|
case NasAction::Eval: {
|
||||||
pc = cs.data[cs.next_index-1];
|
pc = cs.data[cs.next_index-1];
|
||||||
Lisp_Object_Type type = Memory::get_type(pc);
|
Lisp_Object_Type type = pc->type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Lisp_Object_Type::Symbol: {
|
case Lisp_Object_Type::Symbol: {
|
||||||
cs.data[cs.next_index-1] = lookup_symbol(pc, get_current_environment());
|
cs.data[cs.next_index-1] = lookup_symbol(pc, get_current_environment());
|
||||||
@@ -407,7 +383,7 @@ namespace Slime {
|
|||||||
case NasAction::TM: {
|
case NasAction::TM: {
|
||||||
pc = cs.data[cs.next_index-1];
|
pc = cs.data[cs.next_index-1];
|
||||||
|
|
||||||
Lisp_Object_Type type = Memory::get_type(pc);
|
Lisp_Object_Type type = pc->type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Lisp_Object_Type::Function: {
|
case Lisp_Object_Type::Function: {
|
||||||
if(pc->value.function->is_c) {
|
if(pc->value.function->is_c) {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ namespace Slime {
|
|||||||
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);
|
|
||||||
void init();
|
void init();
|
||||||
char* get_c_str(String);
|
char* get_c_str(String);
|
||||||
void free_everything();
|
void free_everything();
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ namespace Slime::GC {
|
|||||||
// marked_strings.append(node->docstring);
|
// marked_strings.append(node->docstring);
|
||||||
|
|
||||||
// mark type specific data
|
// mark type specific data
|
||||||
switch (Memory::get_type(node)) {
|
switch (node->type) {
|
||||||
case Lisp_Object_Type::Pair: {
|
case Lisp_Object_Type::Pair: {
|
||||||
for_lisp_list (node) {
|
for_lisp_list (node) {
|
||||||
maybe_mark(it);
|
maybe_mark(it);
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ namespace Slime::Globals {
|
|||||||
Log_Level log_level = Log_Level::Debug;
|
Log_Level log_level = Log_Level::Debug;
|
||||||
bool debug_log = false;
|
bool debug_log = false;
|
||||||
Array_List<void*> load_path;
|
Array_List<void*> load_path;
|
||||||
|
|
||||||
|
Hash_Map<void*, char*> docs;
|
||||||
|
Hash_Map<void*, Source_Code_Location> source_code_locations;
|
||||||
|
Hash_Map<void*, Lisp_Object*> user_types;
|
||||||
|
|
||||||
namespace Current_Execution {
|
namespace Current_Execution {
|
||||||
Array_List<Lisp_Object*> cs; // call stack
|
Array_List<Lisp_Object*> cs; // call stack
|
||||||
Array_List<Lisp_Object*> pcs; // program counter stack
|
Array_List<Lisp_Object*> pcs; // program counter stack
|
||||||
|
|||||||
+21
-17
@@ -325,7 +325,7 @@ namespace Slime {
|
|||||||
string_builder.dealloc();
|
string_builder.dealloc();
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (Memory::get_type(node)) {
|
switch (node->type) {
|
||||||
case (Lisp_Object_Type::Nil): return strdup("()");
|
case (Lisp_Object_Type::Nil): return strdup("()");
|
||||||
case (Lisp_Object_Type::T): return strdup("t");
|
case (Lisp_Object_Type::T): return strdup("t");
|
||||||
case (Lisp_Object_Type::Continuation): return strdup("[continuation]");
|
case (Lisp_Object_Type::Continuation): return strdup("[continuation]");
|
||||||
@@ -388,10 +388,11 @@ namespace Slime {
|
|||||||
return temp;
|
return temp;
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Function): {
|
case (Lisp_Object_Type::Function): {
|
||||||
if (node->userType) {
|
// TODO(Felix): Enable again when we have user types again:
|
||||||
asprintf(&temp, "[%s]", Memory::get_c_str(node->userType->value.symbol));
|
// if (node->userType) {
|
||||||
return temp;
|
// asprintf(&temp, "[%s]", Memory::get_c_str(node->userType->value.symbol));
|
||||||
}
|
// return temp;
|
||||||
|
// }
|
||||||
if (node->value.function->is_c) {
|
if (node->value.function->is_c) {
|
||||||
// NOTE(Felix): try to find the symbol it is bound to
|
// NOTE(Felix): try to find the symbol it is bound to
|
||||||
// in global env
|
// in global env
|
||||||
@@ -431,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 (head->value.pair.first->type == Lisp_Object_Type::Symbol) {
|
||||||
String identifier = head->value.pair.first->value.symbol;
|
String identifier = head->value.pair.first->value.symbol;
|
||||||
|
|
||||||
|
|
||||||
@@ -473,11 +474,11 @@ namespace Slime {
|
|||||||
string_builder.append(lisp_object_to_string(head->value.pair.first, print_repr));
|
string_builder.append(lisp_object_to_string(head->value.pair.first, print_repr));
|
||||||
head = head->value.pair.rest;
|
head = head->value.pair.rest;
|
||||||
if (!head) break;
|
if (!head) break;
|
||||||
if (Memory::get_type(head) != Lisp_Object_Type::Pair) break;
|
if (head->type != Lisp_Object_Type::Pair) break;
|
||||||
string_builder.append(strdup(" "));
|
string_builder.append(strdup(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (head && Memory::get_type(head) != Lisp_Object_Type::Nil) {
|
if (head && head != Memory::nil) {
|
||||||
string_builder.append(strdup(" . "));
|
string_builder.append(strdup(" . "));
|
||||||
string_builder.append(lisp_object_to_string(head, print_repr));
|
string_builder.append(lisp_object_to_string(head, print_repr));
|
||||||
}
|
}
|
||||||
@@ -488,7 +489,7 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
create_generic_error("A Lisp_Object of type-id %d cannot be converted to a string",
|
create_generic_error("A Lisp_Object of type-id %d cannot be converted to a string",
|
||||||
(int)(Memory::get_type(node)));
|
(int)(node->type));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,15 +508,18 @@ namespace Slime {
|
|||||||
print(obj, true);
|
print(obj, true);
|
||||||
printf(console_normal);
|
printf(console_normal);
|
||||||
printf("\n at ");
|
printf("\n at ");
|
||||||
if (obj->sourceCodeLocation) {
|
// TODO(Felix): Enable again when we have a source code
|
||||||
printf("%s (line %d, position %d)",
|
// location again
|
||||||
Memory::get_c_str(
|
|
||||||
obj->sourceCodeLocation->file),
|
// if (obj->sourceCodeLocation) {
|
||||||
obj->sourceCodeLocation->line,
|
// printf("%s (line %d, position %d)",
|
||||||
obj->sourceCodeLocation->column);
|
// Memory::get_c_str(
|
||||||
} else {
|
// obj->sourceCodeLocation->file),
|
||||||
|
// obj->sourceCodeLocation->line,
|
||||||
|
// obj->sourceCodeLocation->column);
|
||||||
|
// } else {
|
||||||
fputs("no source code location avaliable", stdout);
|
fputs("no source code location avaliable", stdout);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
proc print_current_execution() -> void {
|
proc print_current_execution() -> void {
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@ unsigned int hm_hash(void* ptr) {
|
|||||||
|
|
||||||
unsigned int hm_hash(Slime::Lisp_Object* obj) {
|
unsigned int hm_hash(Slime::Lisp_Object* obj) {
|
||||||
using namespace Slime;
|
using namespace Slime;
|
||||||
switch (Memory::get_type(obj)) {
|
switch (obj->type) {
|
||||||
// hash from adress: if two objects of these types have
|
// hash from adress: if two objects of these types have
|
||||||
// different addresses, they are different
|
// different addresses, they are different
|
||||||
case Lisp_Object_Type::Function:
|
case Lisp_Object_Type::Function:
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace Slime {
|
|||||||
case(Lisp_Object_Type::Vector): return "vector";
|
case(Lisp_Object_Type::Vector): return "vector";
|
||||||
case(Lisp_Object_Type::Pointer): return "pointer";
|
case(Lisp_Object_Type::Pointer): return "pointer";
|
||||||
case(Lisp_Object_Type::HashMap): return "hashmap";
|
case(Lisp_Object_Type::HashMap): return "hashmap";
|
||||||
|
case(Lisp_Object_Type::Invalid_Garbage_Collected): return "Invalid: Garbage Collected";
|
||||||
|
case(Lisp_Object_Type::Invalid_Under_Construction): return "Invalid: Under Construction";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "libslime.cpp"
|
#include "libslime.cpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// enable colored terminal output for windows
|
// enable colored terminal output for windows
|
||||||
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|||||||
+26
-63
@@ -60,20 +60,6 @@ namespace Slime::Memory {
|
|||||||
return get_c_str(str->value.string);
|
return get_c_str(str->value.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type {
|
|
||||||
// the type is in the bits 0 to 5 (including)
|
|
||||||
return (Lisp_Object_Type) ((u64)node->flags & (u64)0b11111);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline proc set_type(Lisp_Object* node, Lisp_Object_Type type) {
|
|
||||||
// the type is in the bits 0 to 5 (including)
|
|
||||||
u64 bitmask = (u64)-1;
|
|
||||||
bitmask -= 0b11111;
|
|
||||||
bitmask += (u64) type;
|
|
||||||
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.
|
||||||
@@ -107,18 +93,13 @@ namespace Slime::Memory {
|
|||||||
|
|
||||||
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->type = Lisp_Object_Type::Invalid_Under_Construction;
|
||||||
object->sourceCodeLocation = nullptr;
|
|
||||||
object->userType = nullptr;
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc free_everything() -> void {
|
proc free_everything() -> void {
|
||||||
object_memory.for_each([](Lisp_Object* lo){
|
object_memory.for_each([](Lisp_Object* lo){
|
||||||
free(lo->sourceCodeLocation);
|
switch (lo->type) {
|
||||||
lo->sourceCodeLocation = 0;
|
|
||||||
|
|
||||||
switch (Memory::get_type(lo)) {
|
|
||||||
case Lisp_Object_Type::Function: {
|
case Lisp_Object_Type::Function: {
|
||||||
lo->value.function->args.positional.symbols.dealloc();
|
lo->value.function->args.positional.symbols.dealloc();
|
||||||
lo->value.function->args.keyword.keywords.dealloc();
|
lo->value.function->args.keyword.keywords.dealloc();
|
||||||
@@ -141,9 +122,14 @@ namespace Slime::Memory {
|
|||||||
hm->dealloc();
|
hm->dealloc();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for_hash_map(Globals::docs) {
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
|
||||||
// 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();
|
||||||
|
Globals::docs.dealloc();
|
||||||
Globals::Current_Execution::envi_stack.dealloc();
|
Globals::Current_Execution::envi_stack.dealloc();
|
||||||
Globals::Current_Execution::cs.dealloc();
|
Globals::Current_Execution::cs.dealloc();
|
||||||
Globals::Current_Execution::ams.dealloc();
|
Globals::Current_Execution::ams.dealloc();
|
||||||
@@ -212,6 +198,7 @@ namespace Slime::Memory {
|
|||||||
Globals::Current_Execution::ats.alloc();
|
Globals::Current_Execution::ats.alloc();
|
||||||
Globals::Current_Execution::mes.alloc();
|
Globals::Current_Execution::mes.alloc();
|
||||||
|
|
||||||
|
Globals::docs.alloc();
|
||||||
Globals::load_path.alloc();
|
Globals::load_path.alloc();
|
||||||
add_to_load_path(exe_path);
|
add_to_load_path(exe_path);
|
||||||
add_to_load_path("../bin/");
|
add_to_load_path("../bin/");
|
||||||
@@ -219,11 +206,11 @@ namespace Slime::Memory {
|
|||||||
|
|
||||||
// init nil
|
// init nil
|
||||||
try_void nil = create_lisp_object();
|
try_void nil = create_lisp_object();
|
||||||
set_type(nil, Lisp_Object_Type::Nil);
|
nil->type = Lisp_Object_Type::Nil;
|
||||||
|
|
||||||
// init t
|
// init t
|
||||||
try_void t = create_lisp_object();
|
try_void t = create_lisp_object();
|
||||||
set_type(t, Lisp_Object_Type::T);
|
t->type = Lisp_Object_Type::T;
|
||||||
|
|
||||||
try_void Parser::standard_in = create_string("stdin");
|
try_void Parser::standard_in = create_string("stdin");
|
||||||
|
|
||||||
@@ -241,7 +228,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object(void* ptr) -> Lisp_Object* {
|
proc create_lisp_object(void* ptr) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Pointer);
|
node->type = Lisp_Object_Type::Pointer;
|
||||||
node->value.pointer = ptr;
|
node->value.pointer = ptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -249,7 +236,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_hash_map() -> Lisp_Object* {
|
proc create_lisp_object_hash_map() -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::HashMap);
|
node->type = Lisp_Object_Type::HashMap;
|
||||||
node->value.hashMap = hashmap_memory.allocate();
|
node->value.hashMap = hashmap_memory.allocate();
|
||||||
node->value.hashMap->alloc();
|
node->value.hashMap->alloc();
|
||||||
return node;
|
return node;
|
||||||
@@ -258,7 +245,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object(double number) -> Lisp_Object* {
|
proc create_lisp_object(double number) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Number);
|
node->type = Lisp_Object_Type::Number;
|
||||||
node->value.number = number;
|
node->value.number = number;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -266,7 +253,7 @@ namespace Slime::Memory {
|
|||||||
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);
|
node->type = Lisp_Object_Type::String;
|
||||||
node->value.string = str;
|
node->value.string = str;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -274,7 +261,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object(const char* str) -> Lisp_Object* {
|
proc create_lisp_object(const char* 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);
|
node->type = Lisp_Object_Type::String;
|
||||||
node->value.string = create_string(str);
|
node->value.string = create_string(str);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -293,7 +280,7 @@ namespace Slime::Memory {
|
|||||||
|
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Vector);
|
node->type = Lisp_Object_Type::Vector;
|
||||||
|
|
||||||
node->value.vector.length = length;
|
node->value.vector.length = length;
|
||||||
try node->value.vector.data = allocate_vector(length);
|
try node->value.vector.data = allocate_vector(length);
|
||||||
@@ -313,7 +300,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_vector(Lisp_Object* e1) -> Lisp_Object* {
|
proc create_lisp_object_vector(Lisp_Object* e1) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Vector);
|
node->type = Lisp_Object_Type::Vector;
|
||||||
|
|
||||||
node->value.vector.length = 1;
|
node->value.vector.length = 1;
|
||||||
try node->value.vector.data = allocate_vector(1);
|
try node->value.vector.data = allocate_vector(1);
|
||||||
@@ -326,7 +313,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_vector(Lisp_Object* e1, Lisp_Object* e2) -> Lisp_Object* {
|
proc create_lisp_object_vector(Lisp_Object* e1, Lisp_Object* e2) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Vector);
|
node->type = Lisp_Object_Type::Vector;
|
||||||
|
|
||||||
node->value.vector.length = 2;
|
node->value.vector.length = 2;
|
||||||
try node->value.vector.data = allocate_vector(2);
|
try node->value.vector.data = allocate_vector(2);
|
||||||
@@ -340,7 +327,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_vector(Lisp_Object* e1, Lisp_Object* e2, Lisp_Object* e3) -> Lisp_Object* {
|
proc create_lisp_object_vector(Lisp_Object* e1, Lisp_Object* e2, Lisp_Object* e3) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Vector);
|
node->type = Lisp_Object_Type::Vector;
|
||||||
|
|
||||||
node->value.vector.length = 3;
|
node->value.vector.length = 3;
|
||||||
try node->value.vector.data = allocate_vector(3);
|
try node->value.vector.data = allocate_vector(3);
|
||||||
@@ -355,7 +342,7 @@ namespace Slime::Memory {
|
|||||||
inline proc _create_symbol(char* identifier) -> Lisp_Object* {
|
inline proc _create_symbol(char* identifier) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Symbol);
|
node->type = Lisp_Object_Type::Symbol;
|
||||||
node->value.symbol = create_string(identifier);
|
node->value.symbol = create_string(identifier);
|
||||||
global_symbol_table.set_object((char*)node->value.symbol.data, node);
|
global_symbol_table.set_object((char*)node->value.symbol.data, node);
|
||||||
return node;
|
return node;
|
||||||
@@ -374,7 +361,7 @@ namespace Slime::Memory {
|
|||||||
inline proc _create_keyword(char* identifier) -> Lisp_Object* {
|
inline proc _create_keyword(char* identifier) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Keyword);
|
node->type = Lisp_Object_Type::Keyword;
|
||||||
node->value.symbol = create_string(identifier);
|
node->value.symbol = create_string(identifier);
|
||||||
global_keyword_table.set_object((char*)node->value.symbol.data, node);
|
global_keyword_table.set_object((char*)node->value.symbol.data, node);
|
||||||
return node;
|
return node;
|
||||||
@@ -390,34 +377,10 @@ namespace Slime::Memory {
|
|||||||
return _create_keyword((char*)identifier);
|
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();
|
||||||
set_type(node, Lisp_Object_Type::Function);
|
node->type = Lisp_Object_Type::Function;
|
||||||
node->value.function = (Function*)malloc(sizeof(Function));
|
node->value.function = (Function*)malloc(sizeof(Function));
|
||||||
node->value.function->type.c_function_type = type;
|
node->value.function->type.c_function_type = type;
|
||||||
node->value.function->args.keyword.keywords.alloc();
|
node->value.function->args.keyword.keywords.alloc();
|
||||||
@@ -430,7 +393,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_function(Lisp_Function_Type ft) -> Lisp_Object* {
|
proc create_lisp_object_function(Lisp_Function_Type ft) -> Lisp_Object* {
|
||||||
Lisp_Object* func;
|
Lisp_Object* func;
|
||||||
try func = Memory::create_lisp_object();
|
try func = Memory::create_lisp_object();
|
||||||
Memory::set_type(func, Lisp_Object_Type::Function);
|
func->type = Lisp_Object_Type::Function;
|
||||||
func->value.function = (Function*)malloc(sizeof(Function));
|
func->value.function = (Function*)malloc(sizeof(Function));
|
||||||
func->value.function->args.keyword.keywords.alloc();
|
func->value.function->args.keyword.keywords.alloc();
|
||||||
func->value.function->args.keyword.values.alloc();
|
func->value.function->args.keyword.values.alloc();
|
||||||
@@ -443,7 +406,7 @@ namespace Slime::Memory {
|
|||||||
proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* {
|
proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* {
|
||||||
Lisp_Object* node;
|
Lisp_Object* node;
|
||||||
try node = create_lisp_object();
|
try node = create_lisp_object();
|
||||||
set_type(node, Lisp_Object_Type::Pair);
|
node->type = Lisp_Object_Type::Pair;
|
||||||
// node->value.pair = new(Pair);
|
// node->value.pair = new(Pair);
|
||||||
node->value.pair.first = first;
|
node->value.pair.first = first;
|
||||||
node->value.pair.rest = rest;
|
node->value.pair.rest = rest;
|
||||||
@@ -457,7 +420,7 @@ namespace Slime::Memory {
|
|||||||
if (n == Memory::nil || n == Memory::t) {
|
if (n == Memory::nil || n == Memory::t) {
|
||||||
return n;
|
return n;
|
||||||
} else {
|
} else {
|
||||||
Lisp_Object_Type type = Memory::get_type(n);
|
Lisp_Object_Type type = n->type;
|
||||||
if (type == Lisp_Object_Type::Symbol ||
|
if (type == Lisp_Object_Type::Symbol ||
|
||||||
type == Lisp_Object_Type::Keyword ||
|
type == Lisp_Object_Type::Keyword ||
|
||||||
type == Lisp_Object_Type::Function)
|
type == Lisp_Object_Type::Function)
|
||||||
@@ -480,7 +443,7 @@ namespace Slime::Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc copy_lisp_object_except_pairs(Lisp_Object* n) -> Lisp_Object* {
|
proc copy_lisp_object_except_pairs(Lisp_Object* n) -> Lisp_Object* {
|
||||||
if (get_type(n) == Lisp_Object_Type::Pair)
|
if (n->type == Lisp_Object_Type::Pair)
|
||||||
return n;
|
return n;
|
||||||
return copy_lisp_object(n);
|
return copy_lisp_object(n);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-17
@@ -3,12 +3,12 @@ namespace Slime {
|
|||||||
struct String;
|
struct String;
|
||||||
struct Environment;
|
struct Environment;
|
||||||
|
|
||||||
enum struct Thread_Type {
|
enum struct Thread_Type : u8 {
|
||||||
Main,
|
Main,
|
||||||
GarbageCollection
|
GarbageCollection
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Lisp_Object_Type {
|
enum struct Lisp_Object_Type : u8 {
|
||||||
Nil,
|
Nil,
|
||||||
T,
|
T,
|
||||||
Symbol,
|
Symbol,
|
||||||
@@ -22,16 +22,11 @@ namespace Slime {
|
|||||||
HashMap,
|
HashMap,
|
||||||
// OwningPointer,
|
// OwningPointer,
|
||||||
Function,
|
Function,
|
||||||
|
Invalid_Garbage_Collected,
|
||||||
|
Invalid_Under_Construction
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Lisp_Object_Flags
|
enum struct NasAction : u8 {
|
||||||
{
|
|
||||||
// bits 1 to 5 (including) will be reserved for the type
|
|
||||||
Already_Garbage_Collected = 1 << 5,
|
|
||||||
Under_Construction = 1 << 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum struct NasAction {
|
|
||||||
And_Then_Action,
|
And_Then_Action,
|
||||||
Macro_Write_Back,
|
Macro_Write_Back,
|
||||||
Eval,
|
Eval,
|
||||||
@@ -43,13 +38,13 @@ namespace Slime {
|
|||||||
Pop_Environment
|
Pop_Environment
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Lisp_Function_Type {
|
enum struct Lisp_Function_Type : u8 {
|
||||||
Lambda, // normal evaluation order
|
Lambda, // normal evaluation order
|
||||||
Macro // args are not evaluated, a new programm is returned
|
Macro // args are not evaluated, a new programm is returned
|
||||||
// that will be executed again
|
// that will be executed again
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct C_Function_Type {
|
enum struct C_Function_Type : u8 {
|
||||||
cFunction, // normal evaluation order
|
cFunction, // normal evaluation order
|
||||||
cSpecial, // args are not evaluated, but result is returned
|
cSpecial, // args are not evaluated, but result is returned
|
||||||
// as you would expect
|
// as you would expect
|
||||||
@@ -57,7 +52,7 @@ namespace Slime {
|
|||||||
// modified
|
// modified
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Log_Level {
|
enum struct Log_Level : u8 {
|
||||||
None,
|
None,
|
||||||
Critical,
|
Critical,
|
||||||
Warning,
|
Warning,
|
||||||
@@ -131,10 +126,9 @@ namespace Slime {
|
|||||||
} body;
|
} body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
struct Lisp_Object {
|
struct Lisp_Object {
|
||||||
Source_Code_Location* sourceCodeLocation;
|
Lisp_Object_Type type;
|
||||||
u64 flags;
|
|
||||||
Lisp_Object* userType; // keyword
|
|
||||||
union value {
|
union value {
|
||||||
String symbol; // used for symbols and keywords
|
String symbol; // used for symbols and keywords
|
||||||
double number;
|
double number;
|
||||||
@@ -145,9 +139,9 @@ namespace Slime {
|
|||||||
void* pointer;
|
void* pointer;
|
||||||
Continuation* continuation;
|
Continuation* continuation;
|
||||||
Hash_Map<Lisp_Object*, Lisp_Object*>* hashMap;
|
Hash_Map<Lisp_Object*, Lisp_Object*>* hashMap;
|
||||||
~value() {}
|
|
||||||
} value;
|
} value;
|
||||||
};
|
};
|
||||||
|
#pragma options align=reset
|
||||||
|
|
||||||
struct Error {
|
struct Error {
|
||||||
Lisp_Object* position;
|
Lisp_Object* position;
|
||||||
|
|||||||
+3
-3
@@ -65,9 +65,9 @@ namespace Slime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define assert_equal_type(node, _type) \
|
#define assert_equal_type(node, _type) \
|
||||||
if (Memory::get_type(node) != _type) { \
|
if (node->type != _type) { \
|
||||||
print_assert_equal_fail( \
|
print_assert_equal_fail( \
|
||||||
lisp_object_type_to_string(Memory::get_type(node)), \
|
lisp_object_type_to_string(node->type), \
|
||||||
lisp_object_type_to_string(_type), char*, "%s"); \
|
lisp_object_type_to_string(_type), char*, "%s"); \
|
||||||
return fail; \
|
return fail; \
|
||||||
} \
|
} \
|
||||||
@@ -613,7 +613,7 @@ namespace Slime {
|
|||||||
invoke_test(test_built_in_and);
|
invoke_test(test_built_in_and);
|
||||||
invoke_test(test_built_in_or);
|
invoke_test(test_built_in_or);
|
||||||
invoke_test(test_built_in_not);
|
invoke_test(test_built_in_not);
|
||||||
invoke_test(test_built_in_type);
|
// invoke_test(test_built_in_type);
|
||||||
|
|
||||||
printf("\n-- Memory management --\n");
|
printf("\n-- Memory management --\n");
|
||||||
invoke_test(test_singular_t_and_nil);
|
invoke_test(test_singular_t_and_nil);
|
||||||
|
|||||||
Reference in New Issue
Block a user