Output line numbers for errors discovered after the AST is built.
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include "ast.h"
|
||||
#include "mem.h"
|
||||
|
||||
extern int yylineno;
|
||||
|
||||
ast_list *make_list(ast *elem, ast_list *tail)
|
||||
{
|
||||
ast_list *list = safe_malloc(sizeof(ast_list));
|
||||
@@ -39,6 +41,7 @@ ast *make_list_node(ast_list *list)
|
||||
elem->tag = node_ast;
|
||||
elem->info.node.tag = kind_list;
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -49,6 +52,7 @@ ast *make_string(char *string)
|
||||
|
||||
elem->tag = str_ast;
|
||||
elem->info.string = string;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -59,6 +63,7 @@ ast *make_integer(long integer)
|
||||
|
||||
elem->tag = int_ast;
|
||||
elem->info.integer = integer;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -69,6 +74,7 @@ ast *make_real(float real)
|
||||
|
||||
elem->tag = real_ast;
|
||||
elem->info.real = real;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -84,6 +90,7 @@ ast *make_function(char *identifier, ast_list *args, ast_list *stmts)
|
||||
list = make_list(make_list_node(args), list);
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -98,6 +105,7 @@ ast *make_fndefint(char *identifier, long num)
|
||||
list = make_list(make_integer(num), list);
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -112,6 +120,7 @@ ast *make_constant(char *identifier, long num)
|
||||
list = make_list(make_integer(num), list);
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -126,6 +135,7 @@ ast *make_realconstant(char *identifier, float num)
|
||||
list = make_list(make_real(num), list);
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -139,6 +149,7 @@ ast *make_fndefext(char *identifier)
|
||||
elem->info.node.tag = kind_fndefext;
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -149,6 +160,7 @@ ast *make_variable(char *identifier)
|
||||
|
||||
elem->tag = var_ast;
|
||||
elem->info.variable = identifier;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -163,6 +175,7 @@ ast *make_array(char *identifier, ast *expression)
|
||||
list = make_list(expression, NULL);
|
||||
list = make_list(make_variable(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -178,6 +191,7 @@ ast *make_assignment(char *identifier, ast *expression)
|
||||
list = make_list(expression, NULL);
|
||||
list = make_list(make_variable(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -193,6 +207,7 @@ ast *make_assignment(ast_list *identifier_list, ast *expression)
|
||||
list = make_list(expression, NULL);
|
||||
list = make_list(make_list_node(identifier_list), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -207,6 +222,7 @@ ast *make_binary_op(ast_kind op, ast *exp1, ast *exp2)
|
||||
list = make_list(exp2, NULL);
|
||||
list = make_list(exp1, list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -220,6 +236,7 @@ ast *make_unary_op(ast_kind op, ast *exp1)
|
||||
elem->info.node.tag = op;
|
||||
list = make_list(exp1, NULL);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -234,6 +251,7 @@ ast *make_call(char *identifier, ast_list *args)
|
||||
list = make_list(make_list_node(args), NULL);
|
||||
list = make_list(make_string(identifier), list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -252,6 +270,7 @@ ast *make_statement(ast_kind type, ast *expression, ast_list *statements,
|
||||
list = make_list(make_list_node(statements), list);
|
||||
list = make_list(expression, list);
|
||||
elem->info.node.head = list;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -262,6 +281,7 @@ ast *make_case_statement_variable(char *identifier)
|
||||
|
||||
elem->tag = casevar_ast;
|
||||
elem->info.variable = identifier;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -272,6 +292,7 @@ ast *make_case_statement_number(long num)
|
||||
|
||||
elem->tag = casenum_ast;
|
||||
elem->info.integer = num;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -283,6 +304,7 @@ ast *make_return_statement(void)
|
||||
elem->tag = node_ast;
|
||||
elem->info.node.tag = stmt_return;
|
||||
elem->info.node.head = NULL;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -294,6 +316,7 @@ ast *make_break_statement(void)
|
||||
elem->tag = node_ast;
|
||||
elem->info.node.tag = stmt_break;
|
||||
elem->info.node.head = NULL;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
@@ -305,6 +328,7 @@ ast *make_default_statement(void)
|
||||
elem->tag = node_ast;
|
||||
elem->info.node.tag = stmt_default;
|
||||
elem->info.node.head = NULL;
|
||||
elem->lineno = yylineno;
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include "types.h"
|
||||
#include "ast.h"
|
||||
#include "codegen.h"
|
||||
@@ -37,6 +38,7 @@ struct label {
|
||||
|
||||
#define MAX_LABELS 4096
|
||||
#define MAX_CONSTS 4096
|
||||
#define ERROR_MAXLEN 1024
|
||||
|
||||
struct label *labels = NULL;
|
||||
int nlabels = 0;
|
||||
@@ -104,6 +106,8 @@ int local_arg_count = -1;
|
||||
int function_count = -1;
|
||||
int constant_count = -1;
|
||||
|
||||
int lineno;
|
||||
|
||||
#define HASHSIZE 512
|
||||
#define HASHMASK (HASHSIZE - 1)
|
||||
|
||||
@@ -111,9 +115,16 @@ struct hashentry *varhash[HASHSIZE];
|
||||
struct hashentry *fnhash[HASHSIZE];
|
||||
struct hashentry *constanthash[HASHSIZE];
|
||||
|
||||
void compiler_error(char *str)
|
||||
void compiler_error(char *str, ...)
|
||||
{
|
||||
errx(1, str);
|
||||
char buf[ERROR_MAXLEN];
|
||||
va_list args;
|
||||
|
||||
snprintf(buf, ERROR_MAXLEN, "%d: %s", lineno, str);
|
||||
|
||||
va_start(args, str);
|
||||
verrx(1, buf, args);
|
||||
va_end(args); /* Not really necessary if errx exits */
|
||||
}
|
||||
|
||||
int count_local_variables(void)
|
||||
@@ -533,12 +544,16 @@ void codegen(ast *node)
|
||||
int stackfixlabel;
|
||||
int hasdefault;
|
||||
int i;
|
||||
int savedlineno;
|
||||
|
||||
union {
|
||||
int i;
|
||||
float f;
|
||||
} conv;
|
||||
|
||||
savedlineno = lineno;
|
||||
|
||||
lineno = node->lineno;
|
||||
#if DEBUG
|
||||
printf("entering codegen with node %p, sp = %d, tag = %d\n", node, sp, node->tag);
|
||||
if (node->tag == node_ast)
|
||||
@@ -582,9 +597,8 @@ void codegen(ast *node)
|
||||
real = (*node->info.string == '%');
|
||||
break;
|
||||
}
|
||||
printf("error: variable '%s' used before assignment\n",
|
||||
compiler_error("variable '%s' used before assignment",
|
||||
var.name);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// printf("sp = %d\n", sp);
|
||||
if (var.flags & VAR_REAL)
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef struct ast {
|
||||
struct ast_list* head;
|
||||
} node;
|
||||
} info;
|
||||
int lineno;
|
||||
} ast;
|
||||
|
||||
typedef struct ast_list {
|
||||
|
||||
Reference in New Issue
Block a user