summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-04-18 21:43:24 -0400
committerTavian Barnes <tavianator@gmail.com>2010-04-18 22:29:41 -0400
commit85c5f17dcd09540e31dc879166502984e483609d (patch)
tree6bc4c9ea1f265756e8b563885dabcdc0af09b0cf /dimension
parent6437ab96674accfb5d5d85066e58d20887c926d7 (diff)
downloaddimension-85c5f17dcd09540e31dc879166502984e483609d.tar.xz
Have dmnsn_diagnostic() take a dmnsn_parse_location.
Diffstat (limited to 'dimension')
-rw-r--r--dimension/common.prologue11
-rw-r--r--dimension/common.rules12
-rw-r--r--dimension/directives.prologue3
-rw-r--r--dimension/directives.rules20
-rw-r--r--dimension/grammar.prologue3
-rw-r--r--dimension/lexer.l23
-rw-r--r--dimension/parse.c83
-rw-r--r--dimension/parse.h22
-rw-r--r--dimension/realize.c8
-rw-r--r--dimension/tokenize.c44
-rw-r--r--dimension/utility.c18
-rw-r--r--dimension/utility.h12
12 files changed, 103 insertions, 156 deletions
diff --git a/dimension/common.prologue b/dimension/common.prologue
index 06ccdb3..d82b110 100644
--- a/dimension/common.prologue
+++ b/dimension/common.prologue
@@ -38,12 +38,7 @@
(Current).last_line = YYRHSLOC(Rhs, N).last_line; \
(Current).last_column = YYRHSLOC(Rhs, N).last_column; \
} else { \
- (Current).first_filename = (Current).last_filename = \
- YYRHSLOC(Rhs, 0).last_filename; \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC(Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC(Rhs, 0).last_column; \
+ (Current) = YYRHSLOC(Rhs, 0); \
} \
} while (0)
@@ -58,9 +53,7 @@ dmnsn_new_astnode(dmnsn_astnode_type type, YYLTYPE lloc)
.ptr = NULL,
.free_fn = NULL,
.refcount = dmnsn_malloc(sizeof(unsigned int)),
- .filename = lloc.first_filename,
- .line = lloc.first_line,
- .col = lloc.first_column
+ .location = lloc
};
*astnode.refcount = 1;
diff --git a/dimension/common.rules b/dimension/common.rules
index cba3669..ff208f2 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -121,10 +121,7 @@ OBJECT: FINITE_SOLID_OBJECT
{
dmnsn_astnode *object = dmnsn_find_symbol(symtable, $3.ptr);
if (!object) {
- dmnsn_diagnostic(@3.first_filename, @3.first_line,
- @3.first_column,
- "unbound identifier '%s'",
- (const char *)$3.ptr);
+ dmnsn_diagnostic(@3, "unbound identifier '%s'", (const char *)$3.ptr);
dmnsn_delete_astnode($3);
YYERROR;
} else {
@@ -165,8 +162,7 @@ OBJECT: FINITE_SOLID_OBJECT
}
default:
- dmnsn_diagnostic(@3.first_filename, @3.first_line,
- @3.first_column,
+ dmnsn_diagnostic(@3,
"identifier '%s' is a %s; expected an object type",
(const char *)$3.ptr,
dmnsn_astnode_string(object->type));
@@ -844,9 +840,7 @@ COLOR_KEYWORD_GROUP_INIT: /* empty */ {
COLOR_KEYWORD_ITEM: IDENTIFIER {
dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, $1.ptr);
if (!symbol) {
- dmnsn_diagnostic(@1.first_filename, @1.first_line,
- @1.first_column,
- "unbound identifier '%s'",
+ dmnsn_diagnostic(@1, "unbound identifier '%s'",
(const char *)$1.ptr);
dmnsn_delete_astnode($1);
YYERROR;
diff --git a/dimension/directives.prologue b/dimension/directives.prologue
index 3649bed..0bb7cad 100644
--- a/dimension/directives.prologue
+++ b/dimension/directives.prologue
@@ -23,8 +23,7 @@ void
yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
dmnsn_symbol_table *symtable, const char *str)
{
- dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column,
- "%s", str);
+ dmnsn_diagnostic(*locp, "%s", str);
}
static int
diff --git a/dimension/directives.rules b/dimension/directives.rules
index 82bdd8f..e199fe3 100644
--- a/dimension/directives.rules
+++ b/dimension/directives.rules
@@ -47,10 +47,8 @@ LANGUAGE_DIRECTIVE: "#include" STRING {
dmnsn_delete_astnode($3);
}
| "#version" FLOAT ";" {
- dmnsn_diagnostic(@$.first_filename, @$.first_line,
- @$.first_column,
- "WARNING: POV-Ray #version"
- " backwards-compatibility not supported");
+ dmnsn_diagnostic(@$, "WARNING: POV-Ray #version backwards-"
+ "compatibility not supported");
dmnsn_delete_astnode($2);
}
| "#debug" STRING {
@@ -58,15 +56,11 @@ LANGUAGE_DIRECTIVE: "#include" STRING {
dmnsn_delete_astnode($2);
}
| "#warning" STRING {
- dmnsn_diagnostic(@$.first_filename, @$.first_line,
- @$.first_column,
- "WARNING: %s", (const char *)$2.ptr);
+ dmnsn_diagnostic(@$, "WARNING: %s", (const char *)$2.ptr);
dmnsn_delete_astnode($2);
}
| "#error" STRING {
- dmnsn_diagnostic(@$.first_filename, @$.first_line,
- @$.first_column,
- "%s", (const char *)$2.ptr);
+ dmnsn_diagnostic(@$, "%s", (const char *)$2.ptr);
dmnsn_delete_astnode($2);
YYERROR;
}
@@ -87,10 +81,8 @@ LANGUAGE_DIRECTIVE: "#include" STRING {
unsigned int nparams_given = dmnsn_array_size($3.children);
if (nparams_given != nparams) {
- dmnsn_diagnostic(@$.first_filename, @$.first_line,
- @$.first_column,
- "wrong number of macro arguments"
- " (%u; should be %u)",
+ dmnsn_diagnostic(@$, "wrong number of macro arguments"
+ " (%u; should be %u)",
nparams_given, nparams);
dmnsn_delete_astnode($3);
YYERROR;
diff --git a/dimension/grammar.prologue b/dimension/grammar.prologue
index 6f8e312..9a00b89 100644
--- a/dimension/grammar.prologue
+++ b/dimension/grammar.prologue
@@ -23,6 +23,5 @@ void
yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
dmnsn_astree *astree, dmnsn_symbol_table *symtable, const char *str)
{
- dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column,
- "%s", str);
+ dmnsn_diagnostic(*locp, "%s", str);
}
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 2684868..f4685b8 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -54,7 +54,8 @@
lvalp->value = NULL; \
llocp->first_filename = llocp->last_filename = filename; \
llocp->first_line = llocp->last_line = yylineno; \
- llocp->first_column = llocp->last_column = yycolumn; \
+ llocp->first_column = yycolumn; \
+ llocp->last_column = yycolumn + yyleng; \
} while (0)
#define CALCULATE_COLUMN() do { yycolumn += yyleng; } while (0)
@@ -296,9 +297,9 @@ unsigned long wchar;
#[\b\r\t\v ]*while RETURN_TOKEN(DMNSN_T_WHILE);
#[\b\r\t\v ]*write RETURN_TOKEN(DMNSN_T_WRITE);
#[\b\r\t\v ]*[[:alnum:]_]* {
- dmnsn_diagnostic(filename, yylineno, yycolumn,
- "unrecognized language directive '%s'", yytext);
- RETURN_TOKEN(DMNSN_T_LEX_ERROR);
+ NEW_TOKEN(DMNSN_T_LEX_ERROR);
+ dmnsn_diagnostic(*llocp, "unrecognized language directive '%s'", yytext);
+ RETURN();
}
(?# Identifiers)
@@ -334,8 +335,12 @@ unsigned long wchar;
yy_pop_state(yyscanner);
}
<DMNSN_STRING_ESCAPE>. {
- dmnsn_diagnostic(filename, yylineno, yycolumn,
- "WARNING: unrecognised escape sequence '\\%c'",
+ dmnsn_parse_location location;
+ location.first_filename = location.last_filename = filename;
+ location.first_line = location.last_line = yylineno;
+ location.first_column = yycolumn;
+ location.last_column = yycolumn + yyleng;
+ dmnsn_diagnostic(location, "WARNING: unrecognised escape sequence '\\%c'",
(int)*yytext);
STRCAT(yytext, yyleng);
yy_pop_state(yyscanner);
@@ -347,10 +352,10 @@ unsigned long wchar;
(?# Fall-through)
. {
- dmnsn_diagnostic(filename, yylineno, yycolumn,
- "unrecognized character '%c' (0x%X)",
+ NEW_TOKEN(DMNSN_T_LEX_ERROR);
+ dmnsn_diagnostic(*llocp, "unrecognized character '%c' (0x%X)",
(int)*yytext, (unsigned int)(unsigned char)*yytext);
- RETURN_TOKEN(DMNSN_T_LEX_ERROR);
+ RETURN();
}
%%
diff --git a/dimension/parse.c b/dimension/parse.c
index 4d27be6..e4f3bf3 100644
--- a/dimension/parse.c
+++ b/dimension/parse.c
@@ -328,9 +328,7 @@ dmnsn_new_astnode(dmnsn_astnode_type type)
.ptr = NULL,
.free_fn = NULL,
.refcount = dmnsn_malloc(sizeof(unsigned int)),
- .filename = "<environment>",
- .line = -1,
- .col = -1,
+ .location = { "<environment>", "<environment>", -1, -1, -1, -1 }
};
*astnode.refcount = 0;
@@ -491,9 +489,7 @@ dmnsn_copy_astnode(dmnsn_astnode astnode)
.children = dmnsn_new_array(sizeof(dmnsn_astnode)),
.ptr = NULL,
.refcount = dmnsn_malloc(sizeof(unsigned int)),
- .filename = astnode.filename,
- .line = astnode.line,
- .col = astnode.col
+ .location = astnode.location
};
*copy.refcount = 1;
@@ -600,8 +596,7 @@ dmnsn_eval_zeroary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid constant '%s'",
+ dmnsn_diagnostic(astnode.location, "invalid constant '%s'",
dmnsn_astnode_string(astnode.type));
ret.type = DMNSN_AST_NONE;
break;
@@ -797,8 +792,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
}
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid unary operator '%s' on %s",
+ dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
@@ -902,8 +896,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
}
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid unary operator '%s' on %s",
+ dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
@@ -926,8 +919,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
if (*endptr != '\0' || endptr == rhs.ptr) {
double d = strtod(rhs.ptr, &endptr);
if (*endptr != '\0' || endptr == rhs.ptr) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid numeric string '%s'",
+ dmnsn_diagnostic(astnode.location, "invalid numeric string '%s'",
(const char *)rhs.ptr);
ret.type = DMNSN_AST_NONE;
} else {
@@ -940,16 +932,14 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
}
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid unary operator '%s' on %s",
+ dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(rhs.type));
ret.type = DMNSN_AST_NONE;
break;
}
} else {
- dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col,
- "expected %s or %s or %s; found %s",
+ dmnsn_diagnostic(rhs.location, "expected %s or %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
dmnsn_astnode_string(DMNSN_AST_STRING),
@@ -1134,7 +1124,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
case DMNSN_AST_LESS_EQUAL:
case DMNSN_AST_GREATER:
case DMNSN_AST_GREATER_EQUAL:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ dmnsn_diagnostic(astnode.location,
"invalid comparison operator '%s' between vectors",
dmnsn_astnode_string(astnode.type));
ret = dmnsn_copy_astnode(astnode);
@@ -1317,7 +1307,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ dmnsn_diagnostic(astnode.location,
"invalid binary operator '%s' on %s and %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(lhs.type),
@@ -1344,8 +1334,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
case DMNSN_AST_DIV:
if (r == 0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_float(&ret, (double)l/0.0);
} else if (l%r == 0) {
dmnsn_make_ast_integer(&ret, l/r);
@@ -1384,8 +1373,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
case DMNSN_AST_INT_DIV:
if (r == 0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_float(&ret, (double)l/0.0);
} else {
dmnsn_make_ast_integer(&ret, l/r);
@@ -1399,8 +1387,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
case DMNSN_AST_MOD:
if (r == 0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_float(&ret, fmod(l, 0.0));
} else {
dmnsn_make_ast_integer(&ret, l%r);
@@ -1424,7 +1411,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ dmnsn_diagnostic(astnode.location,
"invalid binary operator '%s' on %s and %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(lhs.type),
@@ -1442,8 +1429,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
} else if (lhs.type == DMNSN_AST_FLOAT) {
l = *(double *)lhs.ptr;
} else {
- dmnsn_diagnostic(lhs.filename, lhs.line, lhs.col,
- "expected %s or %s; found %s",
+ dmnsn_diagnostic(lhs.location, "expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
dmnsn_astnode_string(lhs.type));
@@ -1458,8 +1444,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
} else if (rhs.type == DMNSN_AST_FLOAT) {
r = *(double *)rhs.ptr;
} else {
- dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col,
- "expected %s or %s; found %s",
+ dmnsn_diagnostic(rhs.location, "expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
dmnsn_astnode_string(rhs.type));
@@ -1480,10 +1465,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_float(&ret, l*r);
break;
case DMNSN_AST_DIV:
- if (r == 0.0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
- }
+ if (r == 0.0)
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_float(&ret, l/r);
break;
@@ -1518,10 +1501,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_make_ast_float(&ret, atan2(l, r));
break;
case DMNSN_AST_INT_DIV:
- if (r == 0.0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
- }
+ if (r == 0.0)
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_maybe_integer(&ret, trunc(l/r));
break;
case DMNSN_AST_MAX:
@@ -1555,10 +1536,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
}
break;
case DMNSN_AST_MOD:
- if (r == 0.0) {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: division by zero");
- }
+ if (r == 0.0)
+ dmnsn_diagnostic(astnode.location, "WARNING: division by zero");
dmnsn_make_ast_float(&ret, fmod(l, r));
break;
case DMNSN_AST_POW:
@@ -1579,7 +1558,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ dmnsn_diagnostic(astnode.location,
"invalid binary operator '%s' on %s and %s",
dmnsn_astnode_string(astnode.type),
dmnsn_astnode_string(lhs.type),
@@ -1611,8 +1590,7 @@ dmnsn_eval_ternary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
break;
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "invalid ternary operator '%s'",
+ dmnsn_diagnostic(astnode.location, "invalid ternary operator '%s'",
dmnsn_astnode_string(astnode.type));
ret = dmnsn_copy_astnode(astnode);
ret.type = DMNSN_AST_NONE;
@@ -1644,13 +1622,11 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, astnode.ptr);
if (symbol) {
dmnsn_astnode id = *symbol;
- id.filename = astnode.filename;
- id.line = astnode.line;
- id.col = astnode.col;
+ id.location = astnode.location;
return dmnsn_eval(id, symtable);
} else {
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "unbound identifier '%s'", (const char *)astnode.ptr);
+ dmnsn_diagnostic(astnode.location, "unbound identifier '%s'",
+ (const char *)astnode.ptr);
dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE);
++*error.refcount;
return error;
@@ -1731,7 +1707,7 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
return dmnsn_eval_ternary(astnode, symtable);
default:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
+ dmnsn_diagnostic(astnode.location,
"expected arithmetic expression; found %s",
dmnsn_astnode_string(astnode.type));
dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE);
@@ -1749,8 +1725,7 @@ dmnsn_eval_scalar(dmnsn_astnode astnode, dmnsn_symbol_table *symtable)
if (ret.type != DMNSN_AST_INTEGER && ret.type != DMNSN_AST_FLOAT
&& ret.type != DMNSN_AST_NONE)
{
- dmnsn_diagnostic(ret.filename, ret.line, ret.col,
- "expected %s or %s; found %s",
+ dmnsn_diagnostic(ret.location, "expected %s or %s; found %s",
dmnsn_astnode_string(DMNSN_AST_INTEGER),
dmnsn_astnode_string(DMNSN_AST_FLOAT),
dmnsn_astnode_string(ret.type));
diff --git a/dimension/parse.h b/dimension/parse.h
index 6e5ef09..3a830b8 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -165,8 +165,16 @@ typedef enum {
DMNSN_AST_MACRO
} dmnsn_astnode_type;
+typedef struct dmnsn_astnode dmnsn_astnode;
+
+typedef struct dmnsn_parse_location {
+ const char *first_filename, *last_filename;
+ int first_line, last_line;
+ int first_column, last_column;
+} dmnsn_parse_location;
+
/* Abstract syntax tree node (a dmnsn_array* of these is an AST) */
-typedef struct dmnsn_astnode {
+struct dmnsn_astnode {
dmnsn_astnode_type type;
/* Child nodes */
@@ -180,9 +188,8 @@ typedef struct dmnsn_astnode {
unsigned int *refcount;
/* File name, and line and column numbers from source code */
- const char *filename;
- int line, col;
-} dmnsn_astnode;
+ dmnsn_parse_location location;
+};
typedef dmnsn_array dmnsn_astree;
@@ -241,13 +248,6 @@ dmnsn_astree *dmnsn_parse_string(const char *str, dmnsn_symbol_table *symtable);
/*
* Parser internals
*/
-
-typedef struct dmnsn_parse_location {
- const char *first_filename, *last_filename;
- int first_line, last_line;
- int first_column, last_column;
-} dmnsn_parse_location;
-
typedef union dmnsn_parse_item {
char *value;
dmnsn_astnode astnode;
diff --git a/dimension/realize.c b/dimension/realize.c
index d0b8fa2..b6c6a60 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -31,8 +31,7 @@ dmnsn_realize_integer(dmnsn_astnode astnode)
case DMNSN_AST_INTEGER:
return *(long *)astnode.ptr;
case DMNSN_AST_FLOAT:
- dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col,
- "WARNING: float rounded to integer");
+ dmnsn_diagnostic(astnode.location, "WARNING: float rounded to integer");
return *(double *)astnode.ptr;
default:
@@ -192,8 +191,7 @@ dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene)
switch (item.type) {
case DMNSN_AST_ASSUMED_GAMMA:
- dmnsn_diagnostic(item.filename, item.line, item.col,
- "WARNING: assumed_gamma not supported");
+ dmnsn_diagnostic(item.location, "WARNING: assumed_gamma not supported");
break;
case DMNSN_AST_MAX_TRACE_LEVEL:
@@ -758,7 +756,7 @@ dmnsn_realize_light_source_modifiers(dmnsn_astnode astnode, dmnsn_light *light)
case DMNSN_AST_PIGMENT:
case DMNSN_AST_FINISH:
case DMNSN_AST_INTERIOR:
- dmnsn_diagnostic(modifier.filename, modifier.line, modifier.col,
+ dmnsn_diagnostic(modifier.location,
"WARNING: ignoring %s applied to light source",
dmnsn_astnode_string(modifier.type));
break;
diff --git a/dimension/tokenize.c b/dimension/tokenize.c
index 1fddea3..c821a3c 100644
--- a/dimension/tokenize.c
+++ b/dimension/tokenize.c
@@ -101,9 +101,7 @@ dmnsn_buffer_balanced(dmnsn_token_buffer *tbuffer, bool recursive,
}
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(buffered.lloc.first_filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
return 1;
} else if (buffered.type == DMNSN_T_LEX_ERROR) {
return 1;
@@ -143,9 +141,7 @@ dmnsn_buffer_strexp(dmnsn_token_buffer *tbuffer, bool recursive,
}
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(buffered.lloc.first_filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
return 1;
} else if (buffered.type == DMNSN_T_LEX_ERROR) {
return 1;
@@ -229,9 +225,7 @@ dmnsn_include_buffer(int token, dmnsn_token_buffer *prev,
FILE *file = fopen(local_include, "r");
if (!file) {
- dmnsn_diagnostic(llocp->first_filename, llocp->first_line,
- llocp->first_column,
- "Couldn't open include file '%s'", include);
+ dmnsn_diagnostic(*llocp, "Couldn't open include file '%s'", include);
dmnsn_undef_symbol(symtable, "$include");
free(local_include);
dmnsn_delete_token_buffer(tbuffer);
@@ -241,9 +235,7 @@ dmnsn_include_buffer(int token, dmnsn_token_buffer *prev,
void *buffer = dmnsn_yy_make_buffer(file, yyscanner);
if (!buffer) {
- dmnsn_diagnostic(llocp->first_filename, llocp->first_line,
- llocp->first_column,
- "Couldn't allocate buffer for include file '%s'",
+ dmnsn_diagnostic(*llocp, "Couldn't allocate buffer for include file '%s'",
include);
dmnsn_undef_symbol(symtable, "$include");
fclose(file);
@@ -300,9 +292,7 @@ dmnsn_declaration_buffer(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
} else if (buffered.type == DMNSN_T_LEX_ERROR) {
@@ -357,9 +347,7 @@ dmnsn_undef_buffer(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
} else if (buffered.type == DMNSN_T_LEX_ERROR) {
@@ -441,9 +429,7 @@ dmnsn_if_buffer(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
}
@@ -472,9 +458,7 @@ dmnsn_if_buffer(int token, dmnsn_token_buffer *prev,
if (else_seen
|| (tbuffer->prev && tbuffer->prev->type == DMNSN_T_WHILE))
{
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected #else");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected #else");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
} else {
@@ -518,9 +502,7 @@ dmnsn_while_buffer(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
}
@@ -576,9 +558,7 @@ dmnsn_version_buffer(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return NULL;
} else if (buffered.type == DMNSN_T_LEX_ERROR) {
@@ -688,9 +668,7 @@ dmnsn_declare_macro(int token, dmnsn_token_buffer *prev,
filename, symtable, yyscanner);
if (buffered.type == DMNSN_T_EOF) {
- dmnsn_diagnostic(filename, buffered.lloc.first_line,
- buffered.lloc.first_column,
- "syntax error, unexpected end-of-file");
+ dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file");
dmnsn_delete_token_buffer(tbuffer);
return false;
}
diff --git a/dimension/utility.c b/dimension/utility.c
index 54dd78a..17a7bba 100644
--- a/dimension/utility.c
+++ b/dimension/utility.c
@@ -22,16 +22,24 @@
#include <stdio.h>
void
-dmnsn_diagnostic(const char *filename, int line, int col, const char *format,
- ...)
+dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...)
{
va_list ap;
va_start(ap, format);
- if (line >= 0 && col >= 0) {
- fprintf(stderr, "%s:%d:%d: ", filename, line, col);
+ if (location.first_line >= 0 && location.first_column >= 0) {
+ if (location.first_line != location.last_line) {
+ fprintf(stderr, "%s:%d-%d: ", location.first_filename,
+ location.first_line, location.last_line);
+ } else if (location.first_column != location.last_column - 1) {
+ fprintf(stderr, "%s:%d:%d-%d: ", location.first_filename,
+ location.first_line, location.first_column, location.last_column);
+ } else {
+ fprintf(stderr, "%s:%d:%d: ", location.first_filename,
+ location.first_line, location.first_column);
+ }
} else {
- fprintf(stderr, "%s: ", filename);
+ fprintf(stderr, "%s: ", location.first_filename);
}
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
diff --git a/dimension/utility.h b/dimension/utility.h
index beb818e..15ceadb 100644
--- a/dimension/utility.h
+++ b/dimension/utility.h
@@ -17,6 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
+#ifndef UTILITY_H
+#define UTILITY_H
+
+#include "parse.h" /* For dmnsn_parse_location */
+
#if defined(__GNUC__) || defined(__attribute__)
#define DMNSN_PRINTF_WARN(f, a) __attribute__((format (printf, f, a)))
#else
@@ -24,6 +29,7 @@
#endif
/* Print a parsing diagnostic to stderr */
-void dmnsn_diagnostic(const char *filename, int line, int col,
- const char *format, ...)
- DMNSN_PRINTF_WARN(4, 5);
+void dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...)
+ DMNSN_PRINTF_WARN(2, 3);
+
+#endif /* UTILITY_H */