|
|
@@ -37,7 +37,7 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { |
|
|
try program = Parser::parse_program(file_name, file_content); |
|
|
try program = Parser::parse_program(file_name, file_content); |
|
|
|
|
|
|
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
try result = eval_expr(program->data[i], env); |
|
|
|
|
|
|
|
|
try result = eval_expr(program->data[i], env); |
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
} else { |
|
|
} else { |
|
|
@@ -114,9 +114,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
|
|
|
|
|
|
defun("=", cLambda { |
|
|
defun("=", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
|
|
|
if (arguments == Memory::nil) |
|
|
if (arguments == Memory::nil) |
|
|
return Memory::t; |
|
|
return Memory::t; |
|
|
@@ -133,16 +131,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun(">", cLambda { |
|
|
defun(">", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
if (arguments->value.pair.first->value.number >= last_number) |
|
|
if (arguments->value.pair.first->value.number >= last_number) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -155,16 +149,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun(">=", cLambda { |
|
|
defun(">=", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
if (arguments->value.pair.first->value.number > last_number) |
|
|
if (arguments->value.pair.first->value.number > last_number) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -184,9 +174,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
double last_number = strtod("-Inf", NULL); |
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
if (arguments->value.pair.first->value.number <= last_number) |
|
|
if (arguments->value.pair.first->value.number <= last_number) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -199,16 +187,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("<=", cLambda { |
|
|
defun("<=", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
if (arguments->value.pair.first->value.number < last_number) |
|
|
if (arguments->value.pair.first->value.number < last_number) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -221,15 +205,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("+", cLambda { |
|
|
defun("+", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
|
|
|
double sum = 0; |
|
|
double sum = 0; |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
sum += arguments->value.pair.first->value.number; |
|
|
sum += arguments->value.pair.first->value.number; |
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
} |
|
|
} |
|
|
@@ -238,20 +219,17 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("-", cLambda { |
|
|
defun("-", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &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 difference = arguments->value.pair.first->value.number; |
|
|
double difference = arguments->value.pair.first->value.number; |
|
|
|
|
|
|
|
|
|
|
|
if (arguments_length == 1) |
|
|
|
|
|
return Memory::create_lisp_object_number(-difference); |
|
|
|
|
|
|
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
difference -= arguments->value.pair.first->value.number; |
|
|
difference -= arguments->value.pair.first->value.number; |
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
@@ -260,20 +238,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("*", cLambda { |
|
|
defun("*", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &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 product = arguments->value.pair.first->value.number; |
|
|
double product = arguments->value.pair.first->value.number; |
|
|
|
|
|
|
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
product *= arguments->value.pair.first->value.number; |
|
|
product *= arguments->value.pair.first->value.number; |
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
@@ -282,20 +254,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("/", cLambda { |
|
|
defun("/", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &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; |
|
|
double quotient = arguments->value.pair.first->value.number; |
|
|
|
|
|
|
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { |
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
quotient /= arguments->value.pair.first->value.number; |
|
|
quotient /= arguments->value.pair.first->value.number; |
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
@@ -304,25 +270,15 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("**", cLambda { |
|
|
defun("**", cLambda { |
|
|
int arguments_length; |
|
|
int arguments_length; |
|
|
try { |
|
|
|
|
|
arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
assert(arguments_length == 2); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
|
|
|
try assert_arguments_length(2, arguments_length); |
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
double base = arguments->value.pair.first->value.number; |
|
|
double base = arguments->value.pair.first->value.number; |
|
|
|
|
|
|
|
|
arguments = arguments->value.pair.rest; |
|
|
arguments = arguments->value.pair.rest; |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); |
|
|
|
|
|
|
|
|
double exponent = arguments->value.pair.first->value.number; |
|
|
double exponent = arguments->value.pair.first->value.number; |
|
|
|
|
|
|
|
|
@@ -343,7 +299,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
defun("define", cLambda { |
|
|
defun("define", cLambda { |
|
|
|
|
|
|
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length >= 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(2, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* symbol = arguments->value.pair.first; |
|
|
Lisp_Object* symbol = arguments->value.pair.first; |
|
|
Lisp_Object* value; |
|
|
Lisp_Object* value; |
|
|
@@ -379,7 +335,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
value = parse_lambda_starting_from_args(fake_lambda, env); |
|
|
value = parse_lambda_starting_from_args(fake_lambda, env); |
|
|
symbol = real_symbol; |
|
|
symbol = real_symbol; |
|
|
} else { |
|
|
} else { |
|
|
try assert(arguments_length <= 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length_less_equal(2, arguments_length); |
|
|
try assert_type(symbol, Lisp_Object_Type::Symbol); |
|
|
try assert_type(symbol, Lisp_Object_Type::Symbol); |
|
|
|
|
|
|
|
|
value = arguments->value.pair.rest->value.pair.first; |
|
|
value = arguments->value.pair.rest->value.pair.first; |
|
|
@@ -428,13 +384,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
// }); |
|
|
// }); |
|
|
defun("mutate", cLambda { |
|
|
defun("mutate", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length(2, arguments_length); |
|
|
|
|
|
|
|
|
if (evaluated_arguments->value.pair.first == Memory::nil || |
|
|
if (evaluated_arguments->value.pair.first == Memory::nil || |
|
|
evaluated_arguments->value.pair.first == Memory::t || |
|
|
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::Keyword || |
|
|
|
|
|
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Symbol) |
|
|
{ |
|
|
{ |
|
|
create_generic_error("You cannot mutate nil, t or keywords"); |
|
|
|
|
|
|
|
|
create_generic_error("You cannot mutate nil, t, keywords or symbols"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Lisp_Object* target = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* target = evaluated_arguments->value.pair.first; |
|
|
@@ -445,7 +402,8 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("if", cLambda { |
|
|
defun("if", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 2 || arguments_length == 3); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(2, arguments_length); |
|
|
|
|
|
try assert_arguments_length_less_equal(3, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* condition = arguments->value.pair.first; |
|
|
Lisp_Object* condition = arguments->value.pair.first; |
|
|
Lisp_Object* then_part = arguments->value.pair.rest; |
|
|
Lisp_Object* then_part = arguments->value.pair.rest; |
|
|
@@ -466,12 +424,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("quote", cLambda { |
|
|
defun("quote", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
return arguments->value.pair.first; |
|
|
return arguments->value.pair.first; |
|
|
}); |
|
|
}); |
|
|
defun("quasiquote", cLambda { |
|
|
defun("quasiquote", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
// print(arguments); |
|
|
// print(arguments); |
|
|
// printf("\n"); |
|
|
// printf("\n"); |
|
|
@@ -553,7 +511,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("not", cLambda { |
|
|
defun("not", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
bool truthy; |
|
|
bool truthy; |
|
|
|
|
|
|
|
|
@@ -584,7 +542,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
defun("let", cLambda { |
|
|
defun("let", cLambda { |
|
|
// (let ((a 10)(b 20)) (body1) (body2)) |
|
|
// (let ((a 10)(b 20)) (body1) (body2)) |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length >= 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
Environment* let_env = Memory::create_child_environment(env); |
|
|
Environment* let_env = Memory::create_child_environment(env); |
|
|
Lisp_Object* bindings = arguments->value.pair.first; |
|
|
Lisp_Object* bindings = arguments->value.pair.first; |
|
|
@@ -638,7 +596,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
* (lambda (x d) (+ 1 2) (- 1 2) (* 1 2)) |
|
|
* (lambda (x d) (+ 1 2) (- 1 2) (* 1 2)) |
|
|
*/ |
|
|
*/ |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length != 0); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, false); |
|
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, false); |
|
|
|
|
|
|
|
|
@@ -646,7 +604,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("special-lambda", cLambda { |
|
|
defun("special-lambda", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length != 0); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, true); |
|
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, true); |
|
|
|
|
|
|
|
|
@@ -654,7 +612,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("eval", cLambda { |
|
|
defun("eval", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* result; |
|
|
Lisp_Object* result; |
|
|
|
|
|
|
|
|
@@ -686,14 +644,15 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("pair", cLambda { |
|
|
defun("pair", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length(2, arguments_length); |
|
|
|
|
|
|
|
|
return Memory::create_lisp_object_pair( |
|
|
return Memory::create_lisp_object_pair( |
|
|
evaluated_arguments->value.pair.first, |
|
|
evaluated_arguments->value.pair.first, |
|
|
evaluated_arguments->value.pair.rest->value.pair.first); |
|
|
evaluated_arguments->value.pair.rest->value.pair.first); |
|
|
}); |
|
|
}); |
|
|
defun("first", cLambda { |
|
|
defun("first", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
if (evaluated_arguments->value.pair.first == Memory::nil) |
|
|
if (evaluated_arguments->value.pair.first == Memory::nil) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -704,7 +663,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("rest", cLambda { |
|
|
defun("rest", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
if (evaluated_arguments->value.pair.first == Memory::nil) |
|
|
if (evaluated_arguments->value.pair.first == Memory::nil) |
|
|
return Memory::nil; |
|
|
return Memory::nil; |
|
|
@@ -715,7 +674,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("set-type", cLambda { |
|
|
defun("set-type", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length(2, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* object = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* object = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* type = evaluated_arguments->value.pair.rest->value.pair.first; |
|
|
Lisp_Object* type = evaluated_arguments->value.pair.rest->value.pair.first; |
|
|
@@ -727,14 +686,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("delete-type", cLambda { |
|
|
defun("delete-type", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
evaluated_arguments->value.pair.first->userType = nullptr; |
|
|
evaluated_arguments->value.pair.first->userType = nullptr; |
|
|
return Memory::t; |
|
|
return Memory::t; |
|
|
}); |
|
|
}); |
|
|
defun("type", cLambda { |
|
|
defun("type", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
if (evaluated_arguments->value.pair.first->userType) { |
|
|
if (evaluated_arguments->value.pair.first->userType) { |
|
|
return evaluated_arguments->value.pair.first->userType; |
|
|
return evaluated_arguments->value.pair.first->userType; |
|
|
@@ -765,7 +724,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("info", cLambda { |
|
|
defun("info", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
print(arguments->value.pair.first); |
|
|
print(arguments->value.pair.first); |
|
|
|
|
|
|
|
|
@@ -840,7 +799,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("show", cLambda { |
|
|
defun("show", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Function); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Function); |
|
|
|
|
|
|
|
|
puts("body:\n"); |
|
|
puts("body:\n"); |
|
|
@@ -851,7 +810,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("print", cLambda { |
|
|
defun("print", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
print(evaluated_arguments->value.pair.first); |
|
|
print(evaluated_arguments->value.pair.first); |
|
|
|
|
|
|
|
|
@@ -859,13 +818,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("read", cLambda { |
|
|
defun("read", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length <= 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length_less_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
if (arguments_length == 1) { |
|
|
if (arguments_length == 1) { |
|
|
Lisp_Object* prompt = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* prompt = evaluated_arguments->value.pair.first; |
|
|
/* if (prompt->type == Lisp_Object_Type::String) */ |
|
|
|
|
|
/* printf("%s", prompt->value.string->value); */ |
|
|
|
|
|
/* else */ |
|
|
|
|
|
print(evaluated_arguments->value.pair.first); |
|
|
print(evaluated_arguments->value.pair.first); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -879,7 +835,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("exit", cLambda { |
|
|
defun("exit", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length <= 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length_less_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
if (arguments_length == 1) { |
|
|
if (arguments_length == 1) { |
|
|
Lisp_Object* error_code = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* error_code = evaluated_arguments->value.pair.first; |
|
|
@@ -899,7 +855,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("try", cLambda { |
|
|
defun("try", cLambda { |
|
|
try arguments_length = list_length(arguments); |
|
|
try arguments_length = list_length(arguments); |
|
|
try assert(arguments_length == 2); |
|
|
|
|
|
|
|
|
try assert_arguments_length(2, arguments_length); |
|
|
|
|
|
|
|
|
Lisp_Object* try_part = arguments->value.pair.first; |
|
|
Lisp_Object* try_part = arguments->value.pair.first; |
|
|
Lisp_Object* catch_part = arguments->value.pair.rest->value.pair.first; |
|
|
Lisp_Object* catch_part = arguments->value.pair.rest->value.pair.first; |
|
|
@@ -908,21 +864,18 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
result = eval_expr(try_part, env); |
|
|
result = eval_expr(try_part, env); |
|
|
if (Globals::error) { |
|
|
if (Globals::error) { |
|
|
delete_error(); |
|
|
delete_error(); |
|
|
try { |
|
|
|
|
|
result = eval_expr(catch_part, env); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try result = eval_expr(catch_part, env); |
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
}); |
|
|
}); |
|
|
defun("load", cLambda { |
|
|
defun("load", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); |
|
|
|
|
|
|
|
|
Lisp_Object* result; |
|
|
Lisp_Object* result; |
|
|
try { |
|
|
|
|
|
result = built_in_load(evaluated_arguments->value.pair.first->value.string, env); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
try result = built_in_load(evaluated_arguments->value.pair.first->value.string, env); |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
|
|
|
|
|
|
|
}); |
|
|
}); |
|
|
@@ -931,7 +884,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
// TODO(Felix): if we are copying string nodes, then |
|
|
// TODO(Felix): if we are copying string nodes, then |
|
|
// shouldn't the string itself also get copied?? |
|
|
// shouldn't the string itself also get copied?? |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (evaluated_arguments->value.pair.first == Memory::nil || |
|
|
if (evaluated_arguments->value.pair.first == Memory::nil || |
|
|
@@ -952,13 +905,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
defun("error", cLambda { |
|
|
defun("error", cLambda { |
|
|
// TODO(Felix): make the error function useful |
|
|
// TODO(Felix): make the error function useful |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 0); |
|
|
|
|
|
|
|
|
try assert_arguments_length(0, arguments_length); |
|
|
create_generic_error("Userlanderror"); |
|
|
create_generic_error("Userlanderror"); |
|
|
return nullptr; |
|
|
return nullptr; |
|
|
}); |
|
|
}); |
|
|
defun("symbol->keyword", cLambda { |
|
|
defun("symbol->keyword", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); |
|
|
|
|
|
|
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
@@ -970,7 +923,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
// example, numbers are not valid symbols. |
|
|
// example, numbers are not valid symbols. |
|
|
|
|
|
|
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); |
|
|
|
|
|
|
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
@@ -979,7 +932,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("symbol->string", cLambda { |
|
|
defun("symbol->string", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length == 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length(1, arguments_length); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); |
|
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); |
|
|
|
|
|
|
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
Lisp_Object* source = evaluated_arguments->value.pair.first; |
|
|
@@ -988,7 +941,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { |
|
|
}); |
|
|
}); |
|
|
defun("concat-strings", cLambda { |
|
|
defun("concat-strings", cLambda { |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); |
|
|
try assert(arguments_length >= 1); |
|
|
|
|
|
|
|
|
try assert_arguments_length_greater_equal(1, arguments_length); |
|
|
|
|
|
|
|
|
int resulting_string_len = 0; |
|
|
int resulting_string_len = 0; |
|
|
|
|
|
|
|
|
|