python.syntax: new way to bind python functions to factor words and updated tests
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.db4
parent
f0b07540d3
commit
584e9c5ce2
|
@ -1,63 +1,43 @@
|
||||||
USING: accessors arrays assocs continuations destructors destructors.private
|
USING: accessors arrays assocs continuations destructors destructors.private
|
||||||
fry io.files.temp kernel math namespaces python python.ffi python.objects
|
fry io.files.temp kernel math namespaces python python.ffi
|
||||||
python.syntax sequences sets splitting tools.test unicode.categories ;
|
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
|
IN: python.syntax.tests
|
||||||
|
|
||||||
: py-test ( result quot -- )
|
: py-test ( result quot -- )
|
||||||
'[ _ with-destructors ] unit-test ; inline
|
'[ _ with-destructors ] unit-test ; inline
|
||||||
|
|
||||||
! py-importing functions
|
{ t } [ getpid py> integer? ] py-test
|
||||||
PY-FROM: os =>
|
|
||||||
getpid ( -- y )
|
|
||||||
system ( x -- y ) ;
|
|
||||||
|
|
||||||
[ t ] [ getpid py> integer? ] unit-test
|
|
||||||
|
|
||||||
! Automatic tuple unpacking
|
! Automatic tuple unpacking
|
||||||
PY-FROM: os.path =>
|
[ "hello.doc" ] [ "/some/path/hello.doc" >py basename py> ] py-test
|
||||||
basename ( x -- x' )
|
|
||||||
splitext ( x -- base ext ) ;
|
|
||||||
|
|
||||||
[ "hello.doc" ] [ "/some/path/hello.doc" >py basename py> ] unit-test
|
|
||||||
|
|
||||||
[ { "hello" ".doc" } ] [
|
[ { "hello" ".doc" } ] [
|
||||||
"hello.doc" >py splitext 2array [ py> ] map
|
"hello.doc" >py splitext 2array [ py> ] s:map
|
||||||
] unit-test
|
] py-test
|
||||||
|
|
||||||
PY-FROM: time => sleep ( n -- ) ;
|
[ ] [ 0 >py sleep ] py-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 ) argv ( -- seq ) ;
|
[ t ] [ $path py> s:sequence? ] py-test
|
||||||
|
|
||||||
[ t ] [ $path py> sequence? ] unit-test
|
[ t ] [ $path len int py> 5 > ] py-test
|
||||||
|
|
||||||
PY-FROM: __builtin__ =>
|
[ 10 ] [ 10 >py range len py> ] py-test
|
||||||
callable ( obj -- ? )
|
|
||||||
dir ( obj -- seq )
|
|
||||||
int ( val -- s )
|
|
||||||
len ( seq -- n )
|
|
||||||
open ( name mode -- file )
|
|
||||||
range ( n -- seq )
|
|
||||||
repr ( obj -- str ) ;
|
|
||||||
|
|
||||||
[ t ] [ $path len int py> 5 > ] unit-test
|
|
||||||
|
|
||||||
[ 10 ] [ 10 >py range len py> ] unit-test
|
|
||||||
|
|
||||||
! Callables
|
! Callables
|
||||||
[ t ] [
|
[ t ] [
|
||||||
"os" py-import "getpid" getattr
|
"os" py-import "getpid" getattr
|
||||||
[ callable ] [ PyCallable_Check 1 = ] bi and
|
[ callable ] [ PyCallable_Check 1 = ] bi and
|
||||||
] unit-test
|
] py-test
|
||||||
|
|
||||||
! Reference counting
|
! Reference counting
|
||||||
PY-FROM: sys => getrefcount ( obj -- n ) ;
|
[ 1 ] [ 3 <py-tuple> getrefcount py> ] py-test
|
||||||
|
|
||||||
[ 2 ] [ 3 <py-tuple> getrefcount py> ] unit-test
|
[ -1 ] [
|
||||||
|
|
||||||
[ -2 ] [
|
|
||||||
H{ { "foo" 33 } { "bar" 44 } } >py
|
H{ { "foo" 33 } { "bar" 44 } } >py
|
||||||
[ "foo" py-dict-get-item-string getrefcount 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 -
|
[ "foo" py-dict-get-item-string getrefcount py> ] tri -
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
[ -2 ] [
|
[ -1 ] [
|
||||||
"abcd" >py <1py-tuple>
|
"abcd" >py <1py-tuple>
|
||||||
[ 0 py-tuple-get-item getrefcount py> ]
|
[ 0 py-tuple-get-item getrefcount py> ]
|
||||||
[
|
[
|
||||||
|
@ -80,36 +60,22 @@ PY-FROM: sys => getrefcount ( obj -- n ) ;
|
||||||
{ t } [
|
{ t } [
|
||||||
6 <py-tuple>
|
6 <py-tuple>
|
||||||
[ getrefcount py> 1 - ]
|
[ getrefcount py> 1 - ]
|
||||||
[ always-destructors get [ alien>> = ] with count ] bi =
|
[ always-destructors get [ alien>> = ] with s:count ] bi =
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PY-METHODS: file =>
|
|
||||||
close ( self -- )
|
|
||||||
fileno ( self -- n )
|
|
||||||
tell ( self -- n ) ;
|
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
"python-file" temp-file >py "wb" >py open
|
"python-file" temp-file >py "wb" >py open
|
||||||
[ tell ] [ fileno ] [ close ] tri
|
[ tell ] [ fileno ] [ close ] tri
|
||||||
[ py> integer? ] bi@ and
|
[ py> integer? ] bi@ and
|
||||||
] py-test
|
] 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
|
! Method chaining
|
||||||
[ t ] [
|
[ t ] [
|
||||||
"hello there" >py title 20 >py zfill "00" >py startswith py>
|
"hello there" >py title 20 >py zfill "00" >py startswith py>
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
[ { "hello" "=" "there" } ] [
|
[ { "hello" "=" "there" } ] [
|
||||||
"hello=there" >py "=" >py partition 3array [ py> ] map
|
"hello=there" >py "=" >py partition 3array [ py> ] s:map
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
! Introspection
|
! Introspection
|
||||||
|
@ -122,49 +88,28 @@ PY-METHODS: code =>
|
||||||
[ 1 ] [ $splitext $func_code $co_argcount py> ] py-test
|
[ 1 ] [ $splitext $func_code $co_argcount py> ] py-test
|
||||||
|
|
||||||
! Change sys.path
|
! Change sys.path
|
||||||
PY-METHODS: list =>
|
|
||||||
append ( list obj -- )
|
|
||||||
remove ( list obj -- ) ;
|
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
$path "test" >py [ append ] [ drop py> ] [ remove ] 2tri
|
$path "test" >py [ append ] [ drop py> ] [ remove ] 2tri
|
||||||
"test" swap in?
|
"test" swap in?
|
||||||
] py-test
|
] 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
|
! Support for kwargs
|
||||||
PY-FROM: datetime => timedelta ( ** -- timedelta ) ;
|
|
||||||
|
|
||||||
[ "datetime.timedelta(4, 10800)" ] [
|
[ "datetime.timedelta(4, 10800)" ] [
|
||||||
H{ { "hours" 99 } } >py timedelta repr py>
|
H{ { "hours" 99 } } >py timedelta repr py>
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
! Kwargs in methods
|
! Kwargs in methods
|
||||||
PY-FROM: argparse => ArgumentParser ( -- self ) ;
|
|
||||||
PY-METHODS: ArgumentParser =>
|
|
||||||
add_argument ( self name ** -- )
|
|
||||||
format_help ( self -- str ) ;
|
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
[
|
[
|
||||||
ArgumentParser dup
|
ArgumentParser dup
|
||||||
"--foo" >py H{ { "help" "badger" } } >py add_argument
|
"--foo" >py H{ { "help" "badger" } } >py add_argument
|
||||||
format_help py>
|
format_help py>
|
||||||
] with-destructors [ blank? ] trim " " split "badger" swap in?
|
] with-destructors [ blank? ] s:trim " " split "badger" swap in?
|
||||||
] py-test
|
] 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 } [
|
{ t } [
|
||||||
[ 987 >py basename ] [ traceback>> ] recover length 0 >
|
[ 987 >py basename ] [ traceback>> ] recover s:length 0 >
|
||||||
] unit-test
|
] py-test
|
||||||
|
|
||||||
! Test if exceptions leak references. If so, the test will leak a few
|
! 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
|
! 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
|
] times
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
|
||||||
! Working with types
|
! Working with types
|
||||||
PY-METHODS: obj =>
|
|
||||||
__name__ ( self -- n ) ;
|
|
||||||
|
|
||||||
PY-QUALIFIED-FROM: types => UnicodeType ( -- ) ;
|
PY-QUALIFIED-FROM: types => UnicodeType ( -- ) ;
|
||||||
|
|
||||||
{ "unicode" } [
|
{ "unicode" } [
|
||||||
|
@ -194,7 +135,6 @@ PY-QUALIFIED-FROM: types => UnicodeType ( -- ) ;
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
! Make callbacks
|
! Make callbacks
|
||||||
|
|
||||||
PY-QUALIFIED-FROM: __builtin__ =>
|
PY-QUALIFIED-FROM: __builtin__ =>
|
||||||
None ( -- )
|
None ( -- )
|
||||||
map ( func seq -- seq' )
|
map ( func seq -- seq' )
|
||||||
|
@ -205,14 +145,16 @@ PY-QUALIFIED-FROM: __builtin__ =>
|
||||||
] py-test
|
] py-test
|
||||||
|
|
||||||
: double-fun ( -- alien )
|
: double-fun ( -- alien )
|
||||||
[ drop first 2 * ] quot>py-callback ;
|
[ drop s:first 2 * ] quot>py-callback ;
|
||||||
|
|
||||||
{ V{ 2 4 16 2 4 68 } } [
|
{ 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
|
] py-test
|
||||||
|
|
||||||
: reduce-func ( -- alien )
|
: reduce-func ( -- alien )
|
||||||
[ drop first2 + ] quot>py-callback ;
|
[ drop s:first2 + ] quot>py-callback ;
|
||||||
|
|
||||||
{ 48 } [
|
{ 48 } [
|
||||||
reduce-func [
|
reduce-func [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: accessors arrays combinators effects effects.parser fry generalizations
|
USING: accessors arrays combinators effects effects.parser fry generalizations
|
||||||
kernel lexer math namespaces parser python python.ffi python.objects sequences
|
kernel lexer locals math namespaces parser python python.ffi python.objects
|
||||||
sequences.generalizations vocabs.parser words ;
|
sequences sequences.generalizations vocabs.parser words ;
|
||||||
IN: python.syntax
|
IN: python.syntax
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -29,9 +29,9 @@ SYMBOL: current-context
|
||||||
[ '[ py-tuple>array _ firstn ] ]
|
[ '[ py-tuple>array _ firstn ] ]
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
: make-function-quot ( alien effect -- quot )
|
: make-function-quot ( obj-quot effect -- quot )
|
||||||
[ in>> gather-args-quot ] [ out>> unpack-value-quot ] bi
|
[ 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 )
|
: make-factor-words ( module name prefix? -- call-word obj-word )
|
||||||
[ [ ":" glue ] [ ":$" glue ] 2bi ] [ nip dup "$" prepend ] if
|
[ [ ":" glue ] [ ":$" glue ] 2bi ] [ nip dup "$" prepend ] if
|
||||||
|
@ -40,13 +40,10 @@ SYMBOL: current-context
|
||||||
: import-getattr ( module name -- alien )
|
: import-getattr ( module name -- alien )
|
||||||
[ py-import ] dip getattr ;
|
[ py-import ] dip getattr ;
|
||||||
|
|
||||||
: make-creator-quots ( alien effect -- call-quot obj-quot )
|
:: add-function ( name effect module prefix? -- )
|
||||||
[ '[ _ _ [ make-function-quot ] keep define-inline ] ]
|
module name prefix? make-factor-words :> ( call-word obj-word )
|
||||||
[ drop '[ [ _ ] { } { "obj" } <effect> define-inline ] ] 2bi ; inline
|
obj-word module name '[ _ _ import-getattr ] ( -- o ) define-inline
|
||||||
|
call-word obj-word def>> effect make-function-quot effect define-inline ;
|
||||||
: add-function ( effect module name prefix? -- )
|
|
||||||
[ make-factor-words ] [ drop import-getattr ] 3bi [ rot ] dip swap
|
|
||||||
make-creator-quots bi* ;
|
|
||||||
|
|
||||||
: make-method-quot ( name effect -- quot )
|
: make-method-quot ( name effect -- quot )
|
||||||
[ in>> 1 tail gather-args-quot ] [ out>> unpack-value-quot ] bi swapd
|
[ in>> 1 tail gather-args-quot ] [ out>> unpack-value-quot ] bi swapd
|
||||||
|
@ -65,11 +62,11 @@ SYMBOL: current-context
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
SYNTAX: PY-FROM: [
|
SYNTAX: PY-FROM: [
|
||||||
current-context get rot f add-function
|
current-context get f add-function
|
||||||
] scan-definitions ; inline
|
] scan-definitions ; inline
|
||||||
|
|
||||||
SYNTAX: PY-QUALIFIED-FROM: [
|
SYNTAX: PY-QUALIFIED-FROM: [
|
||||||
current-context get rot t add-function
|
current-context get t add-function
|
||||||
] scan-definitions ; inline
|
] scan-definitions ; inline
|
||||||
|
|
||||||
SYNTAX: PY-METHODS: [ add-method ] scan-definitions ; inline
|
SYNTAX: PY-METHODS: [ add-method ] scan-definitions ; inline
|
||||||
|
|
Loading…
Reference in New Issue