]> gitweb.factorcode.org Git - factor.git/commitdiff
interpolate: allow mixing of named variables and stack arguments.
authorJohn Benediktsson <mrjbq7@gmail.com>
Sun, 19 Apr 2015 00:18:37 +0000 (17:18 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sun, 19 Apr 2015 00:18:37 +0000 (17:18 -0700)
basis/interpolate/interpolate-docs.factor
basis/interpolate/interpolate-tests.factor
basis/interpolate/interpolate.factor

index 02300ea282c321e9a52c394ae741d126552b2367..6953266edd54735f9ad0b7f4d48e0219f32b2691 100644 (file)
@@ -1,10 +1,24 @@
-USING: help.markup help.syntax math strings ;
+USING: help.markup help.syntax io math strings ;
 IN: interpolate
 
-HELP: ninterpolate
-{ $values { "str" string } { "n" integer } }
-{ $description "Assigns stack arguments to numbered variables for string interpolation." }
+HELP: interpolate.
+{ $values { "str" string } }
+{ $description "String interpolation using named variables and/or stack arguments, writing to the " { $link output-stream } "." }
 { $examples
-    { $example "USING: interpolate ;" "\"Bob\" \"Alice\" \"Hi ${0}, it's ${1}.\" 2 ninterpolate" "Hi Bob, it's Alice." }
-}
-{ $see-also interpolate } ;
+    { $example
+        "USING: interpolate ;"
+        "\"Bob\" \"Alice\" \"Hi ${0}, it's ${1}.\" interpolate."
+        "Hi Bob, it's Alice."
+    }
+    { $example
+        "USING: interpolate namespaces ;"
+        "\"Fred\" \"name\" [ \"Hi ${name}\" interpolate. ] with-variable"
+        "Hi Fred"
+    }
+} ;
+
+HELP: interpolate
+{ $values { "str" string } { "newstr" string } }
+{ $description "String interpolation using named variables and/or stack arguments, captured as a " { $link string } "." } ;
+
+{ interpolate interpolate. } related-words
index 8f84da4ff797467319bb5de915699464d0693b8a..985e5df6b4a8d9adacd15bbb1d826e07cc792abe 100644 (file)
@@ -3,21 +3,30 @@
 USING: interpolate io.streams.string namespaces tools.test locals ;
 IN: interpolate.tests
 
-[ "Hello, Jane." ] [
+{ "A B" } [ "A" "B" "${0} ${1}" interpolate ] unit-test
+{ "B A" } [ "A" "B" "${1} ${0}" interpolate ] unit-test
+{ "C A" } [ "A" "B" "C" "${2} ${0}" interpolate ] unit-test
+
+{ "Hello, Jane." } [
     "Jane" "name" set
-    [ "Hello, ${name}." interpolate ] with-string-writer
+    "Hello, ${name}." interpolate
+] unit-test
+
+{ "Mr. John" } [
+    "John" "name" set
+    "Mr." "${0} ${name}" interpolate
 ] unit-test
 
-[ "Sup Dawg, we heard you liked rims, so we put rims on your rims so you can roll while you roll." ] [
+{ "Sup Dawg, we heard you liked rims, so we put rims on your rims so you can roll while you roll." } [
     "Dawg" "name" set
     "rims" "noun" set
     "roll" "verb" set
-    [ "Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your ${noun} so you can ${verb} while you ${verb}." interpolate ] with-string-writer
+    "Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your ${noun} so you can ${verb} while you ${verb}." interpolate
 ] unit-test
 
-[ "Oops, I accidentally the whole economy..." ] [
+{ "Oops, I accidentally the whole economy..." } [
     [let
         "economy" :> noun
-        [ I[ Oops, I accidentally the whole ${noun}...]I ] with-string-writer
+        "accidentally" [ I[ Oops, I ${0} the whole ${noun}...]I ] with-string-writer
     ]
 ] unit-test
index bed5b7416c9e79586d327a3c48977505641267c8..c1595e2a3749589066f6560d20599bd87355696d 100644 (file)
@@ -1,50 +1,71 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays fry hashtables io kernel macros make
-math.parser multiline namespaces present sequences
-sequences.generalizations splitting strings vocabs.parser ;
+USING: accessors fry generalizations io io.streams.string kernel
+locals macros 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 ;
+
+: (parse-interpolate) ( str -- )
     [
-        "${" split1-slice [ >string , ] [
+        "${" split1-slice [
+            [ >string , ] unless-empty
+        ] [
             [
                 "}" split1-slice
-                [ >string interpolate-var boa , ]
+                [
+                    >string dup string>number
+                    [ stack-var boa ] [ named-var boa ] ?if ,
+                ]
                 [ (parse-interpolate) ] bi*
             ] when*
         ] bi*
     ] unless-empty ;
 
-: parse-interpolate ( string -- seq )
+: parse-interpolate ( str -- seq )
     [ (parse-interpolate) ] { } make ;
 
-: (interpolate) ( string quot -- quot' )
-    [ parse-interpolate ] dip '[
-        dup interpolate-var?
-        [ name>> @ '[ _ @ present write ] ]
-        [ '[ _ write ] ]
-        if
-    ] map [ ] join ; inline
+: 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
+
+    args [
+        dup named-var? [
+            name>> quot call '[ _ @ present write ]
+        ] [
+            dup stack-var? [
+                n>> vars swap - 1 + '[ _ npick present write ]
+            ] [
+                '[ _ write ]
+            ] if
+        ] if
+    ] map concat
+
+    vars [
+        1 + '[ _ ndrop ] append
+    ] when* ; inline
 
 PRIVATE>
 
-MACRO: interpolate ( string -- )
-    [ [ get ] ] (interpolate) ;
+MACRO: interpolate. ( str -- )
+    [ [ get ] ] interpolate-quot ;
+
+: interpolate ( str -- newstr )
+    [ interpolate. ] with-string-writer ; inline
 
-: interpolate-locals ( string -- quot )
-    [ search [ ] ] (interpolate) ;
+: interpolate-locals ( str -- quot )
+    [ dup search [ [ ] ] [ [ get ] ] ?if ] interpolate-quot ;
 
 SYNTAX: I[
     "]I" parse-multiline-string
     interpolate-locals append! ;
-
-MACRO: ninterpolate ( str n -- quot )
-    swap '[
-        _ narray [ number>string swap 2array ] map-index
-        >hashtable [ _ interpolate ] with-variables
-    ] ;