]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/interpolate/interpolate.factor
basis: use lint.vocabs tool to trim using lists
[factor.git] / basis / interpolate / interpolate.factor
index 1de65fa91f8febc1f5002002cb8867f2dda5fd1a..cd300a585c73791bc08121fa464a880f61418cfe 100644 (file)
@@ -1,43 +1,90 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io kernel macros make multiline namespaces parser
-present sequences strings splitting fry accessors ;
+USING: accessors fry generalizations io io.streams.string kernel
+make math math.order math.parser multiline namespaces present
+sequences splitting strings vocabs.parser ;
 IN: interpolate
 
 <PRIVATE
 
-TUPLE: interpolate-var name ;
+TUPLE: named-var name ;
 
-: (parse-interpolate) ( string -- )
+TUPLE: stack-var n ;
+
+TUPLE: anon-var ;
+
+: (parse-interpolate) ( str -- )
     [
-        "${" split1-slice [ >string , ] [
+        "${" split1-slice [
+            [ >string , ] unless-empty
+        ] [
             [
                 "}" split1-slice
-                [ >string interpolate-var boa , ]
+                [
+                    >string dup string>number
+                    [ 1 + stack-var boa ]
+                    [ [ anon-var new ] [ named-var boa ] if-empty ] ?if ,
+                ]
                 [ (parse-interpolate) ] bi*
             ] when*
         ] bi*
     ] unless-empty ;
 
-: parse-interpolate ( string -- seq )
-    [ (parse-interpolate) ] { } make ;
+: deanonymize ( seq -- seq' )
+    0 over <reversed> [
+        dup anon-var? [
+            drop 1 + dup stack-var boa
+        ] when
+    ] map! 2drop ;
+
+: parse-interpolate ( str -- seq )
+    [ (parse-interpolate) ] { } make deanonymize ;
+
+: max-stack-var ( seq -- n/f )
+    f [
+        dup stack-var? [ n>> [ or ] keep max ] [ drop ] if
+    ] reduce ;
+
+:: (interpolate-quot) ( str quot -- quot' )
+    str parse-interpolate :> args
+    args max-stack-var    :> vars
 
-: (interpolate) ( string quot -- quot' )
-    [ parse-interpolate ] dip '[
-        dup interpolate-var?
-        [ name>> @ '[ _ @ present write ] ]
-        [ '[ _ write ] ]
-        if
-    ] map [ ] join ; inline
+    args [
+        dup named-var? [
+            name>> quot call '[ _ @ present write ]
+        ] [
+            dup stack-var? [
+                n>> '[ _ npick present write ]
+            ] [
+                '[ _ write ]
+            ] if
+        ] if
+    ] map concat
+
+    vars [
+        '[ _ ndrop ] append
+    ] when* ; inline
 
 PRIVATE>
 
-MACRO: interpolate ( string -- )
-    [ [ get ] ] (interpolate) ;
+: interpolate-quot ( str -- quot )
+    [ [ get ] ] (interpolate-quot) ;
+
+MACRO: interpolate ( str -- quot )
+    interpolate-quot ;
+
+: interpolate>string ( str -- newstr )
+    [ interpolate ] with-string-writer ; inline
+
+: interpolate-locals-quot ( str -- quot )
+    [ dup search [ [ ] ] [ [ get ] ] ?if ] (interpolate-quot) ;
+
+MACRO: interpolate-locals ( str -- quot )
+    interpolate-locals-quot ;
 
-: interpolate-locals ( string -- quot )
-    [ search [ ] ] (interpolate) ;
+: interpolate-locals>string ( str -- newstr )
+    [ interpolate-locals ] with-string-writer ; inline
 
-SYNTAX: I[
-    "]I" parse-multiline-string
-    interpolate-locals over push-all ;
+SYNTAX: [I
+    "I]" parse-multiline-string
+    interpolate-locals-quot append! ;