d634d1bd9c23fee65428aacde9d69da93c9a1bca
1 (define-module (language python compile
)
2 #:use-module
(ice-9 match
)
3 #:use-module
(ice-9 pretty-print
)
6 (define (p x
) (pretty-print (syntax->datum x
)) x
)
8 (define port
(open-file "compile.log" "a"))
9 (with-output-to-port port
10 (lambda () (pretty-print (syntax->datum x
)) x
))
14 (define (C x
) `(@@ (language python compile
) ,x
))
15 (define (G x
) `(@ (guile) ,x
))
18 (let lp
((as as
) (vs vs
))
28 (let lp
((as as
) (rs '()))
37 (define (get-globals code
)
38 (let lp
((vs (glob code
'())) (rs (scope code
'())))
50 (let lp
((l l
) (vs vs
))
52 (((#:identifier v
) . l
)
53 (let ((s (string->symbol v
)))
65 ((#:def
(#:identifier f
) . _
)
66 (union (list (string->symbol f
)) vs
))
74 (let ((s (string->symbol v
)))
79 (scope y
(scope x vs
)))
84 ((#:def
(#:identifier f
) . _
)
85 (union (list (string->symbol f
)) vs
))
97 (lambda (x) (e vs x
)))
99 (define return
(make-fluid 'error-return
))
103 ((#:power
(#:identifier x
) () .
#f
)
109 (((and x
(or #:+ #:-
#:* #:/)) . l
)
110 (cons (keyword->symbol x
) (map (g vs exp
) l
)))
113 (list 'lognot
(exp vs x
)))
116 (cons 'logand
(map (g vs exp
) l
)))
119 (cons 'logxor
(map (g vs exp
) l
)))
122 (cons 'logior
(map (g vs exp
) l
)))
125 (list 'not
(exp vs x
)))
128 (cons 'or
(map (g vs exp
) x
)))
131 (cons 'and
(map (g vs exp
) x
)))
137 (list 'if
(exp vs e2
) (exp vs e1
) (exp vs e3
)))
139 ((#:suite . l
) (cons 'begin
(map (g vs exp
) l
)))
144 (lambda () ,(exp vs x
))
145 (lambda () ,(exp vs fin
))))
147 ((#:while test code
#f
)
148 (let ((lp (gensym "lp")))
155 ((#:for exp in code
#f
)
157 ((((#:power
(#:identifier x
) #f .
#f
)) .
158 ((#:power
(#:identifier
'range
) ((arg) #f
#f
) .
#f
)))
159 (let ((v (gensym "v"))
161 `(let ((,v
,(exp arg
)))
168 ((((#:power
(#:identifier x
) #f .
#f
)) .
169 ((#:power
(#:identifier
'range
) ((arg1 arg2
) #f
#f
) .
#f
)))
170 (let ((v1 (gensym "va"))
173 `(let ((,v1
,(exp arg1
))
181 ((((#:power
(#:identifier x
) #f .
#f
)) .
182 ((#:power
(#:identifier
'range
) ((arg1 arg2 arg3
) #f
#f
) .
#f
)))
183 (let ((v1 (gensym "va"))
187 `(let ((,v1
,(exp arg1
))
194 (,lp
(+ ,x
,st
))))))))))
197 ((#:while test code else
)
198 (let ((lp (gensym "lp")))
206 ((#:try x exc else fin
)
212 (lambda ,(gensym "x") ,(exp vs x
))))))
218 (let lp
((code (exp vs x
)) (l (reverse exc
)))
221 (lp `(catch ,(exp vs e
)
223 (lambda ,(gensym "x")
226 (lp `(let ((,as
,(exp vs e
)))
229 (lambda ,(gensym "x")
233 (lambda () ,(exp vs fin
)))))
235 ((#:def
(#:identifier f
)
241 (let* ((f (string->symbol f
))
242 (r (gensym "return"))
243 (as (map (lambda (x) (match x
244 ((((#:identifier x
) .
#f
) #f
)
245 (string->symbol x
))))
250 (ls (diff (diff ns vs
) df
)))
252 `(define (,f
,@as
) (,(C 'with-return
) ,r
253 (let ,(map (lambda (x) (list x
#f
)) ls
)
254 ,(with-fluids ((return r
))
261 (list `lambda v
(exp vs e
)))
265 (cons 'values
(map (g vs exp
) l
))
269 ((#:expr-stmt
(l) (#:assign
))
273 `(,(fluid-ref return
) ,@(map (g vs exp
) x
)))
276 ((#:test
(#:power
(#:identifier v
) () .
#f
) #f
))
278 (let ((s (string->symbol v
)))
279 `(set! ,s
,(exp vs l
))))
285 ((or "<" ">" "<=" ">=")
286 (list (string->symbol op
) x y
))
287 ("!=" (list 'not
(list 'equal? x y
)))
288 ("==" (list 'equal? x y
))
289 ("is" (list 'eq? x y
))
290 ("isnot" (list 'not
(list 'eq? x y
)))
291 ("in" (list 'member x y
))
292 ("notin" (list 'not
(list 'member x y
)))
293 ("<>" (list 'not
(list 'equal? x y
)))))
299 (tr op
(exp vs x
) (exp vs y
)))
301 (tr op
(exp vs x
) (lp vs l
))))))))
304 (let ((globs (get-globals x
)))
306 ,@(map (lambda (s) `(define ,s
(values))) globs
)
307 ,@(map (g globs exp
) x
))))
309 (define-syntax with-return
311 (define (analyze ret x
)
312 (syntax-case x
(begin let if
)
314 #`(begin a ...
#,(analyze ret
#'b
)))
316 (symbol?
(syntax->datum
#'lp
))
317 #`(let lp v a ...
#,(analyze ret
#'b
)))
319 #`(let v a ...
#,(analyze ret
#'b
)))
321 #`(if p
#,(analyze ret
#'a
) #,(analyze ret
#'b
)))
323 #`(if p
#,(analyze ret
#'a
)))
325 (equal?
(syntax->datum
#'return
) (syntax->datum ret
))
326 (if (eq?
#'(b ...
) '())
331 (define (is-ec ret x tail
)
332 (syntax-case x
(begin let
)
336 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
337 (is-ec ret
#'b tail
)))
339 ((let lp
((y x
) ...
) a ... b
)
340 (symbol?
(syntax->datum
#'lp
))
342 (or-map (lambda (x) (is-ec ret x
#f
)) #'(x ...
))
343 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
344 (is-ec ret
#'b tail
)))
346 ((let ((y x
) ...
) a ... b
)
349 (or-map (lambda (x) (is-ec ret x
#f
)) #'(x ...
))
350 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
351 (is-ec ret
#'b tail
)))
358 (is-ec ret
#'b tail
)))
363 (is-ec ret
#'a tail
)))
366 (equal?
(syntax->datum
#'return
) (syntax->datum ret
))
371 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
)))
379 (pf (let ((code (analyze #'ret
#'l
)))
380 (if (is-ec #'ret
#'l
#t
)
381 #`(let/ec ret
#,code
)