The unified diff between revisions [6726c07e..] and [9a6e8df1..] is displayed below. It can also be downloaded as a raw diff.

#
# old_revision [6726c07e4874e76763555e1476ce427743e8f73c]
# new_revision [9a6e8df1d6b102f467702e274d53d90f9151e2c8]
#
# patch "src/lsc/ast.c"
#  from [38b009ee4723c4e585350f483aa20ae113304362]
#    to [38d7a1613ebd1088ccb91c4fc2c7c711467cdd57]
# 
# patch "src/lsc/codegen.c"
#  from [eadf986764263a936e4e1daa589e245ccee66212]
#    to [3f17dcc09e552288f4a68b0ac58692cffd524364]
# 
# patch "src/lsc/types.h"
#  from [1c9dcb3d7c1e6ed48b67fc9d367610ebd8ad8ef0]
#    to [0934f3373a49335fb48fc8fb0d9be2350c843533]
#
============================================================
--- src/lsc/ast.c	38b009ee4723c4e585350f483aa20ae113304362
+++ src/lsc/ast.c	38d7a1613ebd1088ccb91c4fc2c7c711467cdd57
@@ -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 = 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, lon
 	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, lon
 	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,
 	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 *e
 	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, a
 	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 *identifie
 	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 *ex
 	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 *exp
 	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_lis
 	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 *
 	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 *
 
 	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;
 }
============================================================
--- src/lsc/codegen.c	eadf986764263a936e4e1daa589e245ccee66212
+++ src/lsc/codegen.c	3f17dcc09e552288f4a68b0ac58692cffd524364
@@ -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 constant_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 *constanthash[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)
============================================================
--- src/lsc/types.h	1c9dcb3d7c1e6ed48b67fc9d367610ebd8ad8ef0
+++ src/lsc/types.h	0934f3373a49335fb48fc8fb0d9be2350c843533
@@ -29,6 +29,7 @@ typedef struct ast {
 			struct ast_list*	head;
 		} node;
 	} info;
+	int lineno;
 } ast;
 
 typedef struct ast_list {