used assert_arguments_length for better errors
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
(font-lock-add-keywords
|
(font-lock-add-keywords
|
||||||
'c++-mode
|
'c++-mode
|
||||||
'(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" .
|
'(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\|try\\|try_void\\|without_logging\\)\\>" .
|
||||||
font-lock-keyword-face)))))))
|
font-lock-keyword-face)))))))
|
||||||
|
|
||||||
(c++-mode . ((eval . (company-clang-set-prefix "slime.h"))
|
(c++-mode . ((eval . (company-clang-set-prefix "slime.h"))
|
||||||
|
|||||||
+65
-112
@@ -114,9 +114,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
|
|
||||||
defun("=", cLambda {
|
defun("=", cLambda {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
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);
|
||||||
|
|
||||||
try {
|
|
||||||
assert(arguments_length == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
try assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
|
||||||
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 {
|
try result = eval_expr(catch_part, env);
|
||||||
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 {
|
try result = built_in_load(evaluated_arguments->value.pair.first->value.string, env);
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
+46
-8
@@ -54,6 +54,25 @@ constexpr bool is_debug_build = false;
|
|||||||
} \
|
} \
|
||||||
else label(body,__LINE__):
|
else label(body,__LINE__):
|
||||||
|
|
||||||
|
;
|
||||||
|
#define without_logging \
|
||||||
|
if (0) \
|
||||||
|
label(finished,__LINE__): ; \
|
||||||
|
else \
|
||||||
|
for (Log_Level log_level_before = log_level;;) \
|
||||||
|
for(log_level = Log_Level::None;;) \
|
||||||
|
if (1) { \
|
||||||
|
goto label(body,__LINE__); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
while (1) \
|
||||||
|
if (1) { \
|
||||||
|
log_level = log_level_before; \
|
||||||
|
goto label(finished,__LINE__); \
|
||||||
|
} \
|
||||||
|
else label(body,__LINE__):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define define_array_list(type, name) \
|
#define define_array_list(type, name) \
|
||||||
struct name##_Array_List { \
|
struct name##_Array_List { \
|
||||||
@@ -147,6 +166,17 @@ struct {
|
|||||||
"Wrong number of arguments: expected %d, got %d", \
|
"Wrong number of arguments: expected %d, got %d", \
|
||||||
expected, actual)
|
expected, actual)
|
||||||
|
|
||||||
|
#define create_too_many_arguments_error(expected, actual) \
|
||||||
|
__create_error("wrong-number-of-arguments", \
|
||||||
|
"Wrong number of arguments: expected less or equal to %d, got %d", \
|
||||||
|
expected, actual)
|
||||||
|
|
||||||
|
#define create_too_few_arguments_error(expected, actual) \
|
||||||
|
__create_error("wrong-number-of-arguments", \
|
||||||
|
"Wrong number of arguments: expected greater or equal to %d, got %d", \
|
||||||
|
expected, actual)
|
||||||
|
|
||||||
|
|
||||||
#define assert_arguments_length(expected, actual) \
|
#define assert_arguments_length(expected, actual) \
|
||||||
do { \
|
do { \
|
||||||
if (expected != actual) { \
|
if (expected != actual) { \
|
||||||
@@ -154,6 +184,22 @@ struct {
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
// TODO(Felix): Shouldn't it be expected > actual here
|
||||||
|
#define assert_arguments_length_less_equal(expected, actual) \
|
||||||
|
do { \
|
||||||
|
if (expected < actual) { \
|
||||||
|
create_too_many_arguments_error(expected, actual); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
// TODO(Felix): Shouldn't it be expected < actual here
|
||||||
|
#define assert_arguments_length_greater_equal(expected, actual) \
|
||||||
|
do { \
|
||||||
|
if (expected > actual) { \
|
||||||
|
create_too_few_arguments_error(expected, actual); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define assert_type(_node, _type) \
|
#define assert_type(_node, _type) \
|
||||||
do { \
|
do { \
|
||||||
@@ -162,14 +208,6 @@ struct {
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define assert_arguments_length(expected, actual) \
|
|
||||||
do { \
|
|
||||||
if (expexted != actual) { \
|
|
||||||
create_wrong_number_of_arguments_error(expected, actual); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
#define assert(condition) \
|
#define assert(condition) \
|
||||||
do { \
|
do { \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
|
|||||||
+4
-7
@@ -426,7 +426,10 @@ proc test_built_in_type() -> testresult {
|
|||||||
// trying to set invalid user type
|
// trying to set invalid user type
|
||||||
char exp_string3[] = "(prog (set-type a \"wrong tpye\")(type a))";
|
char exp_string3[] = "(prog (set-type a \"wrong tpye\")(type a))";
|
||||||
expression = Parser::parse_single_expression(exp_string3);
|
expression = Parser::parse_single_expression(exp_string3);
|
||||||
result = eval_expr(expression, env);
|
|
||||||
|
without_logging {
|
||||||
|
result = eval_expr(expression, env);
|
||||||
|
}
|
||||||
|
|
||||||
assert_error();
|
assert_error();
|
||||||
delete_error();
|
delete_error();
|
||||||
@@ -498,12 +501,6 @@ proc test_file(const char* file) -> testresult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc run_all_tests() -> bool {
|
proc run_all_tests() -> bool {
|
||||||
Log_Level log_level_before = log_level;
|
|
||||||
log_level = Log_Level::None;
|
|
||||||
defer {
|
|
||||||
log_level = log_level_before;
|
|
||||||
};
|
|
||||||
|
|
||||||
Memory::init(4096 * 2, 4096 * 16);
|
Memory::init(4096 * 2, 4096 * 16);
|
||||||
Parser::init(Memory::create_built_ins_environment());
|
Parser::init(Memory::create_built_ins_environment());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user