made source_Code_Locations more reliable (sill oncorrect sometimes)
This commit is contained in:
+35
-2
@@ -55,7 +55,7 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
create_error(Error_Type::Unknown_Error, nullptr);
|
||||
create_error(Error_Type::File_Not_Found, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
#define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object*
|
||||
#define report_error(_type) { \
|
||||
create_error(_type, arguments->sourceCodeLocation); \
|
||||
create_error(_type, current_source_code_location); \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
@@ -294,6 +294,23 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::create_lisp_object_number(pow(base, exponent));
|
||||
});
|
||||
defun("assert", cLambda {
|
||||
int arguments_length;
|
||||
debug_break();
|
||||
try {
|
||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
}
|
||||
|
||||
if (arguments_length != 1) {
|
||||
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||
}
|
||||
|
||||
if (is_truthy(arguments->value.pair->first, env))
|
||||
return Memory::t;
|
||||
|
||||
report_error(Error_Type::Assertion_Error);
|
||||
return nullptr;
|
||||
});
|
||||
defun("define", cLambda {
|
||||
try {
|
||||
arguments_length = list_length(arguments);
|
||||
@@ -1069,7 +1086,23 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
report_error(Error_Type::Unknown_Error);
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
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.string);
|
||||
});
|
||||
defun("string->symbol", cLambda {
|
||||
|
||||
// TODO(Felix): do some sanity checks on the string. For
|
||||
|
||||
+3
-1
@@ -18,6 +18,8 @@ proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
||||
|
||||
proc Error_Type_to_string(Error_Type type) -> const char* {
|
||||
switch (type) {
|
||||
case Error_Type::Assertion_Error: return "Assertion failed";
|
||||
case Error_Type::File_Not_Found: return "File not found";
|
||||
case Error_Type::Ill_Formed_Arguments: return "Evaluation-error: Ill formed arguments";
|
||||
case Error_Type::Ill_Formed_Lambda_List: return "Evaluation-error: Ill formed lambda list";
|
||||
case Error_Type::Ill_Formed_List: return "Evaluation-error: Ill formed list";
|
||||
@@ -32,7 +34,7 @@ proc Error_Type_to_string(Error_Type type) -> const char* {
|
||||
case Error_Type::Unknown_Keyword_Argument: return "Evaluation-error: Unknown keyword argument";
|
||||
case Error_Type::Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments";
|
||||
case Error_Type::Out_Of_Memory: return "Runtime-error: Out of memory";
|
||||
default: return "Unknown Error";
|
||||
default: return "this error type doesn't have a desciption..";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -1,3 +1,5 @@
|
||||
Source_Code_Location* current_source_code_location = nullptr;
|
||||
|
||||
proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> Lisp_Object* {
|
||||
Environment* new_env = Memory::create_child_environment(function->parent_environment);
|
||||
|
||||
@@ -330,6 +332,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
|
||||
evaluated_arguments_head->value.pair->first =
|
||||
eval_expr(current_head->value.pair->first, env);
|
||||
}
|
||||
evaluated_arguments_head->value.pair->first->sourceCodeLocation = current_head->value.pair->first->sourceCodeLocation;
|
||||
current_head = current_head->value.pair->rest;
|
||||
|
||||
if (current_head->type == Lisp_Object_Type::Pair) {
|
||||
@@ -368,6 +371,8 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||
return symbol;
|
||||
}
|
||||
case Lisp_Object_Type::Pair: {
|
||||
current_source_code_location = node->sourceCodeLocation;
|
||||
|
||||
Lisp_Object* lispOperator;
|
||||
if (node->value.pair->first->type != Lisp_Object_Type::CFunction &&
|
||||
node->value.pair->first->type != Lisp_Object_Type::Function)
|
||||
@@ -464,7 +469,6 @@ proc interprete_stdin() -> void {
|
||||
char* line;
|
||||
|
||||
built_in_load(Memory::create_string("pre.slime"), env);
|
||||
built_in_load(Memory::create_string("test.slime"), env);
|
||||
|
||||
if (error) {
|
||||
log_error();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
proc built_in_load(String*, Environment*) -> Lisp_Object*;
|
||||
proc print_environment(Environment*) -> void;
|
||||
proc eval_arguments(Lisp_Object*, Environment*, int*) -> Lisp_Object*;
|
||||
proc eval_expr(Lisp_Object*, Environment*) -> Lisp_Object*;
|
||||
|
||||
+1
-1
@@ -200,7 +200,7 @@ proc read_line() -> char* {
|
||||
}
|
||||
(*line)--; // we dont want the \n actually
|
||||
*line = '\0';
|
||||
|
||||
|
||||
return linep;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -3,8 +3,7 @@
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc > 1) {
|
||||
if (Slime::string_equal(argv[1], "--run-tests")) {
|
||||
Slime::run_all_tests();
|
||||
return 0;
|
||||
return Slime::run_all_tests() ? 0 : 1;
|
||||
}
|
||||
|
||||
Slime::interprete_file(argv[1]);
|
||||
|
||||
+13
-9
@@ -4,15 +4,15 @@ namespace Parser {
|
||||
int parser_line;
|
||||
int parser_col;
|
||||
// NOTE(Felix): In this environment, the build in functions will
|
||||
// be loaded, and the macros will be stroed in form of
|
||||
// be loaded, and the macros will be stored in form of
|
||||
// special-lambdas, that get executed in this environment at
|
||||
// read-time. This should always be the global environment.
|
||||
Environment* environment_for_macros;
|
||||
|
||||
proc init(Environment* env) -> void {
|
||||
// NOTE(Felix): it is important to keep the parser environment
|
||||
// up to date with the global environment. When donig tests,
|
||||
// or running a programm we have to reaload it.
|
||||
// up to date with the global environment. When doing tests,
|
||||
// or running a programm we have to reload it.
|
||||
|
||||
// NOTE(Felix): For now we just allow executing built-ins at
|
||||
// read-time (while creating macros). If later we want to
|
||||
@@ -241,18 +241,21 @@ namespace Parser {
|
||||
}
|
||||
}
|
||||
|
||||
Lisp_Object* ret = nullptr;
|
||||
if (quoteType == '\'')
|
||||
return Memory::create_lisp_object_pair(
|
||||
ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("quote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
else if (quoteType == '`')
|
||||
return Memory::create_lisp_object_pair(
|
||||
ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("quasiquote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
// it has to be an unquote
|
||||
return Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("unquote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
else if (quoteType == ',')
|
||||
ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("unquote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
inject_scl(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,6 +280,7 @@ namespace Parser {
|
||||
Lisp_Object* expression = head;
|
||||
|
||||
while (true) {
|
||||
inject_scl(head);
|
||||
if (text[*index_in_text] == '(' ||
|
||||
text[*index_in_text] == '\''||
|
||||
text[*index_in_text] == '`' ||
|
||||
|
||||
+1
-1
@@ -18,8 +18,8 @@ namespace Slime {
|
||||
#include "./io.cpp"
|
||||
#include "./env.cpp"
|
||||
#include "./parse.cpp"
|
||||
#include "./built_ins.cpp"
|
||||
#include "./eval.cpp"
|
||||
#include "./built_ins.cpp"
|
||||
#include "./testing.cpp"
|
||||
#include "./undefines.cpp"
|
||||
}
|
||||
|
||||
+3
-1
@@ -27,11 +27,14 @@ enum struct Function_Type {
|
||||
};
|
||||
|
||||
enum struct Error_Type {
|
||||
Assertion_Error,
|
||||
File_Not_Found,
|
||||
Ill_Formed_Arguments,
|
||||
Ill_Formed_Lambda_List,
|
||||
Ill_Formed_List,
|
||||
Not_A_Function,
|
||||
Not_Yet_Implemented,
|
||||
Out_Of_Memory,
|
||||
Symbol_Not_Defined,
|
||||
Syntax_Error,
|
||||
Trailing_Garbage,
|
||||
@@ -41,7 +44,6 @@ enum struct Error_Type {
|
||||
Unknown_Error,
|
||||
Unknown_Keyword_Argument,
|
||||
Wrong_Number_Of_Arguments,
|
||||
Out_Of_Memory,
|
||||
};
|
||||
|
||||
enum struct Log_Level {
|
||||
|
||||
+35
-5
@@ -85,8 +85,9 @@
|
||||
printf("%spassed%s\n", console_green, console_normal); \
|
||||
} \
|
||||
else { \
|
||||
result = false; \
|
||||
for(int i = -1; i < 70; ++i) \
|
||||
printf((i%3==1)? "." : " "); \
|
||||
printf((i%3==1)? "." : " "); \
|
||||
printf("%sfailed%s\n", console_red, console_normal); \
|
||||
if(error) { \
|
||||
free(error); \
|
||||
@@ -455,16 +456,42 @@ proc test_singular_t_and_nil() -> testresult {
|
||||
|
||||
assert_no_error();
|
||||
assert_not_null(result3);
|
||||
assert_equal_int(result3, Memory::t);
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
proc run_all_tests() -> void {
|
||||
log_level = Log_Level::None;
|
||||
proc test_class_macro() -> testresult {
|
||||
Memory::init();
|
||||
Environment* env = Memory::create_built_ins_environment();
|
||||
Parser::init(env);
|
||||
|
||||
built_in_load(Memory::create_string("pre.slime"), env);
|
||||
Lisp_Object* result = built_in_load(Memory::create_string("tests/class_macro.slime"), env);
|
||||
|
||||
assert_no_error();
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
proc test_lexical_scope() -> testresult {
|
||||
Memory::init();
|
||||
Environment* env = Memory::create_built_ins_environment();
|
||||
Parser::init(env);
|
||||
|
||||
built_in_load(Memory::create_string("pre.slime"), env);
|
||||
Lisp_Object* result = built_in_load(Memory::create_string("tests/lexical_scope.slime"), env);
|
||||
|
||||
assert_no_error();
|
||||
return pass;
|
||||
}
|
||||
|
||||
proc run_all_tests() -> bool {
|
||||
// log_level = Log_Level::None;
|
||||
Memory::init();
|
||||
Parser::init(Memory::create_built_ins_environment());
|
||||
|
||||
bool result = true;
|
||||
|
||||
printf("-- Parsing --\n");
|
||||
invoke_test(test_parse_atom);
|
||||
invoke_test(test_parse_expression);
|
||||
@@ -486,10 +513,13 @@ proc run_all_tests() -> void {
|
||||
printf("\n-- Memory management --\n");
|
||||
invoke_test(test_singular_t_and_nil);
|
||||
|
||||
printf("\n-- Lexical scope --\n");
|
||||
printf("\n-- Macros --\n");
|
||||
|
||||
printf("\n-- Test Files --\n");
|
||||
invoke_test(test_class_macro);
|
||||
invoke_test(test_lexical_scope);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef epsilon
|
||||
|
||||
Reference in New Issue
Block a user