python: much improved syntax, $ sigil used to get object values
							parent
							
								
									a75a5d7458
								
							
						
					
					
						commit
						981c26596c
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
USING: arrays assocs destructors fry kernel math namespaces python python.ffi
 | 
			
		||||
python.syntax python.tests sequences tools.test ;
 | 
			
		||||
python.syntax python.tests sequences sets tools.test ;
 | 
			
		||||
IN: python.syntax.tests
 | 
			
		||||
 | 
			
		||||
! Importing functions
 | 
			
		||||
| 
						 | 
				
			
			@ -24,20 +24,21 @@ PY-FROM: time => sleep ( n -- ) ;
 | 
			
		|||
 | 
			
		||||
[ ] [ 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 >factor sequence? ] unit-test
 | 
			
		||||
[ t ] [ $path >factor sequence? ] unit-test
 | 
			
		||||
 | 
			
		||||
! ! Use the pipe functions to work on PyObjects.
 | 
			
		||||
PY-FROM: __builtin__ =>
 | 
			
		||||
    callable ( obj -- ? )
 | 
			
		||||
    open ( name mode -- file )
 | 
			
		||||
    dir ( obj -- seq )
 | 
			
		||||
    int ( val -- s )
 | 
			
		||||
    len ( seq -- n )
 | 
			
		||||
    range ( n -- seq ) ;
 | 
			
		||||
    open ( name mode -- file )
 | 
			
		||||
    range ( n -- seq )
 | 
			
		||||
    repr ( obj -- str ) ;
 | 
			
		||||
 | 
			
		||||
[ t ] [ path len int >factor 5 > ] unit-test
 | 
			
		||||
[ t ] [ $path len int >factor 5 > ] unit-test
 | 
			
		||||
 | 
			
		||||
[ 10 ] [ 10 >py range len >factor ] unit-test
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,16 +80,40 @@ PY-METHODS: file =>
 | 
			
		|||
 | 
			
		||||
[ t ] [
 | 
			
		||||
    "testfile" >py "wb" >py open
 | 
			
		||||
    [ ->tell ] [ ->fileno ] [ ->close ] tri
 | 
			
		||||
    [ tell ] [ fileno ] [ close ] tri
 | 
			
		||||
    [ >factor integer? ] bi@ and
 | 
			
		||||
] py-test
 | 
			
		||||
 | 
			
		||||
PY-METHODS: str =>
 | 
			
		||||
    title ( 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 >factor
 | 
			
		||||
    "hello there" >py title 20 >py zfill "00" >py startswith >factor
 | 
			
		||||
] py-test
 | 
			
		||||
 | 
			
		||||
[ { "hello" "=" "there" } ] [
 | 
			
		||||
    "hello=there" >py "=" >py partition 3array [ >factor ] map
 | 
			
		||||
] py-test
 | 
			
		||||
 | 
			
		||||
! Introspection
 | 
			
		||||
PY-METHODS: func =>
 | 
			
		||||
    func_code ( func -- code ) ;
 | 
			
		||||
 | 
			
		||||
PY-METHODS: code =>
 | 
			
		||||
    co_argcount ( code -- n ) ;
 | 
			
		||||
 | 
			
		||||
[ 1 ] [ $splitext $func_code $co_argcount >factor ] py-test
 | 
			
		||||
 | 
			
		||||
! Change sys.path
 | 
			
		||||
PY-METHODS: list =>
 | 
			
		||||
    append ( list obj -- )
 | 
			
		||||
    remove ( list obj -- ) ;
 | 
			
		||||
 | 
			
		||||
[ t ] [
 | 
			
		||||
    $path "test" >py [ append ] [ drop >factor ] [ remove ] 2tri
 | 
			
		||||
    "test" swap in?
 | 
			
		||||
] py-test
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,50 +1,57 @@
 | 
			
		|||
USING: accessors arrays effects effects.parser fry generalizations
 | 
			
		||||
kernel lexer locals math namespaces parser python python.ffi sequences
 | 
			
		||||
kernel lexer math namespaces parser python python.ffi sequences
 | 
			
		||||
sequences.generalizations vocabs.parser words ;
 | 
			
		||||
IN: python.syntax
 | 
			
		||||
 | 
			
		||||
py-initialize
 | 
			
		||||
 | 
			
		||||
SYMBOL: current-module
 | 
			
		||||
SYMBOL: current-context
 | 
			
		||||
 | 
			
		||||
: call-or-eval ( args obj -- ret )
 | 
			
		||||
    dup PyCallable_Check 1 = [ swap call-object ] [ nip ] if ;
 | 
			
		||||
: with-each-definition ( quot -- )
 | 
			
		||||
    scan-token dup ";" = [ 2drop ] [
 | 
			
		||||
        scan-effect rot [ call( tok eff -- ) ] keep with-each-definition
 | 
			
		||||
    ] if ; inline recursive
 | 
			
		||||
 | 
			
		||||
:: add-function ( function effect -- )
 | 
			
		||||
    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 <py-tuple> ] when ] keep
 | 
			
		||||
: scan-definitions ( quot -- )
 | 
			
		||||
    scan-token current-context set "=>" expect with-each-definition ; inline
 | 
			
		||||
 | 
			
		||||
: unpack-value ( alien -- * )
 | 
			
		||||
    [ 0 = [ drop 0 <py-tuple> ] when ] keep
 | 
			
		||||
    [ 1 = [ <1py-tuple> ] when ] keep
 | 
			
		||||
        [ py-tuple>array ] dip firstn
 | 
			
		||||
    ] effect define-inline ; inline
 | 
			
		||||
    [ py-tuple>array ] dip firstn ; inline
 | 
			
		||||
 | 
			
		||||
: parse-python-word ( -- )
 | 
			
		||||
    scan-token dup ";" = [ drop ] [
 | 
			
		||||
        scan-effect add-function parse-python-word
 | 
			
		||||
    ] if ; inline recursive
 | 
			
		||||
: make-function-quot ( alien in out -- quot )
 | 
			
		||||
    swapd '[ _ narray array>py-tuple _ swap call-object _ unpack-value ] ;
 | 
			
		||||
 | 
			
		||||
SYNTAX: PY-FROM:
 | 
			
		||||
    scan-token import current-module set "=>" expect parse-python-word ; inline
 | 
			
		||||
: function-callable ( name alien effect -- )
 | 
			
		||||
    [ create-in ] 2dip
 | 
			
		||||
    [ [ in>> length ] [ out>> length ] bi make-function-quot ] keep
 | 
			
		||||
    define-inline ; inline
 | 
			
		||||
 | 
			
		||||
:: add-method ( attr effect -- )
 | 
			
		||||
    attr "->" prepend create-in
 | 
			
		||||
    effect [ in>> length 1 - ] [ out>> length ] bi
 | 
			
		||||
: function-object ( name alien -- )
 | 
			
		||||
    [ "$" prepend create-in ] [ '[ _ ] ] bi*
 | 
			
		||||
    { } { "obj" } <effect> define-inline ; inline
 | 
			
		||||
 | 
			
		||||
    '[ _ narray array>py-tuple swap attr getattr swap call-object
 | 
			
		||||
       _ [ 1 = [ 1array ] when ] [ firstn ] bi ]
 | 
			
		||||
: add-function ( name effect -- )
 | 
			
		||||
    [ dup current-context get import swap getattr 2dup ] dip
 | 
			
		||||
    function-callable function-object ; inline
 | 
			
		||||
 | 
			
		||||
SYNTAX: PY-FROM: [ add-function ] scan-definitions ; inline
 | 
			
		||||
 | 
			
		||||
    ! '[ attr getattr _ narray array>py-tuple call-object
 | 
			
		||||
    !    _ [ 1 = [ 1array ] when ] [ firstn ] bi ]
 | 
			
		||||
    effect define-inline ;
 | 
			
		||||
: make-method-quot ( name in out -- ret )
 | 
			
		||||
    swapd '[
 | 
			
		||||
        _ narray array>py-tuple swap
 | 
			
		||||
        _ getattr swap call-object
 | 
			
		||||
        _ unpack-value
 | 
			
		||||
    ] ;
 | 
			
		||||
 | 
			
		||||
: parse-python-method ( -- )
 | 
			
		||||
    scan-token dup ";" = [ drop ] [
 | 
			
		||||
        scan-effect add-method parse-python-method
 | 
			
		||||
    ] if ; inline recursive
 | 
			
		||||
: method-object ( name -- )
 | 
			
		||||
    [ "$" prepend create-in ] [ '[ _ getattr ] ] bi
 | 
			
		||||
    { "obj" } { "obj'" } <effect> define-inline ;
 | 
			
		||||
 | 
			
		||||
SYNTAX: PY-METHODS:
 | 
			
		||||
    scan-token drop "=>" expect parse-python-method ; inline
 | 
			
		||||
: add-method ( name effect -- )
 | 
			
		||||
    [ dup dup create-in swap ] dip
 | 
			
		||||
    [ [ in>> length 1 - ] [ out>> length ] bi make-method-quot ] keep
 | 
			
		||||
    define-inline method-object ;
 | 
			
		||||
 | 
			
		||||
SYNTAX: PY-METHODS: [ add-method ] scan-definitions ; inline
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue