smalltalk-tng
view experiments/experimental-syntax.tng2 @ 321:c4a0718c2d3c
Sketch of dependencies
| author | Tony Garnock-Jones <tonygarnockjones@gmail.com> |
|---|---|
| date | Sat Oct 08 15:36:03 2011 -0400 (7 months ago) |
| parents | |
| children |
line source
1 "
3 So, let's assume data constructors for
5 - labelled product types
6 - unlabelled product types
8 What about sum types? What about lists?
10 label: value label: value label: value
11 a, b, c
13 Core lazy lambda:
15 - application
16 - abstraction
18 Reinterpreting these in a reflective lambda:
20 - split application up:
21 - substitution
22 - evaluation
23 - abstraction stays.
25 Syntax for lazy lambda:
27 - application: adjacency?
29 writeLine ""Hello, World!""
31 - abstraction: some kind of block syntax
33 (pattern -> expr)
35 (define (parse-results-next results)
36 (let ((next (parse-results-next* results)))
37 (if (procedure? next)
38 (let ((next-value (next)))
39 (set-parse-results-next! results next-value)
40 next-value)
41 next)))
43 "
45 module packrat
47 (
48 let: next be: (atomic: get: next*: results),
49 if: (procedure?: next)
50 then: (let: next-value be: (apply: next),
51 atomic: set: (next*: results) to: next-value,
52 next-value)
53 else: next
54 )
56 [
57 tvar <- results next*.
58 [
59 next <- tvar value.
60 next procedure?
61 ifTrue: [next-value <- next apply.
62 tvar value: next-value.
63 next-value]
64 ifFalse: [next]
65 ] atomic
66 ]
68 [
69 results next* -> tvar.
70 [
71 tvar value -> next.
72 next procedure?
73 ifTrue: [next apply -> next-value.
74 tvar value: next-value.
75 next-value]
76 ifFalse: [next]
77 ] atomic
78 ]
80 Collection do: Block
81 (-> (c, b).
82 1 to: (c size) do: (-> i. b apply: (c at: i)).)
85 -> results.
86 results next* -> tvar.
87 [
88 tvar value -> next.
89 next procedure?
90 ifTrue: [$next -> next-value.
91 tvar value: next-value.
92 next-value]
93 ifFalse: [next].
94 ] atomic.
98 -> (list @ Pair car: a cdr: d, block @ -> _ . _).
99 Pair car: ($block a) cdr: (d map: block).
101 -> (Nil, block @ -> _ . _).
102 Nil.
105 myList map: (-> e. e + 3) -> result.
110 -> results.
111 next* results -> tvar.
112 atomic [
113 value tvar -> next.
114 if: procedure? next
115 then: [$next -> next-value.
116 tvar value: next-value.
117 next-value]
118 else: [next].
119 ].
123 bind (-> over: (list @ Pair car: a cdr: d) map: (block @ -> _ . _).
124 Pair car: ($block a) cdr: (over: d map: block)).
126 bind (-> over: Nil map: (block @ -> _ . _).
127 Nil).
129 bind (-> succ (i @ Integer). i + 1).
132 bind (-> merge: (e1 @ ParseErrors _) with: e2 . e1).
133 bind (-> merge: e1 with: (e2 @ ParseErrors _) . e2).
134 bind (-> merge: (e1 @ ParseErrors pos: p1 \ _)
135 with: (e2 @ ParseErrors pos: p2 \ _).
136 cond: (
137 [[p1 > p2] || [empty? e2]] => [e1],
138 [[p2 > p1] || [empty? e1]] => [e2]
139 ) else: [ParseErrors pos: p1
140 expected: (union (expected e1, expected e2))
141 messages: (append (messages e1, messages e2))]).
152 bind (-> over: list @ Pair^(car: a cdr: d)
153 map: block @ (-> _ . _).
154 Pair^ car: ($block a) cdr: (over: d map: block)).
156 bind (-> over: list @ Nil^_
157 map: block @ (-> _ . _).
158 list).
160 bind (-> succ (i @ Integer^_). i + 1).
163 bind (-> merge: (e1 @ ParseErrors^_) with: e2 . e1).
164 bind (-> merge: e1 with: (e2 @ ParseErrors^_) . e2).
165 bind (-> merge: (e1 @ ParseErrors^ pos: p1 \ _)
166 with: (e2 @ ParseErrors^ pos: p2 \ _).
167 cond: (
168 [[p1 > p2] || [empty? e2]] => [e1],
169 [[p2 > p1] || [empty? e1]] => [e2]
170 ) else: [ParseErrors^ pos: p1
171 expected: expected e1 `union` expected e2
172 messages: messages e1 `append` messages e2]).
183 bind (-> over: list @ Pair{car: a cdr: d}
184 map: block @ (-> _ . _).
185 Pair{car: ($block a) cdr: (over: d map: block)}.
187 bind (-> over: list @ Nil{}
188 map: block @ (-> _ . _).
189 list).
191 bind (-> succ (i @ Integer{}). i + 1).
194 bind (-> merge: e1 @ ParseErrors{} with: e2 . e1).
195 bind (-> merge: e1 with: e2 @ ParseErrors{} . e2).
196 bind (-> merge: e1 @ ParseErrors{pos: p1 expected: x1 messages: m1}
197 with: e2 @ ParseErrors{pos: p2 expected: x2 messages: m2}
198 .
199 Cond {
200 [[p1 > p2] || [empty? e2]] => [e1],
201 [[p2 > p1] || [empty? e1]] => [e2]
202 } else: [ParseErrors{pos: p1
203 expected: x1 `union` x2
204 messages: m1 `append` m2}]
205 ).
207 bind (-> next results @ ParseResults{next: tvar} .
208 atomic [
209 !tvar -> next.
210 if: procedure? next
211 then: [$next -> next-value.
212 tvar := next-value.
213 next-value]
214 else: [next].
215 ].
216 ).
219 [
220 "This is to parse as 'meta (-> m. ...)'."
221 meta -> m.
222 dict at: key ifAbsent: [m `return` false] -> val.
223 val
224 ]
233 "Now, experiment without the [] syntax for nullary functions"
235 bind (-> merge: e1 @ ParseErrors{} with: e2 . e1).
236 bind (-> merge: e1 with: e2 @ ParseErrors{} . e2).
237 bind (-> merge: e1 @ ParseErrors{pos: p1 expected: x1 messages: m1}
238 with: e2 @ ParseErrors{pos: p2 expected: x2 messages: m2}
239 .
240 Cond {
241 (. (. p1 > p2) || (. empty? e2)) => (. e1),
242 (. (. p2 > p1) || (. empty? e1)) => (. e2)
243 } else: (. ParseErrors{pos: p1
244 expected: x1 `union` x2
245 messages: m1 `append` m2})
246 ).
248 bind (-> next results @ ParseResults{next: tvar} .
249 atomic (.
250 !tvar -> next.
251 if: procedure? next
252 then: (. $next -> next-value.
253 tvar := next-value.
254 next-value)
255 else: (. next).
256 ).
257 ).
264 "Now, reimagine everything as lazy - so each expression is effectively a nullary thunk."
265 "Note that pattern-matching is what forces promises!"
266 "We add syntactic sugar for lists here."
267 "Spineless, tagless G-machine?..."
268 "Monad? Is the interpreter the monad? How does polymorphic return work?"
270 bind (-> merge: e1 @ ParseErrors{} with: e2 . e1).
271 bind (-> merge: e1 with: e2 @ ParseErrors{} . e2).
272 bind (-> merge: e1 @ ParseErrors{pos: p1 expected: x1 messages: m1}
273 with: e2 @ ParseErrors{pos: p2 expected: x2 messages: m2}
274 .
275 Cond [
276 ((p1 > p2) || (empty? e2)) => e1,
277 ((p2 > p1) || (empty? e1)) => e2
278 ] else: ParseErrors{pos: p1
279 expected: x1 `union` x2
280 messages: m1 `append` m2}
281 ).
283 bind (-> next results @ ParseResults{next: tvar} .
284 atomic (
285 !tvar -> next.
286 if: procedure? next
287 then: ($next () -> next-value.
288 tvar := next-value.
289 next-value)
290 else: next.
291 ).
292 ).
294 (
295 "This is to parse as 'meta (-> m. ...)'."
296 meta -> m.
297 dict at: key ifAbsent: [m `return` false] -> val.
298 val
299 )
301 bind (-> over: list @ Pair{car: a cdr: d}
302 map: block @ (-> _ . _).
303 Pair{car: ($block a) cdr: (over: d map: block)}.
305 bind (-> over: list @ Nil{}
306 map: block @ (-> _ . _).
307 list).
309 bind (-> succ (i @ Integer{}). i + 1).
311 "The pattern (-> p1 . p2) is sugar for Function{pattern: p1 body: p2}"
