plasma 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/lib/extras/plasma_view.rb +8 -2
- data/lib/plasma.rb +3 -1
- data/lib/plasma/include/plasma_core.rb +4 -0
- data/lib/plasma/interpreter/plasma_grammar.rb +419 -88
- data/lib/plasma/interpreter/plasma_grammar.treetop +36 -8
- data/lib/plasma/interpreter/plasma_grammarnode.rb +74 -25
- data/lib/plasma/interpreter/plasma_interpreter.rb +16 -6
- data/lib/plasma/interpreter/polychoron_grammar.treetop +19 -0
- data/lib/plasma/template/plasma_template.rb +7 -3
- data/test/hanoi.plasma +18 -0
- data/test/parse_test.rb +49 -0
- data/test/template_test.plasma +42 -0
- data/test/template_test.rb +9 -0
- metadata +8 -4
- data/test/plasmatest.rb +0 -37
data/Rakefile
CHANGED
@@ -7,12 +7,12 @@ require 'rake/gempackagetask'
|
|
7
7
|
|
8
8
|
gemspec = Gem::Specification.new do |s|
|
9
9
|
s.name = "plasma"
|
10
|
-
s.version = "0.0
|
10
|
+
s.version = "0.1.0"
|
11
11
|
s.author = "Ryan Spangler"
|
12
12
|
s.email = "patch_work8848@yahoo.com"
|
13
13
|
s.homepage = "http://kaleidomedallion.com/plasma/"
|
14
14
|
s.platform = Gem::Platform::RUBY
|
15
|
-
s.summary = "plasma --- a lightweight interpreted templating language in ruby"
|
15
|
+
s.summary = "plasma --- a lightweight interpreted templating language in treetop and ruby"
|
16
16
|
s.files = FileList['README', 'Rakefile', "{test,lib,bin,doc,examples}/**/*"].to_a
|
17
17
|
s.bindir = 'bin'
|
18
18
|
s.executables = ['plasma']
|
data/lib/extras/plasma_view.rb
CHANGED
@@ -12,7 +12,13 @@ class PlasmaView
|
|
12
12
|
end
|
13
13
|
assigns.merge!(local_assigns)
|
14
14
|
|
15
|
-
plasma = Plasma::
|
16
|
-
|
15
|
+
plasma = Plasma::Interpreter::PlasmaGrammarParser.new
|
16
|
+
env = Plasma::Interpreter::Env.new(assigns)
|
17
|
+
|
18
|
+
tree = plasma.parse(template)
|
19
|
+
tree.evaluate(env)
|
17
20
|
end
|
18
21
|
end
|
22
|
+
|
23
|
+
|
24
|
+
|
data/lib/plasma.rb
CHANGED
@@ -2,10 +2,12 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
dir = File.dirname(__FILE__)
|
4
4
|
|
5
|
+
PLASMA_LIB = dir
|
5
6
|
PLASMA_ROOT = File.join(dir, 'plasma')
|
6
7
|
PLASMA_PACKAGE_ROOT = File.expand_path(dir + '/..')
|
8
|
+
PLASMA_TEST = File.join(PLASMA_PACKAGE_ROOT, 'test')
|
7
9
|
|
8
10
|
require File.join(PLASMA_ROOT, 'interpreter')
|
9
|
-
require File.join(
|
11
|
+
require File.join(PLASMA_LIB, 'extras/plasma_view')
|
10
12
|
|
11
13
|
$LOAD_PATH.unshift(dir)
|
@@ -4,7 +4,260 @@ module Plasma
|
|
4
4
|
include Treetop::Runtime
|
5
5
|
|
6
6
|
def root
|
7
|
-
@root || :
|
7
|
+
@root || :template
|
8
|
+
end
|
9
|
+
|
10
|
+
module Template0
|
11
|
+
def macro
|
12
|
+
elements[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
def tail
|
16
|
+
elements[1]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Template1
|
21
|
+
def head
|
22
|
+
elements[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def body
|
26
|
+
elements[1]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def _nt_template
|
31
|
+
start_index = index
|
32
|
+
if node_cache[:template].has_key?(index)
|
33
|
+
cached = node_cache[:template][index]
|
34
|
+
@index = cached.interval.end if cached
|
35
|
+
return cached
|
36
|
+
end
|
37
|
+
|
38
|
+
i0, s0 = index, []
|
39
|
+
s1, i1 = [], index
|
40
|
+
loop do
|
41
|
+
r2 = _nt_plain
|
42
|
+
if r2
|
43
|
+
s1 << r2
|
44
|
+
else
|
45
|
+
break
|
46
|
+
end
|
47
|
+
end
|
48
|
+
r1 = SyntaxNode.new(input, i1...index, s1)
|
49
|
+
s0 << r1
|
50
|
+
if r1
|
51
|
+
s3, i3 = [], index
|
52
|
+
loop do
|
53
|
+
i4, s4 = index, []
|
54
|
+
r5 = _nt_macro
|
55
|
+
s4 << r5
|
56
|
+
if r5
|
57
|
+
s6, i6 = [], index
|
58
|
+
loop do
|
59
|
+
r7 = _nt_plain
|
60
|
+
if r7
|
61
|
+
s6 << r7
|
62
|
+
else
|
63
|
+
break
|
64
|
+
end
|
65
|
+
end
|
66
|
+
r6 = SyntaxNode.new(input, i6...index, s6)
|
67
|
+
s4 << r6
|
68
|
+
end
|
69
|
+
if s4.last
|
70
|
+
r4 = (SyntaxNode).new(input, i4...index, s4)
|
71
|
+
r4.extend(Template0)
|
72
|
+
else
|
73
|
+
self.index = i4
|
74
|
+
r4 = nil
|
75
|
+
end
|
76
|
+
if r4
|
77
|
+
s3 << r4
|
78
|
+
else
|
79
|
+
break
|
80
|
+
end
|
81
|
+
end
|
82
|
+
r3 = SyntaxNode.new(input, i3...index, s3)
|
83
|
+
s0 << r3
|
84
|
+
end
|
85
|
+
if s0.last
|
86
|
+
r0 = (TemplateNode).new(input, i0...index, s0)
|
87
|
+
r0.extend(Template1)
|
88
|
+
else
|
89
|
+
self.index = i0
|
90
|
+
r0 = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
node_cache[:template][start_index] = r0
|
94
|
+
|
95
|
+
return r0
|
96
|
+
end
|
97
|
+
|
98
|
+
def _nt_plain
|
99
|
+
start_index = index
|
100
|
+
if node_cache[:plain].has_key?(index)
|
101
|
+
cached = node_cache[:plain][index]
|
102
|
+
@index = cached.interval.end if cached
|
103
|
+
return cached
|
104
|
+
end
|
105
|
+
|
106
|
+
if input.index(Regexp.new('[^\\[\\]`\']'), index) == index
|
107
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
108
|
+
@index += 1
|
109
|
+
else
|
110
|
+
r0 = nil
|
111
|
+
end
|
112
|
+
|
113
|
+
node_cache[:plain][start_index] = r0
|
114
|
+
|
115
|
+
return r0
|
116
|
+
end
|
117
|
+
|
118
|
+
def _nt_macro
|
119
|
+
start_index = index
|
120
|
+
if node_cache[:macro].has_key?(index)
|
121
|
+
cached = node_cache[:macro][index]
|
122
|
+
@index = cached.interval.end if cached
|
123
|
+
return cached
|
124
|
+
end
|
125
|
+
|
126
|
+
i0 = index
|
127
|
+
r1 = _nt_quote
|
128
|
+
if r1
|
129
|
+
r0 = r1
|
130
|
+
else
|
131
|
+
r2 = _nt_expansion
|
132
|
+
if r2
|
133
|
+
r0 = r2
|
134
|
+
else
|
135
|
+
self.index = i0
|
136
|
+
r0 = nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
node_cache[:macro][start_index] = r0
|
141
|
+
|
142
|
+
return r0
|
143
|
+
end
|
144
|
+
|
145
|
+
module Quote0
|
146
|
+
def template
|
147
|
+
elements[1]
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def _nt_quote
|
153
|
+
start_index = index
|
154
|
+
if node_cache[:quote].has_key?(index)
|
155
|
+
cached = node_cache[:quote][index]
|
156
|
+
@index = cached.interval.end if cached
|
157
|
+
return cached
|
158
|
+
end
|
159
|
+
|
160
|
+
i0, s0 = index, []
|
161
|
+
if input.index('`', index) == index
|
162
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
163
|
+
@index += 1
|
164
|
+
else
|
165
|
+
terminal_parse_failure('`')
|
166
|
+
r1 = nil
|
167
|
+
end
|
168
|
+
s0 << r1
|
169
|
+
if r1
|
170
|
+
r2 = _nt_template
|
171
|
+
s0 << r2
|
172
|
+
if r2
|
173
|
+
if input.index('\'', index) == index
|
174
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
175
|
+
@index += 1
|
176
|
+
else
|
177
|
+
terminal_parse_failure('\'')
|
178
|
+
r3 = nil
|
179
|
+
end
|
180
|
+
s0 << r3
|
181
|
+
end
|
182
|
+
end
|
183
|
+
if s0.last
|
184
|
+
r0 = (QuoteNode).new(input, i0...index, s0)
|
185
|
+
r0.extend(Quote0)
|
186
|
+
else
|
187
|
+
self.index = i0
|
188
|
+
r0 = nil
|
189
|
+
end
|
190
|
+
|
191
|
+
node_cache[:quote][start_index] = r0
|
192
|
+
|
193
|
+
return r0
|
194
|
+
end
|
195
|
+
|
196
|
+
module Expansion0
|
197
|
+
def x
|
198
|
+
elements[1]
|
199
|
+
end
|
200
|
+
|
201
|
+
def plasma
|
202
|
+
elements[2]
|
203
|
+
end
|
204
|
+
|
205
|
+
def x
|
206
|
+
elements[3]
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
def _nt_expansion
|
212
|
+
start_index = index
|
213
|
+
if node_cache[:expansion].has_key?(index)
|
214
|
+
cached = node_cache[:expansion][index]
|
215
|
+
@index = cached.interval.end if cached
|
216
|
+
return cached
|
217
|
+
end
|
218
|
+
|
219
|
+
i0, s0 = index, []
|
220
|
+
if input.index('[', index) == index
|
221
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
222
|
+
@index += 1
|
223
|
+
else
|
224
|
+
terminal_parse_failure('[')
|
225
|
+
r1 = nil
|
226
|
+
end
|
227
|
+
s0 << r1
|
228
|
+
if r1
|
229
|
+
r2 = _nt_x
|
230
|
+
s0 << r2
|
231
|
+
if r2
|
232
|
+
r3 = _nt_plasma
|
233
|
+
s0 << r3
|
234
|
+
if r3
|
235
|
+
r4 = _nt_x
|
236
|
+
s0 << r4
|
237
|
+
if r4
|
238
|
+
if input.index(']', index) == index
|
239
|
+
r5 = (SyntaxNode).new(input, index...(index + 1))
|
240
|
+
@index += 1
|
241
|
+
else
|
242
|
+
terminal_parse_failure(']')
|
243
|
+
r5 = nil
|
244
|
+
end
|
245
|
+
s0 << r5
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
if s0.last
|
251
|
+
r0 = (ExpansionNode).new(input, i0...index, s0)
|
252
|
+
r0.extend(Expansion0)
|
253
|
+
else
|
254
|
+
self.index = i0
|
255
|
+
r0 = nil
|
256
|
+
end
|
257
|
+
|
258
|
+
node_cache[:expansion][start_index] = r0
|
259
|
+
|
260
|
+
return r0
|
8
261
|
end
|
9
262
|
|
10
263
|
def _nt_plasma
|
@@ -64,24 +317,29 @@ module Plasma
|
|
64
317
|
if r12
|
65
318
|
r0 = r12
|
66
319
|
else
|
67
|
-
r13 =
|
320
|
+
r13 = _nt_regex
|
68
321
|
if r13
|
69
322
|
r0 = r13
|
70
323
|
else
|
71
|
-
r14 =
|
324
|
+
r14 = _nt_date
|
72
325
|
if r14
|
73
326
|
r0 = r14
|
74
327
|
else
|
75
|
-
r15 =
|
328
|
+
r15 = _nt_time
|
76
329
|
if r15
|
77
330
|
r0 = r15
|
78
331
|
else
|
79
|
-
r16 =
|
332
|
+
r16 = _nt_str
|
80
333
|
if r16
|
81
334
|
r0 = r16
|
82
335
|
else
|
83
|
-
|
84
|
-
|
336
|
+
r17 = _nt_num
|
337
|
+
if r17
|
338
|
+
r0 = r17
|
339
|
+
else
|
340
|
+
self.index = i0
|
341
|
+
r0 = nil
|
342
|
+
end
|
85
343
|
end
|
86
344
|
end
|
87
345
|
end
|
@@ -364,46 +622,6 @@ module Plasma
|
|
364
622
|
return r0
|
365
623
|
end
|
366
624
|
|
367
|
-
module Quote0
|
368
|
-
def plasma
|
369
|
-
elements[1]
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
def _nt_quote
|
374
|
-
start_index = index
|
375
|
-
if node_cache[:quote].has_key?(index)
|
376
|
-
cached = node_cache[:quote][index]
|
377
|
-
@index = cached.interval.end if cached
|
378
|
-
return cached
|
379
|
-
end
|
380
|
-
|
381
|
-
i0, s0 = index, []
|
382
|
-
if input.index("'", index) == index
|
383
|
-
r1 = (SyntaxNode).new(input, index...(index + 1))
|
384
|
-
@index += 1
|
385
|
-
else
|
386
|
-
terminal_parse_failure("'")
|
387
|
-
r1 = nil
|
388
|
-
end
|
389
|
-
s0 << r1
|
390
|
-
if r1
|
391
|
-
r2 = _nt_plasma
|
392
|
-
s0 << r2
|
393
|
-
end
|
394
|
-
if s0.last
|
395
|
-
r0 = (QuoteNode).new(input, i0...index, s0)
|
396
|
-
r0.extend(Quote0)
|
397
|
-
else
|
398
|
-
self.index = i0
|
399
|
-
r0 = nil
|
400
|
-
end
|
401
|
-
|
402
|
-
node_cache[:quote][start_index] = r0
|
403
|
-
|
404
|
-
return r0
|
405
|
-
end
|
406
|
-
|
407
625
|
module Defun0
|
408
626
|
def x
|
409
627
|
elements[1]
|
@@ -1171,7 +1389,7 @@ module Plasma
|
|
1171
1389
|
|
1172
1390
|
s0, i0 = [], index
|
1173
1391
|
loop do
|
1174
|
-
if input.index(Regexp.new('[a-z
|
1392
|
+
if input.index(Regexp.new('[a-z+!\\^&@?*%<>=_-]'), index) == index
|
1175
1393
|
r1 = (SyntaxNode).new(input, index...(index + 1))
|
1176
1394
|
@index += 1
|
1177
1395
|
else
|
@@ -1483,6 +1701,104 @@ module Plasma
|
|
1483
1701
|
return r0
|
1484
1702
|
end
|
1485
1703
|
|
1704
|
+
module Regex0
|
1705
|
+
def body
|
1706
|
+
elements[1]
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
def _nt_regex
|
1712
|
+
start_index = index
|
1713
|
+
if node_cache[:regex].has_key?(index)
|
1714
|
+
cached = node_cache[:regex][index]
|
1715
|
+
@index = cached.interval.end if cached
|
1716
|
+
return cached
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
i0, s0 = index, []
|
1720
|
+
if input.index('/', index) == index
|
1721
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
1722
|
+
@index += 1
|
1723
|
+
else
|
1724
|
+
terminal_parse_failure('/')
|
1725
|
+
r1 = nil
|
1726
|
+
end
|
1727
|
+
s0 << r1
|
1728
|
+
if r1
|
1729
|
+
s2, i2 = [], index
|
1730
|
+
loop do
|
1731
|
+
r3 = _nt_regex_char
|
1732
|
+
if r3
|
1733
|
+
s2 << r3
|
1734
|
+
else
|
1735
|
+
break
|
1736
|
+
end
|
1737
|
+
end
|
1738
|
+
r2 = SyntaxNode.new(input, i2...index, s2)
|
1739
|
+
s0 << r2
|
1740
|
+
if r2
|
1741
|
+
if input.index('/', index) == index
|
1742
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
1743
|
+
@index += 1
|
1744
|
+
else
|
1745
|
+
terminal_parse_failure('/')
|
1746
|
+
r4 = nil
|
1747
|
+
end
|
1748
|
+
s0 << r4
|
1749
|
+
end
|
1750
|
+
end
|
1751
|
+
if s0.last
|
1752
|
+
r0 = (RegexNode).new(input, i0...index, s0)
|
1753
|
+
r0.extend(Regex0)
|
1754
|
+
else
|
1755
|
+
self.index = i0
|
1756
|
+
r0 = nil
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
node_cache[:regex][start_index] = r0
|
1760
|
+
|
1761
|
+
return r0
|
1762
|
+
end
|
1763
|
+
|
1764
|
+
def _nt_regex_char
|
1765
|
+
start_index = index
|
1766
|
+
if node_cache[:regex_char].has_key?(index)
|
1767
|
+
cached = node_cache[:regex_char][index]
|
1768
|
+
@index = cached.interval.end if cached
|
1769
|
+
return cached
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
i0 = index
|
1773
|
+
if input.index('\\/', index) == index
|
1774
|
+
r1 = (SyntaxNode).new(input, index...(index + 2))
|
1775
|
+
@index += 2
|
1776
|
+
else
|
1777
|
+
terminal_parse_failure('\\/')
|
1778
|
+
r1 = nil
|
1779
|
+
end
|
1780
|
+
if r1
|
1781
|
+
r0 = r1
|
1782
|
+
else
|
1783
|
+
if input.index(Regexp.new('[^/]'), index) == index
|
1784
|
+
r2 = (SyntaxNode).new(input, index...(index + 1))
|
1785
|
+
@index += 1
|
1786
|
+
else
|
1787
|
+
r2 = nil
|
1788
|
+
end
|
1789
|
+
if r2
|
1790
|
+
r0 = r2
|
1791
|
+
else
|
1792
|
+
self.index = i0
|
1793
|
+
r0 = nil
|
1794
|
+
end
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
node_cache[:regex_char][start_index] = r0
|
1798
|
+
|
1799
|
+
return r0
|
1800
|
+
end
|
1801
|
+
|
1486
1802
|
module Date0
|
1487
1803
|
def s
|
1488
1804
|
elements[0]
|
@@ -1747,14 +2063,10 @@ module Plasma
|
|
1747
2063
|
end
|
1748
2064
|
|
1749
2065
|
module Str0
|
1750
|
-
def
|
2066
|
+
def body
|
1751
2067
|
elements[1]
|
1752
2068
|
end
|
1753
2069
|
|
1754
|
-
def rest
|
1755
|
-
elements[2]
|
1756
|
-
end
|
1757
|
-
|
1758
2070
|
end
|
1759
2071
|
|
1760
2072
|
def _nt_str
|
@@ -1775,45 +2087,26 @@ module Plasma
|
|
1775
2087
|
end
|
1776
2088
|
s0 << r1
|
1777
2089
|
if r1
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
else
|
1787
|
-
r2 = SyntaxNode.new(input, index...index)
|
2090
|
+
s2, i2 = [], index
|
2091
|
+
loop do
|
2092
|
+
r3 = _nt_str_char
|
2093
|
+
if r3
|
2094
|
+
s2 << r3
|
2095
|
+
else
|
2096
|
+
break
|
2097
|
+
end
|
1788
2098
|
end
|
2099
|
+
r2 = SyntaxNode.new(input, i2...index, s2)
|
1789
2100
|
s0 << r2
|
1790
2101
|
if r2
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
r5 = nil
|
1798
|
-
end
|
1799
|
-
if r5
|
1800
|
-
s4 << r5
|
1801
|
-
else
|
1802
|
-
break
|
1803
|
-
end
|
2102
|
+
if input.index('"', index) == index
|
2103
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
2104
|
+
@index += 1
|
2105
|
+
else
|
2106
|
+
terminal_parse_failure('"')
|
2107
|
+
r4 = nil
|
1804
2108
|
end
|
1805
|
-
r4 = SyntaxNode.new(input, i4...index, s4)
|
1806
2109
|
s0 << r4
|
1807
|
-
if r4
|
1808
|
-
if input.index('"', index) == index
|
1809
|
-
r6 = (SyntaxNode).new(input, index...(index + 1))
|
1810
|
-
@index += 1
|
1811
|
-
else
|
1812
|
-
terminal_parse_failure('"')
|
1813
|
-
r6 = nil
|
1814
|
-
end
|
1815
|
-
s0 << r6
|
1816
|
-
end
|
1817
2110
|
end
|
1818
2111
|
end
|
1819
2112
|
if s0.last
|
@@ -1829,6 +2122,44 @@ module Plasma
|
|
1829
2122
|
return r0
|
1830
2123
|
end
|
1831
2124
|
|
2125
|
+
def _nt_str_char
|
2126
|
+
start_index = index
|
2127
|
+
if node_cache[:str_char].has_key?(index)
|
2128
|
+
cached = node_cache[:str_char][index]
|
2129
|
+
@index = cached.interval.end if cached
|
2130
|
+
return cached
|
2131
|
+
end
|
2132
|
+
|
2133
|
+
i0 = index
|
2134
|
+
if input.index('\\"', index) == index
|
2135
|
+
r1 = (SyntaxNode).new(input, index...(index + 2))
|
2136
|
+
@index += 2
|
2137
|
+
else
|
2138
|
+
terminal_parse_failure('\\"')
|
2139
|
+
r1 = nil
|
2140
|
+
end
|
2141
|
+
if r1
|
2142
|
+
r0 = r1
|
2143
|
+
else
|
2144
|
+
if input.index(Regexp.new('[^"]'), index) == index
|
2145
|
+
r2 = (SyntaxNode).new(input, index...(index + 1))
|
2146
|
+
@index += 1
|
2147
|
+
else
|
2148
|
+
r2 = nil
|
2149
|
+
end
|
2150
|
+
if r2
|
2151
|
+
r0 = r2
|
2152
|
+
else
|
2153
|
+
self.index = i0
|
2154
|
+
r0 = nil
|
2155
|
+
end
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
node_cache[:str_char][start_index] = r0
|
2159
|
+
|
2160
|
+
return r0
|
2161
|
+
end
|
2162
|
+
|
1832
2163
|
module Num0
|
1833
2164
|
end
|
1834
2165
|
|
@@ -1837,7 +2168,7 @@ module Plasma
|
|
1837
2168
|
elements[0]
|
1838
2169
|
end
|
1839
2170
|
|
1840
|
-
def
|
2171
|
+
def decimal
|
1841
2172
|
elements[1]
|
1842
2173
|
end
|
1843
2174
|
end
|
@@ -1,8 +1,28 @@
|
|
1
1
|
module Plasma
|
2
2
|
module Interpreter
|
3
3
|
grammar PlasmaGrammar
|
4
|
+
rule template
|
5
|
+
head:(plain)* body:(macro tail:(plain)*)* <TemplateNode>
|
6
|
+
end
|
7
|
+
|
8
|
+
rule plain
|
9
|
+
[^\[\]`'] #`
|
10
|
+
end
|
11
|
+
|
12
|
+
rule macro
|
13
|
+
quote / expansion
|
14
|
+
end
|
15
|
+
|
16
|
+
rule quote
|
17
|
+
'`' template '\'' <QuoteNode>
|
18
|
+
end
|
19
|
+
|
20
|
+
rule expansion
|
21
|
+
'[' x plasma x ']' <ExpansionNode>
|
22
|
+
end
|
23
|
+
|
4
24
|
rule plasma
|
5
|
-
decl / seq / quote / defun / def / fun / if / apply / bool / sym / hash / list / date / time / str / num
|
25
|
+
decl / seq / quote / defun / def / fun / if / apply / bool / sym / hash / list / regex / date / time / str / num
|
6
26
|
end
|
7
27
|
|
8
28
|
rule decl
|
@@ -13,10 +33,6 @@ module Plasma
|
|
13
33
|
'(' x first:plasma? rest:(s '|' s plasma)* x ')' <SeqNode>
|
14
34
|
end
|
15
35
|
|
16
|
-
rule quote
|
17
|
-
"'" plasma <QuoteNode>
|
18
|
-
end
|
19
|
-
|
20
36
|
rule defun
|
21
37
|
'(' x 'defun' s params s plasma x ')' <DefunNode>
|
22
38
|
end
|
@@ -46,7 +62,7 @@ module Plasma
|
|
46
62
|
end
|
47
63
|
|
48
64
|
rule sym
|
49
|
-
[a-z
|
65
|
+
[a-z+!\^&@?*%<>=_-]+ <SymNode>
|
50
66
|
end
|
51
67
|
|
52
68
|
rule hash
|
@@ -61,6 +77,14 @@ module Plasma
|
|
61
77
|
'[' x first:plasma? rest:(s plasma)* x ']' <ListNode>
|
62
78
|
end
|
63
79
|
|
80
|
+
rule regex
|
81
|
+
'/' body:(regex_char)* '/' <RegexNode>
|
82
|
+
end
|
83
|
+
|
84
|
+
rule regex_char
|
85
|
+
'\\/' / [^/]
|
86
|
+
end
|
87
|
+
|
64
88
|
rule date
|
65
89
|
year [-] month:dual [-] day:dual (s time)? <DateNode>
|
66
90
|
end
|
@@ -78,11 +102,15 @@ module Plasma
|
|
78
102
|
end
|
79
103
|
|
80
104
|
rule str
|
81
|
-
'"'
|
105
|
+
'"' body:(str_char)* '"' <StrNode>
|
106
|
+
end
|
107
|
+
|
108
|
+
rule str_char
|
109
|
+
'\\"' / [^"] #"
|
82
110
|
end
|
83
111
|
|
84
112
|
rule num
|
85
|
-
whole:([0-9]+)
|
113
|
+
whole:([0-9]+) decimal:('.' [0-9]+)? <NumNode>
|
86
114
|
end
|
87
115
|
|
88
116
|
rule x
|
@@ -37,6 +37,20 @@ module Plasma
|
|
37
37
|
self
|
38
38
|
end
|
39
39
|
|
40
|
+
def scope(inner={})
|
41
|
+
self.scope!(inner)
|
42
|
+
|
43
|
+
begin
|
44
|
+
value = yield self
|
45
|
+
self.release!
|
46
|
+
|
47
|
+
return value
|
48
|
+
rescue => detail
|
49
|
+
self.release!
|
50
|
+
detail
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
40
54
|
def resolve(key)
|
41
55
|
@state.reverse_each do |layer|
|
42
56
|
return layer[key] if layer.include?(key)
|
@@ -55,11 +69,11 @@ module Plasma
|
|
55
69
|
end
|
56
70
|
|
57
71
|
def unquote(env)
|
58
|
-
@unevaluated.
|
72
|
+
@unevaluated.evaluate(env)
|
59
73
|
end
|
60
74
|
|
61
75
|
def to_plasma
|
62
|
-
"
|
76
|
+
"`#{@unevaluated.text_value}'"
|
63
77
|
end
|
64
78
|
end
|
65
79
|
|
@@ -80,11 +94,9 @@ module Plasma
|
|
80
94
|
zipped.merge!(:env => @env)
|
81
95
|
|
82
96
|
if left.empty?
|
83
|
-
@env.scope
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
return value
|
97
|
+
@env.scope(zipped) do |env|
|
98
|
+
@body.evaluate(env)
|
99
|
+
end
|
88
100
|
else
|
89
101
|
return Closure.new(@env.dup.merge!(zipped), left, body)
|
90
102
|
end
|
@@ -121,7 +133,7 @@ module Plasma
|
|
121
133
|
keys = fresh.keys.join(' ')
|
122
134
|
env = Env.new(fresh.merge(@name => self))
|
123
135
|
|
124
|
-
interp.interpret("fun (#{params}) (
|
136
|
+
interp.interpret("fun (#{params}) (#{@name} #{keys} #{params})", env)
|
125
137
|
end
|
126
138
|
end
|
127
139
|
end
|
@@ -174,30 +186,57 @@ module Plasma
|
|
174
186
|
end
|
175
187
|
end
|
176
188
|
|
177
|
-
class
|
189
|
+
class Treetop::Runtime::SyntaxNode
|
190
|
+
def to_s
|
191
|
+
text_value
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class TemplateNode < PlasmaNode
|
178
196
|
def evaluate(env)
|
179
|
-
value =
|
180
|
-
|
197
|
+
value = body.empty? ? '' : body.elements.inject('') do |so_far, el|
|
198
|
+
macro_value = el.macro.is_a?(ExpansionNode) ? el.macro.evaluate(env).to_s : el.macro.template.text_value
|
199
|
+
tail_value = el.respond_to?(:tail) ? el.tail.text_value : ''
|
200
|
+
|
201
|
+
so_far + macro_value + tail_value
|
181
202
|
end
|
182
|
-
value
|
203
|
+
head.text_value + value
|
183
204
|
end
|
184
205
|
end
|
185
206
|
|
186
|
-
class
|
207
|
+
class PlainNode < PlasmaNode
|
187
208
|
def evaluate(env)
|
188
|
-
|
189
|
-
|
209
|
+
self.text_value
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class QuoteNode < PlasmaNode
|
214
|
+
def evaluate(env)
|
215
|
+
template.evaluate(env)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class ExpansionNode < PlasmaNode
|
220
|
+
def evaluate(env)
|
221
|
+
plasma.evaluate(env)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class DeclNode < ColNode
|
226
|
+
def evaluate(env)
|
227
|
+
col.inject(nil) do |value, statement|
|
190
228
|
statement.evaluate(env)
|
191
229
|
end
|
192
|
-
env.release!
|
193
|
-
|
194
|
-
value
|
195
230
|
end
|
196
231
|
end
|
197
232
|
|
198
|
-
class
|
233
|
+
class SeqNode < ColNode
|
199
234
|
def evaluate(env)
|
200
|
-
|
235
|
+
env.scope do |env|
|
236
|
+
col.inject(nil) do |value, statement|
|
237
|
+
statement.evaluate(env)
|
238
|
+
end
|
239
|
+
end
|
201
240
|
end
|
202
241
|
end
|
203
242
|
|
@@ -207,7 +246,7 @@ module Plasma
|
|
207
246
|
closure = Closure.new(env, syms.slice(1..syms.length), plasma)
|
208
247
|
closure.env.merge!(syms[0] => closure)
|
209
248
|
env.bind!(syms[0], closure)
|
210
|
-
|
249
|
+
''
|
211
250
|
end
|
212
251
|
end
|
213
252
|
|
@@ -215,7 +254,7 @@ module Plasma
|
|
215
254
|
def evaluate(env)
|
216
255
|
value = plasma.evaluate(env)
|
217
256
|
env.bind!(sym.text_value.to_sym, value)
|
218
|
-
|
257
|
+
''
|
219
258
|
end
|
220
259
|
end
|
221
260
|
|
@@ -305,6 +344,12 @@ module Plasma
|
|
305
344
|
end
|
306
345
|
end
|
307
346
|
|
347
|
+
class RegexNode < PlasmaNode
|
348
|
+
def evaluate(env)
|
349
|
+
Regexp.new(body.text_value)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
308
353
|
class DateNode < PlasmaNode
|
309
354
|
def evaluate(env)
|
310
355
|
end
|
@@ -315,15 +360,19 @@ module Plasma
|
|
315
360
|
end
|
316
361
|
end
|
317
362
|
|
318
|
-
class StrNode <
|
363
|
+
class StrNode < PlasmaNode
|
319
364
|
def evaluate(env)
|
320
|
-
|
365
|
+
body.text_value
|
321
366
|
end
|
322
367
|
end
|
323
368
|
|
324
369
|
class NumNode < PlasmaNode
|
325
370
|
def evaluate(env)
|
326
|
-
|
371
|
+
if self.respond_to?(:decimal)
|
372
|
+
text_value.to_f
|
373
|
+
else
|
374
|
+
text_value.to_i
|
375
|
+
end
|
327
376
|
end
|
328
377
|
end
|
329
378
|
end
|
@@ -5,6 +5,8 @@ module Plasma
|
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@prompt = "-----| "
|
8
|
+
@comment = /##*[^#]+##*/
|
9
|
+
|
8
10
|
@dir = File.dirname(__FILE__)
|
9
11
|
@load_path = [File.join(PLASMA_ROOT, 'include'), PLASMA_PACKAGE_ROOT, @dir]
|
10
12
|
|
@@ -67,6 +69,10 @@ module Plasma
|
|
67
69
|
raise NoSuchSourceException.new(plasma), "no such source #{plasma}", caller
|
68
70
|
end
|
69
71
|
|
72
|
+
def strip(code)
|
73
|
+
code.gsub(@comment, '').strip
|
74
|
+
end
|
75
|
+
|
70
76
|
def parse(code)
|
71
77
|
tree = @plasma.parse(code)
|
72
78
|
raise FailedToParseException.new, "failed to parse #{code}", caller if tree.nil?
|
@@ -75,12 +81,12 @@ module Plasma
|
|
75
81
|
end
|
76
82
|
|
77
83
|
def evaluate(tree, env=nil)
|
78
|
-
env
|
84
|
+
env ||= @env
|
79
85
|
tree.evaluate(env)
|
80
86
|
end
|
81
87
|
|
82
88
|
def interpret(code, env=nil)
|
83
|
-
tree = parse(code)
|
89
|
+
tree = parse(strip(code))
|
84
90
|
evaluate(tree, env)
|
85
91
|
end
|
86
92
|
|
@@ -88,14 +94,18 @@ module Plasma
|
|
88
94
|
while true
|
89
95
|
begin
|
90
96
|
STDOUT.write(@prompt)
|
97
|
+
|
91
98
|
input = STDIN.readline.strip
|
92
|
-
|
99
|
+
unless input.empty?
|
93
100
|
|
94
|
-
|
101
|
+
value = interpret input
|
95
102
|
|
96
|
-
|
103
|
+
STDOUT.write(" #{value.to_plasma}\n")
|
104
|
+
end
|
105
|
+
rescue EOFError => e
|
106
|
+
break
|
97
107
|
rescue Exception => e
|
98
|
-
STDOUT.write(" #{e
|
108
|
+
STDOUT.write(" #{e}\n")
|
99
109
|
end
|
100
110
|
end
|
101
111
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Plasma
|
2
|
+
module Interpreter
|
3
|
+
grammar PolychoronGrammar
|
4
|
+
include plasma
|
5
|
+
|
6
|
+
rule template
|
7
|
+
first:plain? rest:('[' s body:polychoron s ']' tail:plain?)* <TemplateNode>
|
8
|
+
end
|
9
|
+
|
10
|
+
rule plain
|
11
|
+
[^[`]+ <PlainNode> #`
|
12
|
+
end
|
13
|
+
|
14
|
+
rule polychoron
|
15
|
+
plasma
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Plasma
|
2
2
|
module Template
|
3
3
|
class PlasmaTemplate
|
4
|
-
|
4
|
+
attr_accessor :plasma
|
5
|
+
|
6
|
+
@@separator = /##*[^#]+##*/
|
5
7
|
|
6
8
|
def self.parse(template)
|
7
9
|
return PlasmaTemplate.new(template)
|
@@ -40,8 +42,8 @@ module Plasma
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
def render(
|
44
|
-
@plasma.env.merge!(
|
45
|
+
def render(rel={})
|
46
|
+
@plasma.env.merge!(rel)
|
45
47
|
evaluated = @plasmic.map{|p| @plasma.evaluate(p)}
|
46
48
|
|
47
49
|
rendered = ''
|
@@ -55,3 +57,5 @@ module Plasma
|
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
60
|
+
|
61
|
+
|
data/test/hanoi.plasma
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
[(def move
|
2
|
+
(fun (a b) `move disk from [a] to [b]
|
3
|
+
' ))]
|
4
|
+
|
5
|
+
[(def do_hanoi
|
6
|
+
(fun (a b c d)
|
7
|
+
(if (<= a 1)
|
8
|
+
then (move b c)
|
9
|
+
else `[(do_hanoi (- a 1) b d c)][(move b c)][(do_hanoi (- a 1) d c b)]')))]
|
10
|
+
|
11
|
+
[(def hanoi
|
12
|
+
(fun (n)
|
13
|
+
(do_hanoi n "source" "destination" "auxillary"))) ]
|
14
|
+
|
15
|
+
[(def levels 5)]
|
16
|
+
|
17
|
+
Tower of Hanoi ([levels] levels)
|
18
|
+
[(hanoi 5)]
|
data/test/parse_test.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'lib/plasma.rb'
|
2
|
+
|
3
|
+
plasma = Plasma::Interpreter::PlasmaGrammarParser.new
|
4
|
+
|
5
|
+
decl = "[| `eiii' | 1233333 | def xxx 5 |]"
|
6
|
+
declb = "[xxx]"
|
7
|
+
seq = "[(`oeheo' | 238 | 11)]"
|
8
|
+
quote = "[`(333333)']"
|
9
|
+
define = "[(def a 2121212 | a)]"
|
10
|
+
defun = "[(defun (ff x) (* x 13) | (ff 14))]"
|
11
|
+
fun = "[(fun (x c) (+ x c))]"
|
12
|
+
apply1 = "[(+ 11 14)]"
|
13
|
+
apply2 = "[((fun (x c) (+ x c)) 11 14)]"
|
14
|
+
curry = "[(def aaa ((fun (a b) (* a b)) 3) | (aaa 11))]"
|
15
|
+
sym = "[(def tatao+ht-o*he<>i==== 555 | tatao+ht-o*he<>i====)]"
|
16
|
+
hash = "[{yayay:77777 rrr:111}]"
|
17
|
+
list = "[[11 33 449]]"
|
18
|
+
regex = "[/[^7]*777\\/88?/]"
|
19
|
+
date = "[3409-65-22]"
|
20
|
+
time = "[55:32:18]"
|
21
|
+
str = '["yaodui iw\"fhoeo"]'
|
22
|
+
num = "[444.22]"
|
23
|
+
test = "[| def yar (fun (x) (* 3 x)) |
|
24
|
+
def peanut (fun (y z) (/ (- y z) z)) |
|
25
|
+
(peanut (yar 66) 12) |]"
|
26
|
+
bad = "[(999)(888)]"
|
27
|
+
cond = "[(if (> xxx 13) then 12 else [3 3 5 3])]"
|
28
|
+
|
29
|
+
template = "ol[(* 3 8)] weee! [(* \"okok\" 5)] okoko NO no way okay but [\"how about now\"] yes?" #"
|
30
|
+
template2 = "yayayay``nonono'ya'yayay"
|
31
|
+
|
32
|
+
env = Plasma::Interpreter::Env.new
|
33
|
+
|
34
|
+
|
35
|
+
statements = []
|
36
|
+
statements += [seq, quote, define, defun, fun, apply1, apply2,
|
37
|
+
sym, hash, list, regex, date, time, str, num, test,
|
38
|
+
decl, declb, defun, bad, curry, cond]
|
39
|
+
|
40
|
+
statements += [template, template2]
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
statements.each do |statement|
|
45
|
+
parsed = plasma.parse(statement)
|
46
|
+
evaluated = parsed.nil? ? "does not parse" : parsed.evaluate(env).to_plasma
|
47
|
+
|
48
|
+
puts "#{statement} -> #{parsed.class} : #{evaluated}"
|
49
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
okay so we are starting out clear
|
2
|
+
|
3
|
+
[( def fi 3 )]
|
4
|
+
[( def ya (fun (x) (* x 3)) )]
|
5
|
+
[( def ikik (map ["rrr" "uiowoyqpp i " fi "nogo deetdelowu"] ya) )]
|
6
|
+
[( * 55 12 )]
|
7
|
+
[( join ikik " " )]
|
8
|
+
|
9
|
+
continuing on now... maybe I will throw in a [(* 3 5)] just for fun. Yes?
|
10
|
+
what about Ifs, and loops? All about control flow.
|
11
|
+
|
12
|
+
[( if (true)
|
13
|
+
then `what?? [(* "yes" 14)] Really?'
|
14
|
+
else `yes really.' )]
|
15
|
+
|
16
|
+
So that almost makes sense. The grouping should really be more clear though.
|
17
|
+
maybe something with a directional brace, something like {{ maybe? }}
|
18
|
+
|
19
|
+
no.
|
20
|
+
|
21
|
+
[( def new (fun (x) (x "lalala")) )]
|
22
|
+
[( def thing (fun (y) (concat (* y 3) " dogono")) )]
|
23
|
+
[( def x "palatial" )]
|
24
|
+
|
25
|
+
So it will go like this... [( new thing )] and maybe another
|
26
|
+
[( if (> x "borox")
|
27
|
+
then `this could happen if [ x ] was defined they would all be substit[`u']ted'
|
28
|
+
else (* 3 11) )]
|
29
|
+
And maybe a function could go
|
30
|
+
[( def follow (fun (x) `okay now this is plain text again? How did [x] that happen? I guess in the quote???') )]
|
31
|
+
now we go along for a while and end up with a call to [( follow 3 )] and end up with something significant? So the scopes switch back and forth? That cant be right!
|
32
|
+
|
33
|
+
Okay, calling the macro and quoting are two different things. They must be treated differently. Okay
|
34
|
+
|
35
|
+
|
36
|
+
Now for some tricky shit:
|
37
|
+
|
38
|
+
[( def dog `now a thing for [( thing `yes maybe just [x] ' )] and some more' )]
|
39
|
+
[( dog )]
|
40
|
+
|
41
|
+
|
42
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plasma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Spangler
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-08-
|
12
|
+
date: 2008-08-18 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,9 +32,12 @@ extra_rdoc_files: []
|
|
32
32
|
files:
|
33
33
|
- README
|
34
34
|
- Rakefile
|
35
|
+
- test/hanoi.plasma
|
35
36
|
- test/import_test.plasma
|
36
|
-
- test/
|
37
|
+
- test/parse_test.rb
|
37
38
|
- test/plasmic.plasma
|
39
|
+
- test/template_test.plasma
|
40
|
+
- test/template_test.rb
|
38
41
|
- lib/extras
|
39
42
|
- lib/extras/plasma_view.rb
|
40
43
|
- lib/plasma
|
@@ -47,6 +50,7 @@ files:
|
|
47
50
|
- lib/plasma/interpreter/plasma_grammar.treetop
|
48
51
|
- lib/plasma/interpreter/plasma_grammarnode.rb
|
49
52
|
- lib/plasma/interpreter/plasma_interpreter.rb
|
53
|
+
- lib/plasma/interpreter/polychoron_grammar.treetop
|
50
54
|
- lib/plasma/interpreter.rb
|
51
55
|
- lib/plasma/template
|
52
56
|
- lib/plasma/template/plasma_template.rb
|
@@ -78,6 +82,6 @@ rubyforge_project: plasma
|
|
78
82
|
rubygems_version: 1.0.1
|
79
83
|
signing_key:
|
80
84
|
specification_version: 2
|
81
|
-
summary: plasma --- a lightweight interpreted templating language in ruby
|
85
|
+
summary: plasma --- a lightweight interpreted templating language in treetop and ruby
|
82
86
|
test_files: []
|
83
87
|
|
data/test/plasmatest.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'lib/plasma.rb'
|
2
|
-
|
3
|
-
plasma = Plasma::Interpreter::PlasmaGrammarParser.new
|
4
|
-
|
5
|
-
decl = "| 'eiii | 1233333 | (def xxx 5) |"
|
6
|
-
declb = "xxx"
|
7
|
-
seq = "('oeheo | 238 | 11)"
|
8
|
-
quote = "'(333333)"
|
9
|
-
define = "((def a 2121212) | a)"
|
10
|
-
defun = "(defun (ff x) (* x 13))"
|
11
|
-
fun = "(fun (x c) (+ x c))"
|
12
|
-
apply1 = "(+ 11 14)"
|
13
|
-
apply2 = "((fun (x c) (+ x c)) 11 14)"
|
14
|
-
curry = "((def aaa ((fun (a b) (* a b)) 3)) | (aaa 11))"
|
15
|
-
sym = "((def tatao+ht-o*he<>i==== 555) | tatao+ht-o*he<>i====)"
|
16
|
-
hash = "{yayay:77777 rrr:111}"
|
17
|
-
list = "[11 33 449]"
|
18
|
-
date = "3409-65-22"
|
19
|
-
time = "55:32:18"
|
20
|
-
str = '"yaodui iwfhoeo"'
|
21
|
-
num = "444.22"
|
22
|
-
test = "| (def yar (fun (x) (* 3 x))) |
|
23
|
-
(def peanut (fun (y z) (/ (- y z) z))) |
|
24
|
-
(peanut (yar 66) 12) |"
|
25
|
-
bad = "(999)(888)"
|
26
|
-
env = Plasma::Interpreter::Env.new
|
27
|
-
|
28
|
-
|
29
|
-
statements = [seq, quote, define, defun, fun, apply1, apply2,
|
30
|
-
sym, hash, list, date, time, str, num, test,
|
31
|
-
decl, declb, defun, bad, curry]
|
32
|
-
statements.each do |statement|
|
33
|
-
parsed = plasma.parse(statement)
|
34
|
-
evaluated = parsed.nil? ? "does not parse" : parsed.evaluate(env).to_plasma
|
35
|
-
|
36
|
-
puts "#{statement} -> #{parsed} : #{evaluated}"
|
37
|
-
end
|