python.syntax: vocab that makes python functions work like factor words
							parent
							
								
									7b92bad65a
								
							
						
					
					
						commit
						0af4fee085
					
				| 
						 | 
					@ -71,6 +71,9 @@ FUNCTION: int PyList_Size ( PyObject* t ) ;
 | 
				
			||||||
FUNCTION: c-string PyModule_GetName ( PyObject* module ) ;
 | 
					FUNCTION: c-string PyModule_GetName ( PyObject* module ) ;
 | 
				
			||||||
FUNCTION: PyObject* PyModule_GetDict ( PyObject* module ) ;
 | 
					FUNCTION: PyObject* PyModule_GetDict ( PyObject* module ) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Callables
 | 
				
			||||||
 | 
					FUNCTION: int PyCallable_Check ( PyObject* obj ) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Objects
 | 
					! Objects
 | 
				
			||||||
FUNCTION: PyObject* PyObject_CallObject ( PyObject* callable,
 | 
					FUNCTION: PyObject* PyObject_CallObject ( PyObject* callable,
 | 
				
			||||||
                                          PyObject* args ) ;
 | 
					                                          PyObject* args ) ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ USING:
 | 
				
			||||||
    fry kernel
 | 
					    fry kernel
 | 
				
			||||||
    math
 | 
					    math
 | 
				
			||||||
    namespaces
 | 
					    namespaces
 | 
				
			||||||
    python python.ffi python.stdlib.builtin python.stdlib.sys
 | 
					    python python.ffi
 | 
				
			||||||
    sequences
 | 
					    sequences
 | 
				
			||||||
    strings tools.test ;
 | 
					    strings tools.test ;
 | 
				
			||||||
IN: python.tests
 | 
					IN: python.tests
 | 
				
			||||||
| 
						 | 
					@ -116,31 +116,3 @@ SYMBOLS: year month day ;
 | 
				
			||||||
[ t ] [
 | 
					[ t ] [
 | 
				
			||||||
    "os" import PyModule_GetDict dup Py_IncRef &Py_DecRef py-dict-size 100 >
 | 
					    "os" import PyModule_GetDict dup Py_IncRef &Py_DecRef py-dict-size 100 >
 | 
				
			||||||
] py-test
 | 
					] 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
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,21 +107,20 @@ ERROR: python-error type message ;
 | 
				
			||||||
    [ PyUnicodeUCS2_FromString ] if ;
 | 
					    [ PyUnicodeUCS2_FromString ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Data marshalling to Python
 | 
					! 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' )
 | 
					GENERIC: (>py) ( obj -- obj' )
 | 
				
			||||||
M: string (>py) utf8>py-unicode ;
 | 
					M: string (>py) utf8>py-unicode ;
 | 
				
			||||||
M: math:fixnum (>py) PyLong_FromLong ;
 | 
					M: math:fixnum (>py) PyLong_FromLong ;
 | 
				
			||||||
M: math:float (>py) PyFloat_FromDouble ;
 | 
					M: math:float (>py) PyFloat_FromDouble ;
 | 
				
			||||||
 | 
					M: array (>py) [ (>py) ] map array>py-tuple ;
 | 
				
			||||||
M: array (>py)
 | 
					 | 
				
			||||||
    [ length <py-tuple> dup ] [ [ (>py) ] map ] bi
 | 
					 | 
				
			||||||
    [ rot py-tuple-set-item ] with each-index ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: hashtable (>py)
 | 
					M: hashtable (>py)
 | 
				
			||||||
    <py-dict> swap dupd [
 | 
					    <py-dict> swap dupd [
 | 
				
			||||||
        swapd [ (>py) ] [ (>py) ] bi* py-dict-set-item
 | 
					        swapd [ (>py) ] [ (>py) ] bi* py-dict-set-item
 | 
				
			||||||
    ] with assoc-each ;
 | 
					    ] with assoc-each ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! ! I'll make a fast-path for this
 | 
					 | 
				
			||||||
M: word (>py) name>> (>py) ;
 | 
					M: word (>py) name>> (>py) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: >py ( obj -- py-obj )
 | 
					: >py ( obj -- py-obj )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,26 +0,0 @@
 | 
				
			||||||
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 ;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
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 ;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,81 @@
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
		Loading…
	
		Reference in New Issue