From 4af3611c835e9b6acb979987568f46ba86ef52e7 Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Mon, 7 Nov 2016 20:16:14 -0800
Subject: New #; syntax for erasing following object.

* parser.c (parser_circ_ref): Don't generate the
circular reference if circular suppression is in
effect.

* parser.h (struct parser): New member, circ_suppress.
We use this for suppressing the generation of
circular #n# references in erased objects.

* parser.l (grammar): Scan #; producing HASH_SEMI token.

* parser.y (HASH_SEMI): New token.
(hash_semis_n_expr, hash_semis_i_expr, ignored_i_exprs,
ignored_n_exprs): New nonterminals, needed for supporting
the use of #; in front of top-level forms.
(spec): Use hash_semis_n_expr and hash_semis_i_expr
instead of n_expr and i_expr.
(r_expr): Support object erasure within nested syntax.
(yybadtoken): Handle H_SEMI token.
(parse): Initialize new circ_suppress member of parser
struct to zero.

* txr.1: Documented.

* genvim.txr (txr_ign_par, txr_ign_bkt, txr_ign_par_interior,
txr_ign_bkt_interior): New regions for colorizing erased
objects (partial support).
(txr_list, txr_bracket, txr_mlist, txr_mbrackets): Include
erased objects by including regions txr_ign_par and
txr_ign_bkt.

* txr.vim, tl.vim: Regenerated.
---
 genvim.txr | 16 +++++++++---
 parser.c   |  2 +-
 parser.h   |  1 +
 parser.l   |  5 ++++
 parser.y   | 44 ++++++++++++++++++++++++++++++---
 tl.vim     | 16 +++++++++---
 txr.1      | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 txr.vim    | 16 +++++++++---
 8 files changed, 165 insertions(+), 17 deletions(-)

diff --git a/genvim.txr b/genvim.txr
index 2089103f..4130831a 100644
--- a/genvim.txr
+++ b/genvim.txr
@@ -147,14 +147,18 @@ syn region txr_directive matchgroup=Delimiter start="@@[ \t]*(" matchgroup=Delim
 @    (end)
 @  (end)
 @  (output :continue out)
-syn region txr_list @(if txr-p "contained ")matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_bracket @(if txr-p "contained ")matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mlist @(if txr-p "contained ")matchgroup=Delimiter start="@@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mbracket matchgroup=Delimiter start="@@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_list @(if txr-p "contained ")matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_bracket @(if txr-p "contained ")matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mlist @(if txr-p "contained ")matchgroup=Delimiter start="@@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mbracket matchgroup=Delimiter start="@@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
 syn region txr_string @(if txr-p "contained ")start=+#\?\*\?"+ end=+["\n]+ contains=txr_stresc,txr_numesc,txr_badesc
 syn region txr_quasilit @(if txr-p "contained ")start=+#\?\*\?`+ end=+[`\n]+ contains=txr_splicevar,txr_metanum,txr_bracevar,txr_mlist,txr_mbracket,txr_escat,txr_stresc,txr_numesc,txr_badesc
 syn region txr_regex @(if txr-p "contained ")start="/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
 syn region tl_regex @(if txr-p "contained ")start="#/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
+syn region txr_ign_par @(if txr-p "contained ")matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt @(if txr-p "contained ")matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_par_interior contained matchgroup=Comment start="(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt_interior contained matchgroup=Comment start="\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
 
 hi def link txr_at Special
 hi def link txr_atstar Special
@@ -194,6 +198,10 @@ hi def link txr_munqspl Special
 hi def link tl_splice Special
 hi def link txr_error Error
 hi def link txr_nested_error Error
+hi def link txr_ign_par Comment
+hi def link txr_ign_bkt_interior Comment
+hi def link txr_ign_par_interior Comment
+hi def link txr_ign_bkt Comment
 
 let b:current_syntax = "lisp"
 
diff --git a/parser.c b/parser.c
index 8817abe4..655ee8f1 100644
--- a/parser.c
+++ b/parser.c
@@ -375,7 +375,7 @@ val parser_circ_ref(parser_t *p, val num)
   if (!obj)
     yyerrorf(p->scanner, lit("dangling #~s# ref"), num, nao);
 
-  if (obj == unique_s) {
+  if (obj == unique_s && !p->circ_suppress) {
     p->circ_count++;
     return cons(circref_s, cons(num, nil));
   }
diff --git a/parser.h b/parser.h
index a12d45ee..6980e0f4 100644
--- a/parser.h
+++ b/parser.h
@@ -56,6 +56,7 @@ struct parser {
   val syntax_tree;
   val circ_ref_hash;
   cnum circ_count;
+  int circ_suppress;
   scanner_t *scanner;
   struct yy_token recent_tok;
   struct yy_token tok_pushback[4];
diff --git a/parser.l b/parser.l
index 763f6544..28e0d1d2 100644
--- a/parser.l
+++ b/parser.l
@@ -708,6 +708,11 @@ UONLY   {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
   return HASH_R;
 }
 
+<NESTED,BRACED>#; {
+  yylval->lineno = yyextra->lineno;
+  return HASH_SEMI;
+}
+
 <NESTED,BRACED>#{DIG}+= {
   val str = string_own(utf8_dup_from(yytext + 1));
   yylval->val = int_str(str, num(10));
diff --git a/parser.y b/parser.y
index 8cc1232a..48d36840 100644
--- a/parser.y
+++ b/parser.y
@@ -103,7 +103,7 @@ int yyparse(scanner_t *, parser_t *);
 %token <lineno> UNTIL COLL OUTPUT REPEAT REP SINGLE FIRST LAST EMPTY
 %token <lineno> MOD MODLAST DEFINE TRY CATCH FINALLY IF
 %token <lineno> ERRTOK /* deliberately not used in grammar */
-%token <lineno> HASH_BACKSLASH HASH_SLASH DOTDOT HASH_H HASH_S HASH_R
+%token <lineno> HASH_BACKSLASH HASH_SLASH DOTDOT HASH_H HASH_S HASH_R HASH_SEMI
 %token <lineno> WORDS WSPLICE QWORDS QWSPLICE
 %token <lineno> SECRET_ESCAPE_R SECRET_ESCAPE_E SECRET_ESCAPE_I
 
@@ -112,7 +112,9 @@ int yyparse(scanner_t *, parser_t *);
 
 %token <chr> REGCHAR REGTOKEN LITCHAR SPLICE CONSDOT LAMBDOT
 
-%type <val> spec clauses_rev clauses_opt clause
+%type <val> spec hash_semis_n_expr hash_semis_i_expr
+%type <val> ignored_i_exprs ignored_n_exprs
+%type <val> clauses_rev clauses_opt clause
 %type <val> all_clause some_clause none_clause maybe_clause block_clause
 %type <val> cases_clause choose_clause gather_clause collect_clause until_last
 %type <val> collect_repeat
@@ -150,9 +152,11 @@ int yyparse(scanner_t *, parser_t *);
 
 spec : clauses_opt              { parser->syntax_tree = $1; }
      | SECRET_ESCAPE_R regexpr  { parser->syntax_tree = $2; end_of_regex(scnr); }
-     | SECRET_ESCAPE_E n_expr   { parser->syntax_tree = $2; YYACCEPT; }
+     | SECRET_ESCAPE_E hash_semis_n_expr
+                                { parser->syntax_tree = $2; YYACCEPT; }
        byacc_fool               { internal_error("notreached"); }
-     | SECRET_ESCAPE_I i_expr   { parser->syntax_tree = $2; YYACCEPT; }
+     | SECRET_ESCAPE_I hash_semis_i_expr
+                                { parser->syntax_tree = $2; YYACCEPT; }
        byacc_fool               { internal_error("notreached"); }
      | SECRET_ESCAPE_E          { if (yychar == YYEOF) {
                                     parser->syntax_tree = nao;
@@ -176,6 +180,30 @@ spec : clauses_opt              { parser->syntax_tree = $1; }
 
      ;
 
+hash_semis_n_expr : ignored_n_exprs n_expr      { $$ = $2; }
+                  | n_expr                      { $$ = $1; }
+                  ;
+
+ignored_n_exprs : ignored_n_exprs HASH_SEMI     { parser->circ_suppress = 1; }
+                  n_expr                        { parser->circ_suppress = 0;
+                                                  $$ = nil; }
+                | HASH_SEMI                     { parser->circ_suppress = 1; }
+                  n_expr                        { parser->circ_suppress = 0;
+                                                  $$ = nil; }
+                ;
+
+hash_semis_i_expr : ignored_i_exprs i_expr      { $$ = $2; }
+                  | i_expr                      { $$ = $1; }
+                  ;
+
+ignored_i_exprs : ignored_i_exprs HASH_SEMI     { parser->circ_suppress = 1; }
+                  i_expr                        { parser->circ_suppress = 0;
+                                                  $$ = nil; }
+                | HASH_SEMI                     { parser->circ_suppress = 1; }
+                  i_expr                        { parser->circ_suppress = 0;
+                                                  $$ = nil; }
+                ;
+
 /* Hack needed for Berkeley Yacc */
 byacc_fool : n_expr { internal_error("notreached"); }
            | { internal_error("notreached"); }
@@ -876,6 +904,12 @@ n_exprs : r_exprs               { val term_atom = pop(&$1);
 r_exprs : n_expr                { val exprs = cons($1, nil);
                                   rlcp(exprs, $1);
                                   $$ = rlcp(cons(unique_s, exprs), exprs); }
+        | HASH_SEMI             { parser->circ_suppress = 1; }
+          n_expr                { parser->circ_suppress = 0;
+                                  $$ = cons(unique_s, nil); }
+        | r_exprs HASH_SEMI     { parser->circ_suppress = 1; }
+          n_expr                { parser->circ_suppress = 0;
+                                  $$ = $1; }
         | r_exprs n_expr        { uses_or2;
                                   val term_atom_cons = $1;
                                   val exprs = cdr($1);
@@ -1672,6 +1706,7 @@ void yybadtoken(parser_t *parser, int tok, val context)
   case HASH_H:         problem = lit("#H"); break;
   case HASH_S:         problem = lit("#S"); break;
   case HASH_R:         problem = lit("#R"); break;
+  case HASH_SEMI:      problem = lit("#;"); break;
   case HASH_N_EQUALS:  problem = lit("#<n>="); break;
   case HASH_N_HASH:    problem = lit("#<n>#"); break;
   case WORDS:   problem = lit("#\""); break;
@@ -1747,6 +1782,7 @@ int parse(parser_t *parser, val name, enum prime_parser prim)
   parser->prepared_msg = nil;
   parser->circ_ref_hash = nil;
   parser->circ_count = 0;
+  parser->circ_suppress = 0;
   parser->syntax_tree = nil;
 
   prime_parser(parser, name, prim);
diff --git a/tl.vim b/tl.vim
index 61c81a71..228b989d 100644
--- a/tl.vim
+++ b/tl.vim
@@ -436,14 +436,18 @@ syn match txr_dotdot "\.\." contained
 syn match txr_metaat "@" contained
 
 syn region txr_bracevar matchgroup=Delimiter start="@[ \t]*[*]\?{" matchgroup=Delimiter end="}" contains=txr_num,tl_ident,tl_splice,tl_metanum,txr_metaat,txr_braced_ident,txr_dot,txr_dotdot,txr_string,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_regex,txr_quasilit,txr_chr,tl_splice,txr_nested_error
-syn region txr_list matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_bracket matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mlist matchgroup=Delimiter start="@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mbracket matchgroup=Delimiter start="@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_list matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_bracket matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mlist matchgroup=Delimiter start="@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mbracket matchgroup=Delimiter start="@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
 syn region txr_string start=+#\?\*\?"+ end=+["\n]+ contains=txr_stresc,txr_numesc,txr_badesc
 syn region txr_quasilit start=+#\?\*\?`+ end=+[`\n]+ contains=txr_splicevar,txr_metanum,txr_bracevar,txr_mlist,txr_mbracket,txr_escat,txr_stresc,txr_numesc,txr_badesc
 syn region txr_regex start="/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
 syn region tl_regex start="#/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
+syn region txr_ign_par matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_par_interior contained matchgroup=Comment start="(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt_interior contained matchgroup=Comment start="\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
 
 hi def link txr_at Special
 hi def link txr_atstar Special
@@ -483,6 +487,10 @@ hi def link txr_munqspl Special
 hi def link tl_splice Special
 hi def link txr_error Error
 hi def link txr_nested_error Error
+hi def link txr_ign_par Comment
+hi def link txr_ign_bkt_interior Comment
+hi def link txr_ign_par_interior Comment
+hi def link txr_ign_bkt Comment
 
 let b:current_syntax = "lisp"
 
diff --git a/txr.1 b/txr.1
index eb16015a..6dd6285e 100644
--- a/txr.1
+++ b/txr.1
@@ -10812,6 +10812,88 @@ document, judiciously taking into account the content of the X3J13 Cleanup
 Issues named PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK and
 PRINT-CIRCLE-SHARED:RESPECT-PRINT-CIRCLE.
 
+.NP* Notation for Erasing Objects
+
+.meIP #; < expr
+
+The \*(TL notation
+.code #;
+in TXR Lisp indicates that the expression
+.meta expr
+is to be read and then discarded, as if it were replaced by whitespace.
+
+This is useful for temporarily "commenting out" an expression.
+
+.TP* Notes:
+Whereas it is valid for a \*(TL source file to be empty, it is
+a syntax error if a \*(TL source file contains nothing but one or more
+objects which are each suppressed by a preceding
+.codn #; .
+In the interactive listener, an input line consisting of nothing but
+commented-out objects is similarly a syntax error.
+
+The notation does not cascade; consecutive occurrences of
+.code #;
+trigger a syntax error.
+
+The notation interacts with the circle notation. Firstly, if an object
+which is erased by
+.code #;
+contains circular-referencing instances of the label notation,
+those instances refer to
+.codn nil .
+Secondly, commented-out objects may introduce labels
+which are subsequently referenced in
+.metn expr .
+An example of the first situation occurs in:
+
+.cblk
+  #;(#1=(#1#))
+.cble
+
+Here the
+.code #1#
+label is a circular reference because it refers to an object which
+is a parent of the object which contains that reference. Such a reference
+is only satisfied by a "backpatching" process once the entire surrounding syntax
+is processed to the top level. The erasure perpetrated by
+.code #;
+causes the
+.code #1#
+label reference to be replaced by
+.codn nil ,
+and therefore the labeled object is the object
+.codn (nil) .
+
+An example of the second situation is
+
+.cblk
+  #;(#2=(a b c)) #2#
+.cble
+
+Here, even though the expression
+.code "(#2=(a b c))"
+is suppressed, the label definition which it has introduced persists into the
+following object, where the label reference
+.code #2#
+resolves to
+.codn "(a b c)" .
+
+A combination of the two situations occurs in
+
+.cblk
+  #;(#1=(#1#)) #1#
+.cble
+
+which yields
+.codn "(nil)" .
+This is because the
+.code #1=
+label is available; but the earlier
+.code #1#
+reference, being a circular reference inside an erased object, had lapsed to
+.codn nil .
+
 .SS* Generalization of List Accessors
 In ancient Lisp in the 1960's, it was not possible to apply the operations
 .code car
diff --git a/txr.vim b/txr.vim
index 9d331d08..394eb2c1 100644
--- a/txr.vim
+++ b/txr.vim
@@ -464,14 +464,18 @@ syn match txr_metaat "@" contained
 
 syn region txr_bracevar matchgroup=Delimiter start="@[ \t]*[*]\?{" matchgroup=Delimiter end="}" contains=txr_num,tl_ident,tl_splice,tl_metanum,txr_metaat,txr_braced_ident,txr_dot,txr_dotdot,txr_string,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_regex,txr_quasilit,txr_chr,tl_splice,txr_nested_error
 syn region txr_directive matchgroup=Delimiter start="@[ \t]*(" matchgroup=Delimiter end=")" contains=txr_keyword,txr_string,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_num,txr_badnum,tl_ident,tl_regex,txr_string,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_list contained matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_bracket contained matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mlist contained matchgroup=Delimiter start="@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
-syn region txr_mbracket matchgroup=Delimiter start="@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_list contained matchgroup=Delimiter start="\(#[HSR]\?\)\?(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_bracket contained matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mlist contained matchgroup=Delimiter start="@[ \t^',]*(" matchgroup=Delimiter end=")" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
+syn region txr_mbracket matchgroup=Delimiter start="@[ \t^',]*\[" matchgroup=Delimiter end="\]" contains=tl_keyword,txr_string,tl_regex,txr_num,txr_badnum,tl_ident,txr_metanum,txr_ign_par,txr_ign_bkt,txr_list,txr_bracket,txr_mlist,txr_mbracket,txr_quasilit,txr_chr,txr_quote,txr_unquote,txr_splice,txr_dot,txr_dotdot,txr_metaat,txr_ncomment,txr_nested_error
 syn region txr_string contained start=+#\?\*\?"+ end=+["\n]+ contains=txr_stresc,txr_numesc,txr_badesc
 syn region txr_quasilit contained start=+#\?\*\?`+ end=+[`\n]+ contains=txr_splicevar,txr_metanum,txr_bracevar,txr_mlist,txr_mbracket,txr_escat,txr_stresc,txr_numesc,txr_badesc
 syn region txr_regex contained start="/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
 syn region tl_regex contained start="#/" end="[/\n]" contains=txr_regesc,txr_numesc,txr_badesc
+syn region txr_ign_par contained matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt contained matchgroup=Comment start="#;[ \t',]*\(#[HSR]\?\)\?\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_par_interior contained matchgroup=Comment start="(" matchgroup=Comment end=")" contains=txr_ign_par_interior,txr_ign_bkt_interior
+syn region txr_ign_bkt_interior contained matchgroup=Comment start="\[" matchgroup=Comment end="\]" contains=txr_ign_par_interior,txr_ign_bkt_interior
 
 hi def link txr_at Special
 hi def link txr_atstar Special
@@ -511,6 +515,10 @@ hi def link txr_munqspl Special
 hi def link tl_splice Special
 hi def link txr_error Error
 hi def link txr_nested_error Error
+hi def link txr_ign_par Comment
+hi def link txr_ign_bkt_interior Comment
+hi def link txr_ign_par_interior Comment
+hi def link txr_ign_bkt Comment
 
 let b:current_syntax = "lisp"
 
-- 
cgit v1.2.3