|
|
|
@@ -40,281 +40,260 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_equals(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
if (arguments->type == Lisp_Object_Type::Nil) |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
|
|
|
|
Lisp_Object* first = arguments->value.pair->first; |
|
|
|
|
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
if (!lisp_object_equal(arguments->value.pair->first, first)) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_greater(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { |
|
|
|
char* file_content = read_entire_file(Memory::get_c_str(file_name)); |
|
|
|
if (file_content) { |
|
|
|
Lisp_Object* result = Memory::create_lisp_object_nil(); |
|
|
|
Lisp_Object_Array_List* program; |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
program = Parser::parse_program(file_name, file_content); |
|
|
|
} |
|
|
|
|
|
|
|
if (arguments->value.pair->first->value.number->value >= last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
|
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
|
try { |
|
|
|
result = eval_expr(program->data[i], env); |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
} else { |
|
|
|
create_error(Error_Type::Unknown_Error, nullptr); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_greater_equal(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
Lisp_Object* evaluated_arguments; |
|
|
|
|
|
|
|
#define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object* |
|
|
|
#define report_error(_type) { \ |
|
|
|
create_error(_type, arguments->sourceCodeLocation); \ |
|
|
|
return nullptr; \ |
|
|
|
} |
|
|
|
|
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
proc defun = [&](const char* name, auto fun) { |
|
|
|
define_symbol( |
|
|
|
Memory::create_lisp_object_symbol(name), |
|
|
|
Memory::create_lisp_object_cfunction(fun), |
|
|
|
env); |
|
|
|
}; |
|
|
|
|
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
defun("=", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
if (arguments->value.pair->first->value.number->value > last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
if (arguments->type == Lisp_Object_Type::Nil) |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
|
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
Lisp_Object* first = arguments->value.pair->first; |
|
|
|
|
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
} |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
if (!lisp_object_equal(arguments->value.pair->first, first)) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_less(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
}); |
|
|
|
defun(">", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (arguments->value.pair->first->value.number->value <= last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
if (arguments->value.pair->first->value.number->value >= last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
|
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
}); |
|
|
|
defun(">=", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_less_equal(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
if (arguments->value.pair->first->value.number->value > last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
|
|
|
|
if (arguments->value.pair->first->value.number->value < last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
}); |
|
|
|
defun("<", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
} |
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
proc built_in_add(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
double sum = 0; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
sum += arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
if (arguments->value.pair->first->value.number->value <= last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
|
|
|
|
return Memory::create_lisp_object_number(sum); |
|
|
|
} |
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_substract(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
}); |
|
|
|
defun("<=", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double difference = arguments->value.pair->first->value.number->value; |
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
difference -= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(difference); |
|
|
|
} |
|
|
|
if (arguments->value.pair->first->value.number->value < last_number) |
|
|
|
return Memory::create_lisp_object_nil(); |
|
|
|
|
|
|
|
proc built_in_multiply(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
last_number = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double product = arguments->value.pair->first->value.number->value; |
|
|
|
return Memory::create_lisp_object_t(); |
|
|
|
}); |
|
|
|
defun("+", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double sum = 0; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
sum += arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
product *= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(product); |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(sum); |
|
|
|
}); |
|
|
|
defun("-", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
proc built_in_divide(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double difference = arguments->value.pair->first->value.number->value; |
|
|
|
|
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double quotient = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
difference -= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(difference); |
|
|
|
}); |
|
|
|
defun("*", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
quotient /= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(quotient); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double product = arguments->value.pair->first->value.number->value; |
|
|
|
|
|
|
|
proc built_in_exponentiate(Lisp_Object* arguments, Environment* env) -> Lisp_Object* { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (arguments_length != 2) { |
|
|
|
create_error(Error_Type::Wrong_Number_Of_Arguments, arguments->sourceCodeLocation); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
product *= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(product); |
|
|
|
}); |
|
|
|
defun("/", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
double quotient = arguments->value.pair->first->value.number->value; |
|
|
|
|
|
|
|
double base = arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
while (arguments->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
quotient /= arguments->value.pair->first->value.number->value; |
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
} |
|
|
|
return Memory::create_lisp_object_number(quotient); |
|
|
|
}); |
|
|
|
defun("**", cLambda { |
|
|
|
int arguments_length; |
|
|
|
try { |
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
if (arguments_length != 2) { |
|
|
|
create_error(Error_Type::Wrong_Number_Of_Arguments, arguments->sourceCodeLocation); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
double exponent = arguments->value.pair->first->value.number->value; |
|
|
|
try { |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
|
|
|
|
return Memory::create_lisp_object_number(pow(base, exponent)); |
|
|
|
} |
|
|
|
double base = arguments->value.pair->first->value.number->value; |
|
|
|
|
|
|
|
arguments = arguments->value.pair->rest; |
|
|
|
|
|
|
|
proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { |
|
|
|
char* file_content = read_entire_file(Memory::get_c_str(file_name)); |
|
|
|
if (file_content) { |
|
|
|
Lisp_Object* result = Memory::create_lisp_object_nil(); |
|
|
|
Lisp_Object_Array_List* program; |
|
|
|
try { |
|
|
|
program = Parser::parse_program(file_name, file_content); |
|
|
|
} |
|
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
|
try { |
|
|
|
result = eval_expr(program->data[i], env); |
|
|
|
assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
} else { |
|
|
|
create_error(Error_Type::Unknown_Error, nullptr); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
|
int arguments_length; |
|
|
|
Lisp_Object* evaluated_arguments; |
|
|
|
|
|
|
|
#define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object* |
|
|
|
#define report_error(_type) { \ |
|
|
|
create_error(_type, arguments->sourceCodeLocation); \ |
|
|
|
return nullptr; \ |
|
|
|
} |
|
|
|
|
|
|
|
proc defun = [&](const char* name, std::function<Lisp_Object*(Lisp_Object*, Environment*)> fun) { |
|
|
|
define_symbol( |
|
|
|
Memory::create_lisp_object_symbol(name), |
|
|
|
Memory::create_lisp_object_cfunction(fun), |
|
|
|
env); |
|
|
|
}; |
|
|
|
double exponent = arguments->value.pair->first->value.number->value; |
|
|
|
|
|
|
|
defun("=", built_in_equals); |
|
|
|
defun(">", built_in_greater); |
|
|
|
defun(">=", built_in_greater_equal); |
|
|
|
defun("<", built_in_less); |
|
|
|
defun("<=", built_in_less_equal); |
|
|
|
defun("+", built_in_add); |
|
|
|
defun("-", built_in_substract); |
|
|
|
defun("*", built_in_multiply); |
|
|
|
defun("/", built_in_divide); |
|
|
|
defun("**", built_in_exponentiate); |
|
|
|
return Memory::create_lisp_object_number(pow(base, exponent)); |
|
|
|
}); |
|
|
|
defun("define", cLambda { |
|
|
|
try { |
|
|
|
arguments_length = list_length(arguments); |
|
|
|
@@ -345,41 +324,41 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
|
|
|
|
|
return value; |
|
|
|
}); |
|
|
|
defun("define-upwards", cLambda { |
|
|
|
try { |
|
|
|
arguments_length = list_length(arguments); |
|
|
|
} |
|
|
|
// defun("define-upwards", cLambda { |
|
|
|
// try { |
|
|
|
// arguments_length = list_length(arguments); |
|
|
|
// } |
|
|
|
|
|
|
|
if (arguments_length != 2) { |
|
|
|
report_error(Error_Type::Wrong_Number_Of_Arguments); |
|
|
|
} |
|
|
|
// if (arguments_length != 2) { |
|
|
|
// report_error(Error_Type::Wrong_Number_Of_Arguments); |
|
|
|
// } |
|
|
|
|
|
|
|
Lisp_Object* symbol = arguments->value.pair->first; |
|
|
|
// Lisp_Object* symbol = arguments->value.pair->first; |
|
|
|
|
|
|
|
if (symbol->type == Lisp_Object_Type::Pair) { |
|
|
|
try { |
|
|
|
symbol = eval_expr(symbol, env); |
|
|
|
} |
|
|
|
} |
|
|
|
// if (symbol->type == Lisp_Object_Type::Pair) { |
|
|
|
// try { |
|
|
|
// symbol = eval_expr(symbol, env); |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
if (symbol->type != Lisp_Object_Type::Symbol) { |
|
|
|
report_error(Error_Type::Type_Missmatch); |
|
|
|
} |
|
|
|
// if (symbol->type != Lisp_Object_Type::Symbol) { |
|
|
|
// report_error(Error_Type::Type_Missmatch); |
|
|
|
// } |
|
|
|
|
|
|
|
if (!env->parent) { |
|
|
|
report_error(Error_Type::Unknown_Error); |
|
|
|
} |
|
|
|
// if (!env->parent) { |
|
|
|
// report_error(Error_Type::Unknown_Error); |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
Lisp_Object* value = arguments->value.pair->rest->value.pair->first; |
|
|
|
try { |
|
|
|
value = eval_expr(value, env); |
|
|
|
} |
|
|
|
// Lisp_Object* value = arguments->value.pair->rest->value.pair->first; |
|
|
|
// try { |
|
|
|
// value = eval_expr(value, env); |
|
|
|
// } |
|
|
|
|
|
|
|
define_symbol(symbol, value, env->parent); |
|
|
|
// define_symbol(symbol, value, env->parent); |
|
|
|
|
|
|
|
return value; |
|
|
|
}); |
|
|
|
// return value; |
|
|
|
// }); |
|
|
|
defun("mutate", cLambda { |
|
|
|
try { |
|
|
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
@@ -453,8 +432,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
|
// print(arguments); |
|
|
|
// printf("\n"); |
|
|
|
|
|
|
|
// recursive lambdas in lambdas yay!! |
|
|
|
std::function<Lisp_Object*(Lisp_Object*)> unquoteSomeExpressions; |
|
|
|
/* recursive lambdas in lambdas yay!! */ |
|
|
|
// NOTE(Felix): first we have to initialize the variable |
|
|
|
// with a garbage lambda, so that we can then overwrite it |
|
|
|
// a recursive lambda |
|
|
|
std::function<Lisp_Object*(Lisp_Object*)> unquoteSomeExpressions; // = [] (Lisp_Object* expr) -> Lisp_Object* {return nullptr;}; |
|
|
|
unquoteSomeExpressions = [&unquoteSomeExpressions, &env] (Lisp_Object* expr) -> Lisp_Object* { |
|
|
|
// if it is an atom, return it |
|
|
|
if (expr->type != Lisp_Object_Type::Pair) |
|
|
|
|