summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog32
-rw-r--r--genvim.txr7
-rw-r--r--lib.c12
-rw-r--r--parser.l21
-rw-r--r--parser.y24
-rw-r--r--tests/009/json.txr4
-rw-r--r--tests/010/reghash.txr2
-rw-r--r--tests/011/macros-2.txr2
-rw-r--r--tests/011/mandel.txr10
-rw-r--r--tests/011/special-1.txr2
-rw-r--r--txr.1155
-rw-r--r--txr.vim211
12 files changed, 257 insertions, 225 deletions
diff --git a/ChangeLog b/ChangeLog
index bbc66d65..588d2f6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2014-03-03 Kaz Kylheku <kaz@kylheku.com>
+
+ * parser.l: Allowing ^ to be a quote character, and adjusting definition
+ of identifiers to rule this out from being the first character of a
+ symbol which has no prefix. Recognize the ^ character as a token in the
+ NESTED state.
+
+ * lib.c (obj_print, obj_pprint): Render sys:qquote as ^.
+
+ * parser.y (choose_quote): Function removed.
+ (n_expr): Recognize '^' as quasiquote. Removed all the "smart quote"
+ hacks that try to make quote behave as quote or quasiquote, or try to
+ cancel out unquotes and quotes.
+
+ * tests/009/json.txr: Fixed to ^ quasiquote.
+
+ * tests/010/reghash.txr: Likewise.
+
+ * tests/011/macros-2.txr: Likewise.
+
+ * tests/011/mandel.txr: Likewise.
+
+ * tests/011/special-1.txr: Likewise.
+
+ * txr.1: Updated docs.
+
+ * genvim.txr: Revamped definitions for txr_ident and txl_ident so that
+ unqualified identifiers cannot start with # or ^, but ones with @ or :
+ in front can start with these characters.
+
+ * txr.vim: Regenerated.
+
2014-03-02 Kaz Kylheku <kaz@kylheku.com>
* Makefile (lex.yy.c): Remove lex.yy.c before trying to regenerate it.
diff --git a/genvim.txr b/genvim.txr
index bbd9bcc0..00d3506e 100644
--- a/genvim.txr
+++ b/genvim.txr
@@ -92,8 +92,10 @@ syn match txr_num "#x[+\-]\?[0-9A-Fa-f]\+" contained
syn match txr_num "#o[+\-]\?[0-7]\+" contained
syn match txr_num "#b[+\-]\?[0-1]\+" contained
syn match txr_num "[+\-]\?[0-9]\+" contained
-syn match txr_ident "[:@@]\?[A-Za-z0-9!$%&*+\-<=>?\\^_~]*[A-Za-z!$%&*+\-<=>?\\^_~][A-Za-z0-9!$%&*+\-<=>?\\^_~]*" contained
-syn match txl_ident "[:@@]\?[A-Za-z0-9!$%&*+\-<=>?\\^_~/]*[A-Za-z!$%&*+\-<=>?\\^_~/][A-Za-z0-9!$%&*+\-<=>?\\^_~/]*" contained
+syn match txr_ident "[:@@][A-Za-z0-9!#$%&*+\-<=>?\\^_~]\+" contained
+syn match txr_ident "[A-Za-z0-9!$%&*+\-<=>?\\_~]*[A-Za-z!$#%&*+\-<=>?\\^_~][A-Za-z0-9!$#%&*+\-<=>?\\^_~]*" contained
+syn match txl_ident "[:@@][A-Za-z0-9!$%&*+\-<=>?\\\^_~/]\+" contained
+syn match txl_ident "[A-Za-z0-9!$%&*+\-<=>?\\_~/]*[A-Za-z!$#%&*+\-<=>?\\^_~/][A-Za-z0-9!$#%&*+\-<=>?\\^_~/]*" contained
syn match txr_num "[+\-]\?[0-9]*[.][0-9]\+\([eE][+\-]\?[0-9]\+\)\?" contained
syn match txr_num "[+\-]\?[0-9]\+\([eE][+\-]\?[0-9]\+\)" contained
syn match txl_ident ":" contained
@@ -101,6 +103,7 @@ syn match txl_ident ":" contained
syn match txr_unquote "," contained
syn match txr_splice ",\*" contained
syn match txr_quote "'" contained
+syn match txr_quote "\^" contained
syn match txr_dotdot "\.\." contained
syn match txr_metaat "@@" contained
diff --git a/lib.c b/lib.c
index 04c550fa..d28d16d7 100644
--- a/lib.c
+++ b/lib.c
@@ -5233,9 +5233,12 @@ val obj_print(val obj, val out)
{
val sym = car(obj);
- if (sym == quote_s || sym == sys_qquote_s) {
+ if (sym == quote_s) {
put_char(chr('\''), out);
obj_print(second(obj), out);
+ } else if (sym == sys_qquote_s) {
+ put_char(chr('^'), out);
+ obj_print(second(obj), out);
} else if (sym == sys_unquote_s) {
put_char(chr(','), out);
obj_print(second(obj), out);
@@ -5419,9 +5422,12 @@ val obj_pprint(val obj, val out)
{
val sym = car(obj);
- if (sym == quote_s || sym == sys_qquote_s) {
+ if (sym == quote_s) {
put_char(chr('\''), out);
- obj_pprint(second(obj), out);
+ obj_print(second(obj), out);
+ } else if (sym == sys_qquote_s) {
+ put_char(chr('^'), out);
+ obj_print(second(obj), out);
} else if (sym == sys_unquote_s) {
put_char(chr(','), out);
obj_pprint(second(obj), out);
diff --git a/parser.l b/parser.l
index ba907888..1d2d5525 100644
--- a/parser.l
+++ b/parser.l
@@ -158,19 +158,20 @@ FLODOT {SGN}?{DIG}+[.]
XNUM #x{SGN}?{XDIG}+
ONUM #o{SGN}?[0-7]+
BNUM #b{SGN}?[0-1]+
-BSCHR [a-zA-Z0-9!$%&*+\-<=>?\\^_~]
-NSCHR [a-zA-Z0-9!$%&*+\-<=>?\\^_~/]
-ID_END [^a-zA-Z0-9!$%&*+\-<=>?\\^_~/]
+BSCHR [a-zA-Z0-9!$%&*+\-<=>?\\_~]
+NSCHR [a-zA-Z0-9!$%&*+\-<=>?\\_~/]
+ID_END [^a-zA-Z0-9!$%&*+\-<=>?\\_~/]
+EXTRA [#^]
TOK {SYM}
-BT0 {BSCHR}({BSCHR}|#)*
-BT1 @({BSCHR}|#)+
-BT2 ({BSCHR}|#)+
+BT0 {BSCHR}({BSCHR}|{EXTRA})*
+BT1 @({BSCHR}|{EXTRA})+
+BT2 ({BSCHR}|{EXTRA})+
BTREG (({BT0}|{BT1})?:{BT2}|({BT0}|{BT1})(:{BT2})?|:)
BTKEY @?:{BT2}?
BTOK {BTREG}|{BTKEY}
-NT0 {NSCHR}({NSCHR}|#)*
-NT1 @({NSCHR}|#)+
-NT2 ({NSCHR}|#)+
+NT0 {NSCHR}({NSCHR}|{EXTRA})*
+NT1 @({NSCHR}|{EXTRA})+
+NT2 ({NSCHR}|{EXTRA})+
NTREG (({NT0}|{NT1})?:{NT2}|({NT0}|{NT1})(:{NT2})?|:)
NTKEY @?:{NT2}?
NTOK {NTREG}|{NTKEY}
@@ -510,7 +511,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return SPLICE;
}
-<NESTED>[,'] {
+<NESTED>[,'^] {
yylval.chr = yytext[0];
return yytext[0];
}
diff --git a/parser.y b/parser.y
index 67409d4b..5b2775ad 100644
--- a/parser.y
+++ b/parser.y
@@ -55,7 +55,6 @@ static val define_transform(val define_form);
static val lit_char_helper(val litchars);
static val optimize_text(val text_form);
static val unquotes_occur(val quoted_form, int level);
-static val choose_quote(val quoted_form);
static val expand_meta(val form, val menv);
static wchar_t char_from_name(const wchar_t *name);
@@ -107,7 +106,7 @@ static val parsed_spec;
%right OUTPUT REPEAT REP FIRST LAST EMPTY DEFINE
%right SPACE TEXT NUMBER
%nonassoc '[' ']' '(' ')'
-%left '-' ',' '\'' SPLICE '@'
+%left '-' ',' '\'' '^' SPLICE '@'
%left '|' '/'
%left '&'
%right '~' '*' '?' '+' '%'
@@ -753,18 +752,10 @@ n_expr : SYMTOK { $$ = sym_helper($1, t); }
| chrlit { $$ = $1; }
| strlit { $$ = $1; }
| quasilit { $$ = $1; }
- | ',' n_expr { val expr = $2;
- if (consp(expr) && car(expr) == sys_qquote_s)
- expr = cons(quote_s, rest(expr));
- $$ = rlcp(list(sys_unquote_s, expr, nao),
- $2); }
- | '\'' n_expr { $$ = rlcp(list(choose_quote($2),
- $2, nao), $2); }
- | SPLICE n_expr { val expr = $2;
- if (consp(expr) && car(expr) == sys_qquote_s)
- expr = cons(quote_s, rest(expr));
- $$ = rlcp(list(sys_splice_s, expr, nao),
- $2); }
+ | '\'' n_expr { $$ = rlcp(list(quote_s, $2, nao), $2); }
+ | '^' n_expr { $$ = rlcp(list(sys_qquote_s, $2, nao), $2); }
+ | ',' n_expr { $$ = rlcp(list(sys_unquote_s, $2, nao), $2); }
+ | SPLICE n_expr { $$ = rlcp(list(sys_splice_s, $2, nao), $2); }
;
regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex();
@@ -1123,11 +1114,6 @@ static val unquotes_occur(val quoted_form, int level)
}
}
-static val choose_quote(val quoted_form)
-{
- return unquotes_occur(quoted_form, 0) ? sys_qquote_s : quote_s;
-}
-
static val expand_meta(val form, val menv)
{
val sym;
diff --git a/tests/009/json.txr b/tests/009/json.txr
index 4350207e..e450b6bb 100644
--- a/tests/009/json.txr
+++ b/tests/009/json.txr
@@ -66,7 +66,7 @@
@(bind pair (p e))@\
@(until)}@\
@(end)}@(ws)@\
- @(bind v @(progn '#H((:equal-based) ,*pair)))@\
+ @(bind v @(progn ^#H((:equal-based) ,*pair)))@\
@(end)
@;
@; Recognize an array.
@@ -74,7 +74,7 @@
@(define array (v))@\
@(local e)@\
@(ws)[@(ws)@(coll :gap 0 :vars (e))@(value e)@/,?/@(until)]@(end)]@(ws)@\
- @(bind v @(progn '#(,*e)))@\
+ @(bind v @(progn ^#(,*e)))@\
@(end)
@;
@; Now parse the input as a JSON object
diff --git a/tests/010/reghash.txr b/tests/010/reghash.txr
index 6de73a48..178f34ee 100644
--- a/tests/010/reghash.txr
+++ b/tests/010/reghash.txr
@@ -1,4 +1,4 @@
-@(bind result @(let ((table '#H((:equal-based)
+@(bind result @(let ((table ^#H((:equal-based)
,(list "$dim" "length") ("$object" "plank")
("$value" "100") ("$units" "cm"))))
(regsub #/$[a-z]+/ (op table)
diff --git a/tests/011/macros-2.txr b/tests/011/macros-2.txr
index 0d63a13b..be385c6f 100644
--- a/tests/011/macros-2.txr
+++ b/tests/011/macros-2.txr
@@ -2,7 +2,7 @@
(defmacro while ((condition : result) . body)
(let ((cblk (gensym "cnt-blk-"))
(bblk (gensym "brk-blk-")))
- '(macrolet ((break (value) '(return-from ,',bblk ,value)))
+ ^(macrolet ((break (value) ^(return-from ,',bblk ,value)))
(symacrolet ((break (return-from ,bblk))
(continue (return-from ,cblk)))
(block ,bblk
diff --git a/tests/011/mandel.txr b/tests/011/mandel.txr
index 84200ffa..15195f33 100644
--- a/tests/011/mandel.txr
+++ b/tests/011/mandel.txr
@@ -13,9 +13,9 @@
(defvar y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1))))
;; complex number library
- (defmacro cplx (x y) '(cons ,x ,y))
- (defmacro re (c) '(car ,c))
- (defmacro im (c) '(cdr ,c))
+ (defmacro cplx (x y) ^(cons ,x ,y))
+ (defmacro re (c) ^(car ,c))
+ (defmacro im (c) ^(cdr ,c))
(defsymacro c0 (macro-time (cplx 0 0)))
@@ -23,9 +23,9 @@
(defun with-cplx-expand (specs body)
(tree-case specs
(((re im expr) . rest)
- '(tree-bind (,re . ,im) ,expr ,(with-cplx-expand rest body)))
+ ^(tree-bind (,re . ,im) ,expr ,(with-cplx-expand rest body)))
(() (tree-case body
- ((a b . rest) '(progn ,a ,b ,*rest))
+ ((a b . rest) ^(progn ,a ,b ,*rest))
((a) a)
(x (error "with-cplx: invalid body ~s" body))))
(x (error "with-cplx: bad args ~s" x)))))
diff --git a/tests/011/special-1.txr b/tests/011/special-1.txr
index 72ab844a..f3e92a03 100644
--- a/tests/011/special-1.txr
+++ b/tests/011/special-1.txr
@@ -1,6 +1,6 @@
@(do
(defmacro with-output-to-string ((var) . forms)
- '(let ((,var (make-string-output-stream)))
+ ^(let ((,var (make-string-output-stream)))
(progn ,*forms (get-string-from-stream ,var))))
(let ((x (with-output-to-string (*stdout*)
diff --git a/txr.1 b/txr.1
index 8fa6c836..22f99f62 100644
--- a/txr.1
+++ b/txr.1
@@ -4873,66 +4873,68 @@ In no other circumstances is nil printed as (), or a symbol as (. sym).
symbol is followed by a symbol.
-.SS Quoting/Unquoting
+.SS Quote and Quasiquote
-.IP 'form
+.IP '<expr>
-The quote character in front of a form is used for suppressing evaluation,
+The quote character in front of an expression is used for suppressing evaluation,
which is useful for forms that evaluate to something other than themselves.
For instance if '(+ 2 2) is evaluated, the value is the three-element list
(+ 2 2), wheras if (+ 2 2) is evaluated, the value is 4. Similarly, the
value of 'a is the symbol a itself, whereas the value of a is the value
of the variable a.
-Note that TXR Lisp does not have a distinct quote and backquote read syntax.
-There is only one quote, which supports unquoting. However, this is true
-only of the read syntax. There is a quote special operator, and
-a qquote macro. The quote read syntax translates either to the quote
-operator, or to an inernal version of qquote.
+.IP ^<qq-template>
-A quoted form which contains no unquotes codifies an ordinary quote.
+The caret in front of an expression is a quasiquote. A quasiquote is like
+a quote, but with the possibility of substitution of material.
-A quoted form which contains unquotes expresses a quasiquote. (This should not
-be confused with a string quasiliteral, although it is a related concept.)
+Under a quasiquote, form is considered to be a quasiquote template. The template
+is considered to be a literal structure, except that it may contain
+the notations ,<expr> and ,*<expr> which denote non-constant parts.
-.IP ,form
+A quasiquote gets translated into code which, when evaluated, constructs
+the structure implied by <qq-template>, taking into account the unquotes
+and splices.
-The comma character is used within a quoted list to denote an unquote. Wheras
+A quasiquote also processes nested quasiquotes specially.
+
+If <qq-template> does not contain any unquotes or splices (which match its
+level of nesting), or is simply an atom, then ^<qq-template> is equivalent to
+'<qq-template>: in other words, it is like an ordinary quote. For instance ^(a
+b ^(c ,d)) is equivalent to '(a b ^(c ,d)). Although there is an unquote ,d it
+belongs to the inner quasiquote ^(c ,d), and the outer quasiquote does not have
+any unquotes of its own, making it equivalent to a quote.
+
+Dialect note: in Common Lisp and Scheme, ^form is written `form, and
+quasiquotes are also informally known as backquotes. In TXR, the backquote is
+used for quasi string literals already. Moreover, the caret is more visually
+distinct from the backquote, making it somewhat easier to tell apart generated
+code from its surroundings.
+
+.IP ,<expr>
+
+The comma character is used within a <qq-template> to denote an unquote. Whereas
the quote suppresses evaluation, the comma introduces an exception: an element
-of a form which is evaluated. For example, list '(a b c ,(+ 2 2)
+of a form which is evaluated. For example, list ^(a b c ,(+ 2 2)
(+ 2 2)) is the list (a b c 4 (+ 2 2)). Everything
-in the quote stands for itself, except for the ,(+ 2 2) which is evaluated.
-The presence of ,(+ 2 2) in the quoted list turns it into a quasiquote.
-
-.IP ,*form
-
-The comma-star operator is used within a quoted list to denote a splicing unquote.
-Wheras the quote suppresses evaluation, the comma introduces an exception:
-the form which follows ,* must evaluate to a list. That list is spliced into
-the quoted list. For example: '(a b c ,*(list (+ 3 3) (+ 4 4) d)) evaluates
-to (a b c 6 8 d). The expression (list (+ 3 3) (+ 4 4)) is evaluated
-to produce the list (6 8), and this list is spliced into the quoted template.
-
-.IP ,'form
-
-The comma-quote combination has a special meaning: the quote always
-behaves as a regular quote and not a quasiquote, even if form contains
-unquotes. Therefore, it does not "capture" these unquotes: they cannot
-"belong" to this quote. The comma and quote "cancel out", so the only effect
-of comma-quote is to add one level of unquoting. So for instance, whereas
-in '(a b c '(,d)), the subsitution of d belongs to the inner quote (it is
-unquoted by the leftmost comma which belongs to the innermost quote) by
-contrast, in '(a b c '(,',d)) the d is now one comma removed from the leftmost
-comma and thus the substitution of d belongs to the outer quote.
-In other dialects of Lisp, this would be written `(a b c `(,',d)), making it
-explicit which kind of quote is being specified. TXR Lisp works out which
-kind of quote to use internally.
-
-.IP ,*'form
-
-The comma-splice form is analogous to comma-quote (see above). Like in the
-,' combination, in the ,*' combination, the quote behaves as a regular quote
-and not a quasiquote.
+in the quasiquote stands for itself, except for the ,(+ 2 2) which is evaluated.
+
+Note: if a variable is called *x*, then the syntax ,*x* means ,* x*: splice
+the value of x*. In this situation, whitespace between the comma and the
+variable name should be used: , *x*.
+
+.IP ,*<expr>
+
+The comma-star operator is used within quasiquote list to denote a splicing unquote.
+The form which follows ,* must evaluate to a list. That list is spliced into
+the structure which the quasiquote denotes. For example: '(a b c ,*(list
+(+ 3 3) (+ 4 4) d)) evaluates to (a b c 6 8 d). The expression (list (+ 3 3)
+(+ 4 4)) is evaluated to produce the list (6 8), and this list is spliced into
+the quoted template.
+
+Dialect note: in other Lisp dialects, the equivalent syntax is usually ,@
+(comma at). The @ character already has an assigned meaning, so * is used.
.SS Quasiquoting non-List Objects
@@ -4940,19 +4942,31 @@ Quasiquoting is supported over hash table and vector literals (see Vectors
and Hashes below). A hash table or vector literal can be quoted, like any
object, for instance:
- '#(1 2 3) ; value is #(1 2 3)
+ '#(1 2 3)
-If unquotes occur in the vector, it is a quasivector.
+The #(1 2 3) literal is turned into a vector atom right in the TXR parser,
+and this atom is being quoted: this is (quote <atom>) syntactically,
+which evaluates to <atom>.
+
+When a vector is quasi-quoted, this is a case of ^<atom>, which
+evaluates to <atom>.
+
+ ^#(1 2 3)
+
+If unquotes occur in the quasi-quoted vector, it is a quasivector.
(let ((a 42))
- '#(1 ,a 3)) ; value is #(1 42 3)
+ ^#(1 ,a 3)) ; value is #(1 42 3)
+
+In this situation, the ^#(...) notation produces code which constructs
+a vector.
The vector in the following example is also a quasivector. It contains
unquotes, and is though the quote is not directly applied to it,
it is surrounded in a quote.
(let ((a 42))
- '(a b c #(d ,a))) ; value is (a b c #(d 42))
+ ^(a b c #(d ,a))) ; value is (a b c #(d 42))
Hash table literals have two parts: the list of hash construction
arguments and the key-value pairs. For instance:
@@ -4960,20 +4974,20 @@ arguments and the key-value pairs. For instance:
#H((:equal-based) (a 1) (b 2))
where (:equal-based) is the list of arguments and the pairs are (a 1) and (b
-2). In quasiquoting, the arguments and pairs are treated as separate syntax;
-it is not one big list. So the following is not a possible way
-to express the above hash:
+2). Hash literals may be quasiquoted. In quasiquoting, the arguments and pairs
+are treated as separate syntax; it is not one big list. So the following is
+not a possible way to express the above hash:
;; not supported: splicing across the entire syntax
(let ((hash-syntax '((:equal-based) (a 1) (b 2))))
- '#H(,*hash-syntax))
+ ^#H(,*hash-syntax))
This is correct:
;; fine: splicing hash arguments and contents separatly
(let ((hash-args '(:equal-based))
(hash-contents '((a 1) (b 2))))
- '#H(,hash-args ,*hash-contents))
+ ^#H(,hash-args ,*hash-contents))
.SS Vectors
@@ -4993,19 +5007,6 @@ a hash table. Allowed keywords are: :equal-based, :weak-keys, :weak-values.
An empty list can be specified as nil or (), which defaults to a
hash table basd on the eq function, with no weak semantics.
-.SS Nested Quotes
-
-Quotes can be nested. What if it is necessary to unquote something in the
-nested list? The following will not work in TXR Lisp like it does in
-Common Lisp or Scheme: '(1 2 3 '(4 5 6 ,(+ 1 2))). This is because the quote
-is also "active" as a quasiquote, and so the ,(+ 1 2) belongs to the inner
-quote, which protects it from evaluation. To get the (+ 1 2) value "through"
-to the inner quote, the unquote syntax must also be nested using multiple
-commas, like this: '(1 2 3 '(4 5 6 ,',(+ 1 2))). The leftmost comma goes
-with the innermost quote. The quote between the commas protects the (+ 1 2)
-from repeated evaluations: the two unquotes call for two evaluations, but
-we only want (+ 1 2) to be evaluated once.
-
.SS The .. notation
In TXR Lisp, there is a special "dotdot" notation consiting of a pair of dots.
@@ -8077,7 +8078,7 @@ an instance of the gen operator, like this:
(defmacro gun (expr)
(let ((var (gensym)))
- '(let (,var)
+ ^(let (,var)
(gen (set ,var ,expr)
,var))))
@@ -8090,7 +8091,7 @@ In turn, gen can be implemented as a macro expanding to some lambda
functions which are passed to the generate function:
(defmacro gen (while-expr produce-expr)
- '(generate (lambda () ,while-expr) (lambda () ,produce-expr)))
+ ^(generate (lambda () ,while-expr) (lambda () ,produce-expr)))
Note 2: GEN can be considered as an acronym for Generate, testing Expression
before Next item, whereas GUN stands for Generate Until Null.
@@ -13131,9 +13132,9 @@ Dialect note:
In Lisp dialects which have a published syntax, there is the expectation
that the quasiquote read syntax corresponds to it. That is to say, that
-for instance 1(a b ,c) is translated to (qquote b (unquote c)).
+for instance ^(a b ,c) is translated to (qquote b (unquote c)).
-In TXR Lisp, this is not true! Although '(b b ,c) is translated to a
+In TXR Lisp, this is not true! Although ^(b b ,c) is translated to a
quasiquoting macro, it is an internal one, not based on the public qquote,
unquote and splice symbols.
@@ -13144,9 +13145,9 @@ since it doesn't treat them specially.
This also allows programmers to use the quasiquote read syntax to construct
quasiquote macros. For instance
- '(qquote (unquote ,x))
+ ^(qquote (unquote ,x))
-does not mean '',x. To the quasiquote reader, the qquote and unquote symbols
+does not mean ^^,x. To the quasiquote reader, the qquote and unquote symbols
mean nothing special, and so this syntax simply means that if the value of x is
foo, the result will be (qquote (unquote foo)).
@@ -13334,7 +13335,7 @@ Examples:
(defmacro swap (a b)
(let ((temp (gensym)))
- '(let ((,temp ,a))
+ ^(let ((,temp ,a))
(set ,a ,b)
(set ,b ,temp))))
@@ -13349,7 +13350,7 @@ Examples:
(defmacro dolist ((var list : result) . body)
(let ((i (my-gensym)))
- '(for ((i ,list)) (i ,result) ((set i (cdr i)))
+ ^(for ((i ,list)) (i ,result) ((set i (cdr i)))
(let ((,var (car i)))
,*body))))
@@ -13609,7 +13610,7 @@ Example:
(tree-case obj
(() ()) ;; the empty list is just returned
((a) obj) ;; one-element list just returned (unnecessary case)
- ((a . b) '(,*(tb-reverse b) ,a)) ;; car/cdr recursion
+ ((a . b) ^(,*(tb-reverse b) ,a)) ;; car/cdr recursion
(a a))) ;; atom is just returned
Note that in this example, the atom case is placed last, because an
diff --git a/txr.vim b/txr.vim
index 0ac68a63..22f67e6b 100644
--- a/txr.vim
+++ b/txr.vim
@@ -62,108 +62,108 @@ syn keyword txl_keyword contained daemon dec defmacro defsymacro
syn keyword txl_keyword contained defun defvar del delay
syn keyword txl_keyword contained delete-package do dohash downcase-str
syn keyword txl_keyword contained dwim each each* env
-syn keyword txl_keyword contained env-hash eq eql equal
-syn keyword txl_keyword contained errno error eval evenp
-syn keyword txl_keyword contained exit exp expt exptmod
-syn keyword txl_keyword contained fboundp fifth find find-if
-syn keyword txl_keyword contained find-package first fixnump flatten
-syn keyword txl_keyword contained flatten* flip flo-int flo-str
-syn keyword txl_keyword contained floatp floor flush-stream for
-syn keyword txl_keyword contained for* force format fourth
-syn keyword txl_keyword contained fun func-get-env func-get-form func-set-env
-syn keyword txl_keyword contained functionp gcd gen generate
-syn keyword txl_keyword contained gensym get-byte get-char get-hash-userdata
-syn keyword txl_keyword contained get-line get-list-from-stream get-sig-handler get-string-from-stream
-syn keyword txl_keyword contained gethash group-by gun hash
-syn keyword txl_keyword contained hash-alist hash-construct hash-count hash-diff
-syn keyword txl_keyword contained hash-eql hash-equal hash-isec hash-keys
-syn keyword txl_keyword contained hash-pairs hash-uni hash-update hash-update-1
-syn keyword txl_keyword contained hash-values hashp identity if
-syn keyword txl_keyword contained iff iffi inc inhash
-syn keyword txl_keyword contained int-flo int-str integerp intern
-syn keyword txl_keyword contained interp-fun-p isqrt keep-if keep-if*
-syn keyword txl_keyword contained keywordp lambda lazy-str lazy-str-force
-syn keyword txl_keyword contained lazy-str-force-upto lazy-str-get-trailing-list lazy-stream-cons lazy-stringp
-syn keyword txl_keyword contained lcons-fun ldiff length length-list
-syn keyword txl_keyword contained length-str length-str-< length-str-<= length-str->
-syn keyword txl_keyword contained length-str->= length-vec let let*
-syn keyword txl_keyword contained link lisp-parse list list*
-syn keyword txl_keyword contained list-str list-vector listp log
-syn keyword txl_keyword contained log-alert log-auth log-authpriv log-cons
-syn keyword txl_keyword contained log-crit log-daemon log-debug log-emerg
-syn keyword txl_keyword contained log-err log-info log-ndelay log-notice
-syn keyword txl_keyword contained log-nowait log-odelay log-perror log-pid
-syn keyword txl_keyword contained log-user log-warning logand logior
-syn keyword txl_keyword contained lognot logtest logtrunc logxor
-syn keyword txl_keyword contained macro-form-p macro-time macroexpand macroexpand-1
-syn keyword txl_keyword contained macrolet major make-catenated-stream make-hash
-syn keyword txl_keyword contained make-lazy-cons make-package make-random-state make-similar-hash
-syn keyword txl_keyword contained make-string-byte-input-stream make-string-input-stream make-string-output-stream make-strlist-output-stream
-syn keyword txl_keyword contained make-sym make-time make-time-utc makedev
-syn keyword txl_keyword contained mapcar mapcar* maphash mappend
-syn keyword txl_keyword contained mappend* mask match-fun match-regex
-syn keyword txl_keyword contained match-regex-right match-str match-str-tree max
-syn keyword txl_keyword contained memq memql memqual merge
-syn keyword txl_keyword contained min minor mkdir mknod
-syn keyword txl_keyword contained mkstring mod multi-sort n-choose-k
-syn keyword txl_keyword contained n-perm-k none not nreverse
-syn keyword txl_keyword contained null num-chr num-str numberp
-syn keyword txl_keyword contained oddp op open-command open-directory
-syn keyword txl_keyword contained open-file open-pipe open-process open-tail
-syn keyword txl_keyword contained openlog or orf packagep
-syn keyword txl_keyword contained perm pop pos pos-if
-syn keyword txl_keyword contained posq posql posqual pprinl
-syn keyword txl_keyword contained pprint prinl print prog1
-syn keyword txl_keyword contained progn prop proper-listp push
-syn keyword txl_keyword contained pushhash put-byte put-char put-line
-syn keyword txl_keyword contained put-string pwd qquote quasi
-syn keyword txl_keyword contained quote rand random random-fixnum
-syn keyword txl_keyword contained random-state-p range range* rcomb
-syn keyword txl_keyword contained read readlink real-time-stream-p reduce-left
-syn keyword txl_keyword contained reduce-right ref refset regex-compile
-syn keyword txl_keyword contained regex-parse regexp regsub rehome-sym
-syn keyword txl_keyword contained remhash remove-if remove-if* remove-path
-syn keyword txl_keyword contained remq remq* remql remql*
-syn keyword txl_keyword contained remqual remqual* rename-path repeat
-syn keyword txl_keyword contained replace replace-list replace-str replace-vec
-syn keyword txl_keyword contained rest return return-from reverse
-syn keyword txl_keyword contained rlcp rperm rplaca rplacd
-syn keyword txl_keyword contained s-ifblk s-ifchr s-ifdir s-ififo
-syn keyword txl_keyword contained s-iflnk s-ifmt s-ifreg s-ifsock
-syn keyword txl_keyword contained s-irgrp s-iroth s-irusr s-irwxg
-syn keyword txl_keyword contained s-irwxo s-irwxu s-isgid s-isuid
-syn keyword txl_keyword contained s-isvtx s-iwgrp s-iwoth s-iwusr
-syn keyword txl_keyword contained s-ixgrp s-ixoth s-ixusr search-regex
-syn keyword txl_keyword contained search-str search-str-tree second seek-stream
-syn keyword txl_keyword contained set set-diff set-hash-userdata set-sig-handler
-syn keyword txl_keyword contained sethash setlogmask sig-abrt sig-alrm
-syn keyword txl_keyword contained sig-bus sig-check sig-chld sig-cont
-syn keyword txl_keyword contained sig-fpe sig-hup sig-ill sig-int
-syn keyword txl_keyword contained sig-io sig-iot sig-kill sig-lost
-syn keyword txl_keyword contained sig-pipe sig-poll sig-prof sig-pwr
-syn keyword txl_keyword contained sig-quit sig-segv sig-stkflt sig-stop
-syn keyword txl_keyword contained sig-sys sig-term sig-trap sig-tstp
-syn keyword txl_keyword contained sig-ttin sig-ttou sig-urg sig-usr1
-syn keyword txl_keyword contained sig-usr2 sig-vtalrm sig-winch sig-xcpu
-syn keyword txl_keyword contained sig-xfsz sin sixth size-vec
-syn keyword txl_keyword contained some sort source-loc source-loc-str
-syn keyword txl_keyword contained span-str splice split-str split-str-set
-syn keyword txl_keyword contained sqrt stat stream-get-prop stream-set-prop
-syn keyword txl_keyword contained streamp string-cmp string-extend string-lt
-syn keyword txl_keyword contained stringp sub sub-list sub-str
-syn keyword txl_keyword contained sub-vec symacrolet symbol-function symbol-name
-syn keyword txl_keyword contained symbol-package symbol-value symbolp symlink
-syn keyword txl_keyword contained sys-qquote sys-splice sys-unquote syslog
-syn keyword txl_keyword contained tan third throw throwf
-syn keyword txl_keyword contained time time-fields-local time-fields-utc time-string-local
-syn keyword txl_keyword contained time-string-utc time-usec tok-str tostring
-syn keyword txl_keyword contained tostringp tree-bind tree-case tree-find
-syn keyword txl_keyword contained trim-str trunc typeof unget-byte
-syn keyword txl_keyword contained unget-char unquote upcase-str update
-syn keyword txl_keyword contained url-decode url-encode usleep uw-protect
-syn keyword txl_keyword contained vec vec-push vec-set-length vecref
-syn keyword txl_keyword contained vector vector-list vectorp with-saved-vars
-syn keyword txl_keyword contained zerop
+syn keyword txl_keyword contained env-fbind env-hash env-vbind eq
+syn keyword txl_keyword contained eql equal errno error
+syn keyword txl_keyword contained eval evenp exit exp
+syn keyword txl_keyword contained expt exptmod fboundp fifth
+syn keyword txl_keyword contained find find-if find-package first
+syn keyword txl_keyword contained fixnump flatten flatten* flip
+syn keyword txl_keyword contained flo-int flo-str floatp floor
+syn keyword txl_keyword contained flush-stream for for* force
+syn keyword txl_keyword contained format fourth fun func-get-env
+syn keyword txl_keyword contained func-get-form func-set-env functionp gcd
+syn keyword txl_keyword contained gen generate gensym get-byte
+syn keyword txl_keyword contained get-char get-hash-userdata get-line get-list-from-stream
+syn keyword txl_keyword contained get-sig-handler get-string-from-stream gethash group-by
+syn keyword txl_keyword contained gun hash hash-alist hash-construct
+syn keyword txl_keyword contained hash-count hash-diff hash-eql hash-equal
+syn keyword txl_keyword contained hash-isec hash-keys hash-pairs hash-uni
+syn keyword txl_keyword contained hash-update hash-update-1 hash-values hashp
+syn keyword txl_keyword contained identity if iff iffi
+syn keyword txl_keyword contained inc inhash int-flo int-str
+syn keyword txl_keyword contained integerp intern interp-fun-p isqrt
+syn keyword txl_keyword contained keep-if keep-if* keywordp lambda
+syn keyword txl_keyword contained lazy-str lazy-str-force lazy-str-force-upto lazy-str-get-trailing-list
+syn keyword txl_keyword contained lazy-stream-cons lazy-stringp lcons-fun ldiff
+syn keyword txl_keyword contained length length-list length-str length-str-<
+syn keyword txl_keyword contained length-str-<= length-str-> length-str->= length-vec
+syn keyword txl_keyword contained let let* link lisp-parse
+syn keyword txl_keyword contained list list* list-str list-vector
+syn keyword txl_keyword contained listp log log-alert log-auth
+syn keyword txl_keyword contained log-authpriv log-cons log-crit log-daemon
+syn keyword txl_keyword contained log-debug log-emerg log-err log-info
+syn keyword txl_keyword contained log-ndelay log-notice log-nowait log-odelay
+syn keyword txl_keyword contained log-perror log-pid log-user log-warning
+syn keyword txl_keyword contained logand logior lognot logtest
+syn keyword txl_keyword contained logtrunc logxor macro-form-p macro-time
+syn keyword txl_keyword contained macroexpand macroexpand-1 macrolet major
+syn keyword txl_keyword contained make-catenated-stream make-env make-hash make-lazy-cons
+syn keyword txl_keyword contained make-package make-random-state make-similar-hash make-string-byte-input-stream
+syn keyword txl_keyword contained make-string-input-stream make-string-output-stream make-strlist-output-stream make-sym
+syn keyword txl_keyword contained make-time make-time-utc makedev mapcar
+syn keyword txl_keyword contained mapcar* maphash mappend mappend*
+syn keyword txl_keyword contained mask match-fun match-regex match-regex-right
+syn keyword txl_keyword contained match-str match-str-tree max memq
+syn keyword txl_keyword contained memql memqual merge min
+syn keyword txl_keyword contained minor mkdir mknod mkstring
+syn keyword txl_keyword contained mod multi-sort n-choose-k n-perm-k
+syn keyword txl_keyword contained none not nreverse null
+syn keyword txl_keyword contained num-chr num-str numberp oddp
+syn keyword txl_keyword contained op open-command open-directory open-file
+syn keyword txl_keyword contained open-pipe open-process open-tail openlog
+syn keyword txl_keyword contained or orf packagep perm
+syn keyword txl_keyword contained pop pos pos-if posq
+syn keyword txl_keyword contained posql posqual pprinl pprint
+syn keyword txl_keyword contained prinl print prog1 progn
+syn keyword txl_keyword contained prop proper-listp push pushhash
+syn keyword txl_keyword contained put-byte put-char put-line put-string
+syn keyword txl_keyword contained pwd qquote quasi quote
+syn keyword txl_keyword contained rand random random-fixnum random-state-p
+syn keyword txl_keyword contained range range* rcomb read
+syn keyword txl_keyword contained readlink real-time-stream-p reduce-left reduce-right
+syn keyword txl_keyword contained ref refset regex-compile regex-parse
+syn keyword txl_keyword contained regexp regsub rehome-sym remhash
+syn keyword txl_keyword contained remove-if remove-if* remove-path remq
+syn keyword txl_keyword contained remq* remql remql* remqual
+syn keyword txl_keyword contained remqual* rename-path repeat replace
+syn keyword txl_keyword contained replace-list replace-str replace-vec rest
+syn keyword txl_keyword contained return return-from reverse rlcp
+syn keyword txl_keyword contained rperm rplaca rplacd s-ifblk
+syn keyword txl_keyword contained s-ifchr s-ifdir s-ififo s-iflnk
+syn keyword txl_keyword contained s-ifmt s-ifreg s-ifsock s-irgrp
+syn keyword txl_keyword contained s-iroth s-irusr s-irwxg s-irwxo
+syn keyword txl_keyword contained s-irwxu s-isgid s-isuid s-isvtx
+syn keyword txl_keyword contained s-iwgrp s-iwoth s-iwusr s-ixgrp
+syn keyword txl_keyword contained s-ixoth s-ixusr search-regex search-str
+syn keyword txl_keyword contained search-str-tree second seek-stream set
+syn keyword txl_keyword contained set-diff set-hash-userdata set-sig-handler sethash
+syn keyword txl_keyword contained setlogmask sig-abrt sig-alrm sig-bus
+syn keyword txl_keyword contained sig-check sig-chld sig-cont sig-fpe
+syn keyword txl_keyword contained sig-hup sig-ill sig-int sig-io
+syn keyword txl_keyword contained sig-iot sig-kill sig-lost sig-pipe
+syn keyword txl_keyword contained sig-poll sig-prof sig-pwr sig-quit
+syn keyword txl_keyword contained sig-segv sig-stkflt sig-stop sig-sys
+syn keyword txl_keyword contained sig-term sig-trap sig-tstp sig-ttin
+syn keyword txl_keyword contained sig-ttou sig-urg sig-usr1 sig-usr2
+syn keyword txl_keyword contained sig-vtalrm sig-winch sig-xcpu sig-xfsz
+syn keyword txl_keyword contained sin sixth size-vec some
+syn keyword txl_keyword contained sort source-loc source-loc-str span-str
+syn keyword txl_keyword contained splice split-str split-str-set sqrt
+syn keyword txl_keyword contained stat stream-get-prop stream-set-prop streamp
+syn keyword txl_keyword contained string-cmp string-extend string-lt stringp
+syn keyword txl_keyword contained sub sub-list sub-str sub-vec
+syn keyword txl_keyword contained symacrolet symbol-function symbol-name symbol-package
+syn keyword txl_keyword contained symbol-value symbolp symlink sys-qquote
+syn keyword txl_keyword contained sys-splice sys-unquote syslog tan
+syn keyword txl_keyword contained third throw throwf time
+syn keyword txl_keyword contained time-fields-local time-fields-utc time-string-local time-string-utc
+syn keyword txl_keyword contained time-usec tok-str tostring tostringp
+syn keyword txl_keyword contained tree-bind tree-case tree-find trim-str
+syn keyword txl_keyword contained trunc typeof unget-byte unget-char
+syn keyword txl_keyword contained unquote upcase-str update url-decode
+syn keyword txl_keyword contained url-encode usleep uw-protect vec
+syn keyword txl_keyword contained vec-push vec-set-length vecref vector
+syn keyword txl_keyword contained vector-list vectorp with-saved-vars zerop
syn match txr_error "@[\t ]*[*]\?[\t ]*."
syn match txr_nested_error "[^\t `]\+" contained
@@ -191,8 +191,10 @@ syn match txr_num "#x[+\-]\?[0-9A-Fa-f]\+" contained
syn match txr_num "#o[+\-]\?[0-7]\+" contained
syn match txr_num "#b[+\-]\?[0-1]\+" contained
syn match txr_num "[+\-]\?[0-9]\+" contained
-syn match txr_ident "[:@]\?[A-Za-z0-9!$%&*+\-<=>?\\^_~]*[A-Za-z!$%&*+\-<=>?\\^_~][A-Za-z0-9!$%&*+\-<=>?\\^_~]*" contained
-syn match txl_ident "[:@]\?[A-Za-z0-9!$%&*+\-<=>?\\^_~/]*[A-Za-z!$%&*+\-<=>?\\^_~/][A-Za-z0-9!$%&*+\-<=>?\\^_~/]*" contained
+syn match txr_ident "[:@][A-Za-z0-9!#$%&*+\-<=>?\\^_~]\+" contained
+syn match txr_ident "[A-Za-z0-9!$%&*+\-<=>?\\_~]*[A-Za-z!$#%&*+\-<=>?\\^_~][A-Za-z0-9!$#%&*+\-<=>?\\^_~]*" contained
+syn match txl_ident "[:@][A-Za-z0-9!$%&*+\-<=>?\\\^_~/]\+" contained
+syn match txl_ident "[A-Za-z0-9!$%&*+\-<=>?\\_~/]*[A-Za-z!$#%&*+\-<=>?\\^_~/][A-Za-z0-9!$#%&*+\-<=>?\\^_~/]*" contained
syn match txr_num "[+\-]\?[0-9]*[.][0-9]\+\([eE][+\-]\?[0-9]\+\)\?" contained
syn match txr_num "[+\-]\?[0-9]\+\([eE][+\-]\?[0-9]\+\)" contained
syn match txl_ident ":" contained
@@ -200,6 +202,7 @@ syn match txl_ident ":" contained
syn match txr_unquote "," contained
syn match txr_splice ",\*" contained
syn match txr_quote "'" contained
+syn match txr_quote "\^" contained
syn match txr_dotdot "\.\." contained
syn match txr_metaat "@" contained