Checkpoint before unquote-splicing

This commit is contained in:
Felix Brendel
2019-05-21 16:56:52 +02:00
parent 912ec19373
commit eb3bc262b9
6 changed files with 591 additions and 92 deletions
+67 -47
View File
@@ -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
View File
@@ -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()");