Merge branch 'master' into new_ui

db4
Slava Pestov 2009-02-10 16:23:14 -06:00
commit ab386d01aa
35 changed files with 487 additions and 307 deletions

View File

@ -1,9 +1,19 @@
! Copyright (C) 2009 Joe Groff ! Copyright (C) 2009 Joe Groff
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel quotations sequences strings ; USING: help.markup help.syntax kernel quotations sequences strings words.symbol ;
QUALIFIED-WITH: alien.syntax c QUALIFIED-WITH: alien.syntax c
IN: alien.fortran IN: alien.fortran
ARTICLE: "alien.fortran-abis" "Fortran ABIs"
"Fortran does not have a standard ABI like C does. Factor supports the following Fortran ABIs:"
{ $list
{ { $subsection gfortran-abi } " is used by gfortran, the Fortran compiler included with GCC 4." }
{ { $subsection f2c-abi } " is used by the F2C Fortran-to-C translator and G77, the Fortran compiler included with GCC 3.x and earlier. It is also used by gfortran when compiling with the -ff2c flag." }
{ { $subsection intel-unix-abi } " is used by the Intel Fortran Compiler on Linux and Mac OS X." }
{ { $subsection intel-windows-abi } " is used by the Intel Fortran Compiler on Windows." }
}
"A library's ABI is specified when that library is opened by the " { $link add-fortran-library } " word." ;
ARTICLE: "alien.fortran-types" "Fortran types" ARTICLE: "alien.fortran-types" "Fortran types"
"The Fortran FFI recognizes the following Fortran types:" "The Fortran FFI recognizes the following Fortran types:"
{ $list { $list
@ -15,7 +25,7 @@ ARTICLE: "alien.fortran-types" "Fortran types"
{ { $snippet "DOUBLE-COMPLEX" } " specifies a double-precision floating-point complex value. The alias " { $snippet "COMPLEX*16" } " is also recognized." } { { $snippet "DOUBLE-COMPLEX" } " specifies a double-precision floating-point complex value. The alias " { $snippet "COMPLEX*16" } " is also recognized." }
{ { $snippet "CHARACTER(n)" } " specifies a character string of length " { $snippet "n" } ". The Fortran 77 syntax " { $snippet "CHARACTER*n" } " is also recognized." } { { $snippet "CHARACTER(n)" } " specifies a character string of length " { $snippet "n" } ". The Fortran 77 syntax " { $snippet "CHARACTER*n" } " is also recognized." }
{ "Fortran arrays can be specified by suffixing a comma-separated set of dimensions in parentheses, e.g. " { $snippet "REAL(2,3,4)" } ". Arrays of unspecified length can be specified using " { $snippet "*" } " as a dimension. Arrays are passed in as flat " { $link "specialized-arrays" } "." } { "Fortran arrays can be specified by suffixing a comma-separated set of dimensions in parentheses, e.g. " { $snippet "REAL(2,3,4)" } ". Arrays of unspecified length can be specified using " { $snippet "*" } " as a dimension. Arrays are passed in as flat " { $link "specialized-arrays" } "." }
{ "Fortran records defined by " { $link POSTPONE: RECORD: } " and C structs defined by " { $link POSTPONE: c:C-STRUCT: } " are also supported as parameters." } { "Fortran records defined by " { $link POSTPONE: RECORD: } " and C structs defined by " { $link POSTPONE: c:C-STRUCT: } " are also supported as parameter and return types." }
} }
"When declaring the parameters of Fortran functions, an output argument can be specified by prefixing an exclamation point to the type name. This will cause the function word to leave the final value of the parameter on the stack." ; "When declaring the parameters of Fortran functions, an output argument can be specified by prefixing an exclamation point to the type name. This will cause the function word to leave the final value of the parameter on the stack." ;
@ -30,11 +40,16 @@ HELP: SUBROUTINE:
HELP: LIBRARY: HELP: LIBRARY:
{ $syntax "LIBRARY: name" } { $syntax "LIBRARY: name" }
{ $values { "name" "a logical library name" } } { $values { "name" "a logical library name" } }
{ $description "Sets the logical library for subsequent " { $link POSTPONE: FUNCTION: } " and " { $link POSTPONE: SUBROUTINE: } " definitions." } ; { $description "Sets the logical library for subsequent " { $link POSTPONE: FUNCTION: } " and " { $link POSTPONE: SUBROUTINE: } " definitions. The given library name must have been opened with a previous call to " { $link add-fortran-library } "." } ;
HELP: RECORD: HELP: RECORD:
{ $syntax "RECORD: NAME { \"TYPE\" \"SLOT\" } ... ;" } { $syntax "RECORD: NAME { \"TYPE\" \"SLOT\" } ... ;" }
{ $description "Defines a Fortran record type with the given slots." } ; { $description "Defines a Fortran record type with the given slots. The record is defined as the corresponding C struct and can be used as a type for subsequent Fortran or C function declarations." } ;
HELP: add-fortran-library
{ $values { "name" string } { "soname" string } { "fortran-abi" symbol } }
{ $description "Opens the shared library in the file specified by " { $snippet "soname" } " under the logical name " { $snippet "name" } " so that it may be used in subsequent " { $link POSTPONE: LIBRARY: } " and " { $link fortran-invoke } " calls. Functions and subroutines from the library will be defined using the specified " { $snippet "fortran-abi" } ", which must be one of the supported " { $link "alien.fortran-abis" } "." }
;
HELP: fortran-invoke HELP: fortran-invoke
{ $values { $values
@ -46,6 +61,8 @@ HELP: fortran-invoke
ARTICLE: "alien.fortran" "Fortran FFI" ARTICLE: "alien.fortran" "Fortran FFI"
"The " { $vocab-link "alien.fortran" } " vocabulary provides an interface to code in shared libraries written in Fortran." "The " { $vocab-link "alien.fortran" } " vocabulary provides an interface to code in shared libraries written in Fortran."
{ $subsection "alien.fortran-types" } { $subsection "alien.fortran-types" }
{ $subsection "alien.fortran-abis" }
{ $subsection add-fortran-library }
{ $subsection POSTPONE: LIBRARY: } { $subsection POSTPONE: LIBRARY: }
{ $subsection POSTPONE: FUNCTION: } { $subsection POSTPONE: FUNCTION: }
{ $subsection POSTPONE: SUBROUTINE: } { $subsection POSTPONE: SUBROUTINE: }

View File

@ -1,21 +1,25 @@
! (c) 2009 Joe Groff, see BSD license ! (c) 2009 Joe Groff, see BSD license
USING: accessors alien alien.c-types alien.complex USING: accessors alien alien.c-types alien.complex
alien.fortran alien.strings alien.structs alien.syntax arrays alien.fortran alien.fortran.private alien.strings alien.structs
assocs byte-arrays combinators fry generalizations arrays assocs byte-arrays combinators fry
io.encodings.ascii kernel macros macros.expander namespaces generalizations io.encodings.ascii kernel macros
sequences shuffle tools.test ; macros.expander namespaces sequences shuffle tools.test ;
IN: alien.fortran.tests IN: alien.fortran.tests
<< intel-unix-abi "(alien.fortran-tests)" (add-fortran-library) >>
LIBRARY: (alien.fortran-tests)
RECORD: FORTRAN_TEST_RECORD RECORD: FORTRAN_TEST_RECORD
{ "INTEGER" "FOO" } { "INTEGER" "FOO" }
{ "REAL(2)" "BAR" } { "REAL(2)" "BAR" }
{ "CHARACTER*4" "BAS" } ; { "CHARACTER*4" "BAS" } ;
intel-unix-abi fortran-abi [
! fortran-name>symbol-name ! fortran-name>symbol-name
[ "fun_" ] [ "FUN" fortran-name>symbol-name ] unit-test [ "fun_" ] [ "FUN" fortran-name>symbol-name ] unit-test
[ "fun_times__" ] [ "Fun_Times" fortran-name>symbol-name ] unit-test [ "fun_times_" ] [ "Fun_Times" fortran-name>symbol-name ] unit-test
[ "funtimes___" ] [ "FunTimes_" fortran-name>symbol-name ] unit-test [ "funtimes__" ] [ "FunTimes_" fortran-name>symbol-name ] unit-test
! fortran-type>c-type ! fortran-type>c-type
@ -46,9 +50,12 @@ RECORD: FORTRAN_TEST_RECORD
[ "int[24]" ] [ "int[24]" ]
[ "integer(4,3,2)" fortran-type>c-type ] unit-test [ "integer(4,3,2)" fortran-type>c-type ] unit-test
[ "char[1]" ] [ "char" ]
[ "character" fortran-type>c-type ] unit-test [ "character" fortran-type>c-type ] unit-test
[ "char" ]
[ "character*1" fortran-type>c-type ] unit-test
[ "char[17]" ] [ "char[17]" ]
[ "character*17" fortran-type>c-type ] unit-test [ "character*17" fortran-type>c-type ] unit-test
@ -99,14 +106,20 @@ RECORD: FORTRAN_TEST_RECORD
[ "fortran_test_record*" { } ] [ "fortran_test_record*" { } ]
[ "fortran_test_record" fortran-arg-type>c-type ] unit-test [ "fortran_test_record" fortran-arg-type>c-type ] unit-test
[ "char*" { "long" } ] [ "char*" { } ]
[ "character" fortran-arg-type>c-type ] unit-test [ "character" fortran-arg-type>c-type ] unit-test
[ "char*" { } ]
[ "character(1)" fortran-arg-type>c-type ] unit-test
[ "char*" { "long" } ] [ "char*" { "long" } ]
[ "character(17)" fortran-arg-type>c-type ] unit-test [ "character(17)" fortran-arg-type>c-type ] unit-test
! fortran-ret-type>c-type ! fortran-ret-type>c-type
[ "char" { } ]
[ "character(1)" fortran-ret-type>c-type ] unit-test
[ "void" { "char*" "long" } ] [ "void" { "char*" "long" } ]
[ "character(17)" fortran-ret-type>c-type ] unit-test [ "character(17)" fortran-ret-type>c-type ] unit-test
@ -119,6 +132,9 @@ RECORD: FORTRAN_TEST_RECORD
[ "float" { } ] [ "float" { } ]
[ "real" fortran-ret-type>c-type ] unit-test [ "real" fortran-ret-type>c-type ] unit-test
[ "void" { "float*" } ]
[ "real(*)" fortran-ret-type>c-type ] unit-test
[ "double" { } ] [ "double" { } ]
[ "double-precision" fortran-ret-type>c-type ] unit-test [ "double-precision" fortran-ret-type>c-type ] unit-test
@ -140,11 +156,15 @@ RECORD: FORTRAN_TEST_RECORD
[ "real" { "integer" "character*17" "real" "real*8" } fortran-sig>c-sig ] [ "real" { "integer" "character*17" "real" "real*8" } fortran-sig>c-sig ]
unit-test unit-test
[ "void" { "char*" "long" "char*" "char*" "int*" "long" "long" } ] [ "char" { "char*" "char*" "int*" "long" } ]
[ "character(1)" { "character*17" "character" "integer" } fortran-sig>c-sig ]
unit-test
[ "void" { "char*" "long" "char*" "char*" "int*" "long" } ]
[ "character*18" { "character*17" "character" "integer" } fortran-sig>c-sig ] [ "character*18" { "character*17" "character" "integer" } fortran-sig>c-sig ]
unit-test unit-test
[ "void" { "complex-float*" "char*" "char*" "int*" "long" "long" } ] [ "void" { "complex-float*" "char*" "char*" "int*" "long" } ]
[ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ] [ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ]
unit-test unit-test
@ -213,7 +233,7 @@ unit-test
[ { [ drop ] } spread ] [ { [ drop ] } spread ]
} 1 ncleave } 1 ncleave
! [fortran-invoke] ! [fortran-invoke]
[ "float" "funpack" "fun_times__" { "float*" } alien-invoke ] [ "float" "funpack" "fun_times_" { "float*" } alien-invoke ]
1 nkeep 1 nkeep
! [fortran-results>] ! [fortran-results>]
shuffle( reta aa -- reta aa ) shuffle( reta aa -- reta aa )
@ -230,7 +250,7 @@ unit-test
{ [ { [ ] } spread ] [ { [ drop ] } spread ] } 1 ncleave { [ { [ ] } spread ] [ { [ drop ] } spread ] } 1 ncleave
! [fortran-invoke] ! [fortran-invoke]
[ [
"void" "funpack" "fun_times__" "void" "funpack" "fun_times_"
{ "complex-float*" "float*" } { "complex-float*" "float*" }
alien-invoke alien-invoke
] 2 nkeep ] 2 nkeep
@ -247,7 +267,7 @@ unit-test
[ 20 <byte-array> 20 ] 0 ndip [ 20 <byte-array> 20 ] 0 ndip
! [fortran-invoke] ! [fortran-invoke]
[ [
"void" "funpack" "fun_times__" "void" "funpack" "fun_times_"
{ "char*" "long" } { "char*" "long" }
alien-invoke alien-invoke
] 2 nkeep ] 2 nkeep
@ -273,7 +293,7 @@ unit-test
} 3 ncleave } 3 ncleave
! [fortran-invoke] ! [fortran-invoke]
[ [
"void" "funpack" "fun_times__" "void" "funpack" "fun_times_"
{ "char*" "long" "char*" "float*" "char*" "long" "long" } { "char*" "long" "char*" "float*" "char*" "long" "long" }
alien-invoke alien-invoke
] 7 nkeep ] 7 nkeep
@ -293,3 +313,69 @@ unit-test
(fortran-invoke) (fortran-invoke)
] unit-test ] unit-test
] with-variable ! intel-unix-abi
intel-windows-abi fortran-abi [
[ "FUN" ] [ "FUN" fortran-name>symbol-name ] unit-test
[ "FUN_TIMES" ] [ "Fun_Times" fortran-name>symbol-name ] unit-test
[ "FUNTIMES_" ] [ "FunTimes_" fortran-name>symbol-name ] unit-test
] with-variable
f2c-abi fortran-abi [
[ "char[1]" ]
[ "character(1)" fortran-type>c-type ] unit-test
[ "char*" { "long" } ]
[ "character" fortran-arg-type>c-type ] unit-test
[ "void" { "char*" "long" } ]
[ "character" fortran-ret-type>c-type ] unit-test
[ "double" { } ]
[ "real" fortran-ret-type>c-type ] unit-test
[ "void" { "float*" } ]
[ "real(*)" fortran-ret-type>c-type ] unit-test
[ "fun_" ] [ "FUN" fortran-name>symbol-name ] unit-test
[ "fun_times__" ] [ "Fun_Times" fortran-name>symbol-name ] unit-test
[ "funtimes___" ] [ "FunTimes_" fortran-name>symbol-name ] unit-test
] with-variable
gfortran-abi fortran-abi [
[ "float" { } ]
[ "real" fortran-ret-type>c-type ] unit-test
[ "void" { "float*" } ]
[ "real(*)" fortran-ret-type>c-type ] unit-test
[ "complex-float" { } ]
[ "complex" fortran-ret-type>c-type ] unit-test
[ "complex-double" { } ]
[ "double-complex" fortran-ret-type>c-type ] unit-test
[ "char[1]" ]
[ "character(1)" fortran-type>c-type ] unit-test
[ "char*" { "long" } ]
[ "character" fortran-arg-type>c-type ] unit-test
[ "void" { "char*" "long" } ]
[ "character" fortran-ret-type>c-type ] unit-test
[ "complex-float" { } ]
[ "complex" fortran-ret-type>c-type ] unit-test
[ "complex-double" { } ]
[ "double-complex" fortran-ret-type>c-type ] unit-test
[ "void" { "complex-double*" } ]
[ "double-complex(3)" fortran-ret-type>c-type ] unit-test
] with-variable

View File

@ -5,11 +5,10 @@ byte-arrays combinators combinators.short-circuit fry generalizations
kernel lexer macros math math.parser namespaces parser sequences kernel lexer macros math math.parser namespaces parser sequences
splitting stack-checker vectors vocabs.parser words locals splitting stack-checker vectors vocabs.parser words locals
io.encodings.ascii io.encodings.string shuffle effects math.ranges io.encodings.ascii io.encodings.string shuffle effects math.ranges
math.order sorting system ; math.order sorting strings system ;
IN: alien.fortran IN: alien.fortran
! XXX this currently only supports the gfortran/f2c abi. SINGLETONS: f2c-abi gfortran-abi intel-unix-abi intel-windows-abi ;
! XXX we should also support ifort at some point for commercial BLASes
<< <<
: add-f2c-libraries ( -- ) : add-f2c-libraries ( -- )
@ -22,18 +21,55 @@ os netbsd? [ add-f2c-libraries ] when
: alien>nstring ( alien len encoding -- string ) : alien>nstring ( alien len encoding -- string )
[ memory>byte-array ] dip decode ; [ memory>byte-array ] dip decode ;
: fortran-name>symbol-name ( fortran-name -- c-name )
>lower CHAR: _ over member?
[ "__" append ] [ "_" append ] if ;
ERROR: invalid-fortran-type type ; ERROR: invalid-fortran-type type ;
DEFER: fortran-sig>c-sig DEFER: fortran-sig>c-sig
DEFER: fortran-ret-type>c-type DEFER: fortran-ret-type>c-type
DEFER: fortran-arg-type>c-type DEFER: fortran-arg-type>c-type
DEFER: fortran-name>symbol-name
SYMBOL: library-fortran-abis
SYMBOL: fortran-abi
library-fortran-abis [ H{ } clone ] initialize
<PRIVATE <PRIVATE
: lowercase-name-with-underscore ( name -- name' )
>lower "_" append ;
: lowercase-name-with-extra-underscore ( name -- name' )
>lower CHAR: _ over member?
[ "__" append ] [ "_" append ] if ;
HOOK: fortran-c-abi fortran-abi ( -- abi )
M: f2c-abi fortran-c-abi "cdecl" ;
M: gfortran-abi fortran-c-abi "cdecl" ;
M: intel-unix-abi fortran-c-abi "cdecl" ;
M: intel-windows-abi fortran-c-abi "cdecl" ;
HOOK: real-functions-return-double? fortran-abi ( -- ? )
M: f2c-abi real-functions-return-double? t ;
M: gfortran-abi real-functions-return-double? f ;
M: intel-unix-abi real-functions-return-double? f ;
M: intel-windows-abi real-functions-return-double? f ;
HOOK: complex-functions-return-by-value? fortran-abi ( -- ? )
M: f2c-abi complex-functions-return-by-value? f ;
M: gfortran-abi complex-functions-return-by-value? t ;
M: intel-unix-abi complex-functions-return-by-value? f ;
M: intel-windows-abi complex-functions-return-by-value? f ;
HOOK: character(1)-maps-to-char? fortran-abi ( -- ? )
M: f2c-abi character(1)-maps-to-char? f ;
M: gfortran-abi character(1)-maps-to-char? f ;
M: intel-unix-abi character(1)-maps-to-char? t ;
M: intel-windows-abi character(1)-maps-to-char? t ;
HOOK: mangle-name fortran-abi ( name -- name' )
M: f2c-abi mangle-name lowercase-name-with-extra-underscore ;
M: gfortran-abi mangle-name lowercase-name-with-underscore ;
M: intel-unix-abi mangle-name lowercase-name-with-underscore ;
M: intel-windows-abi mangle-name >upper ;
TUPLE: fortran-type dims size out? ; TUPLE: fortran-type dims size out? ;
TUPLE: number-type < fortran-type ; TUPLE: number-type < fortran-type ;
@ -107,10 +143,14 @@ M: double-complex-type (fortran-type>c-type)
M: misc-type (fortran-type>c-type) M: misc-type (fortran-type>c-type)
dup name>> simple-type ; dup name>> simple-type ;
: single-char? ( character-type -- ? )
{ [ drop character(1)-maps-to-char? ] [ dims>> product 1 = ] } 1&& ;
: fix-character-type ( character-type -- character-type' ) : fix-character-type ( character-type -- character-type' )
clone dup size>> clone dup size>>
[ dup dims>> [ invalid-fortran-type ] [ dup size>> 1array >>dims f >>size ] if ] [ dup dims>> [ invalid-fortran-type ] [ dup size>> 1array >>dims f >>size ] if ]
[ dup dims>> [ ] [ { 1 } >>dims ] if ] if ; [ dup dims>> [ ] [ f >>dims ] if ] if
dup single-char? [ f >>dims ] when ;
M: character-type (fortran-type>c-type) M: character-type (fortran-type>c-type)
fix-character-type "char" simple-type ; fix-character-type "char" simple-type ;
@ -142,22 +182,23 @@ M: character-type (fortran-type>c-type)
GENERIC: added-c-args ( type -- args ) GENERIC: added-c-args ( type -- args )
M: fortran-type added-c-args drop { } ; M: fortran-type added-c-args drop { } ;
M: character-type added-c-args drop { "long" } ; M: character-type added-c-args fix-character-type single-char? [ { } ] [ { "long" } ] if ;
GENERIC: returns-by-value? ( type -- ? ) GENERIC: returns-by-value? ( type -- ? )
M: f returns-by-value? drop t ; M: f returns-by-value? drop t ;
M: fortran-type returns-by-value? drop f ; M: fortran-type returns-by-value? drop f ;
M: number-type returns-by-value? dims>> not ; M: number-type returns-by-value? dims>> not ;
M: complex-type returns-by-value? drop f ; M: character-type returns-by-value? fix-character-type single-char? ;
M: complex-type returns-by-value?
{ [ drop complex-functions-return-by-value? ] [ dims>> not ] } 1&& ;
GENERIC: (fortran-ret-type>c-type) ( type -- c-type ) GENERIC: (fortran-ret-type>c-type) ( type -- c-type )
M: f (fortran-ret-type>c-type) drop "void" ; M: f (fortran-ret-type>c-type) drop "void" ;
M: fortran-type (fortran-ret-type>c-type) (fortran-type>c-type) ; M: fortran-type (fortran-ret-type>c-type) (fortran-type>c-type) ;
! XXX F2C claims to return double for REAL typed functions M: real-type (fortran-ret-type>c-type)
! XXX OSX Accelerate.framework uses float drop real-functions-return-double? [ "double" ] [ "float" ] if ;
! M: real-type (fortran-ret-type>c-type) drop "double" ;
: suffix! ( seq elt -- seq ) over push ; inline : suffix! ( seq elt -- seq ) over push ; inline
: append! ( seq-a seq-b -- seq-a ) over push-all ; inline : append! ( seq-a seq-b -- seq-a ) over push-all ; inline
@ -209,7 +250,9 @@ M: double-complex-type (fortran-arg>c-args)
[ drop [ <complex-double> ] [ drop ] ] args?dims ; [ drop [ <complex-double> ] [ drop ] ] args?dims ;
M: character-type (fortran-arg>c-args) M: character-type (fortran-arg>c-args)
drop [ ascii string>alien ] [ length ] ; fix-character-type single-char?
[ [ first <char> ] [ drop ] ]
[ [ ascii string>alien ] [ length ] ] if ;
M: misc-type (fortran-arg>c-args) M: misc-type (fortran-arg>c-args)
drop [ ] [ drop ] ; drop [ ] [ drop ] ;
@ -255,7 +298,9 @@ M: double-complex-type (fortran-result>)
[ drop { [ *complex-double ] } ] result?dims ; [ drop { [ *complex-double ] } ] result?dims ;
M: character-type (fortran-result>) M: character-type (fortran-result>)
drop { [ ] [ ascii alien>nstring ] } ; fix-character-type single-char?
[ { [ *char 1string ] } ]
[ { [ ] [ ascii alien>nstring ] } ] if ;
M: misc-type (fortran-result>) M: misc-type (fortran-result>)
drop { [ ] } ; drop { [ ] } ;
@ -331,8 +376,18 @@ M: character-type (<fortran-result>)
append append
\ spread [ ] 2sequence append ; \ spread [ ] 2sequence append ;
: (add-fortran-library) ( fortran-abi name -- )
library-fortran-abis get-global set-at ;
PRIVATE> PRIVATE>
: add-fortran-library ( name soname fortran-abi -- )
[ fortran-abi [ fortran-c-abi ] with-variable add-library ]
[ nip swap (add-fortran-library) ] 3bi ;
: fortran-name>symbol-name ( fortran-name -- c-name )
mangle-name ;
: fortran-type>c-type ( fortran-type -- c-type ) : fortran-type>c-type ( fortran-type -- c-type )
parse-fortran-type (fortran-type>c-type) ; parse-fortran-type (fortran-type>c-type) ;
@ -344,7 +399,7 @@ PRIVATE>
parse-fortran-type dup returns-by-value? parse-fortran-type dup returns-by-value?
[ (fortran-ret-type>c-type) { } ] [ [ (fortran-ret-type>c-type) { } ] [
"void" swap "void" swap
[ added-c-args ] [ (fortran-ret-type>c-type) c-type>pointer ] bi prefix [ added-c-args ] [ (fortran-type>c-type) c-type>pointer ] bi prefix
] if ; ] if ;
: fortran-arg-types>c-types ( fortran-types -- c-types ) : fortran-arg-types>c-types ( fortran-types -- c-types )
@ -388,4 +443,7 @@ MACRO: fortran-invoke ( return library function parameters -- )
[ "()" subseq? not ] filter define-fortran-function ; parsing [ "()" subseq? not ] filter define-fortran-function ; parsing
: LIBRARY: : LIBRARY:
scan "c-library" set ; parsing scan
[ "c-library" set ]
[ library-fortran-abis get-global at fortran-abi set ] bi ; parsing

View File

@ -1,3 +1,2 @@
fortran fortran
ffi ffi
unportable

View File

@ -29,7 +29,7 @@ SYMBOL: super-sent-messages
SYMBOL: frameworks SYMBOL: frameworks
frameworks global [ V{ } clone or ] change-at frameworks [ V{ } clone ] initialize
[ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook [ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook

View File

@ -19,8 +19,8 @@ IN: cocoa.messages
SYMBOL: message-senders SYMBOL: message-senders
SYMBOL: super-message-senders SYMBOL: super-message-senders
message-senders global [ H{ } assoc-like ] change-at message-senders [ H{ } clone ] initialize
super-message-senders global [ H{ } assoc-like ] change-at super-message-senders [ H{ } clone ] initialize
: cache-stub ( method function hash -- ) : cache-stub ( method function hash -- )
[ [
@ -53,7 +53,7 @@ MEMO: <selector> ( name -- sel ) f \ selector boa ;
SYMBOL: objc-methods SYMBOL: objc-methods
objc-methods global [ H{ } assoc-like ] change-at objc-methods [ H{ } clone ] initialize
: lookup-method ( selector -- method ) : lookup-method ( selector -- method )
dup objc-methods get at dup objc-methods get at
@ -79,7 +79,7 @@ MACRO: (send) ( selector super? -- quot )
! Runtime introspection ! Runtime introspection
SYMBOL: class-init-hooks SYMBOL: class-init-hooks
class-init-hooks global [ H{ } clone or ] change-at class-init-hooks [ H{ } clone or ] initialize
: (objc-class) ( name word -- class ) : (objc-class) ( name word -- class )
2dup execute dup [ 2nip ] [ 2dup execute dup [ 2nip ] [

View File

@ -24,4 +24,4 @@ IN: compiler.utilities
SYMBOL: yield-hook SYMBOL: yield-hook
yield-hook global [ [ ] or ] change-at yield-hook [ [ ] ] initialize

View File

@ -85,4 +85,4 @@ PRIVATE>
: get-process ( name -- process ) : get-process ( name -- process )
dup registered-processes at [ ] [ thread ] ?if ; dup registered-processes at [ ] [ thread ] ?if ;
\ registered-processes global [ H{ } assoc-like ] change-at \ registered-processes [ H{ } clone ] initialize

View File

@ -122,7 +122,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
SYMBOL: help-hook SYMBOL: help-hook
help-hook global [ [ print-topic ] or ] change-at help-hook [ [ print-topic ] ] initialize
: help ( topic -- ) : help ( topic -- )
help-hook get call( topic -- ) ; help-hook get call( topic -- ) ;

View File

@ -28,11 +28,11 @@ M: link summary
! Help articles ! Help articles
SYMBOL: articles SYMBOL: articles
articles global [ H{ } assoc-like ] change-at articles [ H{ } clone ] initialize
SYMBOL: article-xref SYMBOL: article-xref
article-xref global [ H{ } assoc-like ] change-at article-xref [ H{ } clone ] initialize
GENERIC: article-name ( topic -- string ) GENERIC: article-name ( topic -- string )
GENERIC: article-title ( topic -- string ) GENERIC: article-title ( topic -- string )

View File

@ -11,7 +11,7 @@ html.templates ;
SYMBOL: tags SYMBOL: tags
tags global [ H{ } clone or ] change-at tags [ H{ } clone ] initialize
: define-chloe-tag ( name quot -- ) swap tags get set-at ; : define-chloe-tag ( name quot -- ) swap tags get set-at ;

View File

@ -161,7 +161,7 @@ C: <trivial-responder> trivial-responder
M: trivial-responder call-responder* nip response>> clone ; M: trivial-responder call-responder* nip response>> clone ;
main-responder global [ <404> <trivial-responder> or ] change-at main-responder [ <404> <trivial-responder> ] initialize
: invert-slice ( slice -- slice' ) : invert-slice ( slice -- slice' )
dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ; dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ;

View File

@ -47,8 +47,8 @@ PRIVATE>
"resource:basis/io/encodings/iana/character-sets" "resource:basis/io/encodings/iana/character-sets"
utf8 <file-reader> make-aliases aliases set-global utf8 <file-reader> make-aliases aliases set-global
n>e-table global [ initial-n>e or ] change-at n>e-table [ initial-n>e ] initialize
e>n-table global [ initial-e>n or ] change-at e>n-table [ initial-e>n ] initialize
: register-encoding ( descriptor name -- ) : register-encoding ( descriptor name -- )
[ [

View File

@ -3,9 +3,11 @@ IN: math.blas.ffi
<< <<
"blas" { "blas" {
{ [ os macosx? ] [ "libblas.dylib" "cdecl" add-library ] } { [ os macosx? ] [ "libblas.dylib" intel-unix-abi add-fortran-library ] }
{ [ os windows? ] [ "blas.dll" "cdecl" add-library ] } { [ os windows? cpu x86.32? and ] [ "blas.dll" f2c-abi add-fortran-library ] }
[ "libblas.so" "cdecl" add-library ] { [ os windows? cpu x86.64? and ] [ "blas.dll" gfortran-abi add-fortran-library ] }
{ [ os freebsd? ] [ "libblas.so" gfortran-abi add-fortran-library ] }
[ "libblas.so" f2c-abi add-fortran-library ]
} cond } cond
>> >>

View File

@ -1,4 +1,3 @@
math math
bindings bindings
fortran fortran
unportable

View File

@ -1,3 +1,2 @@
math math
bindings bindings
unportable

View File

@ -1,3 +1,2 @@
math math
bindings bindings
unportable

View File

@ -87,7 +87,7 @@ M: word annotate-methods
SYMBOL: word-timing SYMBOL: word-timing
word-timing global [ H{ } clone or ] change-at word-timing [ H{ } clone ] initialize
: reset-word-timing ( -- ) : reset-word-timing ( -- )
word-timing get clear-assoc ; word-timing get clear-assoc ;

View File

@ -142,9 +142,9 @@ CLASS: {
SYMBOL: cocoa-init-hook SYMBOL: cocoa-init-hook
cocoa-init-hook global [ cocoa-init-hook [
[ "MiniFactor.nib" load-nib install-app-delegate ] or [ "MiniFactor.nib" load-nib install-app-delegate ]
] change-at ] initialize
M: cocoa-ui-backend (with-ui) M: cocoa-ui-backend (with-ui)
"UI" assert.app [ "UI" assert.app [

View File

@ -79,7 +79,7 @@ SYMBOL: ui-error-hook
: ui-error ( error -- ) : ui-error ( error -- )
ui-error-hook get [ call( error -- ) ] [ die drop ] if* ; ui-error-hook get [ call( error -- ) ] [ die drop ] if* ;
ui-error-hook global [ [ rethrow ] or ] change-at ui-error-hook [ [ rethrow ] ] initialize
: draw-world ( world -- ) : draw-world ( world -- )
dup draw-world? [ dup draw-world? [

View File

@ -27,7 +27,7 @@ word wrap.">
" " wrap-indented-string " " wrap-indented-string
] unit-test ] unit-test
[ "this text\nhas lots\nof spaces" ] [ "this text\nhas lots of\nspaces" ]
[ "this text has lots of spaces" 12 wrap-string ] unit-test [ "this text has lots of spaces" 12 wrap-string ] unit-test
[ "hello\nhow\nare\nyou\ntoday?" ] [ "hello\nhow\nare\nyou\ntoday?" ]
@ -39,3 +39,5 @@ word wrap.">
[ "aaa bb\nccccccc\nddddddd" ] [ "aaa bb ccccccc ddddddd" 6 wrap-string ] unit-test [ "aaa bb\nccccccc\nddddddd" ] [ "aaa bb ccccccc ddddddd" 6 wrap-string ] unit-test
\ wrap-string must-infer \ wrap-string must-infer
[ "a b c d e f\ng h" ] [ "a b c d e f g h" 11 wrap-string ] unit-test

View File

@ -36,8 +36,10 @@ SYMBOL: line-ideal
] each drop ; inline ] each drop ; inline
: paragraph-cost ( paragraph -- cost ) : paragraph-cost ( paragraph -- cost )
dup lines>> 1list? [ drop 0 ] [
[ head-width>> deviation ] [ head-width>> deviation ]
[ tail-cost>> ] bi + ; [ tail-cost>> ] bi +
] if ;
: min-cost ( paragraphs -- paragraph ) : min-cost ( paragraphs -- paragraph )
[ paragraph-cost ] min-by ; [ paragraph-cost ] min-by ;

View File

@ -51,7 +51,7 @@ M: alien equal?
SYMBOL: libraries SYMBOL: libraries
libraries global [ H{ } assoc-like ] change-at libraries [ H{ } clone ] initialize
TUPLE: library path abi dll ; TUPLE: library path abi dll ;

View File

@ -178,6 +178,4 @@ SYMBOL: remake-generics-hook
: default-recompile-hook ( words -- alist ) : default-recompile-hook ( words -- alist )
[ f ] { } map>assoc ; [ f ] { } map>assoc ;
recompile-hook global recompile-hook [ [ default-recompile-hook ] ] initialize
[ [ default-recompile-hook ] or ]
change-at

View File

@ -8,7 +8,7 @@ SYMBOL: io-backend
SINGLETON: c-io-backend SINGLETON: c-io-backend
io-backend global [ c-io-backend or ] change-at io-backend [ c-io-backend ] initialize
HOOK: init-io io-backend ( -- ) HOOK: init-io io-backend ( -- )

View File

@ -1,6 +1,6 @@
USING: help.markup help.syntax kernel kernel.private USING: help.markup help.syntax kernel kernel.private
sequences words namespaces.private quotations vectors sequences words namespaces.private quotations vectors
math.parser math ; math.parser math words.symbol ;
IN: namespaces IN: namespaces
ARTICLE: "namespaces-combinators" "Namespace combinators" ARTICLE: "namespaces-combinators" "Namespace combinators"
@ -20,7 +20,8 @@ ARTICLE: "namespaces-global" "Global variables"
{ $subsection namespace } { $subsection namespace }
{ $subsection global } { $subsection global }
{ $subsection get-global } { $subsection get-global }
{ $subsection set-global } ; { $subsection set-global }
{ $subsection initialize } ;
ARTICLE: "namespaces.private" "Namespace implementation details" ARTICLE: "namespaces.private" "Namespace implementation details"
"The namestack holds namespaces." "The namestack holds namespaces."
@ -159,3 +160,7 @@ HELP: ndrop
HELP: init-namespaces HELP: init-namespaces
{ $description "Resets the name stack to its initial state, holding a single copy of the global namespace." } { $description "Resets the name stack to its initial state, holding a single copy of the global namespace." }
$low-level-note ; $low-level-note ;
HELP: initialize
{ $values { "variable" symbol } { "quot" quotation } }
{ $description "If " { $snippet "variable" } " does not have a value in the global namespace, calls " { $snippet "quot" } " and assigns the result to " { $snippet "variable" } " in the global namespace." } ;

View File

@ -12,3 +12,14 @@ H{ } clone "test-namespace" set
[ f ] [ f ]
[ H{ } clone [ f "some-global" set "some-global" get ] bind ] [ H{ } clone [ f "some-global" set "some-global" get ] bind ]
unit-test unit-test
SYMBOL: test-initialize
test-initialize [ 1 ] initialize
test-initialize [ 2 ] initialize
[ 1 ] [ test-initialize get-global ] unit-test
f test-initialize set-global
test-initialize [ 5 ] initialize
[ 5 ] [ test-initialize get-global ] unit-test

View File

@ -38,3 +38,6 @@ PRIVATE>
: with-variable ( value key quot -- ) : with-variable ( value key quot -- )
[ associate >n ] dip call ndrop ; inline [ associate >n ] dip call ndrop ; inline
: initialize ( variable quot -- )
[ global ] [ [ unless* ] curry ] bi* change-at ;

View File

@ -203,7 +203,7 @@ SYMBOL: interactive-vocabs
SYMBOL: print-use-hook SYMBOL: print-use-hook
print-use-hook global [ [ ] or ] change-at print-use-hook [ [ ] ] initialize
: parse-fresh ( lines -- quot ) : parse-fresh ( lines -- quot )
[ [

View File

@ -22,9 +22,9 @@ ERROR: bad-escape ;
SYMBOL: name>char-hook SYMBOL: name>char-hook
name>char-hook global [ name>char-hook [
[ "Unicode support not available" throw ] or [ "Unicode support not available" throw ]
] change-at ] initialize
: unicode-escape ( str -- ch str' ) : unicode-escape ( str -- ch str' )
"{" ?head-slice [ "{" ?head-slice [

View File

@ -96,11 +96,11 @@ M: word uses ( word -- seq )
SYMBOL: compiled-crossref SYMBOL: compiled-crossref
compiled-crossref global [ H{ } assoc-like ] change-at compiled-crossref [ H{ } clone ] initialize
SYMBOL: compiled-generic-crossref SYMBOL: compiled-generic-crossref
compiled-generic-crossref global [ H{ } assoc-like ] change-at compiled-generic-crossref [ H{ } clone ] initialize
: (compiled-xref) ( word dependencies word-prop variable -- ) : (compiled-xref) ( word dependencies word-prop variable -- )
[ [ set-word-prop ] curry ] [ [ set-word-prop ] curry ]

View File

@ -3,15 +3,15 @@
USING: help.markup help.syntax sequences kernel ; USING: help.markup help.syntax sequences kernel ;
IN: id3 IN: id3
HELP: id3-parse-mp3-file HELP: file-id3-tags
{ $values { $values
{ "path" "a path string" } { "path" "a path string" }
{ "object/f" "either a tuple consisting of the data from an MP3 file, or an f indicating this file has no (supported) ID3 information." } } { "object/f" "a tuple storing ID3 metadata or f" } }
{ $description "Return a tuple containing the ID3 information parsed out of the MP3 file" } ; { $description "Return a tuple containing the ID3 information parsed out of the MP3 file, or " { $link f } " if no metadata is present." } ;
ARTICLE: "id3" "ID3 tags" ARTICLE: "id3" "ID3 tags"
{ $emphasis "ID3" } " tags are textual data that is used to describe the information (title, artist, etc.) in an .MP3 file" "The " { $vocab-link "id3" } " vocabulary contains words for parsing " { $emphasis "ID3" } " tags, which are textual fields storing an MP3's title, artist, and other metadata." $nl
"Parsing an MP3 file: " "Parsing ID3 tags from an MP3 file:"
{ $subsection id3-parse-mp3-file } ; { $subsection file-id3-tags } ;
ABOUT: "id3" ABOUT: "id3"

View File

@ -58,7 +58,7 @@ IN: id3.tests
} }
} }
} }
] [ "resource:extra/id3/tests/blah3.mp3" id3-parse-mp3-file ] unit-test ] [ "resource:extra/id3/tests/blah3.mp3" file-id3-tags ] unit-test
[ [
T{ mp3v2-file T{ mp3v2-file
@ -159,7 +159,7 @@ IN: id3.tests
} }
} }
} }
] [ "resource:extra/id3/tests/blah2.mp3" id3-parse-mp3-file ] unit-test ] [ "resource:extra/id3/tests/blah2.mp3" file-id3-tags ] unit-test
[ [
T{ mp3v1-file T{ mp3v1-file
@ -178,5 +178,5 @@ IN: id3.tests
} }
{ genre 89 } { genre 89 }
} }
] [ "resource:extra/id3/tests/blah.mp3" id3-parse-mp3-file ] unit-test ] [ "resource:extra/id3/tests/blah.mp3" file-id3-tags ] unit-test

View File

@ -142,7 +142,7 @@ PRIVATE>
! main stuff ! main stuff
: id3-parse-mp3-file ( path -- object ) : file-id3-tags ( path -- object/f )
[ [
{ {
{ [ dup id3v2? ] [ read-v2-tag-data ] } ! ( ? -- mp3v2-file ) { [ dup id3v2? ] [ read-v2-tag-data ] } ! ( ? -- mp3v2-file )

View File

@ -81,7 +81,7 @@ SYMBOL: upload-directory
! Optional: override ssh and scp command names ! Optional: override ssh and scp command names
SYMBOL: scp-command SYMBOL: scp-command
scp-command global [ "scp" or ] change-at scp-command [ "scp" ] initialize
SYMBOL: ssh-command SYMBOL: ssh-command
ssh-command global [ "ssh" or ] change-at ssh-command [ "ssh" ] initialize