first step to better errors, but broeken af
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
void assert_type (Ast_Node* node, Ast_Node_Type type) {
|
||||
if (!node)
|
||||
create_error(Error_Type_Unknown_Error, node);
|
||||
create_error(Error_Type_Unknown_Error, nullptr);
|
||||
if (node->type == type) return;
|
||||
create_error(Error_Type_Type_Missmatch, node);
|
||||
create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation);
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ typedef struct {
|
||||
} Built_In_Function;
|
||||
|
||||
struct Ast_Node {
|
||||
Source_Code_Location* sourceCodeLocation;
|
||||
Ast_Node_Type type;
|
||||
union {
|
||||
Symbol* symbol;
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
||||
n1->value.number->value ==
|
||||
n2->value.number->value;
|
||||
case Ast_Node_Type_Pair:
|
||||
create_error(Error_Type_Not_Yet_Implemented, n1);
|
||||
create_error(Error_Type_Not_Yet_Implemented, n1->sourceCodeLocation);
|
||||
return false;
|
||||
case Ast_Node_Type_String:
|
||||
return string_equal(
|
||||
@@ -203,7 +203,7 @@ Ast_Node* built_in_load(char* file_name, Environment* env) {
|
||||
Ast_Node* result = create_ast_node_nil();
|
||||
Ast_Node_Array_List* program;
|
||||
try {
|
||||
program = parse_program(file_content);
|
||||
program = parse_program(file_name, file_content);
|
||||
}
|
||||
for (int i = 0; i < program->next_index; ++i) {
|
||||
try {
|
||||
@@ -212,7 +212,7 @@ Ast_Node* built_in_load(char* file_name, Environment* env) {
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
|
||||
create_error(Error_Type_Unknown_Error, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
||||
|
||||
void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
||||
if (env->type != Environment_Type_Macro) {
|
||||
create_error(Error_Type_Unknown_Error, symbol);
|
||||
create_error(Error_Type_Unknown_Error, symbol->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,8 +118,9 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
||||
Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
|
||||
// first check current environment
|
||||
Symbol* sym = node->value.symbol;
|
||||
Ast_Node* result;
|
||||
result = lookup_symbol_in_this_envt(sym, env);
|
||||
if (result)
|
||||
@@ -147,7 +148,7 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
|
||||
create_error(Error_Type_Symbol_Not_Defined, node->sourceCodeLocation);
|
||||
/* printf("%s\n", sym->identifier); */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
Error_Type type;
|
||||
Ast_Node* location;
|
||||
Source_Code_Location* location;
|
||||
} Error;
|
||||
|
||||
Error* error;
|
||||
@@ -29,7 +29,7 @@ void delete_error() {
|
||||
}
|
||||
}
|
||||
|
||||
void create_error(Error_Type type, Ast_Node* location) {
|
||||
void create_error(Error_Type type, Source_Code_Location* location) {
|
||||
delete_error();
|
||||
|
||||
error = new(Error);
|
||||
|
||||
+22
-22
@@ -19,7 +19,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
arguments->value.pair->first, new_env);
|
||||
} else {
|
||||
// not enough arguments given
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
arguments = arguments->value.pair->rest;
|
||||
@@ -47,7 +47,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
}
|
||||
}
|
||||
if (!accepted) {
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
// 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);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
// not already read in, is there a next element to actually
|
||||
// set it to?
|
||||
if (arguments->value.pair->rest->type != Ast_Node_Type_Pair) {
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
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);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
@@ -135,7 +135,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
||||
arguments, new_env);
|
||||
} else {
|
||||
// rest was not declared but additional arguments were found
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -186,13 +186,13 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
|
||||
break;
|
||||
else {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
// keywords,
|
||||
if (arguments->type != Ast_Node_Type_Pair) {
|
||||
if (arguments->type != Ast_Node_Type_Nil)
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
if (arguments->type != Ast_Node_Type_Pair ||
|
||||
arguments->value.pair->first->type != Ast_Node_Type_Symbol)
|
||||
{
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,13 +228,13 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
|
||||
break;
|
||||
else {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
next->value.pair->first);
|
||||
arguments = next->value.pair->rest;
|
||||
} else {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -274,7 +274,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
// if there is a rest argument
|
||||
if (arguments->type != Ast_Node_Type_Pair) {
|
||||
if (arguments->type != Ast_Node_Type_Nil)
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -285,16 +285,16 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
||||
if (arguments->type != Ast_Node_Type_Pair ||
|
||||
arguments->value.pair->first->type != Ast_Node_Type_Symbol)
|
||||
{
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
return;
|
||||
}
|
||||
function->rest_argument = arguments->value.pair->first->value.symbol->identifier;
|
||||
if (arguments->value.pair->rest->type != Ast_Node_Type_Nil) {
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||
}
|
||||
} else {
|
||||
printf("this should not happen?");
|
||||
create_error(Error_Type_Unknown_Error, arguments);
|
||||
create_error(Error_Type_Unknown_Error, arguments->sourceCodeLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ int list_length(Ast_Node* node) {
|
||||
return 0;
|
||||
|
||||
if (node->type != Ast_Node_Type_Pair) {
|
||||
create_error(Error_Type_Type_Missmatch, node);
|
||||
create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ int list_length(Ast_Node* node) {
|
||||
return len;
|
||||
}
|
||||
|
||||
create_error(Error_Type_Ill_Formed_List, node);
|
||||
create_error(Error_Type_Ill_Formed_List, node->sourceCodeLocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen
|
||||
} else if (current_head->type == Ast_Node_Type_Nil) {
|
||||
evaluated_arguments_head->value.pair->rest = current_head;
|
||||
} else {
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
++(*out_arguments_length);
|
||||
@@ -363,7 +363,7 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen
|
||||
|
||||
Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
#define report_error(_type) { \
|
||||
create_error(_type, node); \
|
||||
create_error(_type, node->sourceCodeLocation); \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
case Ast_Node_Type_Symbol: {
|
||||
Ast_Node* symbol;
|
||||
try {
|
||||
symbol = lookup_symbol(node->value.symbol, env);
|
||||
symbol = lookup_symbol(node, env);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
|
||||
#define try_void \
|
||||
if (1) \
|
||||
goto label(body,__LINE__); \
|
||||
else \
|
||||
while (1) \
|
||||
if (1) { \
|
||||
if(error) return; \
|
||||
break; \
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
|
||||
|
||||
#define define_array_list(type, name) \
|
||||
typedef struct { \
|
||||
type* data; \
|
||||
@@ -210,3 +222,19 @@ char* read_line() {
|
||||
*line = '\0';
|
||||
return linep;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
char* file;
|
||||
int line;
|
||||
} Source_Code_Location;
|
||||
|
||||
Source_Code_Location* create_source_code_location(char* file, int line) {
|
||||
if (!file)
|
||||
return nullptr;
|
||||
|
||||
Source_Code_Location* ret = new(Source_Code_Location);
|
||||
ret->file = file;
|
||||
ret->line = line;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -96,12 +96,19 @@ void print(Ast_Node* node) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_error_location() {
|
||||
if (error->location) {
|
||||
printf("%s: %d", error->location->file, error->location->line);
|
||||
} else {
|
||||
printf("no source code location avaliable");
|
||||
}
|
||||
}
|
||||
|
||||
void log_error() {
|
||||
printf("%s%s%s\n", console_red,
|
||||
Error_Type_to_string(error->type),
|
||||
console_normal);
|
||||
printf(" in: %s", console_cyan);
|
||||
print(error->location);
|
||||
print_error_location(error->location);
|
||||
printf("%s\n", console_normal);
|
||||
}
|
||||
|
||||
+15
-18
@@ -18,30 +18,29 @@
|
||||
#include "./testing.c"
|
||||
#include "./init.c"
|
||||
|
||||
int interprete_file (char* file_content) {
|
||||
Ast_Node_Array_List* program = parse_program(file_content);
|
||||
if (error) {
|
||||
log_error();
|
||||
return 1;
|
||||
void interprete_file (char* file_name) {
|
||||
char* file_content = read_entire_file(file_name);
|
||||
if (!file_content) {
|
||||
create_error(Error_Type_Unknown_Error, nullptr);
|
||||
}
|
||||
|
||||
Ast_Node_Array_List* program;
|
||||
try_void {
|
||||
parse_program(file_name, file_content);
|
||||
}
|
||||
|
||||
Environment* env = create_empty_environment(Environment_Type_Let);
|
||||
|
||||
try_void {
|
||||
built_in_load("pre.slime", env);
|
||||
if (error) {
|
||||
log_error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
Ast_Node* result = create_ast_node_nil();
|
||||
for (int i = 0; i < program->next_index; ++i) {
|
||||
try_void {
|
||||
result = eval_expr(program->data[i], env);
|
||||
if (error) {
|
||||
log_error();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int interprete_stdin () {
|
||||
@@ -81,11 +80,9 @@ int main (int argc, char *argv[]) {
|
||||
init();
|
||||
|
||||
if (argc > 1) {
|
||||
char* file_content = read_entire_file(argv[1]);
|
||||
if (file_content) {
|
||||
return interprete_file(file_content);
|
||||
} else {
|
||||
printf("The file could not be read\n");
|
||||
interprete_file(argv[1]);
|
||||
if (error) {
|
||||
log_error();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
+21
-6
@@ -1,3 +1,7 @@
|
||||
char* parser_file;
|
||||
int parser_line;
|
||||
|
||||
// TODO(Felix): use the array list macro here?
|
||||
Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length) {
|
||||
Ast_Node_Array_List* ret = new (Ast_Node_Array_List);
|
||||
|
||||
@@ -29,6 +33,10 @@ void eat_comment_line(char* text, int* index_in_text) {
|
||||
} while (text[(*index_in_text)] != '\n' &&
|
||||
text[(*index_in_text)] != '\r' &&
|
||||
text[(*index_in_text)] != '\0');
|
||||
|
||||
if (text[(*index_in_text)] == '\n') {
|
||||
++parser_line;
|
||||
}
|
||||
}
|
||||
|
||||
void eat_whitespace(char* text, int* index_in_text) {
|
||||
@@ -39,6 +47,9 @@ void eat_whitespace(char* text, int* index_in_text) {
|
||||
text[(*index_in_text)] == '\r') {
|
||||
++(*index_in_text);
|
||||
}
|
||||
if (text[(*index_in_text)] == '\n') {
|
||||
++parser_line;
|
||||
}
|
||||
}
|
||||
|
||||
void eat_until_code(char* text, int* index_in_text) {
|
||||
@@ -130,7 +141,9 @@ Ast_Node* parse_string(char* text, int* index_in_text) {
|
||||
char* string = (char*)malloc(string_length*sizeof(char)+1); // plus null char
|
||||
|
||||
if (!unescape_string(text+(*index_in_text))) {
|
||||
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
|
||||
create_error(
|
||||
Error_Type_Unknown_Error,
|
||||
create_source_code_location(parser_file, parser_line));
|
||||
return nullptr;
|
||||
}
|
||||
strcpy(string, text+(*index_in_text));
|
||||
@@ -223,7 +236,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
||||
|
||||
eat_until_code(text, index_in_text);
|
||||
if (text[(*index_in_text)] == '\0') {
|
||||
create_error(Error_Type_Unexpected_Eof, expression);
|
||||
create_error(Error_Type_Unexpected_Eof, create_source_code_location(parser_file, parser_line));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -244,7 +257,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
||||
eat_until_code(text, index_in_text);
|
||||
|
||||
if (text[(*index_in_text)] != ')')
|
||||
create_error(Error_Type_Syntax_Error, nullptr);
|
||||
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line));
|
||||
++(*index_in_text);
|
||||
break;
|
||||
} else {
|
||||
@@ -270,11 +283,13 @@ Ast_Node* parse_single_expression(char* text) {
|
||||
eat_until_code(text, &index_in_text);
|
||||
if (text[(index_in_text)] == '\0')
|
||||
return result;
|
||||
create_error(Error_Type_Trailing_Garbage, create_ast_node_nil());
|
||||
create_error(Error_Type_Trailing_Garbage, create_source_code_location(parser_file, parser_line));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ast_Node_Array_List* parse_program(char* text) {
|
||||
Ast_Node_Array_List* parse_program(char* file_name, char* text) {
|
||||
parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1);
|
||||
strcpy(parser_file, file_name);
|
||||
Ast_Node_Array_List* program = create_Ast_Node_Array_List(16);
|
||||
|
||||
int index_in_text = 0;
|
||||
@@ -297,7 +312,7 @@ Ast_Node_Array_List* parse_program(char* text) {
|
||||
} break;
|
||||
default:
|
||||
/* syntax error */
|
||||
create_error(Error_Type_Syntax_Error, create_ast_node_nil());
|
||||
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user