1 (define-module (language python compile
)
2 #:use-module
(ice-9 match
)
3 #:use-module
(ice-9 pretty-print
)
6 (define (fold f init l
)
8 (fold f
(f (car l
) init
) (cdr l
))
12 (define port
(open-file "/home/stis/src/python-on-guile/log.txt" "a"))
13 (with-output-to-port port
20 (define port
(open-file "/home/stis/src/python-on-guile/compile.log" "a"))
21 (with-output-to-port port
22 (lambda () (pretty-print (syntax->datum x
)) x
))
26 (define (C x
) `(@@ (language python compile
) ,x
))
27 (define (O x
) `(@@ (oop pf-objects
) ,x
))
28 (define (G x
) `(@ (guile) ,x
))
31 (let lp
((as as
) (vs vs
))
41 (let lp
((as as
) (rs '()))
50 (define (get-globals code
)
51 (let lp
((vs (glob code
'())) (rs (scope code
'())))
63 (let lp
((l l
) (vs vs
))
65 (((#:identifier v . _
) . l
)
66 (let ((s (string->symbol v
)))
78 ((#:def
(#:identifier f . _
) . _
)
79 (union (list (string->symbol f
)) vs
))
87 (let ((s (string->symbol v
)))
92 (scope y
(scope x vs
)))
97 ((#:def
(#:identifier f . _
) . _
)
98 (union (list (string->symbol f
)) vs
))
106 (defs y
(defs x vs
)))
110 (lambda (x) (e vs x
)))
112 (define return
(make-fluid 'error-return
))
114 (define (make-set vs x u
)
116 ((#:test
(#:power
(#:identifier v . _
) addings . _
) . _
)
117 (let ((v (string->symbol v
)))
120 (let* ((rev (reverse addings
))
122 (new (reverse (cdr rev
))))
123 `(,(O 'set
) ,(let lp
((v v
) (new new
))
126 (lp `(,(O 'ref
) ,v
,(exp vs x
)) ',new
))
128 ',(exp vs las
) ,u
)))))))
137 ;; Function calls (x1:x1.y.f(1) + x2:x2.y.f(2)) will do functional calls
138 ((#:power vf
((and trailer
(#:identifier _ . _
)) ...
139 (#:arglist
(args ...
) #f
#f
)) .
#f
)
140 (let ((args (map (g vs exp
) args
)))
142 ((#:f
(#:identifier f . _
) e
)
143 (let ((obj (gensym "obj"))
145 '(call-with-values (lambda () (fcall (,(exp vs e
)
146 ,@(map (g vd exp
) trailer
))
149 `(set! ,(string->symbol f
) ,obj
)
150 (apply 'values
,l
)))))
152 `(,(C 'call
) (,(exp vs x
) ,@(map (g vs exp
) trailer
)) ,@args
)))))
154 ((#:identifier x . _
)
160 (((and x
(or #:+ #:-
#:* #:/)) . l
)
161 (cons (keyword->symbol x
) (map (g vs exp
) l
)))
164 (list 'lognot
(exp vs x
)))
167 (cons 'logand
(map (g vs exp
) l
)))
170 (cons 'logxor
(map (g vs exp
) l
)))
173 (cons 'logior
(map (g vs exp
) l
)))
176 (list 'not
(exp vs x
)))
179 (cons 'or
(map (g vs exp
) x
)))
182 (cons 'and
(map (g vs exp
) x
)))
188 (list 'if
(exp vs e2
) (exp vs e1
) (exp vs e3
)))
190 ((#:if test a
((tests . as
) ...
) . else
)
192 (,(exp vs test
) ,(exp vs a
))
193 ,@(map (lambda (p a
) (list (exp vs p
) (exp vs a
))) tests as
)
194 ,@(if else
`((else ,(exp vs else
))) '())))
196 ((#:suite . l
) (cons 'begin
(map (g vs exp
) l
)))
201 (lambda () ,(exp vs x
))
202 (lambda () ,(exp vs fin
))))
204 ((#:while test code
#f
)
205 (let ((lp (gensym "lp")))
212 ((#:classdef
(#:identifier class . _
) parents defs
)
218 (((or 'fast
'functional
)) s
)
221 (define (is-functional l
)
222 (fold (lambda (x pred
)
229 (fold (lambda (x pred
)
237 (let* ((class (string->symbol class
))
238 (parents (match parents
241 ((#:arglist args . _
)
242 (map (g vs exp
) args
))))
243 (is-func (is-functional parents
))
244 (is-fast (is-fast parents
))
252 (parents (filt parents
)))
253 `(define ,class
(,(O 'wrap
)
256 ,(map (lambda (x) `(,(O 'get-class
) ,x
)) parents
)
258 ,(match (exp vs defs
)
267 ((#:for e in code .
#f
)
270 (((#:power
(#:identifier x . _
) () .
#f
))
272 (((#:test power . _
))
275 (#:identifier
"range" . _
)
276 ((#:arglist arglist . _
))
280 (let ((v (gensym "v"))
281 (x (string->symbol x
))
283 `(let ((,v
,(exp vs arg
)))
290 (let ((v1 (gensym "va"))
293 `(let ((,v1
,(exp vs arg1
))
294 (,v2
,(exp vs arg2
)))
301 (let ((v1 (gensym "va"))
305 `(let ((,v1
,(exp vs arg1
))
307 (,v2
,(exp vs arg3
)))
320 (error "range with step 0 not allowed"))))))
326 ((#:while test code else
)
327 (let ((lp (gensym "lp")))
335 ((#:try x exc else fin
)
341 (lambda ,(gensym "x") ,(exp vs x
))))))
347 (let lp
((code (exp vs x
)) (l (reverse exc
)))
350 (lp `(catch ,(exp vs e
)
352 (lambda ,(gensym "x")
355 (lp `(let ((,as
,(exp vs e
)))
358 (lambda ,(gensym "x")
362 (lambda () ,(exp vs fin
)))))
364 ((#:def
(#:identifier f . _
)
370 (let* ((f (string->symbol f
))
371 (r (gensym "return"))
372 (as (map (lambda (x) (match x
373 ((((#:identifier x . _
) .
#f
) #f
)
374 (string->symbol x
))))
379 (ls (diff (diff ns vs
) df
)))
381 `(define ,f
(lambda (,@as
)
382 (,(C 'with-return
) ,r
383 (let ,(map (lambda (x) (list x
#f
)) ls
)
384 ,(with-fluids ((return r
))
391 (list `lambda v
(exp vs e
)))
395 (cons 'values
(map (g vs exp
) l
))
399 ((#:expr-stmt
(l) (#:assign
))
402 ((#:expr-stmt l
(#:assign u
))
404 ((= (length l
) (length u
))
405 (cons 'begin
(map make-set
(map (lambda x vs
) l
) l
(map (g vs exp
) u
))))
407 (let ((vars (map (lambda (x) (gensym "v")) l
)))
408 `(call-with-values (lambda () (exp vs
(car u
)))
410 ,@(map make-set l vars
)))))))
415 `(,(fluid-ref return
) ,@(map (g vs exp
) x
)))
418 ((#:test
(#:power
(#:identifier v . _
) () .
#f
) #f
))
420 (let ((s (string->symbol v
)))
421 `(set! ,s
,(exp vs l
))))
429 ((or "<" ">" "<=" ">=")
430 (list (G (string->symbol op
)) x y
))
431 ("!=" (list 'not
(list 'equal? x y
)))
432 ("==" (list 'equal? x y
))
433 ("is" (list 'eq? x y
))
434 ("isnot" (list 'not
(list 'eq? x y
)))
435 ("in" (list 'member x y
))
436 ("notin" (list 'not
(list 'member x y
)))
437 ("<>" (list 'not
(list 'equal? x y
)))))
438 (tr op
(exp vs x
) (exp vs y
)))
449 (#:identifier
"module" . _
)
450 ((#:arglist arglist
#f
#f
))
459 `((,(G 'define-module
) (language python module
,@args
)))))
465 (let ((globs (get-globals x
)))
468 ,@(map (lambda (s) `(,(C 'var
) ,s
)) globs
)
469 ,@(map (g globs exp
) x
))))
471 (define-syntax with-return
473 (define (analyze ret x
)
474 (syntax-case x
(begin let if
)
476 #`(begin a ...
#,(analyze ret
#'b
)))
478 (symbol?
(syntax->datum
#'lp
))
479 #`(let lp v a ...
#,(analyze ret
#'b
)))
481 #`(let v a ...
#,(analyze ret
#'b
)))
483 #`(if p
#,(analyze ret
#'a
) #,(analyze ret
#'b
)))
485 #`(if p
#,(analyze ret
#'a
)))
487 (equal?
(syntax->datum
#'return
) (syntax->datum ret
))
488 (if (eq?
#'(b ...
) '())
493 (define (is-ec ret x tail
)
494 (syntax-case x
(begin let
)
498 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
499 (is-ec ret
#'b tail
)))
501 ((let lp
((y x
) ...
) a ... b
)
502 (symbol?
(syntax->datum
#'lp
))
504 (or-map (lambda (x) (is-ec ret x
#f
)) #'(x ...
))
505 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
506 (is-ec ret
#'b tail
)))
508 ((let ((y x
) ...
) a ... b
)
511 (or-map (lambda (x) (is-ec ret x
#f
)) #'(x ...
))
512 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
))
513 (is-ec ret
#'b tail
)))
520 (is-ec ret
#'b tail
)))
525 (is-ec ret
#'a tail
)))
528 (equal?
(syntax->datum
#'return
) (syntax->datum ret
))
533 (or-map (lambda (x) (is-ec ret x
#f
)) #'(a ...
)))
541 (let ((code (analyze #'ret
#'l
)))
542 (if (is-ec #'ret
#'l
#t
)
543 #`(let/ec ret
#,code
)
548 ((_ (f) . l
) (f . l
))))
550 (define-syntax-rule (var v
)