summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--parser.l15
-rw-r--r--parser.y41
3 files changed, 54 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 20792a0d..09b4be30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2015-06-26 Kaz Kylheku <kaz@kylheku.com>
+ First round of quasiliteral-related fixes.
+
+ * parser.l: Do not try to recognize floating-point literals
+ in QSPECIAL state; that is not possible because @134.3
+ in a quasiliteral parses as a METANUM followed by ".3".
+ On the other hand, recognize METANUM literals in QSPECIAL state,
+ so that @@123 scans. Recognize @ as a token in QSPECIAL state,
+ so @@abc will scan. When transitioning from QSILIT and QWLIT
+ states to QSPECIAL upon scanning @, return a @ token, which
+ is now parsed in the grammar.
+
+ * parser.y (quasi_meta_helper): New static function.
+ (q_var): Do not handle SYMTOK any more, only the braced
+ variable syntax. SYMTOK is handled as a n_expr.
+ Braced vars are handled with explicit '@' token, which
+ is now produced by the scanner when it shifts from QSILIT
+ to QSPECIAL.
+ (quasi_item): No longer necessary to recognize various
+ forms here such as quotes and splices. Just recognize a n_expr,
+ preceded by '@'.
+
+2015-06-26 Kaz Kylheku <kaz@kylheku.com>
+
* genman.txr: New filter to add hyperlinks within code in
more places such as examples and summary lists.
diff --git a/parser.l b/parser.l
index 9036278f..4a133836 100644
--- a/parser.l
+++ b/parser.l
@@ -269,7 +269,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return NUMBER;
}
-<SPECIAL,QSPECIAL,NESTED,BRACED>{FLO} {
+<SPECIAL,NESTED,BRACED>{FLO} {
val str = string_own(utf8_dup_from(yytext));
if (yy_top_state(yyscanner) == INITIAL
@@ -293,7 +293,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return NUMBER;
}
-<SPECIAL,QSPECIAL>({FLO}|{FLODOT}){TOK} |
+<SPECIAL>({FLO}|{FLODOT}){TOK} |
<BRACED>({FLO}|{FLODOT}){BTOK} |
<NESTED>({FLO}|{FLODOT}){NTOK} {
val str = string_utf8(yytext);
@@ -309,7 +309,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return NUMBER;
}
-<NESTED,QSILIT,QWLIT>@{NUM} {
+<NESTED,QSILIT,QWLIT,QSPECIAL>@{NUM} {
val str = string_own(utf8_dup_from(yytext + 1));
if (yy_top_state(yyscanner) == INITIAL
@@ -320,7 +320,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return METANUM;
}
-<NESTED,QSILIT,QWLIT>@{XNUM} {
+<NESTED,QSILIT,QWLIT,QSPECIAL>@{XNUM} {
val str = string_own(utf8_dup_from(yytext + 3));
if (yy_top_state(yyscanner) == INITIAL
@@ -331,7 +331,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return METANUM;
}
-<NESTED,QSILIT,QWLIT>@{ONUM} {
+<NESTED,QSILIT,QWLIT,QSPECIAL>@{ONUM} {
val str = string_own(utf8_dup_from(yytext + 3));
if (yy_top_state(yyscanner) == INITIAL
@@ -342,7 +342,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return METANUM;
}
-<NESTED,QSILIT,QWLIT>@{BNUM} {
+<NESTED,QSILIT,QWLIT,QSPECIAL>@{BNUM} {
val str = string_own(utf8_dup_from(yytext + 3));
if (yy_top_state(yyscanner) == INITIAL
@@ -558,7 +558,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return yytext[0];
}
-<NESTED,BRACED>@ {
+<NESTED,BRACED,QSPECIAL>@ {
yylval->lineno = yyextra->lineno;
return yytext[0];
}
@@ -897,6 +897,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
<QSILIT,QWLIT>@ {
yy_push_state(QSPECIAL, yyscanner);
+ return yytext[0];
}
<WLIT,QWLIT>{WS} {
diff --git a/parser.y b/parser.y
index 01e7295e..12324f51 100644
--- a/parser.y
+++ b/parser.y
@@ -58,6 +58,7 @@ static val rlrec(parser_t *, val form, val line);
static wchar_t char_from_name(const wchar_t *name);
static val make_expr(parser_t *, val sym, val rest, val lineno);
static val check_for_include(val spec_rev);
+static val quasi_meta_helper(val obj);
#if YYBISON
union YYSTYPE;
@@ -685,12 +686,10 @@ o_var : SYMTOK { $$ = list(var_s, symhlpr($1, nil), nao);
yybadtok(yychar, lit("variable spec")); }
;
-q_var : SYMTOK { $$ = list(var_s, symhlpr($1, nil), nao);
+q_var : '@' '{' n_expr n_exprs_opt '}'
+ { $$ = list(var_s, $3, $4, nao);
rl($$, num(parser->lineno)); }
- | '{' n_expr n_exprs_opt '}'
- { $$ = list(var_s, $2, $3, nao);
- rl($$, num(parser->lineno)); }
- | SYMTOK error { $$ = nil;
+ | '@' '{' error { $$ = nil;
yybadtok(yychar, lit("variable spec")); }
;
@@ -959,19 +958,7 @@ quasi_item : litchars { $$ = lit_char_helper($1); }
| q_var { $$ = $1; }
| METANUM { $$ = cons(var_s, cons($1, nil));
rl($$, num(parser->lineno)); }
- | list { $$ = rlcp(cons(expr_s, $1), $1); }
- | '\'' n_expr { $$ = rl(rlcp(cons(expr_s, list(quote_s, $2, nao)), $2),
- num(parser->lineno));
- rlcp_tree($$, $$); }
- | '^' n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_qquote_s, $2, nao)), $2),
- num(parser->lineno));
- rlcp_tree($$, $$); }
- | ',' n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_unquote_s, $2, nao)), $2),
- num(parser->lineno));
- rlcp_tree($$, $$); }
- | SPLICE n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_splice_s, $2, nao)), $2),
- num(parser->lineno));
- rlcp_tree($$, $$); }
+ | '@' n_expr { $$ = quasi_meta_helper($2); }
;
litchars : LITCHAR { $$ = rl(cons(chr($1), nil), num(parser->lineno)); }
@@ -1357,6 +1344,24 @@ static val check_for_include(val spec_rev)
return spec_rev;
}
+static val quasi_meta_helper(val obj)
+{
+ if (integerp(obj) || symbolp(obj))
+ goto var;
+
+ if (atom(obj) || length(obj) != two)
+ goto expr;
+
+ if (first(obj) == var_s && integerp(second(obj)))
+ goto var;
+
+var:
+ return rlcp_tree(cons(var_s, cons(obj, nil)), obj);
+
+expr:
+ return rlcp(cons(expr_s, obj), obj);
+}
+
#ifndef YYEOF
#define YYEOF 0
#endif