forked from factor/factor
-
Notifications
You must be signed in to change notification settings - Fork 3
/
interpolate.factor
71 lines (57 loc) · 1.71 KB
/
interpolate.factor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
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: named-var name ;
TUPLE: stack-var n ;
: (parse-interpolate) ( str -- )
[
"${" split1-slice [
[ >string , ] unless-empty
] [
[
"}" split1-slice
[
>string dup string>number
[ stack-var boa ] [ named-var boa ] ?if ,
]
[ (parse-interpolate) ] bi*
] when*
] bi*
] unless-empty ;
: parse-interpolate ( str -- seq )
[ (parse-interpolate) ] { } make ;
: 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 ( str -- )
[ [ get ] ] interpolate-quot ;
: interpolate>string ( str -- newstr )
[ interpolate ] with-string-writer ; inline
: interpolate-locals ( str -- quot )
[ dup search [ [ ] ] [ [ get ] ] ?if ] interpolate-quot ;
SYNTAX: I[
"]I" parse-multiline-string
interpolate-locals append! ;