From: John Benediktsson Date: Sun, 19 Apr 2015 00:18:37 +0000 (-0700) Subject: interpolate: allow mixing of named variables and stack arguments. X-Git-Tag: unmaintained~2888 X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor.git;a=commitdiff_plain;h=ce491a5aa16afa5489a85f75a5350dff69b97321 interpolate: allow mixing of named variables and stack arguments. --- diff --git a/basis/interpolate/interpolate-docs.factor b/basis/interpolate/interpolate-docs.factor index 02300ea282..6953266edd 100644 --- a/basis/interpolate/interpolate-docs.factor +++ b/basis/interpolate/interpolate-docs.factor @@ -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 diff --git a/basis/interpolate/interpolate-tests.factor b/basis/interpolate/interpolate-tests.factor index 8f84da4ff7..985e5df6b4 100644 --- a/basis/interpolate/interpolate-tests.factor +++ b/basis/interpolate/interpolate-tests.factor @@ -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 diff --git a/basis/interpolate/interpolate.factor b/basis/interpolate/interpolate.factor index bed5b7416c..c1595e2a37 100644 --- a/basis/interpolate/interpolate.factor +++ b/basis/interpolate/interpolate.factor @@ -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 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 - ] ;