first step to better errors, but broeken af

This commit is contained in:
Felix Brendel
2018-11-20 14:24:13 +01:00
parent 3e8f883308
commit f8e9a8799e
10 changed files with 198 additions and 149 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
void assert_type (Ast_Node* node, Ast_Node_Type type) { void assert_type (Ast_Node* node, Ast_Node_Type type) {
if (!node) if (!node)
create_error(Error_Type_Unknown_Error, node); create_error(Error_Type_Unknown_Error, nullptr);
if (node->type == type) return; if (node->type == type) return;
create_error(Error_Type_Type_Missmatch, node); create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation);
} }
+1
View File
@@ -214,6 +214,7 @@ typedef struct {
} Built_In_Function; } Built_In_Function;
struct Ast_Node { struct Ast_Node {
Source_Code_Location* sourceCodeLocation;
Ast_Node_Type type; Ast_Node_Type type;
union { union {
Symbol* symbol; Symbol* symbol;
+91 -91
View File
@@ -2,40 +2,40 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env);
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
if (n1 == n2) if (n1 == n2)
return true; return true;
if (n1->type != n2->type) if (n1->type != n2->type)
return false; return false;
switch (n1->type) { switch (n1->type) {
case Ast_Node_Type_Built_In_Function: case Ast_Node_Type_Built_In_Function:
return n1->value.built_in_function->type return n1->value.built_in_function->type
== n2->value.built_in_function->type; == n2->value.built_in_function->type;
case Ast_Node_Type_Function: case Ast_Node_Type_Function:
// if they have the same pointer, true is // if they have the same pointer, true is
// returned a few lines above // returned a few lines above
return false; return false;
case Ast_Node_Type_Keyword: case Ast_Node_Type_Keyword:
return string_equal( return string_equal(
n1->value.keyword->identifier, n1->value.keyword->identifier,
n2->value.keyword->identifier); n2->value.keyword->identifier);
case Ast_Node_Type_T: case Ast_Node_Type_T:
case Ast_Node_Type_Nil: case Ast_Node_Type_Nil:
return true; return true;
case Ast_Node_Type_Number: case Ast_Node_Type_Number:
return return
n1->value.number->value == n1->value.number->value ==
n2->value.number->value; n2->value.number->value;
case Ast_Node_Type_Pair: case Ast_Node_Type_Pair:
create_error(Error_Type_Not_Yet_Implemented, n1); create_error(Error_Type_Not_Yet_Implemented, n1->sourceCodeLocation);
return false; return false;
case Ast_Node_Type_String: case Ast_Node_Type_String:
return string_equal( return string_equal(
n1->value.string->value, n1->value.string->value,
n2->value.string->value); n2->value.string->value);
case Ast_Node_Type_Symbol: case Ast_Node_Type_Symbol:
return string_equal( return string_equal(
n1->value.symbol->identifier, n1->value.symbol->identifier,
n2->value.symbol->identifier); n2->value.symbol->identifier);
} }
// we should never reach here // we should never reach here
@@ -44,32 +44,32 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
Ast_Node* built_in_equals(Ast_Node* operands) { Ast_Node* built_in_equals(Ast_Node* operands) {
if (operands->type == Ast_Node_Type_Nil) if (operands->type == Ast_Node_Type_Nil)
return create_ast_node_t(); return create_ast_node_t();
Ast_Node* first = operands->value.pair->first; Ast_Node* first = operands->value.pair->first;
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
if (!ast_node_equal(operands->value.pair->first, first)) if (!ast_node_equal(operands->value.pair->first, first))
return create_ast_node_nil(); return create_ast_node_nil();
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_t(); return create_ast_node_t();
} }
Ast_Node* built_in_greater(Ast_Node* operands) { Ast_Node* built_in_greater(Ast_Node* operands) {
double last_number = strtod("Inf", NULL); double last_number = strtod("Inf", NULL);
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
if (operands->value.pair->first->value.number->value >= last_number) if (operands->value.pair->first->value.number->value >= last_number)
return create_ast_node_nil(); return create_ast_node_nil();
last_number = operands->value.pair->first->value.number->value; last_number = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_t(); return create_ast_node_t();
@@ -79,15 +79,15 @@ Ast_Node* built_in_greater_equal(Ast_Node* operands) {
double last_number = strtod("Inf", NULL); double last_number = strtod("Inf", NULL);
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
if (operands->value.pair->first->value.number->value > last_number) if (operands->value.pair->first->value.number->value > last_number)
return create_ast_node_nil(); return create_ast_node_nil();
last_number = operands->value.pair->first->value.number->value; last_number = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_t(); return create_ast_node_t();
@@ -97,15 +97,15 @@ Ast_Node* built_in_less(Ast_Node* operands) {
double last_number = strtod("-Inf", NULL); double last_number = strtod("-Inf", NULL);
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
if (operands->value.pair->first->value.number->value <= last_number) if (operands->value.pair->first->value.number->value <= last_number)
return create_ast_node_nil(); return create_ast_node_nil();
last_number = operands->value.pair->first->value.number->value; last_number = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_t(); return create_ast_node_t();
@@ -115,15 +115,15 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) {
double last_number = strtod("-Inf", NULL); double last_number = strtod("-Inf", NULL);
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
if (operands->value.pair->first->value.number->value < last_number) if (operands->value.pair->first->value.number->value < last_number)
return create_ast_node_nil(); return create_ast_node_nil();
last_number = operands->value.pair->first->value.number->value; last_number = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_t(); return create_ast_node_t();
@@ -132,11 +132,11 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) {
Ast_Node* built_in_add(Ast_Node* operands) { Ast_Node* built_in_add(Ast_Node* operands) {
double sum = 0; double sum = 0;
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
sum += operands->value.pair->first->value.number->value; sum += operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_number(sum); return create_ast_node_number(sum);
@@ -144,54 +144,54 @@ Ast_Node* built_in_add(Ast_Node* operands) {
Ast_Node* built_in_substract(Ast_Node* operands) { Ast_Node* built_in_substract(Ast_Node* operands) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
double difference = operands->value.pair->first->value.number->value; double difference = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
difference -= operands->value.pair->first->value.number->value; difference -= operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_number(difference); return create_ast_node_number(difference);
} }
Ast_Node* built_in_multiply(Ast_Node* operands) { Ast_Node* built_in_multiply(Ast_Node* operands) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
double product = operands->value.pair->first->value.number->value; double product = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
product *= operands->value.pair->first->value.number->value; product *= operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_number(product); return create_ast_node_number(product);
} }
Ast_Node* built_in_divide(Ast_Node* operands) { Ast_Node* built_in_divide(Ast_Node* operands) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
double quotient = operands->value.pair->first->value.number->value; double quotient = operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
while (operands->type == Ast_Node_Type_Pair) { while (operands->type == Ast_Node_Type_Pair) {
try { try {
assert_type(operands->value.pair->first, Ast_Node_Type_Number); assert_type(operands->value.pair->first, Ast_Node_Type_Number);
} }
quotient /= operands->value.pair->first->value.number->value; quotient /= operands->value.pair->first->value.number->value;
operands = operands->value.pair->rest; operands = operands->value.pair->rest;
} }
return create_ast_node_number(quotient); return create_ast_node_number(quotient);
} }
@@ -200,19 +200,19 @@ Ast_Node* built_in_divide(Ast_Node* operands) {
Ast_Node* built_in_load(char* file_name, Environment* env) { Ast_Node* built_in_load(char* file_name, Environment* env) {
char* file_content = read_entire_file(file_name); char* file_content = read_entire_file(file_name);
if (file_content) { if (file_content) {
Ast_Node* result = create_ast_node_nil(); Ast_Node* result = create_ast_node_nil();
Ast_Node_Array_List* program; Ast_Node_Array_List* program;
try { try {
program = parse_program(file_content); program = parse_program(file_name, file_content);
} }
for (int i = 0; i < program->next_index; ++i) { for (int i = 0; i < program->next_index; ++i) {
try { try {
result = eval_expr(program->data[i], env); result = eval_expr(program->data[i], env);
} }
} }
return result; return result;
} else { } else {
create_error(Error_Type_Unknown_Error, create_ast_node_nil()); create_error(Error_Type_Unknown_Error, nullptr);
return nullptr; return nullptr;
} }
} }
+4 -3
View File
@@ -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) { void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->type != Environment_Type_Macro) { if (env->type != Environment_Type_Macro) {
create_error(Error_Type_Unknown_Error, symbol); create_error(Error_Type_Unknown_Error, symbol->sourceCodeLocation);
return; return;
} }
@@ -118,8 +118,9 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
return nullptr; return nullptr;
} }
Ast_Node* lookup_symbol(Symbol* sym, Environment* env) { Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
// first check current environment // first check current environment
Symbol* sym = node->value.symbol;
Ast_Node* result; Ast_Node* result;
result = lookup_symbol_in_this_envt(sym, env); result = lookup_symbol_in_this_envt(sym, env);
if (result) if (result)
@@ -147,7 +148,7 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
if (result) if (result)
return 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); */ /* printf("%s\n", sym->identifier); */
return nullptr; return nullptr;
} }
+2 -2
View File
@@ -17,7 +17,7 @@ typedef enum {
typedef struct { typedef struct {
Error_Type type; Error_Type type;
Ast_Node* location; Source_Code_Location* location;
} Error; } Error;
Error* 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(); delete_error();
error = new(Error); error = new(Error);
+24 -24
View File
@@ -19,7 +19,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
arguments->value.pair->first, new_env); arguments->value.pair->first, new_env);
} else { } else {
// not enough arguments given // not enough arguments given
create_error(Error_Type_Ill_Formed_Arguments, arguments); create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; return nullptr;
} }
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
@@ -47,7 +47,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
} }
} }
if (!accepted) { if (!accepted) {
create_error(Error_Type_Ill_Formed_Arguments, arguments); create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; 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 // necessary keywords then we have to count the rest
// as :rest here, instead od always creating an error // as :rest here, instead od always creating an error
// (special case with default variables) // (special case with default variables)
create_error(Error_Type_Ill_Formed_Arguments, arguments); create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; 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 // not already read in, is there a next element to actually
// set it to? // set it to?
if (arguments->value.pair->rest->type != Ast_Node_Type_Pair) { 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; 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 (function->keyword_arguments->values->data[i] == nullptr) {
// if this one does not have a default value // if this one does not have a default value
if (!was_set) { if (!was_set) {
create_error(Error_Type_Ill_Formed_Arguments, arguments); create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; return nullptr;
} }
} else { } else {
@@ -135,7 +135,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
arguments, new_env); arguments, new_env);
} else { } else {
// rest was not declared but additional arguments were found // 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; 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")) string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
break; break;
else { else {
create_error(Error_Type_Ill_Formed_Lambda_List, arguments); create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
} }
if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) { 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; return;
} }
@@ -208,7 +208,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
// keywords, // keywords,
if (arguments->type != Ast_Node_Type_Pair) { if (arguments->type != Ast_Node_Type_Pair) {
if (arguments->type != Ast_Node_Type_Nil) 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; return;
} }
@@ -219,7 +219,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
if (arguments->type != Ast_Node_Type_Pair || if (arguments->type != Ast_Node_Type_Pair ||
arguments->value.pair->first->type != Ast_Node_Type_Symbol) 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; 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")) if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
break; break;
else { else {
create_error(Error_Type_Ill_Formed_Lambda_List, arguments); create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
} }
if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) { 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; return;
} }
@@ -256,7 +256,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
next->value.pair->first); next->value.pair->first);
arguments = next->value.pair->rest; arguments = next->value.pair->rest;
} else { } else {
create_error(Error_Type_Ill_Formed_Lambda_List, arguments); create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
} else { } else {
@@ -274,7 +274,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
// if there is a rest argument // if there is a rest argument
if (arguments->type != Ast_Node_Type_Pair) { if (arguments->type != Ast_Node_Type_Pair) {
if (arguments->type != Ast_Node_Type_Nil) 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; return;
} }
@@ -285,16 +285,16 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
if (arguments->type != Ast_Node_Type_Pair || if (arguments->type != Ast_Node_Type_Pair ||
arguments->value.pair->first->type != Ast_Node_Type_Symbol) 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; return;
} }
function->rest_argument = arguments->value.pair->first->value.symbol->identifier; function->rest_argument = arguments->value.pair->first->value.symbol->identifier;
if (arguments->value.pair->rest->type != Ast_Node_Type_Nil) { 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 { } else {
printf("this should not happen?"); 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; return 0;
if (node->type != Ast_Node_Type_Pair) { if (node->type != Ast_Node_Type_Pair) {
create_error(Error_Type_Type_Missmatch, node); create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation);
return 0; return 0;
} }
@@ -316,7 +316,7 @@ int list_length(Ast_Node* node) {
return len; return len;
} }
create_error(Error_Type_Ill_Formed_List, node); create_error(Error_Type_Ill_Formed_List, node->sourceCodeLocation);
return 0; 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) { } else if (current_head->type == Ast_Node_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); create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; return nullptr;
} }
++(*out_arguments_length); ++(*out_arguments_length);
@@ -362,9 +362,9 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen
} }
Ast_Node* eval_expr(Ast_Node* node, Environment* env) { Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
#define report_error(_type) { \ #define report_error(_type) { \
create_error(_type, node); \ create_error(_type, node->sourceCodeLocation); \
return nullptr; \ return nullptr; \
} }
if (error) if (error)
@@ -378,7 +378,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
case Ast_Node_Type_Symbol: { case Ast_Node_Type_Symbol: {
Ast_Node* symbol; Ast_Node* symbol;
try { try {
symbol = lookup_symbol(node->value.symbol, env); symbol = lookup_symbol(node, env);
} }
return symbol; return symbol;
} }
+28
View File
@@ -14,6 +14,18 @@
} \ } \
else label(body,__LINE__): 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) \ #define define_array_list(type, name) \
typedef struct { \ typedef struct { \
type* data; \ type* data; \
@@ -210,3 +222,19 @@ char* read_line() {
*line = '\0'; *line = '\0';
return linep; 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;
}
+8 -1
View File
@@ -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() { void log_error() {
printf("%s%s%s\n", console_red, printf("%s%s%s\n", console_red,
Error_Type_to_string(error->type), Error_Type_to_string(error->type),
console_normal); console_normal);
printf(" in: %s", console_cyan); printf(" in: %s", console_cyan);
print(error->location); print_error_location(error->location);
printf("%s\n", console_normal); printf("%s\n", console_normal);
} }
+17 -20
View File
@@ -18,30 +18,29 @@
#include "./testing.c" #include "./testing.c"
#include "./init.c" #include "./init.c"
int interprete_file (char* file_content) { void interprete_file (char* file_name) {
Ast_Node_Array_List* program = parse_program(file_content); char* file_content = read_entire_file(file_name);
if (error) { if (!file_content) {
log_error(); create_error(Error_Type_Unknown_Error, nullptr);
return 1;
} }
Ast_Node_Array_List* program;
try_void {
parse_program(file_name, file_content);
}
Environment* env = create_empty_environment(Environment_Type_Let); Environment* env = create_empty_environment(Environment_Type_Let);
built_in_load("pre.slime", env); try_void {
if (error) { built_in_load("pre.slime", env);
log_error();
return 1;
} }
Ast_Node* result = create_ast_node_nil(); Ast_Node* result = create_ast_node_nil();
for (int i = 0; i < program->next_index; ++i) { for (int i = 0; i < program->next_index; ++i) {
result = eval_expr(program->data[i], env); try_void {
if (error) { result = eval_expr(program->data[i], env);
log_error();
return 1;
} }
} }
return 0;
} }
int interprete_stdin () { int interprete_stdin () {
@@ -81,11 +80,9 @@ int main (int argc, char *argv[]) {
init(); init();
if (argc > 1) { if (argc > 1) {
char* file_content = read_entire_file(argv[1]); interprete_file(argv[1]);
if (file_content) { if (error) {
return interprete_file(file_content); log_error();
} else {
printf("The file could not be read\n");
return 1; return 1;
} }
} else { } else {
+21 -6
View File
@@ -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* create_Ast_Node_Array_List(int initial_length) {
Ast_Node_Array_List* ret = new (Ast_Node_Array_List); 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' && } while (text[(*index_in_text)] != '\n' &&
text[(*index_in_text)] != '\r' && text[(*index_in_text)] != '\r' &&
text[(*index_in_text)] != '\0'); text[(*index_in_text)] != '\0');
if (text[(*index_in_text)] == '\n') {
++parser_line;
}
} }
void eat_whitespace(char* text, int* index_in_text) { 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') { text[(*index_in_text)] == '\r') {
++(*index_in_text); ++(*index_in_text);
} }
if (text[(*index_in_text)] == '\n') {
++parser_line;
}
} }
void eat_until_code(char* text, int* index_in_text) { 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 char* string = (char*)malloc(string_length*sizeof(char)+1); // plus null char
if (!unescape_string(text+(*index_in_text))) { 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; return nullptr;
} }
strcpy(string, text+(*index_in_text)); 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); eat_until_code(text, index_in_text);
if (text[(*index_in_text)] == '\0') { 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; return nullptr;
} }
@@ -244,7 +257,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
eat_until_code(text, index_in_text); eat_until_code(text, index_in_text);
if (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); ++(*index_in_text);
break; break;
} else { } else {
@@ -270,11 +283,13 @@ Ast_Node* parse_single_expression(char* text) {
eat_until_code(text, &index_in_text); eat_until_code(text, &index_in_text);
if (text[(index_in_text)] == '\0') if (text[(index_in_text)] == '\0')
return result; 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; 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); Ast_Node_Array_List* program = create_Ast_Node_Array_List(16);
int index_in_text = 0; int index_in_text = 0;
@@ -297,7 +312,7 @@ Ast_Node_Array_List* parse_program(char* text) {
} break; } break;
default: default:
/* syntax error */ /* 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; return nullptr;
} }
} }