FUNCTION: c-string PyModule_GetName ( PyObject* module ) ;
FUNCTION: PyObject* PyModule_GetDict ( PyObject* module ) ;
+! Callables
+FUNCTION: int PyCallable_Check ( PyObject* obj ) ;
+
! Objects
FUNCTION: PyObject* PyObject_CallObject ( PyObject* callable,
PyObject* args ) ;
fry kernel
math
namespaces
- python python.ffi python.stdlib.builtin python.stdlib.sys
+ python python.ffi
sequences
strings tools.test ;
IN: python.tests
[ t ] [
"os" import PyModule_GetDict dup Py_IncRef &Py_DecRef py-dict-size 100 >
] py-test
-
-! Reference counting tests
-[ 2 ] [ 3 <py-tuple> getrefcount >factor ] py-test
-
-[ -2 ] [
- H{ { "foo" 33 } { "bar" 44 } } >py
- [ "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 >factor ] tri -
-] py-test
-
-[ -2 ] [
- "abcd" >py <1py-tuple>
- [ 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 >factor ] tri -
-] py-test
-
-! Tests for builtins
-[ 10 ] [ 10 range >factor length ] py-test
-
-[ t ] [ "os" import "getpid" getattr callable >factor ] py-test
[ PyUnicodeUCS2_FromString ] if ;
! Data marshalling to Python
+: array>py-tuple ( arr -- py-tuple )
+ [ length <py-tuple> dup ] keep
+ [ rot py-tuple-set-item ] with each-index ;
+
GENERIC: (>py) ( obj -- obj' )
M: string (>py) utf8>py-unicode ;
M: math:fixnum (>py) PyLong_FromLong ;
M: math:float (>py) PyFloat_FromDouble ;
-
-M: array (>py)
- [ length <py-tuple> dup ] [ [ (>py) ] map ] bi
- [ rot py-tuple-set-item ] with each-index ;
-
+M: array (>py) [ (>py) ] map array>py-tuple ;
M: hashtable (>py)
<py-dict> swap dupd [
swapd [ (>py) ] [ (>py) ] bi* py-dict-set-item
] with assoc-each ;
-! ! I'll make a fast-path for this
M: word (>py) name>> (>py) ;
: >py ( obj -- py-obj )
+++ /dev/null
-USING: alien arrays kernel namespaces python ;
-IN: python.stdlib.builtin
-
-py-initialize
-
-SYMBOL: builtin
-
-builtin [ "__builtin__" import ] initialize
-
-: simple-call ( arg func-name -- return )
- builtin get swap getattr swap <1py-tuple> call-object ;
-
-: repr ( alien/factor -- py-str )
- dup alien? [ >py ] unless "repr" simple-call ;
-
-: range ( n -- py-list )
- >py "range" simple-call ;
-
-: dir ( obj -- py-list )
- "dir" simple-call ;
-
-: type ( obj -- py-obj )
- "type" simple-call ;
-
-: callable ( obj -- py-obj )
- "callable" simple-call ;
+++ /dev/null
-USING: kernel namespaces python ;
-IN: python.stdlib.sys
-
-py-initialize
-
-SYMBOL: sys
-sys [ "sys" import ] initialize
-
-: getrefcount ( alien -- py-int )
- <1py-tuple> sys get "getrefcount" getattr swap call-object ;
--- /dev/null
+USING:
+ 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
+
+! 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" ] [ "hello.doc" splitext ] unit-test
+
+PY-FROM: time => sleep ( n -- ) ;
+
+[ ] [ 0 sleep ] unit-test
+
+! Module variables are bound as zero-arg functions
+PY-FROM: sys => path ( -- seq ) ;
+
+[ t ] [ path sequence? ] unit-test
+
+! Use the pipe functions to work on PyObjects.
+PY-FROM: __builtin__ =>
+ callable ( obj -- ? )
+ int ( val -- s )
+ len ( seq -- n )
+ range ( n -- seq ) ;
+
+[ t ] [ path| |len| |int 5 > ] unit-test
+
+[ 10 ] [ 10 range| |len ] py-test
+
+! Callables
+[ t ] [
+ "os" import "getpid" getattr
+ [ |callable ] [ PyCallable_Check 1 = ] bi and
+] py-test
+
+! Reference counting
+PY-FROM: sys => getrefcount ( obj -- n ) ;
+
+[ 2 ] [ 3 <py-tuple> |getrefcount ] py-test
+
+[ -2 ] [
+ H{ { "foo" 33 } { "bar" 44 } } >py
+ [ "foo" py-dict-get-item-string |getrefcount ]
+ [
+ '[
+ 500 [ _ "foo" py-dict-get-item-string drop ] times
+ ] with-destructors
+ ]
+ [ "foo" py-dict-get-item-string |getrefcount ] tri -
+] py-test
+
+[ -2 ] [
+ "abcd" >py <1py-tuple>
+ [ 0 py-tuple-get-item |getrefcount ]
+ [
+ [ 100 [ swap 0 py-tuple-get-item drop ] with times ] with-destructors
+ ]
+ [ 0 py-tuple-get-item |getrefcount ] tri -
+] py-test
--- /dev/null
+USING:
+ accessors
+ arrays
+ effects effects.parser
+ formatting
+ fry
+ generalizations
+ kernel
+ lexer
+ locals
+ namespaces
+ parser
+ python python.ffi
+ sequences sequences.generalizations
+ vocabs.parser
+ words ;
+IN: python.syntax
+
+py-initialize
+
+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 -- )
+ function "%s" effect [ factor>factor-quot ] make-function
+ function "|%s" effect [ py>factor-quot ] make-function
+ function "|%s|" effect in>> { "ret" } <effect> [ py>py-quot ] make-function
+ function "%s|" effect in>> { "ret" } <effect> [ factor>py-quot ] make-function
+ ; inline
+
+: parse-python-word ( -- )
+ scan-token dup ";" = [ drop ] [
+ scan-effect add-function parse-python-word
+ ] if ; inline recursive
+
+SYNTAX: PY-FROM:
+ scan-token import current-module set "=>" expect parse-python-word ; inline