]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' into new_ui
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 10 Feb 2009 22:23:14 +0000 (16:23 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 10 Feb 2009 22:23:14 +0000 (16:23 -0600)
35 files changed:
basis/alien/fortran/fortran-docs.factor
basis/alien/fortran/fortran-tests.factor
basis/alien/fortran/fortran.factor
basis/alien/fortran/tags.txt
basis/cocoa/cocoa.factor
basis/cocoa/messages/messages.factor
basis/compiler/utilities/utilities.factor
basis/concurrency/messaging/messaging.factor
basis/help/help.factor
basis/help/topics/topics.factor
basis/html/templates/chloe/syntax/syntax.factor
basis/http/server/server.factor
basis/io/encodings/iana/iana.factor
basis/math/blas/ffi/ffi.factor
basis/math/blas/ffi/tags.txt
basis/math/blas/matrices/tags.txt
basis/math/blas/vectors/tags.txt
basis/tools/annotations/annotations.factor
basis/ui/backend/cocoa/cocoa.factor
basis/ui/gadgets/worlds/worlds.factor
basis/wrap/strings/strings-tests.factor
basis/wrap/wrap.factor
core/alien/alien.factor
core/compiler/units/units.factor
core/io/backend/backend.factor
core/namespaces/namespaces-docs.factor
core/namespaces/namespaces-tests.factor
core/namespaces/namespaces.factor
core/parser/parser.factor
core/strings/parser/parser.factor
core/words/words.factor
extra/id3/id3-docs.factor
extra/id3/id3-tests.factor
extra/id3/id3.factor
extra/mason/config/config.factor

index 4accbf5965689567071f4429d3b44d449a10603f..c5d124e198a744be4eb80b68eae43ae2812f0eba 100644 (file)
@@ -1,9 +1,19 @@
 ! Copyright (C) 2009 Joe Groff
 ! 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
 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"
 "The Fortran FFI recognizes the following Fortran types:"
 { $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 "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 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." ;
 
@@ -30,15 +40,20 @@ HELP: SUBROUTINE:
 HELP: LIBRARY:
 { $syntax "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:
 { $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
 { $values
-     { "return" string } { "library" string } { "procedure" string } { "parameters" sequence }
+    { "return" string } { "library" string } { "procedure" string } { "parameters" sequence }
 }
 { $description "Invokes the Fortran subroutine or function " { $snippet "procedure" } " in " { $snippet "library" } " with parameters specified by the " { $link "alien.fortran-types" } " specified in the " { $snippet "parameters" } " sequence. If the " { $snippet "return" } " value is " { $link f } ", no return value is expected, otherwise a return value of the specified Fortran type is expected. Input values are taken off the top of the datastack, and output values are left for the return value (if any) and any parameters specified as out parameters by prepending " { $snippet "\"!\"" } "." }
 ;
@@ -46,6 +61,8 @@ HELP: fortran-invoke
 ARTICLE: "alien.fortran" "Fortran FFI"
 "The " { $vocab-link "alien.fortran" } " vocabulary provides an interface to code in shared libraries written in Fortran."
 { $subsection "alien.fortran-types" }
+{ $subsection "alien.fortran-abis" }
+{ $subsection add-fortran-library }
 { $subsection POSTPONE: LIBRARY: }
 { $subsection POSTPONE: FUNCTION: }
 { $subsection POSTPONE: SUBROUTINE: }
index 1b2ffda4a9455f3a4a3be294d329206bdaf74ee5..177d1077c2a90b119d4ef987056a5e58a3ccd31f 100644 (file)
 ! (c) 2009 Joe Groff, see BSD license
 USING: accessors alien alien.c-types alien.complex
-alien.fortran alien.strings alien.structs alien.syntax arrays
-assocs byte-arrays combinators fry generalizations
-io.encodings.ascii kernel macros macros.expander namespaces
-sequences shuffle tools.test ;
+alien.fortran alien.fortran.private alien.strings alien.structs
+arrays assocs byte-arrays combinators fry
+generalizations io.encodings.ascii kernel macros
+macros.expander namespaces sequences shuffle tools.test ;
 IN: alien.fortran.tests
 
+<< intel-unix-abi "(alien.fortran-tests)" (add-fortran-library) >>
+LIBRARY: (alien.fortran-tests)
 RECORD: FORTRAN_TEST_RECORD
     { "INTEGER"     "FOO" }
     { "REAL(2)"     "BAR" }
     { "CHARACTER*4" "BAS" } ;
 
-! fortran-name>symbol-name
+intel-unix-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
+    ! fortran-name>symbol-name
 
-! fortran-type>c-type
+    [ "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
 
-[ "short" ]
-[ "integer*2" fortran-type>c-type ] unit-test
+    ! fortran-type>c-type
 
-[ "int" ]
-[ "integer*4" fortran-type>c-type ] unit-test
+    [ "short" ]
+    [ "integer*2" fortran-type>c-type ] unit-test
 
-[ "int" ]
-[ "INTEGER" fortran-type>c-type ] unit-test
+    [ "int" ]
+    [ "integer*4" fortran-type>c-type ] unit-test
 
-[ "longlong" ]
-[ "iNteger*8" fortran-type>c-type ] unit-test
+    [ "int" ]
+    [ "INTEGER" fortran-type>c-type ] unit-test
 
-[ "int[0]" ]
-[ "integer(*)" fortran-type>c-type ] unit-test
+    [ "longlong" ]
+    [ "iNteger*8" fortran-type>c-type ] unit-test
 
-[ "int[0]" ]
-[ "integer(3,*)" fortran-type>c-type ] unit-test
+    [ "int[0]" ]
+    [ "integer(*)" fortran-type>c-type ] unit-test
 
-[ "int[3]" ]
-[ "integer(3)" fortran-type>c-type ] unit-test
+    [ "int[0]" ]
+    [ "integer(3,*)" fortran-type>c-type ] unit-test
 
-[ "int[6]" ]
-[ "integer(3,2)" fortran-type>c-type ] unit-test
+    [ "int[3]" ]
+    [ "integer(3)" fortran-type>c-type ] unit-test
 
-[ "int[24]" ]
-[ "integer(4,3,2)" fortran-type>c-type ] unit-test
+    [ "int[6]" ]
+    [ "integer(3,2)" fortran-type>c-type ] unit-test
 
-[ "char[1]" ]
-[ "character" fortran-type>c-type ] unit-test
+    [ "int[24]" ]
+    [ "integer(4,3,2)" fortran-type>c-type ] unit-test
 
-[ "char[17]" ]
-[ "character*17" fortran-type>c-type ] unit-test
+    [ "char" ]
+    [ "character" fortran-type>c-type ] unit-test
 
-[ "char[17]" ]
-[ "character(17)" fortran-type>c-type ] unit-test
+    [ "char" ]
+    [ "character*1" fortran-type>c-type ] unit-test
 
-[ "int" ]
-[ "logical" fortran-type>c-type ] unit-test
+    [ "char[17]" ]
+    [ "character*17" fortran-type>c-type ] unit-test
 
-[ "float" ]
-[ "real" fortran-type>c-type ] unit-test
+    [ "char[17]" ]
+    [ "character(17)" fortran-type>c-type ] unit-test
 
-[ "double" ]
-[ "double-precision" fortran-type>c-type ] unit-test
+    [ "int" ]
+    [ "logical" fortran-type>c-type ] unit-test
 
-[ "float" ]
-[ "real*4" fortran-type>c-type ] unit-test
+    [ "float" ]
+    [ "real" fortran-type>c-type ] unit-test
 
-[ "double" ]
-[ "real*8" fortran-type>c-type ] unit-test
+    [ "double" ]
+    [ "double-precision" fortran-type>c-type ] unit-test
 
-[ "complex-float" ]
-[ "complex" fortran-type>c-type ] unit-test
+    [ "float" ]
+    [ "real*4" fortran-type>c-type ] unit-test
 
-[ "complex-double" ]
-[ "double-complex" fortran-type>c-type ] unit-test
+    [ "double" ]
+    [ "real*8" fortran-type>c-type ] unit-test
 
-[ "complex-float" ]
-[ "complex*8" fortran-type>c-type ] unit-test
+    [ "complex-float" ]
+    [ "complex" fortran-type>c-type ] unit-test
 
-[ "complex-double" ]
-[ "complex*16" fortran-type>c-type ] unit-test
+    [ "complex-double" ]
+    [ "double-complex" fortran-type>c-type ] unit-test
 
-[ "fortran_test_record" ]
-[ "fortran_test_record" fortran-type>c-type ] unit-test
+    [ "complex-float" ]
+    [ "complex*8" fortran-type>c-type ] unit-test
 
-! fortran-arg-type>c-type
+    [ "complex-double" ]
+    [ "complex*16" fortran-type>c-type ] unit-test
 
-[ "int*" { } ]
-[ "integer" fortran-arg-type>c-type ] unit-test
+    [ "fortran_test_record" ]
+    [ "fortran_test_record" fortran-type>c-type ] unit-test
 
-[ "int*" { } ]
-[ "integer(3)" fortran-arg-type>c-type ] unit-test
+    ! fortran-arg-type>c-type
 
-[ "int*" { } ]
-[ "integer(*)" fortran-arg-type>c-type ] unit-test
+    [ "int*" { } ]
+    [ "integer" fortran-arg-type>c-type ] unit-test
 
-[ "fortran_test_record*" { } ]
-[ "fortran_test_record" fortran-arg-type>c-type ] unit-test
+    [ "int*" { } ]
+    [ "integer(3)" fortran-arg-type>c-type ] unit-test
 
-[ "char*" { "long" } ]
-[ "character" fortran-arg-type>c-type ] unit-test
+    [ "int*" { } ]
+    [ "integer(*)" fortran-arg-type>c-type ] unit-test
 
-[ "char*" { "long" } ]
-[ "character(17)" fortran-arg-type>c-type ] unit-test
+    [ "fortran_test_record*" { } ]
+    [ "fortran_test_record" fortran-arg-type>c-type ] unit-test
 
-! fortran-ret-type>c-type
+    [ "char*" { } ]
+    [ "character" fortran-arg-type>c-type ] unit-test
 
-[ "void" { "char*" "long" } ]
-[ "character(17)" fortran-ret-type>c-type ] unit-test
+    [ "char*" { } ]
+    [ "character(1)" fortran-arg-type>c-type ] unit-test
 
-[ "int" { } ]
-[ "integer" fortran-ret-type>c-type ] unit-test
+    [ "char*" { "long" } ]
+    [ "character(17)" fortran-arg-type>c-type ] unit-test
 
-[ "int" { } ]
-[ "logical" fortran-ret-type>c-type ] unit-test
+    ! fortran-ret-type>c-type
 
-[ "float" { } ]
-[ "real" fortran-ret-type>c-type ] unit-test
+    [ "char" { } ]
+    [ "character(1)" fortran-ret-type>c-type ] unit-test
 
-[ "double" { } ]
-[ "double-precision" fortran-ret-type>c-type ] unit-test
-
-[ "void" { "complex-float*" } ]
-[ "complex" fortran-ret-type>c-type ] unit-test
-
-[ "void" { "complex-double*" } ]
-[ "double-complex" fortran-ret-type>c-type ] unit-test
-
-[ "void" { "int*" } ]
-[ "integer(*)" fortran-ret-type>c-type ] unit-test
-
-[ "void" { "fortran_test_record*" } ]
-[ "fortran_test_record" fortran-ret-type>c-type ] unit-test
-
-! fortran-sig>c-sig
-
-[ "float" { "int*" "char*" "float*" "double*" "long" } ]
-[ "real" { "integer" "character*17" "real" "real*8" } fortran-sig>c-sig ]
-unit-test
-
-[ "void" { "char*" "long" "char*" "char*" "int*" "long" "long" } ]
-[ "character*18" { "character*17" "character" "integer" } fortran-sig>c-sig ]
-unit-test
-
-[ "void" { "complex-float*" "char*" "char*" "int*" "long" "long" } ]
-[ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ]
-unit-test
-
-! fortran-record>c-struct
-
-[ {
-    { "double"   "ex"  }
-    { "float"    "wye" }
-    { "int"      "zee" }
-    { "char[20]" "woo" }
-} ] [
-    {
-        { "DOUBLE-PRECISION" "EX"  }
-        { "REAL"             "WYE" }
-        { "INTEGER"          "ZEE" }
-        { "CHARACTER(20)"    "WOO" }
-    } fortran-record>c-struct
-] unit-test
-
-! RECORD:
-
-[ 16 ] [ "fortran_test_record" heap-size ] unit-test
-[  0 ] [ "foo" "fortran_test_record" offset-of ] unit-test
-[  4 ] [ "bar" "fortran_test_record" offset-of ] unit-test
-[ 12 ] [ "bas" "fortran_test_record" offset-of ] unit-test
-
-! (fortran-invoke)
-
-[ [
-    ! [fortran-args>c-args]
-    {
-        [ {
-            [ ascii string>alien ]
-            [ <longlong> ]
-            [ <float> ]
-            [ <complex-float> ]
-            [ 1 0 ? <short> ]
-        } spread ]
-        [ { [ length ] [ drop ] [ drop ] [ drop ] [ drop ] } spread ]
-    } 5 ncleave
-    ! [fortran-invoke]
-    [ 
-        "void" "funpack" "funtimes_"
-        { "char*" "longlong*" "float*" "complex-float*" "short*" "long" }
-        alien-invoke
-    ] 6 nkeep
-    ! [fortran-results>]
-    shuffle( aa ba ca da ea ab -- aa ab ba ca da ea ) 
-    {
-        [ drop ]
-        [ drop ]
-        [ drop ]
-        [ *float ]
-        [ drop ]
-        [ drop ]
-    } spread
-] ] [
-    f "funpack" "FUNTIMES" { "CHARACTER*12" "INTEGER*8" "!REAL" "COMPLEX" "LOGICAL*2" }
-    (fortran-invoke)
-] unit-test
-
-[ [
-    ! [fortran-args>c-args]
-    {
-        [ { [ ] } spread ]
-        [ { [ drop ] } spread ]
-    } 1 ncleave
-    ! [fortran-invoke]
-    [ "float" "funpack" "fun_times__" { "float*" } alien-invoke ]
-    1 nkeep
-    ! [fortran-results>]
-    shuffle( reta aa -- reta aa ) 
-    { [ ] [ drop ] } spread
-] ] [
-    "REAL" "funpack" "FUN_TIMES" { "REAL(*)" }
-    (fortran-invoke)
-] unit-test
-
-[ [
-    ! [<fortran-result>]
-    [ "complex-float" <c-object> ] 1 ndip
-    ! [fortran-args>c-args]
-    { [ { [ ] } spread ] [ { [ drop ] } spread ] } 1 ncleave
-    ! [fortran-invoke]
-    [
-        "void" "funpack" "fun_times__"
-        { "complex-float*" "float*" } 
-        alien-invoke
-    ] 2 nkeep
-    ! [fortran-results>]
-    shuffle( reta aa -- reta aa )
-    { [ *complex-float ] [ drop ] } spread
-] ] [
-    "COMPLEX" "funpack" "FUN_TIMES" { "REAL(*)" }
-    (fortran-invoke)
-] unit-test
-
-[ [
-    ! [<fortran-result>]
-    [ 20 <byte-array> 20 ] 0 ndip
-    ! [fortran-invoke]
-    [
-        "void" "funpack" "fun_times__"
-        { "char*" "long" } 
-        alien-invoke
-    ] 2 nkeep
-    ! [fortran-results>]
-    shuffle( reta retb -- reta retb ) 
-    { [ ] [ ascii alien>nstring ] } spread
-] ] [
-    "CHARACTER*20" "funpack" "FUN_TIMES" { }
-    (fortran-invoke)
-] unit-test
-
-[ [
-    ! [<fortran-result>]
-    [ 10 <byte-array> 10 ] 3 ndip
-    ! [fortran-args>c-args]
-    {
-        [ {
-            [ ascii string>alien ]
-            [ <float> ]
-            [ ascii string>alien ]
-        } spread ]
-        [ { [ length ] [ drop ] [ length ] } spread ]
-    } 3 ncleave
-    ! [fortran-invoke]
-    [
-        "void" "funpack" "fun_times__"
-        { "char*" "long" "char*" "float*" "char*" "long" "long" } 
-        alien-invoke
-    ] 7 nkeep
-    ! [fortran-results>]
-    shuffle( reta retb aa ba ca ab cb -- reta retb aa ab ba ca cb ) 
-    {
-        [ ]
-        [ ascii alien>nstring ]
-        [ ]
-        [ ascii alien>nstring ]
-        [ *float ]
-        [ ]
-        [ ascii alien>nstring ]
-    } spread
-] ] [
-    "CHARACTER*10" "funpack" "FUN_TIMES" { "!CHARACTER*20" "!REAL" "!CHARACTER*30" }
-    (fortran-invoke)
-] unit-test
+    [ "void" { "char*" "long" } ]
+    [ "character(17)" fortran-ret-type>c-type ] unit-test
 
+    [ "int" { } ]
+    [ "integer" fortran-ret-type>c-type ] unit-test
+
+    [ "int" { } ]
+    [ "logical" fortran-ret-type>c-type ] unit-test
+
+    [ "float" { } ]
+    [ "real" fortran-ret-type>c-type ] unit-test
+
+    [ "void" { "float*" } ]
+    [ "real(*)" fortran-ret-type>c-type ] unit-test
+
+    [ "double" { } ]
+    [ "double-precision" fortran-ret-type>c-type ] unit-test
+
+    [ "void" { "complex-float*" } ]
+    [ "complex" fortran-ret-type>c-type ] unit-test
+
+    [ "void" { "complex-double*" } ]
+    [ "double-complex" fortran-ret-type>c-type ] unit-test
+
+    [ "void" { "int*" } ]
+    [ "integer(*)" fortran-ret-type>c-type ] unit-test
+
+    [ "void" { "fortran_test_record*" } ]
+    [ "fortran_test_record" fortran-ret-type>c-type ] unit-test
+
+    ! fortran-sig>c-sig
+
+    [ "float" { "int*" "char*" "float*" "double*" "long" } ]
+    [ "real" { "integer" "character*17" "real" "real*8" } fortran-sig>c-sig ]
+    unit-test
+
+    [ "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 ]
+    unit-test
+
+    [ "void" { "complex-float*" "char*" "char*" "int*" "long" } ]
+    [ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ]
+    unit-test
+
+    ! fortran-record>c-struct
+
+    [ {
+        { "double"   "ex"  }
+        { "float"    "wye" }
+        { "int"      "zee" }
+        { "char[20]" "woo" }
+    } ] [
+        {
+            { "DOUBLE-PRECISION" "EX"  }
+            { "REAL"             "WYE" }
+            { "INTEGER"          "ZEE" }
+            { "CHARACTER(20)"    "WOO" }
+        } fortran-record>c-struct
+    ] unit-test
+
+    ! RECORD:
+
+    [ 16 ] [ "fortran_test_record" heap-size ] unit-test
+    [  0 ] [ "foo" "fortran_test_record" offset-of ] unit-test
+    [  4 ] [ "bar" "fortran_test_record" offset-of ] unit-test
+    [ 12 ] [ "bas" "fortran_test_record" offset-of ] unit-test
+
+    ! (fortran-invoke)
+
+    [ [
+        ! [fortran-args>c-args]
+        {
+            [ {
+                [ ascii string>alien ]
+                [ <longlong> ]
+                [ <float> ]
+                [ <complex-float> ]
+                [ 1 0 ? <short> ]
+            } spread ]
+            [ { [ length ] [ drop ] [ drop ] [ drop ] [ drop ] } spread ]
+        } 5 ncleave
+        ! [fortran-invoke]
+        [ 
+            "void" "funpack" "funtimes_"
+            { "char*" "longlong*" "float*" "complex-float*" "short*" "long" }
+            alien-invoke
+        ] 6 nkeep
+        ! [fortran-results>]
+        shuffle( aa ba ca da ea ab -- aa ab ba ca da ea ) 
+        {
+            [ drop ]
+            [ drop ]
+            [ drop ]
+            [ *float ]
+            [ drop ]
+            [ drop ]
+        } spread
+    ] ] [
+        f "funpack" "FUNTIMES" { "CHARACTER*12" "INTEGER*8" "!REAL" "COMPLEX" "LOGICAL*2" }
+        (fortran-invoke)
+    ] unit-test
+
+    [ [
+        ! [fortran-args>c-args]
+        {
+            [ { [ ] } spread ]
+            [ { [ drop ] } spread ]
+        } 1 ncleave
+        ! [fortran-invoke]
+        [ "float" "funpack" "fun_times_" { "float*" } alien-invoke ]
+        1 nkeep
+        ! [fortran-results>]
+        shuffle( reta aa -- reta aa ) 
+        { [ ] [ drop ] } spread
+    ] ] [
+        "REAL" "funpack" "FUN_TIMES" { "REAL(*)" }
+        (fortran-invoke)
+    ] unit-test
+
+    [ [
+        ! [<fortran-result>]
+        [ "complex-float" <c-object> ] 1 ndip
+        ! [fortran-args>c-args]
+        { [ { [ ] } spread ] [ { [ drop ] } spread ] } 1 ncleave
+        ! [fortran-invoke]
+        [
+            "void" "funpack" "fun_times_"
+            { "complex-float*" "float*" } 
+            alien-invoke
+        ] 2 nkeep
+        ! [fortran-results>]
+        shuffle( reta aa -- reta aa )
+        { [ *complex-float ] [ drop ] } spread
+    ] ] [
+        "COMPLEX" "funpack" "FUN_TIMES" { "REAL(*)" }
+        (fortran-invoke)
+    ] unit-test
+
+    [ [
+        ! [<fortran-result>]
+        [ 20 <byte-array> 20 ] 0 ndip
+        ! [fortran-invoke]
+        [
+            "void" "funpack" "fun_times_"
+            { "char*" "long" } 
+            alien-invoke
+        ] 2 nkeep
+        ! [fortran-results>]
+        shuffle( reta retb -- reta retb ) 
+        { [ ] [ ascii alien>nstring ] } spread
+    ] ] [
+        "CHARACTER*20" "funpack" "FUN_TIMES" { }
+        (fortran-invoke)
+    ] unit-test
+
+    [ [
+        ! [<fortran-result>]
+        [ 10 <byte-array> 10 ] 3 ndip
+        ! [fortran-args>c-args]
+        {
+            [ {
+                [ ascii string>alien ]
+                [ <float> ]
+                [ ascii string>alien ]
+            } spread ]
+            [ { [ length ] [ drop ] [ length ] } spread ]
+        } 3 ncleave
+        ! [fortran-invoke]
+        [
+            "void" "funpack" "fun_times_"
+            { "char*" "long" "char*" "float*" "char*" "long" "long" } 
+            alien-invoke
+        ] 7 nkeep
+        ! [fortran-results>]
+        shuffle( reta retb aa ba ca ab cb -- reta retb aa ab ba ca cb ) 
+        {
+            [ ]
+            [ ascii alien>nstring ]
+            [ ]
+            [ ascii alien>nstring ]
+            [ *float ]
+            [ ]
+            [ ascii alien>nstring ]
+        } spread
+    ] ] [
+        "CHARACTER*10" "funpack" "FUN_TIMES" { "!CHARACTER*20" "!REAL" "!CHARACTER*30" }
+        (fortran-invoke)
+    ] 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
index 9327c7b02c18e1500b18ee39a9e2409fb11fd906..cdf64ecb10a26250e1e4b59a0ebf6b59366753af 100644 (file)
@@ -5,11 +5,10 @@ byte-arrays combinators combinators.short-circuit fry generalizations
 kernel lexer macros math math.parser namespaces parser sequences
 splitting stack-checker vectors vocabs.parser words locals
 io.encodings.ascii io.encodings.string shuffle effects math.ranges
-math.order sorting system ;
+math.order sorting strings system ;
 IN: alien.fortran
 
-! XXX this currently only supports the gfortran/f2c abi.
-! XXX we should also support ifort at some point for commercial BLASes
+SINGLETONS: f2c-abi gfortran-abi intel-unix-abi intel-windows-abi ;
 
 << 
 : add-f2c-libraries ( -- )
@@ -22,18 +21,55 @@ os netbsd? [ add-f2c-libraries ] when
 : alien>nstring ( alien len encoding -- string )
     [ 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 ;
 
 DEFER: fortran-sig>c-sig
 DEFER: fortran-ret-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
 
+: 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: number-type < fortran-type ;
@@ -107,10 +143,14 @@ M: double-complex-type (fortran-type>c-type)
 M: misc-type (fortran-type>c-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' )
     clone dup size>>
     [ 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)
     fix-character-type "char" simple-type ;
@@ -142,22 +182,23 @@ M: character-type (fortran-type>c-type)
 GENERIC: added-c-args ( type -- args )
 
 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 -- ? )
 
 M: f returns-by-value? drop t ;
 M: fortran-type returns-by-value? drop f ;
 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 )
 
 M: f (fortran-ret-type>c-type) drop "void" ;
 M: fortran-type (fortran-ret-type>c-type) (fortran-type>c-type) ;
-! XXX F2C claims to return double for REAL typed functions
-! XXX OSX Accelerate.framework uses float 
-! M: real-type (fortran-ret-type>c-type) drop "double" ;
+M: real-type (fortran-ret-type>c-type)
+    drop real-functions-return-double? [ "double" ] [ "float" ] if ;
 
 : suffix! ( seq   elt   -- seq   ) over push     ; 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 ;
 
 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)
     drop [ ] [ drop ] ;
@@ -255,7 +298,9 @@ M: double-complex-type (fortran-result>)
     [ drop { [ *complex-double ] } ] result?dims ;
 
 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>)
     drop { [ ] } ;
@@ -331,8 +376,18 @@ M: character-type (<fortran-result>)
     append
     \ spread [ ] 2sequence append ;
 
+: (add-fortran-library) ( fortran-abi name -- )
+    library-fortran-abis get-global set-at ;
+
 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 )
     parse-fortran-type (fortran-type>c-type) ;
 
@@ -344,7 +399,7 @@ PRIVATE>
     parse-fortran-type dup returns-by-value?
     [ (fortran-ret-type>c-type) { } ] [
         "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 ;
 
 : 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
 
 : LIBRARY:
-    scan "c-library" set ; parsing
+    scan
+    [ "c-library" set ]
+    [ library-fortran-abis get-global at fortran-abi set ] bi  ; parsing
+
index 58465edeb5a81f675b0587d38600af299ecd8243..2a9b5def7abf44b13004cff1eaca149339251dac 100644 (file)
@@ -1,3 +1,2 @@
 fortran
 ffi
-unportable
index 44252a3b19fd35aa1b6e7314fb91573ff25a62d6..01f134e2836cac06f1f314f5fc2119ea12abda39 100644 (file)
@@ -29,7 +29,7 @@ SYMBOL: super-sent-messages
 
 SYMBOL: frameworks
 
-frameworks global [ V{ } clone or ] change-at
+frameworks [ V{ } clone ] initialize
 
 [ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook
 
index 89b94b30601d08ee4cf84af2a0ddcd6ce4165675..5234fc6d667f5ecbb5cdbc44b7cab1c794fc11c7 100644 (file)
@@ -19,8 +19,8 @@ IN: cocoa.messages
 SYMBOL: message-senders
 SYMBOL: super-message-senders
 
-message-senders global [ H{ } assoc-like ] change-at
-super-message-senders global [ H{ } assoc-like ] change-at
+message-senders [ H{ } clone ] initialize
+super-message-senders [ H{ } clone ] initialize
 
 : cache-stub ( method function hash -- )
     [
@@ -53,7 +53,7 @@ MEMO: <selector> ( name -- sel ) f \ selector boa ;
 
 SYMBOL: objc-methods
 
-objc-methods global [ H{ } assoc-like ] change-at
+objc-methods [ H{ } clone ] initialize
 
 : lookup-method ( selector -- method )
     dup objc-methods get at
@@ -79,7 +79,7 @@ MACRO: (send) ( selector super? -- quot )
 ! Runtime introspection
 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 )
     2dup execute dup [ 2nip ] [
index ec4ced8c9f359a37fdebc7947aae7e4dc06b7010..31faaef480a84ef380b64f369827ebfc47103d74 100644 (file)
@@ -24,4 +24,4 @@ IN: compiler.utilities
 
 SYMBOL: yield-hook
 
-yield-hook global [ [ ] or ] change-at
+yield-hook [ [ ] ] initialize
index 61a3c3899192b8bf15051f4545b2038d81d84145..ce7f7d611083f8333469f4649d02c825f59a9f5a 100644 (file)
@@ -85,4 +85,4 @@ PRIVATE>
 : get-process ( name -- process )\r
     dup registered-processes at [ ] [ thread ] ?if ;\r
 \r
-\ registered-processes global [ H{ } assoc-like ] change-at\r
+\ registered-processes [ H{ } clone ] initialize\r
index eb533af3999c9a68f644e11cecb19e7e59990193..27a81f9948b1eb50ac1bf05c1cfef40dcdc649d4 100644 (file)
@@ -122,7 +122,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
 
 SYMBOL: help-hook
 
-help-hook global [ [ print-topic ] or ] change-at
+help-hook [ [ print-topic ] ] initialize
 
 : help ( topic -- )
     help-hook get call( topic -- ) ;
index 54cc53a0e8bdb5cf7fcc72598094c74c6a87030b..459d7f9f2706bf06addc09b3a604f70d59e8d9e1 100644 (file)
@@ -28,11 +28,11 @@ M: link summary
 ! Help articles
 SYMBOL: articles
 
-articles global [ H{ } assoc-like ] change-at
+articles [ H{ } clone ] initialize
     
 SYMBOL: article-xref
 
-article-xref global [ H{ } assoc-like ] change-at
+article-xref [ H{ } clone ] initialize
 
 GENERIC: article-name ( topic -- string )
 GENERIC: article-title ( topic -- string )
index cfee92a310b7f040cd8441bd75aa7467542dc9c6..d9462d5dde9a1e76ff04118dad61745032e3a7e6 100644 (file)
@@ -11,7 +11,7 @@ html.templates ;
 
 SYMBOL: tags
 
-tags global [ H{ } clone or ] change-at
+tags [ H{ } clone ] initialize
 
 : define-chloe-tag ( name quot -- ) swap tags get set-at ;
 
index b6ee70057b81bb5926fc97746022a8207cdd7cdc..f2f3deead248e3300c5df6ccaf047e8a819f139d 100755 (executable)
@@ -161,7 +161,7 @@ C: <trivial-responder> trivial-responder
 
 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' )
     dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ;
index a56bd1194b01d6c9b3fe7e5eecebd7d6dcd2e7e2..6afae924292620cf3fb746931cf3193d1323de98 100644 (file)
@@ -47,8 +47,8 @@ PRIVATE>
 "resource:basis/io/encodings/iana/character-sets"
 utf8 <file-reader> make-aliases aliases set-global
 
-n>e-table global [ initial-n>e or ] change-at
-e>n-table global [ initial-e>n or ] change-at
+n>e-table [ initial-n>e ] initialize
+e>n-table [ initial-e>n ] initialize
 
 : register-encoding ( descriptor name -- )
     [
index 77cee1aa8288ab692b524dcb21ad1cd21ebc87ce..1749103ce41a47b8c5e70e1e77ac9726ca4cebae 100644 (file)
@@ -3,9 +3,11 @@ IN: math.blas.ffi
 
 <<
 "blas" {
-    { [ os macosx? ] [ "libblas.dylib" "cdecl" add-library ] }
-    { [ os windows? ] [ "blas.dll" "cdecl" add-library ] }
-    [ "libblas.so" "cdecl" add-library ]
+    { [ os macosx? ] [ "libblas.dylib" intel-unix-abi add-fortran-library ] }
+    { [ os windows? cpu x86.32? and ] [ "blas.dll" f2c-abi add-fortran-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
 >>
 
index a4a4ea88ab31c799f3002a1472c5531e803153c7..f468a9989d19840145e7accd85f77a36dc800fbc 100644 (file)
@@ -1,4 +1,3 @@
 math
 bindings
 fortran
-unportable
index 5118958180c04bc1fa91c81557ea06c5694c8c6f..241ec1ecdaa6949fae47e4cca431ec44632d36f7 100644 (file)
@@ -1,3 +1,2 @@
 math
 bindings
-unportable
index 5118958180c04bc1fa91c81557ea06c5694c8c6f..241ec1ecdaa6949fae47e4cca431ec44632d36f7 100644 (file)
@@ -1,3 +1,2 @@
 math
 bindings
-unportable
index ecf3ba0a76563dea2f1a784cb4054003edfecd5a..b436be5163fc0e268abe3d0cff914d103bcbba5c 100644 (file)
@@ -87,7 +87,7 @@ M: word annotate-methods
 
 SYMBOL: word-timing
 
-word-timing global [ H{ } clone or ] change-at
+word-timing [ H{ } clone ] initialize
 
 : reset-word-timing ( -- )
     word-timing get clear-assoc ;
index 669e50b6f766b8dd44cb6ae1b0bba7629aa7d0eb..59f78c242d16c63f6656c356535873c06c637802 100755 (executable)
@@ -142,9 +142,9 @@ CLASS: {
 
 SYMBOL: cocoa-init-hook
 
-cocoa-init-hook global [
-    [ "MiniFactor.nib" load-nib install-app-delegate ] or
-] change-at
+cocoa-init-hook [
+    [ "MiniFactor.nib" load-nib install-app-delegate ]
+] initialize
 
 M: cocoa-ui-backend (with-ui)
     "UI" assert.app [
index 68cee4dc12a9c689a5507b89dcaf61d9683e5516..749db69b5287cdf75e53007e8e5204268f111fa3 100644 (file)
@@ -79,7 +79,7 @@ SYMBOL: ui-error-hook
 : ui-error ( error -- )
     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 -- )
     dup draw-world? [
index 0bea9b5d326d36704f36728d9d82c1789d6011d2..e66572dc1b21c5bf1a20e0bafdc2364bd5e815ce 100644 (file)
@@ -27,7 +27,7 @@ word wrap.">
     "  " wrap-indented-string
 ] 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
 
 [ "hello\nhow\nare\nyou\ntoday?" ]
@@ -39,3 +39,5 @@ word wrap.">
 [ "aaa bb\nccccccc\nddddddd" ] [ "aaa bb ccccccc ddddddd" 6 wrap-string ] unit-test
 
 \ 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
index 6e5bf310750eb8990da65ae4b72d94675d99517d..0b7f869141a47dd61d64e3d3e04570297880434f 100644 (file)
@@ -36,8 +36,10 @@ SYMBOL: line-ideal
     ] each drop ; inline
 
 : paragraph-cost ( paragraph -- cost )
-    [ head-width>> deviation ]
-    [ tail-cost>> ] bi + ;
+    dup lines>> 1list? [ drop 0 ] [
+        [ head-width>> deviation ]
+        [ tail-cost>> ] bi +
+    ] if ;
 
 : min-cost ( paragraphs -- paragraph )
     [ paragraph-cost ] min-by ;
index 93d1a8e30697c61ebaae7344a96f65bc8129aa03..52e9cd0f30a8980edebe19e70920d4e53db585fd 100644 (file)
@@ -51,7 +51,7 @@ M: alien equal?
 
 SYMBOL: libraries
 
-libraries global [ H{ } assoc-like ] change-at
+libraries [ H{ } clone ] initialize
 
 TUPLE: library path abi dll ;
 
index 999b783c489d94dd2d2394da7c9e76c0c43f395d..ac3e99e24cf262014e299d6e22ce003cddaf7a09 100644 (file)
@@ -178,6 +178,4 @@ SYMBOL: remake-generics-hook
 : default-recompile-hook ( words -- alist )
     [ f ] { } map>assoc ;
 
-recompile-hook global
-[ [ default-recompile-hook ] or ]
-change-at
+recompile-hook [ [ default-recompile-hook ] ] initialize
index fd5567cfa2300450f6a9750f97a49ebb5b1b4a02..2f0bb1063f80d4d7b46c7dcfc7efc17a1fe8e49c 100644 (file)
@@ -8,7 +8,7 @@ SYMBOL: 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 ( -- )
 
index 1cc3d86e9866a9e2f5501f5191780b366abdd3a4..ff0542a7b87da8b877c0c7f326033d9d48f6b60f 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax kernel kernel.private
 sequences words namespaces.private quotations vectors
-math.parser math ;
+math.parser math words.symbol ;
 IN: namespaces
 
 ARTICLE: "namespaces-combinators" "Namespace combinators"
@@ -20,7 +20,8 @@ ARTICLE: "namespaces-global" "Global variables"
 { $subsection namespace }
 { $subsection global }
 { $subsection get-global }
-{ $subsection set-global } ;
+{ $subsection set-global }
+{ $subsection initialize } ;
 
 ARTICLE: "namespaces.private" "Namespace implementation details"
 "The namestack holds namespaces."
@@ -159,3 +160,7 @@ HELP: ndrop
 HELP: init-namespaces
 { $description "Resets the name stack to its initial state, holding a single copy of the global namespace." }
 $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." } ;
index 4c11e2389f1605ebeb1679d59b8be01c6e03c702..616ddef7fc70299d23dfa05c7bdddaca66343760 100644 (file)
@@ -12,3 +12,14 @@ H{ } clone "test-namespace" set
 [ f ]
 [ H{ } clone [ f "some-global" set "some-global" get ] bind ]
 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
index 36559095cba3902b824c842c39dd31231d4bfb45..24095fd38203122bcfb9e214148b5a35727715ad 100644 (file)
@@ -37,4 +37,7 @@ PRIVATE>
     H{ } clone >n call ndrop ; inline
 
 : 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 ;
index f862885339da883f75de79eb37199ee16e6d88f7..3a8c1c10478903f97fe12335253ed5c36ec3a92d 100644 (file)
@@ -203,7 +203,7 @@ SYMBOL: interactive-vocabs
 
 SYMBOL: print-use-hook
 
-print-use-hook global [ [ ] or ] change-at
+print-use-hook [ [ ] ] initialize
 
 : parse-fresh ( lines -- quot )
     [
index 4062e16e3d807a4859e85d03a4b36b0eb0b42066..8c9d0b555794faa169b47962953c0db2e1bf2343 100644 (file)
@@ -22,9 +22,9 @@ ERROR: bad-escape ;
 
 SYMBOL: name>char-hook
 
-name>char-hook global [
-    [ "Unicode support not available" throw ] or
-] change-at
+name>char-hook [
+    [ "Unicode support not available" throw ]
+] initialize
 
 : unicode-escape ( str -- ch str' )
     "{" ?head-slice [
index cbaa7b964b657730a9fdc4b528c4a2c77a77fdd1..c177ca96d9086fc618c3a2b7095d674b00e40e1b 100755 (executable)
@@ -96,11 +96,11 @@ M: word uses ( word -- seq )
 
 SYMBOL: compiled-crossref
 
-compiled-crossref global [ H{ } assoc-like ] change-at
+compiled-crossref [ H{ } clone ] initialize
 
 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 -- )
     [ [ set-word-prop ] curry ]
index 94128dc3b28dd6db49d8d6c3c339436ebaea3f0e..da69c2ced3746bf58de9f059d74f2c0e8e7db7de 100644 (file)
@@ -3,15 +3,15 @@
 USING: help.markup help.syntax sequences kernel ;
 IN: id3
 
-HELP: id3-parse-mp3-file
+HELP: file-id3-tags
 { $values 
     { "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." } }
-{ $description "Return a tuple containing the ID3 information parsed out of the MP3 file" } ;
+    { "object/f" "a tuple storing ID3 metadata or f" } }
+{ $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"
-{ $emphasis "ID3" } " tags are textual data that is used to describe the information (title, artist, etc.) in an .MP3 file"
-"Parsing an MP3 file: "
-{ $subsection id3-parse-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 ID3 tags from an MP3 file:"
+{ $subsection file-id3-tags } ;
 
 ABOUT: "id3"
index d84f2c87260dedb2c9975f3a319b04441d41e740..b9d45b1b04fc1af9fd93a667b1f71407d40d7230 100644 (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
@@ -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
@@ -178,5 +178,5 @@ IN: id3.tests
      }
      { 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
 
index b2c2ec0621ff226342894c6929e9eab5576bc1c0..64e1ff1d10b498b8778a2ee5716f540a5b929897 100644 (file)
@@ -142,7 +142,7 @@ PRIVATE>
 
 ! main stuff
 
-: id3-parse-mp3-file ( path -- object )
+: file-id3-tags ( path -- object/f )
     [
         {
             { [ dup id3v2? ] [ read-v2-tag-data ] } ! ( ? -- mp3v2-file )
index b1739d85faff15c104a0ecdf3acbe86f2e9766ef..51b09543f483583e7bc061a6f25cd5d18d5809a7 100644 (file)
@@ -81,7 +81,7 @@ SYMBOL: upload-directory
 
 ! Optional: override ssh and scp command names
 SYMBOL: scp-command
-scp-command global [ "scp" or ] change-at
+scp-command [ "scp" ] initialize
 
 SYMBOL: ssh-command
-ssh-command global [ "ssh" or ] change-at
+ssh-command [ "ssh" ] initialize