Browse Source

Output line numbers for errors discovered after the AST is built.

master
Gavan Fantom 17 years ago
parent
commit
8251351a2e
  1. 24
      src/lsc/ast.c
  2. 22
      src/lsc/codegen.c
  3. 1
      src/lsc/types.h

24
src/lsc/ast.c

@ -7,6 +7,8 @@
#include "ast.h" #include "ast.h"
#include "mem.h" #include "mem.h"
extern int yylineno;
ast_list *make_list(ast *elem, ast_list *tail) ast_list *make_list(ast *elem, ast_list *tail)
{ {
ast_list *list = safe_malloc(sizeof(ast_list)); ast_list *list = safe_malloc(sizeof(ast_list));
@ -39,6 +41,7 @@ ast *make_list_node(ast_list *list)
elem->tag = node_ast; elem->tag = node_ast;
elem->info.node.tag = kind_list; elem->info.node.tag = kind_list;
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -49,6 +52,7 @@ ast *make_string(char *string)
elem->tag = str_ast; elem->tag = str_ast;
elem->info.string = string; elem->info.string = string;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -59,6 +63,7 @@ ast *make_integer(long integer)
elem->tag = int_ast; elem->tag = int_ast;
elem->info.integer = integer; elem->info.integer = integer;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -69,6 +74,7 @@ ast *make_real(float real)
elem->tag = real_ast; elem->tag = real_ast;
elem->info.real = real; elem->info.real = real;
elem->lineno = yylineno;
return elem; 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_list_node(args), list);
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -98,6 +105,7 @@ ast *make_fndefint(char *identifier, long num)
list = make_list(make_integer(num), list); list = make_list(make_integer(num), list);
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -112,6 +120,7 @@ ast *make_constant(char *identifier, long num)
list = make_list(make_integer(num), list); list = make_list(make_integer(num), list);
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -126,6 +135,7 @@ ast *make_realconstant(char *identifier, float num)
list = make_list(make_real(num), list); list = make_list(make_real(num), list);
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -139,6 +149,7 @@ ast *make_fndefext(char *identifier)
elem->info.node.tag = kind_fndefext; elem->info.node.tag = kind_fndefext;
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -149,6 +160,7 @@ ast *make_variable(char *identifier)
elem->tag = var_ast; elem->tag = var_ast;
elem->info.variable = identifier; elem->info.variable = identifier;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -163,6 +175,7 @@ ast *make_array(char *identifier, ast *expression)
list = make_list(expression, NULL); list = make_list(expression, NULL);
list = make_list(make_variable(identifier), list); list = make_list(make_variable(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -178,6 +191,7 @@ ast *make_assignment(char *identifier, ast *expression)
list = make_list(expression, NULL); list = make_list(expression, NULL);
list = make_list(make_variable(identifier), list); list = make_list(make_variable(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -193,6 +207,7 @@ ast *make_assignment(ast_list *identifier_list, ast *expression)
list = make_list(expression, NULL); list = make_list(expression, NULL);
list = make_list(make_list_node(identifier_list), list); list = make_list(make_list_node(identifier_list), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; 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(exp2, NULL);
list = make_list(exp1, list); list = make_list(exp1, list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -220,6 +236,7 @@ ast *make_unary_op(ast_kind op, ast *exp1)
elem->info.node.tag = op; elem->info.node.tag = op;
list = make_list(exp1, NULL); list = make_list(exp1, NULL);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; 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_list_node(args), NULL);
list = make_list(make_string(identifier), list); list = make_list(make_string(identifier), list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; 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(make_list_node(statements), list);
list = make_list(expression, list); list = make_list(expression, list);
elem->info.node.head = list; elem->info.node.head = list;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -262,6 +281,7 @@ ast *make_case_statement_variable(char *identifier)
elem->tag = casevar_ast; elem->tag = casevar_ast;
elem->info.variable = identifier; elem->info.variable = identifier;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -272,6 +292,7 @@ ast *make_case_statement_number(long num)
elem->tag = casenum_ast; elem->tag = casenum_ast;
elem->info.integer = num; elem->info.integer = num;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -283,6 +304,7 @@ ast *make_return_statement(void)
elem->tag = node_ast; elem->tag = node_ast;
elem->info.node.tag = stmt_return; elem->info.node.tag = stmt_return;
elem->info.node.head = NULL; elem->info.node.head = NULL;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -294,6 +316,7 @@ ast *make_break_statement(void)
elem->tag = node_ast; elem->tag = node_ast;
elem->info.node.tag = stmt_break; elem->info.node.tag = stmt_break;
elem->info.node.head = NULL; elem->info.node.head = NULL;
elem->lineno = yylineno;
return elem; return elem;
} }
@ -305,6 +328,7 @@ ast *make_default_statement(void)
elem->tag = node_ast; elem->tag = node_ast;
elem->info.node.tag = stmt_default; elem->info.node.tag = stmt_default;
elem->info.node.head = NULL; elem->info.node.head = NULL;
elem->lineno = yylineno;
return elem; return elem;
} }

22
src/lsc/codegen.c

@ -6,6 +6,7 @@
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>
#include <limits.h> #include <limits.h>
#include <stdarg.h>
#include "types.h" #include "types.h"
#include "ast.h" #include "ast.h"
#include "codegen.h" #include "codegen.h"
@ -37,6 +38,7 @@ struct label {
#define MAX_LABELS 4096 #define MAX_LABELS 4096
#define MAX_CONSTS 4096 #define MAX_CONSTS 4096
#define ERROR_MAXLEN 1024
struct label *labels = NULL; struct label *labels = NULL;
int nlabels = 0; int nlabels = 0;
@ -104,6 +106,8 @@ int local_arg_count = -1;
int function_count = -1; int function_count = -1;
int constant_count = -1; int constant_count = -1;
int lineno;
#define HASHSIZE 512 #define HASHSIZE 512
#define HASHMASK (HASHSIZE - 1) #define HASHMASK (HASHSIZE - 1)
@ -111,9 +115,16 @@ struct hashentry *varhash[HASHSIZE];
struct hashentry *fnhash[HASHSIZE]; struct hashentry *fnhash[HASHSIZE];
struct hashentry *constanthash[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) int count_local_variables(void)
@ -533,12 +544,16 @@ void codegen(ast *node)
int stackfixlabel; int stackfixlabel;
int hasdefault; int hasdefault;
int i; int i;
int savedlineno;
union { union {
int i; int i;
float f; float f;
} conv; } conv;
savedlineno = lineno;
lineno = node->lineno;
#if DEBUG #if DEBUG
printf("entering codegen with node %p, sp = %d, tag = %d\n", node, sp, node->tag); printf("entering codegen with node %p, sp = %d, tag = %d\n", node, sp, node->tag);
if (node->tag == node_ast) if (node->tag == node_ast)
@ -582,9 +597,8 @@ void codegen(ast *node)
real = (*node->info.string == '%'); real = (*node->info.string == '%');
break; break;
} }
printf("error: variable '%s' used before assignment\n", compiler_error("variable '%s' used before assignment",
var.name); var.name);
exit(EXIT_FAILURE);
} }
// printf("sp = %d\n", sp); // printf("sp = %d\n", sp);
if (var.flags & VAR_REAL) if (var.flags & VAR_REAL)

1
src/lsc/types.h

@ -29,6 +29,7 @@ typedef struct ast {
struct ast_list* head; struct ast_list* head;
} node; } node;
} info; } info;
int lineno;
} ast; } ast;
typedef struct ast_list { typedef struct ast_list {

Loading…
Cancel
Save