Przeglądaj źródła

Finished the error refactor

master
Felix Brendel 7 lat temu
rodzic
commit
33ca222922
5 zmienionych plików z 174 dodań i 352 usunięć
  1. +141
    -326
      src/built_ins.cpp
  2. +21
    -11
      src/defines.cpp
  3. +9
    -12
      src/eval.cpp
  4. +2
    -2
      src/slime.h
  5. +1
    -1
      src/testing.cpp

+ 141
- 326
src/built_ins.cpp Wyświetl plik

@@ -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) {
create_error(Error_Type::Wrong_Number_Of_Arguments, arguments->sourceCodeLocation);
return nullptr;
try {
assert(arguments_length == 2);
} }


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 {
arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);


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) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try arguments_length = list_length(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 {
assert_type(real_symbol, Lisp_Object_Type::Symbol);
}
try 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) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
if (symbol->type != Lisp_Object_Type::Symbol) {
report_error(Error_Type::Type_Missmatch);
}
try assert(arguments_length <= 2);
try assert_type(symbol, Lisp_Object_Type::Symbol);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 2)
report_error(Error_Type::Wrong_Number_Of_Arguments);
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 2);


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 {
arguments_length = list_length(arguments);
}

if (arguments_length != 2 && arguments_length != 3) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try arguments_length = list_length(arguments);
try assert(arguments_length == 2 || arguments_length == 3);


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 {
truthy = is_truthy(condition, env);
}
try truthy = is_truthy(condition, env);


Lisp_Object* result; Lisp_Object* result;


if (truthy) if (truthy)
try{
result = eval_expr(then_part->value.pair.first, env);
}
try result = eval_expr(then_part->value.pair.first, env);
else if (arguments_length == 3) else if (arguments_length == 3)
try {
result = eval_expr(else_part->value.pair.first, env);
}
try 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 {
arguments_length = list_length(arguments);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}

try arguments_length = list_length(arguments);
try assert(arguments_length == 1);
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);


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) {
report_error(Error_Type::Ill_Formed_List);
}
try {
result &= is_truthy(arguments->value.pair.first, env);
}
arguments = arguments->value.pair.rest;
try assert_type(arguments, Lisp_Object_Type::Pair);
try result &= is_truthy(arguments->value.pair.first, env);


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) {
report_error(Error_Type::Ill_Formed_List);
}
try {
result |= is_truthy(arguments->value.pair.first, env);
}
arguments = arguments->value.pair.rest;
try assert_type(arguments, Lisp_Object_Type::Pair);
try result |= is_truthy(arguments->value.pair.first, env);


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 {
arguments_length = list_length(arguments);
}
try 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);
}
if (truthy)
return Memory::nil;
return Memory::t;

try truthy = is_truthy(arguments->value.pair.first, env);

return (truthy) ? Memory::nil : Memory::t;
}); });
defun("while", cLambda { defun("while", cLambda {
try {
arguments_length = list_length(arguments);
}
try 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 {
condition = eval_expr(condition_part, env);
}
if (condition->type == Lisp_Object_Type::Nil) {
try condition = eval_expr(condition_part, env);

if (condition->type == Lisp_Object_Type::Nil)
break; break;
}
try {
result = eval_expr(then_part->value.pair.first, env);
}

try 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 {
arguments_length = list_length(arguments);
}

if (arguments_length < 1)
report_error(Error_Type::Wrong_Number_Of_Arguments);
try arguments_length = list_length(arguments);
try assert(arguments_length >= 1);


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);
}
if (rest_sym->value.pair.rest->type != Lisp_Object_Type::Nil) {
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);


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 {
evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
}
try 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 {
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);
// parse lambda starting from arguments
try arguments_length = list_length(arguments);
try assert(arguments_length != 0);


Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, false);


return function; return function;
}); });
defun("special-lambda", cLambda { defun("special-lambda", cLambda {
/*
* (special-lambda ())
* (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);
try arguments_length = list_length(arguments);
try assert(arguments_length != 0);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);

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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
try 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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
return evaluated_arguments; return evaluated_arguments;
}); });
defun("pair", cLambda { defun("pair", cLambda {
try {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 2) {
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);
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 2);
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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);

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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);

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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 2) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 2);


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 {
assert_type(type, Lisp_Object_Type::Keyword);
}
try 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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);

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);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);


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 {
arguments_length = list_length(arguments);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try arguments_length = list_length(arguments);
try assert(arguments_length == 1);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
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);
}
try 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);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1);

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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length > 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length <= 1);


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();
defer {
free(line);
};
String* strLine = Memory::create_string(line); String* strLine = Memory::create_string(line);
free(line);
return Memory::create_lisp_object_string(strLine); return Memory::create_lisp_object_string(strLine);
}); });
defun("exit", cLambda { defun("exit", cLambda {
try {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length > 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length <= 1);


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)
report_error(Error_Type::Type_Missmatch);

try assert_type(error_code, Lisp_Object_Type::Number);
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 {
arguments_length = list_length(arguments);
}

if (arguments_length != 2) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try arguments_length = list_length(arguments);
try assert(arguments_length == 2);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

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);
try 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);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
try 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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}
if (arguments_length != 0) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
report_error(Error_Type::Unknown_Error);
// TODO(Felix): make the error function useful
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 0);
create_generic_error("Userlanderror");
return nullptr;
}); });
defun("symbol->keyword", cLambda { defun("symbol->keyword", cLambda {
try {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try 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);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try 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);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length != 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try 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);


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 {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
}

if (arguments_length < 1) {
report_error(Error_Type::Wrong_Number_Of_Arguments);
}
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length >= 1);


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 {
assert_type(head->value.pair.first, Lisp_Object_Type::String);
}
resulting_string_len += head->value.pair.first->value.string->length;
try assert_type(head->value.pair.first, Lisp_Object_Type::String);


resulting_string_len += head->value.pair.first->value.string->length;
head = head->value.pair.rest; head = head->value.pair.rest;
} }




+ 21
- 11
src/defines.cpp Wyświetl plik

@@ -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
src/eval.cpp Wyświetl plik

@@ -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) {
create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
return 0;
}
assert_type(node, Lisp_Object_Type::Pair);


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
src/slime.h Wyświetl plik

@@ -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
src/testing.cpp Wyświetl plik

@@ -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();




Ładowanie…
Anuluj
Zapisz