From a75a5d7458f22edebdd590a81a784908cd5fdf5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Wed, 29 Jan 2014 00:31:43 +0100 Subject: [PATCH] python: syntax for methods and ditching of the auto-marshalling words, the syntax didn't turn out great --- extra/python/python.factor | 7 +-- extra/python/syntax/syntax-tests.factor | 63 ++++++++++++++++--------- extra/python/syntax/syntax.factor | 61 ++++++++++++------------ 3 files changed, 77 insertions(+), 54 deletions(-) diff --git a/extra/python/python.factor b/extra/python/python.factor index be4052e87f..1f83f83377 100644 --- a/extra/python/python.factor +++ b/extra/python/python.factor @@ -99,6 +99,9 @@ ERROR: python-error type message ; [ length dup ] keep [ rot py-tuple-set-item ] with each-index ; +: py-tuple>array ( py-tuple -- arr ) + dup py-tuple-size iota [ py-tuple-get-item ] with map ; + GENERIC: (>py) ( obj -- obj' ) M: string (>py) utf8>py-unicode ; M: math:fixnum (>py) PyLong_FromLong ; @@ -130,9 +133,7 @@ DEFER: >factor ] } { "long" [ PyLong_AsLong ] } { "str" [ PyString_AsString (check-return) ] } - { "tuple" [ - dup py-tuple-size iota [ py-tuple-get-item >factor ] with map - ] } + { "tuple" [ py-tuple>array [ >factor ] map ] } { "unicode" [ py-unicode>utf8 ] } } clone ; diff --git a/extra/python/syntax/syntax-tests.factor b/extra/python/syntax/syntax-tests.factor index 0bd184732f..43a92bf1c7 100644 --- a/extra/python/syntax/syntax-tests.factor +++ b/extra/python/syntax/syntax-tests.factor @@ -1,73 +1,94 @@ -USING: assocs destructors fry kernel math namespaces python python.ffi +USING: arrays assocs destructors fry kernel math namespaces python python.ffi python.syntax python.tests sequences tools.test ; IN: python.syntax.tests -! Define your own type conversions. -[ py-date>factor ] "date" py-type-dispatch get set-at - ! Importing functions PY-FROM: os => getpid ( -- y ) system ( x -- y ) ; -[ t ] [ getpid integer? ] unit-test +[ t ] [ getpid >factor integer? ] unit-test -! Automatic tuple unpacking +! ! Automatic tuple unpacking PY-FROM: os.path => basename ( x -- x' ) splitext ( x -- base ext ) ; -[ "hello.doc" ] [ "/some/path/hello.doc" basename ] unit-test +[ "hello.doc" ] [ "/some/path/hello.doc" >py basename >factor ] unit-test -[ "hello" ".doc" ] [ "hello.doc" splitext ] unit-test +[ { "hello" ".doc" } ] [ + "hello.doc" >py splitext 2array [ >factor ] map +] unit-test PY-FROM: time => sleep ( n -- ) ; -[ ] [ 0 sleep ] unit-test +[ ] [ 0 >py sleep ] unit-test -! Module variables are bound as zero-arg functions +! ! Module variables are bound as zero-arg functions PY-FROM: sys => path ( -- seq ) ; -[ t ] [ path sequence? ] unit-test +[ t ] [ path >factor sequence? ] unit-test -! Use the pipe functions to work on PyObjects. +! ! Use the pipe functions to work on PyObjects. PY-FROM: __builtin__ => callable ( obj -- ? ) + open ( name mode -- file ) int ( val -- s ) len ( seq -- n ) range ( n -- seq ) ; -[ t ] [ path| |len| |int 5 > ] unit-test +[ t ] [ path len int >factor 5 > ] unit-test -[ 10 ] [ 10 range| |len ] py-test +[ 10 ] [ 10 >py range len >factor ] unit-test ! Callables [ t ] [ "os" import "getpid" getattr - [ |callable ] [ PyCallable_Check 1 = ] bi and -] py-test + [ callable ] [ PyCallable_Check 1 = ] bi and +] unit-test ! Reference counting PY-FROM: sys => getrefcount ( obj -- n ) ; -[ 2 ] [ 3 |getrefcount ] py-test +[ 2 ] [ 3 getrefcount >factor ] unit-test [ -2 ] [ H{ { "foo" 33 } { "bar" 44 } } >py - [ "foo" py-dict-get-item-string |getrefcount ] + [ "foo" py-dict-get-item-string getrefcount >factor ] [ '[ 500 [ _ "foo" py-dict-get-item-string drop ] times ] with-destructors ] - [ "foo" py-dict-get-item-string |getrefcount ] tri - + [ "foo" py-dict-get-item-string getrefcount >factor ] tri - ] py-test [ -2 ] [ "abcd" >py <1py-tuple> - [ 0 py-tuple-get-item |getrefcount ] + [ 0 py-tuple-get-item getrefcount >factor ] [ [ 100 [ swap 0 py-tuple-get-item drop ] with times ] with-destructors ] - [ 0 py-tuple-get-item |getrefcount ] tri - + [ 0 py-tuple-get-item getrefcount >factor ] tri - +] py-test + +PY-METHODS: file => + close ( self -- ) + fileno ( self -- n ) + tell ( self -- n ) ; + +[ t ] [ + "testfile" >py "wb" >py open + [ ->tell ] [ ->fileno ] [ ->close ] tri + [ >factor integer? ] bi@ and +] py-test + +PY-METHODS: str => + title ( self -- self' ) + startswith ( self str -- ? ) + zfill ( self n -- str' ) ; + +! Method chaining +[ t ] [ + "hello there" >py ->title 20 >py ->zfill "00" >py ->startswith >factor ] py-test diff --git a/extra/python/syntax/syntax.factor b/extra/python/syntax/syntax.factor index fa6644ffc2..5b69f31654 100644 --- a/extra/python/syntax/syntax.factor +++ b/extra/python/syntax/syntax.factor @@ -1,5 +1,5 @@ -USING: accessors arrays effects effects.parser formatting fry generalizations -kernel lexer locals namespaces parser python python.ffi sequences +USING: accessors arrays effects effects.parser fry generalizations +kernel lexer locals math namespaces parser python python.ffi sequences sequences.generalizations vocabs.parser words ; IN: python.syntax @@ -10,35 +10,16 @@ SYMBOL: current-module : call-or-eval ( args obj -- ret ) dup PyCallable_Check 1 = [ swap call-object ] [ nip ] if ; -: factor>factor-quot ( py-function effect -- quot ) - [ in>> length ] [ out>> length ] bi swapd '[ - _ narray >py _ call-or-eval >factor - _ [ 1 = [ 1array ] when ] [ firstn ] bi - ] ; - -: factor>py-quot ( py-function effect -- quot ) - in>> length swap '[ _ narray >py _ call-or-eval ] ; - -: py>factor-quot ( py-function effect -- quot ) - [ in>> length ] [ out>> length ] bi swapd '[ - _ narray array>py-tuple _ call-or-eval >factor - _ [ 1 = [ 1array ] when ] [ firstn ] bi - ] ; - -: py>py-quot ( py-function effect -- quot ) - in>> length swap '[ _ narray array>py-tuple _ call-or-eval ] ; - -:: make-function ( basename format effect quot -- ) - basename format sprintf create-in - current-module get basename getattr - effect quot [ define-inline ] bi ; inline - :: add-function ( function effect -- ) - effect in>> { "ret" } :> py-effect - function "%s" effect [ factor>factor-quot ] make-function - function "|%s" effect [ py>factor-quot ] make-function - function "|%s|" py-effect [ py>py-quot ] make-function - function "%s|" py-effect [ factor>py-quot ] make-function ; inline + function create-in + effect [ in>> length ] [ out>> length ] bi + current-module get function getattr swap + '[ + _ narray array>py-tuple _ call-or-eval + _ [ 0 = [ drop 0 ] when ] keep + [ 1 = [ <1py-tuple> ] when ] keep + [ py-tuple>array ] dip firstn + ] effect define-inline ; inline : parse-python-word ( -- ) scan-token dup ";" = [ drop ] [ @@ -47,3 +28,23 @@ SYMBOL: current-module SYNTAX: PY-FROM: scan-token import current-module set "=>" expect parse-python-word ; inline + +:: add-method ( attr effect -- ) + attr "->" prepend create-in + effect [ in>> length 1 - ] [ out>> length ] bi + + '[ _ narray array>py-tuple swap attr getattr swap call-object + _ [ 1 = [ 1array ] when ] [ firstn ] bi ] + + + ! '[ attr getattr _ narray array>py-tuple call-object + ! _ [ 1 = [ 1array ] when ] [ firstn ] bi ] + effect define-inline ; + +: parse-python-method ( -- ) + scan-token dup ";" = [ drop ] [ + scan-effect add-method parse-python-method + ] if ; inline recursive + +SYNTAX: PY-METHODS: + scan-token drop "=>" expect parse-python-method ; inline