]> gitweb.factorcode.org Git - factor.git/blob - basis/interpolate/interpolate.factor
fd00b1fdd1de51fb9d4de1772a145b67fbdaeffe
[factor.git] / basis / interpolate / interpolate.factor
1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors fry generalizations io io.streams.string kernel
4 locals macros make math math.order math.parser multiline
5 namespaces present sequences splitting strings vocabs.parser ;
6 IN: interpolate
7
8 <PRIVATE
9
10 TUPLE: named-var name ;
11
12 TUPLE: stack-var n ;
13
14 TUPLE: anon-var ;
15
16 : (parse-interpolate) ( str -- )
17     [
18         "${" split1-slice [
19             [ >string , ] unless-empty
20         ] [
21             [
22                 "}" split1-slice
23                 [
24                     >string dup string>number
25                     [ 1 + stack-var boa ]
26                     [ [ anon-var new ] [ named-var boa ] if-empty ] ?if ,
27                 ]
28                 [ (parse-interpolate) ] bi*
29             ] when*
30         ] bi*
31     ] unless-empty ;
32
33 : deanonymize ( seq -- seq' )
34     0 over <reversed> [
35         dup anon-var? [
36             drop 1 + dup stack-var boa
37         ] when
38     ] map! 2drop ;
39
40 : parse-interpolate ( str -- seq )
41     [ (parse-interpolate) ] { } make deanonymize ;
42
43 : max-stack-var ( seq -- n/f )
44     f [
45         dup stack-var? [ n>> [ or ] keep max ] [ drop ] if
46     ] reduce ;
47
48 :: (interpolate-quot) ( str quot -- quot' )
49     str parse-interpolate :> args
50     args max-stack-var    :> vars
51
52     args [
53         dup named-var? [
54             name>> quot call '[ _ @ present write ]
55         ] [
56             dup stack-var? [
57                 n>> '[ _ npick present write ]
58             ] [
59                 '[ _ write ]
60             ] if
61         ] if
62     ] map concat
63
64     vars [
65         '[ _ ndrop ] append
66     ] when* ; inline
67
68 PRIVATE>
69
70 : interpolate-quot ( str -- quot )
71     [ [ get ] ] (interpolate-quot) ;
72
73 MACRO: interpolate ( str -- quot )
74     interpolate-quot ;
75
76 : interpolate>string ( str -- newstr )
77     [ interpolate ] with-string-writer ; inline
78
79 : interpolate-locals-quot ( str -- quot )
80     [ dup search [ [ ] ] [ [ get ] ] ?if ] (interpolate-quot) ;
81
82 MACRO: interpolate-locals ( str -- quot )
83     interpolate-locals-quot ;
84
85 : interpolate-locals>string ( str -- newstr )
86     [ interpolate-locals ] with-string-writer ; inline
87
88 SYNTAX: [I
89     "I]" parse-multiline-string
90     interpolate-locals-quot append! ;