]> gitweb.factorcode.org Git - factor.git/commitdiff
python.syntax: new way to bind python functions to factor words and updated tests
authorBjörn Lindqvist <bjourne@gmail.com>
Mon, 27 Oct 2014 12:41:03 +0000 (13:41 +0100)
committerDoug Coleman <doug.coleman@gmail.com>
Mon, 27 Oct 2014 16:52:04 +0000 (09:52 -0700)
this way avoids binding literal alien values inside the words which is
just wrong. the hardcoded alien addresses goes "out of sync" when
factor is restarded and causes crashes.

extra/python/syntax/syntax-tests.factor
extra/python/syntax/syntax.factor

index 3ec5fa7b6e0c23ac301be629987cf6da62a9a865..ca0551cabbe3a6dfb21eaa00a182953cfed555af 100644 (file)
@@ -1,63 +1,43 @@
 USING: accessors arrays assocs continuations destructors destructors.private
-fry io.files.temp kernel math namespaces python python.ffi python.objects
-python.syntax sequences sets splitting tools.test unicode.categories ;
+fry io.files.temp kernel math namespaces python python.ffi
+python.modules.__builtin__ python.modules.argparse python.modules.datetime
+python.modules.os python.modules.os.path python.modules.sys
+python.modules.time python.objects python.syntax sets splitting tools.test
+unicode.categories ;
+QUALIFIED-WITH: sequences s
 IN: python.syntax.tests
 
 : py-test ( result quot -- )
     '[ _ with-destructors ] unit-test ; inline
 
-! py-importing functions
-PY-FROM: os =>
-    getpid ( -- y )
-    system ( x -- y ) ;
-
-[ t ] [ getpid py> integer? ] unit-test
+{ t } [ getpid py> integer? ] py-test
 
 ! Automatic tuple unpacking
-PY-FROM: os.path =>
-    basename ( x -- x' )
-    splitext ( x -- base ext ) ;
-
-[ "hello.doc" ] [ "/some/path/hello.doc" >py basename py> ] unit-test
+[ "hello.doc" ] [ "/some/path/hello.doc" >py basename py> ] py-test
 
 [ { "hello" ".doc" } ] [
-    "hello.doc" >py splitext 2array [ py> ] map
-] unit-test
-
-PY-FROM: time => sleep ( n -- ) ;
+    "hello.doc" >py splitext 2array [ py> ] s:map
+] py-test
 
-[ ] [ 0 >py sleep ] unit-test
+[ ] [ 0 >py sleep ] py-test
 
 ! Module variables are bound as zero-arg functions
-PY-FROM: sys => path ( -- seq ) argv ( -- seq ) ;
-
-[ t ] [ $path py> sequence? ] unit-test
-
-PY-FROM: __builtin__ =>
-    callable ( obj -- ? )
-    dir ( obj -- seq )
-    int ( val -- s )
-    len ( seq -- n )
-    open ( name mode -- file )
-    range ( n -- seq )
-    repr ( obj -- str ) ;
+[ t ] [ $path py> s:sequence? ] py-test
 
-[ t ] [ $path len int py> 5 > ] unit-test
+[ t ] [ $path len int py> 5 > ] py-test
 
-[ 10 ] [ 10 >py range len py> ] unit-test
+[ 10 ] [ 10 >py range len py> ] py-test
 
 ! Callables
 [ t ] [
     "os" py-import "getpid" getattr
     [ callable ] [ PyCallable_Check 1 = ] bi and
-] unit-test
+] py-test
 
 ! Reference counting
-PY-FROM: sys => getrefcount ( obj -- n ) ;
+[ 1 ] [ 3 <py-tuple> getrefcount py> ] py-test
 
-[ 2 ] [ 3 <py-tuple> getrefcount py> ] unit-test
-
-[ -2 ] [
+[ -1 ] [
     H{ { "foo" 33 } { "bar" 44 } } >py
     [ "foo" py-dict-get-item-string getrefcount py> ]
     [
@@ -68,7 +48,7 @@ PY-FROM: sys => getrefcount ( obj -- n ) ;
     [ "foo" py-dict-get-item-string getrefcount py> ] tri -
 ] py-test
 
-[ -2 ] [
+[ -1 ] [
     "abcd" >py <1py-tuple>
     [ 0 py-tuple-get-item getrefcount py> ]
     [
@@ -80,36 +60,22 @@ PY-FROM: sys => getrefcount ( obj -- n ) ;
 { t } [
     6 <py-tuple>
     [ getrefcount py> 1 - ]
-    [ always-destructors get [ alien>> = ] with count ] bi =
+    [ always-destructors get [ alien>> = ] with s:count ] bi =
 ] py-test
 
-
-
-PY-METHODS: file =>
-    close ( self -- )
-    fileno ( self -- n )
-    tell ( self -- n ) ;
-
 [ t ] [
     "python-file" temp-file >py "wb" >py open
     [ tell ] [ fileno ] [ close ] tri
     [ py> integer? ] bi@ and
 ] py-test
 
-PY-METHODS: str =>
-    lower ( self -- self' )
-    partition ( self sep -- bef sep aft )
-    startswith ( self str -- ? )
-    title ( self -- self' )
-    zfill ( self n -- str' ) ;
-
 ! Method chaining
 [ t ] [
     "hello there" >py title 20 >py zfill "00" >py startswith py>
 ] py-test
 
 [ { "hello" "=" "there" } ] [
-    "hello=there" >py "=" >py partition 3array [ py> ] map
+    "hello=there" >py "=" >py partition 3array [ py> ] s:map
 ] py-test
 
 ! Introspection
@@ -122,49 +88,28 @@ PY-METHODS: code =>
 [ 1 ] [ $splitext $func_code $co_argcount py> ] py-test
 
 ! Change sys.path
-PY-METHODS: list =>
-    append ( list obj -- )
-    remove ( list obj -- ) ;
-
 [ t ] [
     $path "test" >py [ append ] [ drop py> ] [ remove ] 2tri
     "test" swap in?
 ] py-test
 
-! setattr doesn't affect which objects $words are referencing.
-PY-FROM: sys => platform ( -- x ) ;
-
-[ t ] [
-    $platform "sys" py-import "platform" "tjaba" >py setattr $platform =
-] py-test
-
 ! Support for kwargs
-PY-FROM: datetime => timedelta ( ** -- timedelta ) ;
-
 [ "datetime.timedelta(4, 10800)" ] [
     H{ { "hours" 99 } } >py timedelta repr py>
 ] py-test
 
 ! Kwargs in methods
-PY-FROM: argparse => ArgumentParser ( -- self ) ;
-PY-METHODS: ArgumentParser =>
-    add_argument ( self name ** -- )
-    format_help ( self -- str ) ;
-
 [ t ] [
     [
         ArgumentParser dup
         "--foo" >py H{ { "help" "badger" } } >py add_argument
         format_help py>
-    ] with-destructors [ blank? ] trim " " split "badger" swap in?
+    ] with-destructors [ blank? ] s:trim " " split "badger" swap in?
 ] py-test
 
-! Can you pass a callback written in factor to a python function?
-PY-FROM: wsgiref.simple_server => make_server ( iface port callback -- httpd ) ;
-
 { t } [
-    [ 987 >py basename ] [ traceback>> ] recover length 0 >
-] unit-test
+    [ 987 >py basename ] [ traceback>> ] recover s:length 0 >
+] py-test
 
 ! Test if exceptions leak references. If so, the test will leak a few
 ! hundred megs of memory. Enough to be noticed but not to slow down
@@ -182,11 +127,7 @@ PY-FROM: wsgiref.simple_server => make_server ( iface port callback -- httpd ) ;
     ] times
 ] unit-test
 
-
 ! Working with types
-PY-METHODS: obj =>
-    __name__ ( self -- n ) ;
-
 PY-QUALIFIED-FROM: types => UnicodeType ( -- ) ;
 
 { "unicode" } [
@@ -194,7 +135,6 @@ PY-QUALIFIED-FROM: types => UnicodeType ( -- ) ;
 ] py-test
 
 ! Make callbacks
-
 PY-QUALIFIED-FROM: __builtin__ =>
     None ( -- )
     map ( func seq -- seq' )
@@ -205,14 +145,16 @@ PY-QUALIFIED-FROM: __builtin__ =>
 ] py-test
 
 : double-fun ( -- alien )
-    [ drop first 2 * ] quot>py-callback ;
+    [ drop s:first 2 * ] quot>py-callback ;
 
 { V{ 2 4 16 2 4 68 } } [
-    double-fun [ { 1 2 8 1 2 34 } >py __builtin__:map py> ] with-quot>py-cfunction
+    double-fun [
+        { 1 2 8 1 2 34 } >py __builtin__:map py>
+    ] with-quot>py-cfunction
 ] py-test
 
 : reduce-func ( -- alien )
-    [ drop first2 + ] quot>py-callback ;
+    [ drop s:first2 + ] quot>py-callback ;
 
 { 48 } [
     reduce-func [
index 9dba3b5994d338bcaf9400c8eb5adf913b52d78d..62a3fbddc2def2772104c1d2cb84ad6f2f50372a 100644 (file)
@@ -1,6 +1,6 @@
 USING: accessors arrays combinators effects effects.parser fry generalizations
-kernel lexer math namespaces parser python python.ffi python.objects sequences
-sequences.generalizations vocabs.parser words ;
+kernel lexer locals math namespaces parser python python.ffi python.objects
+sequences sequences.generalizations vocabs.parser words ;
 IN: python.syntax
 
 <PRIVATE
@@ -29,9 +29,9 @@ SYMBOL: current-context
         [ '[ py-tuple>array _ firstn ] ]
     } case ;
 
-: make-function-quot ( alien effect -- quot )
+: make-function-quot ( obj-quot effect -- quot )
     [ in>> gather-args-quot ] [ out>> unpack-value-quot ] bi
-    swapd '[ @ _ -rot call-object-full @ ] ;
+    swapd '[ @ @ -rot call-object-full @ ] ;
 
 : make-factor-words ( module name prefix? -- call-word obj-word )
     [ [ ":" glue ] [ ":$" glue ] 2bi ] [ nip dup "$" prepend ] if
@@ -40,13 +40,10 @@ SYMBOL: current-context
 : import-getattr ( module name -- alien )
     [ py-import ] dip getattr ;
 
-: make-creator-quots ( alien effect -- call-quot obj-quot )
-    [ '[ _ _ [ make-function-quot ] keep define-inline ] ]
-    [ drop '[ [ _ ] { } { "obj" } <effect> define-inline ] ] 2bi ; inline
-
-: add-function ( effect module name prefix? -- )
-    [ make-factor-words ] [ drop import-getattr ] 3bi [ rot ] dip swap
-    make-creator-quots bi* ;
+:: add-function ( name effect module prefix? -- )
+    module name prefix? make-factor-words :> ( call-word obj-word )
+    obj-word module name '[ _ _ import-getattr ] ( -- o ) define-inline
+    call-word obj-word def>> effect make-function-quot effect define-inline ;
 
 : make-method-quot ( name effect -- quot )
     [ in>> 1 tail gather-args-quot ] [ out>> unpack-value-quot ] bi swapd
@@ -65,11 +62,11 @@ SYMBOL: current-context
 PRIVATE>
 
 SYNTAX: PY-FROM: [
-    current-context get rot f add-function
+    current-context get f add-function
 ] scan-definitions ; inline
 
 SYNTAX: PY-QUALIFIED-FROM: [
-    current-context get rot t add-function
+    current-context get t add-function
 ] scan-definitions ; inline
 
 SYNTAX: PY-METHODS: [ add-method ] scan-definitions ; inline