summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-08-06 06:28:39 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-08-06 06:28:39 -0700
commit7c7d97f53e421e81e631c120559d0f6f11abc060 (patch)
tree4978231c5d1930a1be540a784572a318fd8deca2
parent14054b5ced1bd363b631ec5aade8d87f4a810b48 (diff)
downloadtxr-7c7d97f53e421e81e631c120559d0f6f11abc060.tar.gz
txr-7c7d97f53e421e81e631c120559d0f6f11abc060.tar.bz2
txr-7c7d97f53e421e81e631c120559d0f6f11abc060.zip
Better diagnosis for loose @ forms.
* eval.c (op_meta_error): New static function. (eval_init): Register sys:var and sys:expr as operators that throw error. * parser.y (sym_helper): Take parser_t instead of scanner_t argument so we have access to the name and line number. Obtain scanner internally from parser. Add source location info to (sys:var ...) form. (symhlpr): Retarget macro to pass parser rather than scanner to sm_helper.
-rw-r--r--ChangeLog15
-rw-r--r--eval.c7
-rw-r--r--parser.y9
3 files changed, 27 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 65a5775b..2bac16d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2015-08-06 Kaz Kylheku <kaz@kylheku.com>
+
+ Better diagnosis for loose @ forms.
+
+ * eval.c (op_meta_error): New static function.
+ (eval_init): Register sys:var and sys:expr as operators
+ that throw error.
+
+ * parser.y (sym_helper): Take parser_t instead of scanner_t
+ argument so we have access to the name and line number.
+ Obtain scanner internally from parser. Add source location
+ info to (sys:var ...) form.
+ (symhlpr): Retarget macro to pass parser rather than scanner to
+ sm_helper.
+
2015-08-05 Kaz Kylheku <kaz@kylheku.com>
New filesystem object testing functions.
diff --git a/eval.c b/eval.c
index bb701106..398955f0 100644
--- a/eval.c
+++ b/eval.c
@@ -1163,6 +1163,11 @@ static val op_error(val form, val env)
abort();
}
+static val op_meta_error(val form, val env)
+{
+ eval_error(form, lit("meta with no meaning: ~s"), form, nao);
+}
+
static val op_quote(val form, val env)
{
val d = cdr(form);
@@ -4090,6 +4095,8 @@ void eval_init(void)
with_saved_vars_s = intern(lit("with-saved-vars"), system_package);
reg_op(macrolet_s, op_error);
reg_op(symacrolet_s, op_error);
+ reg_op(var_s, op_meta_error);
+ reg_op(expr_s, op_meta_error);
reg_op(quote_s, op_quote);
reg_op(qquote_s, op_qquote_error);
reg_op(sys_qquote_s, op_qquote_error);
diff --git a/parser.y b/parser.y
index e82e5b7a..f9df9531 100644
--- a/parser.y
+++ b/parser.y
@@ -47,7 +47,7 @@
#include "stream.h"
#include "parser.h"
-static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed);
+static val sym_helper(parser_t *parser, wchar_t *lexeme, val meta_allowed);
static val repeat_rep_helper(val sym, val args, val main, val parts);
static val define_transform(parser_t *parser, val define_form);
static val lit_char_helper(val litchars);
@@ -67,7 +67,7 @@ int yylex(union YYSTYPE *, yyscan_t scanner);
#define rl(form, line) rlrec(parser, form, line)
#define mkexp(sym, rest, lineno) make_expr(parser, sym, rest, lineno)
-#define symhlpr(lexeme, meta_allowed) sym_helper(scnr, lexeme, meta_allowed)
+#define symhlpr(lexeme, meta_allowed) sym_helper(parser, lexeme, meta_allowed)
#define yyerr(msg) yyerror(scnr, parser, msg)
#define yybadtok(tok, context) yybadtoken(parser, tok, context)
@@ -1027,8 +1027,9 @@ int yylex(YYSTYPE *, yyscan_t scanner);
val rlcp(val to, val from);
#endif
-static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed)
+static val sym_helper(parser_t *parser, wchar_t *lexeme, val meta_allowed)
{
+ scanner_t *scnr = parser->scanner;
int leading_at = *lexeme == L'@';
wchar_t *tokfree = lexeme;
wchar_t *colon = wcschr(lexeme, L':');
@@ -1066,7 +1067,7 @@ static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed)
sym = intern(sym_name, package);
- return leading_at ? list(var_s, sym, nao) : sym;
+ return leading_at ? rl(list(var_s, sym, nao), num(parser->lineno)) : sym;
}
static val repeat_rep_helper(val sym, val args, val main, val parts)