 
 DEFER: (parse-regexp)
 : parse-special-group ( -- )
-    beginning-of-group push-stack
-    (parse-regexp) pop-stack make-non-capturing-group ;
+    ;
+    ! beginning-of-group push-stack
+    ! (parse-regexp) pop-stack make-non-capturing-group ;
 
 ERROR: bad-special-group string ;
 
-DEFER: nested-parse-regexp
+: nested-parse-regexp ( token ? -- )
+    [ push-stack (parse-regexp) pop-stack ] dip
+    [ <negation> ] when pop-stack boa push-stack ;
+
+! non-capturing groups
 : (parse-special-group) ( -- )
     read1 {
-        { [ dup CHAR: # = ]
-            [ drop nested-parse-regexp pop-stack drop ] }
+        { [ dup CHAR: # = ] ! comment
+            [ drop comment-group f nested-parse-regexp pop-stack drop ] }
         { [ dup CHAR: : = ]
-            [ drop nested-parse-regexp pop-stack make-non-capturing-group ] }
+            [ drop non-capture-group f nested-parse-regexp ] }
         { [ dup CHAR: = = ]
-            [ drop nested-parse-regexp pop-stack make-positive-lookahead ] }
+            [ drop lookahead f nested-parse-regexp ] }
         { [ dup CHAR: ! = ]
-            [ drop nested-parse-regexp pop-stack make-negative-lookahead ] }
+            [ drop lookahead t nested-parse-regexp ] }
         { [ dup CHAR: > = ]
-            [ drop nested-parse-regexp pop-stack make-independent-group ] }
+            [ drop non-capture-group f nested-parse-regexp ] }
         { [ dup CHAR: < = peek1 CHAR: = = and ]
-            [ drop drop1 nested-parse-regexp pop-stack make-positive-lookbehind ] }
+            [ drop drop1 lookbehind f nested-parse-regexp ] }
         { [ dup CHAR: < = peek1 CHAR: ! = and ]
-            [ drop drop1 nested-parse-regexp pop-stack make-negative-lookbehind ] }
+            [ drop drop1 lookbehind t nested-parse-regexp ] }
         [
             ":)" read-until
             [ swap prefix ] dip
             {
-                { CHAR: : [ parse-options parse-special-group ] }
+                { CHAR: : [ parse-options (parse-special-group) ] }
                 { CHAR: ) [ parse-options ] }
                 [ drop bad-special-group ]
             } case

    } case ;

: (parse-regexp) ( -- )
    read1 [ ((parse-regexp)) [ (parse-regexp) ] when ] when* ;

: parse-regexp ( regexp -- )
    dup current-regexp [

TUPLE: negation term ; INSTANCE: negation node
TUPLE: constant char ; INSTANCE: constant node
TUPLE: range from to ; INSTANCE: range node

MIXIN: parentheses-group
TUPLE: lookahead term ; INSTANCE: lookahead node
INSTANCE: lookahead parentheses-group
TUPLE: lookbehind term ; INSTANCE: lookbehind node
INSTANCE: lookbehind parentheses-group
TUPLE: capture-group term ; INSTANCE: capture-group node
INSTANCE: capture-group parentheses-group
TUPLE: non-capture-group term ; INSTANCE: non-capture-group node
INSTANCE: non-capture-group parentheses-group
TUPLE: independent-group term ; INSTANCE: independent-group node ! atomic group
INSTANCE: independent-group parentheses-group
TUPLE: comment-group term ; INSTANCE: comment-group node
INSTANCE: comment-group parentheses-group

TUPLE: character-class-range from to ; INSTANCE: character-class-range node
SINGLETON: epsilon INSTANCE: epsilon node
SINGLETON: any-char INSTANCE: any-char node
