Finished the error refactor
This commit is contained in:
+140
-325
@@ -24,7 +24,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
|||||||
case Lisp_Object_Type::Number:
|
case Lisp_Object_Type::Number:
|
||||||
return n1->value.number == n2->value.number;
|
return n1->value.number == n2->value.number;
|
||||||
case Lisp_Object_Type::Pair:
|
case Lisp_Object_Type::Pair:
|
||||||
create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation);
|
create_not_yet_implemented_error();
|
||||||
return false;
|
return false;
|
||||||
case Lisp_Object_Type::String:
|
case Lisp_Object_Type::String:
|
||||||
return string_equal(n1->value.string, n2->value.string);
|
return string_equal(n1->value.string, n2->value.string);
|
||||||
@@ -51,7 +51,7 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
create_error(Error_Type::File_Not_Found, nullptr);
|
create_generic_error("The file '%s' was not found", file_name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,9 +318,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2) {
|
try {
|
||||||
create_error(Error_Type::Wrong_Number_Of_Arguments, arguments->sourceCodeLocation);
|
assert(arguments_length == 2);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -342,28 +341,19 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
defun("assert", cLambda {
|
defun("assert", 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 == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_truthy(arguments->value.pair.first, env))
|
if (is_truthy(arguments->value.pair.first, env))
|
||||||
return Memory::t;
|
return Memory::t;
|
||||||
|
|
||||||
report_error(Error_Type::Assertion_Error);
|
create_generic_error("Userland assertion.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
defun("define", cLambda {
|
defun("define", cLambda {
|
||||||
try {
|
|
||||||
arguments_length = list_length(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length < 2) {
|
try arguments_length = list_length(arguments);
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
try assert(arguments_length >= 2);
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* symbol = arguments->value.pair.first;
|
Lisp_Object* symbol = arguments->value.pair.first;
|
||||||
Lisp_Object* value;
|
Lisp_Object* value;
|
||||||
@@ -390,9 +380,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
|
|
||||||
Lisp_Object* real_symbol = symbol->value.pair.first;
|
Lisp_Object* real_symbol = symbol->value.pair.first;
|
||||||
|
|
||||||
try {
|
try assert_type(real_symbol, Lisp_Object_Type::Symbol);
|
||||||
assert_type(real_symbol, Lisp_Object_Type::Symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* fake_lambda = Memory::create_lisp_object_pair(
|
Lisp_Object* fake_lambda = Memory::create_lisp_object_pair(
|
||||||
symbol ->value.pair.rest,
|
symbol ->value.pair.rest,
|
||||||
@@ -401,17 +389,12 @@ 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 {
|
||||||
if (arguments_length > 2) {
|
try assert(arguments_length <= 2);
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
try assert_type(symbol, Lisp_Object_Type::Symbol);
|
||||||
}
|
|
||||||
if (symbol->type != Lisp_Object_Type::Symbol) {
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = arguments->value.pair.rest->value.pair.first;
|
value = arguments->value.pair.rest->value.pair.first;
|
||||||
try {
|
|
||||||
value = eval_expr(value, env);
|
try value = eval_expr(value, env);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define_symbol(symbol, value, env);
|
define_symbol(symbol, value, env);
|
||||||
@@ -454,17 +437,14 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
// return value;
|
// return value;
|
||||||
// });
|
// });
|
||||||
defun("mutate", cLambda {
|
defun("mutate", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 2);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 2)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
|
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
|
||||||
|
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::T ||
|
||||||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
|
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
|
||||||
{
|
{
|
||||||
report_error(Error_Type::Type_Missmatch);
|
create_generic_error("You cannot mutate nil, t or keywords");
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||||
@@ -474,55 +454,35 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return target;
|
return target;
|
||||||
});
|
});
|
||||||
defun("if", cLambda {
|
defun("if", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 2 || arguments_length == 3);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 2 && arguments_length != 3) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
Lisp_Object* else_part = then_part->value.pair.rest;
|
Lisp_Object* else_part = then_part->value.pair.rest;
|
||||||
|
|
||||||
bool truthy;
|
bool truthy;
|
||||||
try {
|
try truthy = is_truthy(condition, env);
|
||||||
truthy = is_truthy(condition, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
|
|
||||||
if (truthy)
|
if (truthy)
|
||||||
try{
|
try result = eval_expr(then_part->value.pair.first, env);
|
||||||
result = eval_expr(then_part->value.pair.first, env);
|
|
||||||
}
|
|
||||||
else if (arguments_length == 3)
|
else if (arguments_length == 3)
|
||||||
try {
|
try result = eval_expr(else_part->value.pair.first, env);
|
||||||
result = eval_expr(else_part->value.pair.first, env);
|
|
||||||
}
|
|
||||||
else return Memory::nil;
|
else return Memory::nil;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
defun("quote", cLambda {
|
defun("quote", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
return arguments->value.pair.first;
|
return arguments->value.pair.first;
|
||||||
});
|
});
|
||||||
defun("quasiquote", cLambda {
|
defun("quasiquote", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
// print(arguments);
|
// print(arguments);
|
||||||
// printf("\n");
|
// printf("\n");
|
||||||
|
|
||||||
@@ -582,107 +542,77 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
defun("and", cLambda {
|
defun("and", cLambda {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
while (arguments->type != Lisp_Object_Type::Nil) {
|
while (arguments->type != Lisp_Object_Type::Nil) {
|
||||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
try assert_type(arguments, Lisp_Object_Type::Pair);
|
||||||
report_error(Error_Type::Ill_Formed_List);
|
try result &= is_truthy(arguments->value.pair.first, env);
|
||||||
}
|
|
||||||
try {
|
|
||||||
result &= is_truthy(arguments->value.pair.first, env);
|
|
||||||
}
|
|
||||||
arguments = arguments->value.pair.rest;
|
|
||||||
|
|
||||||
|
arguments = arguments->value.pair.rest;
|
||||||
if (!result) return Memory::nil;
|
if (!result) return Memory::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Memory::t;
|
return Memory::t;
|
||||||
});
|
});
|
||||||
defun("or", cLambda {
|
defun("or", cLambda {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
while (arguments->type != Lisp_Object_Type::Nil) {
|
while (arguments->type != Lisp_Object_Type::Nil) {
|
||||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
try assert_type(arguments, Lisp_Object_Type::Pair);
|
||||||
report_error(Error_Type::Ill_Formed_List);
|
try result |= is_truthy(arguments->value.pair.first, env);
|
||||||
}
|
|
||||||
try {
|
|
||||||
result |= is_truthy(arguments->value.pair.first, env);
|
|
||||||
}
|
|
||||||
arguments = arguments->value.pair.rest;
|
|
||||||
|
|
||||||
|
arguments = arguments->value.pair.rest;
|
||||||
if (result) return Memory::t;
|
if (result) return Memory::t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
});
|
});
|
||||||
defun("not", cLambda {
|
defun("not", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
bool truthy;
|
bool truthy;
|
||||||
try {
|
|
||||||
truthy = is_truthy(arguments->value.pair.first, env);
|
try truthy = is_truthy(arguments->value.pair.first, env);
|
||||||
}
|
|
||||||
if (truthy)
|
return (truthy) ? Memory::nil : Memory::t;
|
||||||
return Memory::nil;
|
|
||||||
return Memory::t;
|
|
||||||
});
|
});
|
||||||
defun("while", cLambda {
|
defun("while", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length >= 2);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length < 2) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
Lisp_Object* condition_part = arguments->value.pair.first;
|
Lisp_Object* condition_part = arguments->value.pair.first;
|
||||||
Lisp_Object* condition;
|
Lisp_Object* condition;
|
||||||
Lisp_Object* then_part = arguments->value.pair.rest;
|
Lisp_Object* then_part = arguments->value.pair.rest;
|
||||||
Lisp_Object* result = Memory::nil;
|
Lisp_Object* result = Memory::nil;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try condition = eval_expr(condition_part, env);
|
||||||
condition = eval_expr(condition_part, env);
|
|
||||||
}
|
if (condition->type == Lisp_Object_Type::Nil)
|
||||||
if (condition->type == Lisp_Object_Type::Nil) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
try {
|
try result = eval_expr(then_part->value.pair.first, env);
|
||||||
result = eval_expr(then_part->value.pair.first, env);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
});
|
});
|
||||||
defun("let", cLambda {
|
defun("let", cLambda {
|
||||||
// (let ((a 10)(b 20)) (body1) (body2))
|
// (let ((a 10)(b 20)) (body1) (body2))
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length >= 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length < 1)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
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;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (bindings->type == Lisp_Object_Type::Nil) {
|
if (bindings->type == Lisp_Object_Type::Nil) {
|
||||||
break;
|
break;
|
||||||
} else if (bindings->type != Lisp_Object_Type::Pair) {
|
|
||||||
report_error(Error_Type::Ill_Formed_Arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
if(sym->type != Lisp_Object_Type::Symbol) {
|
|
||||||
report_error(Error_Type::Ill_Formed_Arguments);
|
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;
|
||||||
if (rest_sym->type != Lisp_Object_Type::Pair) {
|
|
||||||
report_error(Error_Type::Ill_Formed_Arguments);
|
try assert_type(rest_sym, Lisp_Object_Type::Pair);
|
||||||
}
|
try assert_type(rest_sym->value.pair.rest, Lisp_Object_Type::Nil);
|
||||||
if (rest_sym->value.pair.rest->type != Lisp_Object_Type::Nil) {
|
|
||||||
report_error(Error_Type::Ill_Formed_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* value = eval_expr(rest_sym->value.pair.first, env);
|
Lisp_Object* value = eval_expr(rest_sym->value.pair.first, env);
|
||||||
|
|
||||||
@@ -697,9 +627,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
arguments = arguments->value.pair.rest;
|
arguments = arguments->value.pair.rest;
|
||||||
|
|
||||||
Lisp_Object* evaluated_arguments;
|
Lisp_Object* evaluated_arguments;
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evaluated_arguments->type == Lisp_Object_Type::Nil)
|
if (evaluated_arguments->type == Lisp_Object_Type::Nil)
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
@@ -719,56 +647,35 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
* (lambda ())
|
* (lambda ())
|
||||||
* (lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
|
* (lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
|
||||||
*/
|
*/
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length != 0);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length == 0)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env);
|
|
||||||
// parse lambda starting from arguments
|
|
||||||
|
|
||||||
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, false);
|
||||||
|
|
||||||
return function;
|
return function;
|
||||||
});
|
});
|
||||||
defun("special-lambda", cLambda {
|
defun("special-lambda", cLambda {
|
||||||
/*
|
try arguments_length = list_length(arguments);
|
||||||
* (special-lambda ())
|
try assert(arguments_length != 0);
|
||||||
* (special-lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
|
|
||||||
*/
|
|
||||||
try {
|
|
||||||
arguments_length = list_length(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length == 0)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, true);
|
Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, true);
|
||||||
// parse lambda starting from arguments
|
|
||||||
|
|
||||||
|
|
||||||
return function;
|
return function;
|
||||||
});
|
});
|
||||||
defun("eval", cLambda {
|
defun("eval", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
try {
|
|
||||||
result = eval_expr(evaluated_arguments->value.pair.first, env);
|
try result = eval_expr(evaluated_arguments->value.pair.first, env);
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
defun("prog", cLambda {
|
defun("prog", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evaluated_arguments->type == Lisp_Object_Type::Nil)
|
if (evaluated_arguments->type == Lisp_Object_Type::Nil)
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
@@ -784,84 +691,60 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return evaluated_arguments->value.pair.first;
|
return evaluated_arguments->value.pair.first;
|
||||||
});
|
});
|
||||||
defun("list", cLambda {
|
defun("list", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
|
||||||
}
|
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
});
|
});
|
||||||
defun("pair", cLambda {
|
defun("pair", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 2);
|
||||||
}
|
return Memory::create_lisp_object_pair(
|
||||||
|
evaluated_arguments->value.pair.first,
|
||||||
if (arguments_length != 2) {
|
evaluated_arguments->value.pair.rest->value.pair.first);
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
return Memory::create_lisp_object_pair(evaluated_arguments->value.pair.first, evaluated_arguments->value.pair.rest->value.pair.first);
|
|
||||||
});
|
});
|
||||||
defun("first", cLambda {
|
defun("first", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
|
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
|
||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::Pair)
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair);
|
||||||
|
|
||||||
return evaluated_arguments->value.pair.first->value.pair.first;
|
return evaluated_arguments->value.pair.first->value.pair.first;
|
||||||
});
|
});
|
||||||
defun("rest", cLambda {
|
defun("rest", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
|
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
|
||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::Pair)
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair);
|
||||||
|
|
||||||
return evaluated_arguments->value.pair.first->value.pair.rest;
|
return evaluated_arguments->value.pair.first->value.pair.rest;
|
||||||
});
|
});
|
||||||
defun("set-type", cLambda {
|
defun("set-type", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 2);
|
||||||
}
|
|
||||||
if (arguments_length != 2) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
try {
|
try assert_type(type, Lisp_Object_Type::Keyword);
|
||||||
assert_type(type, Lisp_Object_Type::Keyword);
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluated_arguments->value.pair.first->userType = type;
|
evaluated_arguments->value.pair.first->userType = type;
|
||||||
return type;
|
return type;
|
||||||
});
|
});
|
||||||
defun("delete-type", cLambda {
|
defun("delete-type", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
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 {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -891,13 +774,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return Memory::get_or_create_lisp_object_keyword("unknown");
|
return Memory::get_or_create_lisp_object_keyword("unknown");
|
||||||
});
|
});
|
||||||
defun("info", cLambda {
|
defun("info", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
print(arguments->value.pair.first);
|
print(arguments->value.pair.first);
|
||||||
|
|
||||||
@@ -971,15 +849,9 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
});
|
});
|
||||||
defun("show", cLambda {
|
defun("show", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Function);
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::Function) {
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
puts("body:\n");
|
puts("body:\n");
|
||||||
print(evaluated_arguments->value.pair.first->value.function.body);
|
print(evaluated_arguments->value.pair.first->value.function.body);
|
||||||
@@ -988,24 +860,16 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
});
|
});
|
||||||
defun("print", cLambda {
|
defun("print", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
print(evaluated_arguments->value.pair.first);
|
print(evaluated_arguments->value.pair.first);
|
||||||
// printf("\n");
|
|
||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
});
|
});
|
||||||
defun("read", cLambda {
|
defun("read", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length <= 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length > 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length == 1) {
|
if (arguments_length == 1) {
|
||||||
Lisp_Object* prompt = evaluated_arguments->value.pair.first;
|
Lisp_Object* prompt = evaluated_arguments->value.pair.first;
|
||||||
@@ -1014,25 +878,22 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
/* else */
|
/* else */
|
||||||
print(evaluated_arguments->value.pair.first);
|
print(evaluated_arguments->value.pair.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Felix): make read_line return a String*
|
||||||
char* line = read_line();
|
char* line = read_line();
|
||||||
String* strLine = Memory::create_string(line);
|
defer {
|
||||||
free(line);
|
free(line);
|
||||||
|
};
|
||||||
|
String* strLine = Memory::create_string(line);
|
||||||
return Memory::create_lisp_object_string(strLine);
|
return Memory::create_lisp_object_string(strLine);
|
||||||
});
|
});
|
||||||
defun("exit", cLambda {
|
defun("exit", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length <= 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length > 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
if (error_code->type != Lisp_Object_Type::Number)
|
try assert_type(error_code, Lisp_Object_Type::Number);
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
|
|
||||||
exit((int)error_code->value.number);
|
exit((int)error_code->value.number);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -1047,13 +908,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return Memory::nil;
|
return Memory::nil;
|
||||||
});
|
});
|
||||||
defun("try", cLambda {
|
defun("try", cLambda {
|
||||||
try {
|
try arguments_length = list_length(arguments);
|
||||||
arguments_length = list_length(arguments);
|
try assert(arguments_length == 2);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 2) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -1069,15 +925,9 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
defun("load", cLambda {
|
defun("load", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String);
|
||||||
|
|
||||||
if (arguments_length != 1)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::String)
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
|
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
try {
|
try {
|
||||||
@@ -1090,17 +940,15 @@ 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 {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length != 1)
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
|
if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
|
||||||
|
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::T ||
|
||||||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
|
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
|
||||||
{
|
{
|
||||||
report_error(Error_Type::Type_Missmatch);
|
create_generic_error("The values of 'nil', 't', and keywords can't be copied.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* target = Memory::create_lisp_object();
|
Lisp_Object* target = Memory::create_lisp_object();
|
||||||
@@ -1110,87 +958,54 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
return target;
|
return target;
|
||||||
});
|
});
|
||||||
defun("error", cLambda {
|
defun("error", cLambda {
|
||||||
try {
|
// TODO(Felix): make the error function useful
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
try assert(arguments_length == 0);
|
||||||
if (arguments_length != 0) {
|
create_generic_error("Userlanderror");
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
return nullptr;
|
||||||
}
|
|
||||||
report_error(Error_Type::Unknown_Error);
|
|
||||||
});
|
});
|
||||||
defun("symbol->keyword", cLambda {
|
defun("symbol->keyword", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol);
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
||||||
|
|
||||||
if (source->type != Lisp_Object_Type::Symbol) {
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Memory::get_or_create_lisp_object_keyword(source->value.identifier);
|
return Memory::get_or_create_lisp_object_keyword(source->value.identifier);
|
||||||
});
|
});
|
||||||
defun("string->symbol", cLambda {
|
defun("string->symbol", cLambda {
|
||||||
|
|
||||||
// TODO(Felix): do some sanity checks on the string. For
|
// TODO(Felix): do some sanity checks on the string. For
|
||||||
// example, numbers are not valid symbols.
|
// example, numbers are not valid symbols.
|
||||||
|
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String);
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
||||||
|
|
||||||
if (source->type != Lisp_Object_Type::String) {
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
|
return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
|
||||||
});
|
});
|
||||||
defun("symbol->string", cLambda {
|
defun("symbol->string", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length == 1);
|
||||||
}
|
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol);
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
Lisp_Object* source = evaluated_arguments->value.pair.first;
|
||||||
|
|
||||||
if (source->type != Lisp_Object_Type::Symbol) {
|
|
||||||
report_error(Error_Type::Type_Missmatch);
|
|
||||||
}
|
|
||||||
return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.identifier));
|
return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.identifier));
|
||||||
});
|
});
|
||||||
defun("concat-strings", cLambda {
|
defun("concat-strings", cLambda {
|
||||||
try {
|
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
try assert(arguments_length >= 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments_length < 1) {
|
|
||||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
int resulting_string_len = 0;
|
int resulting_string_len = 0;
|
||||||
|
|
||||||
Lisp_Object* head = evaluated_arguments;
|
Lisp_Object* head = evaluated_arguments;
|
||||||
|
|
||||||
while (head->type == Lisp_Object_Type::Pair) {
|
while (head->type == Lisp_Object_Type::Pair) {
|
||||||
try {
|
try assert_type(head->value.pair.first, Lisp_Object_Type::String);
|
||||||
assert_type(head->value.pair.first, Lisp_Object_Type::String);
|
|
||||||
}
|
|
||||||
resulting_string_len += head->value.pair.first->value.string->length;
|
|
||||||
|
|
||||||
|
resulting_string_len += head->value.pair.first->value.string->length;
|
||||||
head = head->value.pair.rest;
|
head = head->value.pair.rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-11
@@ -20,16 +20,6 @@ constexpr bool is_debug_build = false;
|
|||||||
# define if_linux if (1)
|
# define if_linux if (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define assert(cond) \
|
|
||||||
if_debug { \
|
|
||||||
if (!cond) { \
|
|
||||||
if (log_level == Log_Level::Debug) { \
|
|
||||||
printf("Assertion failed: %s %d", __FILE__, __LINE__); \
|
|
||||||
} \
|
|
||||||
debug_break(); \
|
|
||||||
} \
|
|
||||||
} else {} \
|
|
||||||
|
|
||||||
#define concat_( a, b) a##b
|
#define concat_( a, b) a##b
|
||||||
#define label(prefix, lnum) concat_(prefix,lnum)
|
#define label(prefix, lnum) concat_(prefix,lnum)
|
||||||
#define try \
|
#define try \
|
||||||
@@ -139,6 +129,9 @@ struct {
|
|||||||
#define create_generic_error(...) \
|
#define create_generic_error(...) \
|
||||||
__create_error("generic", __VA_ARGS__)
|
__create_error("generic", __VA_ARGS__)
|
||||||
|
|
||||||
|
#define create_not_yet_implemented_error() \
|
||||||
|
__create_error("not-yet-implemented", "This feature has not yet been implemented.")
|
||||||
|
|
||||||
#define create_parsing_error(...) \
|
#define create_parsing_error(...) \
|
||||||
__create_error("parsing-error", __VA_ARGS__)
|
__create_error("parsing-error", __VA_ARGS__)
|
||||||
|
|
||||||
@@ -160,10 +153,27 @@ struct {
|
|||||||
do { \
|
do { \
|
||||||
if (_node->type != _type) { \
|
if (_node->type != _type) { \
|
||||||
create_type_missmatch_error("symbol", Lisp_Object_Type_to_string(_node->type)); \
|
create_type_missmatch_error("symbol", Lisp_Object_Type_to_string(_node->type)); \
|
||||||
return nullptr; \
|
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define assert(condition) \
|
||||||
|
do { \
|
||||||
|
if (!(condition)) { \
|
||||||
|
create_generic_error("Assertion-error."); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
// #define assert(cond) \
|
||||||
|
// if_debug { \
|
||||||
|
// if (!cond) { \
|
||||||
|
// if (log_level == Log_Level::Debug) { \
|
||||||
|
// printf("Assertion failed: %s %d", __FILE__, __LINE__); \
|
||||||
|
// } \
|
||||||
|
// debug_break(); \
|
||||||
|
// } \
|
||||||
|
// } else {} \
|
||||||
|
|
||||||
|
|
||||||
#define console_normal "\x1B[0m"
|
#define console_normal "\x1B[0m"
|
||||||
#define console_red "\x1B[31m"
|
#define console_red "\x1B[31m"
|
||||||
#define console_green "\x1B[32m"
|
#define console_green "\x1B[32m"
|
||||||
|
|||||||
+9
-12
@@ -296,19 +296,19 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
|||||||
string_equal(arguments->value.pair.first->value.identifier, "rest"))
|
string_equal(arguments->value.pair.first->value.identifier, "rest"))
|
||||||
{
|
{
|
||||||
arguments = arguments->value.pair.rest;
|
arguments = arguments->value.pair.rest;
|
||||||
if (arguments->type != Lisp_Object_Type::Pair ||
|
if (// arguments->type != Lisp_Object_Type::Pair ||
|
||||||
arguments->value.pair.first->type != Lisp_Object_Type::Symbol)
|
arguments->value.pair.first->type != Lisp_Object_Type::Symbol)
|
||||||
{
|
{
|
||||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_parsing_error("After the 'rest' marker there must follow a symbol.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
function->rest_argument = arguments->value.pair.first->value.identifier;
|
function->rest_argument = arguments->value.pair.first->value.identifier;
|
||||||
if (arguments->value.pair.rest->type != Lisp_Object_Type::Nil) {
|
if (arguments->value.pair.rest->type != Lisp_Object_Type::Nil) {
|
||||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_parsing_error("The lambda list must end after the rest symbol");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("this should not happen?");
|
printf("this should not happen?");
|
||||||
create_error(Error_Type::Unknown_Error, arguments->sourceCodeLocation);
|
create_generic_error("What is happening?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +317,7 @@ proc list_length(Lisp_Object* node) -> int {
|
|||||||
if (node->type == Lisp_Object_Type::Nil)
|
if (node->type == Lisp_Object_Type::Nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (node->type != Lisp_Object_Type::Pair) {
|
assert_type(node, Lisp_Object_Type::Pair);
|
||||||
create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (node->type == Lisp_Object_Type::Pair) {
|
while (node->type == Lisp_Object_Type::Pair) {
|
||||||
@@ -330,7 +327,7 @@ proc list_length(Lisp_Object* node) -> int {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_error(Error_Type::Ill_Formed_List, node->sourceCodeLocation);
|
create_parsing_error("Can't calculate length of ill formed list.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +364,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
|
|||||||
} else if (current_head->type == Lisp_Object_Type::Nil) {
|
} else if (current_head->type == Lisp_Object_Type::Nil) {
|
||||||
evaluated_arguments_head->value.pair.rest = current_head;
|
evaluated_arguments_head->value.pair.rest = current_head;
|
||||||
} else {
|
} else {
|
||||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_parsing_error("Attempting to evaluate ill formed argument list.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
++my_out_arguments_length;
|
++my_out_arguments_length;
|
||||||
@@ -432,7 +429,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
create_error(Error_Type::Not_A_Function, node->sourceCodeLocation);
|
create_generic_error("Not a function.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +452,7 @@ proc interprete_file (char* file_name) -> Lisp_Object* {
|
|||||||
|
|
||||||
char* file_content = read_entire_file(file_name);
|
char* file_content = read_entire_file(file_name);
|
||||||
if (!file_content) {
|
if (!file_content) {
|
||||||
create_error(Error_Type::Unknown_Error, nullptr);
|
create_generic_error("The file '%s' could not be read.", file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
load_built_ins_into_environment(env);
|
load_built_ins_into_environment(env);
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@
|
|||||||
#undef _CRT_SECURE_NO_DEPRECATE
|
#undef _CRT_SECURE_NO_DEPRECATE
|
||||||
#undef _CRT_SECURE_NO_WARNINGS
|
#undef _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
// namespace Slime {
|
namespace Slime {
|
||||||
#include "./defines.cpp"
|
#include "./defines.cpp"
|
||||||
#include "./structs.cpp"
|
#include "./structs.cpp"
|
||||||
#include "./forward_decls.cpp"
|
#include "./forward_decls.cpp"
|
||||||
@@ -26,4 +26,4 @@
|
|||||||
#include "./built_ins.cpp"
|
#include "./built_ins.cpp"
|
||||||
#include "./testing.cpp"
|
#include "./testing.cpp"
|
||||||
#include "./undefines.cpp"
|
#include "./undefines.cpp"
|
||||||
// }
|
}
|
||||||
|
|||||||
+1
-1
@@ -478,7 +478,7 @@ proc test_singular_t_and_nil() -> testresult {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc test_file(char* file) -> testresult {
|
proc test_file(const char* file) -> testresult {
|
||||||
Memory::reset();
|
Memory::reset();
|
||||||
Environment* env = Memory::create_built_ins_environment();
|
Environment* env = Memory::create_built_ins_environment();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user