Checkpoint before unquote-splicing
This commit is contained in:
+67
-47
@@ -392,17 +392,25 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
|
||||
if (evaluated_arguments->value.pair.first == Memory::nil ||
|
||||
evaluated_arguments->value.pair.first == Memory::t ||
|
||||
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Keyword ||
|
||||
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Symbol)
|
||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||
|
||||
if (target == Memory::nil ||
|
||||
target == Memory::t ||
|
||||
Memory::get_type(target) == Lisp_Object_Type::Keyword ||
|
||||
Memory::get_type(target) == Lisp_Object_Type::Symbol)
|
||||
{
|
||||
create_generic_error("You cannot mutate to nil, t, keywords or symbols because they have to be unique");
|
||||
}
|
||||
|
||||
if (source == Memory::nil ||
|
||||
source == Memory::t ||
|
||||
Memory::get_type(source) == Lisp_Object_Type::Keyword ||
|
||||
Memory::get_type(source) == Lisp_Object_Type::Symbol)
|
||||
{
|
||||
create_generic_error("You cannot mutate nil, t, keywords or symbols");
|
||||
}
|
||||
|
||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||
|
||||
*target = *source;
|
||||
return target;
|
||||
});
|
||||
@@ -533,6 +541,12 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
Lisp_Object* condition_part = arguments->value.pair.first;
|
||||
Lisp_Object* condition;
|
||||
Lisp_Object* then_part = arguments->value.pair.rest;
|
||||
Lisp_Object* wrapped_then_part;
|
||||
|
||||
try wrapped_then_part = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("begin"),
|
||||
then_part);
|
||||
|
||||
Lisp_Object* result = Memory::nil;
|
||||
|
||||
while (true) {
|
||||
@@ -541,63 +555,63 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
if (condition == Memory::nil)
|
||||
break;
|
||||
|
||||
try result = eval_expr(then_part->value.pair.first, env);
|
||||
try result = eval_expr(wrapped_then_part, env);
|
||||
}
|
||||
return result;
|
||||
|
||||
});
|
||||
defun("let", cLambda {
|
||||
// (let ((a 10)(b 20)) (body1) (body2))
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length_greater_equal(1, arguments_length);
|
||||
// defun("let", cLambda {
|
||||
// // (let ((a 10)(b 20)) (body1) (body2))
|
||||
// try arguments_length = list_length(arguments);
|
||||
// try assert_arguments_length_greater_equal(1, arguments_length);
|
||||
|
||||
Environment* let_env;
|
||||
try let_env = Memory::create_child_environment(env);
|
||||
Lisp_Object* bindings = arguments->value.pair.first;
|
||||
while (true) {
|
||||
if (bindings == Memory::nil) {
|
||||
break;
|
||||
}
|
||||
// Environment* let_env;
|
||||
// try let_env = Memory::create_child_environment(env);
|
||||
// Lisp_Object* bindings = arguments->value.pair.first;
|
||||
// while (true) {
|
||||
// if (bindings == Memory::nil) {
|
||||
// break;
|
||||
// }
|
||||
|
||||
try assert_type(bindings, Lisp_Object_Type::Pair);
|
||||
// try assert_type(bindings, Lisp_Object_Type::Pair);
|
||||
|
||||
Lisp_Object* sym = bindings->value.pair.first->value.pair.first;
|
||||
// Lisp_Object* sym = bindings->value.pair.first->value.pair.first;
|
||||
|
||||
try assert_type(sym, Lisp_Object_Type::Symbol);
|
||||
// try assert_type(sym, Lisp_Object_Type::Symbol);
|
||||
|
||||
Lisp_Object* rest_sym = bindings->value.pair.first->value.pair.rest;
|
||||
// Lisp_Object* rest_sym = bindings->value.pair.first->value.pair.rest;
|
||||
|
||||
try assert_type(rest_sym, Lisp_Object_Type::Pair);
|
||||
try assert_type(rest_sym->value.pair.rest, Lisp_Object_Type::Nil);
|
||||
// try assert_type(rest_sym, Lisp_Object_Type::Pair);
|
||||
// try assert_type(rest_sym->value.pair.rest, Lisp_Object_Type::Nil);
|
||||
|
||||
Lisp_Object* value = eval_expr(rest_sym->value.pair.first, env);
|
||||
// Lisp_Object* value = eval_expr(rest_sym->value.pair.first, env);
|
||||
|
||||
// NOTE(Felix): We have to copy the value here because
|
||||
// if the let body modifies the value, it would bake
|
||||
// in... bad bad...
|
||||
define_symbol(sym, Memory::copy_lisp_object(value), let_env);
|
||||
// // NOTE(Felix): We have to copy the value here because
|
||||
// // if the let body modifies the value, it would bake
|
||||
// // in... bad bad...
|
||||
// define_symbol(sym, Memory::copy_lisp_object(value), let_env);
|
||||
|
||||
bindings = bindings->value.pair.rest;
|
||||
}
|
||||
// bindings = bindings->value.pair.rest;
|
||||
// }
|
||||
|
||||
arguments = arguments->value.pair.rest;
|
||||
// arguments = arguments->value.pair.rest;
|
||||
|
||||
Lisp_Object* evaluated_arguments;
|
||||
try evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
||||
// Lisp_Object* evaluated_arguments;
|
||||
// try evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
||||
|
||||
if (evaluated_arguments == Memory::nil)
|
||||
return evaluated_arguments;
|
||||
// if (evaluated_arguments == Memory::nil)
|
||||
// return evaluated_arguments;
|
||||
|
||||
// skip to the last evaluated operand and return it,
|
||||
// we use eval_arguments here instead of doing it
|
||||
// manually, because we want to increase code reuse,
|
||||
// but at the cost that we have to find the end of the
|
||||
// list again
|
||||
while (Memory::get_type(evaluated_arguments->value.pair.rest) == Lisp_Object_Type::Pair) {
|
||||
evaluated_arguments = evaluated_arguments->value.pair.rest;
|
||||
}
|
||||
return evaluated_arguments->value.pair.first;
|
||||
});
|
||||
// // skip to the last evaluated operand and return it,
|
||||
// // we use eval_arguments here instead of doing it
|
||||
// // manually, because we want to increase code reuse,
|
||||
// // but at the cost that we have to find the end of the
|
||||
// // list again
|
||||
// while (Memory::get_type(evaluated_arguments->value.pair.rest) == Lisp_Object_Type::Pair) {
|
||||
// evaluated_arguments = evaluated_arguments->value.pair.rest;
|
||||
// }
|
||||
// return evaluated_arguments->value.pair.first;
|
||||
// });
|
||||
defun("lambda", cLambda {
|
||||
/* TODO(Felix): first one crashes
|
||||
* (lambda ())
|
||||
@@ -820,6 +834,12 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("addr-of", cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
return Memory::create_lisp_object_number((u64)&(evaluated_arguments->value.pair.first->value));
|
||||
});
|
||||
defun("print", cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
+2
-2
@@ -140,7 +140,7 @@ namespace Memory {
|
||||
// if we still have space
|
||||
if (object_memory_size == next_index_in_object_memory) {
|
||||
create_out_of_memory_error(
|
||||
"There is not enough space in the lisp object"
|
||||
"There is not enough space in the lisp object "
|
||||
"memory to allocate additional lisp objects. "
|
||||
"Maybe try increasing the Memory size when "
|
||||
"calling Memory::init()");
|
||||
@@ -300,7 +300,7 @@ namespace Memory {
|
||||
// if we still have space
|
||||
if (environment_memory_size == next_index_in_environment_memory) {
|
||||
create_out_of_memory_error(
|
||||
"There is not enough space in the environment"
|
||||
"There is not enough space in the environment "
|
||||
"memory to allocate additional environments. "
|
||||
"Maybe try increasing the Memory size when "
|
||||
"calling Memory::init()");
|
||||
|
||||
Reference in New Issue
Block a user