Error locations are somewhat working now
This commit is contained in:
+3
-1
@@ -12,4 +12,6 @@
|
|||||||
(defun ! (n)
|
(defun ! (n)
|
||||||
(if (< n 2)
|
(if (< n 2)
|
||||||
1
|
1
|
||||||
(* n (! (- 1 n)))))
|
(* n (! (- n 1)))))
|
||||||
|
|
||||||
|
(erros "alskdj")
|
||||||
@@ -237,22 +237,28 @@ typedef struct {
|
|||||||
Ast_Node_Array_List* keyword_values;
|
Ast_Node_Array_List* keyword_values;
|
||||||
} Parsed_Arguments;
|
} Parsed_Arguments;
|
||||||
|
|
||||||
Ast_Node* create_ast_node_nil() {
|
Ast_Node* create_ast_node() {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = new(Ast_Node);
|
||||||
|
node->sourceCodeLocation = nullptr;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_Node* create_ast_node_nil() {
|
||||||
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Nil;
|
node->type = Ast_Node_Type_Nil;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_t() {
|
Ast_Node* create_ast_node_t() {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_T;
|
node->type = Ast_Node_Type_T;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_number(double number) {
|
Ast_Node* create_ast_node_number(double number) {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Number;
|
node->type = Ast_Node_Type_Number;
|
||||||
node->value.number = new(Number);
|
node->value.number = new(Number);
|
||||||
node->value.number->value = number;
|
node->value.number->value = number;
|
||||||
@@ -260,7 +266,7 @@ Ast_Node* create_ast_node_number(double number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_string(char* str, int length) {
|
Ast_Node* create_ast_node_string(char* str, int length) {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_String;
|
node->type = Ast_Node_Type_String;
|
||||||
node->value.string = new(String);
|
node->value.string = new(String);
|
||||||
node->value.string->value = str;
|
node->value.string->value = str;
|
||||||
@@ -269,7 +275,7 @@ Ast_Node* create_ast_node_string(char* str, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_symbol(char* identifier) {
|
Ast_Node* create_ast_node_symbol(char* identifier) {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Symbol;
|
node->type = Ast_Node_Type_Symbol;
|
||||||
node->value.symbol = new(Symbol);
|
node->value.symbol = new(Symbol);
|
||||||
node->value.symbol->identifier = identifier;
|
node->value.symbol->identifier = identifier;
|
||||||
@@ -277,7 +283,7 @@ Ast_Node* create_ast_node_symbol(char* identifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_keyword(char* keyword) {
|
Ast_Node* create_ast_node_keyword(char* keyword) {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Keyword;
|
node->type = Ast_Node_Type_Keyword;
|
||||||
node->value.keyword = new(Keyword);
|
node->value.keyword = new(Keyword);
|
||||||
node->value.keyword->identifier = keyword;
|
node->value.keyword->identifier = keyword;
|
||||||
@@ -326,7 +332,7 @@ Ast_Node* create_ast_node_built_in_function(char* name) {
|
|||||||
else if (string_equal(name, "while")) type = Built_In_While;
|
else if (string_equal(name, "while")) type = Built_In_While;
|
||||||
else return nullptr;
|
else return nullptr;
|
||||||
|
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Built_In_Function;
|
node->type = Ast_Node_Type_Built_In_Function;
|
||||||
node->value.built_in_function = new(Built_In_Function);
|
node->value.built_in_function = new(Built_In_Function);
|
||||||
node->value.built_in_function->type = type;
|
node->value.built_in_function->type = type;
|
||||||
@@ -334,7 +340,7 @@ Ast_Node* create_ast_node_built_in_function(char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
|
Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Pair;
|
node->type = Ast_Node_Type_Pair;
|
||||||
node->value.pair = new(Pair);
|
node->value.pair = new(Pair);
|
||||||
node->value.pair->first = first;
|
node->value.pair->first = first;
|
||||||
@@ -343,7 +349,7 @@ Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* copy_ast_node(Ast_Node* n) {
|
Ast_Node* copy_ast_node(Ast_Node* n) {
|
||||||
Ast_Node* target = new(Ast_Node);
|
Ast_Node* target = create_ast_node();
|
||||||
*target = *n;
|
*target = *n;
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -227,14 +227,16 @@ char* read_line() {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char* file;
|
char* file;
|
||||||
int line;
|
int line;
|
||||||
|
int column;
|
||||||
} Source_Code_Location;
|
} Source_Code_Location;
|
||||||
|
|
||||||
Source_Code_Location* create_source_code_location(char* file, int line) {
|
Source_Code_Location* create_source_code_location(char* file, int line, int col) {
|
||||||
if (!file)
|
if (!file)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Source_Code_Location* ret = new(Source_Code_Location);
|
Source_Code_Location* ret = new(Source_Code_Location);
|
||||||
ret->file = file;
|
ret->file = file;
|
||||||
ret->line = line;
|
ret->line = line;
|
||||||
|
ret->column = col;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,10 @@ void print(Ast_Node* node) {
|
|||||||
|
|
||||||
void print_error_location() {
|
void print_error_location() {
|
||||||
if (error->location) {
|
if (error->location) {
|
||||||
printf("%s: %d", error->location->file, error->location->line);
|
printf("%s (line %d, position %d)",
|
||||||
|
error->location->file,
|
||||||
|
error->location->line,
|
||||||
|
error->location->column);
|
||||||
} else {
|
} else {
|
||||||
printf("no source code location avaliable");
|
printf("no source code location avaliable");
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-18
@@ -1,5 +1,13 @@
|
|||||||
char* parser_file;
|
char* parser_file;
|
||||||
int parser_line;
|
int parser_line;
|
||||||
|
int parser_col;
|
||||||
|
|
||||||
|
#define inject_scl(_ret) \
|
||||||
|
ret->sourceCodeLocation = new(Source_Code_Location); \
|
||||||
|
ret->sourceCodeLocation->file = parser_file; \
|
||||||
|
ret->sourceCodeLocation->line = parser_line; \
|
||||||
|
ret->sourceCodeLocation->column = parser_col
|
||||||
|
|
||||||
|
|
||||||
// TODO(Felix): use the array list macro here?
|
// 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) {
|
||||||
@@ -30,13 +38,10 @@ void eat_comment_line(char* text, int* index_in_text) {
|
|||||||
// eat the comment line
|
// eat the comment line
|
||||||
do {
|
do {
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
} 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) {
|
||||||
@@ -44,12 +49,16 @@ void eat_whitespace(char* text, int* index_in_text) {
|
|||||||
while (text[(*index_in_text)] == ' ' ||
|
while (text[(*index_in_text)] == ' ' ||
|
||||||
text[(*index_in_text)] == '\t' ||
|
text[(*index_in_text)] == '\t' ||
|
||||||
text[(*index_in_text)] == '\n' ||
|
text[(*index_in_text)] == '\n' ||
|
||||||
text[(*index_in_text)] == '\r') {
|
text[(*index_in_text)] == '\r')
|
||||||
|
{
|
||||||
|
if (text[(*index_in_text)] == '\n') {
|
||||||
|
++parser_line;
|
||||||
|
parser_col = 0;
|
||||||
|
}
|
||||||
|
++parser_col;
|
||||||
++(*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) {
|
||||||
@@ -98,33 +107,43 @@ Ast_Node* parse_number(char* text, int* index_in_text) {
|
|||||||
double number;
|
double number;
|
||||||
char* str_number = read_atom(text, index_in_text);
|
char* str_number = read_atom(text, index_in_text);
|
||||||
sscanf(str_number, "%lf", &number);
|
sscanf(str_number, "%lf", &number);
|
||||||
return create_ast_node_number(number);
|
Ast_Node* ret = create_ast_node_number(number);
|
||||||
|
inject_scl(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ast_Node* parse_keyword(char* text, int* index_in_text) {
|
Ast_Node* parse_keyword(char* text, int* index_in_text) {
|
||||||
// we are now on the colon
|
// we are now on the colon
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
char* str_keyword = read_atom(text, index_in_text);
|
char* str_keyword = read_atom(text, index_in_text);
|
||||||
return create_ast_node_keyword(str_keyword);
|
Ast_Node* ret = create_ast_node_keyword(str_keyword);
|
||||||
|
inject_scl(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* parse_symbol(char* text, int* index_in_text) {
|
Ast_Node* parse_symbol(char* text, int* index_in_text) {
|
||||||
// we are now at the first char of the symbol
|
// we are now at the first char of the symbol
|
||||||
char* str_symbol = read_atom(text, index_in_text);
|
char* str_symbol = read_atom(text, index_in_text);
|
||||||
return create_ast_node_symbol(str_symbol);
|
Ast_Node* ret = create_ast_node_symbol(str_symbol);
|
||||||
|
inject_scl(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* parse_string(char* text, int* index_in_text) {
|
Ast_Node* parse_string(char* text, int* index_in_text) {
|
||||||
// the first character is the '"'
|
// the first character is the '"'
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
|
|
||||||
// now we are at the first letter, if this is the closing '"' then
|
// now we are at the first letter, if this is the closing '"' then
|
||||||
// it's easy
|
// it's easy
|
||||||
if (text[*index_in_text] == '"') {
|
if (text[*index_in_text] == '"') {
|
||||||
char* str = new(char);
|
char* str = new(char);
|
||||||
*str = '\0';
|
*str = '\0';
|
||||||
return create_ast_node_string(str, 0);
|
Ast_Node* ret = create_ast_node_string(str, 0);
|
||||||
|
inject_scl(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// okay so the first letter was not actually closing the string...
|
// okay so the first letter was not actually closing the string...
|
||||||
@@ -143,7 +162,7 @@ Ast_Node* parse_string(char* text, int* index_in_text) {
|
|||||||
if (!unescape_string(text+(*index_in_text))) {
|
if (!unescape_string(text+(*index_in_text))) {
|
||||||
create_error(
|
create_error(
|
||||||
Error_Type_Unknown_Error,
|
Error_Type_Unknown_Error,
|
||||||
create_source_code_location(parser_file, parser_line));
|
create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
strcpy(string, text+(*index_in_text));
|
strcpy(string, text+(*index_in_text));
|
||||||
@@ -159,7 +178,9 @@ Ast_Node* parse_string(char* text, int* index_in_text) {
|
|||||||
*index_in_text += string_length +1; // plus one because we want to
|
*index_in_text += string_length +1; // plus one because we want to
|
||||||
// go after the quotes
|
// go after the quotes
|
||||||
|
|
||||||
return create_ast_node_string(string, string_length);
|
Ast_Node* ret = create_ast_node_string(string, string_length);
|
||||||
|
inject_scl(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* parse_atom(char* text, int* index_in_text) {
|
Ast_Node* parse_atom(char* text, int* index_in_text) {
|
||||||
@@ -193,6 +214,7 @@ Ast_Node* parse_atom(char* text, int* index_in_text) {
|
|||||||
Ast_Node* parse_expression(char* text, int* index_in_text) {
|
Ast_Node* parse_expression(char* text, int* index_in_text) {
|
||||||
if (text[*index_in_text] == '\'') {
|
if (text[*index_in_text] == '\'') {
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
if (text[*index_in_text] == '(' || text[*index_in_text] == '\'' ) {
|
if (text[*index_in_text] == '(' || text[*index_in_text] == '\'' ) {
|
||||||
try {
|
try {
|
||||||
@@ -208,12 +230,14 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
|||||||
create_ast_node_pair(result, create_ast_node_nil()));
|
create_ast_node_pair(result, create_ast_node_nil()));
|
||||||
}
|
}
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
|
|
||||||
eat_whitespace(text, index_in_text);
|
eat_whitespace(text, index_in_text);
|
||||||
|
|
||||||
// if there was actually nothing in the list, return nil
|
// if there was actually nothing in the list, return nil
|
||||||
if (text[(*index_in_text)] == ')') {
|
if (text[(*index_in_text)] == ')') {
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
|
++parser_col;
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,16 +260,18 @@ 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, create_source_code_location(parser_file, parser_line));
|
create_error(Error_Type_Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (text[(*index_in_text)] == ')') {
|
if (text[(*index_in_text)] == ')') {
|
||||||
head->value.pair->rest = create_ast_node_nil();
|
head->value.pair->rest = create_ast_node_nil();
|
||||||
|
++parser_col;
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
break;
|
break;
|
||||||
} else if (text[(*index_in_text)] == '.') {
|
} else if (text[(*index_in_text)] == '.') {
|
||||||
|
++parser_col;
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
eat_until_code(text, index_in_text);
|
eat_until_code(text, index_in_text);
|
||||||
|
|
||||||
@@ -257,7 +283,8 @@ 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, create_source_code_location(parser_file, parser_line));
|
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
|
++parser_col;
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -269,6 +296,10 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* parse_single_expression(char* text) {
|
Ast_Node* parse_single_expression(char* text) {
|
||||||
|
parser_file = "stdin";
|
||||||
|
parser_line = 1;
|
||||||
|
parser_col = 1;
|
||||||
|
|
||||||
int index_in_text = 0;
|
int index_in_text = 0;
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
eat_until_code(text, &index_in_text);
|
eat_until_code(text, &index_in_text);
|
||||||
@@ -283,13 +314,16 @@ 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_source_code_location(parser_file, parser_line));
|
create_error(Error_Type_Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node_Array_List* parse_program(char* file_name, char* text) {
|
Ast_Node_Array_List* parse_program(char* file_name, char* text) {
|
||||||
parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1);
|
parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1);
|
||||||
strcpy(parser_file, file_name);
|
strcpy(parser_file, file_name);
|
||||||
|
parser_line = 1;
|
||||||
|
parser_col = 0;
|
||||||
|
|
||||||
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;
|
||||||
@@ -312,9 +346,11 @@ Ast_Node_Array_List* parse_program(char* file_name, char* text) {
|
|||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
/* syntax error */
|
/* syntax error */
|
||||||
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line));
|
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef inject_scl
|
||||||
|
|||||||
Reference in New Issue
Block a user