diff options
Diffstat (limited to 'modules/language/python/compile.scm')
-rw-r--r-- | modules/language/python/compile.scm | 320 |
1 files changed, 219 insertions, 101 deletions
diff --git a/modules/language/python/compile.scm b/modules/language/python/compile.scm index 170cb11..0b3b872 100644 --- a/modules/language/python/compile.scm +++ b/modules/language/python/compile.scm @@ -41,6 +41,11 @@ (define-inlinable (H x) `(@ (language python hash) ,x)) (define-inlinable (W x) `(@ (language python with) ,x)) +(define-syntax-rule (use a ...) + (catch #t + (lambda () (use-modules a ...)) + (lambda x (raise (ImportError '(a ...)))))) + (define s/d 'set!) (define (pre) (warn "Patching guile will lead to way better experience use 'python.patch' on guile-2.2 e.g. (use-modules (language python guilemod))")) @@ -119,8 +124,13 @@ (match e (#f item) ((#:cfor for-e in-e cont) - `(,(F 'for) ((,@(map (g vs exp) for-e) : ,(exp vs in-e))) () - ,(gen-sel vs cont item))) + (let lp ((for-e for-e)) + (match for-e + (((#:power #f (#:tuple . l) . _)) + (lp l)) + (_ + `(,(F 'for) ((,@(map (g vs exp) for-e) : ,(exp vs in-e))) () + ,(gen-sel vs cont item)))))) ((#:cif cif cont) `(if ,(exp vs cif) ,(gen-sel vs cont item))))) @@ -217,6 +227,23 @@ '() l) vs)) + + ((#:expr-stmt l (#:assign k . u)) + (union + (union (fold (lambda (x s) + (match x + ((#:test (#:power v2 v1 () . _) . _) + (if v2 + (union + (union (list (exp '() v1)) + (list (exp '() v2))) + s) + (union (list (exp '() v1)) s))) + (_ s))) + '() + l) + vs) + (scope `(#:expr-stmt ,k (#:asignvs . ,u)) vs))) ((x . y) (scope y (scope x vs))) @@ -425,11 +452,17 @@ (() '())))) -(define (get-args_ vs arg) +(define (getarg x) + (match x + ((#:tp x . l) + x) + (x x))) + +(define (get-args_ vs arg) (let lp ((arg arg)) (match arg (((#:arg x) . arg) - (cons (exp vs (car x)) + (cons (exp vs (getarg x)) (lp arg))) ((x . args) (lp args)) @@ -441,7 +474,7 @@ (let lp ((arg arg)) (match arg (((#:= x v) . arg) - (cons (list '= (exp vs (car x)) (exp vs v)) + (cons (list '= (exp vs (getarg x)) (exp vs v)) (lp arg))) ((x . args) @@ -454,7 +487,7 @@ (let lp ((arg arg)) (match arg (((#:* x) . arg) - (cons (list '* (exp vs (car x))) + (cons (list '* (exp vs (getarg x))) (lp arg))) ((x . args) @@ -467,7 +500,7 @@ (let lp ((arg arg)) (match arg (((#:** x) . arg) - (cons (list '** (exp vs (car x))) + (cons (list '** (exp vs (getarg x))) (lp arg))) ((x . args) @@ -570,6 +603,7 @@ ("//=" 'floor-quotient))) (match x + ((#:verb x) x) ((#:test (#:power kind v addings . _) . _) (let* ((v (exp vs v)) (v.add (if (is-prefix? v) @@ -661,6 +695,18 @@ ...)) +(define (tr-comp op x y) + (match op + ((or "<" ">" "<=" ">=") + (list (G (string->symbol op)) x y)) + ("!=" (list (G 'not) (list (O 'equal?) x y))) + ("==" (list (O 'equal?) x y)) + ("is" (list (G 'eq?) x y)) + ("isnot" (list (G 'not) (list (G 'eq?) x y))) + ("in" (list (L 'in) x y)) + ("notin" (list (G 'not) (list (L 'in) x y))) + ("<>" (list (G 'not) (list (O 'equal?) x y))))) + (gen-table x vs (#:power ((_ _ (x) () . #f) @@ -869,7 +915,7 @@ `(,(G 'cons) '() '())) ,(map (lambda (x) `(define ,x #f)) ls) ,(exp vs code)))))))))) -(#:verb + (#:verb ((_ x) x)) (#:scm @@ -877,17 +923,17 @@ (#:import ((_ (#:from (() . nm) . #f)) - `(use-modules (language python module ,@(map (lambda (nm) (exp vs nm)) + `(,(C 'use) (language python module ,@(map (lambda (nm) (exp vs nm)) nm)))) - ((_ (#:from (() . nm) . l)) - `(use-modules ((language python module ,@(map (lambda (nm) (exp vs nm)) + ((_ (#:from (() . nm) l)) + `(,(C 'use) ((language python module ,@(map (lambda (nm) (exp vs nm)) nm)) - #:select ,(map (lambda (x) - (match x - ((a . #f) - (exp vs a)) - ((a . b) - (cons (exp vs a) (exp vs b))))) + #:select ,(map (lambda (x) + (match x + ((a . #f) + (exp vs a)) + ((a . b) + (cons (exp vs a) (exp vs b))))) l)))) @@ -923,71 +969,80 @@ (#:for ((_ e in code . #f) (=> next) - (match e - (((#:power #f (#:identifier x . _) () . #f)) - (match in - (((#:test power . _)) - (match power - ((#:power #f - (#:identifier "range" . _) - ((#:arglist arglist . _)) - . _) - (match arglist - ((arg) - (let ((v (gensym "v")) - (x (string->symbol x)) - (lp (gensym "lp"))) - `(let ((,v ,(exp vs arg))) - (let ,lp ((,x 0)) - (if (< ,x ,v) - (begin - ,(exp vs code) - (,lp (+ ,x 1)))))))) - ((arg1 arg2) - (let ((v1 (gensym "va")) - (v2 (gensym "vb")) - (lp (gensym "lp"))) - `(let ((,v1 ,(exp vs arg1)) - (,v2 ,(exp vs arg2))) - (let ,lp ((,x ,v1)) - (if (< ,x ,v2) - (begin - ,(exp vs code) - (,lp (+ ,x 1)))))))) - ((arg1 arg2 arg3) - (let ((v1 (gensym "va")) - (v2 (gensym "vb")) - (st (gensym "vs")) - (lp (gensym "lp"))) - `(let ((,v1 ,(exp vs arg1)) - (,st ,(exp vs arg2)) - (,v2 ,(exp vs arg3))) - (if (> st 0) - (let ,lp ((,x ,v1)) - (if (< ,x ,v2) - (begin - ,(exp vs code) - (,lp (+ ,x ,st))))) - (if (< st 0) - (let ,lp ((,x ,v1)) - (if (> ,x ,v2) - (begin - ,(exp vs code) - (,lp (+ ,x ,st))))) - (error "range with step 0 not allowed")))))) - (_ (next)))) - (_ (next)))) - (_ (next)))) - (_ (next)))) + (let lp ((e e)) + (match e + (((#:power #f (#:tuple . l) . _)) + (lp l)) + + (((#:power #f (#:identifier x . _) () . #f)) + (match in + (((#:test power . _)) + (match power + ((#:power #f + (#:identifier "range" . _) + ((#:arglist arglist . _)) + . _) + (match arglist + ((arg) + (let ((v (gensym "v")) + (x (string->symbol x)) + (lp (gensym "lp"))) + `(let ((,v ,(exp vs arg))) + (let ,lp ((,x 0)) + (if (< ,x ,v) + (begin + ,(exp vs code) + (,lp (+ ,x 1)))))))) + ((arg1 arg2) + (let ((v1 (gensym "va")) + (v2 (gensym "vb")) + (lp (gensym "lp"))) + `(let ((,v1 ,(exp vs arg1)) + (,v2 ,(exp vs arg2))) + (let ,lp ((,x ,v1)) + (if (< ,x ,v2) + (begin + ,(exp vs code) + (,lp (+ ,x 1)))))))) + ((arg1 arg2 arg3) + (let ((v1 (gensym "va")) + (v2 (gensym "vb")) + (st (gensym "vs")) + (lp (gensym "lp"))) + `(let ((,v1 ,(exp vs arg1)) + (,st ,(exp vs arg2)) + (,v2 ,(exp vs arg3))) + (if (> st 0) + (let ,lp ((,x ,v1)) + (if (< ,x ,v2) + (begin + ,(exp vs code) + (,lp (+ ,x ,st))))) + (if (< st 0) + (let ,lp ((,x ,v1)) + (if (> ,x ,v2) + (begin + ,(exp vs code) + (,lp (+ ,x ,st))))) + (error "range with step 0 not allowed")))))) + (_ (next)))) + (_ (next)))) + (_ (next)))) + (_ (next))))) ((_ es in code . else) - (let* ((es2 (map (g vs exp) es)) - (vs2 (union es2 vs)) - (code2 (exp vs2 code)) - (p (is-ec #t code2 #t (list (C 'break) (C 'continue)))) - (else2 (if else (exp vs2 else) #f)) - (in2 (map (g vs exp) in))) - (list (C 'cfor) es2 in2 code2 else2 p)))) + (let lp ((es es)) + (match es + (((#:power #f (#:tuple . l) . _)) + (lp l)) + (_ + (let* ((es2 (map (g vs exp) es)) + (vs2 (union es2 vs)) + (code2 (exp vs2 code)) + (p (is-ec #t code2 #t (list (C 'break) (C 'continue)))) + (else2 (if else (exp vs2 else) #f)) + (in2 (map (g vs exp) in))) + (list (C 'cfor) es2 in2 code2 else2 p))))))) (#:while @@ -1016,11 +1071,11 @@ ((_ x exc else . fin) - `(,(T 'try) ,(exp vs x) + `(,(T 'try) (lambda () ,(exp vs x)) ,@(let lp ((exc exc) (r (if else (exp vs else) '()))) (match exc ((((test . #f) code) . exc) - (lp exc (cons `(#:except ,(exp vs code)) r))) + (lp exc (cons `(#:except ,(exp vs test) ,(exp vs code)) r))) (((#f code) . exc) (lp exc (cons `(#:except ,(exp vs code)) r))) @@ -1075,7 +1130,7 @@ (set! ,(C 'inhibit-finally) #t) (let ((,g (,f ,@(gen-yargs vs args)))) (,g)))))) - + (#:def ((_ f (#:types-args-list . args) @@ -1199,8 +1254,12 @@ `(cons ,(exp vs x) ,(lp l))))))) (#:lambdef - ((_ v e) - (list `lambda v (exp vs e)))) + ((_ (#:var-args-list . v) e) + (let ((as (get-args_ vs v)) + (a= (get-args= vs v)) + (a* (get-args* vs v)) + (** (get-args** vs v))) + (list (C `lam) `(,@as ,@a* ,@a= ,@**) (exp vs e))))) (#:stmt ((_ l) @@ -1214,7 +1273,12 @@ (if (= (length l) 1) (car l) `(,(G 'values) ,@l)))) - + + ((_ l (#:assign x y . u)) + (let ((z (gensym "x"))) + `(let ((,x ,(exp vs `(#:expr-stmt1 ((#:verb ,z)) (#:assign ,y . ,u))))) + ,(exp vs `(#:expr-stmt ,x (#:assign ((#:verb ,z)))))))) + ((_ l type) (=> fail) (call-with-values @@ -1273,6 +1337,61 @@ x))) (,(C 'raise) ,(C 'AssertionError) ',f ,n ,m)))) + + + (#:expr-stmt1 + ((_ l (#:assign x y . u)) + (let ((z (gensym "x"))) + `(let ((,x ,(exp vs `(#:expr-stmt1 ((#:verb ,z)) + (#:assign ,y . ,u))))) + ,(exp vs `(#:expr-stmt ,x (#:assign ((#:verb ,z)))))))) + + ((_ l type) + (=> fail) + (call-with-values + (lambda () (match type + ((#:assign u) + (values #f u)) + ((#:augassign op u) + (values op u)) + (_ (fail)))) + + (lambda (op u) + (cond + ((= (length l) (length u)) + (if (= (length l) 1) + `(begin + ,(make-set vs op (car l) (exp vs (car u))) + ,(exp vs (car l))) + `(begin + @,(map (lambda (l u) (make-set vs op l u)) + l + (map (g vs exp) u)) + (values ,@(map (g exp vs) l))))) + + ((and (= (length u) 1) (not op)) + (let ((vars (map (lambda (x) (gensym "v")) l)) + (q (gensym "q")) + (f (gensym "f"))) + `(begin + (call-with-values (lambda () ,(exp vs (car u))) + (letrec ((,f + (case-lambda + ((,q) + (if (pair? ,q) + (apply ,f ,q) + (apply ,f (,(L 'to-list) ,q)))) + (,vars + ,@(map (lambda (l v) (make-set vs op l v)) + l vars))))) + ,f)) + (values ,@(map (g exp vs) l))))) + + ((and (= (length l) 1) (not op)) + `(begin + ,(make-set vs op (car l) `(,(G 'list) ,@(map (g vs exp) u))) + (values ,(exp vs (car l)))))))))) + (#:return ((_ x) (if x @@ -1318,18 +1437,14 @@ (exp vs x)) ((_ x (op . y)) - (define (tr op x y) - (match op - ((or "<" ">" "<=" ">=") - (list (G (string->symbol op)) x y)) - ("!=" (list (G 'not) (list (O 'equal?) x y))) - ("==" (list (O 'equal?) x y)) - ("is" (list (G 'eq?) x y)) - ("isnot" (list (G 'not) (list (G 'eq?) x y))) - ("in" (list (L 'in) x y)) - ("notin" (list (G 'not) (list (L 'in) x y))) - ("<>" (list (G 'not) (list (O 'equal?) x y))))) - (tr op (exp vs x) (exp vs y))))) + (tr-comp op (exp vs x) (exp vs y))) + + ((_ x (op . y) . l) + (let ((m (gensym "op"))) + `(let ((,m ,(exp vs y))) + (and ,(tr-comp op (exp vs x) m) + ,(exp vs `(#:comp (#:verb ,m) . ,l)))))))) + (define (exp vs x) (match (pr x) @@ -1372,7 +1487,8 @@ arglist)) `((,(G 'define-module) (language python module ,@args) - #:use-module (language python module python)) + #:use-module (language python module python) + #:use-module (language python exceptions)) (define __doc__ #f) (define __module__ '(language python module ,@args))))) (x '()))) @@ -1936,6 +2052,8 @@ (define (export-all) (define mod (current-module)) (if (module-defined? mod '__all__) - (for ((x : (module-ref mod '__all__))) () - (module-export! mod (string->symbol (scm-str x)))))) + (module-export! mod + (for ((x : (module-ref mod '__all__))) ((l '())) + (cons (string->symbol (scm-str x)) l) + #:final l)))) |