| rev |
line source |
|
tonyg@217
|
1 (define previous-inspector (current-inspector))
|
|
tonyg@217
|
2 (current-inspector (make-inspector))
|
|
tonyg@217
|
3
|
|
tonyg@278
|
4 (define-record-type etng-alternation
|
|
tonyg@278
|
5 (make-etng-alternation clauses)
|
|
tonyg@278
|
6 etng-alternation?
|
|
tonyg@278
|
7 (clauses etng-alternation-clauses))
|
|
tonyg@217
|
8
|
|
tonyg@217
|
9 (current-inspector previous-inspector)
|
|
tonyg@217
|
10
|
|
tonyg@217
|
11 ;---------------------------------------------------------------------------
|
|
tonyg@217
|
12
|
|
tonyg@221
|
13 (define etng-namespaces '())
|
|
tonyg@221
|
14 (define implicit-etng-namespace #f)
|
|
tonyg@221
|
15
|
|
tonyg@221
|
16 (define builtin-namespace-url "http://www.eighty-twenty.org/etng/r2/builtin#")
|
|
tonyg@221
|
17
|
|
tonyg@221
|
18 (define (set-etng-namespace! prefix url)
|
|
tonyg@221
|
19 (cond
|
|
tonyg@221
|
20 ((assq prefix etng-namespaces) =>
|
|
tonyg@221
|
21 (lambda (cell) (set-box! (cdr cell) url)))
|
|
tonyg@221
|
22 (else
|
|
tonyg@221
|
23 (set! etng-namespaces (cons (cons prefix (box url)) etng-namespaces)))))
|
|
tonyg@221
|
24
|
|
tonyg@221
|
25 (set-etng-namespace! '|| builtin-namespace-url)
|
|
tonyg@221
|
26
|
|
tonyg@221
|
27 (define (mangle-etng-id* url localname)
|
|
tonyg@221
|
28 (string->symbol (string-append "etng___" url (symbol->string localname))))
|
|
tonyg@221
|
29
|
|
tonyg@217
|
30 (define (mangle-etng-id id)
|
|
tonyg@217
|
31 (cond
|
|
tonyg@221
|
32 ((qname? id)
|
|
tonyg@221
|
33 (cond
|
|
tonyg@221
|
34 ((assq (qname-uri id) etng-namespaces) =>
|
|
tonyg@221
|
35 (lambda (entry)
|
|
tonyg@221
|
36 (mangle-etng-id* (unbox (cdr entry)) (qname-localname id))))
|
|
tonyg@221
|
37 (else
|
|
tonyg@221
|
38 (error 'unknown-qname-prefix id))))
|
|
tonyg@221
|
39 ((symbol? id)
|
|
tonyg@221
|
40 (if implicit-etng-namespace
|
|
tonyg@221
|
41 (mangle-etng-id* implicit-etng-namespace id)
|
|
tonyg@221
|
42 (mangle-etng-id* "" id)))
|
|
tonyg@217
|
43 (else (error 'invalid-etng-id id))))
|
|
tonyg@217
|
44
|
|
tonyg@221
|
45 (define (etng-send-via-named-proxy receiver localname message)
|
|
tonyg@221
|
46 (etng-send* receiver
|
|
tonyg@221
|
47 (namespace-variable-value (mangle-etng-id* builtin-namespace-url localname))
|
|
tonyg@221
|
48 message))
|
|
tonyg@221
|
49
|
|
tonyg@278
|
50 (define (etng-alternation->parser a)
|
|
tonyg@278
|
51 (lambda (input ks kf)
|
|
tonyg@278
|
52 (let loop ((clauses (etng-alternation-clauses a)))
|
|
tonyg@278
|
53 (if (null? clauses)
|
|
tonyg@278
|
54 (kf)
|
|
tonyg@278
|
55 ((car clauses) input ks (lambda () (loop (cdr clauses))))))))
|
|
tonyg@278
|
56
|
|
tonyg@278
|
57 (define (make-parser-invocation first-message)
|
|
tonyg@278
|
58 (let ((fragments-rev (make-parameter (list first-message))))
|
|
tonyg@278
|
59 (define (fragment-following f)
|
|
tonyg@278
|
60 (let search ((candidate #f)
|
|
tonyg@278
|
61 (fs (fragments-rev)))
|
|
tonyg@278
|
62 (cond
|
|
tonyg@278
|
63 ((null? fs) (error 'should-not-reach-here 'fragment-following))
|
|
tonyg@278
|
64 ((eq? (car fs) f) candidate)
|
|
tonyg@278
|
65 (else (search (car fs) (cdr fs))))))
|
|
tonyg@278
|
66 (define (remaining-input-following f)
|
|
tonyg@278
|
67 (let search ((acc '())
|
|
tonyg@278
|
68 (fs (fragments-rev)))
|
|
tonyg@278
|
69 (cond
|
|
tonyg@278
|
70 ((null? fs) (error 'should-not-reach-here 'fragment-following))
|
|
tonyg@278
|
71 ((eq? (car fs) f) acc)
|
|
tonyg@278
|
72 (else (search (append (car fs) acc) (cdr fs))))))
|
|
tonyg@278
|
73 (define (stream-fragment f)
|
|
tonyg@278
|
74 (let loop ((position f))
|
|
tonyg@278
|
75 (lambda (op k)
|
|
tonyg@278
|
76 (case op
|
|
tonyg@278
|
77 ((next)
|
|
tonyg@278
|
78 (if (null? position)
|
|
tonyg@278
|
79 (let ((next-fragment (fragment-following f)))
|
|
tonyg@278
|
80 (if next-fragment
|
|
tonyg@278
|
81 ((stream-fragment next-fragment) 'next k)
|
|
tonyg@278
|
82 (let ((so-far (fragments-rev)))
|
|
tonyg@278
|
83 (lambda (ignored-receiver)
|
|
tonyg@278
|
84 (lambda (message)
|
|
tonyg@278
|
85 (parameterize ((fragments-rev (cons message so-far)))
|
|
tonyg@278
|
86 ((stream-fragment message) 'next k)))))))
|
|
tonyg@278
|
87 (k (car position) (loop (cdr position)))))
|
|
tonyg@278
|
88 ((rest)
|
|
tonyg@278
|
89 (k (append position (remaining-input-following f))))
|
|
tonyg@278
|
90 (else
|
|
tonyg@278
|
91 (error 'invalid-op op))))))
|
|
tonyg@278
|
92 (stream-fragment first-message)))
|
|
tonyg@278
|
93
|
|
tonyg@278
|
94 (define (etng-lookup via message)
|
|
tonyg@278
|
95 (cond
|
|
tonyg@278
|
96 ((etng-alternation? via)
|
|
tonyg@278
|
97 ((etng-alternation->parser via)
|
|
tonyg@278
|
98 (make-parser-invocation message)
|
|
tonyg@278
|
99 (lambda (rhs-thunk-waiting-for-self remaining-input)
|
|
tonyg@278
|
100 (remaining-input 'rest
|
|
tonyg@278
|
101 (lambda (remaining-message)
|
|
tonyg@278
|
102 (if (null? remaining-message)
|
|
tonyg@278
|
103 rhs-thunk-waiting-for-self
|
|
tonyg@278
|
104 (lambda (receiver)
|
|
tonyg@278
|
105 (etng-send (rhs-thunk-waiting-for-self receiver)
|
|
tonyg@278
|
106 remaining-message))))))
|
|
tonyg@278
|
107 (lambda () #f)))
|
|
tonyg@278
|
108 ((procedure? via)
|
|
tonyg@278
|
109 (via message))
|
|
tonyg@278
|
110 (else 'invalid-via (list via message))))
|
|
tonyg@278
|
111
|
|
tonyg@278
|
112 (define (etng-directly-invokable? x)
|
|
tonyg@278
|
113 (or (procedure? x) ;; a parser-invocation, (lambda (message) ...)
|
|
tonyg@278
|
114 (etng-alternation? x) ;; a parser without invocation: see etng-lookup
|
|
tonyg@278
|
115 ))
|
|
tonyg@217
|
116
|
|
tonyg@217
|
117 (define (etng-send* receiver via message)
|
|
tonyg@217
|
118 (cond
|
|
tonyg@278
|
119 ((etng-directly-invokable? via)
|
|
tonyg@278
|
120 (let ((thunk (or (etng-lookup via message)
|
|
tonyg@221
|
121 (error 'does-not-understand receiver via message))))
|
|
tonyg@221
|
122 (thunk receiver)))
|
|
tonyg@217
|
123 ((number? via) (etng-send-via-named-proxy receiver 'numberProxy message))
|
|
tonyg@217
|
124 ((string? via) (etng-send-via-named-proxy receiver 'stringProxy message))
|
|
tonyg@229
|
125 ((qname-or-symbol? via) (etng-send-via-named-proxy receiver 'symbolProxy message))
|
|
tonyg@221
|
126 ((vector? via) (etng-send-via-named-proxy receiver 'tupleProxy message))
|
|
tonyg@221
|
127 ((not via) (etng-send-via-named-proxy receiver 'falseProxy message))
|
|
tonyg@221
|
128 ((eq? via #t) (etng-send-via-named-proxy receiver 'trueProxy message))
|
|
tonyg@217
|
129 (else (error 'illegal-primitive-object receiver via message))))
|
|
tonyg@217
|
130
|
|
tonyg@217
|
131 (define (etng-send receiver message)
|
|
tonyg@217
|
132 (etng-send* receiver receiver message))
|
|
tonyg@217
|
133
|
|
tonyg@219
|
134 (define (etng-merge-functions f1 f2)
|
|
tonyg@278
|
135 (make-etng-alternation (append (etng-alternation-clauses f1) (etng-alternation-clauses f2))))
|
|
tonyg@219
|
136
|
|
tonyg@217
|
137 (define (compile-to-scheme ast)
|
|
tonyg@217
|
138
|
|
tonyg@217
|
139 (define (schemeify tng-sexp)
|
|
tonyg@217
|
140 (if (pair? tng-sexp)
|
|
tonyg@217
|
141 (case (car tng-sexp)
|
|
tonyg@217
|
142 ((paren) (map schemeify (cdr tng-sexp)))
|
|
tonyg@217
|
143 (else (error 'brack-and-brace-illegal-in-scheme-assembly)))
|
|
tonyg@217
|
144 tng-sexp))
|
|
tonyg@217
|
145
|
|
tonyg@217
|
146 (define (make-definition id val)
|
|
tonyg@217
|
147 `(namespace-set-variable-value! ',(mangle-etng-id id) ,val))
|
|
tonyg@217
|
148
|
|
tonyg@217
|
149 (define (toplevel ast)
|
|
tonyg@217
|
150 (case (car ast)
|
|
tonyg@221
|
151 ((define-namespace) `(set-etng-namespace! ',(cadr ast) ',(caddr ast)))
|
|
tonyg@221
|
152 ((declare-default-namespace) `(set! implicit-etng-namespace ',(cadr ast)))
|
|
tonyg@217
|
153 ((define-value) (make-definition (cadr ast) (expr (caddr ast))))
|
|
tonyg@217
|
154 ((define-function) (make-definition (cadr ast) (expr `(function ,(caddr ast)))))
|
|
tonyg@217
|
155 (else (expr ast))))
|
|
tonyg@217
|
156
|
|
tonyg@217
|
157 (define (expr ast)
|
|
tonyg@217
|
158 (case (car ast)
|
|
tonyg@217
|
159 ((ref) (mangle-etng-id (cadr ast)))
|
|
tonyg@217
|
160 ((lit) `',(cadr ast))
|
|
tonyg@278
|
161 ((object) `(make-etng-alternation (list ,@(map (method (cadr ast)) (cddr ast)))))
|
|
tonyg@278
|
162 ((function) `(make-etng-alternation (list ,@(map (method #f) (cdr ast)))))
|
|
tonyg@217
|
163 ((tuple) `(vector ,@(map expr (cdr ast))))
|
|
tonyg@258
|
164 ((send) `(etng-send ,(expr (cadr ast)) (list ,@(map expr (cddr ast)))))
|
|
tonyg@217
|
165 ((assemble) `(let ,(map (lambda (binding)
|
|
tonyg@217
|
166 `(,(car binding) ,(expr (cadr binding))))
|
|
tonyg@217
|
167 (cadr ast))
|
|
tonyg@217
|
168 ,(schemeify (cadr (assq 'scheme (caddr ast))))))))
|
|
tonyg@217
|
169
|
|
tonyg@258
|
170 (define (pattern p on-success on-failure)
|
|
tonyg@258
|
171 (case (car p)
|
|
tonyg@258
|
172 ((discard) on-success)
|
|
tonyg@258
|
173 ((bind) `(let ((,(mangle-etng-id (cadr p)) _arg)) ,on-success))
|
|
tonyg@258
|
174 ((lit) `(if (equal? ',(cadr p) _arg)
|
|
tonyg@258
|
175 ,on-success
|
|
tonyg@258
|
176 ,on-failure))
|
|
tonyg@258
|
177 ((tuple) `(if (and (vector? _arg)
|
|
tonyg@258
|
178 (= (vector-length _arg) ,(length (cdr p))))
|
|
tonyg@258
|
179 ,(let ((tuple-name (gensym '_argtuple)))
|
|
tonyg@258
|
180 `(let ((,tuple-name _arg))
|
|
tonyg@258
|
181 ,(let match-elts ((elts (cdr p))
|
|
tonyg@258
|
182 (index 0))
|
|
tonyg@258
|
183 (if (null? elts)
|
|
tonyg@258
|
184 on-success
|
|
tonyg@258
|
185 `(let ((_arg (vector-ref ,tuple-name ,index)))
|
|
tonyg@258
|
186 ,(pattern (car elts)
|
|
tonyg@258
|
187 (match-elts (cdr elts) (+ index 1))
|
|
tonyg@258
|
188 on-failure))))))
|
|
tonyg@258
|
189 ,on-failure))))
|
|
tonyg@258
|
190
|
|
tonyg@234
|
191 (define (method self-id)
|
|
tonyg@217
|
192 (lambda (ast)
|
|
tonyg@278
|
193 (let ((body (caddr ast)))
|
|
tonyg@278
|
194 `(lambda (_stream _kt _kf)
|
|
tonyg@278
|
195 ,(let loop ((patterns (cadr ast)))
|
|
tonyg@278
|
196 `(_stream 'next
|
|
tonyg@278
|
197 (lambda (_arg _stream)
|
|
tonyg@278
|
198 ,(let* ((remaining-patterns (cdr patterns)))
|
|
tonyg@278
|
199 (pattern (car patterns)
|
|
tonyg@278
|
200 (if (null? remaining-patterns)
|
|
tonyg@278
|
201 `(_kt (lambda (,(if self-id
|
|
tonyg@278
|
202 (mangle-etng-id self-id)
|
|
tonyg@278
|
203 '_self))
|
|
tonyg@278
|
204 ,(expr body))
|
|
tonyg@278
|
205 _stream)
|
|
tonyg@278
|
206 (loop remaining-patterns))
|
|
tonyg@278
|
207 `(_kf))))))))))
|
|
tonyg@217
|
208
|
|
tonyg@217
|
209 (toplevel ast))
|