-
Notifications
You must be signed in to change notification settings - Fork 4
/
syntax-quote.ralph
67 lines (58 loc) · 2.24 KB
/
syntax-quote.ralph
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
(define-module ralph/compiler/syntax-quote
import: (ralph/compiler/module
ralph/compiler/environment
ralph/compiler/utilities)
export: (syntax-quote-form))
;;;; utilities
(define-function unquoted? (form env)
(and (expression? form)
(== (resolve-symbol (first form) env)
`unquote)))
(define-function unquote-spliced? (form env)
(and (expression? form)
(== (resolve-symbol (first form) env)
`unquote-splicing)))
;;;; syntax-quoting
(define-function syntax-quote-symbol (symbol env)
`(quote ,(resolve-symbol symbol env)))
; NOTE: working, but unoptimized version
; (define-function syntax-quote-array (array env)
; (if (unquoted? array env)
; (second array)
; `(concatenate ,@(map (method (form)
; (if (unquote-spliced? form env)
; (second form)
; `(%array ,(if (unquoted? form env)
; (second form)
; (syntax-quote-form form env)))))
; array))))
;; NOTE: optimized
(define-function syntax-quote-array (array env)
(if (unquoted? array env)
(second array)
(bind ((part `(%array)))
(reduce (method (result form)
(if (unquote-spliced? form env)
(begin
(set! part #f)
`(%concat ,result
,(second form)))
(bind ((form* (if (unquoted? form env)
(second form)
(syntax-quote-form form env))))
(if part
(begin
(push-last part form*)
result)
(begin
(set! part `(%array ,form*))
`(%concat ,result ,part))))))
part array))))
;; TODO [#B]: turn into methods ?
(define-function syntax-quote-form (form env)
(select form instance?
((<array>)
(syntax-quote-array form env))
((<symbol>)
(syntax-quote-symbol form env))
(else: form)))