From: Slava Pestov Date: Thu, 4 Dec 2008 08:26:34 +0000 (-0600) Subject: Rewrite interpolate without using PEGs for mad lulz X-Git-Tag: 0.94~2294^2 X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor.git;a=commitdiff_plain;h=d70c8eff1c3decbb5e03e55413353a91ab67b912 Rewrite interpolate without using PEGs for mad lulz --- diff --git a/basis/interpolate/interpolate-tests.factor b/basis/interpolate/interpolate-tests.factor index 005ae87746..c15debd9b5 100644 --- a/basis/interpolate/interpolate-tests.factor +++ b/basis/interpolate/interpolate-tests.factor @@ -1,4 +1,22 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: tools.test interpolate ; +USING: interpolate io.streams.string namespaces tools.test locals ; IN: interpolate.tests + +[ "Hello, Jane." ] [ + "Jane" "name" set + [ "Hello, ${name}." interpolate ] with-string-writer +] unit-test + +[ "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 +] unit-test + +[ "Oops, I accidentally the whole economy..." ] [ + [let | noun [ "economy" ] | + [ I[ Oops, I accidentally the whole ${noun}...]I ] with-string-writer + ] +] unit-test diff --git a/basis/interpolate/interpolate.factor b/basis/interpolate/interpolate.factor index 27f0756f1f..5e4805a8ac 100644 --- a/basis/interpolate/interpolate.factor +++ b/basis/interpolate/interpolate.factor @@ -1,21 +1,40 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: io kernel macros make multiline namespaces parser -peg.ebnf present sequences strings ; +present sequences strings splitting fry accessors ; IN: interpolate +TUPLE: interpolate-var name ; + +: (parse-interpolate) ( string -- ) + [ + "${" split1-slice [ >string , ] [ + [ + "}" split1-slice + [ >string interpolate-var boa , ] + [ (parse-interpolate) ] bi* + ] when* + ] bi* + ] unless-empty ; + +: parse-interpolate ( string -- seq ) + [ (parse-interpolate) ] { } make ; + MACRO: interpolate ( string -- ) -[EBNF -var = "${" [^}]+ "}" => [[ second >string [ get present write ] curry ]] -text = [^$]+ => [[ >string [ write ] curry ]] -interpolate = (var|text)* => [[ [ ] join ]] -EBNF] ; + parse-interpolate [ + dup interpolate-var? + [ name>> '[ _ get present write ] ] + [ '[ _ write ] ] + if + ] map [ ] join ; -EBNF: interpolate-locals -var = "${" [^}]+ "}" => [[ [ second >string search , [ present write ] % ] [ ] make ]] -text = [^$]+ => [[ [ >string , [ write ] % ] [ ] make ]] -interpolate = (var|text)* => [[ [ ] join ]] -;EBNF +: interpolate-locals ( string -- quot ) + parse-interpolate [ + dup interpolate-var? + [ name>> search '[ _ present write ] ] + [ '[ _ write ] ] + if + ] map [ ] join ; : I[ "]I" parse-multiline-string interpolate-locals parsed \ call parsed ; parsing