/much/ better error handling

This commit is contained in:
Bill Currie 2001-06-28 21:26:40 +00:00
parent eef9e8e2dc
commit 6dfee9968b
4 changed files with 73 additions and 52 deletions

View file

@ -61,3 +61,6 @@ expr_t *function_expr (expr_t *e1, expr_t *e2);
def_t *emit_statement (opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c);
void emit_expr (expr_t *e);
expr_t *error (expr_t *e, const char *fmt, ...);
void warning (expr_t *e, const char *fmt, ...);

View file

@ -7,7 +7,6 @@
#include "scope.h"
#include "qc-parse.h"
void yyerror (const char*);
extern function_t *current_func;
static etype_t qc_types[] = {
@ -71,6 +70,48 @@ get_type (expr_t *e)
return ev_void;
}
expr_t *
error (expr_t *e, const char *fmt, ...)
{
va_list args;
string_t file = s_file;
int line = pr_source_line;
va_start (args, fmt);
if (e) {
file = e->file;
line = e->line;
}
fprintf (stderr, "%s:%d: ", strings + file, line);
vfprintf (stderr, fmt, args);
fputs ("\n", stderr);
if (e) {
e = new_expr ();
e->type = ex_int;
}
va_end (args);
pr_error_count++;
return e;
}
void
warning (expr_t *e, const char *fmt, ...)
{
va_list args;
string_t file = s_file;
int line = pr_source_line;
va_start (args, fmt);
if (e) {
file = e->file;
line = e->line;
}
fprintf (stderr, "%s:%d: warning:", strings + file, line);
vfprintf (stderr, fmt, args);
fputs ("\n", stderr);
va_end (args);
}
expr_t *
new_expr (void)
{
@ -261,8 +302,7 @@ do_op_string (int op, expr_t *e1, expr_t *e2)
e1->e.int_val = strcmp (s1, s2) != 0;
break;
default:
yyerror ("invalid operand for string");
return 0;
return error (e1, "invalid operand for string");
}
return e1;
}
@ -325,8 +365,7 @@ do_op_float (int op, expr_t *e1, expr_t *e2)
e1->e.int_val = f1 != f2;
break;
default:
yyerror ("invalid operand for string");
return 0;
return error (e1, "invalid operand for string");
}
return e1;
}
@ -363,8 +402,7 @@ do_op_vector (int op, expr_t *e1, expr_t *e2)
|| (v1[2] != v2[2]);
break;
default:
yyerror ("invalid operand for string");
return 0;
return error (e1, "invalid operand for string");
}
return e1;
}
@ -372,8 +410,7 @@ do_op_vector (int op, expr_t *e1, expr_t *e2)
static expr_t *
do_op_huh (int op, expr_t *e1, expr_t *e2)
{
yyerror ("funny constant");
return 0;
return error (e1, "funny constant");
}
static expr_t *(*do_op[]) (int op, expr_t *e1, expr_t *e2) = {
@ -399,11 +436,9 @@ binary_const (int op, expr_t *e1, expr_t *e2)
if (t1 == t2) {
return do_op[t1](op, e1, e2);
} else {
yyerror ("type missmatch for");
fprintf (stderr, "%d (%c)\n", op, (op > ' ' && op < 127) ? op : ' ');
return 0;
return error (e1, "type missmatch for %d (%c)",
op, (op > ' ' && op < 127) ? op : ' ');
}
return 0;
}
static expr_t *
@ -416,8 +451,7 @@ field_expr (expr_t *e1, expr_t *e2)
t2 = get_type (e2);
if (t1 != ev_entity || t2 != ev_field) {
yyerror ("type missmatch for .");
return 0;
return error (e1, "type missmatch for .");
}
e = new_binary_expr ('.', e1, e2);
@ -440,14 +474,13 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if ((op == '&' || op == '|')
&& e1->type == ex_uexpr && e1->e.expr.op == '!' && !e1->paren) {
fprintf (stderr, "%s:%d: warning: ambiguous logic. Suggest explicit parentheses with expressions involving ! and %c\n",
strings + e1->file, e1->line, op);
warning (e1, "ambiguous logic. Suggest explicit parentheses with expressions involving ! and %c", op);
}
t1 = get_type (e1);
t2 = get_type (e2);
if (t1 == ev_void || t2 == ev_void) {
yyerror ("internal error");
error (e1, "internal error");
abort ();
}
@ -489,9 +522,7 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
}
default:
type_mismatch:
yyerror ("type missmatch");
fprintf (stderr, "%d %d\n", t1, t2);
return 0;
return error (e1, "type missmatch %d %d", t1, t2);
}
}
}
@ -524,7 +555,7 @@ unary_expr (int op, expr_t *e)
e->e.float_val *= -1;
return e;
case ex_string:
return 0; // FIXME
return error (e, "invalid type for unary -");
case ex_vector:
e->e.vector_val[0] *= -1;
e->e.vector_val[1] *= -1;
@ -580,7 +611,7 @@ unary_expr (int op, expr_t *e)
default:
abort ();
}
yyerror ("internal error");
error (e, "internal error");
abort ();
}
@ -595,9 +626,7 @@ function_expr (expr_t *e1, expr_t *e2)
t1 = get_type (e1);
if (t1 != ev_func) {
yyerror ("called object is not a function");
fprintf (stderr, "%d\n", t1);
return 0;
return error (e1, "called object is not a function %d", t1);
}
ftype = e1->type == ex_def
@ -607,16 +636,13 @@ function_expr (expr_t *e1, expr_t *e2)
for (e = e2; e; e = e->next)
parm_count++;
if (parm_count > 8) {
yyerror ("more than 8 paramters");
return 0;
return error (e1, "more than 8 paramters");
}
if (ftype->num_parms != -1) {
if (parm_count > ftype->num_parms) {
yyerror ("too many arguments");
return 0;
return error (e1, "too many arguments");
} else if (parm_count < ftype->num_parms) {
yyerror ("too few arguments");
return 0;
return error (e1, "too few arguments");
}
}
e = new_binary_expr ('c', e1, e2);
@ -739,8 +765,7 @@ emit_assign_expr (expr_t *e)
def_a->ofs = ofs;
def_a->initialized = 0;
} else {
fprintf (stderr, "%s:%d: assignment to constant %s\n",
strings + e->file, e->line, def_a->name);
error (e1, "assignment to constant %s", def_a->name);
}
}
if (e2->type == ex_expr) {
@ -927,9 +952,8 @@ emit_expr (expr_t *e)
emit_statement (op_state, def_a, def_b, 0);
break;
default:
fprintf (stderr,
"%s:%d: warning: unused expression ignored\n",
strings + e->file, e->line);
warning (e, "unused expression ignored");
break;
}
break;
case ex_uexpr:
@ -944,9 +968,7 @@ emit_expr (expr_t *e)
emit_branch (op_goto, 0, e->e.expr.e1);
break;
default:
fprintf (stderr,
"%s:%d: warning: unused expression ignored\n",
strings + e->file, e->line);
warning (e, "unused expression ignored");
emit_expr (e->e.expr.e1);
break;
}
@ -957,8 +979,7 @@ emit_expr (expr_t *e)
case ex_string:
case ex_vector:
case ex_quaternion:
fprintf (stderr, "%s:%d: warning: unused expression ignored\n",
strings + e->file, e->line);
warning (e, "unused expression ignored");
break;
}
PR_FreeTempDefs ();

View file

@ -6,8 +6,6 @@
#define YY_NO_UNPUT
void error (char*s){fprintf(stderr,"%s:%d: %s\n",strings+s_file,pr_source_line,s);}
int type_or_name (char *token);
int do_grab (char *token);
@ -40,7 +38,7 @@ m ([\-+]?)
while (c == '*')
c = input ();
if (c == EOF)
error ("EOF in comment");
error (0, "EOF in comment");
if (c == '\n')
pr_source_line++;
} while (c != '/' && c != EOF);
@ -129,7 +127,7 @@ m ([\-+]?)
<*>{s}* /* skip */
<*>. error ("all your typo are belong to us");
<*>. error (0, "all your typo are belong to us");
%%

View file

@ -10,7 +10,7 @@ extern int pr_source_line;
void
yyerror (const char *s)
{
fprintf (stderr, "%s:%d, %s %s\n", strings + s_file, pr_source_line, yytext, s);
error (0, "%s %s\n", strings + s_file, pr_source_line, yytext, s);
}
int yylex (void);
@ -180,8 +180,7 @@ param_list
| param_list ',' param
{
if ($3->next) {
yyerror ("parameter redeclared");
yyerror ($3->name);
error (0, "parameter redeclared: %s", $3->name);
$$ = $1;
} else {
$3->next = $1;
@ -213,10 +212,10 @@ opt_initializer
| '=' '#' const
{
if (current_type->type != ev_func) {
yyerror ("note a function");
error (0, "%s is not a function");
} else {
if ($3->type != ex_int && $3->type != ex_float) {
yyerror ("invalid constant for = #");
error (0, "invalid constant for = #");
} else {
function_t *f;
@ -480,7 +479,7 @@ parse_params (def_t *parms)
for (p = parms; p; p = p->next, new.num_parms++)
;
if (new.num_parms > MAX_PARMS) {
yyerror ("too many params");
error (0, "too many params");
return current_type;
}
i = 1;