on the way to better errors
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@
|
||||
(font-lock-add-keywords 'c++-mode
|
||||
'(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" .
|
||||
font-lock-keyword-face)))))))
|
||||
(c++-mode . ((eval . (company-clang-set-prefix "main.cpp"))
|
||||
(c++-mode . ((eval . (company-clang-set-prefix "slime.h"))
|
||||
(eval . (flycheck-mode 0))
|
||||
(eval . (rainbow-mode 0))
|
||||
)))
|
||||
|
||||
@@ -122,6 +122,48 @@ struct {
|
||||
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
|
||||
#define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&]
|
||||
|
||||
/*
|
||||
Usage of the create_error_macros:
|
||||
|
||||
*/
|
||||
#define __create_error(keyword, ...) \
|
||||
create_error( \
|
||||
__FILE__, __LINE__, \
|
||||
Memory::get_or_create_lisp_object_keyword(keyword), \
|
||||
__VA_ARGS__)
|
||||
|
||||
|
||||
#define create_out_of_memory_error(...) \
|
||||
__create_error("out-of-memory", __VA_ARGS__)
|
||||
|
||||
#define create_generic_error(...) \
|
||||
__create_error("generic", __VA_ARGS__)
|
||||
|
||||
#define create_parsing_error(...) \
|
||||
__create_error("parsing-error", __VA_ARGS__)
|
||||
|
||||
#define create_symbol_undefined_error(...) \
|
||||
__create_error("symbol-undefined", __VA_ARGS__)
|
||||
|
||||
#define create_type_missmatch_error(expected, actual) \
|
||||
__create_error("type-missmatch", \
|
||||
"Type missmatch: expected %s, got %s", \
|
||||
expected, actual)
|
||||
|
||||
#define create_wrong_number_of_arguments_error(expected, actual) \
|
||||
__create_error("wrong-number-of-arguments", \
|
||||
"Wrong number of arguments: expected %d, got %d", \
|
||||
expected, actual)
|
||||
|
||||
|
||||
#define assert_type(_node, _type) \
|
||||
do { \
|
||||
if (_node->type != _type) { \
|
||||
create_type_missmatch_error("symbol", Lisp_Object_Type_to_string(_node->type)); \
|
||||
return nullptr; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define console_normal "\x1B[0m"
|
||||
#define console_red "\x1B[31m"
|
||||
#define console_green "\x1B[32m"
|
||||
|
||||
+2
-2
@@ -45,8 +45,8 @@ proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||
return Memory::t;
|
||||
}
|
||||
|
||||
printf("%s\n", Memory::get_c_str(identifier));
|
||||
create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);
|
||||
create_symbol_undefined_error("The symbol '%s' is not defined.", &identifier->data);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
+57
-28
@@ -7,40 +7,69 @@ proc delete_error() -> void {
|
||||
}
|
||||
}
|
||||
|
||||
proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
||||
proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void {
|
||||
if_debug {
|
||||
printf("Error created in:\n%s:%d\n", c_file_name, c_file_line);
|
||||
}
|
||||
|
||||
delete_error();
|
||||
debug_break();
|
||||
|
||||
error = new(Error);
|
||||
error->type = type;
|
||||
error->location = location;
|
||||
error->message = message;
|
||||
}
|
||||
|
||||
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";
|
||||
case Error_Type::Not_A_Function: return "Evaluation-error: Not a function";
|
||||
case Error_Type::Not_Yet_Implemented: return "Evaluation-error: Not yet implemented";
|
||||
case Error_Type::Symbol_Not_Defined: return "Evaluation-error: Symbol not defined";
|
||||
case Error_Type::Syntax_Error: return "Syntax Error";
|
||||
case Error_Type::Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression";
|
||||
case Error_Type::Type_Missmatch: return "Evaluation-error: Type Missmatch";
|
||||
case Error_Type::Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis";
|
||||
case Error_Type::Unexpected_Eof: return "Parsing-error: Unexpected EOF";
|
||||
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 "this error type doesn't have a desciption..";
|
||||
}
|
||||
|
||||
proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...) -> void {
|
||||
// HACK(Felix): the length of all error strings is 200!!!!!!!!!!
|
||||
|
||||
int length = 200;
|
||||
String* formatted_string = Memory::create_string("", length);
|
||||
|
||||
int written_length;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
written_length = vsnprintf(&formatted_string->data, length, format, args);
|
||||
va_end(args);
|
||||
|
||||
formatted_string->length = written_length;
|
||||
|
||||
create_error(c_file_name, c_file_line, type, formatted_string);
|
||||
}
|
||||
|
||||
proc assert_type(Lisp_Object* node, Lisp_Object_Type type) -> void {
|
||||
if (!node)
|
||||
create_error(Error_Type::Unknown_Error, nullptr);
|
||||
if (node->type == type) return;
|
||||
create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
|
||||
}
|
||||
// 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";
|
||||
// case Error_Type::Not_A_Function: return "Evaluation-error: Not a function";
|
||||
// case Error_Type::Not_Yet_Implemented: return "Evaluation-error: Not yet implemented";
|
||||
// case Error_Type::Symbol_Not_Defined: return "Evaluation-error: Symbol not defined";
|
||||
// case Error_Type::Syntax_Error: return "Syntax Error";
|
||||
// case Error_Type::Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression";
|
||||
// case Error_Type::Type_Missmatch: return "Evaluation-error: Type Missmatch";
|
||||
// case Error_Type::Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis";
|
||||
// case Error_Type::Unexpected_Eof: return "Parsing-error: Unexpected EOF";
|
||||
// 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 "this error type doesn't have a desciption..";
|
||||
// }
|
||||
// }
|
||||
|
||||
// proc assert_type(Lisp_Object* node, Lisp_Object_Type type) -> void {
|
||||
// if (!node) {
|
||||
// create_generic_error(
|
||||
// "The node where the type should have"
|
||||
// "been checked was nullptr.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (node->type != type)
|
||||
// create_type_missmatch_error(
|
||||
// ""
|
||||
// );
|
||||
// }
|
||||
|
||||
+48
-28
@@ -5,18 +5,17 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
|
||||
// positional arguments
|
||||
for (int i = 0; i < function->positional_arguments->next_index; ++i) {
|
||||
if (arguments->type == Lisp_Object_Type::Pair) {
|
||||
// TODO(Felix): here we create new lisp_object_symbols from
|
||||
// their identifiers but before we converted them to
|
||||
// strings from symbols... Wo maybe just use the symbols?
|
||||
define_symbol(
|
||||
Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]),
|
||||
arguments->value.pair.first, new_env);
|
||||
} else {
|
||||
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
||||
create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i);
|
||||
return nullptr;
|
||||
}
|
||||
// TODO(Felix): here we create new lisp_object_symbols from
|
||||
// their identifiers but before we converted them to
|
||||
// strings from symbols... Wo maybe just use the symbols?
|
||||
define_symbol(
|
||||
Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]),
|
||||
arguments->value.pair.first, new_env);
|
||||
|
||||
arguments = arguments->value.pair.rest;
|
||||
}
|
||||
|
||||
@@ -46,8 +45,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
// necessary keywords then we have to count the rest
|
||||
// as :rest here, instead od always creating an error
|
||||
// (special case with default variables)
|
||||
puts("??");
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
create_generic_error(
|
||||
"The function does not take the keyword argument ':%s'",
|
||||
&(arguments->value.pair.first->value.identifier));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
// necessary keywords then we have to count the rest
|
||||
// as :rest here, instead od always creating an error
|
||||
// (special case with default variables)
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
create_generic_error(
|
||||
"The function already read the keyword argument ':%s'",
|
||||
&(arguments->value.pair.first->value.identifier));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +72,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
// not already read in, is there a next element to actually
|
||||
// set it to?
|
||||
if (arguments->value.pair.rest->type != Lisp_Object_Type::Pair) {
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
create_generic_error(
|
||||
"Attempting to set the keyword argument ':%s', but no value was supplied.",
|
||||
&(arguments->value.pair.first->value.identifier));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -107,7 +111,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
if (function->keyword_arguments->values->data[i] == nullptr) {
|
||||
// if this one does not have a default value
|
||||
if (!was_set) {
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
create_generic_error(
|
||||
"There was no value supplied for the required "
|
||||
"keyword argument ':%s'.",
|
||||
&defined_keyword->data);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
@@ -135,7 +142,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
arguments, new_env);
|
||||
} else {
|
||||
// rest was not declared but additional arguments were found
|
||||
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
create_generic_error(
|
||||
"A rest argument was not declared "
|
||||
"but the function was called with additional arguments.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -180,13 +189,17 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||
string_equal(arguments->value.pair.first->value.identifier, "rest"))
|
||||
break;
|
||||
else {
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error("A non recognized marker was found "
|
||||
"in the lambda list: ':%s'",
|
||||
&arguments->value.pair.first->value.identifier);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error("Only symbols and keywords can be "
|
||||
"parsed here, but found '%s'",
|
||||
Lisp_Object_Type_to_string(arguments->value.pair.first->type));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,7 +215,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||
// keywords,
|
||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
||||
if (arguments->type != Lisp_Object_Type::Nil)
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error("The lambda list must be nil terminated.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,25 +223,32 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||
string_equal(arguments->value.pair.first->value.identifier, "keys"))
|
||||
{
|
||||
arguments = arguments->value.pair.rest;
|
||||
if (arguments->type != Lisp_Object_Type::Pair ||
|
||||
arguments->value.pair.first->type != Lisp_Object_Type::Symbol)
|
||||
{
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
||||
create_parsing_error("Actual keys have to follow the :keys indicator.");
|
||||
}
|
||||
// if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||
// create_parsing_error(
|
||||
// "Only symbols can be parsed here, but found '%s'.",
|
||||
// Lisp_Object_Type_to_string(arguments->value.pair.first->type));
|
||||
// return;
|
||||
// }
|
||||
|
||||
while (arguments->type == Lisp_Object_Type::Pair) {
|
||||
if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) {
|
||||
if (string_equal(arguments->value.pair.first->value.identifier, "rest"))
|
||||
break;
|
||||
else {
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error(
|
||||
"Only the :rest keyword can be parsed here, but got ':%s'.",
|
||||
&arguments->value.pair.first->value.identifier->data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error(
|
||||
"Only symbols can be parsed here, but found '%s'.",
|
||||
Lisp_Object_Type_to_string(arguments->value.pair.first->type));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,7 +270,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||
next->value.pair.first);
|
||||
arguments = next->value.pair.rest;
|
||||
} else {
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error("Expecting a value after 'defaults-to'");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -268,7 +288,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||
// if there is a rest argument
|
||||
if (arguments->type != Lisp_Object_Type::Pair) {
|
||||
if (arguments->type != Lisp_Object_Type::Nil)
|
||||
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
create_parsing_error("The lambda list must be nil terminated.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
proc assert_type(Lisp_Object*, Lisp_Object_Type) -> void;
|
||||
// proc assert_type(Lisp_Object*, Lisp_Object_Type) -> void;
|
||||
proc built_in_load(String*, Environment*) -> Lisp_Object*;
|
||||
proc create_error(Error_Type, Source_Code_Location*) -> void;
|
||||
proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void;
|
||||
proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, const char* format, ...) -> void;
|
||||
proc create_error(Lisp_Object* type, const char* message, const char* c_file_name, int c_file_line) -> void;
|
||||
proc eval_arguments(Lisp_Object*, Environment*, int*) -> Lisp_Object*;
|
||||
proc eval_expr(Lisp_Object*, Environment*) -> Lisp_Object*;
|
||||
proc is_truthy (Lisp_Object*, Environment*) -> bool;
|
||||
@@ -8,3 +10,8 @@ proc list_length(Lisp_Object*) -> int;
|
||||
proc load_built_ins_into_environment(Environment*) -> void;
|
||||
proc parse_argument_list(Lisp_Object*, Function*) -> void;
|
||||
proc print_environment(Environment*) -> void;
|
||||
|
||||
proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*;
|
||||
namespace Memory {
|
||||
proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*;
|
||||
}
|
||||
|
||||
+9
-9
@@ -281,19 +281,19 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) ->
|
||||
|
||||
|
||||
proc print_error_location() -> void {
|
||||
if (error->location) {
|
||||
printf("%s (line %d, position %d)",
|
||||
Memory::get_c_str(error->location->file),
|
||||
error->location->line,
|
||||
error->location->column);
|
||||
} else {
|
||||
printf("no source code location avaliable");
|
||||
}
|
||||
// if (error->location) {
|
||||
// printf("%s (line %d, position %d)",
|
||||
// Memory::get_c_str(error->location->file),
|
||||
// error->location->line,
|
||||
// error->location->column);
|
||||
// } else {
|
||||
// printf("no source code location avaliable");
|
||||
// }
|
||||
}
|
||||
|
||||
proc log_error() -> void {
|
||||
printf("%s%s%s\n", console_red,
|
||||
Error_Type_to_string(error->type),
|
||||
Memory::get_c_str(error->message),
|
||||
console_normal);
|
||||
printf(" in: %s", console_cyan);
|
||||
print_error_location();
|
||||
|
||||
+28
-2
@@ -3,7 +3,7 @@ namespace Memory {
|
||||
// ------------------
|
||||
// lisp_object
|
||||
// ------------------
|
||||
int object_memory_size;
|
||||
int object_memory_size;
|
||||
Int_Array_List* free_spots_in_object_memory;
|
||||
Lisp_Object* object_memory;
|
||||
int next_index_in_object_memory = 0;
|
||||
@@ -82,13 +82,33 @@ namespace Memory {
|
||||
return create_string(str, (int)strlen(str));
|
||||
}
|
||||
|
||||
// proc create_string_formatted (const char* format, ...) -> String* {
|
||||
// // HACK(Felix): the length of all strings is 200!!!!!!!!!!
|
||||
// // HACK(Felix): the length of all strings is 200!!!!!!!!!!
|
||||
// int length = 200;
|
||||
// String* ret = create_string("", length);
|
||||
|
||||
// int written_length;
|
||||
// va_list args;
|
||||
// va_start(args, format);
|
||||
// written_length = vsnprintf(&ret->data, length, format, args);
|
||||
// va_end(args);
|
||||
|
||||
// ret->length = written_length;
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
proc create_lisp_object() -> Lisp_Object* {
|
||||
int index;
|
||||
// if we have no free spots then append at the end
|
||||
if (free_spots_in_object_memory->next_index == 0) {
|
||||
// if we still have space
|
||||
if (object_memory_size == next_index_in_object_memory) {
|
||||
create_error(Error_Type::Out_Of_Memory, nullptr);
|
||||
create_out_of_memory_error(
|
||||
"There is not enough space in the lisp object"
|
||||
"memory to allocate additional lisp objects. "
|
||||
"Maybe try increasing the Memory size when "
|
||||
"calling Memory::init()");
|
||||
return nullptr;
|
||||
}
|
||||
index = next_index_in_object_memory++;
|
||||
@@ -162,6 +182,9 @@ namespace Memory {
|
||||
}
|
||||
|
||||
proc get_or_create_lisp_object_symbol(const char* identifier) -> Lisp_Object* {
|
||||
// TODO(Felix): This is really bad: we create a new string
|
||||
// even if the symbol/keyword is already existing, just to
|
||||
// check IF it exists and then never deleting it.
|
||||
return get_or_create_lisp_object_symbol(
|
||||
Memory::create_string(identifier));
|
||||
}
|
||||
@@ -177,6 +200,9 @@ namespace Memory {
|
||||
}
|
||||
|
||||
proc get_or_create_lisp_object_keyword(const char* keyword) -> Lisp_Object* {
|
||||
// TODO(Felix): This is really bad: we create a new string
|
||||
// even if the symbol/keyword is already existing, just to
|
||||
// check IF it exists and then never deleting it.
|
||||
return get_or_create_lisp_object_keyword(
|
||||
Memory::create_string(keyword));
|
||||
}
|
||||
|
||||
+20
-15
@@ -166,15 +166,15 @@ namespace Parser {
|
||||
// we found the end of the string
|
||||
text[*index_in_text+string_length] = '\0';
|
||||
|
||||
String* string = Memory::create_string("", string_length);
|
||||
|
||||
if (!unescape_string(text+(*index_in_text))) {
|
||||
create_error(
|
||||
Error_Type::Unknown_Error,
|
||||
create_source_code_location(parser_file, parser_line, parser_col));
|
||||
create_parsing_error(
|
||||
"The string '%s' at %s:%d:%d could not be unescaped.",
|
||||
text+(*index_in_text), parser_file, parser_line, parser_col);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
String* string = Memory::create_string("", string_length);
|
||||
|
||||
// TODO(Felix): manually copy to parse control sequences
|
||||
// correctly without the need to unescape the string, also
|
||||
// better for keeping track of the encountered new lines and
|
||||
@@ -314,7 +314,9 @@ namespace Parser {
|
||||
|
||||
eat_until_code(text, index_in_text);
|
||||
if (text[(*index_in_text)] == '\0') {
|
||||
create_error(Error_Type::Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col));
|
||||
create_parsing_error(
|
||||
"Unexpected EOF in %s:%d:%d",
|
||||
parser_file, parser_line, parser_col);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -337,7 +339,9 @@ namespace Parser {
|
||||
eat_until_code(text, index_in_text);
|
||||
|
||||
if (text[(*index_in_text)] != ')')
|
||||
create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||
create_parsing_error(
|
||||
"Expected ')' after the element after the '.' in %s:%d:%d",
|
||||
create_source_code_location(parser_file, parser_line, parser_col));
|
||||
++parser_col;
|
||||
++(*index_in_text);
|
||||
break;
|
||||
@@ -362,14 +366,11 @@ namespace Parser {
|
||||
|
||||
// (define-syntax defun (name args :rest body) (...))
|
||||
if (arguments_length < 2) {
|
||||
create_error(Error_Type::Wrong_Number_Of_Arguments, expression->sourceCodeLocation);
|
||||
create_wrong_number_of_arguments_error(3, arguments_length);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||
create_error(Error_Type::Type_Missmatch, expression->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
assert_type(arguments->value.pair.first, Lisp_Object_Type::Symbol);
|
||||
|
||||
// extract the name
|
||||
Lisp_Object* symbol_for_macro = arguments->value.pair.first;
|
||||
@@ -429,7 +430,8 @@ namespace Parser {
|
||||
// that, when an entry is not found immidiately, we
|
||||
// know for sure that it does not exist in the table.
|
||||
|
||||
create_error(Error_Type::Not_Yet_Implemented, expression->sourceCodeLocation);
|
||||
create_generic_error("deleting macros has not yet be implemented,"
|
||||
"and I don't know if it is a good idea to do so.");
|
||||
return nullptr;
|
||||
} else {
|
||||
// if threre is a macro named like this, then macroexpand
|
||||
@@ -478,7 +480,9 @@ namespace Parser {
|
||||
eat_until_code(text, &index_in_text);
|
||||
if (text[(index_in_text)] == '\0')
|
||||
return result;
|
||||
create_error(Error_Type::Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col));
|
||||
|
||||
create_parsing_error("Trainling garbage after expression at %s:%d:%d",
|
||||
parser_file, parser_line, parser_col);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -573,7 +577,8 @@ namespace Parser {
|
||||
} break;
|
||||
default:
|
||||
/* syntax error */
|
||||
create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||
create_parsing_error("Garbage in file scope at %s:%d:%d",
|
||||
parser_file, parser_line, parser_col);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -6,11 +6,13 @@
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <ctype.h>
|
||||
// #include <type_traits>
|
||||
#include <stdarg.h>
|
||||
#include <functional>
|
||||
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
namespace Slime {
|
||||
// namespace Slime {
|
||||
#include "./defines.cpp"
|
||||
#include "./structs.cpp"
|
||||
#include "./forward_decls.cpp"
|
||||
@@ -24,7 +26,4 @@ namespace Slime {
|
||||
#include "./built_ins.cpp"
|
||||
#include "./testing.cpp"
|
||||
#include "./undefines.cpp"
|
||||
}
|
||||
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_WARNINGS
|
||||
// }
|
||||
|
||||
+25
-22
@@ -26,25 +26,25 @@ enum struct Function_Type {
|
||||
Macro
|
||||
};
|
||||
|
||||
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,
|
||||
Type_Missmatch,
|
||||
Unbalanced_Parenthesis,
|
||||
Unexpected_Eof,
|
||||
Unknown_Error,
|
||||
Unknown_Keyword_Argument,
|
||||
Wrong_Number_Of_Arguments,
|
||||
};
|
||||
// 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,
|
||||
// Type_Missmatch,
|
||||
// Unbalanced_Parenthesis,
|
||||
// Unexpected_Eof,
|
||||
// Unknown_Error,
|
||||
// Unknown_Keyword_Argument,
|
||||
// Wrong_Number_Of_Arguments,
|
||||
// };
|
||||
|
||||
enum struct Log_Level {
|
||||
None,
|
||||
@@ -141,12 +141,15 @@ struct Environment {
|
||||
|
||||
int capacity;
|
||||
int next_index;
|
||||
|
||||
// TODO(Felix): Use a hashmap here.
|
||||
char** keys;
|
||||
char** keys;
|
||||
Lisp_Object** values;
|
||||
};
|
||||
|
||||
struct Error {
|
||||
Error_Type type;
|
||||
Source_Code_Location* location;
|
||||
Lisp_Object* position;
|
||||
// type has to be a keyword
|
||||
Lisp_Object* type;
|
||||
String* message;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user