]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorJohn Benediktsson <mrjbq7@gmail.com>
Fri, 13 Feb 2009 23:04:14 +0000 (15:04 -0800)
committerJohn Benediktsson <mrjbq7@gmail.com>
Fri, 13 Feb 2009 23:04:14 +0000 (15:04 -0800)
293 files changed:
.gitignore
README.txt
basis/alien/arrays/arrays.factor [changed mode: 0644->0755]
basis/alien/c-types/c-types.factor [changed mode: 0644->0755]
basis/alien/complex/complex-tests.factor
basis/alien/complex/complex.factor
basis/alien/complex/functor/functor.factor
basis/alien/fortran/authors.txt [new file with mode: 0644]
basis/alien/fortran/fortran-docs.factor [new file with mode: 0644]
basis/alien/fortran/fortran-tests.factor [new file with mode: 0644]
basis/alien/fortran/fortran.factor [new file with mode: 0644]
basis/alien/fortran/summary.txt [new file with mode: 0644]
basis/alien/fortran/tags.txt [new file with mode: 0644]
basis/alien/structs/fields/fields.factor
basis/alien/structs/structs-tests.factor [changed mode: 0644->0755]
basis/alien/structs/structs.factor [changed mode: 0644->0755]
basis/bit-arrays/bit-arrays.factor
basis/bitstreams/authors.txt [new file with mode: 0644]
basis/bitstreams/bitstreams-tests.factor [new file with mode: 0644]
basis/bitstreams/bitstreams.factor [new file with mode: 0644]
basis/bootstrap/image/image-docs.factor
basis/call/call-docs.factor [new file with mode: 0644]
basis/call/call-tests.factor [new file with mode: 0644]
basis/call/call.factor [new file with mode: 0644]
basis/cocoa/cocoa.factor
basis/cocoa/messages/messages.factor
basis/combinators/smart/smart-tests.factor
basis/combinators/smart/smart.factor
basis/compiler/alien/alien.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/utilities/utilities.factor
basis/compression/lzw/authors.txt [new file with mode: 0644]
basis/compression/lzw/lzw-tests.factor [new file with mode: 0644]
basis/compression/lzw/lzw.factor [new file with mode: 0644]
basis/compression/zlib/authors.txt [new file with mode: 0755]
basis/compression/zlib/ffi/authors.txt [new file with mode: 0755]
basis/compression/zlib/ffi/ffi.factor [new file with mode: 0755]
basis/compression/zlib/zlib-tests.factor [new file with mode: 0755]
basis/compression/zlib/zlib.factor [new file with mode: 0755]
basis/concurrency/messaging/messaging.factor
basis/constructors/authors.txt [new file with mode: 0644]
basis/constructors/constructors-tests.factor [new file with mode: 0644]
basis/constructors/constructors.factor [new file with mode: 0644]
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/64/unix/unix.factor
basis/cpu/x86/64/winnt/winnt.factor
basis/csv/csv-tests.factor
basis/csv/csv.factor
basis/db/postgresql/ffi/ffi.factor
basis/db/postgresql/lib/lib.factor
basis/db/queries/queries.factor
basis/db/sqlite/ffi/ffi.factor
basis/db/sqlite/sqlite-tests.factor
basis/db/sqlite/sqlite.factor
basis/db/types/types.factor
basis/editors/editors.factor
basis/endian/endian.factor
basis/furnace/chloe-tags/chloe-tags.factor
basis/furnace/furnace-tests.factor
basis/furnace/utilities/utilities-docs.factor
basis/furnace/utilities/utilities.factor
basis/generalizations/generalizations-docs.factor
basis/generalizations/generalizations-tests.factor
basis/generalizations/generalizations.factor
basis/help/help.factor
basis/help/lint/lint.factor
basis/help/topics/topics.factor
basis/html/components/components-docs.factor
basis/html/components/components.factor
basis/html/html-docs.factor [new file with mode: 0644]
basis/html/html.factor
basis/html/templates/chloe/chloe-docs.factor
basis/html/templates/chloe/chloe.factor
basis/html/templates/chloe/compiler/compiler.factor
basis/html/templates/chloe/syntax/syntax.factor
basis/html/templates/fhtml/fhtml.factor
basis/http/client/client-docs.factor
basis/http/client/client.factor
basis/http/http-docs.factor
basis/http/http-tests.factor
basis/http/http.factor
basis/http/server/server.factor
basis/http/server/static/static-docs.factor
basis/http/server/static/static.factor
basis/images/authors.txt [new file with mode: 0644]
basis/images/bitmap/authors.txt [new file with mode: 0755]
basis/images/bitmap/bitmap-tests.factor [new file with mode: 0644]
basis/images/bitmap/bitmap.factor [new file with mode: 0755]
basis/images/images.factor [new file with mode: 0644]
basis/images/loader/authors.txt [new file with mode: 0644]
basis/images/loader/loader.factor [new file with mode: 0644]
basis/images/tags.txt [new file with mode: 0644]
basis/images/test-images/1bit.bmp [new file with mode: 0644]
basis/images/test-images/octagon.tiff [new file with mode: 0644]
basis/images/test-images/rgb.tiff [new file with mode: 0755]
basis/images/test-images/rgb4bit.bmp [new file with mode: 0644]
basis/images/test-images/rgb8bit.bmp [new file with mode: 0644]
basis/images/test-images/thiswayup24.bmp [new file with mode: 0644]
basis/images/tiff/authors.txt [new file with mode: 0755]
basis/images/tiff/tiff-tests.factor [new file with mode: 0755]
basis/images/tiff/tiff.factor [new file with mode: 0755]
basis/io/backend/unix/unix.factor
basis/io/backend/windows/nt/nt.factor
basis/io/buffers/buffers.factor
basis/io/encodings/iana/iana.factor
basis/io/launcher/windows/nt/nt-tests.factor [changed mode: 0644->0755]
basis/io/ports/ports.factor
basis/lists/authors.txt [new file with mode: 0644]
basis/lists/lazy/authors.txt [new file with mode: 0644]
basis/lists/lazy/examples/authors.txt [new file with mode: 0755]
basis/lists/lazy/examples/examples-tests.factor [new file with mode: 0644]
basis/lists/lazy/examples/examples.factor [new file with mode: 0644]
basis/lists/lazy/lazy-docs.factor [new file with mode: 0644]
basis/lists/lazy/lazy-tests.factor [new file with mode: 0644]
basis/lists/lazy/lazy.factor [new file with mode: 0644]
basis/lists/lazy/old-doc.html [new file with mode: 0644]
basis/lists/lazy/summary.txt [new file with mode: 0644]
basis/lists/lazy/tags.txt [new file with mode: 0644]
basis/lists/lists-docs.factor [new file with mode: 0644]
basis/lists/lists-tests.factor [new file with mode: 0644]
basis/lists/lists.factor [new file with mode: 0644]
basis/lists/summary.txt [new file with mode: 0644]
basis/lists/tags.txt [new file with mode: 0644]
basis/math/blas/cblas/authors.txt [deleted file]
basis/math/blas/cblas/cblas.factor [deleted file]
basis/math/blas/cblas/summary.txt [deleted file]
basis/math/blas/cblas/tags.txt [deleted file]
basis/math/blas/ffi/authors.txt [new file with mode: 0644]
basis/math/blas/ffi/ffi.factor [new file with mode: 0644]
basis/math/blas/ffi/summary.txt [new file with mode: 0644]
basis/math/blas/ffi/tags.txt [new file with mode: 0644]
basis/math/blas/matrices/matrices-docs.factor
basis/math/blas/matrices/matrices.factor
basis/math/blas/vectors/tags.txt
basis/math/blas/vectors/vectors-docs.factor
basis/math/blas/vectors/vectors-tests.factor
basis/math/blas/vectors/vectors.factor
basis/math/polynomials/polynomials.factor
basis/pack/pack.factor
basis/persistent/deques/deques-docs.factor
basis/persistent/deques/deques.factor
basis/regexp/traversal/traversal.factor
basis/shuffle/shuffle-tests.factor
basis/shuffle/shuffle.factor
basis/specialized-arrays/complex-double/complex-double-tests.factor [new file with mode: 0644]
basis/specialized-arrays/complex-double/complex-double.factor [new file with mode: 0644]
basis/specialized-arrays/complex-float/complex-float.factor [new file with mode: 0644]
basis/specialized-arrays/direct/complex-double/complex-double.factor [new file with mode: 0644]
basis/specialized-arrays/direct/complex-float/complex-float.factor [new file with mode: 0644]
basis/specialized-arrays/direct/functor/functor.factor
basis/specialized-arrays/functor/functor.factor
basis/specialized-arrays/specialized-arrays-docs.factor
basis/tools/annotations/annotations.factor
basis/tools/deploy/backend/backend.factor [changed mode: 0644->0755]
basis/tools/deploy/macosx/macosx.factor [changed mode: 0644->0755]
basis/tools/deploy/unix/unix.factor [changed mode: 0644->0755]
basis/tools/deploy/windows/windows.factor
basis/tools/hexdump/hexdump.factor
basis/ui/cocoa/cocoa.factor
basis/ui/gadgets/worlds/worlds.factor
basis/ui/tools/interactor/interactor.factor
basis/ui/ui.factor
basis/urls/urls-docs.factor
basis/wrap/strings/strings-docs.factor [new file with mode: 0644]
basis/wrap/strings/strings-tests.factor [new file with mode: 0644]
basis/wrap/strings/strings.factor [new file with mode: 0644]
basis/wrap/words/words-docs.factor [new file with mode: 0644]
basis/wrap/words/words-tests.factor [new file with mode: 0644]
basis/wrap/words/words.factor [new file with mode: 0644]
basis/wrap/wrap-docs.factor
basis/wrap/wrap-tests.factor [deleted file]
basis/wrap/wrap.factor
basis/xml-rpc/xml-rpc.factor
basis/xml/syntax/syntax.factor
basis/xml/tests/test.factor
basis/xml/writer/writer.factor
basis/xml/xml-docs.factor
basis/xml/xml.factor
basis/zlib/authors.txt [deleted file]
basis/zlib/ffi/authors.txt [deleted file]
basis/zlib/ffi/ffi.factor [deleted file]
basis/zlib/zlib-tests.factor [deleted file]
basis/zlib/zlib.factor [deleted file]
core/alien/alien.factor
core/classes/tuple/tuple-docs.factor
core/combinators/combinators-tests.factor
core/combinators/combinators.factor
core/compiler/units/units.factor
core/io/backend/backend.factor
core/io/files/files-tests.factor
core/io/io-docs.factor
core/io/io-tests.factor
core/kernel/kernel-docs.factor
core/kernel/kernel.factor
core/math/math-docs.factor
core/namespaces/namespaces-docs.factor
core/namespaces/namespaces-tests.factor
core/namespaces/namespaces.factor
core/parser/parser.factor
core/quotations/quotations-docs.factor
core/slots/slots.factor [changed mode: 0644->0755]
core/strings/parser/parser.factor
core/syntax/syntax-docs.factor
core/words/words.factor
extra/annotations/annotations-docs.factor [new file with mode: 0644]
extra/annotations/annotations-tests.factor [new file with mode: 0644]
extra/annotations/annotations.factor [new file with mode: 0644]
extra/annotations/authors.txt [new file with mode: 0644]
extra/annotations/summary.txt [new file with mode: 0644]
extra/annotations/tags.txt [new file with mode: 0644]
extra/cap/cap.factor
extra/constructors/authors.txt [deleted file]
extra/constructors/constructors-tests.factor [deleted file]
extra/constructors/constructors.factor [deleted file]
extra/graphics/authors.txt [deleted file]
extra/graphics/bitmap/authors.txt [deleted file]
extra/graphics/bitmap/bitmap-tests.factor [deleted file]
extra/graphics/bitmap/bitmap.factor [deleted file]
extra/graphics/bitmap/test-images/1bit.bmp [deleted file]
extra/graphics/bitmap/test-images/rgb4bit.bmp [deleted file]
extra/graphics/bitmap/test-images/rgb8bit.bmp [deleted file]
extra/graphics/bitmap/test-images/thiswayup24.bmp [deleted file]
extra/graphics/tags.txt [deleted file]
extra/graphics/tiff/authors.txt [deleted file]
extra/graphics/tiff/rgb.tiff [deleted file]
extra/graphics/tiff/tiff-tests.factor [deleted file]
extra/graphics/tiff/tiff.factor [deleted file]
extra/graphics/viewer/authors.txt [deleted file]
extra/graphics/viewer/viewer.factor [deleted file]
extra/id3/authors.txt [new file with mode: 0644]
extra/id3/id3-docs.factor [new file with mode: 0644]
extra/id3/id3-tests.factor [new file with mode: 0644]
extra/id3/id3.factor [new file with mode: 0644]
extra/id3/tests/blah.mp3 [new file with mode: 0644]
extra/id3/tests/blah2.mp3 [new file with mode: 0644]
extra/id3/tests/blah3.mp3 [new file with mode: 0644]
extra/images/viewer/authors.txt [new file with mode: 0755]
extra/images/viewer/viewer.factor [new file with mode: 0644]
extra/infix/ast/ast.factor
extra/infix/authors.txt [new file with mode: 0644]
extra/infix/infix-docs.factor
extra/infix/infix-tests.factor
extra/infix/infix.factor
extra/infix/parser/parser-tests.factor
extra/infix/parser/parser.factor
extra/infix/summary.txt [new file with mode: 0644]
extra/infix/tags.txt [new file with mode: 0644]
extra/infix/tokenizer/tokenizer-tests.factor
extra/infix/tokenizer/tokenizer.factor
extra/lists/authors.txt [deleted file]
extra/lists/lazy/authors.txt [deleted file]
extra/lists/lazy/examples/authors.txt [deleted file]
extra/lists/lazy/examples/examples-tests.factor [deleted file]
extra/lists/lazy/examples/examples.factor [deleted file]
extra/lists/lazy/lazy-docs.factor [deleted file]
extra/lists/lazy/lazy-tests.factor [deleted file]
extra/lists/lazy/lazy.factor [deleted file]
extra/lists/lazy/old-doc.html [deleted file]
extra/lists/lazy/summary.txt [deleted file]
extra/lists/lazy/tags.txt [deleted file]
extra/lists/lists-docs.factor [deleted file]
extra/lists/lists-tests.factor [deleted file]
extra/lists/lists.factor [deleted file]
extra/lists/summary.txt [deleted file]
extra/lists/tags.txt [deleted file]
extra/mason/config/config.factor
extra/parser-combinators/parser-combinators.factor
extra/project-euler/002/002.factor
extra/project-euler/134/134.factor
extra/promises/promises.factor
extra/reports/noise/noise.factor
extra/system-info/linux/linux.factor
extra/tar/tar.factor
extra/taxes/usa/futa/futa.factor
extra/taxes/usa/usa.factor
extra/twitter/twitter.factor [new file with mode: 0644]
extra/ui/offscreen/offscreen-docs.factor
extra/ui/offscreen/offscreen.factor
extra/ui/render/test/test.factor
extra/webapps/todo/todo.factor
extra/webapps/todo/todo.xml
extra/websites/concatenative/concatenative.factor
misc/fuel/fuel-completion.el
misc/fuel/fuel-connection.el
misc/fuel/fuel-edit.el
misc/fuel/fuel-help.el
misc/fuel/fuel-listener.el
misc/fuel/fuel-markup.el
misc/fuel/fuel-scaffold.el
misc/fuel/fuel-xref.el
vm/os-unix.c

index 435595f502cbdcec6f019cae08b41d2d1d4555dc..22dda8efb4b7d80d0abffccb5a77eeb385b6d221 100644 (file)
@@ -24,3 +24,4 @@ build-support/wordsize
 *.bak
 .#*
 *.swo
+checksums.txt
index 98616539d20d9c6f6366928dadf0bf27b1a5549f..d60bf03130beda211bb15f8a27383c58f87207cc 100755 (executable)
@@ -116,16 +116,22 @@ Now if $DISPLAY is set, running ./factor will start the UI.
 
 * Running Factor on Windows XP/Vista
 
+The Factor runtime is compiled into two binaries:
+
+  factor.com - a Windows console application
+  factor.exe - a Windows native application, without a console
+
 If you did not download the binary package, you can bootstrap Factor in
-the command prompt:
+the command prompt using the console application:
 
-  factor.exe -i=boot.<cpu>.image
+  factor.com -i=boot.<cpu>.image
 
-Once bootstrapped, double-clicking factor.exe starts the Factor UI.
+Once bootstrapped, double-clicking factor.exe or factor.com starts
+the Factor UI.
 
 To run the listener in the command prompt:
 
-  factor.exe -run=listener
+  factor.com -run=listener
 
 * The Factor FAQ
 
old mode 100644 (file)
new mode 100755 (executable)
index 8253d94..6a182f8
@@ -26,7 +26,7 @@ M: array box-return drop "void*" box-return ;
 
 M: array stack-size drop "void*" stack-size ;
 
-M: array c-type-boxer-quot drop f ;
+M: array c-type-boxer-quot drop [ ] ;
 
 M: array c-type-unboxer-quot drop [ >c-ptr ] ;
 
old mode 100644 (file)
new mode 100755 (executable)
index cf5daa1..a44b5cf
@@ -4,7 +4,7 @@ USING: byte-arrays arrays assocs kernel kernel.private libc math
 namespaces make parser sequences strings words assocs splitting
 math.parser cpu.architecture alien alien.accessors quotations
 layouts system compiler.units io.files io.encodings.binary
-accessors combinators effects continuations fry ;
+accessors combinators effects continuations fry call classes ;
 IN: alien.c-types
 
 DEFER: <int>
@@ -13,18 +13,20 @@ DEFER: *char
 : little-endian? ( -- ? ) 1 <int> *char 1 = ; foldable
 
 TUPLE: c-type
-class
-boxer boxer-quot unboxer unboxer-quot
-getter setter
-reg-class size align stack-align? ;
-
-: new-c-type ( class -- type )
-    new
-        int-regs >>reg-class
-        object >>class ; inline
+{ class class initial: object }
+boxer
+{ boxer-quot callable }
+unboxer
+{ unboxer-quot callable }
+{ getter callable }
+{ setter callable }
+{ reg-class initial: int-regs }
+size
+align
+stack-align? ;
 
 : <c-type> ( -- type )
-    \ c-type new-c-type ;
+    \ c-type new ;
 
 SYMBOL: c-types
 
@@ -185,6 +187,9 @@ M: f byte-length drop 0 ;
         [ "Cannot read struct fields with this type" throw ]
     ] unless* ;
 
+: c-type-getter-boxer ( name -- quot )
+    [ c-getter ] [ c-type-boxer-quot ] bi append ;
+
 : c-setter ( name -- quot )
     c-type-setter [
         [ "Cannot write struct fields with this type" throw ]
@@ -221,7 +226,7 @@ M: f byte-length drop 0 ;
 TUPLE: long-long-type < c-type ;
 
 : <long-long-type> ( -- type )
-    long-long-type new-c-type ;
+    long-long-type new ;
 
 M: long-long-type unbox-parameter ( n type -- )
     c-type-unboxer %unbox-long-long ;
@@ -258,7 +263,7 @@ M: long-long-type box-return ( type -- )
         unclip [
             [
                 dup word? [
-                    def>> { } swap with-datastack first
+                    def>> call( -- object )
                 ] when
             ] map
         ] dip prefix
index bfb2c1137c60000b061604077368af9676e9cd72..0bff73b898dae2ddc88e873c4c0d3d722461275c 100644 (file)
@@ -15,4 +15,4 @@ C-STRUCT: complex-holder
     C{ 1.0 2.0 } <complex-holder> "h" set
 ] unit-test
 
-[ C{ 1.0 2.0 } ] [ "h" get complex-holder-z ] unit-test
\ No newline at end of file
+[ C{ 1.0 2.0 } ] [ "h" get complex-holder-z ] unit-test
index 60a84b939433520a358ed2838405a88b78883899..c80ead73f0bf701d6173abf0ccd234681572713b 100644 (file)
@@ -1,6 +1,13 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.complex.functor sequences kernel ;
+USING: alien.c-types alien.structs alien.complex.functor accessors
+sequences kernel ;
 IN: alien.complex
 
-<< { "float" "double" } [ dup "complex-" prepend define-complex-type ] each >>
\ No newline at end of file
+<<
+{ "float" "double" } [ dup "complex-" prepend define-complex-type ] each
+
+! This overrides the fact that small structures are never returned
+! in registers on NetBSD, Linux and Solaris running on 32-bit x86.
+"complex-float" c-type t >>return-in-registers? drop
+ >>
index 1d12bb0ff4da7c70aa99bf55b747ac99f36ee1ef..31af0291b46561f884984714f15dfa7ca9ba1e87 100644 (file)
@@ -12,15 +12,15 @@ T-imaginary DEFINES ${T}-imaginary
 set-T-real DEFINES set-${T}-real
 set-T-imaginary DEFINES set-${T}-imaginary
 
->T DEFINES >${T}
-T> DEFINES ${T}>
+<T> DEFINES <${T}>
+*T DEFINES *${T}
 
 WHERE
 
-: >T ( z -- alien )
+: <T> ( z -- alien )
     >rect T <c-object> [ set-T-imaginary ] [ set-T-real ] [ ] tri ; inline
 
-: T> ( alien -- z )
+: *T ( alien -- z )
     [ T-real ] [ T-imaginary ] bi rect> ; inline
 
 T in get
@@ -28,8 +28,8 @@ T in get
 define-struct
 
 T c-type
-T> 1quotation >>boxer-quot
->T 1quotation >>unboxer-quot
+<T> 1quotation >>unboxer-quot
+*T 1quotation >>boxer-quot
 drop
 
-;FUNCTOR
\ No newline at end of file
+;FUNCTOR
diff --git a/basis/alien/fortran/authors.txt b/basis/alien/fortran/authors.txt
new file mode 100644 (file)
index 0000000..f13c9c1
--- /dev/null
@@ -0,0 +1 @@
+Joe Groff
diff --git a/basis/alien/fortran/fortran-docs.factor b/basis/alien/fortran/fortran-docs.factor
new file mode 100644 (file)
index 0000000..c5d124e
--- /dev/null
@@ -0,0 +1,73 @@
+! Copyright (C) 2009 Joe Groff
+! See http://factorcode.org/license.txt for BSD license.
+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
+    { { $snippet "INTEGER" } " specifies a four-byte integer value. Sized integers can be specified with " { $snippet "INTEGER*1" } ", " { $snippet "INTEGER*2" } ", " { $snippet "INTEGER*4" } ", and " { $snippet "INTEGER*8" } "." }
+    { { $snippet "LOGICAL" } " specifies a four-byte boolean value. Sized booleans can be specified with " { $snippet "LOGICAL*1" } ", " { $snippet "LOGICAL*2" } ", " { $snippet "LOGICAL*4" } ", and " { $snippet "LOGICAL*8" } "." }
+    { { $snippet "REAL" } " specifies a single-precision floating-point real value." }
+    { { $snippet "DOUBLE-PRECISION" } " specifies a double-precision floating-point real value. The alias " { $snippet "REAL*8" } " is also recognized." }
+    { { $snippet "COMPLEX" } " specifies a single-precision floating-point complex value." }
+    { { $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 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." ;
+
+HELP: FUNCTION:
+{ $syntax "FUNCTION: RETURN-TYPE NAME ( [!]ARGUMENT-TYPE NAME, ... ) ;" }
+{ $description "Declares a Fortran function binding with the given return type and arguments. See " { $link "alien.fortran-types" } " for a list of supported types." } ;
+
+HELP: SUBROUTINE:
+{ $syntax "SUBROUTINE: NAME ( [!]ARGUMENT-TYPE NAME, ... ) ;" }
+{ $description "Declares a Fortran subroutine binding with the given arguments. See " { $link "alien.fortran-types" } " for a list of supported types." } ;
+
+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. 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. 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 }
+}
+{ $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 "\"!\"" } "." }
+;
+
+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: }
+{ $subsection POSTPONE: RECORD: }
+{ $subsection fortran-invoke }
+;
+
+ABOUT: "alien.fortran"
diff --git a/basis/alien/fortran/fortran-tests.factor b/basis/alien/fortran/fortran-tests.factor
new file mode 100644 (file)
index 0000000..177d107
--- /dev/null
@@ -0,0 +1,381 @@
+! (c) 2009 Joe Groff, see BSD license
+USING: accessors alien alien.c-types alien.complex
+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" } ;
+
+intel-unix-abi fortran-abi [
+
+    ! fortran-name>symbol-name
+
+    [ "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-type>c-type
+
+    [ "short" ]
+    [ "integer*2" fortran-type>c-type ] unit-test
+
+    [ "int" ]
+    [ "integer*4" fortran-type>c-type ] unit-test
+
+    [ "int" ]
+    [ "INTEGER" fortran-type>c-type ] unit-test
+
+    [ "longlong" ]
+    [ "iNteger*8" fortran-type>c-type ] unit-test
+
+    [ "int[0]" ]
+    [ "integer(*)" fortran-type>c-type ] unit-test
+
+    [ "int[0]" ]
+    [ "integer(3,*)" fortran-type>c-type ] unit-test
+
+    [ "int[3]" ]
+    [ "integer(3)" fortran-type>c-type ] unit-test
+
+    [ "int[6]" ]
+    [ "integer(3,2)" fortran-type>c-type ] unit-test
+
+    [ "int[24]" ]
+    [ "integer(4,3,2)" fortran-type>c-type ] unit-test
+
+    [ "char" ]
+    [ "character" fortran-type>c-type ] unit-test
+
+    [ "char" ]
+    [ "character*1" fortran-type>c-type ] unit-test
+
+    [ "char[17]" ]
+    [ "character*17" fortran-type>c-type ] unit-test
+
+    [ "char[17]" ]
+    [ "character(17)" fortran-type>c-type ] unit-test
+
+    [ "int" ]
+    [ "logical" fortran-type>c-type ] unit-test
+
+    [ "float" ]
+    [ "real" fortran-type>c-type ] unit-test
+
+    [ "double" ]
+    [ "double-precision" fortran-type>c-type ] unit-test
+
+    [ "float" ]
+    [ "real*4" fortran-type>c-type ] unit-test
+
+    [ "double" ]
+    [ "real*8" fortran-type>c-type ] unit-test
+
+    [ "complex-float" ]
+    [ "complex" fortran-type>c-type ] unit-test
+
+    [ "complex-double" ]
+    [ "double-complex" fortran-type>c-type ] unit-test
+
+    [ "complex-float" ]
+    [ "complex*8" fortran-type>c-type ] unit-test
+
+    [ "complex-double" ]
+    [ "complex*16" fortran-type>c-type ] unit-test
+
+    [ "fortran_test_record" ]
+    [ "fortran_test_record" fortran-type>c-type ] unit-test
+
+    ! fortran-arg-type>c-type
+
+    [ "int*" { } ]
+    [ "integer" fortran-arg-type>c-type ] unit-test
+
+    [ "int*" { } ]
+    [ "integer(3)" 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
+
+    [ "char*" { } ]
+    [ "character" fortran-arg-type>c-type ] unit-test
+
+    [ "char*" { } ]
+    [ "character(1)" fortran-arg-type>c-type ] unit-test
+
+    [ "char*" { "long" } ]
+    [ "character(17)" fortran-arg-type>c-type ] unit-test
+
+    ! fortran-ret-type>c-type
+
+    [ "char" { } ]
+    [ "character(1)" fortran-ret-type>c-type ] 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
diff --git a/basis/alien/fortran/fortran.factor b/basis/alien/fortran/fortran.factor
new file mode 100644 (file)
index 0000000..915b7d3
--- /dev/null
@@ -0,0 +1,452 @@
+! (c) 2009 Joe Groff, see BSD license
+USING: accessors alien alien.c-types alien.complex alien.parser
+alien.strings alien.structs alien.syntax arrays ascii assocs
+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 strings system ;
+IN: alien.fortran
+
+SINGLETONS: f2c-abi gfortran-abi intel-unix-abi intel-windows-abi ;
+
+<< 
+: add-f2c-libraries ( -- )
+    "I77" "libI77.so" "cdecl" add-library
+    "F77" "libF77.so" "cdecl" add-library ;
+
+os netbsd? [ add-f2c-libraries ] when
+>>
+
+: alien>nstring ( alien len encoding -- string )
+    [ memory>byte-array ] dip decode ;
+
+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 ;
+TUPLE: integer-type < number-type ;
+TUPLE: logical-type < integer-type ;
+TUPLE: real-type < number-type ;
+TUPLE: double-precision-type < number-type ;
+
+TUPLE: character-type < fortran-type ;
+TUPLE: misc-type < fortran-type name ;
+
+TUPLE: complex-type < number-type ;
+TUPLE: real-complex-type < complex-type ;
+TUPLE: double-complex-type < complex-type ;
+
+CONSTANT: fortran>c-types H{
+    { "character"        character-type        }
+    { "integer"          integer-type          }
+    { "logical"          logical-type          }
+    { "real"             real-type             }
+    { "double-precision" double-precision-type }
+    { "complex"          real-complex-type     }
+    { "double-complex"   double-complex-type   }
+}
+
+: append-dimensions ( base-c-type type -- c-type )
+    dims>>
+    [ product number>string "[" "]" surround append ] when* ;
+
+MACRO: size-case-type ( cases -- )
+    [ invalid-fortran-type ] suffix
+    '[ [ size>> _ case ] [ append-dimensions ] bi ] ;
+
+: simple-type ( type base-c-type -- c-type )
+    swap
+    [ dup size>> [ invalid-fortran-type ] [ drop ] if ]
+    [ append-dimensions ] bi ;
+
+: new-fortran-type ( out? dims size class -- type )
+    new [ [ (>>size) ] [ (>>dims) ] [ (>>out?) ] tri ] keep ;
+
+GENERIC: (fortran-type>c-type) ( type -- c-type )
+
+M: f (fortran-type>c-type) drop "void" ;
+
+M: integer-type (fortran-type>c-type)
+    {
+        { f [ "int"      ] }
+        { 1 [ "char"     ] }
+        { 2 [ "short"    ] }
+        { 4 [ "int"      ] }
+        { 8 [ "longlong" ] }
+    } size-case-type ;
+M: real-type (fortran-type>c-type)
+    {
+        { f [ "float"  ] }
+        { 4 [ "float"  ] }
+        { 8 [ "double" ] }
+    } size-case-type ;
+M: real-complex-type (fortran-type>c-type)
+    {
+        {  f [ "complex-float"  ] }
+        {  8 [ "complex-float"  ] }
+        { 16 [ "complex-double" ] }
+    } size-case-type ;
+
+M: double-precision-type (fortran-type>c-type)
+    "double" simple-type ;
+M: double-complex-type (fortran-type>c-type)
+    "complex-double" simple-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>> [ ] [ f >>dims ] if ] if
+    dup single-char? [ f >>dims ] when ;
+
+M: character-type (fortran-type>c-type)
+    fix-character-type "char" simple-type ;
+
+: dimension>number ( string -- number )
+    dup "*" = [ drop 0 ] [ string>number ] if ;
+
+: parse-out ( string -- string' out? )
+    "!" ?head ;
+
+: parse-dims ( string -- string' dim )
+    "(" split1 dup
+    [ ")" ?tail drop "," split [ [ blank? ] trim dimension>number ] map ] when ;
+
+: parse-size ( string -- string' size )
+    "*" split1 dup [ string>number ] when ;
+
+: (parse-fortran-type) ( fortran-type-string -- type )
+    parse-out swap parse-dims swap parse-size swap
+    dup >lower fortran>c-types at*
+    [ nip new-fortran-type ] [ drop misc-type boa ] if ;
+
+: parse-fortran-type ( fortran-type-string/f -- type/f )
+    dup [ (parse-fortran-type) ] when ;
+
+: c-type>pointer ( c-type -- c-type* )
+    "[" split1 drop "*" append ;
+
+GENERIC: added-c-args ( type -- args )
+
+M: fortran-type added-c-args drop { } ;
+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: 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) ;
+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
+
+GENERIC: (fortran-arg>c-args) ( type -- main-quot added-quot )
+
+: args?dims ( type quot -- main-quot added-quot )
+    [ dup dims>> [ drop [ ] [ drop ] ] ] dip if ; inline
+
+M: integer-type (fortran-arg>c-args)
+    [
+        size>> {
+            { f [ [ <int>      ] [ drop ] ] }
+            { 1 [ [ <char>     ] [ drop ] ] }
+            { 2 [ [ <short>    ] [ drop ] ] }
+            { 4 [ [ <int>      ] [ drop ] ] }
+            { 8 [ [ <longlong> ] [ drop ] ] }
+            [ invalid-fortran-type ]
+        } case
+    ] args?dims ;
+
+M: logical-type (fortran-arg>c-args)
+    [ call-next-method [ [ 1 0 ? ] prepend ] dip ] args?dims ;
+
+M: real-type (fortran-arg>c-args)
+    [
+        size>> {
+            { f [ [ <float>  ] [ drop ] ] }
+            { 4 [ [ <float>  ] [ drop ] ] }
+            { 8 [ [ <double> ] [ drop ] ] }
+            [ invalid-fortran-type ]
+        } case
+    ] args?dims ;
+
+M: real-complex-type (fortran-arg>c-args)
+    [
+        size>> {
+            {  f [ [ <complex-float>  ] [ drop ] ] }
+            {  8 [ [ <complex-float>  ] [ drop ] ] }
+            { 16 [ [ <complex-double> ] [ drop ] ] }
+            [ invalid-fortran-type ]
+        } case
+    ] args?dims ;
+
+M: double-precision-type (fortran-arg>c-args)
+    [ drop [ <double> ] [ drop ] ] args?dims ;
+
+M: double-complex-type (fortran-arg>c-args)
+    [ drop [ <complex-double> ] [ drop ] ] args?dims ;
+
+M: character-type (fortran-arg>c-args)
+    fix-character-type single-char?
+    [ [ first <char> ] [ drop ] ]
+    [ [ ascii string>alien ] [ length ] ] if ;
+
+M: misc-type (fortran-arg>c-args)
+    drop [ ] [ drop ] ;
+
+GENERIC: (fortran-result>) ( type -- quots )
+
+: result?dims ( type quot -- quot )
+    [ dup dims>> [ drop { [ ] } ] ] dip if ; inline
+
+M: integer-type (fortran-result>)
+    [ size>> {
+        { f [ { [ *int      ] } ] }
+        { 1 [ { [ *char     ] } ] }
+        { 2 [ { [ *short    ] } ] }
+        { 4 [ { [ *int      ] } ] }
+        { 8 [ { [ *longlong ] } ] }
+        [ invalid-fortran-type ]
+    } case ] result?dims ;
+
+M: logical-type (fortran-result>)
+    [ call-next-method first [ zero? not ] append 1array ] result?dims ;
+
+M: real-type (fortran-result>)
+    [ size>> {
+        { f [ { [ *float  ] } ] }
+        { 4 [ { [ *float  ] } ] }
+        { 8 [ { [ *double ] } ] }
+        [ invalid-fortran-type ]
+    } case ] result?dims ;
+
+M: real-complex-type (fortran-result>)
+    [ size>> {
+        {  f [ { [ *complex-float  ] } ] }
+        {  8 [ { [ *complex-float  ] } ] }
+        { 16 [ { [ *complex-double ] } ] }
+        [ invalid-fortran-type ]
+    } case ] result?dims ;
+
+M: double-precision-type (fortran-result>)
+    [ drop { [ *double ] } ] result?dims ;
+
+M: double-complex-type (fortran-result>)
+    [ drop { [ *complex-double ] } ] result?dims ;
+
+M: character-type (fortran-result>)
+    fix-character-type single-char?
+    [ { [ *char 1string ] } ]
+    [ { [ ] [ ascii alien>nstring ] } ] if ;
+
+M: misc-type (fortran-result>)
+    drop { [ ] } ;
+
+GENERIC: (<fortran-result>) ( type -- quot )
+
+M: fortran-type (<fortran-result>) 
+    (fortran-type>c-type) \ <c-object> [ ] 2sequence ;
+
+M: character-type (<fortran-result>)
+    fix-character-type dims>> product dup
+    [ \ <byte-array> ] dip [ ] 3sequence ;
+
+: [<fortran-result>] ( return parameters -- quot )
+    [ parse-fortran-type ] dip
+    over returns-by-value?
+    [ 2drop [ ] ]
+    [ [ (<fortran-result>) ] [ length \ ndip [ ] 3sequence ] bi* ] if ;
+
+: [fortran-args>c-args] ( parameters -- quot )
+    [ [ ] ] [
+        [ parse-fortran-type (fortran-arg>c-args) 2array ] map flip first2
+        [ [ \ spread [ ] 2sequence ] bi@ 2array ] [ length ] bi 
+        \ ncleave [ ] 3sequence
+    ] if-empty ;
+
+:: [fortran-invoke] ( [args>args] return library function parameters -- [args>args] quot ) 
+    return parameters fortran-sig>c-sig :> c-parameters :> c-return
+    function fortran-name>symbol-name :> c-function
+    [args>args] 
+    c-return library c-function c-parameters \ alien-invoke
+    5 [ ] nsequence
+    c-parameters length \ nkeep
+    [ ] 3sequence ;
+
+: [fortran-out-param>] ( parameter -- quot )
+    parse-fortran-type
+    [ (fortran-result>) ] [ out?>> ] bi
+    [ ] [ [ drop [ drop ] ] map ] if ;
+
+: [fortran-return>] ( return -- quot )
+    parse-fortran-type {
+        { [ dup not ] [ drop { } ] }
+        { [ dup returns-by-value? ] [ drop { [ ] } ] }
+        [ (fortran-result>) ]
+    } cond ;
+
+: letters ( -- seq ) CHAR: a CHAR: z [a,b] ;
+
+: (shuffle-map) ( return parameters -- ret par )
+    [
+        fortran-ret-type>c-type length swap "void" = [ 1+ ] unless
+        letters swap head [ "ret" swap suffix ] map
+    ] [
+        [ fortran-arg-type>c-type nip length 1+ ] map letters swap zip
+        [ first2 letters swap head [ "" 2sequence ] with map ] map concat
+    ] bi* ;
+
+: (fortran-in-shuffle) ( ret par -- seq )
+    [ [ second ] bi@ <=> ] sort append ;
+
+: (fortran-out-shuffle) ( ret par -- seq )
+    append ;
+
+: [fortran-result-shuffle] ( return parameters -- quot )
+    (shuffle-map) [ (fortran-in-shuffle) ] [ (fortran-out-shuffle) ] 2bi <effect>
+    \ shuffle-effect [ ] 2sequence ;
+
+: [fortran-results>] ( return parameters -- quot )
+    [ [fortran-result-shuffle] ]
+    [ drop [fortran-return>] ]
+    [ nip [ [fortran-out-param>] ] map concat ] 2tri
+    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) ;
+
+: fortran-arg-type>c-type ( fortran-type -- c-type added-args )
+    parse-fortran-type
+    [ (fortran-type>c-type) c-type>pointer ]
+    [ added-c-args ] bi ;
+: fortran-ret-type>c-type ( fortran-type -- c-type added-args )
+    parse-fortran-type dup returns-by-value?
+    [ (fortran-ret-type>c-type) { } ] [
+        "void" swap 
+        [ added-c-args ] [ (fortran-type>c-type) c-type>pointer ] bi prefix
+    ] if ;
+
+: fortran-arg-types>c-types ( fortran-types -- c-types )
+    [ length <vector> 1 <vector> ] keep
+    [ fortran-arg-type>c-type swapd [ suffix! ] [ append! ] 2bi* ] each
+    append >array ;
+
+: fortran-sig>c-sig ( fortran-return fortran-args -- c-return c-args )
+    [ fortran-ret-type>c-type ] [ fortran-arg-types>c-types ] bi* append ;
+
+: fortran-record>c-struct ( record -- struct )
+    [ first2 [ fortran-type>c-type ] [ >lower ] bi* 2array ] map ;
+
+: define-fortran-record ( name vocab fields -- )
+    [ >lower ] [ ] [ fortran-record>c-struct ] tri* define-struct ;
+
+: RECORD: scan in get parse-definition define-fortran-record ; parsing
+
+: set-fortran-abi ( library -- )
+    library-fortran-abis get-global at fortran-abi set ;
+
+: (fortran-invoke) ( return library function parameters -- quot )
+    {
+        [ 2nip [<fortran-result>] ]
+        [ nip nip nip [fortran-args>c-args] ]
+        [ [fortran-invoke] ]
+        [ 2nip [fortran-results>] ]
+    } 4 ncleave 4 nappend ;
+
+MACRO: fortran-invoke ( return library function parameters -- )
+    { [ 2drop nip set-fortran-abi ] [ (fortran-invoke) ] } 4 ncleave ;
+
+:: define-fortran-function ( return library function parameters -- )
+    function create-in dup reset-generic 
+    return library function parameters return [ "void" ] unless* parse-arglist
+    [ \ fortran-invoke 5 [ ] nsequence ] dip define-declared ;
+
+: SUBROUTINE: 
+    f "c-library" get scan ";" parse-tokens
+    [ "()" subseq? not ] filter define-fortran-function ; parsing
+
+: FUNCTION:
+    scan "c-library" get scan ";" parse-tokens
+    [ "()" subseq? not ] filter define-fortran-function ; parsing
+
+: LIBRARY:
+    scan
+    [ "c-library" set ]
+    [ set-fortran-abi ] bi  ; parsing
+
diff --git a/basis/alien/fortran/summary.txt b/basis/alien/fortran/summary.txt
new file mode 100644 (file)
index 0000000..8ed8b0c
--- /dev/null
@@ -0,0 +1 @@
+GNU Fortran/G77/F2C alien interface
diff --git a/basis/alien/fortran/tags.txt b/basis/alien/fortran/tags.txt
new file mode 100644 (file)
index 0000000..2a9b5de
--- /dev/null
@@ -0,0 +1,2 @@
+fortran
+ffi
index f5537fa23994d2320f98af4f5859d00845191231..047768344279796f1c98ca005f9f4b78f6a11b6a 100644 (file)
@@ -58,10 +58,7 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
 : define-getter ( type spec -- )
     [ set-reader-props ] keep
     [ reader>> ]
-    [
-        type>>
-        [ c-getter ] [ c-type-boxer-quot ] bi append
-    ]
+    [ type>> c-type-getter-boxer ]
     [ ] tri
     (( c-ptr -- value )) define-struct-slot-word ;
 
old mode 100644 (file)
new mode 100755 (executable)
index ec0c01c..8bc570c
@@ -42,3 +42,18 @@ C-UNION: barx
     [ ] [ \ foox-x "help" get execute ] unit-test
     [ ] [ \ set-foox-x "help" get execute ] unit-test
 ] when
+
+C-STRUCT: nested
+    { "int" "x" } ;
+
+C-STRUCT: nested-2
+    { "nested" "y" } ;
+
+[ 4 ] [
+    "nested-2" <c-object>
+    "nested" <c-object>
+    4 over set-nested-x
+    over set-nested-2-y
+    nested-2-y
+    nested-x
+] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index d9ed53d..ec90806
@@ -1,15 +1,26 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays generic hashtables kernel kernel.private
+USING: accessors arrays assocs generic hashtables kernel kernel.private
 math namespaces parser sequences strings words libc fry
-alien.c-types alien.structs.fields cpu.architecture math.order ;
+alien.c-types alien.structs.fields cpu.architecture math.order
+quotations byte-arrays ;
 IN: alien.structs
 
-TUPLE: struct-type size align fields boxer-quot unboxer-quot getter setter ;
+TUPLE: struct-type
+size
+align
+fields
+{ boxer-quot callable }
+{ unboxer-quot callable }
+{ getter callable }
+{ setter callable }
+return-in-registers? ;
+
+M: struct-type c-type ;
 
 M: struct-type heap-size size>> ;
 
-M: struct-type c-type-class drop object ;
+M: struct-type c-type-class drop byte-array ;
 
 M: struct-type c-type-align align>> ;
 
@@ -29,7 +40,7 @@ M: struct-type box-parameter
     [ %box-large-struct ] [ box-parameter ] if-value-struct ;
 
 : if-small-struct ( c-type true false -- ? )
-    [ dup struct-small-enough? ] 2dip '[ f swap @ ] if ; inline
+    [ dup return-struct-in-registers? ] 2dip '[ f swap @ ] if ; inline
 
 M: struct-type unbox-return
     [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ;
@@ -68,3 +79,8 @@ M: struct-type stack-size
     [ expand-constants ] map
     [ [ heap-size ] [ max ] map-reduce ] keep
     compute-struct-align f (define-struct) ;
+
+: offset-of ( field struct -- offset )
+    c-types get at fields>> 
+    [ name>> = ] with find nip offset>> ;
+
index f1ba71ce1e02861bd79af83aeaff13b9639636b0..3da22e09d65854b49ea65cb8869133da7bef547c 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types accessors math alien.accessors kernel
-kernel.private locals sequences sequences.private byte-arrays
+kernel.private sequences sequences.private byte-arrays
 parser prettyprint.custom fry ;
 IN: bit-arrays
 
@@ -70,16 +70,15 @@ M: bit-array byte-length length 7 + -3 shift ;
 
 : ?{ \ } [ >bit-array ] parse-literal ; parsing
 
-:: integer>bit-array ( n -- bit-array ) 
-    n zero? [ 0 <bit-array> ] [
-        [let | out [ n log2 1+ <bit-array> ] i! [ 0 ] n'! [ n ] |
-            [ n' zero? ] [
-                n' out underlying>> i set-alien-unsigned-1
-                n' -8 shift n'!
-                i 1+ i!
-            ] [ ] until
-            out
-        ]
+: integer>bit-array ( n -- bit-array )
+    dup 0 = [
+        <bit-array>
+    ] [
+        [ log2 1+ <bit-array> 0 ] keep
+        [ dup 0 = ] [
+            [ pick underlying>> pick set-alien-unsigned-1 ] keep
+            [ 1+ ] [ -8 shift ] bi*
+        ] [ ] until 2drop
     ] if ;
 
 : bit-array>integer ( bit-array -- n )
diff --git a/basis/bitstreams/authors.txt b/basis/bitstreams/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/bitstreams/bitstreams-tests.factor b/basis/bitstreams/bitstreams-tests.factor
new file mode 100644 (file)
index 0000000..d55910b
--- /dev/null
@@ -0,0 +1,27 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors bitstreams io io.streams.string kernel tools.test
+grouping compression.lzw multiline byte-arrays io.encodings.binary
+io.streams.byte-array ;
+IN: bitstreams.tests
+
+[ 1 t ]
+[ B{ 254 } <string-reader> <bitstream-reader> read-bit ] unit-test
+
+[ 254 8 t ]
+[ B{ 254 } <string-reader> <bitstream-reader> 8 swap read-bits ] unit-test
+
+[ 4095 12 t ]
+[ B{ 255 255 } <string-reader> <bitstream-reader> 12 swap read-bits ] unit-test
+
+[ B{ 254 } ]
+[
+    <string-writer> <bitstream-writer> 254 8 rot
+    [ write-bits ] keep stream>> >byte-array
+] unit-test
+
+[ 255 8 t ]
+[ B{ 255 } binary <byte-reader> <bitstream-reader> 8 swap read-bits ] unit-test
+
+[ 255 8 f ]
+[ B{ 255 } binary <byte-reader> <bitstream-reader> 9 swap read-bits ] unit-test
diff --git a/basis/bitstreams/bitstreams.factor b/basis/bitstreams/bitstreams.factor
new file mode 100644 (file)
index 0000000..7113b65
--- /dev/null
@@ -0,0 +1,96 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors byte-arrays destructors fry io kernel locals
+math sequences ;
+IN: bitstreams
+
+TUPLE: bitstream stream end-of-stream? current-bits #bits disposed ;
+TUPLE: bitstream-reader < bitstream ;
+
+: reset-bitstream ( stream -- stream )
+    0 >>#bits 0 >>current-bits ; inline
+
+: new-bitstream ( stream class -- bitstream )
+    new
+        swap >>stream
+        reset-bitstream ; inline
+
+M: bitstream-reader dispose ( stream -- )
+    stream>> dispose ;
+
+: <bitstream-reader> ( stream -- bitstream )
+    bitstream-reader new-bitstream ; inline
+
+: read-next-byte ( bitstream -- bitstream )
+    dup stream>> stream-read1 [
+        >>current-bits 8 >>#bits
+    ] [
+        0 >>#bits
+        t >>end-of-stream?
+    ] if* ;
+
+: maybe-read-next-byte ( bitstream -- bitstream )
+    dup #bits>> 0 = [ read-next-byte ] when ; inline
+
+: shift-one-bit ( bitstream -- n )
+    [ current-bits>> ] [ #bits>> ] bi 1- neg shift 1 bitand ; inline
+
+: next-bit ( bitstream -- n/f ? )
+    maybe-read-next-byte
+    dup end-of-stream?>> [
+        drop f
+    ] [
+        [ shift-one-bit ]
+        [ [ 1- ] change-#bits maybe-read-next-byte drop ] bi
+    ] if dup >boolean ;
+
+: read-bit ( bitstream -- n ? )
+    dup #bits>> 1 = [
+        [ current-bits>> 1 bitand ]
+        [ read-next-byte drop ] bi t
+    ] [
+        next-bit
+    ] if ; inline
+
+: bits>integer ( seq -- n )
+    0 [ [ 1 shift ] dip bitor ] reduce ; inline
+
+: read-bits ( width bitstream -- n width ? )
+    [
+        '[ _ read-bit drop ] replicate
+        [ f = ] trim-tail
+        [ bits>integer ] [ length ] bi
+    ] 2keep drop over = ;
+
+TUPLE: bitstream-writer < bitstream ;
+
+: <bitstream-writer> ( stream -- bitstream )
+    bitstream-writer new-bitstream ; inline
+
+: write-bit ( n bitstream -- )
+    [ 1 shift bitor ] change-current-bits
+    [ 1+ ] change-#bits
+    dup #bits>> 8 = [
+        [ [ current-bits>> ] [ stream>> stream-write1 ] bi ]
+        [ reset-bitstream drop ] bi
+    ] [
+        drop
+    ] if ; inline
+
+ERROR: invalid-bit-width n ;
+
+:: write-bits ( n width bitstream -- )
+    n 0 < [ n invalid-bit-width ] when
+    n 0 = [
+        width [ 0 bitstream write-bit ] times
+    ] [
+        width n log2 1+ dup :> n-length - [ 0 bitstream write-bit ] times
+        n-length [
+            n-length swap - 1- neg n swap shift 1 bitand
+            bitstream write-bit
+        ] each
+    ] if ;
+
+: flush-bits ( bitstream -- ) stream>> stream-flush ;
+
+: bitstream-output ( bitstream -- bytes ) stream>> >byte-array ;
index 3856382ffbb4b2b999c8e7d75821ef258d792d9f..835c39c171d3d4fa628d177b20aaab9aea617d91 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax io io.files io.pathnames ;
+USING: help.markup help.syntax io io.files io.pathnames strings ;
 IN: bootstrap.image
 
 ARTICLE: "bootstrap.image" "Bootstrapping new images"
@@ -14,7 +14,7 @@ $nl
 ABOUT: "bootstrap.image"
 
 HELP: make-image
-{ $values { "arch" "a string" } }
+{ $values { "arch" string } }
 { $description "Creates a bootstrap image from sources, where " { $snippet "architecture" } " is one of the following:"
-{ $code "x86.32" "x86.64" "ppc" "arm" }
+{ $code "x86.32" "unix-x86.64" "winnt-x86.64" "macosx-ppc" "linux-ppc" }
 "The new image file is written to the " { $link resource-path } " and is named " { $snippet "boot." { $emphasis "architecture" } ".image" } "." } ;
diff --git a/basis/call/call-docs.factor b/basis/call/call-docs.factor
new file mode 100644 (file)
index 0000000..463bfda
--- /dev/null
@@ -0,0 +1,32 @@
+! Copyright (C) 2009 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax quotations effects words ;
+IN: call
+
+ABOUT: "call"
+
+ARTICLE: "call" "Calling code with known stack effects"
+"The " { $vocab-link "call" } " vocabulary allows for arbitrary quotations to be called from code accepted by the optimizing compiler. This is done by specifying the stack effect of the quotation literally. It is checked at runtime that the stack effect is accurate."
+{ $subsection POSTPONE: call( }
+{ $subsection POSTPONE: execute( }
+{ $subsection call-effect }
+{ $subsection execute-effect } ;
+
+HELP: call(
+{ $syntax "[ ] call( foo -- bar )" }
+{ $description "Calls the quotation on the top of the stack, asserting that it has the given stack effect. The quotation does not need to be known at compile time." } ;
+
+HELP: call-effect
+{ $values { "quot" quotation } { "effect" effect } }
+{ $description "Given a quotation and a stack effect, calls the quotation, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary quotation which is not required at compile time." } ;
+
+HELP: execute(
+{ $syntax "word execute( foo -- bar )" }
+{ $description "Calls the word on the top of the stack, aserting that it has the given stack effect. The word does not need to be known at compile time." } ;
+
+HELP: execute-effect
+{ $values { "word" word } { "effect" effect } }
+{ $description "Given a word and a stack effect, executes the word, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." } ;
+
+{ execute-effect call-effect } related-words
+{ POSTPONE: call( POSTPONE: execute( } related-words
diff --git a/basis/call/call-tests.factor b/basis/call/call-tests.factor
new file mode 100644 (file)
index 0000000..a2bd11b
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2009 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math tools.test call kernel ;
+IN: call.tests
+
+[ 3 ] [ 1 2 [ + ] call( x y -- z ) ] unit-test
+[ 1 2 [ + ] call( -- z ) ] must-fail
+[ 1 2 [ + ] call( x y -- z a ) ] must-fail
+[ 1 2 3 { 4 } ] [ 1 2 3 4 [ datastack nip ] call( x -- y ) ] unit-test
+[ [ + ] call( x y -- z ) ] must-infer
+
+[ 3 ] [ 1 2 \ + execute( x y -- z ) ] unit-test
+[ 1 2 \ + execute( -- z ) ] must-fail
+[ 1 2 \ + execute( x y -- z a ) ] must-fail
+[ \ + execute( x y -- z ) ] must-infer
diff --git a/basis/call/call.factor b/basis/call/call.factor
new file mode 100644 (file)
index 0000000..9b49acf
--- /dev/null
@@ -0,0 +1,30 @@
+! Copyright (C) 2009 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel macros fry summary sequences generalizations accessors
+continuations effects.parser parser words ;
+IN: call
+
+ERROR: wrong-values values quot length-required ;
+
+M: wrong-values summary
+    drop "Wrong number of values returned from quotation" ;
+
+<PRIVATE
+
+: firstn-safe ( array quot n -- ... )
+    3dup nip swap length = [ nip firstn ] [ wrong-values ] if ; inline
+
+PRIVATE>
+
+MACRO: call-effect ( effect -- quot )
+    [ in>> length ] [ out>> length ] bi
+    '[ [ _ narray ] dip [ with-datastack ] keep _ firstn-safe ] ;
+
+: call(
+    ")" parse-effect parsed \ call-effect parsed ; parsing
+
+: execute-effect ( word effect -- )
+    [ [ execute ] curry ] dip call-effect ; inline
+
+: execute(
+    ")" parse-effect parsed \ execute-effect parsed ; parsing
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 a0b0e89a0d97952070d2748f54d2e7da3b4cb01b..ce66467203ffc52dc76dd44096ac5866d63dce91 100644 (file)
@@ -5,7 +5,7 @@ continuations combinators compiler compiler.alien kernel math
 namespaces make parser quotations sequences strings words
 cocoa.runtime io macros memoize io.encodings.utf8
 effects libc libc.private parser lexer init core-foundation fry
-generalizations specialized-arrays.direct.alien ;
+generalizations specialized-arrays.direct.alien call ;
 IN: cocoa.messages
 
 : make-sender ( method function -- quot )
@@ -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,11 +79,11 @@ 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 ] initialize
 
 : (objc-class) ( name word -- class )
     2dup execute dup [ 2nip ] [
-        drop over class-init-hooks get at [ assert-depth ] when*
+        drop over class-init-hooks get at [ call( -- ) ] when*
         2dup execute dup [ 2nip ] [
             2drop "No such class: " prepend throw
         ] if
index 69a3a821e5892750cf2085162b2b88139742056e..1cca697dde24d838fb075b8b01f766b9bc152000 100644 (file)
@@ -44,4 +44,6 @@ IN: combinators.smart.tests
 
 \ nested-smart-combo-test must-infer
 
-[ { { 1 2 } { 3 4 } } ] [ nested-smart-combo-test ] unit-test
\ No newline at end of file
+[ { { 1 2 } { 3 4 } } ] [ nested-smart-combo-test ] unit-test
+
+[ 14 ] [ [ 1 2 3 ] [ sq ] [ + ] map-reduce-outputs ] unit-test
\ No newline at end of file
index e93d84e394a0edb9f6527a75da2d198ab4cfc426..e7bdd75ced39028508cd709d1c41d53ae75772c3 100644 (file)
@@ -21,6 +21,12 @@ MACRO: reduce-outputs ( quot operation -- newquot )
 : sum-outputs ( quot -- n )
     [ + ] reduce-outputs ; inline
 
+MACRO: map-reduce-outputs ( quot mapper reducer -- newquot )
+    [ dup infer out>> ] 2dip
+    [ swap '[ _ _ napply ] ]
+    [ [ 1 [-] ] dip n*quot ] bi-curry* bi
+    '[ @ @ @ ] ;
+
 MACRO: append-outputs-as ( quot exemplar -- newquot )
     [ dup infer out>> ] dip '[ @ _ _ nappend-as ] ;
 
index 4a41014ab2c9ac7bae447d4b757c5fe4cd243893..59901cf79a8f3c22a03131c0fcb1474ac609a2da 100644 (file)
@@ -5,7 +5,7 @@ alien.c-types alien.structs cpu.architecture ;
 IN: compiler.alien
 
 : large-struct? ( ctype -- ? )
-    dup c-struct? [ struct-small-enough? not ] [ drop f ] if ;
+    dup c-struct? [ return-struct-in-registers? not ] [ drop f ] if ;
 
 : alien-parameters ( params -- seq )
     dup parameters>>
index f3b3238b4e72bb7080a51d48749ef0a8244d4f06..06d8d4f73314f588ef3c9c456b3031f4d81113b5 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel arrays sequences math math.order
+USING: accessors kernel arrays sequences math math.order call
 math.partial-dispatch generic generic.standard generic.math
 classes.algebra classes.union sets quotations assocs combinators
 words namespaces continuations classes fry combinators.smart
@@ -181,8 +181,9 @@ SYMBOL: history
     "custom-inlining" word-prop ;
 
 : inline-custom ( #call word -- ? )
-    [ dup 1array ] [ "custom-inlining" word-prop ] bi* with-datastack
-    first object swap eliminate-dispatch ;
+    [ dup ] [ "custom-inlining" word-prop ] bi*
+    call( #call -- word/quot/f )
+    object swap eliminate-dispatch ;
 
 : inline-instance-check ( #call word -- ? )
     over in-d>> second value-info literal>> dup class?
index ec4ced8c9f359a37fdebc7947aae7e4dc06b7010..31faaef480a84ef380b64f369827ebfc47103d74 100644 (file)
@@ -24,4 +24,4 @@ IN: compiler.utilities
 
 SYMBOL: yield-hook
 
-yield-hook global [ [ ] or ] change-at
+yield-hook [ [ ] ] initialize
diff --git a/basis/compression/lzw/authors.txt b/basis/compression/lzw/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/compression/lzw/lzw-tests.factor b/basis/compression/lzw/lzw-tests.factor
new file mode 100644 (file)
index 0000000..698e35d
--- /dev/null
@@ -0,0 +1,4 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors tools.test compression.lzw ;
+IN: compression.lzw.tests
diff --git a/basis/compression/lzw/lzw.factor b/basis/compression/lzw/lzw.factor
new file mode 100644 (file)
index 0000000..6724847
--- /dev/null
@@ -0,0 +1,204 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs bitstreams byte-vectors combinators io
+io.encodings.binary io.streams.byte-array kernel math sequences
+vectors ;
+IN: compression.lzw
+
+CONSTANT: clear-code 256
+CONSTANT: end-of-information 257
+
+TUPLE: lzw input output end-of-input? table count k omega omega-k #bits
+code old-code ;
+
+SYMBOL: table-full
+
+ERROR: index-too-big n ;
+
+: lzw-bit-width ( n -- n' )
+    {
+        { [ dup 510 <= ] [ drop 9 ] }
+        { [ dup 1022 <= ] [ drop 10 ] }
+        { [ dup 2046 <= ] [ drop 11 ] }
+        { [ dup 4094 <= ] [ drop 12 ] }
+        [ drop table-full ]
+    } cond ;
+
+: lzw-bit-width-compress ( lzw -- n )
+    count>> lzw-bit-width ;
+
+: lzw-bit-width-uncompress ( lzw -- n )
+    table>> length lzw-bit-width ;
+
+: initial-compress-table ( -- assoc )
+    258 iota [ [ 1vector ] keep ] H{ } map>assoc ;
+
+: initial-uncompress-table ( -- seq )
+    258 iota [ 1vector ] V{ } map-as ;
+
+: reset-lzw ( lzw -- lzw )
+    257 >>count
+    V{ } clone >>omega
+    V{ } clone >>omega-k
+    9 >>#bits ;
+
+: reset-lzw-compress ( lzw -- lzw )
+    f >>k
+    initial-compress-table >>table reset-lzw ;
+
+: reset-lzw-uncompress ( lzw -- lzw )
+    initial-uncompress-table >>table reset-lzw ;
+
+: <lzw-compress> ( input -- obj )
+    lzw new
+        swap >>input
+        binary <byte-writer> <bitstream-writer> >>output
+        reset-lzw-compress ;
+
+: <lzw-uncompress> ( input -- obj )
+    lzw new
+        swap >>input
+        BV{ } clone >>output
+        reset-lzw-uncompress ;
+
+: push-k ( lzw -- lzw )
+    [ ]
+    [ k>> ]
+    [ omega>> clone [ push ] keep ] tri >>omega-k ;
+
+: omega-k-in-table? ( lzw -- ? )
+    [ omega-k>> ] [ table>> ] bi key? ;
+
+ERROR: not-in-table ;
+
+: write-output ( lzw -- )
+    [
+        [ omega>> ] [ table>> ] bi at* [ not-in-table ] unless
+    ] [
+        [ lzw-bit-width-compress ]
+        [ output>> write-bits ] bi
+    ] bi ;
+
+: omega-k>omega ( lzw -- lzw )
+    dup omega-k>> clone >>omega ;
+
+: k>omega ( lzw -- lzw )
+    dup k>> 1vector >>omega ;
+
+: add-omega-k ( lzw -- )
+    [ [ 1+ ] change-count count>> ]
+    [ omega-k>> clone ]
+    [ table>> ] tri set-at ;
+
+: lzw-compress-char ( lzw k -- )
+    >>k push-k dup omega-k-in-table? [
+        omega-k>omega drop
+    ] [
+        [ write-output ]
+        [ add-omega-k ]
+        [ k>omega drop ] tri
+    ] if ;
+
+: (lzw-compress-chars) ( lzw -- )
+    dup lzw-bit-width-compress table-full = [
+        drop
+    ] [
+        dup input>> stream-read1
+        [ [ lzw-compress-char ] [ drop (lzw-compress-chars) ] 2bi ]
+        [ t >>end-of-input? drop ] if*
+    ] if ;
+
+: lzw-compress-chars ( lzw -- )
+    {
+        ! [ [ clear-code lzw-compress-char ] [ drop ] bi ] ! reset-lzw-compress drop ] bi ]
+        [
+            [ clear-code ] dip
+            [ lzw-bit-width-compress ]
+            [ output>> write-bits ] bi
+        ]
+        [ (lzw-compress-chars) ]
+        [
+            [ k>> ]
+            [ lzw-bit-width-compress ]
+            [ output>> write-bits ] tri
+        ]
+        [
+            [ end-of-information ] dip
+            [ lzw-bit-width-compress ]
+            [ output>> write-bits ] bi
+        ]
+        [ ]
+    } cleave dup end-of-input?>> [ drop ] [ lzw-compress-chars ] if ;
+
+: lzw-compress ( byte-array -- seq )
+    binary <byte-reader> <lzw-compress>
+    [ lzw-compress-chars ] [ output>> stream>> ] bi ;
+
+: lookup-old-code ( lzw -- vector )
+    [ old-code>> ] [ table>> ] bi nth ;
+
+: lookup-code ( lzw -- vector )
+    [ code>> ] [ table>> ] bi nth ;
+
+: code-in-table? ( lzw -- ? )
+    [ code>> ] [ table>> length ] bi < ;
+
+: code>old-code ( lzw -- lzw )
+    dup code>> >>old-code ;
+
+: write-code ( lzw -- )
+    [ lookup-code ] [ output>> ] bi push-all ;
+
+: add-to-table ( seq lzw -- ) table>> push ;
+
+: lzw-read ( lzw -- lzw n )
+    [ ] [ lzw-bit-width-uncompress ] [ input>> ] tri read-bits 2drop ;
+
+DEFER: lzw-uncompress-char
+: handle-clear-code ( lzw -- )
+    reset-lzw-uncompress
+    lzw-read dup end-of-information = [
+        2drop
+    ] [
+        >>code
+        [ write-code ]
+        [ code>old-code ] bi
+        lzw-uncompress-char
+    ] if ;
+
+: handle-uncompress-code ( lzw -- lzw )
+    dup code-in-table? [
+        [ write-code ]
+        [
+            [
+                [ lookup-old-code ]
+                [ lookup-code first ] bi suffix
+            ] [ add-to-table ] bi
+        ] [ code>old-code ] tri
+    ] [
+        [
+            [ lookup-old-code dup first suffix ] keep
+            [ output>> push-all ] [ add-to-table ] 2bi
+        ] [ code>old-code ] bi
+    ] if ;
+    
+: lzw-uncompress-char ( lzw -- )
+    lzw-read [
+        >>code
+        dup code>> end-of-information = [
+            drop
+        ] [
+            dup code>> clear-code = [
+                handle-clear-code
+            ] [
+                handle-uncompress-code
+                lzw-uncompress-char
+            ] if
+        ] if
+    ] [
+        drop
+    ] if* ;
+
+: lzw-uncompress ( seq -- byte-array )
+    binary <byte-reader> <bitstream-reader>
+    <lzw-uncompress> [ lzw-uncompress-char ] [ output>> ] bi ;
diff --git a/basis/compression/zlib/authors.txt b/basis/compression/zlib/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/compression/zlib/ffi/authors.txt b/basis/compression/zlib/ffi/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/compression/zlib/ffi/ffi.factor b/basis/compression/zlib/ffi/ffi.factor
new file mode 100755 (executable)
index 0000000..d369c22
--- /dev/null
@@ -0,0 +1,30 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.syntax combinators system ;
+IN: compression.zlib.ffi
+
+<< "zlib" {
+    { [ os winnt? ] [ "zlib1.dll" ] }
+    { [ os macosx? ] [ "libz.dylib" ] }
+    { [ os unix? ] [ "libz.so" ] }
+} cond "cdecl" add-library >>
+
+LIBRARY: zlib
+
+CONSTANT: Z_OK 0
+CONSTANT: Z_STREAM_END 1
+CONSTANT: Z_NEED_DICT 2
+CONSTANT: Z_ERRNO -1
+CONSTANT: Z_STREAM_ERROR -2
+CONSTANT: Z_DATA_ERROR -3
+CONSTANT: Z_MEM_ERROR -4
+CONSTANT: Z_BUF_ERROR -5
+CONSTANT: Z_VERSION_ERROR -6
+
+TYPEDEF: void Bytef
+TYPEDEF: ulong uLongf
+TYPEDEF: ulong uLong
+
+FUNCTION: int compress ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen ) ;
+FUNCTION: int compress2 ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen, int level ) ;
+FUNCTION: int uncompress ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen ) ;
diff --git a/basis/compression/zlib/zlib-tests.factor b/basis/compression/zlib/zlib-tests.factor
new file mode 100755 (executable)
index 0000000..1baeba7
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel tools.test compression.zlib classes ;
+IN: compression.zlib.tests
+
+: compress-me ( -- byte-array ) B{ 1 2 3 4 5 } ;
+
+[ t ] [ compress-me [ compress uncompress ] keep = ] unit-test
+[ t ] [ compress-me compress compressed instance? ] unit-test
diff --git a/basis/compression/zlib/zlib.factor b/basis/compression/zlib/zlib.factor
new file mode 100755 (executable)
index 0000000..7818173
--- /dev/null
@@ -0,0 +1,48 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.c-types alien.syntax byte-arrays combinators
+kernel math math.functions sequences system accessors
+libc ;
+QUALIFIED: compression.zlib.ffi
+IN: compression.zlib
+
+TUPLE: compressed data length ;
+
+: <compressed> ( data length -- compressed )
+    compressed new
+        swap >>length
+        swap >>data ;
+
+ERROR: zlib-failed n string ;
+
+: zlib-error-message ( n -- * )
+    dup compression.zlib.ffi:Z_ERRNO = [
+        drop errno "native libc error"
+    ] [
+        dup {
+            "no error" "libc_error"
+            "stream error" "data error"
+            "memory error" "buffer error" "zlib version error"
+        } ?nth
+    ] if zlib-failed ;
+
+: zlib-error ( n -- )
+    dup compression.zlib.ffi:Z_OK = [ drop ] [ dup zlib-error-message zlib-failed ] if ;
+
+: compressed-size ( byte-array -- n )
+    length 1001/1000 * ceiling 12 + ;
+
+: compress ( byte-array -- compressed )
+    [
+        [ compressed-size <byte-array> dup length <ulong> ] keep [
+            dup length compression.zlib.ffi:compress zlib-error
+        ] 3keep drop *ulong head
+    ] keep length <compressed> ;
+
+: uncompress ( compressed -- byte-array )
+    [
+        length>> [ <byte-array> ] keep <ulong> 2dup
+    ] [
+        data>> dup length
+        compression.zlib.ffi:uncompress zlib-error
+    ] bi *ulong head ;
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
diff --git a/basis/constructors/authors.txt b/basis/constructors/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/constructors/constructors-tests.factor b/basis/constructors/constructors-tests.factor
new file mode 100644 (file)
index 0000000..367f0ad
--- /dev/null
@@ -0,0 +1,21 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test constructors calendar kernel accessors
+combinators.short-circuit ;
+IN: constructors.tests
+
+TUPLE: stock-spread stock spread timestamp ;
+
+CONSTRUCTOR: stock-spread ( stock spread -- stock-spread )
+   now >>timestamp ;
+
+SYMBOL: AAPL
+
+[ t ] [
+    AAPL 1234 <stock-spread>
+    {
+        [ stock>> AAPL eq? ]
+        [ spread>> 1234 = ]
+        [ timestamp>> timestamp? ]
+    } 1&&
+] unit-test
\ No newline at end of file
diff --git a/basis/constructors/constructors.factor b/basis/constructors/constructors.factor
new file mode 100644 (file)
index 0000000..2eab913
--- /dev/null
@@ -0,0 +1,23 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: slots kernel sequences fry accessors parser lexer words
+effects.parser macros ;
+IN: constructors
+
+! An experiment
+
+MACRO: set-slots ( slots -- quot )
+    <reversed> [ setter-word '[ swap _ execute ] ] map [ ] join ;
+
+: construct ( ... class slots -- instance )
+    [ new ] dip set-slots ; inline
+
+: define-constructor ( name class effect body -- )
+    [ [ in>> '[ _ _ construct ] ] dip compose ] [ drop ] 2bi
+    define-declared ;
+
+: CONSTRUCTOR:
+    scan-word [ name>> "<" ">" surround create-in ] keep
+    "(" expect ")" parse-effect
+    parse-definition
+    define-constructor ; parsing
\ No newline at end of file
index 5670110f04dbfc32a1f5037159145b7b7d899d31..2c9675426bc4a8ca6da82ef686b3ac8b97b90907 100644 (file)
@@ -152,7 +152,7 @@ HOOK: %loop-entry cpu ( -- )
 HOOK: small-enough? cpu ( n -- ? )
 
 ! Is this structure small enough to be returned in registers?
-HOOK: struct-small-enough? cpu ( c-type -- ? )
+HOOK: return-struct-in-registers? cpu ( c-type -- ? )
 
 ! Do we pass this struct by value or hidden reference?
 HOOK: value-struct? cpu ( c-type -- ? )
index b177c71d77cd04b9a03b605f5756b3b789a6b287..f245bcb7e12355364e0ec1ad964239a58e669711 100644 (file)
@@ -659,7 +659,7 @@ M: ppc %callback-value ( ctype -- )
 
 M: ppc small-enough? ( n -- ? ) -32768 32767 between? ;
 
-M: ppc struct-small-enough? ( size -- ? ) drop f ;
+M: ppc return-struct-in-registers? ( c-type -- ? ) drop f ;
 
 M: ppc %box-small-struct
     drop "No small structs" throw ;
index affd39ffc576297219e638a5b47738e66eabedec..f881792ac60007440f7815f9800f9c69e6e261b0 100755 (executable)
@@ -48,9 +48,12 @@ M: x86.32 %alien-invoke (CALL) rel-dlsym ;
 
 M: x86.32 %alien-invoke-tail (JMP) rel-dlsym ;
 
-M: x86.32 struct-small-enough? ( size -- ? )
-    heap-size { 1 2 4 8 } member?
-    os { linux netbsd solaris } member? not and ;
+M: x86.32 return-struct-in-registers? ( c-type -- ? )
+    c-type
+    [ return-in-registers?>> ]
+    [ heap-size { 1 2 4 8 } member? ] bi
+    os { linux netbsd solaris } member? not
+    and or ;
 
 : struct-return@ ( n -- operand )
     [ next-stack@ ] [ stack-frame get params>> stack@ ] if* ;
index f5fb5b9640c3f1eb16be0fd3428eda6dbf55dc80..eea960d03dba6fe2e851acfe8fb123c7af286234 100644 (file)
@@ -44,7 +44,7 @@ M: struct-type flatten-value-type ( type -- seq )
         flatten-small-struct
     ] if ;
 
-M: x86.64 struct-small-enough? ( size -- ? )
+M: x86.64 return-struct-in-registers? ( c-type -- ? )
     heap-size 2 cells <= ;
 
 M: x86.64 dummy-stack-params? f ;
index 4c6af6c1e71242074560fe7893bca715210f9e2c..8091be65ae49c31cef64b2cf2d098a56b3e99609 100644 (file)
@@ -10,7 +10,8 @@ M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ;
 
 M: x86.64 reserved-area-size 4 cells ;
 
-M: x86.64 struct-small-enough? heap-size { 1 2 4 8 } member? ;
+M: x86.64 return-struct-in-registers? ( c-type -- ? )
+    heap-size { 1 2 4 8 } member? ;
 
 M: x86.64 value-struct? heap-size { 1 2 4 8 } member? ;
 
index 4d78c2af8605f62add06918fad9ec144a02b0695..6ba8e2d5b8a965b67767fc7400ce751aed0c3892 100644 (file)
@@ -1,14 +1,11 @@
-USING: io.streams.string csv tools.test shuffle kernel strings
+USING: io.streams.string csv tools.test kernel strings
 io.pathnames io.files.unique io.encodings.utf8 io.files
 io.directories ;
 IN: csv.tests
 
 ! I like to name my unit tests
 : named-unit-test ( name output input -- ) 
-  nipd unit-test ; inline
-
-! tests nicked from the wikipedia csv article
-! http://en.wikipedia.org/wiki/Comma-separated_values
+  unit-test drop ; inline
 
 "Fields are separated by commas"
 [ { { "1997" "Ford" "E350" } } ] 
@@ -90,3 +87,5 @@ IN: csv.tests
     { { "writing,some,csv,tests" } } dup "csv-test2-"
     unique-file utf8 [ csv>file ] [ file>csv ] 2bi =
 ] unit-test
+
+[ { { "hello" "" "" "" "goodbye" "" } } ] [ "hello,,\"\",,goodbye," <string-reader> csv ] unit-test
index 152b3dcbba544f354d45c6af70d3485f51e66dde..5902999a7641f69d8f585dfac75ae992be1d937b 100755 (executable)
@@ -46,13 +46,15 @@ DEFER: quoted-field ( -- endchar )
 
 : (row) ( -- sep )
     field , 
-    dup delimiter get = [ drop (row) ] when ;
+    dup delimiter> = [ drop (row) ] when ;
 
 : row ( -- eof? array[string] )
     [ (row) ] { } make ;
 
 : (csv) ( -- )
-    row harvest [ , ] unless-empty [ (csv) ] when ;
+    row
+    dup [ empty? ] all? [ drop ] [ , ] if
+    [ (csv) ] when ;
   
 PRIVATE>
 
@@ -60,7 +62,8 @@ PRIVATE>
     [ row nip ] with-input-stream ;
 
 : csv ( stream -- rows )
-    [ [ (csv) ] { } make ] with-input-stream ;
+    [ [ (csv) ] { } make ] with-input-stream
+    dup peek { "" } = [ but-last ] when ;
 
 : file>csv ( path encoding -- csv )
     <file-reader> csv ;
index 4358d7f3de6d5de9a14f618235b7ac24797e95be..fc407b06bd2f4d81c5c675b8e5f211214e2e881f 100644 (file)
@@ -11,46 +11,46 @@ IN: db.postgresql.ffi
 } cond "cdecl" add-library >>
 
 ! ConnSatusType
-: CONNECTION_OK                     HEX: 0 ; inline
-: CONNECTION_BAD                    HEX: 1 ; inline
-: CONNECTION_STARTED                HEX: 2 ; inline
-: CONNECTION_MADE                   HEX: 3 ; inline
-: CONNECTION_AWAITING_RESPONSE      HEX: 4 ; inline
-: CONNECTION_AUTH_OK                HEX: 5 ; inline
-: CONNECTION_SETENV                 HEX: 6 ; inline
-: CONNECTION_SSL_STARTUP            HEX: 7 ; inline
-: CONNECTION_NEEDED                 HEX: 8 ; inline
+CONSTANT: CONNECTION_OK                     HEX: 0
+CONSTANT: CONNECTION_BAD                    HEX: 1
+CONSTANT: CONNECTION_STARTED                HEX: 2
+CONSTANT: CONNECTION_MADE                   HEX: 3
+CONSTANT: CONNECTION_AWAITING_RESPONSE      HEX: 4
+CONSTANT: CONNECTION_AUTH_OK                HEX: 5
+CONSTANT: CONNECTION_SETENV                 HEX: 6
+CONSTANT: CONNECTION_SSL_STARTUP            HEX: 7
+CONSTANT: CONNECTION_NEEDED                 HEX: 8
 
 ! PostgresPollingStatusType
-: PGRES_POLLING_FAILED              HEX: 0 ; inline
-: PGRES_POLLING_READING             HEX: 1 ; inline
-: PGRES_POLLING_WRITING             HEX: 2 ; inline
-: PGRES_POLLING_OK                  HEX: 3 ; inline
-: PGRES_POLLING_ACTIVE              HEX: 4 ; inline
+CONSTANT: PGRES_POLLING_FAILED              HEX: 0
+CONSTANT: PGRES_POLLING_READING             HEX: 1
+CONSTANT: PGRES_POLLING_WRITING             HEX: 2
+CONSTANT: PGRES_POLLING_OK                  HEX: 3
+CONSTANT: PGRES_POLLING_ACTIVE              HEX: 4
 
 ! ExecStatusType;
-: PGRES_EMPTY_QUERY                 HEX: 0 ; inline
-: PGRES_COMMAND_OK                  HEX: 1 ; inline
-: PGRES_TUPLES_OK                   HEX: 2 ; inline
-: PGRES_COPY_OUT                    HEX: 3 ; inline
-: PGRES_COPY_IN                     HEX: 4 ; inline
-: PGRES_BAD_RESPONSE                HEX: 5 ; inline
-: PGRES_NONFATAL_ERROR              HEX: 6 ; inline
-: PGRES_FATAL_ERROR                 HEX: 7 ; inline
+CONSTANT: PGRES_EMPTY_QUERY                 HEX: 0
+CONSTANT: PGRES_COMMAND_OK                  HEX: 1
+CONSTANT: PGRES_TUPLES_OK                   HEX: 2
+CONSTANT: PGRES_COPY_OUT                    HEX: 3
+CONSTANT: PGRES_COPY_IN                     HEX: 4
+CONSTANT: PGRES_BAD_RESPONSE                HEX: 5
+CONSTANT: PGRES_NONFATAL_ERROR              HEX: 6
+CONSTANT: PGRES_FATAL_ERROR                 HEX: 7
 
 ! PGTransactionStatusType;
-: PQTRANS_IDLE                      HEX: 0 ; inline
-: PQTRANS_ACTIVE                    HEX: 1 ; inline
-: PQTRANS_INTRANS                   HEX: 2 ; inline
-: PQTRANS_INERROR                   HEX: 3 ; inline
-: PQTRANS_UNKNOWN                   HEX: 4 ; inline
+CONSTANT: PQTRANS_IDLE                      HEX: 0
+CONSTANT: PQTRANS_ACTIVE                    HEX: 1
+CONSTANT: PQTRANS_INTRANS                   HEX: 2
+CONSTANT: PQTRANS_INERROR                   HEX: 3
+CONSTANT: PQTRANS_UNKNOWN                   HEX: 4
 
 ! PGVerbosity;
-: PQERRORS_TERSE                    HEX: 0 ; inline
-: PQERRORS_DEFAULT                  HEX: 1 ; inline
-: PQERRORS_VERBOSE                  HEX: 2 ; inline
+CONSTANT: PQERRORS_TERSE                    HEX: 0
+CONSTANT: PQERRORS_DEFAULT                  HEX: 1
+CONSTANT: PQERRORS_VERBOSE                  HEX: 2
 
-: InvalidOid 0 ; inline
+CONSTANT: InvalidOid 0
 
 TYPEDEF: int ConnStatusType
 TYPEDEF: int ExecStatusType 
@@ -348,21 +348,21 @@ FUNCTION: int    PQdsplen ( uchar* s, int encoding ) ;
 FUNCTION: int    PQenv2encoding ( ) ;
 
 ! From git, include/catalog/pg_type.h
-: BOOL-OID 16 ; inline
-: BYTEA-OID 17 ; inline
-: CHAR-OID 18 ; inline
-: NAME-OID 19 ; inline
-: INT8-OID 20 ; inline
-: INT2-OID 21 ; inline
-: INT4-OID 23 ; inline
-: TEXT-OID 23 ; inline
-: OID-OID 26 ; inline
-: FLOAT4-OID 700 ; inline
-: FLOAT8-OID 701 ; inline
-: VARCHAR-OID 1043 ; inline
-: DATE-OID 1082 ; inline
-: TIME-OID 1083 ; inline
-: TIMESTAMP-OID 1114 ; inline
-: TIMESTAMPTZ-OID 1184 ; inline
-: INTERVAL-OID 1186 ; inline
-: NUMERIC-OID 1700 ; inline
+CONSTANT: BOOL-OID 16
+CONSTANT: BYTEA-OID 17
+CONSTANT: CHAR-OID 18
+CONSTANT: NAME-OID 19
+CONSTANT: INT8-OID 20
+CONSTANT: INT2-OID 21
+CONSTANT: INT4-OID 23
+CONSTANT: TEXT-OID 23
+CONSTANT: OID-OID 26
+CONSTANT: FLOAT4-OID 700
+CONSTANT: FLOAT8-OID 701
+CONSTANT: VARCHAR-OID 1043
+CONSTANT: DATE-OID 1082
+CONSTANT: TIME-OID 1083
+CONSTANT: TIMESTAMP-OID 1114
+CONSTANT: TIMESTAMPTZ-OID 1184
+CONSTANT: INTERVAL-OID 1186
+CONSTANT: NUMERIC-OID 1700
index 05114a4deb8128d31a7596011b4b20b623ebecbe..0d50d1ab2c915f5cddb8fa31bca87c3dc23a3676 100644 (file)
@@ -3,7 +3,7 @@
 USING: arrays continuations db io kernel math namespaces
 quotations sequences db.postgresql.ffi alien alien.c-types
 db.types tools.walker ascii splitting math.parser combinators
-libc shuffle calendar.format byte-arrays destructors prettyprint
+libc calendar.format byte-arrays destructors prettyprint
 accessors strings serialize io.encodings.binary io.encodings.utf8
 alien.strings io.streams.byte-array summary present urls
 specialized-arrays.uint specialized-arrays.alien db.private ;
@@ -117,7 +117,7 @@ M: postgresql-result-null summary ( obj -- str )
 
 : pq-get-string ( handle row column -- obj )
     3dup PQgetvalue utf8 alien>string
-    dup empty? [ [ pq-get-is-null f ] dip ? ] [ 3nip ] if ;
+    dup empty? [ [ pq-get-is-null f ] dip ? ] [ [ 3drop ] dip ] if ;
 
 : pq-get-number ( handle row column -- obj )
     pq-get-string dup [ string>number ] when ;
@@ -134,7 +134,7 @@ M: postgresql-malloc-destructor dispose ( obj -- )
 : pq-get-blob ( handle row column -- obj/f )
     [ PQgetvalue ] 3keep 3dup PQgetlength
     dup 0 > [
-        3nip
+        [ 3drop ] dip
         [
             memory>byte-array >string
             0 <uint>
index 495c25ea682add21141a2db21d66b9c1d1f8c723..2730340bfc11c376936e7b19da3989336c47886f 100755 (executable)
@@ -44,11 +44,11 @@ M: retryable execute-statement* ( statement type -- )
     ] bi attempt-all drop ;
 
 : sql-props ( class -- columns table )
-    [ db-columns ] [ db-table ] bi ;
+    [ db-columns ] [ db-table-name ] bi ;
 
 : query-make ( class quot -- statements )
     #! query, input, outputs, secondary queries
-    over unparse "table" set
+    over db-table-name "table-name" set
     [ sql-props ] dip
     [ 0 sql-counter rot with-variable ] curry
     { "" { } { } { } } nmake
index 9f033a1d3c62ad477727c044aa37802581db1200..341995634e1a971cfc0032d6f939a9602489686b 100644 (file)
@@ -13,33 +13,33 @@ IN: db.sqlite.ffi
     } cond "cdecl" add-library >>
 
 ! Return values from sqlite functions
-: SQLITE_OK           0   ; inline ! Successful result
-: SQLITE_ERROR        1   ; inline ! SQL error or missing database
-: SQLITE_INTERNAL     2   ; inline ! An internal logic error in SQLite 
-: SQLITE_PERM         3   ; inline ! Access permission denied 
-: SQLITE_ABORT        4   ; inline ! Callback routine requested an abort 
-: SQLITE_BUSY         5   ; inline ! The database file is locked 
-: SQLITE_LOCKED       6   ; inline ! A table in the database is locked 
-: SQLITE_NOMEM        7   ; inline ! A malloc() failed 
-: SQLITE_READONLY     8   ; inline ! Attempt to write a readonly database 
-: SQLITE_INTERRUPT    9   ; inline ! Operation terminated by sqlite_interrupt() 
-: SQLITE_IOERR       10   ; inline ! Some kind of disk I/O error occurred 
-: SQLITE_CORRUPT     11   ; inline ! The database disk image is malformed 
-: SQLITE_NOTFOUND    12   ; inline ! (Internal Only) Table or record not found 
-: SQLITE_FULL        13   ; inline ! Insertion failed because database is full 
-: SQLITE_CANTOPEN    14   ; inline ! Unable to open the database file 
-: SQLITE_PROTOCOL    15   ; inline ! Database lock protocol error 
-: SQLITE_EMPTY       16   ; inline ! (Internal Only) Database table is empty 
-: SQLITE_SCHEMA      17   ; inline ! The database schema changed 
-: SQLITE_TOOBIG      18   ; inline ! Too much data for one row of a table 
-: SQLITE_CONSTRAINT  19   ; inline ! Abort due to contraint violation 
-: SQLITE_MISMATCH    20   ; inline ! Data type mismatch 
-: SQLITE_MISUSE      21   ; inline ! Library used incorrectly 
-: SQLITE_NOLFS       22   ; inline ! Uses OS features not supported on host 
-: SQLITE_AUTH        23   ; inline ! Authorization denied 
-: SQLITE_FORMAT      24   ; inline ! Auxiliary database format error
-: SQLITE_RANGE       25   ; inline ! 2nd parameter to sqlite3_bind out of range
-: SQLITE_NOTADB      26   ; inline ! File opened that is not a database file
+CONSTANT: SQLITE_OK           0 ! Successful result
+CONSTANT: SQLITE_ERROR        1 ! SQL error or missing database
+CONSTANT: SQLITE_INTERNAL     2 ! An internal logic error in SQLite 
+CONSTANT: SQLITE_PERM         3 ! Access permission denied 
+CONSTANT: SQLITE_ABORT        4 ! Callback routine requested an abort 
+CONSTANT: SQLITE_BUSY         5 ! The database file is locked 
+CONSTANT: SQLITE_LOCKED       6 ! A table in the database is locked 
+CONSTANT: SQLITE_NOMEM        7 ! A malloc() failed 
+CONSTANT: SQLITE_READONLY     8 ! Attempt to write a readonly database 
+CONSTANT: SQLITE_INTERRUPT    9 ! Operation terminated by sqlite_interrupt() 
+CONSTANT: SQLITE_IOERR       10 ! Some kind of disk I/O error occurred 
+CONSTANT: SQLITE_CORRUPT     11 ! The database disk image is malformed 
+CONSTANT: SQLITE_NOTFOUND    12 ! (Internal Only) Table or record not found 
+CONSTANT: SQLITE_FULL        13 ! Insertion failed because database is full 
+CONSTANT: SQLITE_CANTOPEN    14 ! Unable to open the database file 
+CONSTANT: SQLITE_PROTOCOL    15 ! Database lock protocol error 
+CONSTANT: SQLITE_EMPTY       16 ! (Internal Only) Database table is empty 
+CONSTANT: SQLITE_SCHEMA      17 ! The database schema changed 
+CONSTANT: SQLITE_TOOBIG      18 ! Too much data for one row of a table 
+CONSTANT: SQLITE_CONSTRAINT  19 ! Abort due to contraint violation 
+CONSTANT: SQLITE_MISMATCH    20 ! Data type mismatch 
+CONSTANT: SQLITE_MISUSE      21 ! Library used incorrectly 
+CONSTANT: SQLITE_NOLFS       22 ! Uses OS features not supported on host 
+CONSTANT: SQLITE_AUTH        23 ! Authorization denied 
+CONSTANT: SQLITE_FORMAT      24 ! Auxiliary database format error
+CONSTANT: SQLITE_RANGE       25 ! 2nd parameter to sqlite3_bind out of range
+CONSTANT: SQLITE_NOTADB      26 ! File opened that is not a database file
 
 : sqlite-error-messages ( -- seq ) {
     "Successful result"
@@ -72,32 +72,32 @@ IN: db.sqlite.ffi
 } ;
 
 ! Return values from sqlite3_step
-: SQLITE_ROW         100  ; inline
-: SQLITE_DONE        101  ; inline
+CONSTANT: SQLITE_ROW         100
+CONSTANT: SQLITE_DONE        101
 
 ! Return values from the sqlite3_column_type function
-: SQLITE_INTEGER     1 ; inline
-: SQLITE_FLOAT       2 ; inline
-: SQLITE_TEXT        3 ; inline
-: SQLITE_BLOB        4 ; inline
-: SQLITE_NULL        5 ; inline
+CONSTANT: SQLITE_INTEGER     1
+CONSTANT: SQLITE_FLOAT       2
+CONSTANT: SQLITE_TEXT        3
+CONSTANT: SQLITE_BLOB        4
+CONSTANT: SQLITE_NULL        5
 
 ! Values for the 'destructor' parameter of the 'bind' routines. 
-: SQLITE_STATIC      0  ; inline
-: SQLITE_TRANSIENT   -1 ; inline
+CONSTANT: SQLITE_STATIC      0
+CONSTANT: SQLITE_TRANSIENT   -1
 
-: SQLITE_OPEN_READONLY         HEX: 00000001 ; inline
-: SQLITE_OPEN_READWRITE        HEX: 00000002 ; inline
-: SQLITE_OPEN_CREATE           HEX: 00000004 ; inline
-: SQLITE_OPEN_DELETEONCLOSE    HEX: 00000008 ; inline
-: SQLITE_OPEN_EXCLUSIVE        HEX: 00000010 ; inline
-: SQLITE_OPEN_MAIN_DB          HEX: 00000100 ; inline
-: SQLITE_OPEN_TEMP_DB          HEX: 00000200 ; inline
-: SQLITE_OPEN_TRANSIENT_DB     HEX: 00000400 ; inline
-: SQLITE_OPEN_MAIN_JOURNAL     HEX: 00000800 ; inline
-: SQLITE_OPEN_TEMP_JOURNAL     HEX: 00001000 ; inline
-: SQLITE_OPEN_SUBJOURNAL       HEX: 00002000 ; inline
-: SQLITE_OPEN_MASTER_JOURNAL   HEX: 00004000 ; inline
+CONSTANT: SQLITE_OPEN_READONLY         HEX: 00000001
+CONSTANT: SQLITE_OPEN_READWRITE        HEX: 00000002
+CONSTANT: SQLITE_OPEN_CREATE           HEX: 00000004
+CONSTANT: SQLITE_OPEN_DELETEONCLOSE    HEX: 00000008
+CONSTANT: SQLITE_OPEN_EXCLUSIVE        HEX: 00000010
+CONSTANT: SQLITE_OPEN_MAIN_DB          HEX: 00000100
+CONSTANT: SQLITE_OPEN_TEMP_DB          HEX: 00000200
+CONSTANT: SQLITE_OPEN_TRANSIENT_DB     HEX: 00000400
+CONSTANT: SQLITE_OPEN_MAIN_JOURNAL     HEX: 00000800
+CONSTANT: SQLITE_OPEN_TEMP_JOURNAL     HEX: 00001000
+CONSTANT: SQLITE_OPEN_SUBJOURNAL       HEX: 00002000
+CONSTANT: SQLITE_OPEN_MASTER_JOURNAL   HEX: 00004000
 
 TYPEDEF: void sqlite3
 TYPEDEF: void sqlite3_stmt
index 6fb1cd19adccb262b943a4bbad49ccfaa90135e5..5ad4b0c889fc95ab9a9337a276b5035777779403 100644 (file)
@@ -73,3 +73,95 @@ IN: db.sqlite.tests
         "select * from person" sql-query length
     ] with-db
 ] unit-test
+
+! You don't need a primary key
+USING: accessors arrays sorting ;
+TUPLE: things one two ;
+
+things "THINGS" {
+    { "one" "ONE" INTEGER +not-null+ }
+    { "two" "TWO" INTEGER +not-null+ }
+} define-persistent
+
+[ { { 0 0 } { 0 1 } { 1 0 } { 1 1 } } ] [
+    test.db [
+       things create-table
+        0 0 things boa insert-tuple
+        0 1 things boa insert-tuple
+        1 1 things boa insert-tuple
+        1 0 things boa insert-tuple
+        f f things boa select-tuples
+        [ [ one>> ] [ two>> ] bi 2array ] map natural-sort
+       things drop-table
+    ] with-db
+] unit-test
+
+! Tables can have different names than the name of the tuple
+TUPLE: foo slot ;
+C: <foo> foo
+foo "BAR" { { "slot" "SOMETHING" INTEGER +not-null+ } } define-persistent
+
+TUPLE: hi bye try ;
+C: <hi> hi
+hi "HELLO" {
+    { "bye" "BUHBYE" INTEGER { +foreign-id+ foo "SOMETHING" } }
+    { "try" "RETHROW" INTEGER { +foreign-id+ foo "SOMETHING" } }
+} define-persistent
+
+[ T{ foo { slot 1 } } T{ hi { bye 1 } { try 1 } } ] [
+    test.db [
+        foo create-table
+        hi create-table
+        1 <foo> insert-tuple
+        f <foo> select-tuple
+        1 1 <hi> insert-tuple
+        f <hi> select-tuple
+        hi drop-table
+        foo drop-table
+    ] with-db
+] unit-test
+
+[ ] [
+    test.db [
+        hi create-table
+        hi drop-table
+    ] with-db
+] unit-test
+
+TUPLE: show id ;
+TUPLE: user username data ;
+TUPLE: watch show user ;
+
+user "USER" {
+    { "username" "USERNAME" TEXT +not-null+ +user-assigned-id+ }
+    { "data" "DATA" TEXT }
+} define-persistent
+
+show "SHOW" {
+    { "id" "ID" +db-assigned-id+ }
+} define-persistent
+
+watch "WATCH" {
+    { "user" "USER" TEXT +not-null+
+        { +foreign-id+ user "USERNAME" } +user-assigned-id+ }
+    { "show" "SHOW" BIG-INTEGER +not-null+
+        { +foreign-id+ show "ID" } +user-assigned-id+ }
+} define-persistent
+
+[ T{ user { username "littledan" } { data "foo" } } ] [
+    test.db [
+        user create-table
+        show create-table
+        watch create-table
+        "littledan" "foo" user boa insert-tuple
+        "mark" "bar" user boa insert-tuple
+        show new insert-tuple
+        show new select-tuple
+        "littledan" f user boa select-tuple
+        watch boa insert-tuple
+        watch new select-tuple
+        user>> f user boa select-tuple
+    ] with-db
+] unit-test
+
+[ \ swap ensure-table ] must-fail
index fe3bb64d450626d9658227b839459cdcf18e4893..d006145ea83caad2080978e17d9d2b3e89f998a8 100755 (executable)
@@ -138,11 +138,13 @@ M: sqlite-db-connection create-sql-statement ( class -- statement )
             modifiers 0%
         ] interleave
 
-        ", " 0%
-        find-primary-key
-        "primary key(" 0%
-        [ "," 0% ] [ column-name>> 0% ] interleave
-        "));" 0%
+        find-primary-key [
+            ", " 0%
+            "primary key(" 0%
+            [ "," 0% ] [ column-name>> 0% ] interleave
+            ")" 0%
+        ] unless-empty
+        ");" 0%
     ] query-make ;
 
 M: sqlite-db-connection drop-sql-statement ( class -- statement )
@@ -223,11 +225,11 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : insert-trigger ( -- string )
     [
     <"
-        CREATE TRIGGER fki_${table}_${foreign-table}_id
-        BEFORE INSERT ON ${table}
+        CREATE TRIGGER fki_${table-name}_${foreign-table-name}_id
+        BEFORE INSERT ON ${table-name}
         FOR EACH ROW BEGIN
-            SELECT RAISE(ROLLBACK, 'insert on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"')
-            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
+            SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"')
+            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
         END;
     "> interpolate
     ] with-string-writer ;
@@ -235,12 +237,12 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : insert-trigger-not-null ( -- string )
     [
     <"
-        CREATE TRIGGER fki_${table}_${foreign-table}_id
-        BEFORE INSERT ON ${table}
+        CREATE TRIGGER fki_${table-name}_${foreign-table-name}_id
+        BEFORE INSERT ON ${table-name}
         FOR EACH ROW BEGIN
-            SELECT RAISE(ROLLBACK, 'insert on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"')
+            SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"')
             WHERE NEW.${foreign-table-id} IS NOT NULL
-                AND (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
+                AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
         END;
     "> interpolate
     ] with-string-writer ;
@@ -248,11 +250,11 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : update-trigger ( -- string )
     [
     <"
-        CREATE TRIGGER fku_${table}_${foreign-table}_id
-        BEFORE UPDATE ON ${table}
+        CREATE TRIGGER fku_${table-name}_${foreign-table-name}_id
+        BEFORE UPDATE ON ${table-name}
         FOR EACH ROW BEGIN
-            SELECT RAISE(ROLLBACK, 'update on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"')
-            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
+            SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"')
+            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
         END;
     "> interpolate
     ] with-string-writer ;
@@ -260,12 +262,12 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : update-trigger-not-null ( -- string )
     [
     <"
-        CREATE TRIGGER fku_${table}_${foreign-table}_id
-        BEFORE UPDATE ON ${table}
+        CREATE TRIGGER fku_${table-name}_${foreign-table-name}_id
+        BEFORE UPDATE ON ${table-name}
         FOR EACH ROW BEGIN
-            SELECT RAISE(ROLLBACK, 'update on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"')
+            SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"')
             WHERE NEW.${foreign-table-id} IS NOT NULL
-                AND (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
+                AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
         END;
     "> interpolate
     ] with-string-writer ;
@@ -273,11 +275,11 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : delete-trigger-restrict ( -- string )
     [
     <"
-        CREATE TRIGGER fkd_${table}_${foreign-table}_id
-        BEFORE DELETE ON ${foreign-table}
+        CREATE TRIGGER fkd_${table-name}_${foreign-table-name}_id
+        BEFORE DELETE ON ${foreign-table-name}
         FOR EACH ROW BEGIN
-            SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table}" violates foreign key constraint "fk_${foreign-table}_id"')
-            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL;
+            SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"')
+            WHERE  (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL;
         END;
     "> interpolate
     ] with-string-writer ;
@@ -285,10 +287,10 @@ M: sqlite-db-connection persistent-table ( -- assoc )
 : delete-trigger-cascade ( -- string )
     [
     <"
-        CREATE TRIGGER fkd_${table}_${foreign-table}_id
-        BEFORE DELETE ON ${foreign-table}
+        CREATE TRIGGER fkd_${table-name}_${foreign-table-name}_id
+        BEFORE DELETE ON ${foreign-table-name}
         FOR EACH ROW BEGIN
-            DELETE from ${table} WHERE ${table-id} = OLD.${foreign-table-id};
+            DELETE from ${table-name} WHERE ${table-id} = OLD.${foreign-table-id};
         END;
     "> interpolate
     ] with-string-writer ;
@@ -321,7 +323,7 @@ M: sqlite-db-connection compound ( string seq -- new-string )
         { "default" [ first number>string " " glue ] }
         { "references" [
             [ >reference-string ] keep
-            first2 [ "foreign-table" set ]
+            first2 [ db-table-name "foreign-table-name" set ]
             [ "foreign-table-id" set ] bi*
             create-sqlite-triggers
         ] }
index b5a7db987ac2dd9fb31f1c121ae23007a9e5762b..e39a5977eff9d14192e337dd588de85521adff68 100755 (executable)
@@ -49,7 +49,7 @@ ERROR: no-slot ;
 
 ERROR: not-persistent class ;
 
-: db-table ( class -- object )
+: db-table-name ( class -- object )
     dup "db-table" word-prop [ ] [ not-persistent ] ?if ;
 
 : db-columns ( class -- object )
@@ -165,7 +165,7 @@ ERROR: no-column column ;
 
 : >reference-string ( string pair -- string )
     first2
-    [ [ unparse " " glue ] [ db-columns ] bi ] dip
+    [ [ db-table-name " " glue ] [ db-columns ] bi ] dip
     swap [ column-name>> = ] with find nip
     [ no-column ] unless*
     column-name>> "(" ")" surround append ;
index 53887bd3534f5335ab1526e0e91da49c63813619..d060a3dfe67450042c47370bcb433cbc09fcc052 100644 (file)
@@ -1,9 +1,10 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: parser lexer kernel namespaces sequences definitions
 io.files io.backend io.pathnames io summary continuations
 tools.crossref tools.vocabs prettyprint source-files assocs
-vocabs vocabs.loader splitting accessors ;
+vocabs vocabs.loader splitting accessors debugger prettyprint
+help.topics ;
 IN: editors
 
 TUPLE: no-edit-hook ;
@@ -29,11 +30,21 @@ SYMBOL: edit-hook
     [ (normalize-path) ] dip edit-hook get-global
     [ call ] [ no-edit-hook edit-location ] if* ;
 
+ERROR: cannot-find-source definition ;
+
+M: cannot-find-source error.
+    "Cannot find source for ``" write
+    definition>> pprint-short
+    "''" print ;
+
 : edit ( defspec -- )
-    where [ first2 edit-location ] when* ;
+    dup where
+    [ first2 edit-location ]
+    [ dup word-link? [ name>> edit ] [ cannot-find-source ] if ]
+    ?if ;
 
 : edit-vocab ( name -- )
-    vocab-source-path 1 edit-location ;
+    >vocab-link edit ;
 
 GENERIC: error-file ( error -- file )
 
index a832d6c0a29d951699b45068c37d47c664ba1444..a453a7170423469fa914a9663b43b6c95316d856 100755 (executable)
@@ -1,39 +1,39 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types namespaces io.binary fry
-kernel math ;
+kernel math grouping sequences ;
 IN: endian
 
 SINGLETONS: big-endian little-endian ;
 
-: native-endianness ( -- class )
+: compute-native-endianness ( -- class )
     1 <int> *char 0 = big-endian little-endian ? ;
 
 : >signed ( x n -- y )
     2dup neg 1+ shift 1 = [ 2^ - ] [ drop ] if ;
 
-native-endianness \ native-endianness set-global
+SYMBOL: native-endianness
+native-endianness [ compute-native-endianness ] initialize
 
 SYMBOL: endianness
+endianness [ native-endianness get-global ] initialize
 
-\ native-endianness get-global endianness set-global
-
-HOOK: >native-endian native-endianness ( obj n -- str )
+HOOK: >native-endian native-endianness ( obj n -- bytes )
 
 M: big-endian >native-endian >be ;
 
 M: little-endian >native-endian >le ;
 
-HOOK: unsigned-native-endian> native-endianness ( obj -- str )
+HOOK: unsigned-native-endian> native-endianness ( obj -- bytes )
 
 M: big-endian unsigned-native-endian> be> ;
 
 M: little-endian unsigned-native-endian> le> ;
 
-: signed-native-endian> ( obj n -- str )
+: signed-native-endian> ( obj n -- n' )
     [ unsigned-native-endian> ] dip >signed ;
 
-HOOK: >endian endianness ( obj n -- str )
+HOOK: >endian endianness ( obj n -- bytes )
 
 M: big-endian >endian >be ;
 
@@ -45,13 +45,13 @@ M: big-endian endian> be> ;
 
 M: little-endian endian> le> ;
 
-HOOK: unsigned-endian> endianness ( obj -- str )
+HOOK: unsigned-endian> endianness ( obj -- bytes )
 
 M: big-endian unsigned-endian> be> ;
 
 M: little-endian unsigned-endian> le> ;
 
-: signed-endian> ( obj n -- str )
+: signed-endian> ( obj n -- bytes )
     [ unsigned-endian> ] dip >signed ;
 
 : with-endianness ( endian quot -- )
@@ -65,3 +65,15 @@ M: little-endian unsigned-endian> le> ;
 
 : with-native-endian ( quot -- )
     \ native-endianness get-global swap with-endianness ; inline
+
+: seq>native-endianness ( seq n -- seq' )
+    native-endianness get-global dup endianness get = [
+        2drop
+    ] [
+        [ [ <sliced-groups> ] keep ] dip
+        little-endian = [
+            '[ be> _ >le ] map
+        ] [
+            '[ le> _ >be ] map
+        ] if concat
+    ] if ; inline
index d7d9ae9ebb6437618247a1bb73cca25010b6007e..562fe5a61466c6acbda969723c57145b1a72214c 100644 (file)
@@ -81,11 +81,18 @@ CHLOE: a
 CHLOE: base
     compile-a-url [ [XML <base href=<->/> XML] ] [xml-code] ;
 
+: hidden-nested-fields ( -- xml )
+    nested-forms get " " join f like nested-forms-key
+    hidden-form-field ;
+
+: render-hidden ( for -- xml )
+    [ "," split [ hidden render>xml ] map ] [ f ] if* ;
+
 : compile-hidden-form-fields ( for -- )
     '[
-        _ [ "," split [ hidden render>xml ] map ] [ f ] if*
-        nested-forms get " " join f like nested-forms-key hidden-form-field>xml
-        [ [ modify-form ] each-responder ] with-string-writer <unescaped>
+        _ render-hidden
+        hidden-nested-fields
+        form-modifications
         [XML <div style="display: none;"><-><-><-></div> XML]
     ] [code] ;
 
index f01260c68b02ee5f515670a098be20b02bcee671..c591b848ec0f94eb0a29e7e8c4c035bd844dd96e 100644 (file)
@@ -1,7 +1,7 @@
 IN: furnace.tests
 USING: http http.server.dispatchers http.server.responses
 http.server furnace furnace.utilities tools.test kernel
-namespaces accessors io.streams.string urls ;
+namespaces accessors io.streams.string urls xml.writer ;
 TUPLE: funny-dispatcher < dispatcher ;
 
 : <funny-dispatcher> funny-dispatcher new-dispatcher ;
@@ -31,7 +31,7 @@ M: base-path-check-responder call-responder*
 ] unit-test
 
 [ "<input type=\"hidden\" value=\"&amp;&amp;&amp;\" name=\"foo\"/>" ]
-[ [ "&&&" "foo" hidden-form-field ] with-string-writer ]
+[ "&&&" "foo" hidden-form-field xml>string ]
 unit-test
 
 [ f ] [ <request> request [ referrer ] with-variable ] unit-test
index 3a0d8804efccb95efb98dc9f355f99cbc6dc645b..e7fdaf64d61a4da273b47649e29cc03a8cb01596 100644 (file)
@@ -20,13 +20,13 @@ HELP: each-responder
 { $description "Applies the quotation to each responder involved in processing the current request." } ;
 
 HELP: hidden-form-field
-{ $values { "value" string } { "name" string } }
-{ $description "Renders an HTML hidden form field tag." }
+{ $values { "value" string } { "name" string } { "xml" "an XML chunk" } }
+{ $description "Renders an HTML hidden form field tag as XML." }
 { $notes "This word is used by session management, conversation scope and asides." }
 { $examples
     { $example
-        "USING: furnace.utilities io ;"
-        "\"bar\" \"foo\" hidden-form-field nl"
+        "USING: furnace.utilities io xml.writer ;"
+        "\"bar\" \"foo\" hidden-form-field write-xml nl"
         "<input type=\"hidden\" value=\"bar\" name=\"foo\"/>"
     }
 } ;
@@ -38,7 +38,7 @@ HELP: link-attr
 { $examples "Conversation scope adds attributes to link tags." } ;
 
 HELP: modify-form
-{ $values { "responder" "a responder" } }
+{ $values { "responder" "a responder" } { "xml/f" "an XML chunk or f" } }
 { $contract "Emits hidden form fields using " { $link hidden-form-field } "." }
 { $notes "This word is called by " { $link "html.templates.chloe.tags.form" } "." }
 { $examples "Session management, conversation scope and asides use hidden form fields to pass state." } ;
index a2d4c4d996beae9537599f7867a8df5842e8e238..4fc68f773577b69fefec98889ce77e04bee335f9 100755 (executable)
@@ -77,18 +77,18 @@ GENERIC: link-attr ( tag responder -- )
 
 M: object link-attr 2drop ;
 
-GENERIC: modify-form ( responder -- )
+GENERIC: modify-form ( responder -- xml/f )
 
-M: object modify-form drop ;
+M: object modify-form drop ;
 
-: hidden-form-field>xml ( value name -- xml )
+: form-modifications ( -- xml )
+    [ [ modify-form [ , ] when* ] each-responder ] { } make ;
+
+: hidden-form-field ( value name -- xml )
     over [
         [XML <input type="hidden" value=<-> name=<->/> XML]
     ] [ drop ] if ;
 
-: hidden-form-field ( value name -- )
-    hidden-form-field>xml write-xml ;
-
 : nested-forms-key "__n" ;
 
 : request-params ( request -- assoc )
index 912f69587eddb8e3b37ca0f9b03c820dcf3a8839..376ae5bed20aa0c212d8e825bd7270e19a03bd86 100644 (file)
@@ -30,6 +30,10 @@ HELP: narray
 \r
 { nsequence narray } related-words\r
 \r
+HELP: nsum\r
+{ $values { "n" integer } }\r
+{ $description "Adds the top " { $snippet "n" } " stack values." } ;\r
+\r
 HELP: firstn\r
 { $values { "n" integer } }\r
 { $description "A generalization of " { $link first } ", "\r
@@ -54,7 +58,7 @@ HELP: npick
 "placed on the top of the stack."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 npick .s" "1\n2\n3\n4\n1" }\r
+  { $example "USING: kernel prettyprint generalizations ;" "1 2 3 4 4 npick .s clear" "1\n2\n3\n4\n1" }\r
   "Some core words expressed in terms of " { $link npick } ":"\r
     { $table\r
         { { $link dup } { $snippet "1 npick" } }\r
@@ -71,7 +75,7 @@ HELP: ndup
 "placed on the top of the stack."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 ndup .s" "1\n2\n3\n4\n1\n2\n3\n4" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 ndup .s clear" "1\n2\n3\n4\n1\n2\n3\n4" }\r
   "Some core words expressed in terms of " { $link ndup } ":"\r
     { $table\r
         { { $link dup } { $snippet "1 ndup" } }\r
@@ -87,7 +91,7 @@ HELP: nnip
 "for any number of items."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 3 nnip .s" "4" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 nnip .s clear" "4" }\r
   "Some core words expressed in terms of " { $link nnip } ":"\r
     { $table\r
         { { $link nip } { $snippet "1 nnip" } }\r
@@ -102,7 +106,7 @@ HELP: ndrop
 "for any number of items."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 3 ndrop .s" "1" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 ndrop .s clear" "1" }\r
   "Some core words expressed in terms of " { $link ndrop } ":"\r
     { $table\r
         { { $link drop } { $snippet "1 ndrop" } }\r
@@ -117,7 +121,7 @@ HELP: nrot
 "number of items on the stack. "\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 nrot .s" "2\n3\n4\n1" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 nrot .s clear" "2\n3\n4\n1" }\r
   "Some core words expressed in terms of " { $link nrot } ":"\r
     { $table\r
         { { $link swap } { $snippet "1 nrot" } }\r
@@ -131,7 +135,7 @@ HELP: -nrot
 "number of items on the stack. "\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 -nrot .s" "4\n1\n2\n3" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 -nrot .s clear" "4\n1\n2\n3" }\r
   "Some core words expressed in terms of " { $link -nrot } ":"\r
     { $table\r
         { { $link swap } { $snippet "1 -nrot" } }\r
@@ -147,8 +151,8 @@ HELP: ndip
 "stack. The quotation can consume and produce any number of items."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations kernel prettyprint ;" "1 2 [ dup ] 1 ndip .s" "1\n1\n2" }\r
-  { $example "USING: generalizations kernel prettyprint ;" "1 2 3 [ drop ] 2 ndip .s" "2\n3" }\r
+  { $example "USING: generalizations kernel prettyprint kernel ;" "1 2 [ dup ] 1 ndip .s clear" "1\n1\n2" }\r
+  { $example "USING: generalizations kernel prettyprint kernel ;" "1 2 3 [ drop ] 2 ndip .s clear" "2\n3" }\r
   "Some core words expressed in terms of " { $link ndip } ":"\r
     { $table\r
         { { $link dip } { $snippet "1 ndip" } }\r
@@ -164,7 +168,7 @@ HELP: nslip
 "removed from the stack, the quotation called, and the items restored."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations prettyprint ;" "[ 99 ] 1 2 3 4 5 5 nslip .s" "99\n1\n2\n3\n4\n5" }\r
+  { $example "USING: generalizations kernel prettyprint ;" "[ 99 ] 1 2 3 4 5 5 nslip .s clear" "99\n1\n2\n3\n4\n5" }\r
   "Some core words expressed in terms of " { $link nslip } ":"\r
     { $table\r
         { { $link slip } { $snippet "1 nslip" } }\r
@@ -180,7 +184,7 @@ HELP: nkeep
 "saved, the quotation called, and the items restored."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations kernel prettyprint ;" "1 2 3 4 5 [ drop drop drop drop drop 99 ] 5 nkeep .s" "99\n1\n2\n3\n4\n5" }\r
+  { $example "USING: generalizations kernel prettyprint ;" "1 2 3 4 5 [ drop drop drop drop drop 99 ] 5 nkeep .s clear" "99\n1\n2\n3\n4\n5" }\r
   "Some core words expressed in terms of " { $link nkeep } ":"\r
     { $table\r
         { { $link keep } { $snippet "1 nkeep" } }\r
@@ -238,6 +242,11 @@ HELP: ncleave
     }\r
 } ;\r
 \r
+HELP: nspread\r
+{ $values { "quots" "a sequence of quotations" } { "n" integer } }\r
+{ $description "A generalization of " { $link spread } " that can work for any quotation arity."\r
+} ;\r
+\r
 HELP: mnswap\r
 { $values { "m" integer } { "n" integer } }\r
 { $description "Swaps the top " { $snippet "m" } " stack elements with the " { $snippet "n" } " elements directly underneath." }\r
@@ -250,6 +259,17 @@ HELP: mnswap
     }\r
 } ;\r
 \r
+HELP: nweave\r
+{ $values { "n" integer } }\r
+{ $description "Copies the top " { $snippet "n" } " stack elements underneath each one of the " { $snippet "n" } " elements below." }\r
+{ $examples\r
+  { $example\r
+    "USING: arrays kernel generalizations prettyprint ;"\r
+    "\"e1\" \"e2\" \"o1\" \"o2\" 2 nweave [ 3array ] 3dip 3array 2array ."\r
+    "{ { \"e1\" \"o1\" \"o2\" } { \"e2\" \"o1\" \"o2\" } }"\r
+  }\r
+} ;\r
+\r
 HELP: n*quot\r
 { $values\r
      { "n" integer } { "seq" sequence }\r
@@ -299,18 +319,14 @@ HELP: ntuck
 }\r
 { $description "A generalization of " { $link tuck } " that can work for any stack depth. The top item will be copied and placed " { $snippet "n" } " items down on the stack." } ;\r
 \r
-ARTICLE: "generalizations" "Generalized shuffle words and combinators"\r
-"The " { $vocab-link "generalizations" } " vocabulary defines a number of stack shuffling words and combinators for use in "\r
-"macros where the arity of the input quotations depends on an "\r
-"input parameter."\r
-$nl\r
-"Generalized sequence operations:"\r
+ARTICLE: "sequence-generalizations" "Generalized sequence operations"\r
 { $subsection narray }\r
 { $subsection nsequence }\r
 { $subsection firstn }\r
 { $subsection nappend }\r
-{ $subsection nappend-as }\r
-"Generated stack shuffle operations:"\r
+{ $subsection nappend-as } ;\r
+\r
+ARTICLE: "shuffle-generalizations" "Generalized shuffle words"\r
 { $subsection ndup }\r
 { $subsection npick }\r
 { $subsection nrot }\r
@@ -319,14 +335,28 @@ $nl
 { $subsection ndrop }\r
 { $subsection ntuck }\r
 { $subsection mnswap }\r
-"Generalized combinators:"\r
+{ $subsection nweave } ;\r
+\r
+ARTICLE: "combinator-generalizations" "Generalized combinators"\r
 { $subsection ndip }\r
 { $subsection nslip }\r
 { $subsection nkeep }\r
 { $subsection napply }\r
 { $subsection ncleave }\r
-"Generalized quotation construction:"\r
+{ $subsection nspread } ;\r
+\r
+ARTICLE: "other-generalizations" "Additional generalizations"\r
 { $subsection ncurry } \r
-{ $subsection nwith } ;\r
+{ $subsection nwith }\r
+{ $subsection nsum } ;\r
+\r
+ARTICLE: "generalizations" "Generalized shuffle words and combinators"\r
+"The " { $vocab-link "generalizations" } " vocabulary defines a number of stack shuffling words and combinators for use in "\r
+"macros where the arity of the input quotations depends on an "\r
+"input parameter."\r
+{ $subsection "sequence-generalizations" }\r
+{ $subsection "shuffle-generalizations" }\r
+{ $subsection "combinator-generalizations" }\r
+{ $subsection "other-generalizations" } ;\r
 \r
 ABOUT: "generalizations"\r
index 35e02f08b4c8a16544164bec1240f17d3a0b5885..7ede271d017d0fec830904498e06e664b7bdb913 100644 (file)
@@ -53,3 +53,12 @@ IN: generalizations.tests
 \r
 [ 4 nappend ] must-infer\r
 [ 4 { } nappend-as ] must-infer\r
+\r
+[ 17 ] [ 3 1 3 3 7 5 nsum ] unit-test\r
+{ 4 1 } [ 4 nsum ] must-infer-as\r
+\r
+[ "e1" "o1" "o2" "e2" "o1" "o2" ] [ "e1" "e2" "o1" "o2" 2 nweave ] unit-test\r
+{ 3 5 } [ 2 nweave ] must-infer-as\r
+\r
+[ { 0 1 2 } { 3 5 4 } { 7 8 6 } ]\r
+[ 9 [ ] each { [ 3array ] [ swap 3array ] [ rot 3array ] } 3 nspread ] unit-test
\ No newline at end of file
index 4692fd20db34d4c256e3e66e7dc849b380c1f423..9b2b2456c25e1ae661effa02d74a66225251165d 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2008 Chris Double, Doug Coleman, Eduardo
+! Copyright (C) 2007, 2009 Chris Double, Doug Coleman, Eduardo
 ! Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences sequences.private math combinators
@@ -23,6 +23,9 @@ MACRO: nsequence ( n seq -- )
 MACRO: narray ( n -- )
     '[ _ { } nsequence ] ;
 
+MACRO: nsum ( n -- )
+    1- [ + ] n*quot ;
+
 MACRO: firstn ( n -- )
     dup zero? [ drop [ drop ] ] [
         [ [ '[ [ _ ] dip nth-unsafe ] ] map ]
@@ -70,11 +73,23 @@ MACRO: ncleave ( quots n -- )
     [ '[ _ '[ _ _ nkeep ] ] map [ ] join ] [ '[ _ ndrop ] ] bi
     compose ;
 
+MACRO: nspread ( quots n -- )
+    over empty? [ 2drop [ ] ] [
+        [ [ but-last ] dip ]
+        [ [ peek ] dip ] 2bi
+        swap
+        '[ [ _ _ nspread ] _ ndip @ ]
+    ] if ;
+
 MACRO: napply ( quot n -- )
     swap <repetition> spread>quot ;
 
 MACRO: mnswap ( m n -- )
-    1+ '[ _ -nrot ] <repetition> spread>quot ;
+    1+ '[ _ -nrot ] swap '[ _ _ napply ] ;
+
+MACRO: nweave ( n -- )
+    [ dup <reversed> [ '[ _ _ mnswap ] ] with map ] keep
+    '[ _ _ ncleave ] ;
 
 : nappend-as ( n exemplar -- seq )
     [ narray concat ] dip like ; inline
index 272bdc1db3696891947e38f8d0d80cc2857e609a..f980032a8b756c1b71293a157283624043195699 100644 (file)
@@ -118,7 +118,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 ;
index b5f8b78ea325ae1d321d1a86d47ea6fe22b7d8ae..57f64459c86c3362397ef78d6c656b2729dc7378 100755 (executable)
@@ -7,7 +7,7 @@ combinators combinators.short-circuit splitting debugger
 hashtables sorting effects vocabs vocabs.loader assocs editors
 continuations classes.predicate macros math sets eval
 vocabs.parser words.symbol values grouping unicode.categories
-sequences.deep ;
+sequences.deep call ;
 IN: help.lint
 
 SYMBOL: vocabs-quot
@@ -15,9 +15,9 @@ SYMBOL: vocabs-quot
 : check-example ( element -- )
     [
         rest [
-            but-last "\n" join 1vector
-            [ (eval>string) ] with-datastack
-            peek "\n" ?tail drop
+            but-last "\n" join
+            [ (eval>string) ] call( code -- output )
+            "\n" ?tail drop
         ] keep
         peek assert=
     ] vocabs-quot get call ;
@@ -145,7 +145,7 @@ M: help-error error.
     bi ;
 
 : check-something ( obj quot -- )
-    flush '[ _ assert-depth ] swap '[ _ <help-error> , ] recover ; inline
+    flush '[ _ call( -- ) ] swap '[ _ <help-error> , ] recover ; inline
 
 : check-word ( word -- )
     [ with-file-vocabs ] vocabs-quot set
index e6b19d5baae1866acd6e84bb1c299a2e4ff9a2c1..8c687eb1d5d47263ec05f32304a0e42358552517 100644 (file)
@@ -27,11 +27,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 b432cc0cc6679aaae1fb28ffff0f6830eac4d7ae..37dbeba6c1d0b7bfcd218758ba4a2c0930c33e2a 100644 (file)
@@ -57,7 +57,10 @@ HELP: hidden
 { $description "Hidden components render as a hidden form field. For example, a page for editing a weblog post might contain a hidden field with the post ID." } ;
 
 HELP: html
-{ $description "HTML components render HTML verbatim, without any escaping. Care must be taken to only render trusted input, to avoid cross-site scripting attacks." } ;
+{ $description "HTML components render HTML verbatim from a string, without any escaping. Care must be taken to only render trusted input, to avoid cross-site scripting attacks." } ;
+
+HELP: xml
+{ $description "XML components render XML verbatim, from an XML chunk. Care must be taken to only render trusted input, to avoid cross-site scripting attacks." } ;
 
 HELP: inspector
 { $description "Inspector components render an arbitrary object by passing it to the " { $link describe } " word." } ;
@@ -90,6 +93,7 @@ $nl
 { $subsection inspector }
 { $subsection comparison }
 { $subsection html }
+{ $subsection xml }
 "Tuple components:"
 { $subsection field }
 { $subsection password }
index 2b18e283517f1a0d077045d22c6628652ff81571..9dddb856196be32ae008e83cc8b6f12ae80310ce 100644 (file)
@@ -171,3 +171,8 @@ M: comparison render*
 SINGLETON: html
 
 M: html render* 2drop <unescaped> ;
+
+! XML component
+SINGLETON: xml
+
+M: xml render* 2drop ;
diff --git a/basis/html/html-docs.factor b/basis/html/html-docs.factor
new file mode 100644 (file)
index 0000000..83fe4d3
--- /dev/null
@@ -0,0 +1,7 @@
+USING: help.markup help.syntax strings xml.data ;
+IN: html
+
+HELP: simple-page
+{ $values { "title" string } { "head" "XML data" } { "body" "XML data" }
+{ "xml" xml } }
+{ $description "Constructs a simple XHTML page with a " { $snippet "head" } " and " { $snippet "body" } " tag. The given XML data is spliced into the two child tags, and a title is also added to the head tag." } ;
index e86b4917d73322ca458d4a7930c82a839f16c4c2..e446c66d8c33445786bded6a659ad2a52a4257eb 100644 (file)
@@ -15,7 +15,7 @@ IN: html
             </head>
             <body><-></body>
         </html>
-    XML> ; inline
+    XML> ;
 
 : render-error ( message -- xml )
     [XML <span class="error"><-></span> XML] ;
index 18e6db66f6593db78e47d777de83858151e186cc..fcfd454478348a40b170e5f23e30b485e740d1d6 100644 (file)
@@ -1,8 +1,8 @@
 IN: html.templates.chloe
-USING: help.markup help.syntax html.components html.forms
+USING: xml.data help.markup help.syntax html.components html.forms
 html.templates html.templates.chloe.syntax
 html.templates.chloe.compiler html.templates.chloe.components
-math xml.data strings quotations namespaces ;
+math strings quotations namespaces ;
 
 HELP: <chloe>
 { $values { "path" "a pathname string without the trailing " { $snippet ".xml" } " extension" } { "chloe" chloe } }
@@ -70,6 +70,7 @@ ARTICLE: "html.templates.chloe.tags.component" "Component Chloe tags"
     { { $snippet "t:field" }      { $link field } }
     { { $snippet "t:hidden" }     { $link hidden } }
     { { $snippet "t:html" }       { $link html } }
+    { { $snippet "t:xml" }        { $link xml } }
     { { $snippet "t:inspector" }  { $link inspector } }
     { { $snippet "t:label" }      { $link label } }
     { { $snippet "t:link" }       { $link link } }
index 89d00e1f6ea1e684336f60a823becff19063325e..439b207063bd4f39b80d90c73b3f74ab6689831a 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors kernel sequences combinators kernel fry
 namespaces make classes.tuple assocs splitting words arrays io
 io.files io.files.info io.encodings.utf8 io.streams.string
 unicode.case mirrors math urls present multiline quotations xml
-logging continuations
+logging call
 xml.data xml.writer xml.syntax strings
 html.forms
 html
@@ -95,6 +95,7 @@ COMPONENT: password
 COMPONENT: choice
 COMPONENT: checkbox
 COMPONENT: code
+COMPONENT: xml
 
 SYMBOL: template-cache
 
@@ -130,6 +131,6 @@ TUPLE: cached-template path last-modified quot ;
     template-cache get clear-assoc ;
 
 M: chloe call-template*
-    template-quot assert-depth ;
+    template-quot call( -- ) ;
 
 INSTANCE: chloe template
index 394b5ef3594d13443cf53a3e6a0f00fd0764eadd..3cb7523bdc204bf10acaf144b4c055308c4ba6fe 100644 (file)
@@ -2,8 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs namespaces make kernel sequences accessors
 combinators strings splitting io io.streams.string present
-xml.writer xml.data xml.entities html.forms
-html.templates html.templates.chloe.syntax continuations ;
+xml.writer xml.data xml.entities html.forms call
+html.templates html.templates.chloe.syntax ;
 IN: html.templates.chloe.compiler
 
 : chloe-attrs-only ( assoc -- assoc' )
@@ -83,7 +83,7 @@ ERROR: unknown-chloe-tag tag ;
 
 : compile-chloe-tag ( tag -- )
     dup main>> dup tags get at
-    [ curry assert-depth ]
+    [ call( tag -- ) ]
     [ unknown-chloe-tag ]
     ?if ;
 
index f149c3fe474dbb3608c2a77338b24e76013c57f2..faf8bed66bc0d79b3d0f117f0f90c9025e6cdf43 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 c419c4a1973835875e3cfc4177faf2a49748ec91..78202d6460ac96460ba53858dee3d1de90e0eff8 100644 (file)
@@ -3,7 +3,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations sequences kernel namespaces debugger
 combinators math quotations generic strings splitting accessors
-assocs fry vocabs.parser parser lexer io io.files
+assocs fry vocabs.parser parser lexer io io.files call
 io.streams.string io.encodings.utf8 html.templates ;
 IN: html.templates.fhtml
 
@@ -72,6 +72,6 @@ TUPLE: fhtml path ;
 C: <fhtml> fhtml
 
 M: fhtml call-template* ( filename -- )
-    '[ _ path>> utf8 file-contents eval-template ] assert-depth ;
+    [ path>> utf8 file-contents eval-template ] call( filename -- ) ;
 
 INSTANCE: fhtml template
index 9a8aa48738a9dce78e672dff676b7d9d8fdb5869..0d7f7851e2cbf80980cc10ec70b46ff55ca949b6 100644 (file)
@@ -56,8 +56,7 @@ HELP: http-request
 
 HELP: with-http-request
 { $values { "request" request } { "quot" { $quotation "( chunk -- )" } } { "response" response } }
-{ $description "Sends an HTTP request to an HTTP server, and reads the response incrementally. Chunks of data are passed to the quotation as they are read." }
-{ $errors "Throws an error if the HTTP request fails." } ;
+{ $description "Sends an HTTP request to an HTTP server, and reads the response incrementally. Chunks of data are passed to the quotation as they are read. Does not throw an error if the HTTP request fails; to do so, call " { $link check-response } " on the " { $snippet "response" } "." } ;
 
 ARTICLE: "http.client.get" "GET requests with the HTTP client"
 "Basic usage involves passing a " { $link url } " and getting a " { $link response } " and data back:"
index cc1c67c31e139c7326d6df6fbca50987af4e39c0..4099e3d84cc35fea26d929db7ed75a060d13c1b2 100644 (file)
@@ -141,12 +141,15 @@ ERROR: download-failed response ;
 : check-response ( response -- response )
     dup code>> success? [ download-failed ] unless ;
 
+: check-response-with-body ( response body -- response body )
+    [ >>body check-response ] keep ;
+
 : with-http-request ( request quot -- response )
-    [ (with-http-request) check-response ] with-destructors ; inline
+    [ (with-http-request) ] with-destructors ; inline
 
 : http-request ( request -- response data )
     [ [ % ] with-http-request ] B{ } make
-    over content-charset>> decode ;
+    over content-charset>> decode check-response-with-body ;
 
 : <get-request> ( url -- request )
     "GET" <client-request> ;
index fc3f65fa5658c962c6c969762aa19f1a014b2e68..210066176f6ecd1378c4b18384c92e22bc48e782 100644 (file)
@@ -113,6 +113,12 @@ HELP: set-header
 { $notes "This word always returns the same object that was input. This allows for a “pipeline” coding style, where several header parameters are set in a row." }
 { $side-effects "request/response" } ;
 
+HELP: set-basic-auth
+{ $values { "request" request } { "username" string } { "password" string } }
+{ $description "Sets the " { $snippet "Authorization" } " header of " { $snippet "request" } " to perform HTTP Basic authentication with the given " { $snippet "username" } " and " { $snippet "password" } "." }
+{ $notes "This word always returns the same object that was input. This allows for a “pipeline” coding style, where several header parameters are set in a row." }
+{ $side-effects "request" } ;
+
 ARTICLE: "http.cookies" "HTTP cookies"
 "Every " { $link request } " and " { $link response } " instance can contain cookies."
 $nl
index 49acdb639cfdfc97c03b645c06a338e913ea7197..4f685945aab391365085126ffe528e4748c8cb7b 100644 (file)
@@ -359,3 +359,8 @@ SYMBOL: a
 ! Test cloning
 [ f ] [ <404> dup clone "b" "a" set-header drop "a" header ] unit-test
 [ f ] [ <404> dup clone "b" "a" <cookie> put-cookie drop "a" get-cookie ] unit-test
+
+! Test basic auth
+[ "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" ] [ <request> "Aladdin" "open sesame" set-basic-auth "Authorization" header ] unit-test
+
+
index 2b5414b2994e6b6b34f78b825d3c5f0453a22766..d4acd282f884c8e5676edc99c5f4df374dca5d88 100755 (executable)
@@ -7,7 +7,8 @@ calendar.format present urls fry
 io io.encodings io.encodings.iana io.encodings.binary
 io.encodings.8-bit io.crlf
 unicode.case unicode.categories
-http.parsers ;
+http.parsers
+base64 ;
 IN: http
 
 : (read-header) ( -- alist )
@@ -142,6 +143,9 @@ cookies ;
 : set-header ( request/response value key -- request/response )
     pick header>> set-at ;
 
+: set-basic-auth ( request username password -- request )
+    ":" glue >base64 "Basic " prepend "Authorization" set-header ;
+    
 : <request> ( -- request )
     request new
         "1.1" >>version
@@ -156,6 +160,7 @@ cookies ;
 : header ( request/response key -- value )
     swap header>> at ;
 
+
 TUPLE: response
 version
 code
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 fbe20b5fcdcb0f56ddb278c09fa8a64446e487e4..bbad56a6f1122033318a5fafba26054ed4df3f04 100644 (file)
@@ -38,7 +38,7 @@ $nl
 "If all you want to do is serve files from a directory, the following phrase does the trick:"
 { $code
     "USING: namespaces http.server http.server.static ;"
-    "/var/www/mysite.com/ <static> main-responder set"
+    "\"/var/www/mysite.com/\" <static> main-responder set"
     "8080 httpd"
 }
 { $subsection "http.server.static.extend" } ;
index 53d3d4f917e8ebabf526673b2c81d7ca9e628d0a..5d5ad7d2b83419bfe8c3ae7cf99b75ef2c8d8548 100644 (file)
@@ -45,9 +45,8 @@ TUPLE: file-responder root hook special allow-listings ;
     [ file-responder get hook>> call ] [ 2drop <304> ] if ;\r
 \r
 : serving-path ( filename -- filename )\r
-    file-responder get root>> trim-tail-separators\r
-    "/"\r
-    rot "" or trim-head-separators 3append ;\r
+    [ file-responder get root>> trim-tail-separators "/" ] dip\r
+    "" or trim-head-separators 3append ;\r
 \r
 : serve-file ( filename -- response )\r
     dup mime-type\r
diff --git a/basis/images/authors.txt b/basis/images/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/images/bitmap/authors.txt b/basis/images/bitmap/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/images/bitmap/bitmap-tests.factor b/basis/images/bitmap/bitmap-tests.factor
new file mode 100644 (file)
index 0000000..102c13c
--- /dev/null
@@ -0,0 +1,24 @@
+USING: images.bitmap images.viewer io.encodings.binary
+io.files io.files.unique kernel tools.test ;
+IN: images.bitmap.tests
+
+: test-bitmap24 ( -- path )
+    "resource:basis/images/test-images/thiswayup24.bmp" ;
+
+: test-bitmap8 ( -- path )
+    "resource:basis/images/test-images/rgb8bit.bmp" ;
+
+: test-bitmap4 ( -- path )
+    "resource:basis/images/test-images/rgb4bit.bmp" ;
+
+: test-bitmap1 ( -- path )
+    "resource:basis/images/test-images/1bit.bmp" ;
+
+[ t ]
+[
+    test-bitmap24
+    [ binary file-contents ] [ load-bitmap ] bi
+
+    "test-bitmap24" unique-file
+    [ save-bitmap ] [ binary file-contents ] bi =
+] unit-test
diff --git a/basis/images/bitmap/bitmap.factor b/basis/images/bitmap/bitmap.factor
new file mode 100755 (executable)
index 0000000..9005776
--- /dev/null
@@ -0,0 +1,162 @@
+! Copyright (C) 2007, 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.c-types arrays byte-arrays columns
+combinators fry grouping io io.binary io.encodings.binary io.files
+kernel macros math math.bitwise math.functions namespaces sequences
+strings images endian summary ;
+IN: images.bitmap
+
+TUPLE: bitmap-image < image ;
+
+! Currently can only handle 24/32bit bitmaps.
+! Handles row-reversed bitmaps (their height is negative)
+
+TUPLE: bitmap magic size reserved offset header-length width
+height planes bit-count compression size-image
+x-pels y-pels color-used color-important rgb-quads color-index
+buffer ;
+
+: array-copy ( bitmap array -- bitmap array' )
+    over size-image>> abs memory>byte-array ;
+
+: 8bit>buffer ( bitmap -- array )
+    [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
+    [ color-index>> >array ] bi [ swap nth ] with map concat ;
+
+ERROR: bmp-not-supported n ;
+
+: raw-bitmap>buffer ( bitmap -- array )
+    dup bit-count>>
+    {
+        { 32 [ color-index>> ] }
+        { 24 [ color-index>> ] }
+        { 16 [ bmp-not-supported ] }
+        { 8 [ 8bit>buffer ] }
+        { 4 [ bmp-not-supported ] }
+        { 2 [ bmp-not-supported ] }
+        { 1 [ bmp-not-supported ] }
+    } case >byte-array ;
+
+ERROR: bitmap-magic ;
+
+M: bitmap-magic summary
+    drop "First two bytes of bitmap stream must be 'BM'" ;
+
+: read2 ( -- n ) 2 read le> ;
+: read4 ( -- n ) 4 read le> ;
+
+: parse-file-header ( bitmap -- bitmap )
+    2 read >string dup "BM" = [ bitmap-magic ] unless >>magic
+    read4 >>size
+    read4 >>reserved
+    read4 >>offset ;
+
+: parse-bitmap-header ( bitmap -- bitmap )
+    read4 >>header-length
+    read4 >>width
+    read4 >>height
+    read2 >>planes
+    read2 >>bit-count
+    read4 >>compression
+    read4 >>size-image
+    read4 >>x-pels
+    read4 >>y-pels
+    read4 >>color-used
+    read4 >>color-important ;
+
+: rgb-quads-length ( bitmap -- n )
+    [ offset>> 14 - ] [ header-length>> ] bi - ;
+
+: color-index-length ( bitmap -- n )
+    {
+        [ width>> ]
+        [ planes>> * ]
+        [ bit-count>> * 31 + 32 /i 4 * ]
+        [ height>> abs * ]
+    } cleave ;
+
+: parse-bitmap ( bitmap -- bitmap )
+    dup rgb-quads-length read >>rgb-quads
+    dup color-index-length read >>color-index ;
+
+: load-bitmap-data ( path -- bitmap )
+    binary [
+        bitmap new
+        parse-file-header parse-bitmap-header parse-bitmap
+    ] with-file-reader ;
+
+: process-bitmap-data ( bitmap -- bitmap )
+    dup raw-bitmap>buffer >>buffer ;
+
+: load-bitmap ( path -- bitmap )
+    load-bitmap-data process-bitmap-data ;
+
+ERROR: unknown-component-order bitmap ;
+
+: bitmap>component-order ( bitmap -- object )
+    bit-count>> {
+        { 32 [ BGRA ] }
+        { 24 [ BGR ] }
+        { 8 [ BGR ] }
+        [ unknown-component-order ]
+    } case ;
+
+: >image ( bitmap -- bitmap-image )
+    {
+        [ [ width>> ] [ height>> ] bi 2array ]
+        [ bitmap>component-order ]
+        [ buffer>> ]
+    } cleave bitmap-image boa ;
+
+M: bitmap-image load-image* ( path bitmap -- bitmap-image )
+    drop load-bitmap >image ;
+
+M: bitmap-image normalize-scan-line-order
+    dup dim>> '[
+        _ first 4 * <sliced-groups> reverse concat
+    ] change-bitmap ;
+
+MACRO: (nbits>bitmap) ( bits -- )
+    [ -3 shift ] keep '[
+        bitmap new
+            2over * _ * >>size-image
+            swap >>height
+            swap >>width
+            swap array-copy [ >>buffer ] [ >>color-index ] bi
+            _ >>bit-count >image
+    ] ;
+
+: bgr>bitmap ( array height width -- bitmap )
+    24 (nbits>bitmap) ;
+
+: bgra>bitmap ( array height width -- bitmap )
+    32 (nbits>bitmap) ;
+
+: write2 ( n -- ) 2 >le write ;
+: write4 ( n -- ) 4 >le write ;
+
+: save-bitmap ( bitmap path -- )
+    binary [
+        B{ CHAR: B CHAR: M } write
+        [
+            buffer>> length 14 + 40 + write4
+            0 write4
+            54 write4
+            40 write4
+        ] [
+            {
+                [ width>> write4 ]
+                [ height>> write4 ]
+                [ planes>> 1 or write2 ]
+                [ bit-count>> 24 or write2 ]
+                [ compression>> 0 or write4 ]
+                [ size-image>> write4 ]
+                [ x-pels>> 0 or write4 ]
+                [ y-pels>> 0 or write4 ]
+                [ color-used>> 0 or write4 ]
+                [ color-important>> 0 or write4 ]
+                [ rgb-quads>> write ]
+                [ color-index>> write ]
+            } cleave
+        ] bi
+    ] with-file-writer ;
diff --git a/basis/images/images.factor b/basis/images/images.factor
new file mode 100644 (file)
index 0000000..32fbc54
--- /dev/null
@@ -0,0 +1,62 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors grouping sequences combinators
+math specialized-arrays.direct.uint byte-arrays
+specialized-arrays.direct.ushort ;
+IN: images
+
+SINGLETONS: BGR RGB BGRA RGBA ABGR ARGB RGBX XRGB BGRX XBGR
+R16G16B16 R32G32B32 ;
+
+TUPLE: image dim component-order bitmap ;
+
+: <image> ( -- image ) image new ; inline
+
+GENERIC: load-image* ( path tuple -- image )
+
+: add-dummy-alpha ( seq -- seq' )
+    3 <sliced-groups>
+    [ 255 suffix ] map concat ;
+
+: normalize-component-order ( image -- image )
+    dup component-order>>
+    {
+        { RGBA [ ] }
+        { R32G32B32 [
+            [
+                dup length 4 / <direct-uint-array>
+                [ bits>float 255.0 * >integer ] map
+                >byte-array add-dummy-alpha
+            ] change-bitmap
+        ] }
+        { R16G16B16 [
+            [
+                dup length 2 / <direct-ushort-array>
+                [ -8 shift ] map
+                >byte-array add-dummy-alpha
+            ] change-bitmap
+        ] }
+        { BGRA [
+            [
+                4 <sliced-groups> dup [ [ 0 3 ] dip <slice> reverse-here ] each
+            ] change-bitmap
+        ] }
+        { RGB [ [ add-dummy-alpha ] change-bitmap ] }
+        { BGR [
+            [
+                3 <sliced-groups>
+                [ [ [ 0 3 ] dip <slice> reverse-here ] each ]
+                [ add-dummy-alpha ] bi
+            ] change-bitmap
+        ] }
+    } case
+    RGBA >>component-order ;
+
+GENERIC: normalize-scan-line-order ( image -- image )
+
+M: image normalize-scan-line-order ;
+
+: normalize-image ( image -- image )
+    [ >byte-array ] change-bitmap
+    normalize-component-order
+    normalize-scan-line-order ;
diff --git a/basis/images/loader/authors.txt b/basis/images/loader/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/images/loader/loader.factor b/basis/images/loader/loader.factor
new file mode 100644 (file)
index 0000000..6f2ae47
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: constructors kernel splitting unicode.case combinators
+accessors images.bitmap images.tiff images io.backend
+io.pathnames ;
+IN: images.loader
+
+ERROR: unknown-image-extension extension ;
+
+: image-class ( path -- class )
+    file-extension >lower {
+        { "bmp" [ bitmap-image ] }
+        { "tif" [ tiff-image ] }
+        { "tiff" [ tiff-image ] }
+        [ unknown-image-extension ]
+    } case ;
+
+: load-image ( path -- image )
+    dup image-class new load-image* normalize-image ;
diff --git a/basis/images/tags.txt b/basis/images/tags.txt
new file mode 100644 (file)
index 0000000..04b54a0
--- /dev/null
@@ -0,0 +1 @@
+bitmap graphics
diff --git a/basis/images/test-images/1bit.bmp b/basis/images/test-images/1bit.bmp
new file mode 100644 (file)
index 0000000..2f244c1
Binary files /dev/null and b/basis/images/test-images/1bit.bmp differ
diff --git a/basis/images/test-images/octagon.tiff b/basis/images/test-images/octagon.tiff
new file mode 100644 (file)
index 0000000..2b4ba39
Binary files /dev/null and b/basis/images/test-images/octagon.tiff differ
diff --git a/basis/images/test-images/rgb.tiff b/basis/images/test-images/rgb.tiff
new file mode 100755 (executable)
index 0000000..71cbaa9
Binary files /dev/null and b/basis/images/test-images/rgb.tiff differ
diff --git a/basis/images/test-images/rgb4bit.bmp b/basis/images/test-images/rgb4bit.bmp
new file mode 100644 (file)
index 0000000..0c6f00d
Binary files /dev/null and b/basis/images/test-images/rgb4bit.bmp differ
diff --git a/basis/images/test-images/rgb8bit.bmp b/basis/images/test-images/rgb8bit.bmp
new file mode 100644 (file)
index 0000000..bc95c0f
Binary files /dev/null and b/basis/images/test-images/rgb8bit.bmp differ
diff --git a/basis/images/test-images/thiswayup24.bmp b/basis/images/test-images/thiswayup24.bmp
new file mode 100644 (file)
index 0000000..202fb15
Binary files /dev/null and b/basis/images/test-images/thiswayup24.bmp differ
diff --git a/basis/images/tiff/authors.txt b/basis/images/tiff/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/images/tiff/tiff-tests.factor b/basis/images/tiff/tiff-tests.factor
new file mode 100755 (executable)
index 0000000..9905e7a
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test images.tiff ;
+IN: images.tiff.tests
+
+: tiff-test-path ( -- path )
+    "resource:extra/images/test-images/rgb.tiff" ;
+
+: tiff-test-path2 ( -- path )
+    "resource:extra/images/test-images/octagon.tiff" ;
diff --git a/basis/images/tiff/tiff.factor b/basis/images/tiff/tiff.factor
new file mode 100755 (executable)
index 0000000..056f91f
--- /dev/null
@@ -0,0 +1,339 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs byte-arrays classes combinators
+compression.lzw constructors endian fry grouping images io
+io.binary io.encodings.ascii io.encodings.binary
+io.encodings.string io.encodings.utf8 io.files kernel math
+math.bitwise math.order math.parser pack prettyprint sequences
+strings ;
+IN: images.tiff
+
+TUPLE: tiff-image < image ;
+
+TUPLE: parsed-tiff endianness the-answer ifd-offset ifds ;
+CONSTRUCTOR: parsed-tiff ( -- tiff ) V{ } clone >>ifds ;
+
+TUPLE: ifd count ifd-entries next
+processed-tags strips bitmap ;
+CONSTRUCTOR: ifd ( count ifd-entries next -- ifd ) ;
+
+TUPLE: ifd-entry tag type count offset/value ;
+CONSTRUCTOR: ifd-entry ( tag type count offset/value -- ifd-entry ) ;
+
+SINGLETONS: photometric-interpretation
+photometric-interpretation-white-is-zero
+photometric-interpretation-black-is-zero
+photometric-interpretation-rgb
+photometric-interpretation-palette-color ;
+ERROR: bad-photometric-interpretation n ;
+: lookup-photometric-interpretation ( n -- singleton )
+    {
+        { 0 [ photometric-interpretation-white-is-zero ] }
+        { 1 [ photometric-interpretation-black-is-zero ] }
+        { 2 [ photometric-interpretation-rgb ] }
+        { 3 [ photometric-interpretation-palette-color ] }
+        [ bad-photometric-interpretation ]
+    } case ;
+
+SINGLETONS: compression
+compression-none
+compression-CCITT-2
+compression-lzw
+compression-pack-bits ;
+ERROR: bad-compression n ;
+: lookup-compression ( n -- compression )
+    {
+        { 1 [ compression-none ] }
+        { 2 [ compression-CCITT-2 ] }
+        { 5 [ compression-lzw ] }
+        { 32773 [ compression-pack-bits ] }
+        [ bad-compression ]
+    } case ;
+
+SINGLETONS: resolution-unit
+resolution-unit-none
+resolution-unit-inch
+resolution-unit-centimeter ;
+ERROR: bad-resolution-unit n ;
+: lookup-resolution-unit ( n -- object )
+    {
+        { 1 [ resolution-unit-none ] }
+        { 2 [ resolution-unit-inch ] }
+        { 3 [ resolution-unit-centimeter ] }
+        [ bad-resolution-unit ]
+    } case ;
+
+SINGLETONS: predictor
+predictor-none
+predictor-horizontal-differencing ;
+ERROR: bad-predictor n ;
+: lookup-predictor ( n -- object )
+    {
+        { 1 [ predictor-none ] }
+        { 2 [ predictor-horizontal-differencing ] }
+        [ bad-predictor ]
+    } case ;
+
+SINGLETONS: planar-configuration
+planar-configuration-chunky
+planar-configuration-planar ;
+ERROR: bad-planar-configuration n ;
+: lookup-planar-configuration ( n -- object )
+    {
+        { 1 [ planar-configuration-chunky ] }
+        { 2 [ planar-configuration-planar ] }
+        [ bad-planar-configuration ]
+    } case ;
+
+SINGLETONS: sample-format
+sample-format-unsigned-integer
+sample-format-signed-integer
+sample-format-ieee-float
+sample-format-undefined-data ;
+ERROR: bad-sample-format n ;
+: lookup-sample-format ( sequence -- object )
+    [
+        {
+            { 1 [ sample-format-unsigned-integer ] }
+            { 2 [ sample-format-signed-integer ] }
+            { 3 [ sample-format-ieee-float ] }
+            { 4 [ sample-format-undefined-data ] }
+            [ bad-sample-format ]
+        } case
+    ] map ;
+
+SINGLETONS: extra-samples
+extra-samples-unspecified-alpha-data
+extra-samples-associated-alpha-data
+extra-samples-unassociated-alpha-data ;
+ERROR: bad-extra-samples n ;
+: lookup-extra-samples ( sequence -- object )
+    {
+        { 0 [ extra-samples-unspecified-alpha-data ] }
+        { 1 [ extra-samples-associated-alpha-data ] }
+        { 2 [ extra-samples-unassociated-alpha-data ] }
+        [ bad-extra-samples ]
+    } case ;
+
+SINGLETONS: image-length image-width x-resolution y-resolution
+rows-per-strip strip-offsets strip-byte-counts bits-per-sample
+samples-per-pixel new-subfile-type orientation software
+date-time photoshop exif-ifd sub-ifd inter-color-profile
+xmp iptc unhandled-ifd-entry ;
+
+ERROR: bad-tiff-magic bytes ;
+: tiff-endianness ( byte-array -- ? )
+    {
+        { B{ CHAR: M CHAR: M } [ big-endian ] }
+        { B{ CHAR: I CHAR: I } [ little-endian ] }
+        [ bad-tiff-magic ]
+    } case ;
+
+: read-header ( tiff -- tiff )
+    2 read tiff-endianness [ >>endianness ] keep
+    [
+        2 read endian> >>the-answer
+        4 read endian> >>ifd-offset
+    ] with-endianness ;
+
+: push-ifd ( tiff ifd -- tiff ) over ifds>> push ;
+
+: read-ifd ( -- ifd )
+    2 read endian>
+    2 read endian>
+    4 read endian>
+    4 read endian> <ifd-entry> ;
+
+: read-ifds ( tiff -- tiff )
+    dup ifd-offset>> seek-absolute seek-input
+    2 read endian>
+    dup [ read-ifd ] replicate
+    4 read endian>
+    [ <ifd> push-ifd ] [ 0 = [ read-ifds ] unless ] bi ;
+
+ERROR: no-tag class ;
+
+: ?at ( key assoc -- value/key ? )
+    dupd at* [ nip t ] [ drop f ] if ; inline
+
+: find-tag ( idf class -- tag )
+    swap processed-tags>> ?at [ no-tag ] unless ;
+
+: read-strips ( ifd -- ifd )
+    dup
+    [ strip-byte-counts find-tag ]
+    [ strip-offsets find-tag ] bi
+    2dup [ integer? ] both? [
+        seek-absolute seek-input read 1array
+    ] [
+        [ seek-absolute seek-input read ] { } 2map-as
+    ] if >>strips ;
+
+ERROR: unknown-ifd-type n ;
+
+: bytes>bits ( n/byte-array -- n )
+    dup byte-array? [ byte-array>bignum ] when ;
+
+: value-length ( ifd-entry -- n )
+    [ count>> ] [ type>> ] bi {
+        { 1 [ ] }
+        { 2 [ ] }
+        { 3 [ 2 * ] }
+        { 4 [ 4 * ] }
+        { 5 [ 8 * ] }
+        { 6 [ ] }
+        { 7 [ ] }
+        { 8 [ 2 * ] }
+        { 9 [ 4 * ] }
+        { 10 [ 8 * ] }
+        { 11 [ 4 * ] }
+        { 12 [ 8 * ] }
+        { 13 [ 4 * ] }
+        [ unknown-ifd-type ]
+    } case ;
+
+ERROR: bad-small-ifd-type n ;
+
+: adjust-offset/value ( ifd-entry -- obj )
+    [ offset/value>> 4 >endian ] [ type>> ] bi
+    {
+        { 1 [ 1 head endian> ] }
+        { 3 [ 2 head endian> ] }
+        { 4 [ endian> ] }
+        { 6 [ 1 head endian> 8 >signed ] }
+        { 8 [ 2 head endian> 16 >signed ] }
+        { 9 [ endian> 32 >signed ] }
+        { 11 [ endian> bits>float ] }
+        { 13 [ endian> 32 >signed ] }
+        [ bad-small-ifd-type ]
+    } case ;
+
+: offset-bytes>obj ( bytes type -- obj )
+    {
+        { 1 [ ] } ! blank
+        { 2 [ ] } ! read c strings here
+        { 3 [ 2 <sliced-groups> [ endian> ] map ] }
+        { 4 [ 4 <sliced-groups> [ endian> ] map ] }
+        { 5 [ 8 <sliced-groups> [ "II" unpack first2 / ] map ] }
+        { 6 [ [ 8 >signed ] map ] }
+        { 7 [ ] } ! blank
+        { 8 [ 2 <sliced-groups> [ endian> 16 >signed ] map ] }
+        { 9 [ 4 <sliced-groups> [ endian> 32 >signed ] map ] }
+        { 10 [ 8 group [ "ii" unpack first2 / ] map ] }
+        { 11 [ 4 group [ "f" unpack ] map ] }
+        { 12 [ 8 group [ "d" unpack ] map ] }
+        [ unknown-ifd-type ]
+    } case ;
+
+: ifd-entry-value ( ifd-entry -- n )
+    dup value-length 4 <= [
+        adjust-offset/value
+    ] [
+        [ offset/value>> seek-absolute seek-input ]
+        [ value-length read ]
+        [ type>> ] tri offset-bytes>obj
+    ] if ;
+
+: process-ifd-entry ( ifd-entry -- value class )
+    [ ifd-entry-value ] [ tag>> ] bi {
+        { 254 [ new-subfile-type ] }
+        { 256 [ image-width ] }
+        { 257 [ image-length ] }
+        { 258 [ bits-per-sample ] }
+        { 259 [ lookup-compression compression ] }
+        { 262 [ lookup-photometric-interpretation photometric-interpretation ] }
+        { 273 [ strip-offsets ] }
+        { 274 [ orientation ] }
+        { 277 [ samples-per-pixel ] }
+        { 278 [ rows-per-strip ] }
+        { 279 [ strip-byte-counts ] }
+        { 282 [ first x-resolution ] }
+        { 283 [ first y-resolution ] }
+        { 284 [ planar-configuration ] }
+        { 296 [ lookup-resolution-unit resolution-unit ] }
+        { 305 [ ascii decode software ] }
+        { 306 [ ascii decode date-time ] }
+        { 317 [ lookup-predictor predictor ] }
+        { 330 [ sub-ifd ] }
+        { 338 [ lookup-extra-samples extra-samples ] }
+        { 339 [ lookup-sample-format sample-format ] }
+        { 700 [ utf8 decode xmp ] }
+        { 34377 [ photoshop ] }
+        { 34665 [ exif-ifd ] }
+        { 33723 [ iptc ] }
+        { 34675 [ inter-color-profile ] }
+        [ nip unhandled-ifd-entry swap ]
+    } case ;
+
+: process-ifd ( ifd -- ifd )
+    dup ifd-entries>>
+    [ process-ifd-entry swap ] H{ } map>assoc >>processed-tags ;
+
+ERROR: unhandled-compression compression ;
+
+: (uncompress-strips) ( strips compression -- uncompressed-strips )
+    {
+        { compression-none [ ] }
+        { compression-lzw [ [ lzw-uncompress ] map ] }
+        [ unhandled-compression ]
+    } case ;
+
+: uncompress-strips ( ifd -- ifd )
+    dup '[
+        _ compression find-tag (uncompress-strips)
+    ] change-strips ;
+
+: strips>bitmap ( ifd -- ifd )
+    dup strips>> concat >>bitmap ;
+
+ERROR: unknown-component-order ifd ;
+
+: fix-bitmap-endianness ( ifd -- ifd )
+    dup [ bitmap>> ] [ bits-per-sample find-tag ] bi
+    {
+        { { 32 32 32 32 } [ 4 seq>native-endianness ] }
+        { { 32 32 32 } [ 4 seq>native-endianness ] }
+        { { 16 16 16 16 } [ 2 seq>native-endianness ] }
+        { { 16 16 16 } [ 2 seq>native-endianness ] }
+        { { 8 8 8 8 } [ ] }
+        { { 8 8 8 } [ ] }
+        [ unknown-component-order ]
+    } case >>bitmap ;
+
+: ifd-component-order ( ifd -- byte-order )
+    bits-per-sample find-tag {
+        { { 32 32 32 } [ R32G32B32 ] }
+        { { 16 16 16 } [ R16G16B16 ] }
+        { { 8 8 8 8 } [ RGBA ] }
+        { { 8 8 8 } [ RGB ] }
+        [ unknown-component-order ]
+    } case ;
+
+: ifd>image ( ifd -- image )
+    {
+        [ [ image-width find-tag ] [ image-length find-tag ] bi 2array ]
+        [ ifd-component-order ]
+        [ bitmap>> ]
+    } cleave tiff-image boa ;
+
+: tiff>image ( image -- image )
+    ifds>> [ ifd>image ] map first ;
+
+: load-tiff ( path -- parsed-tiff )
+    binary [
+        <parsed-tiff>
+        read-header dup endianness>> [
+            read-ifds
+            dup ifds>> [
+                process-ifd read-strips
+                uncompress-strips
+                strips>bitmap
+                fix-bitmap-endianness
+                drop
+            ] each
+        ] with-endianness
+    ] with-file-reader ;
+
+! tiff files can store several images -- we just take the first for now
+M: tiff-image load-image* ( path tiff-image -- image )
+    drop load-tiff tiff>image ;
index 3372f15cd9d28ea852b0bdd6d12ee28fd06b4fdf..f5e6426859aaa4543a1a407b5fd721ea3b59bca9 100644 (file)
@@ -46,14 +46,14 @@ M: fd cancel-operation ( fd -- )
         2bi
     ] if ;
 
-M: unix (stream-seek) ( n seek-type stream -- )
+M: unix seek-handle ( n seek-type handle -- )
     swap {
         { io:seek-absolute [ SEEK_SET ] }
         { io:seek-relative [ SEEK_CUR ] }
         { io:seek-end [ SEEK_END ] }
         [ io:bad-seek-type ]
     } case
-    [ handle>> fd>> swap ] dip lseek io-error ;
+    [ fd>> swap ] dip lseek io-error ;
 
 SYMBOL: +retry+ ! just try the operation again without blocking
 SYMBOL: +input+
index 7b96e883dd949e2eb15612d9d1f49a9749c51a3f..6f283ac1bb9bfdd0b229b5d3706e3b5926b18b02 100755 (executable)
@@ -87,11 +87,16 @@ ERROR: invalid-file-size n ;
 : handle>file-size ( handle -- n )
     0 <ulonglong> [ GetFileSizeEx win32-error=0/f ] keep *ulonglong ;
 
-M: winnt (stream-seek) ( n seek-type stream -- )
+ERROR: seek-before-start n ;
+
+: set-seek-ptr ( n handle -- )
+    [ dup 0 < [ seek-before-start ] when ] dip (>>ptr) ;
+
+M: winnt seek-handle ( n seek-type handle -- )
     swap {
-        { seek-absolute [ handle>> (>>ptr) ] }
-        { seek-relative [ handle>> [ + ] change-ptr drop ] }
-        { seek-end [ handle>> [ handle>> handle>file-size + ] keep (>>ptr) ] }
+        { seek-absolute [ set-seek-ptr ] }
+        { seek-relative [ [ ptr>> + ] keep set-seek-ptr ] }
+        { seek-end [ [ handle>> handle>file-size + ] keep set-seek-ptr ] }
         [ bad-seek-type ]
     } case ;
 
index a647f27dfc998f76ebe0af5bf72ad6855c02f495..4df081b17de6932b8c381cf802cb131fd9aab23d 100644 (file)
@@ -21,9 +21,6 @@ M: buffer dispose* ptr>> free ;
 : buffer-reset ( n buffer -- )
     swap >>fill 0 >>pos drop ;
 
-: buffer-reset-hard ( buffer -- )
-    0 >>fill 0 >>pos drop ;
-
 : buffer-capacity ( buffer -- n )
     [ size>> ] [ fill>> ] bi - ; inline
 
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 -- )
     [
old mode 100644 (file)
new mode 100755 (executable)
index 4dd0eeb..0420236
@@ -37,11 +37,12 @@ IN: io.launcher.windows.nt.tests
     "out.txt" temp-file ascii file-lines first
 ] unit-test
 
-[ ] [
+[ "( scratchpad ) " ] [
     <process>
         console-vm "-run=listener" 2array >>command
         +closed+ >>stdin
-    try-process
+        +stdout+ >>stderr
+    ascii [ input-stream get contents ] with-process-reader
 ] unit-test
 
 : launcher-test-path ( -- str )
@@ -162,3 +163,5 @@ IN: io.launcher.windows.nt.tests
    
     "append-test" temp-file ascii file-contents
 ] unit-test
+
+
index 1f7fc5f11517378e293790cccf4f8d7ec8c1d159..1a58d4200be8fdcd02ca50ef70b66fc341d0ed59 100644 (file)
@@ -120,12 +120,17 @@ M: output-port stream-write
 
 HOOK: (wait-to-write) io-backend ( port -- )
 
-HOOK: (stream-seek) os ( n seek-type stream -- )
+HOOK: seek-handle os ( n seek-type handle -- )
 
-M: port stream-seek ( n seek-type stream -- )
-    dup check-disposed
-    [ buffer>> buffer-reset-hard 2drop ] [ (stream-seek) ] 3bi ;
+M: input-port stream-seek ( n seek-type stream -- )
+    [ check-disposed ]
+    [ buffer>> 0 swap buffer-reset ]
+    [ handle>> seek-handle ] tri ;
 
+M: output-port stream-seek ( n seek-type stream -- )
+    [ check-disposed ]
+    [ stream-flush ]
+    [ handle>> seek-handle ] tri ;
 
 GENERIC: shutdown ( handle -- )
 
diff --git a/basis/lists/authors.txt b/basis/lists/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/basis/lists/lazy/authors.txt b/basis/lists/lazy/authors.txt
new file mode 100644 (file)
index 0000000..f6ba9ba
--- /dev/null
@@ -0,0 +1,3 @@
+Chris Double
+Samuel Tardieu
+Matthew Willis
diff --git a/basis/lists/lazy/examples/authors.txt b/basis/lists/lazy/examples/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/basis/lists/lazy/examples/examples-tests.factor b/basis/lists/lazy/examples/examples-tests.factor
new file mode 100644 (file)
index 0000000..04886e2
--- /dev/null
@@ -0,0 +1,5 @@
+USING: lists.lazy.examples lists.lazy tools.test ;
+IN: lists.lazy.examples.tests
+
+[ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test
+[ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test
diff --git a/basis/lists/lazy/examples/examples.factor b/basis/lists/lazy/examples/examples.factor
new file mode 100644 (file)
index 0000000..1d5bb49
--- /dev/null
@@ -0,0 +1,15 @@
+! Rewritten by Matthew Willis, July 2006
+! Copyright (C) 2004 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: lists.lazy math kernel sequences quotations ;
+IN: lists.lazy.examples
+
+: naturals ( -- list ) 0 lfrom ;
+: positives ( -- list ) 1 lfrom ;
+: evens ( -- list ) 0 [ 2 + ] lfrom-by ;
+: odds ( -- list ) 1 lfrom [ 2 mod 1 = ] lfilter ;
+: powers-of-2 ( -- list ) 1 [ 2 * ] lfrom-by ;
+: ones ( -- list ) 1 [ ] lfrom-by ;
+: squares ( -- list ) naturals [ dup * ] lazy-map ;
+: first-five-squares ( -- list ) 5 squares ltake list>array ;
diff --git a/basis/lists/lazy/lazy-docs.factor b/basis/lists/lazy/lazy-docs.factor
new file mode 100644 (file)
index 0000000..08fe3bb
--- /dev/null
@@ -0,0 +1,168 @@
+! Copyright (C) 2006 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax sequences strings lists ;
+IN: lists.lazy 
+
+ABOUT: "lists.lazy"
+
+ARTICLE: "lists.lazy" "Lazy lists"
+"The " { $vocab-link "lists.lazy" } " vocabulary implements lazy lists and standard operations to manipulate them."
+{ $subsection { "lists.lazy" "construction" } }
+{ $subsection { "lists.lazy" "manipulation" } }
+{ $subsection { "lists.lazy" "combinators" } }
+{ $subsection { "lists.lazy" "io" } } ;
+
+ARTICLE: { "lists.lazy" "combinators" } "Combinators for manipulating lazy lists"
+"The following combinators create lazy lists from other lazy lists:"
+{ $subsection lmap }
+{ $subsection lfilter }
+{ $subsection luntil }
+{ $subsection lwhile }
+{ $subsection lfrom-by }
+{ $subsection lcomp }
+{ $subsection lcomp* } ;
+
+ARTICLE: { "lists.lazy" "io" } "Lazy list I/O"
+"Input from a stream can be read through a lazy list, using the following words:"
+{ $subsection lcontents }
+{ $subsection llines } ;
+
+ARTICLE: { "lists.lazy" "construction" } "Constructing lazy lists"
+"Words for constructing lazy lists:"
+{ $subsection lazy-cons }
+{ $subsection 1lazy-list }
+{ $subsection 2lazy-list }
+{ $subsection 3lazy-list }
+{ $subsection seq>list }
+{ $subsection >list }
+{ $subsection lfrom } ;
+
+ARTICLE: { "lists.lazy" "manipulation" } "Manipulating lazy lists"
+"To make new lazy lists from old ones:"
+{ $subsection <memoized-cons> }
+{ $subsection lappend }
+{ $subsection lconcat }
+{ $subsection lcartesian-product }
+{ $subsection lcartesian-product* }
+{ $subsection lmerge }
+{ $subsection ltake } ;
+
+HELP: lazy-cons
+{ $values { "car" { $quotation "( -- elt )" } } { "cdr" { $quotation "( -- cons )" } } { "promise" "the resulting cons object" } }
+{ $description "Constructs a cons object for a lazy list from two quotations. The " { $snippet "car" } " quotation should return the head of the list, and the " { $snippet "cons" } " quotation the tail when called. When " { $link cons } " or " { $link cdr } " are called on the lazy-cons object then the appropriate quotation is called." } 
+{ $see-also cons car cdr nil nil? } ;
+
+{ 1lazy-list 2lazy-list 3lazy-list } related-words
+
+HELP: 1lazy-list
+{ $values { "a" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 1 element. The element is the result of calling the quotation. The quotation is only called when the list element is requested." } ;
+
+HELP: 2lazy-list
+{ $values { "a" { $quotation "( -- X )" } } { "b" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 2 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
+
+HELP: 3lazy-list
+{ $values { "a" { $quotation "( -- X )" } } { "b" { $quotation "( -- X )" } } { "c" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 3 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
+
+HELP: <memoized-cons>
+{ $values { "cons" "a cons object" } { "memoized-cons" "the resulting memoized-cons object" } }
+{ $description "Constructs a cons object that wraps an existing cons object. Requests for the car, cdr and nil? will be remembered after the first call, and the previous result returned on subsequent calls." } 
+{ $see-also cons car cdr nil nil? } ;
+
+{ lazy-map ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
+
+HELP: lazy-map
+{ $values { "list" "a cons object" } { "quot" { $quotation "( obj -- X )" } } { "result" "resulting cons object" } }
+{ $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-map> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: ltake
+{ $values { "n" "a non negative integer" } { "list" "a cons object" } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first n items in the list. This is done a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-take> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: lfilter
+{ $values { "list" "a cons object" } { "quot" { $quotation "( -- X )" } } { "result" "resulting cons object" } }
+{ $description "Perform a similar functionality to that of the " { $link filter } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-filter> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: lwhile
+{ $values { "list" "a cons object" } { "quot" { $quotation "( X -- ? )" } } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first items in the list as long as " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: luntil
+{ $values { "list" "a cons object" } { "quot" { $quotation "( X -- ? )" } } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first items in the list until after " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: list>vector
+{ $values { "list" "a cons object" } { "vector" "the list converted to a vector" } }
+{ $description "Convert a list to a vector. If the list is a lazy infinite list then this will enter an infinite loop." } 
+{ $see-also list>array } ;
+
+HELP: list>array
+{ $values { "list" "a cons object" } { "array" "the list converted to an array" } }
+{ $description "Convert a list to an array. If the list is a lazy infinite list then this will enter an infinite loop." } 
+{ $see-also list>vector } ;
+
+HELP: lappend
+{ $values { "list1" "a cons object" } { "list2" "a cons object" } { "result" "a lazy list of list2 appended to list1" } }
+{ $description "Perform a similar functionality to that of the " { $link append } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-append> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required. Successive calls to " { $link cdr } " will iterate through list1, followed by list2." } ;
+
+HELP: lfrom-by
+{ $values { "n" "an integer" } { "quot" { $quotation "( -- int )" } } { "list" "a lazy list of integers" } }
+{ $description "Return an infinite lazy list of values starting from n, with each successive value being the result of applying quot to n." } ;
+
+HELP: lfrom
+{ $values { "n" "an integer" } { "list" "a lazy list of integers" } }
+{ $description "Return an infinite lazy list of incrementing integers starting from n." } ;
+
+HELP: seq>list
+{ $values { "index" "an integer 0 or greater" } { "seq" "a sequence" } { "list" "a list" } }
+{ $description "Convert the sequence into a list, starting from the 'index' offset into the sequence." } 
+{ $see-also >list } ;
+
+HELP: >list
+{ $values { "object" "an object" } { "list" "a list" } }
+{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } 
+{ $see-also seq>list } ;
+    
+{ leach foldl lazy-map ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
+
+HELP: lconcat
+{ $values { "list" "a list of lists" } { "result" "a list" } }
+{ $description "Concatenates a list of lists together into one list." } ;
+
+HELP: lcartesian-product
+{ $values { "list1" "a list" } { "list2" "a list" } { "result" "list of cartesian products" } }
+{ $description "Given two lists, return a list containing the cartesian product of those lists." } ;
+
+HELP: lcartesian-product*
+{ $values { "lists" "a list of lists" } { "result" "list of cartesian products" } }
+{ $description "Given a list of lists, return a list containing the cartesian product of those lists." } ;
+
+HELP: lcomp
+{ $values { "list" "a list of lists" } { "quot" { $quotation "( seq -- X )" } } { "result" "the resulting list" } }
+{ $description "Get the cartesian product of the lists in " { $snippet "list" } " and call " { $snippet "quot" } " call with each element from the cartesian product on the stack, the result of which is returned in the final " { $snippet "list" } "." } ;
+
+HELP: lcomp*
+{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" { $quotation "( seq -- X )" } } { "list" "the resulting list" } { "result" "a list" } }
+{ $description "Get the cartesian product of the lists in " { $snippet "list" } ", filter it by applying each guard quotation to it and call " { $snippet "quot" } " call with each element from the remaining cartesian product items on the stack, the result of which is returned in the final " { $snippet "list" } "." }
+{ $examples
+  { $code "{ 1 2 3 } >list { 4 5 6 } >list 2list { [ first odd? ] } [ first2 + ] lcomp*" }
+} ;
+
+HELP: lmerge
+{ $values { "list1" "a list" } { "list2" "a list" } { "result" "lazy list merging list1 and list2" } }
+{ $description "Return the result of merging the two lists in a lazy manner." } 
+{ $examples
+  { $example "USING: lists.lazy prettyprint ;" "{ 1 2 3 } >list { 4 5 6 } >list lmerge list>array ." "{ 1 4 2 5 3 6 }" }
+} ;
+
+HELP: lcontents
+{ $values { "stream" "a stream" } { "result" string } }
+{ $description "Returns a lazy list of all characters in the file. " { $link car } " returns the next character in the file, " { $link cdr } " returns the remaining characters as a lazy list. " { $link nil? } " indicates end of file." } 
+{ $see-also llines } ;
+
+HELP: llines
+{ $values { "stream" "a stream" } { "result" "a list" } }
+{ $description "Returns a lazy list of all lines in the file. " { $link car } " returns the next lines in the file, " { $link cdr } " returns the remaining lines as a lazy list. " { $link nil? } " indicates end of file." } 
+{ $see-also lcontents } ;
diff --git a/basis/lists/lazy/lazy-tests.factor b/basis/lists/lazy/lazy-tests.factor
new file mode 100644 (file)
index 0000000..f4e55cb
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2006 Matthew Willis and Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: lists lists.lazy tools.test kernel math io sequences ;
+IN: lists.lazy.tests
+
+[ { 1 2 3 4 } ] [
+  { 1 2 3 4 } >list list>array
+] unit-test
+
+[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
+  { 1 2 3 } >list { 4 5 } >list 2list lcartesian-product* list>array
+] unit-test
+
+[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
+  { 1 2 3 } >list { 4 5 } >list lcartesian-product list>array
+] unit-test
+
+[ { 5 6 6 7 7 8 } ] [ 
+  { 1 2 3 } >list { 4 5 } >list 2list [ first2 + ] lcomp list>array
+] unit-test
+
+[ { 5 6 7 8 } ] [ 
+  { 1 2 3 } >list { 4 5 } >list 2list { [ first odd? ] } [ first2 + ] lcomp* list>array
+] unit-test
+
+[ { 4 5 6 } ] [ 
+    3 { 1 2 3 } >list [ + ] with lazy-map list>array
+] unit-test
+
+[ [ ] lmap ] must-infer
+[ [ ] lmap>array ] must-infer
+[ [ drop ] foldr ] must-infer
+[ [ drop ] foldl ] must-infer
+[ [ drop ] leach ] must-infer
+[ lnth ] must-infer
diff --git a/basis/lists/lazy/lazy.factor b/basis/lists/lazy/lazy.factor
new file mode 100644 (file)
index 0000000..d3b08a1
--- /dev/null
@@ -0,0 +1,385 @@
+! Copyright (C) 2004, 2008 Chris Double, Matthew Willis, James Cash.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences math vectors arrays namespaces make
+quotations promises combinators io lists accessors call ;
+IN: lists.lazy
+
+M: promise car ( promise -- car )
+    force car ;
+
+M: promise cdr ( promise -- cdr )
+    force cdr ;
+
+M: promise nil? ( cons -- bool )
+    force nil? ;
+    
+! Both 'car' and 'cdr' are promises
+TUPLE: lazy-cons car cdr ;
+
+: lazy-cons ( car cdr -- promise )
+    [ promise ] bi@ \ lazy-cons boa
+    T{ promise f f t f } clone
+        swap >>value ;
+
+M: lazy-cons car ( lazy-cons -- car )
+    car>> force ;
+
+M: lazy-cons cdr ( lazy-cons -- cdr )
+    cdr>> force ;
+
+M: lazy-cons nil? ( lazy-cons -- bool )
+    nil eq? ;
+
+: 1lazy-list ( a -- lazy-cons )
+    [ nil ] lazy-cons ;
+
+: 2lazy-list ( a b -- lazy-cons )
+    1lazy-list 1quotation lazy-cons ;
+
+: 3lazy-list ( a b c -- lazy-cons )
+    2lazy-list 1quotation lazy-cons ;
+
+TUPLE: memoized-cons original car cdr nil? ;
+
+: not-memoized ( -- obj )
+    { } ;
+
+: not-memoized? ( obj -- bool )
+    not-memoized eq? ;
+
+: <memoized-cons> ( cons -- memoized-cons )
+    not-memoized not-memoized not-memoized
+    memoized-cons boa ;
+
+M: memoized-cons car ( memoized-cons -- car )
+    dup car>> not-memoized? [
+        dup original>> car [ >>car drop ] keep
+    ] [
+        car>>
+    ] if ;
+
+M: memoized-cons cdr ( memoized-cons -- cdr )
+    dup cdr>> not-memoized? [
+        dup original>> cdr [ >>cdr drop ] keep
+    ] [
+        cdr>>
+    ] if ;
+
+M: memoized-cons nil? ( memoized-cons -- bool )
+    dup nil?>> not-memoized? [
+        dup original>> nil?  [ >>nil? drop ] keep
+    ] [
+        nil?>>
+    ] if ;
+
+TUPLE: lazy-map cons quot ;
+
+C: <lazy-map> lazy-map
+
+: lazy-map ( list quot -- result )
+    over nil? [ 2drop nil ] [ <lazy-map> <memoized-cons> ] if ;
+
+M: lazy-map car ( lazy-map -- car )
+    [ cons>> car ] keep
+    quot>> call( old -- new ) ;
+
+M: lazy-map cdr ( lazy-map -- cdr )
+    [ cons>> cdr ] keep
+    quot>> lazy-map ;
+
+M: lazy-map nil? ( lazy-map -- bool )
+    cons>> nil? ;
+
+TUPLE: lazy-take n cons ;
+
+C: <lazy-take> lazy-take
+
+: ltake ( n list -- result )
+        over zero? [ 2drop nil ] [ <lazy-take> ] if ;
+
+M: lazy-take car ( lazy-take -- car )
+    cons>> car ;
+
+M: lazy-take cdr ( lazy-take -- cdr )
+    [ n>> 1- ] keep
+    cons>> cdr ltake ;
+
+M: lazy-take nil? ( lazy-take -- bool )
+    dup n>> zero? [
+        drop t
+    ] [
+        cons>> nil?
+    ] if ;
+
+TUPLE: lazy-until cons quot ;
+
+C: <lazy-until> lazy-until
+
+: luntil ( list quot -- result )
+    over nil? [ drop ] [ <lazy-until> ] if ;
+
+M: lazy-until car ( lazy-until -- car )
+     cons>> car ;
+
+M: lazy-until cdr ( lazy-until -- cdr )
+     [ cons>> unswons ] keep quot>> tuck call( elt -- ? )
+     [ 2drop nil ] [ luntil ] if ;
+
+M: lazy-until nil? ( lazy-until -- bool )
+     drop f ;
+
+TUPLE: lazy-while cons quot ;
+
+C: <lazy-while> lazy-while
+
+: lwhile ( list quot -- result )
+    over nil? [ drop ] [ <lazy-while> ] if ;
+
+M: lazy-while car ( lazy-while -- car )
+     cons>> car ;
+
+M: lazy-while cdr ( lazy-while -- cdr )
+     [ cons>> cdr ] keep quot>> lwhile ;
+
+M: lazy-while nil? ( lazy-while -- bool )
+     [ car ] keep quot>> call( elt -- ? ) not ;
+
+TUPLE: lazy-filter cons quot ;
+
+C: <lazy-filter> lazy-filter
+
+: lfilter ( list quot -- result )
+    over nil? [ 2drop nil ] [ <lazy-filter> <memoized-cons> ] if ;
+
+: car-filter? ( lazy-filter -- ? )
+    [ cons>> car ] [ quot>> ] bi call( elt -- ? ) ;
+
+: skip ( lazy-filter -- )
+    dup cons>> cdr >>cons drop ;
+
+M: lazy-filter car ( lazy-filter -- car )
+    dup car-filter? [ cons>> ] [ dup skip ] if car ;
+
+M: lazy-filter cdr ( lazy-filter -- cdr )
+    dup car-filter? [
+        [ cons>> cdr ] [ quot>> ] bi lfilter
+    ] [
+        dup skip cdr
+    ] if ;
+
+M: lazy-filter nil? ( lazy-filter -- bool )
+    dup cons>> nil? [
+        drop t
+    ] [
+        dup car-filter? [
+            drop f
+        ] [
+            dup skip nil?
+        ] if
+    ] if ;
+
+: list>vector ( list -- vector )
+    [ [ , ] leach ] V{ } make ;
+
+: list>array ( list -- array )
+    [ [ , ] leach ] { } make ;
+
+TUPLE: lazy-append list1 list2 ;
+
+C: <lazy-append> lazy-append
+
+: lappend ( list1 list2 -- result )
+    over nil? [ nip ] [ <lazy-append> ] if ;
+
+M: lazy-append car ( lazy-append -- car )
+    list1>> car ;
+
+M: lazy-append cdr ( lazy-append -- cdr )
+    [ list1>> cdr    ] keep
+    list2>> lappend ;
+
+M: lazy-append nil? ( lazy-append -- bool )
+     drop f ;
+
+TUPLE: lazy-from-by n quot ;
+
+C: lfrom-by lazy-from-by ( n quot -- list )
+
+: lfrom ( n -- list )
+    [ 1+ ] lfrom-by ;
+
+M: lazy-from-by car ( lazy-from-by -- car )
+    n>> ;
+
+M: lazy-from-by cdr ( lazy-from-by -- cdr )
+    [ n>> ] keep
+    quot>> [ call( old -- new ) ] keep lfrom-by ;
+
+M: lazy-from-by nil? ( lazy-from-by -- bool )
+    drop f ;
+
+TUPLE: lazy-zip list1 list2 ;
+
+C: <lazy-zip> lazy-zip
+
+: lzip ( list1 list2 -- lazy-zip )
+        over nil? over nil? or
+        [ 2drop nil ] [ <lazy-zip> ] if ;
+
+M: lazy-zip car ( lazy-zip -- car )
+        [ list1>> car ] keep list2>> car 2array ;
+
+M: lazy-zip cdr ( lazy-zip -- cdr )
+        [ list1>> cdr ] keep list2>> cdr lzip ;
+
+M: lazy-zip nil? ( lazy-zip -- bool )
+        drop f ;
+
+TUPLE: sequence-cons index seq ;
+
+C: <sequence-cons> sequence-cons
+
+: seq>list ( index seq -- list )
+    2dup length >= [
+        2drop nil
+    ] [
+        <sequence-cons>
+    ] if ;
+
+M: sequence-cons car ( sequence-cons -- car )
+    [ index>> ] keep
+    seq>> nth ;
+
+M: sequence-cons cdr ( sequence-cons -- cdr )
+    [ index>> 1+ ] keep
+    seq>> seq>list ;
+
+M: sequence-cons nil? ( sequence-cons -- bool )
+    drop f ;
+
+: >list ( object -- list )
+    {
+        { [ dup sequence? ] [ 0 swap seq>list ] }
+        { [ dup list?         ] [ ] }
+        [ "Could not convert object to a list" throw ]
+    } cond ;
+
+TUPLE: lazy-concat car cdr ;
+
+C: <lazy-concat> lazy-concat
+
+DEFER: lconcat
+
+: (lconcat) ( car cdr -- list )
+    over nil? [
+        nip lconcat
+    ] [
+        <lazy-concat>
+    ] if ;
+
+: lconcat ( list -- result )
+    dup nil? [
+        drop nil
+    ] [
+        uncons (lconcat)
+    ] if ;
+
+M: lazy-concat car ( lazy-concat -- car )
+    car>> car ;
+
+M: lazy-concat cdr ( lazy-concat -- cdr )
+    [ car>> cdr ] keep cdr>> (lconcat) ;
+
+M: lazy-concat nil? ( lazy-concat -- bool )
+    dup car>> nil? [
+        cdr>> nil?
+    ] [
+        drop f
+    ] if ;
+
+: lcartesian-product ( list1 list2 -- result )
+    swap [ swap [ 2array ] with lazy-map  ] with lazy-map  lconcat ;
+
+: lcartesian-product* ( lists -- result )
+    dup nil? [
+        drop nil
+    ] [
+        [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [
+            swap [ swap [ suffix ] with lazy-map  ] with lazy-map  lconcat
+        ] reduce
+    ] if ;
+
+: lcomp ( list quot -- result )
+    [ lcartesian-product* ] dip lazy-map ;
+
+: lcomp* ( list guards quot -- result )
+    [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lazy-map ;
+
+DEFER: lmerge
+
+: (lmerge) ( list1 list2 -- result )
+    over [ car ] curry -rot
+    [
+        dup [ car ] curry -rot
+        [
+            [ cdr ] bi@ lmerge
+        ] 2curry lazy-cons
+    ] 2curry lazy-cons ;
+
+: lmerge ( list1 list2 -- result )
+    {
+        { [ over nil? ] [ nip     ] }
+        { [ dup nil?    ]    [ drop ] }
+        { [ t                 ]    [ (lmerge) ] }
+    } cond ;
+
+TUPLE: lazy-io stream car cdr quot ;
+
+C: <lazy-io> lazy-io
+
+: lcontents ( stream -- result )
+    f f [ stream-read1 ] <lazy-io> ;
+
+: llines ( stream -- result )
+    f f [ stream-readln ] <lazy-io> ;
+
+M: lazy-io car ( lazy-io -- car )
+    dup car>> dup [
+        nip
+    ] [
+        drop dup stream>> over quot>>
+        call( stream -- value )
+        >>car
+    ] if ;
+
+M: lazy-io cdr ( lazy-io -- cdr )
+    dup cdr>> dup [
+        nip
+    ] [
+        drop dup
+        [ stream>> ] keep
+        [ quot>> ] keep
+        car [
+            [ f f ] dip <lazy-io> [ >>cdr drop ] keep
+        ] [
+            3drop nil
+        ] if
+    ] if ;
+
+M: lazy-io nil? ( lazy-io -- bool )
+    car not ;
+
+INSTANCE: sequence-cons list
+INSTANCE: memoized-cons list
+INSTANCE: promise list
+INSTANCE: lazy-io list
+INSTANCE: lazy-concat list
+INSTANCE: lazy-cons list
+INSTANCE: lazy-map list
+INSTANCE: lazy-take list
+INSTANCE: lazy-append list
+INSTANCE: lazy-from-by list
+INSTANCE: lazy-zip list
+INSTANCE: lazy-while list
+INSTANCE: lazy-until list
+INSTANCE: lazy-filter list
diff --git a/basis/lists/lazy/old-doc.html b/basis/lists/lazy/old-doc.html
new file mode 100644 (file)
index 0000000..4c04301
--- /dev/null
@@ -0,0 +1,361 @@
+<html>
+  <head>
+    <title>Lazy Evaluation</title>
+    <link rel="stylesheet" type="text/css" href="style.css">
+      </head>
+  <body>
+    <h1>Lazy Evaluation</h1>
+<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
+    ability to describe infinite structures, and to delay execution of
+    expressions until they are actually used.</p>
+<p>Lazy lists, like normal lists, are composed of a head and tail. In
+    a lazy list the head and tail are something called a 'promise'. 
+    To convert a
+    'promise' into its actual value a word called 'force' is used. To
+    convert a value into a 'promise' the word to use is 'delay'.</p>
+<table border="1">
+<tr><td><a href="#delay">delay</a></td></tr>
+<tr><td><a href="#force">force</a></td></tr>
+</table>
+
+<p>Many of the lazy list words are named similar to the standard list
+    words but with an 'l' suffixed to it. Here are the commonly used
+    words and their equivalent list operation:</p>
+<table border="1">
+<tr><th>Lazy List</th><th>Normal List</th></tr>
+<tr><td><a href="#lnil">lnil</a></td><td>[ ]</td></tr>
+<tr><td><a href="#lnilp">lnil?</a></td><td>Test for nil value</td></tr>
+<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
+<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
+<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
+<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
+<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
+<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
+<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
+<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
+<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
+<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
+</table>
+<p>A few additional words specific to lazy lists are:</p>
+<table border="1">
+<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
+number of items from the lazy list.</td></tr>
+<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
+concatenate them together in a lazy manner, returning a single lazy
+list.</td></tr>
+<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
+that contains the same elements as the normal list.</td></tr>
+</table>
+<h2>Reference</h2>
+<!-- delay description -->
+<a name="delay">
+<h3>delay ( quot -- &lt;promise&gt; )</h3>
+<p>'delay' is used to convert a value or expression into a promise.
+   The word 'force' is used to convert that promise back to its
+   value, or to force evaluation of the expression to return a value.
+</p>
+<p>The value on the stack that 'delay' expects must be quoted. This is
+   a requirement to prevent it from being evaluated.
+</p>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
+       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
+  ( 2 ) <a href="#force">force</a> .
+       => 42
+</pre>
+
+<!-- force description -->
+<a name="force">
+<h3>force ( &lt;promise&gt; -- value )</h3>
+<p>'force' will evaluate a promises original expression
+   and leave the value of that expression on the stack.
+</p>
+<p>A promise can be forced multiple times but the expression
+   is only evaluated once. Future calls of 'force' on the promise
+   will returned the cached value of the original force. If the
+   expression contains side effects, such as i/o, then that i/o
+   will only occur on the first 'force'. See below for an example
+   (steps 3-5).
+</p>
+<p>If a promise is itself delayed, a force will evaluate all promises
+   until a value is returned. Due to this behaviour it is generally not
+   possible to delay a promise. The example below shows what happens
+   in this case.
+</p>
+<pre class="code">       
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
+       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
+  ( 2 ) <a href="#force">force</a> .
+       => 42
+       
+        #! Multiple forces on a promise returns cached value
+  ( 3 ) [ "hello" print 42 ] <a href="#delay">delay</a> dup .
+       => << promise [ ] [ "hello" print 42 ] [ ] [ ] >>
+  ( 4 ) dup <a href="#force">force</a> .
+       => hello
+          42
+  ( 5 ) <a href="#force">force</a> .
+       => 42
+
+        #! Forcing a delayed promise cascades up to return
+        #! original value, rather than the promise.
+  ( 6 ) [ [ 42 ] <a href="#delay">delay</a> ] <a href="#delay">delay</a> dup .
+       => << promise [ ] [ [ 42 ] delay ] [ ] [ ] >>
+  ( 7 ) <a href="#force">force</a> .
+       => 42
+</pre>
+
+<!-- lnil description -->
+<a name="lnil">
+<h3>lnil ( -- lcons )</h3>
+<p>Returns a value representing the empty lazy list.</p>
+<pre class="code">
+  ( 1 ) <a href="#lnil">lnil</a> .
+       => << promise [ ] [ [ ] ] t [ ] >>
+</pre>
+
+<!-- lnil description -->
+<a name="lnilp">
+<h3>lnil? ( lcons -- bool )</h3>
+<p>Returns true if the given lazy cons is the value representing 
+   the empty lazy list.</p>
+<pre class="code">
+  ( 1 ) <a href="#lnil">lnil</a> <a href="#lnilp">lnil?</a> .
+       => t
+  ( 2 ) [ 1 ] <a href="#list2llist">list&gt;llist</a> dup <a href="#lnilp">lnil?</a> .
+       => [ ]
+  ( 3 ) <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
+       => t
+</pre>
+
+<!-- lcons description -->
+<a name="lcons">
+<h3>lcons ( car-promise cdr-promise -- lcons )</h3>
+<p>Provides the same effect as 'cons' does for normal lists. 
+   Both values provided must be promises (ie. expressions that have
+   had <a href="#delay">delay</a> called on them).
+</p>
+<p>As the car and cdr passed on the stack are promises, they are not
+   evaluated until <a href="#lcar">lcar</a> or <a href="#lcdr">lcdr</a>
+   are called on the lazy cons.</p>
+<pre class="code">
+  ( 1 ) [ "car" ] <a href="#delay">delay</a> [ "cdr" ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) dup <a href="#lcar">lcar</a> .
+       => "car"
+  ( 3 ) dup <a href="#lcdr">lcdr</a> .
+       => "cdr"
+</pre>
+  
+<!-- lunit description -->
+<a name="lunit">
+<h3>lunit ( value-promise -- llist )</h3>
+<p>Provides the same effect as 'unit' does for normal lists. It
+creates a lazy list where the first element is the value given.</p>
+<p>Like <a href="#lcons">lcons</a>, the value on the stack must be
+   a promise and is not evaluated until the <a href="#lcar">lcar</a>
+   of the list is requested.</a>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) dup <a href="#lcar">lcar</a> .
+       => 42
+  ( 3 ) dup <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
+       => t
+  ( 4 ) [ . ] <a href="#leach">leach</a>
+       => 42
+</pre>
+
+<!-- lcar description -->
+<a name="lcar">
+<h3>lcar ( lcons -- value )</h3>
+<p>Provides the same effect as 'car' does for normal lists. It
+returns the first element in a lazy cons cell. This will force
+the evaluation of that element.</p>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcar">lcar</a> .
+       => 42
+</pre>
+
+<!-- lcdr description -->
+<a name="lcdr">
+<h3>lcdr ( lcons -- value )</h3>
+<p>Provides the same effect as 'cdr' does for normal lists. It
+returns the second element in a lazy cons cell and forces it. This
+causes that element to be evaluated immediately.</p>
+<pre class="code">
+  ( 1 ) [ 1 ] <a href="#delay">delay</a> [ 5 6 + ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcdr">lcdr</a> .
+       => 11
+</pre>
+
+<pre class="code">
+  ( 1 ) 5 <a href="#lfrom">lfrom</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 6
+  ( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 7
+  ( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 8
+</pre>
+
+<!-- lnth description -->
+<a name="lnth">
+<h3>lnth ( n llist -- value )</h3>
+<p>Provides the same effect as 'nth' does for normal lists. It
+returns the nth value in the lazy list. It causes all the values up to
+'n' to be evaluated.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) 5 swap <a href="#lnth">lnth</a> .
+       => 6
+</pre>
+
+<!-- luncons description -->
+<a name="luncons">
+<h3>luncons ( lcons -- car cdr )</h3>
+<p>Provides the same effect as 'uncons' does for normal lists. It
+returns the car and cdr of the lazy list.</p>
+<pre class="code">
+  ( 1 ) [ 5 ] <a href="#delay">delay</a> [ 6 ] <a  href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#luncons">luncons</a> . .
+       => 6
+          5
+</pre>
+
+<!-- lmap description -->
+<a name="lmap">
+<h3>lmap ( llist quot -- llist )</h3>
+<p>Lazily maps over a lazy list applying the quotation to each element.
+A new lazy list is returned which contains the results of the
+quotation.</p>
+<p>When intially called nothing in the original lazy list is
+evaluated. Only when <a href="#lcar">lcar</a> is called will the item
+in the list be evaluated and applied to the quotation. Ditto with <a
+href="#lcdr">lcdr</a>, thus allowing infinite lists to be mapped over.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
+       => < infinite list of numbers incrementing by 2 >
+  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 2 4 6 8 10 ]
+</pre>
+
+<!-- lsubset description -->
+<a name="lsubset">
+<h3>lsubset ( llist pred -- llist )</h3>
+<p>Provides the same effect as 'subset' does for normal lists. It
+lazily iterates over a lazy list applying the predicate quotation to each
+element. If that quotation returns true, the element will be included
+in the resulting lazy list. If it is false, the element will be skipped.
+A new lazy list is returned which contains  all elements where the
+predicate returned true.</p>
+<p>Like <a href="#lmap">lmap</a>, when initially called no evaluation
+will occur. A lazy list is returned that when values are retrieved
+from in then items are evaluated and checked against the predicate.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ <a href="#primep">prime?</a> ] <a href="#lsubset">lsubset</a>
+       => < infinite list of prime numbers >
+  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 2 3 5 7 11 ]
+</pre>
+
+<!-- leach description -->
+<a name="leach">
+<h3>leach ( llist quot --  )</h3>
+<p>Provides the same effect as 'each' does for normal lists. It
+lazily iterates over a lazy list applying the quotation to each
+element. If this operation is applied to an infinite list it will
+never return unless the quotation escapes out by calling a continuation.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
+       => < infinite list of odd numbers >
+  ( 3 ) [ . ] <a href="#leach">leach</a> 
+       => 1
+          3
+          5
+          7
+          ... for ever ...
+</pre>
+
+<!-- ltake description -->
+<a name="ltake">
+<h3>ltake ( n llist -- llist )</h3>
+<p>Iterates over the lazy list 'n' times, appending each element to a
+lazy list. This provides a convenient way of getting elements out of
+an infinite lazy list.</p>
+<pre class="code">
+  ( 1 ) : ones [ 1 ] delay [ ones ] delay <a href="#lcons">lcons</a> ;
+  ( 2 ) 5 ones <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 1 1 1 1 1  ]
+</pre>
+
+<!-- lappend description -->
+<a name="lappend">
+<h3>lappend ( llist1 llist2 -- llist )</h3>
+<p>Lazily appends two lists together. The actual appending is done
+lazily on iteration rather than immediately so it works very fast no
+matter how large the list.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> <a href="#lappend">lappend</a>
+  ( 2 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+          4
+          5
+          6
+</pre>
+
+<!-- lappend* description -->
+<a name="lappendstar">
+<h3>lappend* ( llists -- llist )</h3>
+<p>Given a lazy list of lazy lists, concatenate them together in a
+lazy fashion. The actual appending is done lazily on iteration rather
+than immediately so it works very fast no matter how large the lists.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2>llist">list&gt;llist</a> 
+  ( 2 ) [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> 
+  ( 3 ) [ 7 8 9 ] <a href="#list2llist">list&gt;llist</a>
+  ( 4 ) 3list <a href="#list2llist">list&gt;llist</a> <a href="#lappendstar">lappend*</a>
+  ( 5 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+          4
+          5
+          6
+          7
+          8
+          9
+</pre>
+
+<!-- list>llist description -->
+<a name="list2llist">
+<h3>list&gt;llist ( list  -- llist )</h3>
+<p>Converts a normal list into a lazy list. This is done lazily so the
+initial list is not iterated through immediately.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> 
+  ( 2 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+</pre>
+
+<p class="footer">
+News and updates to this software can be obtained from the authors
+weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
+<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
+</body> </html>
diff --git a/basis/lists/lazy/summary.txt b/basis/lists/lazy/summary.txt
new file mode 100644 (file)
index 0000000..5d2f302
--- /dev/null
@@ -0,0 +1 @@
+Lazy lists
diff --git a/basis/lists/lazy/tags.txt b/basis/lists/lazy/tags.txt
new file mode 100644 (file)
index 0000000..dd23829
--- /dev/null
@@ -0,0 +1,2 @@
+extensions
+collections
diff --git a/basis/lists/lists-docs.factor b/basis/lists/lists-docs.factor
new file mode 100644 (file)
index 0000000..8494d7c
--- /dev/null
@@ -0,0 +1,187 @@
+! Copyright (C) 2006 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel help.markup help.syntax arrays sequences math quotations ;
+IN: lists
+
+ABOUT: "lists"
+
+ARTICLE: "lists" "Lists"
+"The " { $vocab-link "lists" } " vocabulary implements linked lists. There are simple strict linked lists, but a generic list protocol allows the implementation of lazy lists as well."
+{ $subsection { "lists" "protocol" } }
+{ $subsection { "lists" "strict" } }
+{ $subsection { "lists" "manipulation" } }
+{ $subsection { "lists" "combinators" } }
+{ $vocab-subsection "Lazy lists" "lists.lazy" } ;
+
+ARTICLE: { "lists" "protocol" } "The list protocol"
+"Lists are instances of a mixin class"
+{ $subsection list }
+"Instances of the mixin must implement the following words:"
+{ $subsection car }
+{ $subsection cdr }
+{ $subsection nil? } ;
+
+ARTICLE: { "lists" "strict" } "Strict lists"
+"Strict lists are simply cons cells where the car and cdr have already been evaluated. These are the lists of Lisp. To construct a strict list, the following words are provided:"
+{ $subsection cons }
+{ $subsection swons }
+{ $subsection sequence>cons }
+{ $subsection deep-sequence>cons }
+{ $subsection 1list }
+{ $subsection 2list }
+{ $subsection 3list } ;
+
+ARTICLE: { "lists" "combinators" } "Combinators for lists"
+"Several combinators exist for list traversal."
+{ $subsection leach }
+{ $subsection lmap }
+{ $subsection foldl }
+{ $subsection foldr }
+{ $subsection lmap>array }
+{ $subsection lmap-as }
+{ $subsection traverse } ;
+
+ARTICLE: { "lists" "manipulation" } "Manipulating lists"
+"To get at the contents of a list:"
+{ $subsection uncons }
+{ $subsection unswons }
+{ $subsection lnth }
+{ $subsection cadr }
+{ $subsection llength }
+"To get a new list from an old one:"
+{ $subsection lreverse }
+{ $subsection lappend }
+{ $subsection lcut } ;
+
+HELP: cons 
+{ $values { "car" "the head of the list cell" } { "cdr" "the tail of the list cell" } { "cons" "a cons object" } }
+{ $description "Constructs a cons cell." } ;
+
+HELP: swons 
+{ $values { "cdr" "the tail of the list cell" } { "car" "the head of the list cell" } { "cons" "a cons object" } }
+{ $description "Constructs a cons cell." } ;
+
+{ cons swons uncons unswons } related-words
+
+HELP: car
+{ $values { "cons" "a cons object" } { "car" "the first item in the list" } }
+{ $description "Returns the first item in the list." } ;
+
+HELP: cdr
+{ $values { "cons" "a cons object" } { "cdr" "a cons object" } }
+{ $description "Returns the tail of the list." } ;
+
+{ car cdr } related-words
+
+HELP: nil 
+{ $values { "symbol" "The empty cons (+nil+)" } }
+{ $description "Returns a symbol representing the empty list" } ;
+
+HELP: nil? 
+{ $values { "object" object } { "?" "a boolean" } }
+{ $description "Return true if the cons object is the nil cons." } ;
+
+{ nil nil? } related-words
+
+HELP: list? ( object -- ? )
+{ $values { "object" "an object" } { "?" "a boolean" } }
+{ $description "Returns true if the object conforms to the list protocol." } ;
+
+{ 1list 2list 3list } related-words
+
+HELP: 1list
+{ $values { "obj" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 1 element." } ;
+
+HELP: 2list
+{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 2 elements." } ;
+
+HELP: 3list
+{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 3 elements." } ;
+
+HELP: lnth
+{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } }
+{ $description "Outputs the nth element of the list." } 
+{ $see-also llength cons car cdr } ;
+
+HELP: llength
+{ $values { "list" "a cons object" } { "n" "a non-negative integer" } }
+{ $description "Outputs the length of the list. This should not be called on an infinite list." } 
+{ $see-also lnth cons car cdr } ;
+
+HELP: uncons
+{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } }
+{ $description "Put the head and tail of the list on the stack." } ;
+
+HELP: unswons
+{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } }
+{ $description "Put the head and tail of the list on the stack." } ;
+
+{ leach foldl lmap>array } related-words
+
+HELP: leach
+{ $values { "list" "a cons object" } { "quot" { $quotation "( obj -- )" } } }
+{ $description "Call the quotation for each item in the list." } ;
+
+HELP: foldl
+{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" { $quotation "( prev elt -- next )" } } { "result" "the final result" } }
+{ $description "Combines successive elements of the list (in a left-assocative order) using a binary operation and outputs the final result." } ;
+
+HELP: foldr
+{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" { $quotation "( prev elt -- next )" } } { "result" "the final result" } }
+{ $description "Combines successive elements of the list (in a right-assocative order) using a binary operation, and outputs the final result." } ;
+
+HELP: lmap
+{ $values { "list" "a cons object" } { "quot" { $quotation "( old -- new )" } } { "result" "the final result" } }
+{ $description "Applies the quotation to each element of the list in order, collecting the new elements into a new list." } ;
+
+HELP: lreverse
+{ $values { "list" list } { "newlist" list } }
+{ $description "Reverses the input list, outputing a new, reversed list. The output is a strict cons list." } ;
+
+HELP: list>array    
+{ $values { "list" "a cons object" } { "array" array } }
+{ $description "Turns the given cons object into an array, maintaing order." } ;
+
+HELP: sequence>cons
+{ $values { "sequence" sequence } { "list" cons } }
+{ $description "Turns the given array into a cons object, maintaing order." } ;
+
+HELP: deep-list>array
+{ $values { "list" list } { "array" array } }
+{ $description "Recursively turns the given cons object into an array, maintaing order and also converting nested lists." } ;
+
+HELP: deep-sequence>cons
+{ $values { "sequence" sequence } { "cons" cons } }
+{ $description "Recursively turns the given sequence into a cons object, maintaing order and also converting nested lists." } ;
+
+HELP: traverse    
+{ $values { "list"  "a cons object" } { "pred" { $quotation "( list/elt -- ? )" } }
+          { "quot" { $quotation "( list/elt -- result)" } }  { "result" "a new cons object" } }
+{ $description "Recursively traverses the list object, replacing any elements (which can themselves be sublists) that pred" 
+ " returns true for with the result of applying quot to." } ;
+
+HELP: list
+{ $class-description "The class of lists. All lists are expected to conform to " { $link { "lists" "protocol" } } "." } ;
+
+HELP: cadr
+{ $values { "list" list } { "elt" object } }
+{ $description "Returns the second element of the list, ie the car of the cdr." } ;
+
+HELP: lappend
+{ $values { "list1" list } { "list2" list } { "newlist" list } }
+{ $description "Appends the two lists to form a new list. The first list must be finite. The result is a strict cons cell, and the first list is exausted." } ;
+
+HELP: lcut
+{ $values { "list" list } { "index" integer } { "before" cons } { "after" cons } }
+{ $description "Analogous to " { $link cut } ", this word cuts a list into two pieces at the given index." } ;
+
+HELP: lmap>array
+{ $values { "list" list } { "quot" quotation } { "array" array } }
+{ $description "Executes the quotation on each element of the list, collecting the results in an array." } ;
+
+HELP: lmap-as
+{ $values { "list" list } { "quot" quotation } { "exemplar" sequence } { "sequence" sequence } }
+{ $description "Executes the quotation on each element of the list, collecting the results in a sequence of the type given by the exemplar." } ;
diff --git a/basis/lists/lists-tests.factor b/basis/lists/lists-tests.factor
new file mode 100644 (file)
index 0000000..13d2e03
--- /dev/null
@@ -0,0 +1,71 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test lists math kernel ;
+IN: lists.tests
+
+{ { 3 4 5 6 7 } } [
+    { 1 2 3 4 5 } sequence>cons [ 2 + ] lmap list>array
+] unit-test
+
+{ { 3 4 5 6 } } [
+    T{ cons f 1       
+        T{ cons f 2 
+            T{ cons f 3
+                T{ cons f 4
+                +nil+ } } } } [ 2 + ] lmap>array
+] unit-test
+
+{ 10 } [
+    T{ cons f 1       
+        T{ cons f 2 
+            T{ cons f 3
+                T{ cons f 4
+                +nil+ } } } } 0 [ + ] foldl
+] unit-test
+    
+{ T{ cons f
+      1
+      T{ cons f
+          2
+          T{ cons f
+              T{ cons f
+                  3
+                  T{ cons f
+                      4
+                      T{ cons f
+                          T{ cons f 5 +nil+ }
+                          +nil+ } } }
+          +nil+ } } }
+} [
+    { 1 2 { 3 4 { 5 } } } deep-sequence>cons
+] unit-test
+    
+{ { 1 2 { 3 4 { 5 } } } } [
+  { 1 2 { 3 4 { 5 } } } deep-sequence>cons deep-list>array
+] unit-test
+    
+{ T{ cons f 2 T{ cons f 3 T{ cons f 4 T{ cons f 5 +nil+ } } } } } [
+    { 1 2 3 4 } sequence>cons [ 1+ ] lmap
+] unit-test
+    
+{ 15 } [
+ { 1 2 3 4 5 } sequence>cons 0 [ + ] foldr
+] unit-test
+    
+{ { 5 4 3 2 1 } } [
+    { 1 2 3 4 5 } sequence>cons lreverse list>array
+] unit-test
+    
+{ 5 } [
+    { 1 2 3 4 5 } sequence>cons llength
+] unit-test
+    
+{ { 3 4 { 5 6 { 7 } } } } [
+  { 1 2 { 3 4 { 5 } } } deep-sequence>cons [ atom? ] [ 2 + ] traverse deep-list>array
+] unit-test
+    
+{ { 1 2 3 4 5 6 } } [
+    { 1 2 3 } sequence>cons { 4 5 6 } sequence>cons lappend list>array
+] unit-test
+
+[ { 1 } { 2 } ] [ { 1 2 } sequence>cons 1 lcut [ list>array ] bi@ ] unit-test
diff --git a/basis/lists/lists.factor b/basis/lists/lists.factor
new file mode 100644 (file)
index 0000000..4b0abb7
--- /dev/null
@@ -0,0 +1,147 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences accessors math arrays vectors classes words
+combinators.short-circuit combinators locals ;
+IN: lists
+
+! List Protocol
+MIXIN: list
+GENERIC: car ( cons -- car )
+GENERIC: cdr ( cons -- cdr )
+GENERIC: nil? ( object -- ?   )
+    
+TUPLE: cons { car read-only } { cdr read-only } ;
+
+C: cons cons
+
+M: cons car ( cons -- car )
+    car>> ;
+
+M: cons cdr ( cons -- cdr )
+    cdr>> ;
+
+SINGLETON: +nil+
+M: +nil+ nil? drop t ;
+M: object nil? drop f ;
+
+: atom? ( obj -- ? )
+    list? not ;
+
+: nil ( -- symbol ) +nil+ ; 
+
+: uncons ( cons -- car cdr )
+    [ car ] [ cdr ] bi ;
+
+: swons ( cdr car -- cons )
+    swap cons ;
+
+: unswons ( cons -- cdr car )
+    uncons swap ;
+
+: 1list ( obj -- cons )
+    nil cons ;
+
+: 1list? ( list -- ? )
+    { [ nil? not ] [ cdr nil? ] } 1&& ;
+
+: 2list ( a b -- cons )
+    nil cons cons ;
+
+: 3list ( a b c -- cons )
+    nil cons cons cons ;
+
+: cadr ( list -- elt )    
+    cdr car ;
+: 2car ( list -- car caar )    
+    [ car ] [ cdr car ] bi ;
+: 3car ( list -- car cadr caddr )    
+    [ car ] [ cdr car ] [ cdr cdr car ] tri ;
+
+: lnth ( n list -- elt )
+    swap [ cdr ] times car ;
+
+<PRIVATE
+: (leach) ( list quot -- cdr quot )
+    [ [ car ] dip call ] [ [ cdr ] dip ] 2bi ; inline
+PRIVATE>
+
+: leach ( list quot: ( elt -- ) -- )
+    over nil? [ 2drop ] [ (leach) leach ] if ; inline recursive
+
+: lmap ( list quot: ( elt -- ) -- result )
+    over nil? [ drop ] [ (leach) lmap cons ] if ; inline recursive
+
+: foldl ( list identity quot: ( obj1 obj2 -- obj ) -- result )
+    swapd leach ; inline
+
+:: foldr ( list identity quot: ( obj1 obj2 -- obj ) -- result )
+    list nil? [ identity ] [
+        list cdr identity quot foldr
+        list car quot call
+    ] if ; inline recursive
+
+: llength ( list -- n )
+    0 [ drop 1+ ] foldl ;
+
+: lreverse ( list -- newlist )    
+    nil [ swap cons ] foldl ;
+
+: lappend ( list1 list2 -- newlist )    
+    [ lreverse ] dip [ swap cons ] foldl ;
+
+: lcut ( list index -- before after )
+    [ nil ] dip
+    [ [ [ cdr ] [ car ] bi ] dip cons ] times
+    lreverse swap ;
+
+: sequence>cons ( sequence -- list )    
+    <reversed> nil [ swap cons ] reduce ;
+
+<PRIVATE
+: same? ( obj1 obj2 -- ? ) 
+    [ class ] bi@ = ;
+PRIVATE>
+
+: deep-sequence>cons ( sequence -- cons )
+    [ <reversed> ] keep nil
+    [ tuck same? [ deep-sequence>cons ] when swons ] with reduce ;
+
+<PRIVATE
+:: (lmap>vector) ( acc list quot: ( elt -- elt' ) -- acc )
+    list nil? [ acc ] [
+        list car quot call acc push
+        acc list cdr quot (lmap>vector)
+    ] if ; inline recursive
+
+: lmap>vector ( list quot -- array )
+    [ V{ } clone ] 2dip (lmap>vector) ; inline
+PRIVATE>
+
+: lmap-as ( list quot exemplar -- sequence )
+    [ lmap>vector ] dip like ; inline
+
+: lmap>array ( list quot -- array )
+    { } lmap-as ; inline
+
+: deep-list>array ( list -- array )    
+    [
+        {
+            { [ dup nil? ] [ drop { } ] }
+            { [ dup list? ] [ deep-list>array ] }
+            [ ]
+        } cond
+    ] lmap>array ;
+
+: list>array ( list -- array )    
+    [ ] lmap>array ;
+
+:: traverse ( list pred quot: ( list/elt -- result ) -- result )
+    list [| elt |
+        elt dup pred call [ quot call ] when
+        dup list? [ pred quot traverse ] when
+    ] lmap ; inline recursive
+
+INSTANCE: cons list
+INSTANCE: +nil+ list
diff --git a/basis/lists/summary.txt b/basis/lists/summary.txt
new file mode 100644 (file)
index 0000000..60a1886
--- /dev/null
@@ -0,0 +1 @@
+Implementation of lisp-style linked lists
diff --git a/basis/lists/tags.txt b/basis/lists/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/basis/math/blas/cblas/authors.txt b/basis/math/blas/cblas/authors.txt
deleted file mode 100644 (file)
index f13c9c1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Joe Groff
diff --git a/basis/math/blas/cblas/cblas.factor b/basis/math/blas/cblas/cblas.factor
deleted file mode 100644 (file)
index 2a2e9e3..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-USING: alien alien.c-types alien.syntax kernel system
-combinators ;
-IN: math.blas.cblas
-
-<<
-: load-atlas ( -- )
-    "atlas" "libatlas.so" "cdecl" add-library ;
-: load-fortran ( -- )
-    "I77" "libI77.so" "cdecl" add-library
-    "F77" "libF77.so" "cdecl" add-library ;
-: load-blas ( -- )
-    "blas" "libblas.so" "cdecl" add-library ;
-
-"cblas" {
-    { [ os macosx? ] [ "libblas.dylib" "cdecl" add-library ] }
-    { [ os windows? ] [ "blas.dll" "cdecl" add-library ] }
-    { [ os openbsd? ] [ "libcblas.so" "cdecl" add-library load-blas ] }
-    { [ os netbsd? ] [ 
-        load-fortran load-blas
-        "/usr/local/lib/libcblas.so" "cdecl" add-library
-    ] }
-    { [ os freebsd? ] [ "libcblas.so" "cdecl" add-library load-atlas ] }
-    [ "libblas.so" "cdecl" add-library ]
-} cond
->>
-
-LIBRARY: cblas
-
-TYPEDEF: int CBLAS_ORDER
-CONSTANT: CblasRowMajor 101
-CONSTANT: CblasColMajor 102
-
-TYPEDEF: int CBLAS_TRANSPOSE
-CONSTANT: CblasNoTrans   111
-CONSTANT: CblasTrans     112
-CONSTANT: CblasConjTrans 113
-
-TYPEDEF: int CBLAS_UPLO
-CONSTANT: CblasUpper 121
-CONSTANT: CblasLower 122
-
-TYPEDEF: int CBLAS_DIAG
-CONSTANT: CblasNonUnit 131
-CONSTANT: CblasUnit    132
-
-TYPEDEF: int CBLAS_SIDE
-CONSTANT: CblasLeft  141
-CONSTANT: CblasRight 142
-
-TYPEDEF: int CBLAS_INDEX
-
-C-STRUCT: float-complex
-    { "float" "real" }
-    { "float" "imag" } ;
-C-STRUCT: double-complex
-    { "double" "real" }
-    { "double" "imag" } ;
-
-! Level 1 BLAS (scalar-vector and vector-vector)
-
-FUNCTION: float  cblas_sdsdot
-    ( int N, float    alpha, float*   X, int incX, float*   Y, int incY ) ;
-FUNCTION: double cblas_dsdot
-    ( int N,                 float*   X, int incX, float*   Y, int incY ) ;
-FUNCTION: float  cblas_sdot
-    ( int N,                 float*   X, int incX, float*   Y, int incY ) ;
-FUNCTION: double cblas_ddot
-    ( int N,                 double*  X, int incX, double*  Y, int incY ) ;
-
-FUNCTION: void   cblas_cdotu_sub
-    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotu ) ;
-FUNCTION: void   cblas_cdotc_sub
-    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotc ) ;
-
-FUNCTION: void   cblas_zdotu_sub
-    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotu ) ;
-FUNCTION: void   cblas_zdotc_sub
-    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotc ) ;
-
-FUNCTION: float  cblas_snrm2
-    ( int N,                 float*   X, int incX ) ;
-FUNCTION: float  cblas_sasum
-    ( int N,                 float*   X, int incX ) ;
-
-FUNCTION: double cblas_dnrm2
-    ( int N,                 double*  X, int incX ) ;
-FUNCTION: double cblas_dasum
-    ( int N,                 double*  X, int incX ) ;
-
-FUNCTION: float  cblas_scnrm2
-    ( int N,                 void*    X, int incX ) ;
-FUNCTION: float  cblas_scasum
-    ( int N,                 void*    X, int incX ) ;
-
-FUNCTION: double cblas_dznrm2
-    ( int N,                 void*    X, int incX ) ;
-FUNCTION: double cblas_dzasum
-    ( int N,                 void*    X, int incX ) ;
-
-FUNCTION: CBLAS_INDEX cblas_isamax
-    ( int N,                 float*   X, int incX ) ;
-FUNCTION: CBLAS_INDEX cblas_idamax
-    ( int N,                 double*  X, int incX ) ;
-FUNCTION: CBLAS_INDEX cblas_icamax
-    ( int N,                 void*    X, int incX ) ;
-FUNCTION: CBLAS_INDEX cblas_izamax
-    ( int N,                 void*    X, int incX ) ;
-
-FUNCTION: void cblas_sswap
-    ( int N,                 float*   X, int incX, float*   Y, int incY ) ;
-FUNCTION: void cblas_scopy
-    ( int N,                 float*   X, int incX, float*   Y, int incY ) ;
-FUNCTION: void cblas_saxpy
-    ( int N, float    alpha, float*   X, int incX, float*   Y, int incY ) ;
-
-FUNCTION: void cblas_dswap
-    ( int N,                 double*  X, int incX, double*  Y, int incY ) ;
-FUNCTION: void cblas_dcopy
-    ( int N,                 double*  X, int incX, double*  Y, int incY ) ;
-FUNCTION: void cblas_daxpy
-    ( int N, double   alpha, double*  X, int incX, double*  Y, int incY ) ;
-
-FUNCTION: void cblas_cswap
-    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
-FUNCTION: void cblas_ccopy
-    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
-FUNCTION: void cblas_caxpy
-    ( int N, void*    alpha, void*    X, int incX, void*    Y, int incY ) ;
-
-FUNCTION: void cblas_zswap
-    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
-FUNCTION: void cblas_zcopy
-    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
-FUNCTION: void cblas_zaxpy
-    ( int N, void*    alpha, void*    X, int incX, void*    Y, int incY ) ;
-
-FUNCTION: void cblas_sscal
-    ( int N, float    alpha, float*   X, int incX ) ;
-FUNCTION: void cblas_dscal
-    ( int N, double   alpha, double*  X, int incX ) ;
-FUNCTION: void cblas_cscal
-    ( int N, void*    alpha, void*    X, int incX ) ;
-FUNCTION: void cblas_zscal
-    ( int N, void*    alpha, void*    X, int incX ) ;
-FUNCTION: void cblas_csscal
-    ( int N, float    alpha, void*    X, int incX ) ;
-FUNCTION: void cblas_zdscal
-    ( int N, double   alpha, void*    X, int incX ) ;
-
-FUNCTION: void cblas_srotg
-    ( float* a, float* b, float* c, float* s ) ;
-FUNCTION: void cblas_srotmg
-    ( float* d1, float* d2, float* b1, float b2, float* P ) ;
-FUNCTION: void cblas_srot
-    ( int N, float* X, int incX, float* Y, int incY, float c, float s ) ;
-FUNCTION: void cblas_srotm
-    ( int N, float* X, int incX, float* Y, int incY, float* P ) ;
-
-FUNCTION: void cblas_drotg
-    ( double* a, double* b, double* c, double* s ) ;
-FUNCTION: void cblas_drotmg
-    ( double* d1, double* d2, double* b1, double b2, double* P ) ;
-FUNCTION: void cblas_drot
-    ( int N, double* X, int incX, double* Y, int incY, double c, double s ) ;
-FUNCTION: void cblas_drotm
-    ( int N, double* X, int incX, double* Y, int incY, double* P ) ;
-! Level 2 BLAS (matrix-vector)
-
-FUNCTION: void cblas_sgemv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 float alpha, float* A, int lda,
-                 float* X, int incX, float beta,
-                 float* Y, int incY ) ;
-FUNCTION: void cblas_sgbmv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 int KL, int KU, float alpha,
-                 float* A, int lda, float* X,
-                 int incX, float beta, float* Y, int incY ) ;
-FUNCTION: void cblas_strmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, float* A, int lda,
-                 float* X, int incX ) ;
-FUNCTION: void cblas_stbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, float* A, int lda,
-                 float* X, int incX ) ;
-FUNCTION: void cblas_stpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, float* Ap, float* X, int incX ) ;
-FUNCTION: void cblas_strsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, float* A, int lda, float* X,
-                 int incX ) ;
-FUNCTION: void cblas_stbsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, float* A, int lda,
-                 float* X, int incX ) ;
-FUNCTION: void cblas_stpsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, float* Ap, float* X, int incX ) ;
-
-FUNCTION: void cblas_dgemv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 double alpha, double* A, int lda,
-                 double* X, int incX, double beta,
-                 double* Y, int incY ) ;
-FUNCTION: void cblas_dgbmv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 int KL, int KU, double alpha,
-                 double* A, int lda, double* X,
-                 int incX, double beta, double* Y, int incY ) ;
-FUNCTION: void cblas_dtrmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, double* A, int lda,
-                 double* X, int incX ) ;
-FUNCTION: void cblas_dtbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, double* A, int lda,
-                 double* X, int incX ) ;
-FUNCTION: void cblas_dtpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, double* Ap, double* X, int incX ) ;
-FUNCTION: void cblas_dtrsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, double* A, int lda, double* X,
-                 int incX ) ;
-FUNCTION: void cblas_dtbsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, double* A, int lda,
-                 double* X, int incX ) ;
-FUNCTION: void cblas_dtpsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, double* Ap, double* X, int incX ) ;
-
-FUNCTION: void cblas_cgemv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* X, int incX, void* beta,
-                 void* Y, int incY ) ;
-FUNCTION: void cblas_cgbmv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 int KL, int KU, void* alpha,
-                 void* A, int lda, void* X,
-                 int incX, void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_ctrmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ctbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ctpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* Ap, void* X, int incX ) ;
-FUNCTION: void cblas_ctrsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* A, int lda, void* X,
-                 int incX ) ;
-FUNCTION: void cblas_ctbsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ctpsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* Ap, void* X, int incX ) ;
-
-FUNCTION: void cblas_zgemv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* X, int incX, void* beta,
-                 void* Y, int incY ) ;
-FUNCTION: void cblas_zgbmv ( CBLAS_ORDER Order,
-                 CBLAS_TRANSPOSE TransA, int M, int N,
-                 int KL, int KU, void* alpha,
-                 void* A, int lda, void* X,
-                 int incX, void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_ztrmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ztbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ztpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* Ap, void* X, int incX ) ;
-FUNCTION: void cblas_ztrsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* A, int lda, void* X,
-                 int incX ) ;
-FUNCTION: void cblas_ztbsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, int K, void* A, int lda,
-                 void* X, int incX ) ;
-FUNCTION: void cblas_ztpsv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag,
-                 int N, void* Ap, void* X, int incX ) ;
-
-
-FUNCTION: void cblas_ssymv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, float alpha, float* A,
-                 int lda, float* X, int incX,
-                 float beta, float* Y, int incY ) ;
-FUNCTION: void cblas_ssbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, int K, float alpha, float* A,
-                 int lda, float* X, int incX,
-                 float beta, float* Y, int incY ) ;
-FUNCTION: void cblas_sspmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, float alpha, float* Ap,
-                 float* X, int incX,
-                 float beta, float* Y, int incY ) ;
-FUNCTION: void cblas_sger ( CBLAS_ORDER Order, int M, int N,
-                float alpha, float* X, int incX,
-                float* Y, int incY, float* A, int lda ) ;
-FUNCTION: void cblas_ssyr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, float* X,
-                int incX, float* A, int lda ) ;
-FUNCTION: void cblas_sspr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, float* X,
-                int incX, float* Ap ) ;
-FUNCTION: void cblas_ssyr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, float* X,
-                int incX, float* Y, int incY, float* A,
-                int lda ) ;
-FUNCTION: void cblas_sspr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, float* X,
-                int incX, float* Y, int incY, float* A ) ;
-
-FUNCTION: void cblas_dsymv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, double alpha, double* A,
-                 int lda, double* X, int incX,
-                 double beta, double* Y, int incY ) ;
-FUNCTION: void cblas_dsbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, int K, double alpha, double* A,
-                 int lda, double* X, int incX,
-                 double beta, double* Y, int incY ) ;
-FUNCTION: void cblas_dspmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, double alpha, double* Ap,
-                 double* X, int incX,
-                 double beta, double* Y, int incY ) ;
-FUNCTION: void cblas_dger ( CBLAS_ORDER Order, int M, int N,
-                double alpha, double* X, int incX,
-                double* Y, int incY, double* A, int lda ) ;
-FUNCTION: void cblas_dsyr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, double* X,
-                int incX, double* A, int lda ) ;
-FUNCTION: void cblas_dspr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, double* X,
-                int incX, double* Ap ) ;
-FUNCTION: void cblas_dsyr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, double* X,
-                int incX, double* Y, int incY, double* A,
-                int lda ) ;
-FUNCTION: void cblas_dspr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, double* X,
-                int incX, double* Y, int incY, double* A ) ;
-
-
-FUNCTION: void cblas_chemv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, void* alpha, void* A,
-                 int lda, void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_chbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, int K, void* alpha, void* A,
-                 int lda, void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_chpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, void* alpha, void* Ap,
-                 void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_cgeru ( CBLAS_ORDER Order, int M, int N,
-                 void* alpha, void* X, int incX,
-                 void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_cgerc ( CBLAS_ORDER Order, int M, int N,
-                 void* alpha, void* X, int incX,
-                 void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_cher ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, void* X, int incX,
-                void* A, int lda ) ;
-FUNCTION: void cblas_chpr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, float alpha, void* X,
-                int incX, void* A ) ;
-FUNCTION: void cblas_cher2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo, int N,
-                void* alpha, void* X, int incX,
-                void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_chpr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo, int N,
-                void* alpha, void* X, int incX,
-                void* Y, int incY, void* Ap ) ;
-
-FUNCTION: void cblas_zhemv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, void* alpha, void* A,
-                 int lda, void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_zhbmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, int K, void* alpha, void* A,
-                 int lda, void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_zhpmv ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 int N, void* alpha, void* Ap,
-                 void* X, int incX,
-                 void* beta, void* Y, int incY ) ;
-FUNCTION: void cblas_zgeru ( CBLAS_ORDER Order, int M, int N,
-                 void* alpha, void* X, int incX,
-                 void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_zgerc ( CBLAS_ORDER Order, int M, int N,
-                 void* alpha, void* X, int incX,
-                 void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_zher ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, void* X, int incX,
-                void* A, int lda ) ;
-FUNCTION: void cblas_zhpr ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                int N, double alpha, void* X,
-                int incX, void* A ) ;
-FUNCTION: void cblas_zher2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo, int N,
-                void* alpha, void* X, int incX,
-                void* Y, int incY, void* A, int lda ) ;
-FUNCTION: void cblas_zhpr2 ( CBLAS_ORDER Order, CBLAS_UPLO Uplo, int N,
-                void* alpha, void* X, int incX,
-                void* Y, int incY, void* Ap ) ;
-
-! Level 3 BLAS (matrix-matrix) 
-
-FUNCTION: void cblas_sgemm ( CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA,
-                 CBLAS_TRANSPOSE TransB, int M, int N,
-                 int K, float alpha, float* A,
-                 int lda, float* B, int ldb,
-                 float beta, float* C, int ldc ) ;
-FUNCTION: void cblas_ssymm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 float alpha, float* A, int lda,
-                 float* B, int ldb, float beta,
-                 float* C, int ldc ) ;
-FUNCTION: void cblas_ssyrk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 float alpha, float* A, int lda,
-                 float beta, float* C, int ldc ) ;
-FUNCTION: void cblas_ssyr2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  float alpha, float* A, int lda,
-                  float* B, int ldb, float beta,
-                  float* C, int ldc ) ;
-FUNCTION: void cblas_strmm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 float alpha, float* A, int lda,
-                 float* B, int ldb ) ;
-FUNCTION: void cblas_strsm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 float alpha, float* A, int lda,
-                 float* B, int ldb ) ;
-
-FUNCTION: void cblas_dgemm ( CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA,
-                 CBLAS_TRANSPOSE TransB, int M, int N,
-                 int K, double alpha, double* A,
-                 int lda, double* B, int ldb,
-                 double beta, double* C, int ldc ) ;
-FUNCTION: void cblas_dsymm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 double alpha, double* A, int lda,
-                 double* B, int ldb, double beta,
-                 double* C, int ldc ) ;
-FUNCTION: void cblas_dsyrk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 double alpha, double* A, int lda,
-                 double beta, double* C, int ldc ) ;
-FUNCTION: void cblas_dsyr2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  double alpha, double* A, int lda,
-                  double* B, int ldb, double beta,
-                  double* C, int ldc ) ;
-FUNCTION: void cblas_dtrmm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 double alpha, double* A, int lda,
-                 double* B, int ldb ) ;
-FUNCTION: void cblas_dtrsm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 double alpha, double* A, int lda,
-                 double* B, int ldb ) ;
-
-FUNCTION: void cblas_cgemm ( CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA,
-                 CBLAS_TRANSPOSE TransB, int M, int N,
-                 int K, void* alpha, void* A,
-                 int lda, void* B, int ldb,
-                 void* beta, void* C, int ldc ) ;
-FUNCTION: void cblas_csymm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb, void* beta,
-                 void* C, int ldc ) ;
-FUNCTION: void cblas_csyrk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 void* alpha, void* A, int lda,
-                 void* beta, void* C, int ldc ) ;
-FUNCTION: void cblas_csyr2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  void* alpha, void* A, int lda,
-                  void* B, int ldb, void* beta,
-                  void* C, int ldc ) ;
-FUNCTION: void cblas_ctrmm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb ) ;
-FUNCTION: void cblas_ctrsm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb ) ;
-
-FUNCTION: void cblas_zgemm ( CBLAS_ORDER Order, CBLAS_TRANSPOSE TransA,
-                 CBLAS_TRANSPOSE TransB, int M, int N,
-                 int K, void* alpha, void* A,
-                 int lda, void* B, int ldb,
-                 void* beta, void* C, int ldc ) ;
-FUNCTION: void cblas_zsymm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb, void* beta,
-                 void* C, int ldc ) ;
-FUNCTION: void cblas_zsyrk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 void* alpha, void* A, int lda,
-                 void* beta, void* C, int ldc ) ;
-FUNCTION: void cblas_zsyr2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  void* alpha, void* A, int lda,
-                  void* B, int ldb, void* beta,
-                  void* C, int ldc ) ;
-FUNCTION: void cblas_ztrmm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb ) ;
-FUNCTION: void cblas_ztrsm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA,
-                 CBLAS_DIAG Diag, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb ) ;
-
-FUNCTION: void cblas_chemm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb, void* beta,
-                 void* C, int ldc ) ;
-FUNCTION: void cblas_cherk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 float alpha, void* A, int lda,
-                 float beta, void* C, int ldc ) ;
-FUNCTION: void cblas_cher2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  void* alpha, void* A, int lda,
-                  void* B, int ldb, float beta,
-                  void* C, int ldc ) ;
-FUNCTION: void cblas_zhemm ( CBLAS_ORDER Order, CBLAS_SIDE Side,
-                 CBLAS_UPLO Uplo, int M, int N,
-                 void* alpha, void* A, int lda,
-                 void* B, int ldb, void* beta,
-                 void* C, int ldc ) ;
-FUNCTION: void cblas_zherk ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                 CBLAS_TRANSPOSE Trans, int N, int K,
-                 double alpha, void* A, int lda,
-                 double beta, void* C, int ldc ) ;
-FUNCTION: void cblas_zher2k ( CBLAS_ORDER Order, CBLAS_UPLO Uplo,
-                  CBLAS_TRANSPOSE Trans, int N, int K,
-                  void* alpha, void* A, int lda,
-                  void* B, int ldb, double beta,
-                  void* C, int ldc ) ;
-
diff --git a/basis/math/blas/cblas/summary.txt b/basis/math/blas/cblas/summary.txt
deleted file mode 100644 (file)
index c72e78e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Low-level bindings to the C Basic Linear Algebra Subroutines (BLAS) library
diff --git a/basis/math/blas/cblas/tags.txt b/basis/math/blas/cblas/tags.txt
deleted file mode 100644 (file)
index 241ec1e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-math
-bindings
diff --git a/basis/math/blas/ffi/authors.txt b/basis/math/blas/ffi/authors.txt
new file mode 100644 (file)
index 0000000..f13c9c1
--- /dev/null
@@ -0,0 +1 @@
+Joe Groff
diff --git a/basis/math/blas/ffi/ffi.factor b/basis/math/blas/ffi/ffi.factor
new file mode 100644 (file)
index 0000000..1749103
--- /dev/null
@@ -0,0 +1,522 @@
+USING: alien alien.fortran kernel system combinators ;
+IN: math.blas.ffi
+
+<<
+"blas" {
+    { [ 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
+>>
+
+LIBRARY: blas
+
+! Level 1 BLAS (scalar-vector and vector-vector)
+
+FUNCTION: REAL SDSDOT
+    ( INTEGER N, REAL ALPHA, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+FUNCTION: DOUBLE-PRECISION DSDOT
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+FUNCTION: REAL SDOT
+    ( INTEGER N, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+FUNCTION: DOUBLE-PRECISION DDOT
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+
+FUNCTION: COMPLEX CDOTU
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX, COMPLEX(*) Y, INTEGER INCY ) ;
+FUNCTION: COMPLEX CDOTC
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX, COMPLEX(*) Y, INTEGER INCY ) ;
+
+FUNCTION: DOUBLE-COMPLEX ZDOTU
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+FUNCTION: DOUBLE-COMPLEX ZDOTC
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+
+FUNCTION: REAL SNRM2
+    ( INTEGER N, REAL(*) X, INTEGER INCX ) ;
+FUNCTION: REAL SASUM
+    ( INTEGER N, REAL(*) X, INTEGER INCX ) ;
+
+FUNCTION: DOUBLE-PRECISION DNRM2
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+FUNCTION: DOUBLE-PRECISION DASUM
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+
+FUNCTION: REAL SCNRM2
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX ) ;
+FUNCTION: REAL SCASUM
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX ) ;
+
+FUNCTION: DOUBLE-PRECISION DZNRM2
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+FUNCTION: DOUBLE-PRECISION DZASUM
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+
+FUNCTION: INTEGER ISAMAX
+    ( INTEGER N, REAL(*) X, INTEGER INCX ) ;
+FUNCTION: INTEGER IDAMAX
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+FUNCTION: INTEGER ICAMAX
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX ) ;
+FUNCTION: INTEGER IZAMAX
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+
+SUBROUTINE: SSWAP
+    ( INTEGER N, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SCOPY
+    ( INTEGER N, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SAXPY
+    ( INTEGER N, REAL ALPHA, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY ) ;
+
+SUBROUTINE: DSWAP
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DCOPY
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DAXPY
+    ( INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+
+SUBROUTINE: CSWAP
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CCOPY
+    ( INTEGER N, COMPLEX(*) X, INTEGER INCX, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CAXPY
+    ( INTEGER N, COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX, COMPLEX(*) Y, INTEGER INCY ) ;
+
+SUBROUTINE: ZSWAP
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZCOPY
+    ( INTEGER N, DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZAXPY
+    ( INTEGER N, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+
+SUBROUTINE: SSCAL
+    ( INTEGER N, REAL ALPHA, REAL(*) X, INTEGER INCX ) ;
+SUBROUTINE: DSCAL
+    ( INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+SUBROUTINE: CSCAL
+    ( INTEGER N, COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZSCAL
+    ( INTEGER N, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: CSSCAL
+    ( INTEGER N, REAL ALPHA, COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZDSCAL
+    ( INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+
+SUBROUTINE: SROTG
+    ( REAL(*) A, REAL(*) B, REAL(*) C, REAL(*) S ) ;
+SUBROUTINE: SROTMG
+    ( REAL(*) D1, REAL(*) D2, REAL(*) B1, REAL B2, REAL(*) P ) ;
+SUBROUTINE: SROT
+    ( INTEGER N, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY, REAL C, REAL S ) ;
+SUBROUTINE: SROTM
+    ( INTEGER N, REAL(*) X, INTEGER INCX, REAL(*) Y, INTEGER INCY, REAL(*) P ) ;
+
+SUBROUTINE: DROTG
+    ( DOUBLE-PRECISION(*) A, DOUBLE-PRECISION(*) B, DOUBLE-PRECISION(*) C, DOUBLE-PRECISION(*) S ) ;
+SUBROUTINE: DROTMG
+    ( DOUBLE-PRECISION(*) D1, DOUBLE-PRECISION(*) D2, DOUBLE-PRECISION(*) B1, DOUBLE-PRECISION B2, DOUBLE-PRECISION(*) P ) ;
+SUBROUTINE: DROT
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY, DOUBLE-PRECISION C, DOUBLE-PRECISION S ) ;
+SUBROUTINE: DROTM
+    ( INTEGER N, DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY, DOUBLE-PRECISION(*) P ) ;
+! LEVEL 2 BLAS (MATRIX-VECTOR)
+
+SUBROUTINE: SGEMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 REAL ALPHA, REAL(*) A, INTEGER LDA,
+                 REAL(*) X, INTEGER INCX, REAL BETA,
+                 REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SGBMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 INTEGER KL, INTEGER KU, REAL ALPHA,
+                 REAL(*) A, INTEGER LDA, REAL(*) X,
+                 INTEGER INCX, REAL BETA, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: STRMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, REAL(*) A, INTEGER LDA,
+                 REAL(*) X, INTEGER INCX ) ;
+SUBROUTINE: STBMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, REAL(*) A, INTEGER LDA,
+                 REAL(*) X, INTEGER INCX ) ;
+SUBROUTINE: STPMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, REAL(*) AP, REAL(*) X, INTEGER INCX ) ;
+SUBROUTINE: STRSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, REAL(*) A, INTEGER LDA, REAL(*) X,
+                 INTEGER INCX ) ;
+SUBROUTINE: STBSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, REAL(*) A, INTEGER LDA,
+                 REAL(*) X, INTEGER INCX ) ;
+SUBROUTINE: STPSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, REAL(*) AP, REAL(*) X, INTEGER INCX ) ;
+
+SUBROUTINE: DGEMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) X, INTEGER INCX, DOUBLE-PRECISION BETA,
+                 DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DGBMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 INTEGER KL, INTEGER KU, DOUBLE-PRECISION ALPHA,
+                 DOUBLE-PRECISION(*) A, INTEGER LDA, DOUBLE-PRECISION(*) X,
+                 INTEGER INCX, DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DTRMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+SUBROUTINE: DTBMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+SUBROUTINE: DTPMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-PRECISION(*) AP, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+SUBROUTINE: DTRSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-PRECISION(*) A, INTEGER LDA, DOUBLE-PRECISION(*) X,
+                 INTEGER INCX ) ;
+SUBROUTINE: DTBSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+SUBROUTINE: DTPSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-PRECISION(*) AP, DOUBLE-PRECISION(*) X, INTEGER INCX ) ;
+
+SUBROUTINE: CGEMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) X, INTEGER INCX, COMPLEX BETA,
+                 COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CGBMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 INTEGER KL, INTEGER KU, COMPLEX ALPHA,
+                 COMPLEX(*) A, INTEGER LDA, COMPLEX(*) X,
+                 INTEGER INCX, COMPLEX BETA, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CTRMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: CTBMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: CTPMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, COMPLEX(*) AP, COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: CTRSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, COMPLEX(*) A, INTEGER LDA, COMPLEX(*) X,
+                 INTEGER INCX ) ;
+SUBROUTINE: CTBSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: CTPSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, COMPLEX(*) AP, COMPLEX(*) X, INTEGER INCX ) ;
+
+SUBROUTINE: ZGEMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) X, INTEGER INCX, DOUBLE-COMPLEX BETA,
+                 DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZGBMV ( CHARACTER*1 TRANSA, INTEGER M, INTEGER N,
+                 INTEGER KL, INTEGER KU, DOUBLE-COMPLEX ALPHA,
+                 DOUBLE-COMPLEX(*) A, INTEGER LDA, DOUBLE-COMPLEX(*) X,
+                 INTEGER INCX, DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZTRMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZTBMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZTPMV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-COMPLEX(*) AP, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZTRSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-COMPLEX(*) A, INTEGER LDA, DOUBLE-COMPLEX(*) X,
+                 INTEGER INCX ) ;
+SUBROUTINE: ZTBSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, INTEGER K, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+SUBROUTINE: ZTPSV ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANSA, CHARACTER*1 DIAG,
+                 INTEGER N, DOUBLE-COMPLEX(*) AP, DOUBLE-COMPLEX(*) X, INTEGER INCX ) ;
+
+
+SUBROUTINE: SSYMV ( CHARACTER*1 UPLO,
+                 INTEGER N, REAL ALPHA, REAL(*) A,
+                 INTEGER LDA, REAL(*) X, INTEGER INCX,
+                 REAL BETA, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SSBMV ( CHARACTER*1 UPLO,
+                 INTEGER N, INTEGER K, REAL ALPHA, REAL(*) A,
+                 INTEGER LDA, REAL(*) X, INTEGER INCX,
+                 REAL BETA, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SSPMV ( CHARACTER*1 UPLO,
+                 INTEGER N, REAL ALPHA, REAL(*) AP,
+                 REAL(*) X, INTEGER INCX,
+                 REAL BETA, REAL(*) Y, INTEGER INCY ) ;
+SUBROUTINE: SGER ( INTEGER M, INTEGER N,
+                REAL ALPHA, REAL(*) X, INTEGER INCX,
+                REAL(*) Y, INTEGER INCY, REAL(*) A, INTEGER LDA ) ;
+SUBROUTINE: SSYR ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, REAL(*) X,
+                INTEGER INCX, REAL(*) A, INTEGER LDA ) ;
+SUBROUTINE: SSPR ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, REAL(*) X,
+                INTEGER INCX, REAL(*) AP ) ;
+SUBROUTINE: SSYR2 ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, REAL(*) X,
+                INTEGER INCX, REAL(*) Y, INTEGER INCY, REAL(*) A,
+                INTEGER LDA ) ;
+SUBROUTINE: SSPR2 ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, REAL(*) X,
+                INTEGER INCX, REAL(*) Y, INTEGER INCY, REAL(*) A ) ;
+
+SUBROUTINE: DSYMV ( CHARACTER*1 UPLO,
+                 INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A,
+                 INTEGER LDA, DOUBLE-PRECISION(*) X, INTEGER INCX,
+                 DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DSBMV ( CHARACTER*1 UPLO,
+                 INTEGER N, INTEGER K, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A,
+                 INTEGER LDA, DOUBLE-PRECISION(*) X, INTEGER INCX,
+                 DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DSPMV ( CHARACTER*1 UPLO,
+                 INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) AP,
+                 DOUBLE-PRECISION(*) X, INTEGER INCX,
+                 DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) Y, INTEGER INCY ) ;
+SUBROUTINE: DGER ( INTEGER M, INTEGER N,
+                DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X, INTEGER INCX,
+                DOUBLE-PRECISION(*) Y, INTEGER INCY, DOUBLE-PRECISION(*) A, INTEGER LDA ) ;
+SUBROUTINE: DSYR ( CHARACTER*1 UPLO,
+                INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X,
+                INTEGER INCX, DOUBLE-PRECISION(*) A, INTEGER LDA ) ;
+SUBROUTINE: DSPR ( CHARACTER*1 UPLO,
+                INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X,
+                INTEGER INCX, DOUBLE-PRECISION(*) AP ) ;
+SUBROUTINE: DSYR2 ( CHARACTER*1 UPLO,
+                INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X,
+                INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY, DOUBLE-PRECISION(*) A,
+                INTEGER LDA ) ;
+SUBROUTINE: DSPR2 ( CHARACTER*1 UPLO,
+                INTEGER N, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) X,
+                INTEGER INCX, DOUBLE-PRECISION(*) Y, INTEGER INCY, DOUBLE-PRECISION(*) A ) ;
+
+
+SUBROUTINE: CHEMV ( CHARACTER*1 UPLO,
+                 INTEGER N, COMPLEX ALPHA, COMPLEX(*) A,
+                 INTEGER LDA, COMPLEX(*) X, INTEGER INCX,
+                 COMPLEX BETA, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CHBMV ( CHARACTER*1 UPLO,
+                 INTEGER N, INTEGER K, COMPLEX ALPHA, COMPLEX(*) A,
+                 INTEGER LDA, COMPLEX(*) X, INTEGER INCX,
+                 COMPLEX BETA, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CHPMV ( CHARACTER*1 UPLO,
+                 INTEGER N, COMPLEX ALPHA, COMPLEX(*) AP,
+                 COMPLEX(*) X, INTEGER INCX,
+                 COMPLEX BETA, COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: CGERU ( INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX,
+                 COMPLEX(*) Y, INTEGER INCY, COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: CGERC ( INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX,
+                 COMPLEX(*) Y, INTEGER INCY, COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: CHER ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, COMPLEX(*) X, INTEGER INCX,
+                COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: CHPR ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, COMPLEX(*) X,
+                INTEGER INCX, COMPLEX(*) A ) ;
+SUBROUTINE: CHER2 ( CHARACTER*1 UPLO, INTEGER N,
+                COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX,
+                COMPLEX(*) Y, INTEGER INCY, COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: CHPR2 ( CHARACTER*1 UPLO, INTEGER N,
+                COMPLEX ALPHA, COMPLEX(*) X, INTEGER INCX,
+                COMPLEX(*) Y, INTEGER INCY, COMPLEX(*) AP ) ;
+
+SUBROUTINE: ZHEMV ( CHARACTER*1 UPLO,
+                 INTEGER N, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A,
+                 INTEGER LDA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                 DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZHBMV ( CHARACTER*1 UPLO,
+                 INTEGER N, INTEGER K, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A,
+                 INTEGER LDA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                 DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZHPMV ( CHARACTER*1 UPLO,
+                 INTEGER N, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) AP,
+                 DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                 DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) Y, INTEGER INCY ) ;
+SUBROUTINE: ZGERU ( INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                 DOUBLE-COMPLEX(*) Y, INTEGER INCY, DOUBLE-COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: ZGERC ( INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                 DOUBLE-COMPLEX(*) Y, INTEGER INCY, DOUBLE-COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: ZHER ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                DOUBLE-COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: ZHPR ( CHARACTER*1 UPLO,
+                INTEGER N, REAL ALPHA, DOUBLE-COMPLEX(*) X,
+                INTEGER INCX, DOUBLE-COMPLEX(*) A ) ;
+SUBROUTINE: ZHER2 ( CHARACTER*1 UPLO, INTEGER N,
+                DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                DOUBLE-COMPLEX(*) Y, INTEGER INCY, DOUBLE-COMPLEX(*) A, INTEGER LDA ) ;
+SUBROUTINE: ZHPR2 ( CHARACTER*1 UPLO, INTEGER N,
+                DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) X, INTEGER INCX,
+                DOUBLE-COMPLEX(*) Y, INTEGER INCY, DOUBLE-COMPLEX(*) AP ) ;
+
+! LEVEL 3 BLAS (MATRIX-MATRIX) 
+
+SUBROUTINE: SGEMM ( CHARACTER*1 TRANSA,
+                 CHARACTER*1 TRANSB, INTEGER M, INTEGER N,
+                 INTEGER K, REAL ALPHA, REAL(*) A,
+                 INTEGER LDA, REAL(*) B, INTEGER LDB,
+                 REAL BETA, REAL(*) C, INTEGER LDC ) ;
+SUBROUTINE: SSYMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 REAL ALPHA, REAL(*) A, INTEGER LDA,
+                 REAL(*) B, INTEGER LDB, REAL BETA,
+                 REAL(*) C, INTEGER LDC ) ;
+SUBROUTINE: SSYRK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 REAL ALPHA, REAL(*) A, INTEGER LDA,
+                 REAL BETA, REAL(*) C, INTEGER LDC ) ;
+SUBROUTINE: SSYR2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  REAL ALPHA, REAL(*) A, INTEGER LDA,
+                  REAL(*) B, INTEGER LDB, REAL BETA,
+                  REAL(*) C, INTEGER LDC ) ;
+SUBROUTINE: STRMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 REAL ALPHA, REAL(*) A, INTEGER LDA,
+                 REAL(*) B, INTEGER LDB ) ;
+SUBROUTINE: STRSM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 REAL ALPHA, REAL(*) A, INTEGER LDA,
+                 REAL(*) B, INTEGER LDB ) ;
+
+SUBROUTINE: DGEMM ( CHARACTER*1 TRANSA,
+                 CHARACTER*1 TRANSB, INTEGER M, INTEGER N,
+                 INTEGER K, DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A,
+                 INTEGER LDA, DOUBLE-PRECISION(*) B, INTEGER LDB,
+                 DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) C, INTEGER LDC ) ;
+SUBROUTINE: DSYMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) B, INTEGER LDB, DOUBLE-PRECISION BETA,
+                 DOUBLE-PRECISION(*) C, INTEGER LDC ) ;
+SUBROUTINE: DSYRK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION BETA, DOUBLE-PRECISION(*) C, INTEGER LDC ) ;
+SUBROUTINE: DSYR2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                  DOUBLE-PRECISION(*) B, INTEGER LDB, DOUBLE-PRECISION BETA,
+                  DOUBLE-PRECISION(*) C, INTEGER LDC ) ;
+SUBROUTINE: DTRMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) B, INTEGER LDB ) ;
+SUBROUTINE: DTRSM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 DOUBLE-PRECISION ALPHA, DOUBLE-PRECISION(*) A, INTEGER LDA,
+                 DOUBLE-PRECISION(*) B, INTEGER LDB ) ;
+
+SUBROUTINE: CGEMM ( CHARACTER*1 TRANSA,
+                 CHARACTER*1 TRANSB, INTEGER M, INTEGER N,
+                 INTEGER K, COMPLEX ALPHA, COMPLEX(*) A,
+                 INTEGER LDA, COMPLEX(*) B, INTEGER LDB,
+                 COMPLEX BETA, COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CSYMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) B, INTEGER LDB, COMPLEX BETA,
+                 COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CSYRK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX BETA, COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CSYR2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                  COMPLEX(*) B, INTEGER LDB, COMPLEX BETA,
+                  COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CTRMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) B, INTEGER LDB ) ;
+SUBROUTINE: CTRSM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) B, INTEGER LDB ) ;
+
+SUBROUTINE: ZGEMM ( CHARACTER*1 TRANSA,
+                 CHARACTER*1 TRANSB, INTEGER M, INTEGER N,
+                 INTEGER K, DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A,
+                 INTEGER LDA, DOUBLE-COMPLEX(*) B, INTEGER LDB,
+                 DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZSYMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) B, INTEGER LDB, DOUBLE-COMPLEX BETA,
+                 DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZSYRK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX BETA, DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZSYR2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                  DOUBLE-COMPLEX(*) B, INTEGER LDB, DOUBLE-COMPLEX BETA,
+                  DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZTRMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) B, INTEGER LDB ) ;
+SUBROUTINE: ZTRSM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, CHARACTER*1 TRANSA,
+                 CHARACTER*1 DIAG, INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) B, INTEGER LDB ) ;
+
+SUBROUTINE: CHEMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 COMPLEX(*) B, INTEGER LDB, COMPLEX BETA,
+                 COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CHERK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 REAL ALPHA, COMPLEX(*) A, INTEGER LDA,
+                 REAL BETA, COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: CHER2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  COMPLEX ALPHA, COMPLEX(*) A, INTEGER LDA,
+                  COMPLEX(*) B, INTEGER LDB, REAL BETA,
+                  COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZHEMM ( CHARACTER*1 SIDE,
+                 CHARACTER*1 UPLO, INTEGER M, INTEGER N,
+                 DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 DOUBLE-COMPLEX(*) B, INTEGER LDB, DOUBLE-COMPLEX BETA,
+                 DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZHERK ( CHARACTER*1 UPLO,
+                 CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                 REAL ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                 REAL BETA, DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
+SUBROUTINE: ZHER2K ( CHARACTER*1 UPLO,
+                  CHARACTER*1 TRANS, INTEGER N, INTEGER K,
+                  DOUBLE-COMPLEX ALPHA, DOUBLE-COMPLEX(*) A, INTEGER LDA,
+                  DOUBLE-COMPLEX(*) B, INTEGER LDB, REAL BETA,
+                  DOUBLE-COMPLEX(*) C, INTEGER LDC ) ;
diff --git a/basis/math/blas/ffi/summary.txt b/basis/math/blas/ffi/summary.txt
new file mode 100644 (file)
index 0000000..8c0106b
--- /dev/null
@@ -0,0 +1 @@
+Low-level bindings to the Basic Linear Algebra Subroutines (BLAS) library
diff --git a/basis/math/blas/ffi/tags.txt b/basis/math/blas/ffi/tags.txt
new file mode 100644 (file)
index 0000000..f468a99
--- /dev/null
@@ -0,0 +1,3 @@
+math
+bindings
+fortran
index f20a565e1f437a925f1d24552bf6d476c56c0100..17d2f9ccd1cb83feb17c771800953e5b501308f1 100644 (file)
@@ -8,40 +8,40 @@ ARTICLE: "math.blas-summary" "Basic Linear Algebra Subroutines (BLAS) interface"
 { $subsection "math.blas.vectors" }
 "Vector-matrix and matrix-matrix operations are available in the " { $vocab-link "math.blas.matrices" } " vocabulary:"
 { $subsection "math.blas.matrices" }
-"The low-level BLAS C interface can be accessed directly through the " { $vocab-link "math.blas.cblas" } " vocabulary." ;
+"The low-level BLAS Fortran interface can be accessed directly through the " { $vocab-link "math.blas.ffi" } " vocabulary." ;
 
 ARTICLE: "math.blas-types" "BLAS interface types"
 "BLAS vectors come in single- and double-precision, real and complex flavors:"
 { $subsection float-blas-vector }
 { $subsection double-blas-vector }
-{ $subsection float-complex-blas-vector }
-{ $subsection double-complex-blas-vector }
+{ $subsection complex-float-blas-vector }
+{ $subsection complex-double-blas-vector }
 "These vector types all follow the " { $link sequence } " protocol. In addition, there are corresponding types for matrix data:"
 { $subsection float-blas-matrix }
 { $subsection double-blas-matrix }
-{ $subsection float-complex-blas-matrix }
-{ $subsection double-complex-blas-matrix } 
+{ $subsection complex-float-blas-matrix }
+{ $subsection complex-double-blas-matrix } 
 "There are BOA constructors for all vector and matrix types, which provide the most flexibility in specifying memory layout:"
 { $subsection <float-blas-vector> }
 { $subsection <double-blas-vector> }
-{ $subsection <float-complex-blas-vector> }
-{ $subsection <double-complex-blas-vector> }
+{ $subsection <complex-float-blas-vector> }
+{ $subsection <complex-double-blas-vector> }
 { $subsection <float-blas-matrix> }
 { $subsection <double-blas-matrix> }
-{ $subsection <float-complex-blas-matrix> }
-{ $subsection <double-complex-blas-matrix> }
+{ $subsection <complex-float-blas-matrix> }
+{ $subsection <complex-double-blas-matrix> }
 "For the simple case of creating a dense, zero-filled vector or matrix, simple empty object constructors are provided:"
 { $subsection <empty-vector> }
 { $subsection <empty-matrix> }
 "BLAS vectors and matrices can also be constructed from other Factor sequences:"
 { $subsection >float-blas-vector }
 { $subsection >double-blas-vector }
-{ $subsection >float-complex-blas-vector }
-{ $subsection >double-complex-blas-vector }
+{ $subsection >complex-float-blas-vector }
+{ $subsection >complex-double-blas-vector }
 { $subsection >float-blas-matrix }
 { $subsection >double-blas-matrix }
-{ $subsection >float-complex-blas-matrix }
-{ $subsection >double-complex-blas-matrix } ;
+{ $subsection >complex-float-blas-matrix }
+{ $subsection >complex-double-blas-matrix } ;
 
 ARTICLE: "math.blas.matrices" "BLAS interface matrix operations"
 "Transposing and slicing matrices:"
@@ -87,8 +87,8 @@ HELP: blas-matrix-base
 { $list
     { { $link float-blas-matrix } }
     { { $link double-blas-matrix } }
-    { { $link float-complex-blas-matrix } }
-    { { $link double-complex-blas-matrix } }
+    { { $link complex-float-blas-matrix } }
+    { { $link complex-double-blas-matrix } }
 }
 "All of these subclasses share the same tuple layout:"
 { $list
@@ -104,14 +104,14 @@ HELP: float-blas-matrix
 { $class-description "A matrix of single-precision floating-point values. For details on the tuple layout, see " { $link blas-matrix-base } "." } ;
 HELP: double-blas-matrix
 { $class-description "A matrix of double-precision floating-point values. For details on the tuple layout, see " { $link blas-matrix-base } "." } ;
-HELP: float-complex-blas-matrix
+HELP: complex-float-blas-matrix
 { $class-description "A matrix of single-precision floating-point complex values. Complex values are stored in memory as two consecutive float values, real part then imaginary part. For details on the tuple layout, see " { $link blas-matrix-base } "." } ;
-HELP: double-complex-blas-matrix
+HELP: complex-double-blas-matrix
 { $class-description "A matrix of double-precision floating-point complex values. Complex values are stored in memory as two consecutive float values, real part then imaginary part. For details on the tuple layout, see " { $link blas-matrix-base } "." } ;
 
 {
-    float-blas-matrix double-blas-matrix float-complex-blas-matrix double-complex-blas-matrix
-    float-blas-vector double-blas-vector float-complex-blas-vector double-complex-blas-vector
+    float-blas-matrix double-blas-matrix complex-float-blas-matrix complex-double-blas-matrix
+    float-blas-vector double-blas-vector complex-float-blas-vector complex-double-blas-vector
 } related-words
 
 HELP: Mwidth
@@ -272,7 +272,7 @@ HELP: cmatrix{
     { 0.0 0.0          -1.0 3.0           }
     { 0.0 0.0           0.0 C{ 0.0 -1.0 } }
 } "> }
-{ $description "Construct a literal " { $link float-complex-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
+{ $description "Construct a literal " { $link complex-float-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
 
 HELP: zmatrix{
 { $syntax <" zmatrix{
@@ -281,7 +281,7 @@ HELP: zmatrix{
     { 0.0 0.0          -1.0 3.0           }
     { 0.0 0.0           0.0 C{ 0.0 -1.0 } }
 } "> }
-{ $description "Construct a literal " { $link double-complex-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
+{ $description "Construct a literal " { $link complex-double-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
 
 {
     POSTPONE: smatrix{ POSTPONE: dmatrix{
index d9653fca6f3792ccb9b128368b3be625b05c56f0..6fad54550104b00adeb1cbb463b52a65ddced9e8 100755 (executable)
@@ -1,11 +1,13 @@
 USING: accessors alien alien.c-types arrays byte-arrays combinators
 combinators.short-circuit fry kernel locals macros
-math math.blas.cblas math.blas.vectors math.blas.vectors.private
+math math.blas.ffi math.blas.vectors math.blas.vectors.private
 math.complex math.functions math.order functors words
 sequences sequences.merged sequences.private shuffle
 specialized-arrays.direct.float specialized-arrays.direct.double
 specialized-arrays.float specialized-arrays.double
-parser prettyprint.backend prettyprint.custom ;
+specialized-arrays.direct.complex-float specialized-arrays.direct.complex-double
+specialized-arrays.complex-float specialized-arrays.complex-double
+parser prettyprint.backend prettyprint.custom ascii ;
 IN: math.blas.matrices
 
 TUPLE: blas-matrix-base underlying ld rows cols transpose ;
@@ -25,7 +27,7 @@ GENERIC: n*M.M+n*M! ( alpha A B beta C -- C=alpha*A.B+beta*C )
 <PRIVATE
 
 : (blas-transpose) ( matrix -- integer )
-    transpose>> [ CblasTrans ] [ CblasNoTrans ] if ;
+    transpose>> [ "T" ] [ "N" ] if ;
 
 GENERIC: (blas-matrix-like) ( data ld rows cols transpose exemplar -- matrix )
 
@@ -38,73 +40,70 @@ GENERIC: (blas-matrix-like) ( data ld rows cols transpose exemplar -- matrix )
     unless ;
 
 :: (prepare-gemv)
-    ( alpha A x beta y >c-arg -- order A-trans m n alpha A-data A-ld x-data x-inc beta y-data y-inc
-                                 y )
+    ( alpha A x beta y -- A-trans m n alpha A-data A-ld x-data x-inc beta y-data y-inc
+                          y )
     A x y (validate-gemv)
-    CblasColMajor
     A (blas-transpose)
     A rows>>
     A cols>>
-    alpha >c-arg call
-    A underlying>>
+    alpha
+    A
     A ld>>
-    x underlying>>
+    x
     x inc>>
-    beta >c-arg call
-    y underlying>>
+    beta
+    y
     y inc>>
     y ; inline
 
 : (validate-ger) ( x y A -- )
     {
-        [ nip  [ length>> ] [ Mheight ] bi* = ]
-        [ nipd [ length>> ] [ Mwidth  ] bi* = ]
+        [ [ length>> ] [ drop     ] [ Mheight ] tri* = ]
+        [ [ drop     ] [ length>> ] [ Mwidth  ] tri* = ]
     } 3&&
     [ "Mismatched vertices and matrix in vector outer product" throw ]
     unless ;
 
 :: (prepare-ger)
-    ( alpha x y A >c-arg -- order m n alpha x-data x-inc y-data y-inc A-data A-ld
-                            A )
+    ( alpha x y A -- m n alpha x-data x-inc y-data y-inc A-data A-ld
+                     A )
     x y A (validate-ger)
-    CblasColMajor
     A rows>>
     A cols>>
-    alpha >c-arg call
-    x underlying>>
+    alpha
+    x
     x inc>>
-    y underlying>>
+    y
     y inc>>
-    A underlying>>
+    A
     A ld>>
     A f >>transpose ; inline
 
 : (validate-gemm) ( A B C -- )
     {
-        [ drop [ Mwidth  ] [ Mheight ] bi* = ]
-        [ nip  [ Mheight ] bi@ = ]
-        [ nipd [ Mwidth  ] bi@ = ]
+        [ [ Mwidth  ] [ Mheight ] [ drop    ] tri* = ]
+        [ [ Mheight ] [ drop    ] [ Mheight ] tri* = ]
+        [ [ drop    ] [ Mwidth  ] [ Mwidth  ] tri* = ]
     } 3&&
     [ "Mismatched matrices in matrix multiplication" throw ]
     unless ;
 
 :: (prepare-gemm)
-    ( alpha A B beta C >c-arg -- order A-trans B-trans m n k alpha A-data A-ld B-data B-ld beta C-data C-ld
-                                 C )
+    ( alpha A B beta C -- A-trans B-trans m n k alpha A-data A-ld B-data B-ld beta C-data C-ld
+                          C )
     A B C (validate-gemm)
-    CblasColMajor
     A (blas-transpose)
     B (blas-transpose)
     C rows>>
     C cols>>
     A Mwidth
-    alpha >c-arg call
-    A underlying>>
+    alpha
+    A
     A ld>>
-    B underlying>>
+    B
     B ld>>
-    beta >c-arg call
-    C underlying>>
+    beta
+    C
     C ld>>
     C f >>transpose ; inline
 
@@ -250,16 +249,18 @@ FUNCTOR: (define-blas-matrix) ( TYPE T U C -- )
 VECTOR      IS ${TYPE}-blas-vector
 <VECTOR>    IS <${TYPE}-blas-vector>
 >ARRAY      IS >${TYPE}-array
-TYPE>ARG    IS ${TYPE}>arg
-XGEMV       IS cblas_${T}gemv
-XGEMM       IS cblas_${T}gemm
-XGERU       IS cblas_${T}ger${U}
-XGERC       IS cblas_${T}ger${C}
+XGEMV       IS ${T}GEMV
+XGEMM       IS ${T}GEMM
+XGERU       IS ${T}GER${U}
+XGERC       IS ${T}GER${C}
 
 MATRIX      DEFINES-CLASS ${TYPE}-blas-matrix
 <MATRIX>    DEFINES <${TYPE}-blas-matrix>
 >MATRIX     DEFINES >${TYPE}-blas-matrix
-XMATRIX{    DEFINES ${T}matrix{
+
+t           [ T >lower ]
+
+XMATRIX{    DEFINES ${t}matrix{
 
 WHERE
 
@@ -277,21 +278,16 @@ M: MATRIX (blas-vector-like)
     drop <VECTOR> ;
 
 : >MATRIX ( arrays -- matrix )
-    [ >ARRAY underlying>> ] (>matrix)
-    <MATRIX> ;
+    [ >ARRAY underlying>> ] (>matrix) <MATRIX> ;
 
 M: VECTOR n*M.V+n*V!
-    [ TYPE>ARG ] (prepare-gemv)
-    [ XGEMV ] dip ;
+    (prepare-gemv) [ XGEMV ] dip ;
 M: MATRIX n*M.M+n*M!
-    [ TYPE>ARG ] (prepare-gemm)
-    [ XGEMM ] dip ;
+    (prepare-gemm) [ XGEMM ] dip ;
 M: MATRIX n*V(*)V+M!
-    [ TYPE>ARG ] (prepare-ger)
-    [ XGERU ] dip ;
+    (prepare-ger) [ XGERU ] dip ;
 M: MATRIX n*V(*)Vconj+M!
-    [ TYPE>ARG ] (prepare-ger)
-    [ XGERC ] dip ;
+    (prepare-ger) [ XGERC ] dip ;
 
 : XMATRIX{ \ } [ >MATRIX ] parse-literal ; parsing
 
@@ -304,12 +300,12 @@ M: MATRIX pprint-delims
 : define-real-blas-matrix ( TYPE T -- )
     "" "" (define-blas-matrix) ;
 : define-complex-blas-matrix ( TYPE T -- )
-    "u" "c" (define-blas-matrix) ;
+    "U" "C" (define-blas-matrix) ;
 
-"float"          "s" define-real-blas-matrix
-"double"         "d" define-real-blas-matrix
-"float-complex"  "c" define-complex-blas-matrix
-"double-complex" "z" define-complex-blas-matrix
+"float"          "S" define-real-blas-matrix
+"double"         "D" define-real-blas-matrix
+"complex-float"  "C" define-complex-blas-matrix
+"complex-double" "Z" define-complex-blas-matrix
 
 >>
 
index ede10ab61b276dbb377d546a34593c7eee6b06f5..241ec1ecdaa6949fae47e4cca431ec44632d36f7 100644 (file)
@@ -1 +1,2 @@
 math
+bindings
index b37a4b966ea3684282296f2ed67047f7e9d7548d..badc3171896dd484d36141f15234b659d266bdd3 100644 (file)
@@ -37,8 +37,8 @@ HELP: blas-vector-base
 { $list
     { { $link float-blas-vector } }
     { { $link double-blas-vector } }
-    { { $link float-complex-blas-vector } }
-    { { $link double-complex-blas-vector } }
+    { { $link complex-float-blas-vector } }
+    { { $link complex-double-blas-vector } }
 }
 "All of these subclasses share the same tuple layout:"
 { $list
@@ -51,10 +51,10 @@ HELP: float-blas-vector
 { $class-description "A vector of single-precision floating-point values. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
 HELP: double-blas-vector
 { $class-description "A vector of double-precision floating-point values. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
-HELP: float-complex-blas-vector
-{ $class-description "A vector of single-precision floating-point complex values. Complex values are stored in memory as two consecutive float values, real part then imaginary part. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
-HELP: double-complex-blas-vector
-{ $class-description "A vector of single-precision floating-point complex values. Complex values are stored in memory as two consecutive float values, real part then imaginary part. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
+HELP: complex-float-blas-vector
+{ $class-description "A vector of single-precision floating-point complex values. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
+HELP: complex-double-blas-vector
+{ $class-description "A vector of double-precision floating-point complex values. For details on the tuple layout, see " { $link blas-vector-base } "." } ;
 
 HELP: n*V+V!
 { $values { "alpha" number } { "x" blas-vector-base } { "y" blas-vector-base } { "y=alpha*x+y" blas-vector-base } }
@@ -93,7 +93,7 @@ HELP: Viamax
 
 HELP: Vamax
 { $values { "x" blas-vector-base } { "max" number } }
-{ $description "Return the value of the element in " { $snippet "x" } " with the largest norm-1. If more than one element has the same norm-1, returns the first element. Corresponds to the IxAMAX routines in BLAS." } ;
+{ $description "Return the value of the element in " { $snippet "x" } " with the largest norm-1. If more than one element has the same norm-1, returns the element closest to the beginning. Corresponds to the IxAMAX routines in BLAS." } ;
 
 { Viamax Vamax } related-words
 
@@ -145,11 +145,11 @@ HELP: dvector{
 
 HELP: cvector{
 { $syntax "cvector{ 1.0 -2.0 C{ 3.0 -1.0 } }" }
-{ $description "Construct a literal " { $link float-complex-blas-vector } "." } ;
+{ $description "Construct a literal " { $link complex-float-blas-vector } "." } ;
 
 HELP: zvector{
 { $syntax "dvector{ 1.0 -2.0 C{ 3.0 -1.0 } }" }
-{ $description "Construct a literal " { $link double-complex-blas-vector } "." } ;
+{ $description "Construct a literal " { $link complex-double-blas-vector } "." } ;
 
 {
     POSTPONE: svector{ POSTPONE: dvector{
index da271a4fc7d4b1f4fa015ce93f9c8d1a8bb1efe6..ef2f7ad6f98515be38672a8b6a2770ca01710382 100644 (file)
@@ -1,4 +1,4 @@
-USING: kernel math.blas.vectors sequences tools.test ;
+USING: kernel math.blas.vectors math.functions sequences tools.test ;
 IN: math.blas.vectors.tests
 
 ! clone
@@ -126,11 +126,11 @@ unit-test
 
 ! Vnorm
 
-[ 5.0 ] [ svector{ 3.0 4.0 } Vnorm ] unit-test
-[ 5.0 ] [ dvector{ 3.0 4.0 } Vnorm ] unit-test
+[ t ] [ svector{ 3.0 4.0 } Vnorm 5.0 0.000001 ~ ] unit-test
+[ t ] [ dvector{ 3.0 4.0 } Vnorm 5.0 0.000001 ~ ] unit-test
 
-[ 13.0 ] [ cvector{ C{ 3.0 4.0 } 12.0 } Vnorm ] unit-test
-[ 13.0 ] [ zvector{ C{ 3.0 4.0 } 12.0 } Vnorm ] unit-test
+[ t ] [ cvector{ C{ 3.0 4.0 } 12.0 } Vnorm 13.0 0.000001 ~ ] unit-test
+[ t ] [ zvector{ C{ 3.0 4.0 } 12.0 } Vnorm 13.0 0.000001 ~ ] unit-test
 
 ! Vasum
 
index 4e61f4478e7b2f3a41b3b7f498bfec47e0c8f1f3..84b5fd9e6f707490ca013ac89a3c997e93a71daa 100755 (executable)
@@ -1,10 +1,12 @@
-USING: accessors alien alien.c-types arrays byte-arrays combinators
-combinators.short-circuit fry kernel math math.blas.cblas
-math.complex math.functions math.order sequences.complex
-sequences.complex-components sequences sequences.private
+USING: accessors alien alien.c-types arrays ascii byte-arrays combinators
+combinators.short-circuit fry kernel math math.blas.ffi
+math.complex math.functions math.order sequences sequences.private
 functors words locals parser prettyprint.backend prettyprint.custom
 specialized-arrays.float specialized-arrays.double
-specialized-arrays.direct.float specialized-arrays.direct.double ;
+specialized-arrays.direct.float specialized-arrays.direct.double
+specialized-arrays.complex-float specialized-arrays.complex-double
+specialized-arrays.direct.complex-float
+specialized-arrays.direct.complex-double ;
 IN: math.blas.vectors
 
 TUPLE: blas-vector-base underlying length inc ;
@@ -31,7 +33,7 @@ GENERIC: (blas-direct-array) ( blas-vector -- direct-array )
 : shorter-length ( v1 v2 -- length )
     [ length>> ] bi@ min ; inline
 : data-and-inc ( v -- data inc )
-    [ underlying>> ] [ inc>> ] bi ; inline
+    [ ] [ inc>> ] bi ; inline
 : datas-and-incs ( v1 v2 -- v1-data v1-inc v2-data v2-inc )
     [ data-and-inc ] bi@ ; inline
 
@@ -130,15 +132,20 @@ FUNCTOR: (define-blas-vector) ( TYPE T -- )
 
 <DIRECT-ARRAY> IS <direct-${TYPE}-array>
 >ARRAY         IS >${TYPE}-array
-XCOPY          IS cblas_${T}copy
-XSWAP          IS cblas_${T}swap
-IXAMAX         IS cblas_i${T}amax
+XCOPY          IS ${T}COPY
+XSWAP          IS ${T}SWAP
+IXAMAX         IS I${T}AMAX
 
 VECTOR         DEFINES-CLASS ${TYPE}-blas-vector
 <VECTOR>       DEFINES <${TYPE}-blas-vector>
 >VECTOR        DEFINES >${TYPE}-blas-vector
 
-XVECTOR{       DEFINES ${T}vector{
+t              [ T >lower ]
+
+XVECTOR{       DEFINES ${t}vector{
+
+XAXPY          IS ${T}AXPY
+XSCAL          IS ${T}SCAL
 
 WHERE
 
@@ -157,7 +164,7 @@ M: VECTOR element-type
 M: VECTOR Vswap
     (prepare-swap) [ XSWAP ] 2dip ;
 M: VECTOR Viamax
-    (prepare-nrm2) IXAMAX ;
+    (prepare-nrm2) IXAMAX 1- ;
 
 M: VECTOR (blas-vector-like)
     drop <VECTOR> ;
@@ -167,6 +174,11 @@ M: VECTOR (blas-direct-array)
     [ [ length>> ] [ inc>> ] bi * ] bi
     <DIRECT-ARRAY> ;
 
+M: VECTOR n*V+V!
+    (prepare-axpy) [ XAXPY ] dip ;
+M: VECTOR n*V!
+    (prepare-scal) [ XSCAL ] dip ;
+
 : XVECTOR{ \ } [ >VECTOR ] parse-literal ; parsing
 
 M: VECTOR pprint-delims
@@ -178,11 +190,9 @@ M: VECTOR pprint-delims
 FUNCTOR: (define-real-blas-vector) ( TYPE T -- )
 
 VECTOR         IS ${TYPE}-blas-vector
-XDOT           IS cblas_${T}dot
-XNRM2          IS cblas_${T}nrm2
-XASUM          IS cblas_${T}asum
-XAXPY          IS cblas_${T}axpy
-XSCAL          IS cblas_${T}scal
+XDOT           IS ${T}DOT
+XNRM2          IS ${T}NRM2
+XASUM          IS ${T}ASUM
 
 WHERE
 
@@ -194,33 +204,6 @@ M: VECTOR Vnorm
     (prepare-nrm2) XNRM2 ;
 M: VECTOR Vasum
     (prepare-nrm2) XASUM ;
-M: VECTOR n*V+V!
-    (prepare-axpy) [ XAXPY ] dip ;
-M: VECTOR n*V!
-    (prepare-scal) [ XSCAL ] dip ;
-
-;FUNCTOR
-
-
-FUNCTOR: (define-complex-helpers) ( TYPE -- )
-
-<DIRECT-COMPLEX-ARRAY> DEFINES <direct-${TYPE}-complex-array>
->COMPLEX-ARRAY         DEFINES >${TYPE}-complex-array
-ARG>COMPLEX            DEFINES arg>${TYPE}-complex
-COMPLEX>ARG            DEFINES ${TYPE}-complex>arg
-<DIRECT-ARRAY>         IS      <direct-${TYPE}-array>
->ARRAY                 IS      >${TYPE}-array
-
-WHERE
-
-: <DIRECT-COMPLEX-ARRAY> ( alien len -- sequence )
-    1 shift <DIRECT-ARRAY> <complex-sequence> ;
-: >COMPLEX-ARRAY ( sequence -- sequence )
-    <complex-components> >ARRAY ;
-: COMPLEX>ARG ( complex -- alien )
-    >rect 2array >ARRAY underlying>> ;
-: ARG>COMPLEX ( alien -- complex )
-    2 <DIRECT-ARRAY> first2 rect> ;
 
 ;FUNCTOR
 
@@ -228,35 +211,21 @@ WHERE
 FUNCTOR: (define-complex-blas-vector) ( TYPE C S -- )
 
 VECTOR         IS ${TYPE}-blas-vector
-XDOTU_SUB      IS cblas_${C}dotu_sub
-XDOTC_SUB      IS cblas_${C}dotc_sub
-XXNRM2         IS cblas_${S}${C}nrm2
-XXASUM         IS cblas_${S}${C}asum
-XAXPY          IS cblas_${C}axpy
-XSCAL          IS cblas_${C}scal
-TYPE>ARG       IS ${TYPE}>arg
-ARG>TYPE       IS arg>${TYPE}
+XDOTU          IS ${C}DOTU
+XDOTC          IS ${C}DOTC
+XXNRM2         IS ${S}${C}NRM2
+XXASUM         IS ${S}${C}ASUM
 
 WHERE
 
 M: VECTOR V.
-    (prepare-dot) TYPE <c-object>
-    [ XDOTU_SUB ] keep
-    ARG>TYPE ;
+    (prepare-dot) XDOTU ;
 M: VECTOR V.conj
-    (prepare-dot) TYPE <c-object>
-    [ XDOTC_SUB ] keep
-    ARG>TYPE ;
+    (prepare-dot) XDOTC ;
 M: VECTOR Vnorm
     (prepare-nrm2) XXNRM2 ;
 M: VECTOR Vasum
     (prepare-nrm2) XXASUM ;
-M: VECTOR n*V+V!
-    [ TYPE>ARG ] 2dip
-    (prepare-axpy) [ XAXPY ] dip ;
-M: VECTOR n*V!
-    [ TYPE>ARG ] dip
-    (prepare-scal) [ XSCAL ] dip ;
 
 ;FUNCTOR
 
@@ -264,16 +233,14 @@ M: VECTOR n*V!
 : define-real-blas-vector ( TYPE T -- )
     [ (define-blas-vector) ]
     [ (define-real-blas-vector) ] 2bi ;
-:: define-complex-blas-vector ( TYPE C S -- )
-    TYPE (define-complex-helpers)
-    TYPE "-complex" append
-    [ C (define-blas-vector) ]
-    [ C S (define-complex-blas-vector) ] bi ;
-
-"float"  "s" define-real-blas-vector
-"double" "d" define-real-blas-vector
-"float"  "c" "s" define-complex-blas-vector
-"double" "z" "d" define-complex-blas-vector
+: define-complex-blas-vector ( TYPE C S -- )
+    [ drop (define-blas-vector) ]
+    [ (define-complex-blas-vector) ] 3bi ;
+
+"float"  "S" define-real-blas-vector
+"double" "D" define-real-blas-vector
+"complex-float"  "C" "S" define-complex-blas-vector
+"complex-double" "Z" "D" define-complex-blas-vector
 
 >>
 
index 1ece3d915e0b434fe9436a27d6b2c8f56b55efb8..749bde3a10caebeb082d7869cd7fba4827ac4d49 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel make math math.order math.vectors sequences shuffle
+USING: arrays kernel make math math.order math.vectors sequences
     splitting vectors ;
 IN: math.polynomials
 
@@ -75,7 +75,7 @@ PRIVATE>
 PRIVATE>
 
 : pgcd ( p q -- a d )
-    swap V{ 0 } clone V{ 1 } clone 2swap (pgcd) [ >array ] bi@ ;
+    [ V{ 0 } clone V{ 1 } clone ] 2dip swap (pgcd) [ >array ] bi@ ;
 
 : pdiff ( p -- p' )
     dup length v* { 0 } ?head drop ;
index 9078817206c54f9e961c71f2e52ab0117a77d8f3..27cba6d6e729b22a7e45bd01a31e25b5c2642edc 100755 (executable)
@@ -87,12 +87,12 @@ CONSTANT: packed-length-table
         { CHAR: D 8 }
     }
 
+PRIVATE>
+
 MACRO: pack ( str -- quot )
     [ pack-table at '[ _ execute ] ] { } map-as
     '[ [ [ _ spread ] input<sequence ] B{ } append-outputs-as ] ;
 
-PRIVATE>
-
 : ch>packed-length ( ch -- n )
     packed-length-table at ; inline
 
@@ -113,14 +113,14 @@ PRIVATE>
 : start/end ( seq -- seq1 seq2 )
     [ 0 [ + ] accumulate nip dup ] keep v+ ; inline
 
+PRIVATE>
+
 MACRO: unpack ( str -- quot )
     [ [ ch>packed-length ] { } map-as start/end ]
     [ [ unpack-table at '[ @ ] ] { } map-as ] bi
     [ '[ [ _ _ ] dip <slice> @ ] ] 3map
     '[ [ _ cleave ] output>array ] ;
 
-PRIVATE>
-
 : unpack-native ( seq str -- seq )
     '[ _ _ unpack ] with-native-endian ; inline
 
index 43018bed163b2ee92a8b8dcb88f185fc2324ddec..f1027d107ba046a3f0247787314edaa2a291dd7a 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2008 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
 USING: help.markup help.syntax kernel sequences ;
 IN: persistent.deques
 
index be63d807b9796aca54e38fdb224b88795c63b095..8f93ae1ab81cd568230b7de7e3b6b507c9b586b7 100644 (file)
@@ -1,7 +1,6 @@
-! Copyback (C) 2008 Daniel Ehrenberg
+! Copyright (C) 2008 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors math ;
-QUALIFIED: sequences
+USING: kernel accessors math lists sequences combinators.short-circuit ;
 IN: persistent.deques
 
 ! Amortized O(1) push/pop on both ends for single-threaded access
@@ -9,32 +8,13 @@ IN: persistent.deques
 !   same source, it could take O(m) amortized time per update.
 
 <PRIVATE
-TUPLE: cons { car read-only } { cdr read-only } ;
-C: <cons> cons
-
-: each ( list quot: ( elt -- ) -- )
-    over
-    [ [ [ car>> ] dip call ] [ [ cdr>> ] dip ] 2bi each ]
-    [ 2drop ] if ; inline recursive
-
-: reduce ( list start quot -- end )
-    swapd each ; inline
-
-: reverse ( list -- reversed )
-    f [ swap <cons> ] reduce ;
-
-: length ( list -- length )
-    0 [ drop 1+ ] reduce ;
-
-: cut ( list index -- back front-reversed )
-    f swap [ [ [ cdr>> ] [ car>> ] bi ] dip <cons> ] times ;
-
 : split-reverse ( list -- back-reversed front )
-    dup length 2/ cut [ reverse ] bi@ ;
+    dup llength 2/ lcut lreverse swap ;
 PRIVATE>
 
 TUPLE: deque { front read-only } { back read-only } ;
-: <deque> ( -- deque ) T{ deque } ;
+: <deque> ( -- deque )
+    T{ deque f +nil+ +nil+ } ;
 
 <PRIVATE
 : flip ( deque -- newdeque )
@@ -45,11 +25,11 @@ TUPLE: deque { front read-only } { back read-only } ;
 PRIVATE>
 
 : deque-empty? ( deque -- ? )
-    [ front>> ] [ back>> ] bi or not ;
+    { [ front>> nil? ] [ back>> nil? ] } 1&& ;
 
 <PRIVATE
 : push ( item deque -- newdeque )
-    [ front>> <cons> ] [ back>> ] bi deque boa ; inline
+    [ front>> cons ] [ back>> ] bi deque boa ; inline
 PRIVATE>
 
 : push-front ( deque item -- newdeque )
@@ -60,14 +40,15 @@ PRIVATE>
 
 <PRIVATE
 : remove ( deque -- item newdeque )
-    [ front>> car>> ] [ [ front>> cdr>> ] [ back>> ] bi deque boa ] bi ; inline
+    [ front>> car ] [ [ front>> cdr ] [ back>> ] bi deque boa ] bi ; inline
 
 : transfer ( deque -- item newdeque )
-    back>> [ split-reverse deque boa remove ]
-    [ "Popping from an empty deque" throw ] if* ; inline
+    back>> dup nil?
+    [ "Popping from an empty deque" throw ]
+    [ split-reverse deque boa remove ] if ; inline
 
 : pop ( deque -- item newdeque )
-    dup front>> [ remove ] [ transfer ] if ; inline
+    dup front>> nil? [ transfer ] [ remove ] if ; inline
 PRIVATE>
 
 : pop-front ( deque -- item newdeque )
@@ -76,12 +57,14 @@ PRIVATE>
 : pop-back ( deque -- item newdeque )
     [ pop ] flipped ;
 
-: peek-front ( deque -- item ) pop-front drop ;
+: peek-front ( deque -- item )
+    pop-front drop ;
 
-: peek-back ( deque -- item ) pop-back drop ;
+: peek-back ( deque -- item )
+    pop-back drop ;
 
 : sequence>deque ( sequence -- deque )
-    <deque> [ push-back ] sequences:reduce ;
+    <deque> [ push-back ] reduce ;
 
 : deque>sequence ( deque -- sequence )
-    [ dup deque-empty? not ] [ pop-front swap ] [ ] sequences:produce nip ;
+    [ dup deque-empty? not ] [ pop-front swap ] [ ] produce nip ;
index d8c25eda18ffcea56cc2a0a759c7d48f20fb3747..104a6c2ce1c2159445e2ba8175d55520e5e295b1 100644 (file)
@@ -2,8 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators kernel math
 quotations sequences regexp.parser regexp.classes fry arrays
-combinators.short-circuit regexp.utils prettyprint regexp.nfa
-shuffle ;
+combinators.short-circuit regexp.utils prettyprint regexp.nfa ;
 IN: regexp.traversal
 
 TUPLE: dfa-traverser
@@ -170,7 +169,7 @@ M: capture-group-off flag-action ( dfa-traverser flag -- )
     ] [ drop ] if ;
 
 : match-default ( transition from-state table -- to-state/f )
-    nipd transitions>> at t swap at ;
+    [ drop ] 2dip transitions>> at t swap at ;
 
 : match-transition ( obj from-state dfa -- to-state/f )
     { [ match-literal ] [ match-class ] [ match-default ] } 3|| ;
index f190544e198aef7a4998bb8b7ecc0aaca28e9754..e091af2d06eed05140c14b02db1d38d48bbac411 100644 (file)
@@ -1,5 +1,5 @@
 USING: shuffle tools.test ;
 
-[ 8 ] [ 5 6 7 8 3nip ] unit-test
-[ 3 1 2 3 ] [ 1 2 3 tuckd ] unit-test
 [ 1 2 3 4 ] [ 3 4 1 2 2swap ] unit-test
+
+[ 4 2 3 ] [ 1 2 3 4 shuffle( a b c d -- d b c ) ] unit-test
index b195e4abf903bd261d199d61741af8a4577cc9b7..6cae048d2764290f7ca9371725068f0fd894f95e 100644 (file)
@@ -1,19 +1,29 @@
 ! Copyright (C) 2007 Chris Double, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel generalizations ;
-
+USING: accessors assocs combinators effects.parser generalizations
+hashtables kernel locals locals.backend macros make math
+parser sequences ;
 IN: shuffle
 
-: 2swap ( x y z t -- z t x y ) 2 2 mnswap ; inline
+<PRIVATE
+
+: >index-assoc ( sequence -- assoc )
+    dup length zip >hashtable ;
 
-: nipd ( a b c -- b c ) rot drop ; inline
+PRIVATE>
 
-: 3nip ( a b c d -- d ) 3 nnip ; inline
+MACRO: shuffle-effect ( effect -- )
+    [ out>> ] [ in>> >index-assoc ] bi
+    [
+        [ nip assoc-size , \ narray , ]
+        [ [ at \ swap \ nth [ ] 3sequence ] curry map , \ cleave , ] 2bi
+    ] [ ] make ;
 
-: 4nip ( a b c d e -- e ) 4 nnip ; inline
+: shuffle(
+    ")" parse-effect parsed \ shuffle-effect parsed ; parsing
+
+: 2swap ( x y z t -- z t x y ) 2 2 mnswap ; inline
 
 : 4dup ( a b c d -- a b c d a b c d ) 4 ndup ; inline
 
 : 4drop ( a b c d -- ) 3drop drop ; inline
-
-: tuckd ( x y z -- z x y z ) 2 ntuck ; inline
diff --git a/basis/specialized-arrays/complex-double/complex-double-tests.factor b/basis/specialized-arrays/complex-double/complex-double-tests.factor
new file mode 100644 (file)
index 0000000..9f2bcc9
--- /dev/null
@@ -0,0 +1,13 @@
+USING: kernel sequences specialized-arrays.complex-double tools.test ;
+IN: specialized-arrays.complex-double.tests
+
+[ C{ 3.0 2.0 } ]
+[ complex-double-array{ 1.0 C{ 3.0 2.0 } 5.0 } second ] unit-test
+
+[ C{ 1.0 0.0 } ]
+[ complex-double-array{ 1.0 C{ 3.0 2.0 } 5.0 } first ] unit-test
+
+[ complex-double-array{ 1.0 C{ 6.0 -7.0 } 5.0 } ] [
+    complex-double-array{ 1.0 C{ 3.0 2.0 } 5.0 } 
+    dup [ C{ 6.0 -7.0 } 1 ] dip set-nth
+] unit-test
diff --git a/basis/specialized-arrays/complex-double/complex-double.factor b/basis/specialized-arrays/complex-double/complex-double.factor
new file mode 100644 (file)
index 0000000..00b07fb
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.complex-double
+
+<< "complex-double" define-array >>
diff --git a/basis/specialized-arrays/complex-float/complex-float.factor b/basis/specialized-arrays/complex-float/complex-float.factor
new file mode 100644 (file)
index 0000000..5348343
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.complex-float
+
+<< "complex-float" define-array >>
diff --git a/basis/specialized-arrays/direct/complex-double/complex-double.factor b/basis/specialized-arrays/direct/complex-double/complex-double.factor
new file mode 100644 (file)
index 0000000..ae8d2b5
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.complex-double specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.complex-double
+
+<< "complex-double" define-direct-array >>
diff --git a/basis/specialized-arrays/direct/complex-float/complex-float.factor b/basis/specialized-arrays/direct/complex-float/complex-float.factor
new file mode 100644 (file)
index 0000000..8971196
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.complex-float specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.complex-float
+
+<< "complex-float" define-direct-array >>
index 0c3999db44fe69cdc9cf7693b3a6144a10c094e3..e7e891feded042d1fb371aa9a0ac9f936281d1d1 100755 (executable)
@@ -14,7 +14,7 @@ A'      IS ${T}-array
 A       DEFINES-CLASS direct-${T}-array
 <A>     DEFINES <${A}>
 
-NTH     [ T dup c-getter array-accessor ]
+NTH     [ T dup c-type-getter-boxer array-accessor ]
 SET-NTH [ T dup c-setter array-accessor ]
 
 WHERE
index 3c2c53db31a63c100d0c2baed13e5edb6ad84362..09433a3b51c7181ba62475a501acb441c2e50223 100644 (file)
@@ -22,7 +22,7 @@ A            DEFINES-CLASS ${T}-array
 byte-array>A DEFINES byte-array>${A}
 A{           DEFINES ${A}{
 
-NTH          [ T dup c-getter array-accessor ]
+NTH          [ T dup c-type-getter-boxer array-accessor ]
 SET-NTH      [ T dup c-setter array-accessor ]
 
 WHERE
index 1c1b3dbc599a86ed38a6c5daa94971e18c84e69c..9015cccd8fbc1888cc945e3c1428bbc640bb8e32 100644 (file)
@@ -28,6 +28,8 @@ $nl
     { $snippet "ulonglong" }
     { $snippet "float" }
     { $snippet "double" }
+    { $snippet "complex-float" }
+    { $snippet "complex-double" }
     { $snippet "void*" }
     { $snippet "bool" }
 }
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 ;
old mode 100644 (file)
new mode 100755 (executable)
index 636e440..ff851ed
@@ -11,8 +11,8 @@ tools.deploy.config.editor bootstrap.image io.encodings.utf8
 destructors accessors ;
 IN: tools.deploy.backend
 
-: copy-vm ( executable bundle-name extension -- vm )
-    [ prepend-path ] dip append vm over copy-file ;
+: copy-vm ( executable bundle-name -- vm )
+    prepend-path vm over copy-file ;
 
 : copy-fonts ( name dir -- )
     deploy-ui? get [
old mode 100644 (file)
new mode 100755 (executable)
index 91b4d60..8fe31ac
@@ -54,7 +54,7 @@ IN: tools.deploy.macosx
         } cleave
     ]
     [ create-app-plist ]
-    [ "Contents/MacOS/" append-path "" copy-vm ] 2tri
+    [ "Contents/MacOS/" append-path copy-vm ] 2tri
     dup OCT: 755 set-file-permissions ;
 
 : deploy.app-image ( vocab bundle-name -- str )
old mode 100644 (file)
new mode 100755 (executable)
index 9e0bb8a..c9bf308
@@ -8,7 +8,7 @@ IN: tools.deploy.unix
 
 : create-app-dir ( vocab bundle-name -- vm )
     dup "" copy-fonts
-    "" copy-vm
+    copy-vm
     dup OCT: 755 set-file-permissions ;
 
 : bundle-name ( -- str )
index 7ce635b1ba90623ffac6c0007a036d1f2ab648e4..0e9146b26eccc2911c9f4277db1163f4031bf379 100755 (executable)
@@ -1,9 +1,9 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io io.files io.directories kernel namespaces sequences system
-tools.deploy.backend tools.deploy.config
-tools.deploy.config.editor assocs hashtables prettyprint
-combinators windows.shell32 windows.user32 ;
+USING: io io.files io.pathnames io.directories kernel namespaces
+sequences locals system splitting tools.deploy.backend
+tools.deploy.config tools.deploy.config.editor assocs hashtables
+prettyprint combinators windows.shell32 windows.user32 ;
 IN: tools.deploy.windows
 
 : copy-dll ( bundle-name -- )
@@ -15,13 +15,18 @@ IN: tools.deploy.windows
         "resource:zlib1.dll"
     } swap copy-files-into ;
 
+:: copy-vm ( executable bundle-name extension -- vm )
+    vm "." split1-last drop extension append
+    bundle-name executable ".exe" append append-path
+    [ copy-file ] keep ;
+
 : create-exe-dir ( vocab bundle-name -- vm )
     dup copy-dll
     deploy-ui? get [
-        dup copy-freetype
-        dup "" copy-fonts
-    ] when
-    ".exe" copy-vm ;
+        [ copy-freetype ]
+        [ "" copy-fonts ]
+        [ ".exe" copy-vm ] tri
+    ] [ ".com" copy-vm ] if ;
 
 M: winnt deploy*
     "resource:" [
index b64676088927e6e52567efece4d676ffb8bca3e7..63b55729fbd0454698431af4a43c9ec362c19d32 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays io io.streams.string kernel math math.parser
-namespaces sequences splitting grouping strings ascii byte-arrays ;
+namespaces sequences splitting grouping strings ascii
+byte-arrays byte-vectors ;
 IN: tools.hexdump
 
 <PRIVATE
@@ -26,13 +27,17 @@ IN: tools.hexdump
 : write-hex-line ( bytes lineno -- )
     write-offset [ >hex-digits write ] [ >ascii write ] bi nl ;
 
+: hexdump-bytes ( bytes -- )
+    [ length write-header ]
+    [ 16 <sliced-groups> [ write-hex-line ] each-index ] bi ;
+
 PRIVATE>
 
 GENERIC: hexdump. ( byte-array -- )
 
-M: byte-array hexdump.
-    [ length write-header ]
-    [ 16 <sliced-groups> [ write-hex-line ] each-index ] bi ;
+M: byte-array hexdump. hexdump-bytes ;
+
+M: byte-vector hexdump. hexdump-bytes ;
 
 : hexdump ( byte-array -- str )
     [ hexdump. ] with-string-writer ;
index 331c0a698cbf3c7c98cb2d648a844c1a6f1f4bc3..2fc8856b2636da2ad891f082ae86590666030ae3 100755 (executable)
@@ -141,9 +141,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 ui
     "UI" assert.app [
index 732a438203496df1400c2654eaed6eb487cff55b..f57fb60bcd93e8d59c3f6a1d429b0c7771833cc2 100644 (file)
@@ -81,7 +81,7 @@ SYMBOL: ui-error-hook
 : ui-error ( error -- )
     ui-error-hook get [ call ] [ die ] if* ;
 
-ui-error-hook global [ [ rethrow ] or ] change-at
+ui-error-hook [ [ rethrow ] ] initialize
 
 : draw-world ( world -- )
     dup draw-world? [
index 40da6ebafc7bb185fdd3404d828e8f116e9e042d..eb2eef374232497ad450d7e24afa0052b6f93551 100644 (file)
@@ -5,7 +5,7 @@ hashtables io io.styles kernel math math.order math.vectors
 models models.delay namespaces parser lexer prettyprint
 quotations sequences strings threads listener classes.tuple
 ui.commands ui.gadgets ui.gadgets.editors ui.gadgets.status-bar
-ui.gadgets.presentations ui.gadgets.worlds ui.gestures
+ui.gadgets.presentations ui.gadgets.worlds ui.gestures call
 definitions calendar concurrency.flags concurrency.mailboxes
 ui.tools.workspace accessors sets destructors fry vocabs.parser ;
 IN: ui.tools.interactor
@@ -82,8 +82,7 @@ M: interactor model-changed
     mailbox>> mailbox-put ;
 
 : clear-input ( interactor -- )
-    #! The with-datastack is a kludge to make it infer. Stupid.
-    model>> 1array [ clear-doc ] with-datastack drop ;
+    model>> [ clear-doc ] call( model -- ) ;
 
 : interactor-finish ( interactor -- )
     [ editor-string ] keep
index 37ce4ea499316e04f091fc457d7acfe17ca5dcfa..78f150987f259f1c9c63937fde38c6142f607e1b 100644 (file)
@@ -4,7 +4,7 @@ USING: arrays assocs io kernel math models namespaces make
 dlists deques sequences threads sequences words ui.gadgets
 ui.gadgets.worlds ui.gadgets.tracks ui.gestures ui.backend
 ui.render continuations init combinators hashtables
-concurrency.flags sets accessors calendar ;
+concurrency.flags sets accessors calendar call ;
 IN: ui
 
 ! Assoc mapping aliens to gadgets
@@ -140,7 +140,7 @@ SYMBOL: ui-hook
             layout-queued
             redraw-worlds
             send-queued-gestures
-        ] assert-depth
+        ] call( -- )
     ] [ ui-error ] recover ;
 
 SYMBOL: ui-thread
index f6c25980eac5f96f55716479b6cda9f58f819f5b..437a9419e39131a2b67d6c33974b97b243cc0312 100644 (file)
@@ -82,8 +82,8 @@ HELP: parse-host
 { $notes "This word is used by " { $link >url } ". It can also be used directly to parse " { $snippet "host:port" } " strings which are not full URLs." }
 { $examples
     { $example
-        "USING: prettyprint urls ;"
-        "\"sbcl.org:80\" parse-host .s"
+        "USING: prettyprint urls kernel ;"
+        "\"sbcl.org:80\" parse-host .s 2drop"
         "\"sbcl.org\"\n80"
     }
 } ;
diff --git a/basis/wrap/strings/strings-docs.factor b/basis/wrap/strings/strings-docs.factor
new file mode 100644 (file)
index 0000000..e20780d
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup strings math ;
+IN: wrap.strings
+
+ABOUT: "wrap.strings"
+
+ARTICLE: "wrap.strings" "String word wrapping"
+"The " { $vocab-link "wrap.strings" } " vocabulary implements word wrapping for simple strings, assumed to be in monospace font."
+{ $subsection wrap-lines }
+{ $subsection wrap-string }
+{ $subsection wrap-indented-string } ;
+
+HELP: wrap-lines
+{ $values { "lines" string } { "width" integer } { "newlines" "sequence of strings" } }
+{ $description "Given a string, divides it into a sequence of lines where each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space." } ;
+
+HELP: wrap-string
+{ $values { "string" string } { "width" integer } { "newstring" string } }
+{ $description "Given a string, alters the whitespace in the string so that each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space." } ;
+
+HELP: wrap-indented-string
+{ $values { "string" string } { "width" integer } { "indent" string } { "newstring" string } }
+{ $description "Given a string, alters the whitespace in the string so that each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space. Before each line, the indent string is added." } ;
+
diff --git a/basis/wrap/strings/strings-tests.factor b/basis/wrap/strings/strings-tests.factor
new file mode 100644 (file)
index 0000000..e66572d
--- /dev/null
@@ -0,0 +1,43 @@
+! Copyright (C) 2008, 2009 Daniel Ehrenberg, Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: wrap.strings tools.test multiline ;
+IN: wrap.strings.tests
+
+[
+    <" This is a
+long piece
+of text
+that we
+wish to
+word wrap.">
+] [
+    <" This is a long piece of text that we wish to word wrap."> 10
+    wrap-string
+] unit-test
+    
+[
+    <"   This is a
+  long piece
+  of text
+  that we
+  wish to
+  word wrap.">
+] [
+    <" This is a long piece of text that we wish to word wrap."> 12
+    "  " wrap-indented-string
+] unit-test
+
+[ "this text\nhas lots of\nspaces" ]
+[ "this text        has lots of       spaces" 12 wrap-string ] unit-test
+
+[ "hello\nhow\nare\nyou\ntoday?" ]
+[ "hello how are you today?" 3 wrap-string ] unit-test
+
+[ "aaa\nbb cc\nddddd" ] [ "aaa bb cc ddddd" 6 wrap-string ] unit-test
+[ "aaa\nbb ccc\ndddddd" ] [ "aaa bb ccc dddddd" 6 wrap-string ] unit-test
+[ "aaa bb\ncccc\nddddd" ] [ "aaa bb cccc ddddd" 6 wrap-string ] unit-test
+[ "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
diff --git a/basis/wrap/strings/strings.factor b/basis/wrap/strings/strings.factor
new file mode 100644 (file)
index 0000000..7009352
--- /dev/null
@@ -0,0 +1,29 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: wrap kernel sequences fry splitting math ;
+IN: wrap.strings
+
+<PRIVATE
+
+: split-lines ( string -- elements-lines )
+    string-lines [
+        " \t" split harvest
+        [ dup length 1 <element> ] map
+    ] map ;
+
+: join-elements ( wrapped-lines -- lines )
+    [ " " join ] map ;
+
+: join-lines ( strings -- string )
+    "\n" join ;
+
+PRIVATE>
+
+: wrap-lines ( lines width -- newlines )
+    [ split-lines ] dip '[ _ dup wrap join-elements ] map concat ;
+
+: wrap-string ( string width -- newstring )
+    wrap-lines join-lines ;
+
+: wrap-indented-string ( string width indent -- newstring )
+    [ length - wrap-lines ] keep '[ _ prepend ] map join-lines ;
diff --git a/basis/wrap/words/words-docs.factor b/basis/wrap/words/words-docs.factor
new file mode 100644 (file)
index 0000000..422aea0
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup math kernel ;
+IN: wrap.words
+
+ABOUT: "wrap.words"
+
+ARTICLE: "wrap.words" "Word object wrapping"
+"The " { $vocab-link "wrap.words" } " vocabulary implements word wrapping on abstract word objects, which have certain properties making it a more suitable input representation than strings."
+{ $subsection wrap-words }
+{ $subsection word }
+{ $subsection <word> } ;
+
+HELP: wrap-words
+{ $values { "words" { "a sequence of " { $instance word } "s" } } { "line-max" integer } { "line-ideal" integer } { "lines" "a sequence of sequences of words" } }
+{ $description "Divides the words into lines, where the sum of the lengths of the words on a line (not counting breaks at the end of the line) is at most the given maximum. The returned set of lines is optimized to minimize the square of the deviation of each line from the ideal width. It is not guaranteed to be the minimal number of lines. Every line except for the first one starts with a non-break, and every one but the last ends with a break." } ;
+
+HELP: word
+{ $class-description "A word is a Factor object annotated with a length (in the " { $snippet "width" } " slot) and knowledge about whether it is an allowable position for an optional line break (in the " { $snippet "break?" } " slot). Words can be created with " { $link <word> } "." }
+{ $see-also wrap-words } ;
+
+HELP: <word>
+{ $values { "key" object } { "width" integer } { "break?" { { $link t } " or " { $link POSTPONE: f } } } { "word" word } }
+{ $description "Creates a " { $link word } " object with the given parameters." }
+{ $see-also wrap-words } ;
diff --git a/basis/wrap/words/words-tests.factor b/basis/wrap/words/words-tests.factor
new file mode 100644 (file)
index 0000000..7598b38
--- /dev/null
@@ -0,0 +1,82 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test wrap.words sequences ;
+IN: wrap.words.tests    
+
+[
+    {
+        {
+            T{ word f 1 10 f }
+            T{ word f 2 10 f }
+            T{ word f 3 2 t }
+        }
+        {
+            T{ word f 4 10 f }
+            T{ word f 5 10 f }
+        }
+    }
+] [
+    {
+        T{ word f 1 10 f }
+        T{ word f 2 10 f }
+        T{ word f 3 2 t }
+        T{ word f 4 10 f }
+        T{ word f 5 10 f }
+    } 35 35 wrap-words [ { } like ] map
+] unit-test
+
+[
+    {
+        {
+            T{ word f 1 10 f }
+            T{ word f 2 10 f }
+            T{ word f 3 9 t }
+            T{ word f 3 9 t }
+            T{ word f 3 9 t }
+        }
+        {
+            T{ word f 4 10 f }
+            T{ word f 5 10 f }
+        }
+    }
+] [
+    {
+        T{ word f 1 10 f }
+        T{ word f 2 10 f }
+        T{ word f 3 9 t }
+        T{ word f 3 9 t }
+        T{ word f 3 9 t }
+        T{ word f 4 10 f }
+        T{ word f 5 10 f }
+    } 35 35 wrap-words [ { } like ] map
+] unit-test
+
+[
+    {
+        {
+            T{ word f 1 10 t }
+            T{ word f 1 10 f }
+            T{ word f 3 9 t }
+        }
+        {
+            T{ word f 2 10 f }
+            T{ word f 3 9 t }
+        }
+        {
+            T{ word f 4 10 f }
+            T{ word f 5 10 f }
+        }
+    }
+] [
+    {
+        T{ word f 1 10 t }
+        T{ word f 1 10 f }
+        T{ word f 3 9 t }
+        T{ word f 2 10 f }
+        T{ word f 3 9 t }
+        T{ word f 4 10 f }
+        T{ word f 5 10 f }
+    } 35 35 wrap-words [ { } like ] map
+] unit-test
+
+\ wrap-words must-infer
diff --git a/basis/wrap/words/words.factor b/basis/wrap/words/words.factor
new file mode 100644 (file)
index 0000000..bcf4460
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: sequences kernel splitting.monotonic accessors grouping wrap ;
+IN: wrap.words
+
+TUPLE: word key width break? ;
+C: <word> word
+
+<PRIVATE
+
+: words-length ( words -- length )
+    [ width>> ] map sum ;
+
+: make-element ( whites blacks -- element )
+    [ append ] [ [ words-length ] bi@ ] 2bi <element> ;
+: ?first2 ( seq -- first/f second/f )
+    [ 0 swap ?nth ]
+    [ 1 swap ?nth ] bi ;
+
+: split-words ( seq -- half-elements )
+    [ [ break?>> ] bi@ = ] monotonic-split ;
+
+: ?first-break ( seq -- newseq f/element )
+    dup first first break?>>
+    [ unclip-slice f swap make-element ]
+    [ f ] if ;
+
+: make-elements ( seq f/element -- elements )
+    [ 2 <groups> [ ?first2 make-element ] map ] dip
+    [ prefix ] when* ;
+
+: words>elements ( seq -- newseq )
+    split-words ?first-break make-elements ;
+
+PRIVATE>
+
+: wrap-words ( words line-max line-ideal -- lines )
+    [ words>elements ] 2dip wrap [ concat ] map ;
+
index c94e12907f369ca119ac99d869baac4e9b4faf09..feac7c51a790e533b38c4c0babf4d0d944e73a93 100644 (file)
@@ -6,36 +6,6 @@ IN: wrap
 ABOUT: "wrap"
 
 ARTICLE: "wrap" "Word wrapping"
-"The " { $vocab-link "wrap" } " vocabulary implements word wrapping. There is support for simple string wrapping, with the following words:"
-{ $subsection wrap-lines }
-{ $subsection wrap-string }
-{ $subsection wrap-indented-string }
-"Additionally, the vocabulary provides capabilities to wrap arbitrary groups of things, in units called words."
-{ $subsection wrap }
-{ $subsection word }
-{ $subsection <word> } ;
-
-HELP: wrap-lines
-{ $values { "lines" string } { "width" integer } { "newlines" "sequence of strings" } }
-{ $description "Given a string, divides it into a sequence of lines where each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space." } ;
-
-HELP: wrap-string
-{ $values { "string" string } { "width" integer } { "newstring" string } }
-{ $description "Given a string, alters the whitespace in the string so that each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space." } ;
-
-HELP: wrap-indented-string
-{ $values { "string" string } { "width" integer } { "indent" string } { "newstring" string } }
-{ $description "Given a string, alters the whitespace in the string so that each line has no more than " { $snippet "width" } " characters, unless there is a word longer than " { $snippet "width" } ". Linear whitespace between words is converted to a single space. Before each line, the indent string is added." } ;
-
-HELP: wrap
-{ $values { "words" { "a sequence of " { $instance word } "s" } } { "width" integer } { "lines" "a sequence of sequences of words" } }
-{ $description "Divides the words into lines, where the sum of the lengths of the words on a line (not counting breaks at the end of the line) is at most the given width. Every line except for the first one starts with a non-break, and every one but the last ends with a break." } ;
-
-HELP: word
-{ $class-description "A word, for the purposes of " { $vocab-link "wrap" } ", is a Factor object annotated with a length (in the " { $snippet "width" } " slot) and knowledge about whether it is an allowable position for an optional line break (in the " { $snippet "break?" } " slot). Words can be created with " { $link <word> } "." }
-{ $see-also wrap } ;
-
-HELP: <word>
-{ $values { "key" object } { "width" integer } { "break?" { { $link t } " or " { $link POSTPONE: f } } } { "word" word } }
-{ $description "Creates a " { $link word } " object with the given parameters." }
-{ $see-also wrap } ;
+"The " { $vocab-link "wrap" } " vocabulary implements word wrapping. Wrapping can take place based on simple strings, assumed to be monospace, or abstract word objects."
+{ $vocab-subsection "String word wrapping" "wrap.strings" } 
+{ $vocab-subsection "Word object wrapping" "wrap.words" } ;
diff --git a/basis/wrap/wrap-tests.factor b/basis/wrap/wrap-tests.factor
deleted file mode 100644 (file)
index ba5168a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-! Copyright (C) 2008, 2009 Daniel Ehrenberg, Slava Pestov
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test wrap multiline sequences ;
-IN: wrap.tests
-    
-[
-    {
-        {
-            T{ word f 1 10 f }
-            T{ word f 2 10 f }
-            T{ word f 3 2 t }
-        }
-        {
-            T{ word f 4 10 f }
-            T{ word f 5 10 f }
-        }
-    }
-] [
-    {
-        T{ word f 1 10 f }
-        T{ word f 2 10 f }
-        T{ word f 3 2 t }
-        T{ word f 4 10 f }
-        T{ word f 5 10 f }
-    } 35 wrap [ { } like ] map
-] unit-test
-
-[
-    {
-        {
-            T{ word f 1 10 f }
-            T{ word f 2 10 f }
-            T{ word f 3 9 t }
-            T{ word f 3 9 t }
-            T{ word f 3 9 t }
-        }
-        {
-            T{ word f 4 10 f }
-            T{ word f 5 10 f }
-        }
-    }
-] [
-    {
-        T{ word f 1 10 f }
-        T{ word f 2 10 f }
-        T{ word f 3 9 t }
-        T{ word f 3 9 t }
-        T{ word f 3 9 t }
-        T{ word f 4 10 f }
-        T{ word f 5 10 f }
-    } 35 wrap [ { } like ] map
-] unit-test
-
-[
-    <" This is a
-long piece
-of text
-that we
-wish to
-word wrap.">
-] [
-    <" This is a long piece of text that we wish to word wrap."> 10
-    wrap-string
-] unit-test
-    
-[
-    <"   This is a
-  long piece
-  of text
-  that we
-  wish to
-  word wrap.">
-] [
-    <" This is a long piece of text that we wish to word wrap."> 12
-    "  " wrap-indented-string
-] unit-test
-
-[ "this text\nhas lots of\nspaces" ]
-[ "this text        has lots of       spaces" 12 wrap-string ] unit-test
-
-[ "hello\nhow\nare\nyou\ntoday?" ]
-[ "hello how are you today?" 3 wrap-string ] unit-test
index e93509b58e4bab5c2141f784a34ebd1cd5bb2003..0b7f869141a47dd61d64e3d3e04570297880434f 100644 (file)
@@ -1,73 +1,85 @@
-! Copyright (C) 2008, 2009 Daniel Ehrenberg, Slava Pestov
+! Copyright (C) 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences kernel namespaces make splitting
-math math.order fry assocs accessors ;
+USING: kernel sequences math arrays locals fry accessors
+lists splitting call make combinators.short-circuit namespaces
+grouping splitting.monotonic ;
 IN: wrap
 
-! Word wrapping/line breaking -- not Unicode-aware
+! black is the text length, white is the whitespace length
+TUPLE: element contents black white ;
+C: <element> element
 
-TUPLE: word key width break? ;
+: element-length ( element -- n )
+    [ black>> ] [ white>> ] bi + ;
 
-C: <word> word
+TUPLE: paragraph lines head-width tail-cost ;
+C: <paragraph> paragraph
 
-<PRIVATE
+SYMBOL: line-max
+SYMBOL: line-ideal
 
-SYMBOL: width
+: deviation ( length -- n )
+    line-ideal get - sq ;
 
-: break-here? ( column word -- ? )
-    break?>> not [ width get > ] [ drop f ] if ;
+: top-fits? ( paragraph -- ? )
+    [ head-width>> ]
+    [ lines>> 1list? line-ideal line-max ? get ] bi <= ;
 
-: walk ( n words -- n )
-    ! If on a break, take the rest of the breaks
-    ! If not on a break, go back until you hit a break
-    2dup bounds-check? [
-        2dup nth break?>>
-        [ [ break?>> not ] find-from drop ]
-        [ [ break?>> ] find-last-from drop 1+ ] if
-   ] [ drop ] if ;
+: fits? ( paragraph -- ? )
+    ! Make this not count spaces at end
+    { [ lines>> car 1list? ] [ top-fits? ] } 1|| ;
 
-: find-optimal-break ( words -- n )
-    [ 0 ] keep
-    [ [ width>> + dup ] keep break-here? ] find drop nip
-    [ 1 max swap walk ] [ drop f ] if* ;
+:: min-by ( seq quot -- elt )
+    f 1.0/0.0 seq [| key value new |
+        new quot call :> newvalue
+        newvalue value < [ new newvalue ] [ key value ] if
+    ] each drop ; inline
 
-: (wrap) ( words -- )
-    [
-        dup find-optimal-break
-        [ cut-slice [ , ] [ (wrap) ] bi* ] [ , ] if*
-    ] unless-empty ;
-
-: intersperse ( seq elt -- seq' )
-    [ '[ _ , ] [ , ] interleave ] { } make ;
+: paragraph-cost ( paragraph -- cost )
+    dup lines>> 1list? [ drop 0 ] [
+        [ head-width>> deviation ]
+        [ tail-cost>> ] bi +
+    ] if ;
 
-: split-lines ( string -- words-lines )
-    string-lines [
-        " \t" split harvest
-        [ dup length f <word> ] map
-        " " 1 t <word> intersperse
-    ] map ;
+: min-cost ( paragraphs -- paragraph )
+    [ paragraph-cost ] min-by ;
 
-: join-words ( wrapped-lines -- lines )
-    [
-        [ break?>> ] trim-slice
-        [ key>> ] map concat
-    ] map ;
+: new-line ( paragraph element -- paragraph )
+    [ [ lines>> ] [ 1list ] bi* swons ]
+    [ nip black>> ]
+    [ drop paragraph-cost ] 2tri
+    <paragraph> ;
 
-: join-lines ( strings -- string )
-    "\n" join ;
+: glue ( paragraph element -- paragraph )
+    [ [ lines>> unswons ] dip swons swons ]
+    [ [ head-width>> ] [ element-length ] bi* + ]
+    [ drop tail-cost>> ] 2tri
+    <paragraph> ;
 
-PRIVATE>
+: wrap-step ( paragraphs element -- paragraphs )
+    [ '[ _ glue ] map ]
+    [ [ min-cost ] dip new-line ]
+    2bi prefix
+    [ fits? ] filter ;
 
-: wrap ( words width -- lines )
-    width [
-        [ (wrap) ] { } make
-    ] with-variable ;
+: 1paragraph ( element -- paragraph )
+    [ 1list 1list ]
+    [ black>> ] bi
+    0 <paragraph> ;
 
-: wrap-lines ( lines width -- newlines )
-    [ split-lines ] dip '[ _ wrap join-words ] map concat ;
+: post-process ( paragraph -- array )
+    lines>> deep-list>array
+    [ [ contents>> ] map ] map ;
 
-: wrap-string ( string width -- newstring )
-    wrap-lines join-lines ;
+: initialize ( elements -- elements paragraph )
+    <reversed> unclip-slice 1paragraph 1array ;
 
-: wrap-indented-string ( string width indent -- newstring )
-    [ length - wrap-lines ] keep '[ _ prepend ] map join-lines ;
+: wrap ( elements line-max line-ideal -- paragraph )
+    [
+        line-ideal set
+        line-max set
+        initialize
+        [ wrap-step ] reduce
+        min-cost
+        post-process
+    ] with-scope ;
index 9632cbb1acb9b9f8c771e530e4957ab5531163e5..690ebe94f8d6df6d40d40f9d310e355aa184c27a 100644 (file)
@@ -126,11 +126,11 @@ TAG: int xml>item children>number ;
 TAG: double xml>item children>number ;
 
 TAG: boolean xml>item
-    dup children>string {
-        { [ dup "1" = ] [ 2drop t ] }
-        { [ "0" = ] [ drop f ] }
+    children>string {
+        { "1" [ t ] }
+        { "0" [ f ] }
         [ "Bad boolean" server-error ]
-    } cond ;
+    } case ;
 
 : unstruct-member ( tag -- )
     children-tags first2
index 8e6bebfe6babec7d5fb8c3ad2d85f83959bb8dfe..067bb9ec1173756fca636c8bbf75524bf8f2fa64 100644 (file)
@@ -174,6 +174,8 @@ PRIVATE>
 : [XML
     "XML]" [ string>chunk ] parse-def ; parsing
 
+<PRIVATE
+
 : remove-blanks ( seq -- newseq )
     [ { [ string? not ] [ [ blank? ] all? not ] } 1|| ] filter ;
 
@@ -241,3 +243,5 @@ M: interpolated [undo-xml]
     [undo-xml] '[ H{ } clone [ _ bind ] keep >enum ] ;
 
 \ interpolate-xml 1 [ undo-xml ] define-pop-inverse
+
+PRIVATE>
index b1f6cf002f77738fe259fb1cf97de2191aaee442..03721327368bb15d31336a1fd2afa050ffae722f 100644 (file)
@@ -3,7 +3,7 @@
 IN: xml.tests
 USING: kernel xml tools.test io namespaces make sequences
 xml.errors xml.entities.html parser strings xml.data io.files
-xml.traversal continuations assocs
+xml.traversal continuations assocs io.encodings.binary
 sequences.deep accessors io.streams.string ;
 
 ! This is insufficient
@@ -12,8 +12,14 @@ sequences.deep accessors io.streams.string ;
 \ string>xml must-infer
 
 SYMBOL: xml-file
-[ ] [ "resource:basis/xml/tests/test.xml"
-    [ file>xml ] with-html-entities xml-file set ] unit-test
+[ ] [
+    "resource:basis/xml/tests/test.xml"
+    [ file>xml ] with-html-entities xml-file set
+] unit-test
+[ t ] [
+    "resource:basis/xml/tests/test.xml" binary file-contents
+    [ bytes>xml ] with-html-entities xml-file get =
+] unit-test
 [ "1.0" ] [ xml-file get prolog>> version>> ] unit-test
 [ f ] [ xml-file get prolog>> standalone>> ] unit-test
 [ "a" ] [ xml-file get space>> ] unit-test
index 4b80e0818ef6b89c27abba0795b80fdd986fdec7..4f5bad1aa58054b97f371ae74af2820cecb45181 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: hashtables kernel math namespaces sequences strings\r
 assocs combinators io io.streams.string accessors\r
-xml.data wrap xml.entities unicode.categories fry ;\r
+xml.data wrap.strings xml.entities unicode.categories fry ;\r
 IN: xml.writer\r
 \r
 SYMBOL: sensitive-tags\r
index 024b086ef9aff324df353ed0b3063fa7fcccdbb4..77969c55cde415545dc554c7ee8d1cabf2dfba70 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2009 Daniel Ehrenberg\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: help.markup help.syntax xml.data io strings ;\r
+USING: help.markup help.syntax xml.data io strings byte-arrays ;\r
 IN: xml\r
 \r
 HELP: string>xml\r
@@ -16,7 +16,11 @@ HELP: file>xml
 { $values { "filename" string } { "xml" xml } }\r
 { $description "Opens the given file, reads it in as XML, closes the file and returns the corresponding XML tree. The encoding is automatically detected." } ;\r
 \r
-{ string>xml read-xml file>xml } related-words\r
+HELP: bytes>xml\r
+{ $values { "byte-array" byte-array } { "xml" xml } }\r
+{ $description "Parses a byte array as an XML document. The encoding is automatically detected." } ;\r
+\r
+{ string>xml read-xml file>xml bytes>xml } related-words\r
 \r
 HELP: read-xml-chunk\r
 { $values { "stream" "an input stream" } { "seq" "a sequence of elements" } }\r
@@ -68,6 +72,7 @@ ARTICLE: { "xml" "reading" } "Reading XML"
     { $subsection read-xml-chunk }\r
     { $subsection string>xml-chunk }\r
     { $subsection file>xml }\r
+    { $subsection bytes>xml }\r
     "To read a DTD:"\r
     { $subsection read-dtd }\r
     { $subsection file>dtd }\r
index 57c1b6dbd33936d87432618b37db41f5a7cd680e..073f46cbae3314a7c390ed56f14921f5a00f9830 100755 (executable)
@@ -4,7 +4,7 @@ USING: accessors arrays io io.encodings.binary io.files
 io.streams.string kernel namespaces sequences strings io.encodings.utf8
 xml.data xml.errors xml.elements ascii xml.entities
 xml.writer xml.state xml.autoencoding assocs xml.tokenize
-combinators.short-circuit xml.name splitting ;
+combinators.short-circuit xml.name splitting io.streams.byte-array ;
 IN: xml
 
 <PRIVATE
@@ -184,6 +184,9 @@ PRIVATE>
 : file>xml ( filename -- xml )
     binary <file-reader> read-xml ;
 
+: bytes>xml ( byte-array -- xml )
+    binary <byte-reader> read-xml ;
+
 : read-dtd ( stream -- dtd )
     [
         H{ } clone extra-entities set
diff --git a/basis/zlib/authors.txt b/basis/zlib/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/zlib/ffi/authors.txt b/basis/zlib/ffi/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/zlib/ffi/ffi.factor b/basis/zlib/ffi/ffi.factor
deleted file mode 100755 (executable)
index bda2809..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-! Copyright (C) 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax combinators system ;
-IN: zlib.ffi
-
-<< "zlib" {
-    { [ os winnt? ] [ "zlib1.dll" ] }
-    { [ os macosx? ] [ "libz.dylib" ] }
-    { [ os unix? ] [ "libz.so" ] }
-} cond "cdecl" add-library >>
-
-LIBRARY: zlib
-
-CONSTANT: Z_OK 0
-CONSTANT: Z_STREAM_END 1
-CONSTANT: Z_NEED_DICT 2
-CONSTANT: Z_ERRNO -1
-CONSTANT: Z_STREAM_ERROR -2
-CONSTANT: Z_DATA_ERROR -3
-CONSTANT: Z_MEM_ERROR -4
-CONSTANT: Z_BUF_ERROR -5
-CONSTANT: Z_VERSION_ERROR -6
-
-TYPEDEF: void Bytef
-TYPEDEF: ulong uLongf
-TYPEDEF: ulong uLong
-
-FUNCTION: int compress ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen ) ;
-FUNCTION: int compress2 ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen, int level ) ;
-FUNCTION: int uncompress ( Bytef* dest, uLongf* destLen, Bytef* source, uLong sourceLen ) ;
diff --git a/basis/zlib/zlib-tests.factor b/basis/zlib/zlib-tests.factor
deleted file mode 100755 (executable)
index 0ac7727..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-! Copyright (C) 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel tools.test zlib classes ;
-IN: zlib.tests
-
-: compress-me ( -- byte-array ) B{ 1 2 3 4 5 } ;
-
-[ t ] [ compress-me [ compress uncompress ] keep = ] unit-test
-[ t ] [ compress-me compress compressed instance? ] unit-test
diff --git a/basis/zlib/zlib.factor b/basis/zlib/zlib.factor
deleted file mode 100755 (executable)
index b40d9c2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-! Copyright (C) 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types alien.syntax byte-arrays combinators
-kernel math math.functions sequences system accessors
-libc ;
-QUALIFIED: zlib.ffi
-IN: zlib
-
-TUPLE: compressed data length ;
-
-: <compressed> ( data length -- compressed )
-    compressed new
-        swap >>length
-        swap >>data ;
-
-ERROR: zlib-failed n string ;
-
-: zlib-error-message ( n -- * )
-    dup zlib.ffi:Z_ERRNO = [
-        drop errno "native libc error"
-    ] [
-        dup {
-            "no error" "libc_error"
-            "stream error" "data error"
-            "memory error" "buffer error" "zlib version error"
-        } ?nth
-    ] if zlib-failed ;
-
-: zlib-error ( n -- )
-    dup zlib.ffi:Z_OK = [ drop ] [ dup zlib-error-message zlib-failed ] if ;
-
-: compressed-size ( byte-array -- n )
-    length 1001/1000 * ceiling 12 + ;
-
-: compress ( byte-array -- compressed )
-    [
-        [ compressed-size <byte-array> dup length <ulong> ] keep [
-            dup length zlib.ffi:compress zlib-error
-        ] 3keep drop *ulong head
-    ] keep length <compressed> ;
-
-: uncompress ( compressed -- byte-array )
-    [
-        length>> [ <byte-array> ] keep <ulong> 2dup
-    ] [
-        data>> dup length
-        zlib.ffi:uncompress zlib-error
-    ] bi *ulong head ;
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 561d0962ffc9e39728c4923c338b176d267476d8..0469f3564aaeb466d01ac4dc89b5afcebda17b52 100644 (file)
@@ -241,7 +241,7 @@ ARTICLE: "tuple-examples" "Tuple examples"
 }
 "An example of using a changer:"
 { $code
-    ": positions"
+    ": positions ( -- seq )"
     "    {"
     "        \"junior programmer\""
     "        \"senior programmer\""
index 1a73e22e313ac10ed136c5277840f014143162ee..beb50f1162ac7a69626d92bbbcbffa8a0a042622 100644 (file)
@@ -323,4 +323,18 @@ DEFER: corner-case-1
 [ t ] [ \ corner-case-1 optimized>> ] unit-test
 [ 4 ] [ 2 corner-case-1 ] unit-test
 
-[ 4 ] [ 2 2 [ + ] curry 1array case ] unit-test
\ No newline at end of file
+[ 4 ] [ 2 2 [ + ] curry 1array case ] unit-test
+
+: test-case-8 ( n -- )
+    {
+        { 1 [ "foo" ] }
+    } case ;
+
+[ 3 test-case-8 ]
+[ object>> 3 = ] must-fail-with
+
+[
+    3 {
+        { 1 [ "foo" ] }
+    } case
+] [ object>> 3 = ] must-fail-with
index e356a6d246016db91d7f7cee5e9e35bb33ca219b..daf247d678b438b9e0c24c54daace8d17a642451 100755 (executable)
@@ -49,7 +49,7 @@ ERROR: no-cond ;
     reverse [ no-cond ] swap alist>quot ;
 
 ! case
-ERROR: no-case ;
+ERROR: no-case object ;
 
 : case-find ( obj assoc -- obj' )
     [
@@ -66,7 +66,7 @@ ERROR: no-case ;
     case-find {
         { [ dup array? ] [ nip second call ] }
         { [ dup callable? ] [ call ] }
-        { [ dup not ] [ no-case ] }
+        { [ dup not ] [ drop no-case ] }
     } cond ;
 
 : linear-case-quot ( default assoc -- quot )
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 f9702fd1337a993f460a29f0d6d73b8ecdf42696..152d1bb85d228b65953df779f182979ed72693a1 100644 (file)
@@ -1,8 +1,7 @@
-USING: tools.test io.files io.files.private io.files.temp
-io.directories io.encodings.8-bit arrays make system
-io.encodings.binary io threads kernel continuations
-io.encodings.ascii sequences strings accessors
-io.encodings.utf8 math destructors namespaces ;
+USING: arrays debugger.threads destructors io io.directories
+io.encodings.8-bit io.encodings.ascii io.encodings.binary
+io.files io.files.private io.files.temp io.files.unique kernel
+make math sequences system threads tools.test ;
 IN: io.files.tests
 
 \ exists? must-infer
@@ -75,3 +74,73 @@ USE: debugger.threads
 [ t ] [ "quux-test.txt" temp-file exists? ] unit-test
 
 [ ] [ "quux-test.txt" temp-file delete-file ] unit-test
+
+! File seeking tests
+[ B{ 3 2 3 4 5 } ]
+[
+    "seek-test1" unique-file binary
+    [
+        [
+            B{ 1 2 3 4 5 } write 0 seek-absolute seek-output
+            B{ 3 } write
+        ] with-file-writer
+    ] [
+        file-contents
+    ] 2bi
+] unit-test
+
+[ B{ 1 2 3 4 3 } ]
+[
+    "seek-test2" unique-file binary
+    [
+        [
+            B{ 1 2 3 4 5 } write -1 seek-relative seek-output
+            B{ 3 } write
+        ] with-file-writer
+    ] [
+        file-contents
+    ] 2bi
+] unit-test
+
+[ B{ 1 2 3 4 5 0 3 } ]
+[
+    "seek-test3" unique-file binary
+    [
+        [
+            B{ 1 2 3 4 5 } write 1 seek-relative seek-output
+            B{ 3 } write
+        ] with-file-writer
+    ] [
+        file-contents
+    ] 2bi
+] unit-test
+
+[ B{ 3 } ]
+[
+    B{ 1 2 3 4 5 } "seek-test4" unique-file binary [
+        set-file-contents
+    ] [
+        [
+            -3 seek-end seek-input 1 read
+        ] with-file-reader
+    ] 2bi
+] unit-test
+
+[ B{ 2 } ]
+[
+    B{ 1 2 3 4 5 } "seek-test5" unique-file binary [
+        set-file-contents
+    ] [
+        [
+            3 seek-absolute seek-input
+            -2 seek-relative seek-input
+            1 read
+        ] with-file-reader
+    ] 2bi
+] unit-test
+
+[
+    "seek-test6" unique-file binary [
+        -10 seek-absolute seek-input
+    ] with-file-reader
+] must-fail
index d7534ddb5083080c12e3148e7a3644e6d45891af..5d8aa6a88ffb770ab1b68b05a6b4e03017c7003d 100644 (file)
@@ -68,6 +68,51 @@ HELP: stream-copy
 { $description "Copies the contents of one stream into another, closing both streams when done." } 
 $io-error ;
 
+
+HELP: stream-seek
+{ $values
+     { "n" integer } { "seek-type" "a seek singleton" } { "stream" "a stream" }
+}
+{ $description "Moves the pointer associated with a stream's handle to an offset " { $snippet "n" } " bytes from the seek type so that further reading or writing happens at the new location. For output streams, the buffer is flushed before seeking. Seeking past the end of an output stream will pad the difference with zeros once the stream is written to again." $nl
+    "Three methods of seeking are supported:"
+    { $list { $link seek-absolute } { $link seek-relative } { $link seek-end } }
+}
+{ $notes "Stream seeking is not supported on streams that do not have a known length, e.g. TCP/IP streams." } ;
+
+HELP: seek-absolute
+{ $values
+    
+     { "value" "a seek singleton" }
+}
+{ $description "Seeks to an offset from the beginning of the stream." } ;
+
+HELP: seek-end
+{ $values
+    
+     { "value" "a seek singleton" }
+}
+{ $description "Seeks to an offset from the end of the stream. If the offset puts the stream pointer past the end of the data on an output stream, writing to it will pad the difference with zeros." } ;
+
+HELP: seek-relative
+{ $values
+    
+     { "value" "a seek singleton" }
+}
+{ $description "Seeks to an offset from the current position of the stream pointer." } ;
+
+
+HELP: seek-input
+{ $values
+     { "n" integer } { "seek-type" "a seek singleton" }
+}
+{ $description "Calls " { $link stream-seek } " on the stream stored in " { $link input-stream } "." } ;
+
+HELP: seek-output
+{ $values
+     { "n" integer } { "seek-type" "a seek singleton" }
+}
+{ $description "Calls " { $link stream-seek } " on the stream stored in " { $link output-stream } "." } ;
+
 HELP: input-stream
 { $var-description "Holds an input stream for various implicit stream operations. Rebound using " { $link with-input-stream } " and " { $link with-input-stream* } "." } ;
 
@@ -196,6 +241,8 @@ $nl
 { $subsection stream-write }
 "This word is only required for string output streams:"
 { $subsection stream-nl }
+"This word is for streams that allow seeking:"
+{ $subsection stream-seek }
 "For a discussion of the distinction between binary and string streams, see " { $link "stream-elements" } "."
 { $see-also "io.timeouts" } ;
 
@@ -249,6 +296,8 @@ $nl
 { $subsection read-partial }
 "If the default input stream is a string stream (" { $link "stream-elements" } "), lines of text can be read:"
 { $subsection readln }
+"Seeking on the default input stream:"
+{ $subsection seek-input }
 "A pair of combinators for rebinding the " { $link input-stream } " variable:"
 { $subsection with-input-stream }
 { $subsection with-input-stream* }
@@ -256,7 +305,7 @@ $nl
 { $subsection output-stream }
 "Unless rebound in a child namespace, this variable will be set to a console stream for showing output to the user."
 $nl
-"Words writing to the default input stream:"
+"Words writing to the default output stream:"
 { $subsection flush }
 { $subsection write1 }
 { $subsection write }
@@ -265,6 +314,8 @@ $nl
 { $subsection print }
 { $subsection nl }
 { $subsection bl }
+"Seeking on the default output stream:"
+{ $subsection seek-output }
 "A pair of combinators for rebinding the " { $link output-stream } " variable:"
 { $subsection with-output-stream }
 { $subsection with-output-stream* }
index 8bfc52432d0505ea03bbf09ed8aa3c4834044046..cf6b935215bc1493b20167f76a0cacd44a0bc1ab 100644 (file)
@@ -1,6 +1,4 @@
-USING: arrays io io.files kernel math parser strings system
-tools.test words namespaces make io.encodings.8-bit
-io.encodings.binary sequences io.files.unique ;
+USING: io parser tools.test words ;
 IN: io.tests
 
 [ f ] [
@@ -10,66 +8,3 @@ IN: io.tests
 
 ! Make sure we use correct to_c_string form when writing
 [ ] [ "\0" write ] unit-test
-
-[ B{ 3 2 3 4 5 } ]
-[
-    "seek-test1" unique-file binary
-    [
-        [
-            B{ 1 2 3 4 5 } write flush 0 seek-absolute seek-output
-            B{ 3 } write
-        ] with-file-writer
-    ] [
-        file-contents
-    ] 2bi
-] unit-test
-
-[ B{ 1 2 3 4 3 } ]
-[
-    "seek-test2" unique-file binary
-    [
-        [
-            B{ 1 2 3 4 5 } write flush -1 seek-relative seek-output
-            B{ 3 } write
-        ] with-file-writer
-    ] [
-        file-contents
-    ] 2bi
-] unit-test
-
-[ B{ 1 2 3 4 5 0 3 } ]
-[
-    "seek-test3" unique-file binary
-    [
-        [
-            B{ 1 2 3 4 5 } write flush 1 seek-relative seek-output
-            B{ 3 } write
-        ] with-file-writer
-    ] [
-        file-contents
-    ] 2bi
-] unit-test
-
-[ B{ 3 } ]
-[
-    B{ 1 2 3 4 5 } "seek-test4" unique-file binary [
-        set-file-contents
-    ] [
-        [
-            -3 seek-end seek-input 1 read
-        ] with-file-reader
-    ] 2bi
-] unit-test
-
-[ B{ 2 } ]
-[
-    B{ 1 2 3 4 5 } "seek-test5" unique-file binary [
-        set-file-contents
-    ] [
-        [
-            3 seek-absolute seek-input
-            -2 seek-relative seek-input
-            1 read
-        ] with-file-reader
-    ] 2bi
-] unit-test
index 71183093ee14357e037099ce494c8fc0cabb123e..b8191004dbbff2139a4ff29878af00f74d2ede1b 100644 (file)
@@ -658,7 +658,7 @@ HELP: loop
     "hi hi hi" }
     "A fun loop:"
     { $example "USING: kernel prettyprint math ; "
-    "3 [ dup . 7 + 11 mod dup 3 = not ] loop"
+    "3 [ dup . 7 + 11 mod dup 3 = not ] loop drop"
     "3\n10\n6\n2\n9\n5\n1\n8\n4\n0\n7" }
 } ;
 
index be1de766504fb150bd65974ad650d441e9b4bbc6..06fe289281131cb66b7f89031cdfa2c41c59258c 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel.private slots.private math.private
 classes.tuple.private ;
@@ -51,7 +51,7 @@ DEFER: if
 
 ! Default
 : ?if ( default cond true false -- )
-    pick [ roll 2drop call ] [ 2nip call ] if ; inline
+    pick [ drop [ drop ] 2dip call ] [ 2nip call ] if ; inline
 
 ! Slippers and dippers.
 ! Not declared inline because the compiler special-cases them
@@ -138,39 +138,6 @@ DEFER: if
 : 2tri@ ( u v w y x z quot -- )
     dup dup 2tri* ; inline
 
-! Object protocol
-GENERIC: hashcode* ( depth obj -- code )
-
-M: object hashcode* 2drop 0 ;
-
-M: f hashcode* 2drop 31337 ;
-
-: hashcode ( obj -- code ) 3 swap hashcode* ; inline
-
-GENERIC: equal? ( obj1 obj2 -- ? )
-
-M: object equal? 2drop f ;
-
-TUPLE: identity-tuple ;
-
-M: identity-tuple equal? 2drop f ;
-
-: = ( obj1 obj2 -- ? )
-    2dup eq? [ 2drop t ] [
-        2dup both-fixnums? [ 2drop f ] [ equal? ] if
-    ] if ; inline
-
-GENERIC: clone ( obj -- cloned )
-
-M: object clone ;
-
-M: callstack clone (clone) ;
-
-! Tuple construction
-GENERIC: new ( class -- tuple )
-
-GENERIC: boa ( ... class -- tuple )
-
 ! Quotation building
 : 2curry ( obj1 obj2 quot -- curry )
     curry curry ; inline
@@ -184,6 +151,25 @@ GENERIC: boa ( ... class -- tuple )
 : prepose ( quot1 quot2 -- compose )
     swap compose ; inline
 
+! Curried cleavers
+<PRIVATE
+
+: [curry] ( quot -- quot' ) [ curry ] curry ; inline
+
+PRIVATE>
+
+: bi-curry ( x p q -- p' q' ) [ [curry] ] bi@ bi ; inline
+
+: tri-curry ( x p q r -- p' q' r' ) [ [curry] ] tri@ tri ; inline
+
+: bi-curry* ( x y p q -- p' q' ) [ [curry] ] bi@ bi* ; inline
+
+: tri-curry* ( x y z p q r -- p' q' r' ) [ [curry] ] tri@ tri* ; inline
+
+: bi-curry@ ( x y q -- p' q' ) [curry] bi@ ; inline
+
+: tri-curry@ ( x y z q -- p' q' r' ) [curry] tri@ ; inline
+
 ! Booleans
 : not ( obj -- ? ) [ f ] [ t ] if ; inline
 
@@ -204,7 +190,7 @@ GENERIC: boa ( ... class -- tuple )
 
 ! Loops
 : loop ( pred: ( -- ? ) -- )
-    dup slip swap [ loop ] [ drop ] if ; inline recursive
+    [ call ] keep [ loop ] curry when ; inline recursive
 
 : do ( pred body tail -- pred body tail )
     over 3dip ; inline
@@ -215,6 +201,39 @@ GENERIC: boa ( ... class -- tuple )
 : until ( pred: ( -- ? ) body: ( -- ) tail: ( -- ) -- )
     [ [ not ] compose ] 2dip while ; inline
 
+! Object protocol
+GENERIC: hashcode* ( depth obj -- code )
+
+M: object hashcode* 2drop 0 ;
+
+M: f hashcode* 2drop 31337 ;
+
+: hashcode ( obj -- code ) 3 swap hashcode* ; inline
+
+GENERIC: equal? ( obj1 obj2 -- ? )
+
+M: object equal? 2drop f ;
+
+TUPLE: identity-tuple ;
+
+M: identity-tuple equal? 2drop f ;
+
+: = ( obj1 obj2 -- ? )
+    2dup eq? [ 2drop t ] [
+        2dup both-fixnums? [ 2drop f ] [ equal? ] if
+    ] if ; inline
+
+GENERIC: clone ( obj -- cloned )
+
+M: object clone ;
+
+M: callstack clone (clone) ;
+
+! Tuple construction
+GENERIC: new ( class -- tuple )
+
+GENERIC: boa ( ... class -- tuple )
+
 ! Error handling -- defined early so that other files can
 ! throw errors before continuations are loaded
 : throw ( error -- * ) 5 getenv [ die ] or 1 (throw) ;
index 7d0666328fd7a7eeceaf46b8a9d0c64d0c054cb4..94ff2c1f293121d2886a3de169189b3b9a806af4 100644 (file)
@@ -254,7 +254,7 @@ HELP: fp-infinity?
 { $description "Tests if " { $snippet "x" } " is an IEEE Infinity value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." }
 { $examples
     { $example "USING: math prettyprint ;" "1/0. fp-infinity? ." "t" }
-    { $example "USING: io kernel math ;" "-1/0. [ fp-infinity? ] [ 0 < ] bi [ \"negative infinity\" print ] when" "negative infinity" }
+    { $example "USING: io kernel math ;" "-1/0. [ fp-infinity? ] [ 0 < ] bi and [ \"negative infinity\" print ] when" "negative infinity" }
 } ;
 
 { fp-nan? fp-infinity? } related-words
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 4be7cfa8912b09e5efb2149459d44e58b8d3a08f..971ba245dddbc50790939b6b272f203415f31ac8 100644 (file)
@@ -200,7 +200,7 @@ SYMBOL: interactive-vocabs
 
 SYMBOL: print-use-hook
 
-print-use-hook global [ [ ] or ] change-at
+print-use-hook [ [ ] ] initialize
 
 : parse-fresh ( lines -- quot )
     [
index f2629a36c4317b317656eb73d3b84ee00384cc0f..2a03b7c74f6bca70dd24916390a81d475c68d82b 100644 (file)
@@ -7,6 +7,9 @@ ARTICLE: "quotations" "Quotations"
 $nl
 "Concretely, a quotation is an immutable sequence of objects, some of which may be words, together with a block of machine code which may be executed to achieve the effect of evaluating the quotation. The machine code is generated by a fast non-optimizing quotation compiler which is always running and is transparent to the developer."
 $nl
+"Quotations form a class of objects, however in most cases, methods should dispatch on " { $link callable } " instead, so that " { $link curry } " and " { $link compose } " values can participate."
+{ $subsection quotation }
+{ $subsection quotation? }
 "Quotations evaluate sequentially from beginning to end. Literals are pushed on the stack and words are executed. Details can be found in " { $link "evaluator" } "."
 $nl
 "Quotation literal syntax is documented in " { $link "syntax-quots" } "."
old mode 100644 (file)
new mode 100755 (executable)
index f166378..24ff1b0
@@ -151,6 +151,7 @@ M: class initial-value* no-initial-value ;
         { [ array bootstrap-word over class<= ] [ { } ] }
         { [ byte-array bootstrap-word over class<= ] [ B{ } ] }
         { [ simple-alien bootstrap-word over class<= ] [ <bad-alien> ] }
+        { [ quotation bootstrap-word over class<= ] [ [ ] ] }
         [ dup initial-value* ]
     } cond nip ;
 
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 e08821bddd5a1a4ceec45e194fffde8a0c6ce9e6..035622454f62d7127218a470dafe0e0d220c8016 100644 (file)
@@ -551,12 +551,12 @@ HELP: BIN:
 { $examples { $example "USE: prettyprint" "BIN: 100 ." "4" } } ;
 
 HELP: GENERIC:
-{ $syntax "GENERIC: word" }
+{ $syntax "GENERIC: word" "GENERIC: word ( stack -- effect )" }
 { $values { "word" "a new word to define" } }
 { $description "Defines a new generic word in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." } ;
 
 HELP: GENERIC#
-{ $syntax "GENERIC# word n" }
+{ $syntax "GENERIC# word n" "GENERIC# word n ( stack -- effect )" }
 { $values { "word" "a new word to define" } { "n" "the stack position to dispatch on" } }
 { $description "Defines a new generic word which dispatches on the " { $snippet "n" } "th most element from the top of the stack in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." }
 { $notes
@@ -571,7 +571,7 @@ HELP: MATH:
 { $description "Defines a new generic word which uses the " { $link math-combination } " method combination." } ;
 
 HELP: HOOK:
-{ $syntax "HOOK: word variable" }
+{ $syntax "HOOK: word variable" "HOOK: word variable ( stack -- effect ) " }
 { $values { "word" "a new word to define" } { "variable" word } }
 { $description "Defines a new hook word in the current vocabulary. Hook words are generic words which dispatch on the value of a variable, so methods are defined with " { $link POSTPONE: M: } ". Hook words differ from other generic words in that the dispatch value is removed from the stack before the chosen method is called." }
 { $examples
index 3197d0a6f65ead9aa5fd8df7a5fbdc224b2bc5a8..86486640316d2e39abaf7c80ff73779fce26c3f4 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 ]
diff --git a/extra/annotations/annotations-docs.factor b/extra/annotations/annotations-docs.factor
new file mode 100644 (file)
index 0000000..c340554
--- /dev/null
@@ -0,0 +1,42 @@
+USING: accessors arrays combinators definitions generalizations
+help help.markup help.topics kernel sequences sorting vocabs
+words ;
+IN: annotations
+
+<PRIVATE
+: comment-word ( base -- word ) "!" prepend "annotations" lookup ; 
+: comment-usage-word ( base -- word ) "s" append "annotations" lookup ; 
+: comment-usage.-word ( base -- word ) "s." append "annotations" lookup ; 
+PRIVATE>
+
+"Code annotations"
+{
+    "The " { $vocab-link "annotations" } " vocabulary provides syntax for comment-like annotations that can be looked up with Factor's " { $link usage } " mechanism."
+}
+annotation-tags natural-sort
+[
+    [ \ $subsection swap comment-word 2array ] map append
+    "To look up annotations:" suffix
+] [
+    [ \ $subsection swap comment-usage.-word 2array ] map append
+] bi
+<article> "annotations" add-article
+
+"annotations" vocab "annotations" >>help drop
+
+annotation-tags [
+    {
+        [ [ \ $syntax ] dip "!" " your comment here" surround 2array ]
+        [ [ \ $description "Treats the rest of the line after the exclamation point as a code annotation that can be looked up with the " \ $link ] dip comment-usage.-word 2array " word." 4array ]
+        [ [ \ $unchecked-example ] dip ": foo ( x y z -- w )\n    !" " --w-ó()ò-w-- kilroy was here\n    + * ;" surround 2array 3array ]
+        [ comment-word set-word-help ]
+
+        [ [ \ $description "Displays a list of words, help articles, and vocabularies that contain " \ $link ] dip comment-word 2array " annotations." 4array 1array ]
+        [ comment-usage.-word set-word-help ]
+
+        [ [ { $values { "usages" sequence } } \ $description "Returns a list of words, help articles, and vocabularies that contain " \ $link ] dip [ comment-word 2array " annotations. For a more user-friendly display, use the " \ $link ] [ comment-usage.-word 2array " word." 6 narray 2array ] bi ]
+        [ comment-usage-word set-word-help ]
+
+        [ [ comment-word ] [ comment-usage-word ] [ comment-usage.-word ] tri 3array related-words ]
+    } cleave
+] each
diff --git a/extra/annotations/annotations-tests.factor b/extra/annotations/annotations-tests.factor
new file mode 100644 (file)
index 0000000..d5a13e4
--- /dev/null
@@ -0,0 +1,27 @@
+USING: accessors annotations combinators.short-circuit
+io.pathnames kernel math sequences sorting tools.test ;
+IN: annotations.tests
+
+!NOTE testing toplevel form 
+
+: three ( -- x )
+    !BROKEN english plz
+    "þrij" ;
+
+: four ( -- x )
+    !BROKEN this code is broken
+    2 2 + 1+ ;
+
+: five ( -- x )
+    !TODO return 5
+    f ;
+
+[ t ] [
+    NOTEs {
+        [ length 1 = ]
+        [ first string>> file-name "annotations-tests.factor" = ]
+    } 1&&
+] unit-test
+
+[ { four three } ] [ BROKENs natural-sort ] unit-test
+[ { five } ] [ TODOs ] unit-test
diff --git a/extra/annotations/annotations.factor b/extra/annotations/annotations.factor
new file mode 100644 (file)
index 0000000..6685e4e
--- /dev/null
@@ -0,0 +1,43 @@
+! (c)2009 Joe Groff, Doug Coleman. see BSD license
+USING: accessors combinators.short-circuit definitions functors
+kernel lexer namespaces parser prettyprint sequences words ;
+IN: annotations
+
+<<
+
+: (parse-annotation) ( accum -- accum )
+    lexer get [ line-text>> parsed ] [ next-line ] bi ;
+
+: (non-annotation-usage) ( word -- usages )
+    smart-usage
+    [ { [ word? ] [ vocabulary>> "annotations" = ] } 1&& not ]
+    filter ;
+
+FUNCTOR: define-annotation ( NAME -- )
+
+(NAME) DEFINES (${NAME})
+!NAME  DEFINES !${NAME}
+NAMEs  DEFINES ${NAME}s
+NAMEs. DEFINES ${NAME}s.
+
+WHERE
+
+: (NAME) ( str -- ) drop ; inline
+: !NAME (parse-annotation) \ (NAME) parsed ; parsing
+
+: NAMEs ( -- usages )
+    \ (NAME) (non-annotation-usage) ;
+: NAMEs. ( -- )
+    NAMEs sorted-definitions. ;
+
+;FUNCTOR
+
+CONSTANT: annotation-tags {
+    "XXX" "TODO" "FIXME" "BUG" "REVIEW" "LICENSE"
+    "AUTHOR" "BROKEN" "HACK" "LOL" "NOTE"
+}
+
+annotation-tags [ define-annotation ] each
+
+>>
+
diff --git a/extra/annotations/authors.txt b/extra/annotations/authors.txt
new file mode 100644 (file)
index 0000000..0bc3c5a
--- /dev/null
@@ -0,0 +1,2 @@
+Joe Groff
+Doug Coleman
diff --git a/extra/annotations/summary.txt b/extra/annotations/summary.txt
new file mode 100644 (file)
index 0000000..732ed6f
--- /dev/null
@@ -0,0 +1 @@
+Code annotation comment syntax
diff --git a/extra/annotations/tags.txt b/extra/annotations/tags.txt
new file mode 100644 (file)
index 0000000..278296d
--- /dev/null
@@ -0,0 +1,2 @@
+comments
+annotation
index 716435775d651534c39fc27f9af775f356c6b491..1f6244102866a44c1df526c3a803d7d66a090fd2 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays byte-arrays kernel math namespaces
-opengl.gl sequences math.vectors ui graphics.bitmap graphics.viewer
+opengl.gl sequences math.vectors ui images.bitmap images.viewer
 models ui.gadgets.worlds ui.gadgets fry alien.syntax ;
 IN: cap
 
@@ -27,4 +27,4 @@ IN: cap
     [ screenshot ] dip save-bitmap ;
 
 : screenshot. ( window -- )
-    [ screenshot <graphics-gadget> ] [ title>> ] bi open-window ; 
+    [ screenshot <image-gadget> ] [ title>> ] bi open-window ; 
diff --git a/extra/constructors/authors.txt b/extra/constructors/authors.txt
deleted file mode 100644 (file)
index d4f5d6b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
\ No newline at end of file
diff --git a/extra/constructors/constructors-tests.factor b/extra/constructors/constructors-tests.factor
deleted file mode 100644 (file)
index 367f0ad..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-! Copyright (C) 2009 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test constructors calendar kernel accessors
-combinators.short-circuit ;
-IN: constructors.tests
-
-TUPLE: stock-spread stock spread timestamp ;
-
-CONSTRUCTOR: stock-spread ( stock spread -- stock-spread )
-   now >>timestamp ;
-
-SYMBOL: AAPL
-
-[ t ] [
-    AAPL 1234 <stock-spread>
-    {
-        [ stock>> AAPL eq? ]
-        [ spread>> 1234 = ]
-        [ timestamp>> timestamp? ]
-    } 1&&
-] unit-test
\ No newline at end of file
diff --git a/extra/constructors/constructors.factor b/extra/constructors/constructors.factor
deleted file mode 100644 (file)
index 2eab913..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-! Copyright (C) 2009 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: slots kernel sequences fry accessors parser lexer words
-effects.parser macros ;
-IN: constructors
-
-! An experiment
-
-MACRO: set-slots ( slots -- quot )
-    <reversed> [ setter-word '[ swap _ execute ] ] map [ ] join ;
-
-: construct ( ... class slots -- instance )
-    [ new ] dip set-slots ; inline
-
-: define-constructor ( name class effect body -- )
-    [ [ in>> '[ _ _ construct ] ] dip compose ] [ drop ] 2bi
-    define-declared ;
-
-: CONSTRUCTOR:
-    scan-word [ name>> "<" ">" surround create-in ] keep
-    "(" expect ")" parse-effect
-    parse-definition
-    define-constructor ; parsing
\ No newline at end of file
diff --git a/extra/graphics/authors.txt b/extra/graphics/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/graphics/bitmap/authors.txt b/extra/graphics/bitmap/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/graphics/bitmap/bitmap-tests.factor b/extra/graphics/bitmap/bitmap-tests.factor
deleted file mode 100644 (file)
index f8a125e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-USING: graphics.bitmap graphics.viewer io.encodings.binary
-io.files io.files.unique kernel tools.test ;
-IN: graphics.bitmap.tests
-
-: test-bitmap32-alpha ( -- path )
-    "resource:extra/graphics/bitmap/test-images/32alpha.bmp" ;
-
-: test-bitmap24 ( -- path )
-    "resource:extra/graphics/bitmap/test-images/thiswayup24.bmp" ;
-
-: test-bitmap16 ( -- path )
-    "resource:extra/graphics/bitmap/test-images/rgb16bit.bmp" ;
-
-: test-bitmap8 ( -- path )
-    "resource:extra/graphics/bitmap/test-images/rgb8bit.bmp" ;
-
-: test-bitmap4 ( -- path )
-    "resource:extra/graphics/bitmap/test-images/rgb4bit.bmp" ;
-
-: test-bitmap1 ( -- path )
-    "resource:extra/graphics/bitmap/test-images/1bit.bmp" ;
-
-[ t ]
-[
-    test-bitmap24
-    [ binary file-contents ] [ load-bitmap ] bi
-
-    "test-bitmap24" unique-file
-    [ save-bitmap ] [ binary file-contents ] bi =
-] unit-test
diff --git a/extra/graphics/bitmap/bitmap.factor b/extra/graphics/bitmap/bitmap.factor
deleted file mode 100755 (executable)
index f8008dc..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-! Copyright (C) 2007, 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien alien.c-types arrays byte-arrays columns
-combinators fry grouping io io.binary io.encodings.binary
-io.files kernel libc macros math math.bitwise math.functions
-namespaces opengl opengl.gl prettyprint sequences strings
-summary ui ui.gadgets.panes ;
-IN: graphics.bitmap
-
-! Currently can only handle 24/32bit bitmaps.
-! Handles row-reversed bitmaps (their height is negative)
-
-TUPLE: bitmap magic size reserved offset header-length width
-height planes bit-count compression size-image
-x-pels y-pels color-used color-important rgb-quads color-index
-alpha-channel-zero?
-array ;
-
-: array-copy ( bitmap array -- bitmap array' )
-    over size-image>> abs memory>byte-array ;
-
-MACRO: (nbits>bitmap) ( bits -- )
-    [ -3 shift ] keep '[
-        bitmap new
-            2over * _ * >>size-image
-            swap >>height
-            swap >>width
-            swap array-copy [ >>array ] [ >>color-index ] bi
-            _ >>bit-count
-    ] ;
-
-: bgr>bitmap ( array height width -- bitmap )
-    24 (nbits>bitmap) ;
-
-: bgra>bitmap ( array height width -- bitmap )
-    32 (nbits>bitmap) ;
-
-: 8bit>array ( bitmap -- array )
-    [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
-    [ color-index>> >array ] bi [ swap nth ] with map concat ;
-
-ERROR: bmp-not-supported n ;
-
-: raw-bitmap>array ( bitmap -- array )
-    dup bit-count>>
-    {
-        { 32 [ color-index>> ] }
-        { 24 [ color-index>> ] }
-        { 16 [ bmp-not-supported ] }
-        { 8 [ 8bit>array ] }
-        { 4 [ bmp-not-supported ] }
-        { 2 [ bmp-not-supported ] }
-        { 1 [ bmp-not-supported ] }
-    } case >byte-array ;
-
-ERROR: bitmap-magic ;
-
-M: bitmap-magic summary
-    drop "First two bytes of bitmap stream must be 'BM'" ;
-
-: read2 ( -- n ) 2 read le> ;
-: read4 ( -- n ) 4 read le> ;
-
-: parse-file-header ( bitmap -- bitmap )
-    2 read >string dup "BM" = [ bitmap-magic ] unless >>magic
-    read4 >>size
-    read4 >>reserved
-    read4 >>offset ;
-
-: parse-bitmap-header ( bitmap -- bitmap )
-    read4 >>header-length
-    read4 >>width
-    read4 >>height
-    read2 >>planes
-    read2 >>bit-count
-    read4 >>compression
-    read4 >>size-image
-    read4 >>x-pels
-    read4 >>y-pels
-    read4 >>color-used
-    read4 >>color-important ;
-
-: rgb-quads-length ( bitmap -- n )
-    [ offset>> 14 - ] [ header-length>> ] bi - ;
-
-: color-index-length ( bitmap -- n )
-    {
-        [ width>> ]
-        [ planes>> * ]
-        [ bit-count>> * 31 + 32 /i 4 * ]
-        [ height>> abs * ]
-    } cleave ;
-
-: parse-bitmap ( bitmap -- bitmap )
-    dup rgb-quads-length read >>rgb-quads
-    dup color-index-length read >>color-index ;
-
-: (load-bitmap) ( path -- bitmap )
-    binary [
-        bitmap new
-        parse-file-header parse-bitmap-header parse-bitmap
-    ] with-file-reader ;
-
-: alpha-channel-zero? ( bitmap -- ? )
-    array>> 4 <sliced-groups> 3 <column> [ 0 = ] all? ;
-
-: load-bitmap ( path -- bitmap )
-    (load-bitmap)
-    dup raw-bitmap>array >>array
-    dup alpha-channel-zero? >>alpha-channel-zero? ;
-
-: write2 ( n -- ) 2 >le write ;
-: write4 ( n -- ) 4 >le write ;
-
-: save-bitmap ( bitmap path -- )
-    binary [
-        B{ CHAR: B CHAR: M } write
-        [
-            array>> length 14 + 40 + write4
-            0 write4
-            54 write4
-            40 write4
-        ] [
-            {
-                [ width>> write4 ]
-                [ height>> write4 ]
-                [ planes>> 1 or write2 ]
-                [ bit-count>> 24 or write2 ]
-                [ compression>> 0 or write4 ]
-                [ size-image>> write4 ]
-                [ x-pels>> 0 or write4 ]
-                [ y-pels>> 0 or write4 ]
-                [ color-used>> 0 or write4 ]
-                [ color-important>> 0 or write4 ]
-                [ rgb-quads>> write ]
-                [ color-index>> write ]
-            } cleave
-        ] bi
-    ] with-file-writer ;
diff --git a/extra/graphics/bitmap/test-images/1bit.bmp b/extra/graphics/bitmap/test-images/1bit.bmp
deleted file mode 100644 (file)
index 2f244c1..0000000
Binary files a/extra/graphics/bitmap/test-images/1bit.bmp and /dev/null differ
diff --git a/extra/graphics/bitmap/test-images/rgb4bit.bmp b/extra/graphics/bitmap/test-images/rgb4bit.bmp
deleted file mode 100644 (file)
index 0c6f00d..0000000
Binary files a/extra/graphics/bitmap/test-images/rgb4bit.bmp and /dev/null differ
diff --git a/extra/graphics/bitmap/test-images/rgb8bit.bmp b/extra/graphics/bitmap/test-images/rgb8bit.bmp
deleted file mode 100644 (file)
index bc95c0f..0000000
Binary files a/extra/graphics/bitmap/test-images/rgb8bit.bmp and /dev/null differ
diff --git a/extra/graphics/bitmap/test-images/thiswayup24.bmp b/extra/graphics/bitmap/test-images/thiswayup24.bmp
deleted file mode 100644 (file)
index 202fb15..0000000
Binary files a/extra/graphics/bitmap/test-images/thiswayup24.bmp and /dev/null differ
diff --git a/extra/graphics/tags.txt b/extra/graphics/tags.txt
deleted file mode 100644 (file)
index 04b54a0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bitmap graphics
diff --git a/extra/graphics/tiff/authors.txt b/extra/graphics/tiff/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/graphics/tiff/rgb.tiff b/extra/graphics/tiff/rgb.tiff
deleted file mode 100755 (executable)
index 71cbaa9..0000000
Binary files a/extra/graphics/tiff/rgb.tiff and /dev/null differ
diff --git a/extra/graphics/tiff/tiff-tests.factor b/extra/graphics/tiff/tiff-tests.factor
deleted file mode 100755 (executable)
index daee9a5..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-! Copyright (C) 2009 Your name.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test graphics.tiff ;
-IN: graphics.tiff.tests
-
-: tiff-test-path ( -- path )
-    "resource:extra/graphics/tiff/rgb.tiff" ;
-
-
diff --git a/extra/graphics/tiff/tiff.factor b/extra/graphics/tiff/tiff.factor
deleted file mode 100755 (executable)
index e66ebcc..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-! Copyright (C) 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators io io.encodings.binary io.files
-kernel pack endian tools.hexdump constructors sequences arrays
-sorting.slots math.order math.parser prettyprint ;
-IN: graphics.tiff
-
-TUPLE: tiff
-endianness
-the-answer
-ifd-offset
-ifds
-processed-ifds ;
-
-CONSTRUCTOR: tiff ( -- tiff )
-    V{ } clone >>ifds ;
-
-TUPLE: ifd count ifd-entries next ;
-
-CONSTRUCTOR: ifd ( count ifd-entries next -- ifd ) ;
-
-TUPLE: ifd-entry tag type count offset ;
-
-CONSTRUCTOR: ifd-entry ( tag type count offset -- ifd-entry ) ;
-
-
-TUPLE: photometric-interpretation color ;
-
-CONSTRUCTOR: photometric-interpretation ( color -- object ) ;
-
-SINGLETONS: white-is-zero black-is-zero rgb palette-color ;
-
-ERROR: bad-photometric-interpretation n ;
-
-: lookup-photometric-interpretation ( n -- singleton )
-    {
-        { 0 [ white-is-zero ] }
-        { 1 [ black-is-zero ] }
-        { 2 [ rgb ] }
-        { 3 [ palette-color ] }
-        [ bad-photometric-interpretation ]
-    } case <photometric-interpretation> ;
-
-
-TUPLE: compression method ;
-
-CONSTRUCTOR: compression ( method -- object ) ;
-
-SINGLETONS: no-compression CCITT-2 pack-bits lzw ;
-
-ERROR: bad-compression n ;
-
-: lookup-compression ( n -- compression )
-    {
-        { 1 [ no-compression ] }
-        { 2 [ CCITT-2 ] }
-        { 5 [ lzw ] }
-        { 32773 [ pack-bits ] }
-        [ bad-compression ]
-    } case <compression> ;
-
-TUPLE: image-length n ;
-CONSTRUCTOR: image-length ( n -- object ) ;
-
-TUPLE: image-width n ;
-CONSTRUCTOR: image-width ( n -- object ) ;
-
-TUPLE: x-resolution n ;
-CONSTRUCTOR: x-resolution ( n -- object ) ;
-
-TUPLE: y-resolution n ;
-CONSTRUCTOR: y-resolution ( n -- object ) ;
-
-TUPLE: rows-per-strip n ;
-CONSTRUCTOR: rows-per-strip ( n -- object ) ;
-
-TUPLE: strip-offsets n ;
-CONSTRUCTOR: strip-offsets ( n -- object ) ;
-
-TUPLE: strip-byte-counts n ;
-CONSTRUCTOR: strip-byte-counts ( n -- object ) ;
-
-TUPLE: bits-per-sample n ;
-CONSTRUCTOR: bits-per-sample ( n -- object ) ;
-
-TUPLE: samples-per-pixel n ;
-CONSTRUCTOR: samples-per-pixel ( n -- object ) ;
-
-SINGLETONS: no-resolution-unit
-inch-resolution-unit
-centimeter-resolution-unit ;
-
-TUPLE: resolution-unit type ;
-CONSTRUCTOR: resolution-unit ( type -- object ) ;
-
-ERROR: bad-resolution-unit n ;
-
-: lookup-resolution-unit ( n -- object )
-    {
-        { 1 [ no-resolution-unit ] }
-        { 2 [ inch-resolution-unit ] }
-        { 3 [ centimeter-resolution-unit ] }
-        [ bad-resolution-unit ]
-    } case <resolution-unit> ;
-
-
-TUPLE: predictor type ;
-CONSTRUCTOR: predictor ( type -- object ) ;
-
-SINGLETONS: no-predictor horizontal-differencing-predictor ;
-
-ERROR: bad-predictor n ;
-
-: lookup-predictor ( n -- object )
-    {
-        { 1 [ no-predictor ] }
-        { 2 [ horizontal-differencing-predictor ] }
-        [ bad-predictor ]
-    } case <predictor> ;
-
-
-TUPLE: planar-configuration type ;
-CONSTRUCTOR: planar-configuration ( type -- object ) ;
-
-SINGLETONS: chunky planar ;
-
-ERROR: bad-planar-configuration n ;
-
-: lookup-planar-configuration ( n -- object )
-    {
-        { 1 [ no-predictor ] }
-        { 2 [ horizontal-differencing-predictor ] }
-        [ bad-predictor ]
-    } case <planar-configuration> ;
-
-
-TUPLE: new-subfile-type n ;
-CONSTRUCTOR: new-subfile-type ( n -- object ) ;
-
-
-
-ERROR: bad-tiff-magic bytes ;
-
-: tiff-endianness ( byte-array -- ? )
-    {
-        { B{ CHAR: M CHAR: M } [ big-endian ] }
-        { B{ CHAR: I CHAR: I } [ little-endian ] }
-        [ bad-tiff-magic ]
-    } case ;
-
-: with-tiff-endianness ( tiff quot -- tiff )
-    [ dup endianness>> ] dip with-endianness ; inline
-
-: read-header ( tiff -- tiff )
-    2 read tiff-endianness [ >>endianness ] keep
-    [
-        2 read endian> >>the-answer
-        4 read endian> >>ifd-offset
-    ] with-endianness ;
-
-: push-ifd ( tiff ifd -- tiff )
-    over ifds>> push ;
-
-: read-ifd ( -- ifd )
-    2 read endian>
-    2 read endian>
-    4 read endian>
-    4 read endian> <ifd-entry> ;
-
-: read-ifds ( tiff -- tiff )
-    [
-        dup ifd-offset>> seek-absolute seek-input
-        2 read endian>
-        dup [ read-ifd ] replicate
-        4 read endian>
-        [ <ifd> push-ifd ] [ 0 = [ read-ifds ] unless ] bi
-    ] with-tiff-endianness ;
-
-! ERROR: unhandled-ifd-entry data n ;
-
-: unhandled-ifd-entry ;
-
-: ifd-entry-value ( ifd-entry -- n )
-    dup count>> 1 = [
-        offset>>
-    ] [
-        [ offset>> seek-absolute seek-input ] [ count>> read ] bi
-    ] if ;
-
-: process-ifd-entry ( ifd-entry -- object )
-    [ ifd-entry-value ] [ tag>> ] bi {
-        { 254 [ <new-subfile-type> ] }
-        { 256 [ <image-width> ] }
-        { 257 [ <image-length> ] }
-        { 258 [ <bits-per-sample> ] }
-        { 259 [ lookup-compression ] }
-        { 262 [ lookup-photometric-interpretation ] }
-        { 273 [ <strip-offsets> ] }
-        { 277 [ <samples-per-pixel> ] }
-        { 278 [ <rows-per-strip> ] }
-        { 279 [ <strip-byte-counts> ] }
-        { 282 [ <x-resolution> ] }
-        { 283 [ <y-resolution> ] }
-        { 284 [ <planar-configuration> ] }
-        { 296 [ lookup-resolution-unit ] }
-        { 317 [ lookup-predictor ] }
-        [ unhandled-ifd-entry swap 2array ]
-    } case ;
-
-: process-ifd ( ifd -- processed-ifd )
-    ifd-entries>> [ process-ifd-entry ] map ;
-
-: (load-tiff) ( path -- tiff )
-    binary [
-        <tiff>
-        read-header
-        read-ifds
-        dup ifds>> [ process-ifd ] map
-        >>processed-ifds
-    ] with-file-reader ;
-
-: load-tiff ( path -- tiff )
-    (load-tiff) ;
diff --git a/extra/graphics/viewer/authors.txt b/extra/graphics/viewer/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/graphics/viewer/viewer.factor b/extra/graphics/viewer/viewer.factor
deleted file mode 100644 (file)
index 8e0b1ec..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-! Copyright (C) 2007 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays combinators graphics.bitmap kernel math
-math.functions namespaces opengl opengl.gl ui ui.gadgets
-ui.gadgets.panes ui.render ;
-IN: graphics.viewer
-
-TUPLE: graphics-gadget < gadget image ;
-
-GENERIC: draw-image ( image -- )
-GENERIC: width ( image -- w )
-GENERIC: height ( image -- h )
-
-M: graphics-gadget pref-dim*
-    image>> [ width ] keep height abs 2array ;
-
-M: graphics-gadget draw-gadget* ( gadget -- )
-    origin get [ image>> draw-image ] with-translation ;
-
-: <graphics-gadget> ( bitmap -- gadget )
-    \ graphics-gadget new-gadget
-        swap >>image ;
-
-M: bitmap draw-image ( bitmap -- )
-    dup height>> 0 < [
-        0 0 glRasterPos2i
-        1.0 -1.0 glPixelZoom
-    ] [
-        0 over height>> abs glRasterPos2i
-        1.0 1.0 glPixelZoom
-    ] if
-    [ width>> ] keep
-    [
-        [ height>> abs ] keep
-        bit-count>> {
-            { 32 [ GL_BGRA GL_UNSIGNED_BYTE ] }
-            { 24 [ GL_BGR GL_UNSIGNED_BYTE ] }
-            { 8 [ GL_BGR GL_UNSIGNED_BYTE ] }
-            { 4 [ GL_BGR GL_UNSIGNED_BYTE ] }
-        } case
-    ] keep array>> glDrawPixels ;
-
-M: bitmap width ( bitmap -- ) width>> ;
-M: bitmap height ( bitmap -- ) height>> ;
-
-: bitmap. ( path -- )
-    load-bitmap <graphics-gadget> gadget. ;
-
-: bitmap-window ( path -- gadget )
-    load-bitmap <graphics-gadget> [ "bitmap" open-window ] keep ;
diff --git a/extra/id3/authors.txt b/extra/id3/authors.txt
new file mode 100644 (file)
index 0000000..ece617b
--- /dev/null
@@ -0,0 +1,2 @@
+Tim Wawrzynczak
+
diff --git a/extra/id3/id3-docs.factor b/extra/id3/id3-docs.factor
new file mode 100644 (file)
index 0000000..da69c2c
--- /dev/null
@@ -0,0 +1,17 @@
+! Copyright (C) 2008 Tim Wawrzynczak
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax sequences kernel ;
+IN: id3
+
+HELP: file-id3-tags
+{ $values 
+    { "path" "a path string" } 
+    { "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"
+"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"
diff --git a/extra/id3/id3-tests.factor b/extra/id3/id3-tests.factor
new file mode 100644 (file)
index 0000000..b9d45b1
--- /dev/null
@@ -0,0 +1,182 @@
+! Copyright (C) 2009 Tim Wawrzynczak
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test id3 ;
+IN: id3.tests
+
+[ T{ mp3v2-file
+     { header  T{ header f t 0 502 } }
+     { frames
+       {
+           T{ frame
+              { frame-id "COMM" }
+              { flags B{ 0 0 } }
+              { size 19 }
+              { data "eng, AG# 08E1C12E" }
+           }
+           T{ frame
+              { frame-id "TIT2" }
+              { flags B{ 0 0 } }
+              { size 15 }
+              { data "Stormy Weather" }
+           }
+           T{ frame
+              { frame-id "TRCK" }
+              { flags B{ 0 0 } }
+              { size 3 }
+              { data "32" }
+           }
+           T{ frame
+              { frame-id "TCON" }
+              { flags B{ 0 0 } }
+              { size 5 }
+              { data "(96)" }
+           }
+           T{ frame
+              { frame-id "TALB" }
+              { flags B{ 0 0 } }
+              { size 28 }
+              { data "Night and Day Frank Sinatra" }
+           }
+           T{ frame
+              { frame-id "PRIV" }
+              { flags B{ 0 0 } }
+              { size 39 }
+              { data "WM/MediaClassPrimaryID�}`�#��K�H�*(D" }
+           }
+           T{ frame
+              { frame-id "PRIV" }
+              { flags B{ 0 0 } }
+              { size 41 }
+              { data "WM/MediaClassSecondaryID" }
+           }
+           T{ frame
+              { frame-id "TPE1" }
+              { flags B{ 0 0 } }
+              { size 14 }
+              { data "Frank Sinatra" }
+           }
+       }
+     }
+}
+] [ "resource:extra/id3/tests/blah3.mp3" file-id3-tags ] unit-test
+
+[
+    T{ mp3v2-file
+    { header
+        T{ header { version t } { flags 0 } { size 1405 } }
+    }
+    { frames
+        {
+            T{ frame
+                { frame-id "TIT2" }
+                { flags B{ 0 0 } }
+                { size 22 }
+                { data "Anthem of the Trinity" }
+            }
+            T{ frame
+                { frame-id "TPE1" }
+                { flags B{ 0 0 } }
+                { size 12 }
+                { data "Terry Riley" }
+            }
+            T{ frame
+                { frame-id "TALB" }
+                { flags B{ 0 0 } }
+                { size 11 }
+                { data "Shri Camel" }
+            }
+            T{ frame
+                { frame-id "TCON" }
+                { flags B{ 0 0 } }
+                { size 10 }
+                { data "Classical" }
+            }
+            T{ frame
+                { frame-id "UFID" }
+                { flags B{ 0 0 } }
+                { size 23 }
+                { data "http://musicbrainz.org" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 23 }
+                { data "MusicBrainz Artist Id" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 22 }
+                { data "musicbrainz_artistid" }
+            }
+            T{ frame
+                { frame-id "TRCK" }
+                { flags B{ 0 0 } }
+                { size 2 }
+                { data "1" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 22 }
+                { data "MusicBrainz Album Id" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 21 }
+                { data "musicbrainz_albumid" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 29 }
+                { data "MusicBrainz Album Artist Id" }
+            }
+            T{ frame
+                { frame-id "TXXX" }
+                { flags B{ 0 0 } }
+                { size 27 }
+                { data "musicbrainz_albumartistid" }
+            }
+            T{ frame
+                { frame-id "TPOS" }
+                { flags B{ 0 0 } }
+                { size 2 }
+                { data "1" }
+            }
+            T{ frame
+                { frame-id "TSOP" }
+                { flags B{ 0 0 } }
+                { size 1 }
+            }
+            T{ frame
+                { frame-id "TMED" }
+                { flags B{ 0 0 } }
+                { size 4 }
+                { data "DIG" }
+            }
+        }
+    }
+}
+] [ "resource:extra/id3/tests/blah2.mp3" file-id3-tags ] unit-test
+
+[    
+  T{ mp3v1-file
+     { title
+       "BLAH\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+     }
+     { artist
+       "ARTIST\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+     }
+     { album
+       "ALBUM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+     }
+     { year "2009" }
+     { comment
+       "COMMENT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+     }
+     { genre 89 }
+  }
+] [ "resource:extra/id3/tests/blah.mp3" file-id3-tags ] unit-test
+
diff --git a/extra/id3/id3.factor b/extra/id3/id3.factor
new file mode 100644 (file)
index 0000000..64e1ff1
--- /dev/null
@@ -0,0 +1,154 @@
+! Copyright (C) 2009 Tim Wawrzynczak
+! See http://factorcode.org/license.txt for BSD license.
+USING: sequences io io.encodings.binary io.files io.pathnames strings kernel math io.mmap io.mmap.uchar accessors syntax combinators math.ranges unicode.categories byte-arrays prettyprint io.encodings.string io.encodings.ascii ;
+IN: id3
+
+! tuples
+
+TUPLE: header version flags size ;
+
+TUPLE: frame frame-id flags size data ;
+
+TUPLE: mp3v2-file header frames ;
+
+TUPLE: mp3v1-file title artist album year comment genre ;
+
+: <mp3v1-file> ( -- object ) mp3v1-file new ;
+
+: <mp3v2-file> ( header frames -- object ) mp3v2-file boa ;
+
+: <header> ( -- object ) header new ;
+
+: <frame> ( -- object ) frame new ;
+
+<PRIVATE
+
+! utility words
+
+: id3v2? ( mmap -- ? )
+    "ID3" head? ;
+
+: id3v1? ( mmap -- ? )
+    128 tail-slice* "TAG" head? ;
+
+: >28bitword ( seq -- int )
+    0 [ swap 7 shift bitor ] reduce ;
+
+: filter-text-data ( data -- filtered )
+    [ printable? ] filter ;
+
+! frame details stuff
+
+: valid-frame-id? ( id -- ? )
+    [ [ digit? ] [ LETTER? ] bi or ] all? ;
+
+: read-frame-id ( mmap -- id )
+    4 head-slice ;
+
+: read-frame-size ( mmap -- size )
+    [ 4 8 ] dip subseq ;
+
+: read-frame-flags ( mmap -- flags )
+    [ 8 10 ] dip subseq ;
+
+: read-frame-data ( frame mmap -- frame data )
+    [ 10 over size>> 10 + ] dip <slice> filter-text-data ;
+
+! read whole frames
+
+: (read-frame) ( mmap -- frame )
+    [ <frame> ] dip
+    {
+        [ read-frame-id    ascii decode >>frame-id ]
+        [ read-frame-flags >byte-array  >>flags ]
+        [ read-frame-size  >28bitword   >>size ]
+        [ read-frame-data  ascii decode >>data ]
+    } cleave ;
+
+: read-frame ( mmap -- frame/f )
+    dup read-frame-id valid-frame-id? [ (read-frame) ] [ drop f ] if ;
+
+: remove-frame ( mmap frame -- mmap )
+    size>> 10 + tail-slice ;
+
+: read-frames ( mmap -- frames )
+    [ dup read-frame dup ]
+    [ [ remove-frame ] keep ]
+    [ drop ] produce nip ;
+    
+! header stuff
+
+: read-header-supported-version? ( mmap -- ? )
+    3 tail-slice [ { 4 } head? ] [ { 3 } head? ] bi or ;
+
+: read-header-flags ( mmap -- flags )
+    5 swap nth ;
+
+: read-header-size ( mmap -- size )
+    [ 6 10 ] dip <slice> >28bitword ;
+
+: read-v2-header ( mmap -- id3header )
+    [ <header> ] dip
+    {
+        [ read-header-supported-version?  >>version ]
+        [ read-header-flags >>flags ]
+        [ read-header-size >>size ]
+    } cleave ;
+
+: drop-header ( mmap -- seq1 seq2 )
+    dup 10 tail-slice swap ;
+
+: read-v2-tag-data ( seq -- mp3v2-file )
+    drop-header read-v2-header swap read-frames <mp3v2-file> ;
+
+! v1 information
+
+: skip-to-v1-data ( seq -- seq )
+    125 tail-slice* ;
+
+: read-title ( seq -- title )
+    30 head-slice ;
+
+: read-artist ( seq -- title )
+    [ 30 60 ] dip subseq ;
+
+: read-album ( seq -- album )
+    [ 60 90 ] dip subseq ;
+
+: read-year ( seq -- year )
+    [ 90 94 ] dip subseq ;
+
+: read-comment ( seq -- comment )
+    [ 94 124 ] dip subseq ;
+
+: read-genre ( seq -- genre )
+    [ 124 ] dip nth ;
+
+: (read-v1-tag-data) ( seq -- mp3-file )
+    [ <mp3v1-file> ] dip
+    {
+        [ read-title   ascii decode  >>title ]
+        [ read-artist  ascii decode  >>artist ]
+        [ read-album   ascii decode  >>album ]
+        [ read-year    ascii decode  >>year ]
+        [ read-comment ascii decode  >>comment ]
+        [ read-genre   >fixnum       >>genre ]
+    } cleave ;
+
+: read-v1-tag-data ( seq -- mp3-file )
+    skip-to-v1-data (read-v1-tag-data) ;
+
+PRIVATE>
+
+! main stuff
+
+: file-id3-tags ( path -- object/f )
+    [
+        {
+            { [ dup id3v2? ] [ read-v2-tag-data ] } ! ( ? -- mp3v2-file )
+            { [ dup id3v1? ] [ read-v1-tag-data ] } ! ( ? -- mp3v1-file )
+            [ drop f ] ! ( mmap -- f )
+        } cond
+    ] with-mapped-uchar-file ;
+
+! end
diff --git a/extra/id3/tests/blah.mp3 b/extra/id3/tests/blah.mp3
new file mode 100644 (file)
index 0000000..3a60bff
Binary files /dev/null and b/extra/id3/tests/blah.mp3 differ
diff --git a/extra/id3/tests/blah2.mp3 b/extra/id3/tests/blah2.mp3
new file mode 100644 (file)
index 0000000..5d27429
Binary files /dev/null and b/extra/id3/tests/blah2.mp3 differ
diff --git a/extra/id3/tests/blah3.mp3 b/extra/id3/tests/blah3.mp3
new file mode 100644 (file)
index 0000000..19aaa94
Binary files /dev/null and b/extra/id3/tests/blah3.mp3 differ
diff --git a/extra/images/viewer/authors.txt b/extra/images/viewer/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/extra/images/viewer/viewer.factor b/extra/images/viewer/viewer.factor
new file mode 100644 (file)
index 0000000..06e4c68
--- /dev/null
@@ -0,0 +1,37 @@
+! Copyright (C) 2007 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors images images.loader io.pathnames kernel
+namespaces opengl opengl.gl sequences strings ui ui.gadgets
+ui.gadgets.panes ui.render ;
+IN: images.viewer
+
+TUPLE: image-gadget < gadget { image image } ;
+
+M: image-gadget pref-dim*
+    image>> dim>> ;
+
+: draw-image ( tiff -- )
+    0 0 glRasterPos2i 1.0 -1.0 glPixelZoom
+    [ dim>> first2 GL_RGBA GL_UNSIGNED_BYTE ]
+    [ bitmap>> ] bi glDrawPixels ;
+
+M: image-gadget draw-gadget* ( gadget -- )
+    origin get [ image>> draw-image ] with-translation ;
+
+: <image-gadget> ( image -- gadget )
+    \ image-gadget new-gadget
+        swap >>image ;
+
+: image-window ( path -- gadget )
+    [ load-image <image-gadget> dup ] [ open-window ] bi ;
+
+GENERIC: image. ( object -- )
+
+: default-image. ( path -- )
+    <image-gadget> gadget. ;
+
+M: string image. ( image -- ) load-image default-image. ;
+
+M: pathname image. ( image -- ) load-image default-image. ;
+
+M: image image. ( image -- ) default-image. ;
index 0bc22feeb762341f4c31bcf76dca9e3f475b06dc..1908b3d39bc54af20633d9b22b08e8dc9ab22dcd 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 IN: infix.ast
 
 TUPLE: ast-number value ;
diff --git a/extra/infix/authors.txt b/extra/infix/authors.txt
new file mode 100644 (file)
index 0000000..156a81a
--- /dev/null
@@ -0,0 +1 @@
+Philipp Brüschweiler
index 7a4febb514b7383021d0c4220a30602cfb29dc80..4a2ec963eecad92a21d7ba752ccb1df5c197d76c 100644 (file)
@@ -1,4 +1,6 @@
-USING: help.syntax help.markup prettyprint locals ;
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup math prettyprint locals sequences ;
 IN: infix
 
 HELP: [infix
@@ -36,3 +38,54 @@ HELP: [infix|
 } ;
 
 { POSTPONE: [infix POSTPONE: [infix| } related-words
+
+ARTICLE: "infix" "Infix notation"
+"The " { $vocab-link "infix" } " vocabulary implements support for infix notation in Factor source code."
+{ $subsection POSTPONE: [infix }
+{ $subsection POSTPONE: [infix| }
+$nl
+"The usual infix math operators are supported:"
+{ $list
+    { $link + }
+    { $link - }
+    { $link * }
+    { $link / }
+    { { $snippet "%" } ", which is the infix operator for " { $link mod } "." }
+}
+"The standard precedence rules apply: Grouping with parentheses before " { $snippet "*" } ", " { $snippet "/" } "and " { $snippet "%" } " before " { $snippet "+" } " and " { $snippet "-" } "."
+{ $example
+    "USING: infix prettyprint ;"
+    "[infix 5-40/10*2 infix] ."
+    "-3"
+}
+$nl
+"You can call Factor words in infix expressions just as you would in C. There are some restrictions on which words are legal to use though:"
+{ $list
+    "The word must return exactly one value."
+    "The word name must consist of the letters a-z, A-Z, _ or 0-9, and the first character can't be a number."
+}
+{ $example
+    "USING: infix locals math math.functions prettyprint ;"
+    ":: binary_entropy ( p -- h )"
+    "    [infix -(p*log(p) + (1-p)*log(1-p)) / log(2) infix] ;"
+    "[infix binary_entropy( sqrt(0.25) ) infix] ."
+    "1.0"
+}
+$nl
+"You can access " { $vocab-link "sequences" } " inside infix expressions with the familiar " { $snippet "arr[index]" } " notation."
+{ $example
+    "USING: arrays infix prettyprint ;"
+    "[infix| myarr [ { 1 2 3 4 } ] | myarr[4/2]*3 infix] ."
+    "9"
+}
+"Please note: in Factor " { $emphasis "fixnums are sequences too." } " If you are not careful with sequence accesses you may introduce subtle bugs:"
+{ $example
+    "USING: arrays infix locals prettyprint ;"
+    ":: add-2nd-element ( x y -- res )"
+    "    [infix x[1] + y[1] infix] ;"
+    "{ 1 2 3 } 5 add-2nd-element ."
+    "3"
+}
+;
+
+ABOUT: "infix"
index 5ee64681310ef27bd82e59cde1ce48165b16a287..7e8e2dfcc97c2ecfa4342a3b0142cdea5c4cb87f 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: infix infix.private kernel locals math math.functions
 tools.test ;
 IN: infix.tests
index 31cd1cbe1f4ea82c08373681293a3978f7430779..3e2ba49e3cc926c343538e5bfb5c62145915e4c5 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators combinators.short-circuit
 effects fry infix.parser infix.ast kernel locals.parser
 locals.types math multiline namespaces parser quotations
index 0a0288c41b97cc36a12e634a1ff4c915722a7250..d6b5d0559c5f74d45c664020d3ec5a1e58bc54dc 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: infix.ast infix.parser infix.tokenizer tools.test ;
 IN: infix.parser.tests
 
index beaf3c335d2b7f6889d0295b6ac9a287ee1e57de..2f9ab03d18b9925e8cf17ff323245da2a3aa6ee6 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: infix.ast infix.tokenizer kernel math peg.ebnf sequences
 strings vectors ;
 IN: infix.parser
diff --git a/extra/infix/summary.txt b/extra/infix/summary.txt
new file mode 100644 (file)
index 0000000..63d366d
--- /dev/null
@@ -0,0 +1 @@
+Support for infix notation in Factor programs
diff --git a/extra/infix/tags.txt b/extra/infix/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 7e1fb005efe9f1f1d8cfaeb9d32dacdb9bccac74..f9c908414a80efabfa8a58c97218f423153d6fe6 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: infix.ast infix.tokenizer tools.test ;
 IN: infix.tokenizer.tests
 
index 8c1a1b4a18a5b15c690853aa7279a759c11cbe65..f5bce4b6d7270e860c4001f83a90bc0a2a3d0bc6 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2009 Philipp Brüschweiler
+! See http://factorcode.org/license.txt for BSD license.
 USING: infix.ast kernel peg peg.ebnf math.parser sequences
 strings ;
 IN: infix.tokenizer
diff --git a/extra/lists/authors.txt b/extra/lists/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/lists/lazy/authors.txt b/extra/lists/lazy/authors.txt
deleted file mode 100644 (file)
index f6ba9ba..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Chris Double
-Samuel Tardieu
-Matthew Willis
diff --git a/extra/lists/lazy/examples/authors.txt b/extra/lists/lazy/examples/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/lists/lazy/examples/examples-tests.factor b/extra/lists/lazy/examples/examples-tests.factor
deleted file mode 100644 (file)
index 04886e2..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: lists.lazy.examples lists.lazy tools.test ;
-IN: lists.lazy.examples.tests
-
-[ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test
-[ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test
diff --git a/extra/lists/lazy/examples/examples.factor b/extra/lists/lazy/examples/examples.factor
deleted file mode 100644 (file)
index 1d5bb49..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! Rewritten by Matthew Willis, July 2006
-! Copyright (C) 2004 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: lists.lazy math kernel sequences quotations ;
-IN: lists.lazy.examples
-
-: naturals ( -- list ) 0 lfrom ;
-: positives ( -- list ) 1 lfrom ;
-: evens ( -- list ) 0 [ 2 + ] lfrom-by ;
-: odds ( -- list ) 1 lfrom [ 2 mod 1 = ] lfilter ;
-: powers-of-2 ( -- list ) 1 [ 2 * ] lfrom-by ;
-: ones ( -- list ) 1 [ ] lfrom-by ;
-: squares ( -- list ) naturals [ dup * ] lazy-map ;
-: first-five-squares ( -- list ) 5 squares ltake list>array ;
diff --git a/extra/lists/lazy/lazy-docs.factor b/extra/lists/lazy/lazy-docs.factor
deleted file mode 100644 (file)
index c402cdf..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-! Copyright (C) 2006 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: help.markup help.syntax sequences strings lists ;
-IN: lists.lazy 
-
-HELP: lazy-cons
-{ $values { "car" { $quotation "( -- X )" } } { "cdr" { $quotation "( -- cons )" } } { "promise" "the resulting cons object" } }
-{ $description "Constructs a cons object for a lazy list from two quotations. The " { $snippet "car" } " quotation should return the head of the list, and the " { $snippet "cons" } " quotation the tail when called. When " { $link cons } " or " { $link cdr } " are called on the lazy-cons object then the appropriate quotation is called." } 
-{ $see-also cons car cdr nil nil? } ;
-
-{ 1lazy-list 2lazy-list 3lazy-list } related-words
-
-HELP: 1lazy-list
-{ $values { "a" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 1 element. The element is the result of calling the quotation. The quotation is only called when the list element is requested." } ;
-
-HELP: 2lazy-list
-{ $values { "a" { $quotation "( -- X )" } } { "b" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 2 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
-
-HELP: 3lazy-list
-{ $values { "a" { $quotation "( -- X )" } } { "b" { $quotation "( -- X )" } } { "c" { $quotation "( -- X )" } } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 3 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
-
-HELP: <memoized-cons>
-{ $values { "cons" "a cons object" } { "memoized-cons" "the resulting memoized-cons object" } }
-{ $description "Constructs a cons object that wraps an existing cons object. Requests for the car, cdr and nil? will be remembered after the first call, and the previous result returned on subsequent calls." } 
-{ $see-also cons car cdr nil nil? } ;
-
-{ lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
-
-HELP: lazy-map
-{ $values { "list" "a cons object" } { "quot" { $quotation "( obj -- X )" } } { "result" "resulting cons object" } }
-{ $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-map> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lazy-map-with
-{ $values { "value" "an object" } { "list" "a cons object" } { "quot" { $quotation "( obj elt -- X )" } } { "result" "resulting cons object" } }
-{ $description "Variant of " { $link lazy-map } " which pushes a retained object on each invocation of the quotation." } ;
-
-HELP: ltake
-{ $values { "n" "a non negative integer" } { "list" "a cons object" } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first n items in the list. This is done a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-take> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lfilter
-{ $values { "list" "a cons object" } { "quot" { $quotation "( -- X )" } } { "result" "resulting cons object" } }
-{ $description "Perform a similar functionality to that of the " { $link filter } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-filter> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lwhile
-{ $values { "list" "a cons object" } { "quot" { $quotation "( X -- ? )" } } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first items in the list as long as " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: luntil
-{ $values { "list" "a cons object" } { "quot" { $quotation "( X -- ? )" } } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first items in the list until after " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: list>vector
-{ $values { "list" "a cons object" } { "vector" "the list converted to a vector" } }
-{ $description "Convert a list to a vector. If the list is a lazy infinite list then this will enter an infinite loop." } 
-{ $see-also list>array } ;
-
-HELP: list>array
-{ $values { "list" "a cons object" } { "array" "the list converted to an array" } }
-{ $description "Convert a list to an array. If the list is a lazy infinite list then this will enter an infinite loop." } 
-{ $see-also list>vector } ;
-
-HELP: lappend
-{ $values { "list1" "a cons object" } { "list2" "a cons object" } { "result" "a lazy list of list2 appended to list1" } }
-{ $description "Perform a similar functionality to that of the " { $link append } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-append> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required. Successive calls to " { $link cdr } " will iterate through list1, followed by list2." } ;
-
-HELP: lfrom-by
-{ $values { "n" "an integer" } { "quot" { $quotation "( -- int )" } } { "list" "a lazy list of integers" } }
-{ $description "Return an infinite lazy list of values starting from n, with each successive value being the result of applying quot to n." } ;
-
-HELP: lfrom
-{ $values { "n" "an integer" } { "list" "a lazy list of integers" } }
-{ $description "Return an infinite lazy list of incrementing integers starting from n." } ;
-
-HELP: seq>list
-{ $values { "index" "an integer 0 or greater" } { "seq" "a sequence" } { "list" "a list" } }
-{ $description "Convert the sequence into a list, starting from the 'index' offset into the sequence." } 
-{ $see-also >list } ;
-
-HELP: >list
-{ $values { "object" "an object" } { "list" "a list" } }
-{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } 
-{ $see-also seq>list } ;
-    
-{ leach foldl lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
-
-HELP: lconcat
-{ $values { "list" "a list of lists" } { "result" "a list" } }
-{ $description "Concatenates a list of lists together into one list." } ;
-
-HELP: lcartesian-product
-{ $values { "list1" "a list" } { "list2" "a list" } { "result" "list of cartesian products" } }
-{ $description "Given two lists, return a list containing the cartesian product of those lists." } ;
-
-HELP: lcartesian-product*
-{ $values { "lists" "a list of lists" } { "result" "list of cartesian products" } }
-{ $description "Given a list of lists, return a list containing the cartesian product of those lists." } ;
-
-HELP: lcomp
-{ $values { "list" "a list of lists" } { "quot" { $quotation "( seq -- X )" } } { "result" "the resulting list" } }
-{ $description "Get the cartesian product of the lists in " { $snippet "list" } " and call " { $snippet "quot" } " call with each element from the cartesian product on the stack, the result of which is returned in the final " { $snippet "list" } "." } ;
-
-HELP: lcomp*
-{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" { $quotation "( seq -- X )" } } { "list" "the resulting list" } { "result" "a list" } }
-{ $description "Get the cartesian product of the lists in " { $snippet "list" } ", filter it by applying each guard quotation to it and call " { $snippet "quot" } " call with each element from the remaining cartesian product items on the stack, the result of which is returned in the final " { $snippet "list" } "." }
-{ $examples
-  { $code "{ 1 2 3 } >list { 4 5 6 } >list 2list { [ first odd? ] } [ first2 + ] lcomp*" }
-} ;
-
-HELP: lmerge
-{ $values { "list1" "a list" } { "list2" "a list" } { "result" "lazy list merging list1 and list2" } }
-{ $description "Return the result of merging the two lists in a lazy manner." } 
-{ $examples
-  { $example "USING: lists.lazy prettyprint ;" "{ 1 2 3 } >list { 4 5 6 } >list lmerge list>array ." "{ 1 4 2 5 3 6 }" }
-} ;
-
-HELP: lcontents
-{ $values { "stream" "a stream" } { "result" string } }
-{ $description "Returns a lazy list of all characters in the file. " { $link car } " returns the next character in the file, " { $link cdr } " returns the remaining characters as a lazy list. " { $link nil? } " indicates end of file." } 
-{ $see-also llines } ;
-
-HELP: llines
-{ $values { "stream" "a stream" } { "result" "a list" } }
-{ $description "Returns a lazy list of all lines in the file. " { $link car } " returns the next lines in the file, " { $link cdr } " returns the remaining lines as a lazy list. " { $link nil? } " indicates end of file." } 
-{ $see-also lcontents } ;
diff --git a/extra/lists/lazy/lazy-tests.factor b/extra/lists/lazy/lazy-tests.factor
deleted file mode 100644 (file)
index 5749f94..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-! Copyright (C) 2006 Matthew Willis and Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-!
-USING: lists lists.lazy tools.test kernel math io sequences ;
-IN: lists.lazy.tests
-
-[ { 1 2 3 4 } ] [
-  { 1 2 3 4 } >list list>array
-] unit-test
-
-[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
-  { 1 2 3 } >list { 4 5 } >list 2list lcartesian-product* list>array
-] unit-test
-
-[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
-  { 1 2 3 } >list { 4 5 } >list lcartesian-product list>array
-] unit-test
-
-[ { 5 6 6 7 7 8 } ] [ 
-  { 1 2 3 } >list { 4 5 } >list 2list [ first2 + ] lcomp list>array
-] unit-test
-
-[ { 5 6 7 8 } ] [ 
-  { 1 2 3 } >list { 4 5 } >list 2list { [ first odd? ] } [ first2 + ] lcomp* list>array
-] unit-test
-
-[ { 4 5 6 } ] [ 
-    3 { 1 2 3 } >list [ + ] lazy-map-with list>array
-] unit-test
diff --git a/extra/lists/lazy/lazy.factor b/extra/lists/lazy/lazy.factor
deleted file mode 100644 (file)
index e60fcba..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-! Copyright (C) 2004 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-!
-! Updated by Matthew Willis, July 2006
-! Updated by Chris Double, September 2006
-! Updated by James Cash, June 2008
-!
-USING: kernel sequences math vectors arrays namespaces make
-quotations promises combinators io lists accessors ;
-IN: lists.lazy
-
-M: promise car ( promise -- car )
-    force car ;
-
-M: promise cdr ( promise -- cdr )
-    force cdr ;
-
-M: promise nil? ( cons -- bool )
-    force nil? ;
-    
-! Both 'car' and 'cdr' are promises
-TUPLE: lazy-cons car cdr ;
-
-: lazy-cons ( car cdr -- promise )
-    [ promise ] bi@ \ lazy-cons boa
-    T{ promise f f t f } clone
-        swap >>value ;
-
-M: lazy-cons car ( lazy-cons -- car )
-    car>> force ;
-
-M: lazy-cons cdr ( lazy-cons -- cdr )
-    cdr>> force ;
-
-M: lazy-cons nil? ( lazy-cons -- bool )
-    nil eq? ;
-
-: 1lazy-list ( a -- lazy-cons )
-    [ nil ] lazy-cons ;
-
-: 2lazy-list ( a b -- lazy-cons )
-    1lazy-list 1quotation lazy-cons ;
-
-: 3lazy-list ( a b c -- lazy-cons )
-    2lazy-list 1quotation lazy-cons ;
-
-TUPLE: memoized-cons original car cdr nil? ;
-
-: not-memoized ( -- obj )
-    { } ;
-
-: not-memoized? ( obj -- bool )
-    not-memoized eq? ;
-
-: <memoized-cons> ( cons -- memoized-cons )
-    not-memoized not-memoized not-memoized
-    memoized-cons boa ;
-
-M: memoized-cons car ( memoized-cons -- car )
-    dup car>> not-memoized? [
-        dup original>> car [ >>car drop ] keep
-    ] [
-        car>>
-    ] if ;
-
-M: memoized-cons cdr ( memoized-cons -- cdr )
-    dup cdr>> not-memoized? [
-        dup original>> cdr [ >>cdr drop ] keep
-    ] [
-        cdr>>
-    ] if ;
-
-M: memoized-cons nil? ( memoized-cons -- bool )
-    dup nil?>> not-memoized? [
-        dup original>> nil?  [ >>nil? drop ] keep
-    ] [
-        nil?>>
-    ] if ;
-
-TUPLE: lazy-map cons quot ;
-
-C: <lazy-map> lazy-map
-
-: lazy-map ( list quot -- result )
-    over nil? [ 2drop nil ] [ <lazy-map> <memoized-cons> ] if ;
-
-M: lazy-map car ( lazy-map -- car )
-    [ cons>> car ] keep
-    quot>> call ;
-
-M: lazy-map cdr ( lazy-map -- cdr )
-    [ cons>> cdr ] keep
-    quot>> lazy-map ;
-
-M: lazy-map nil? ( lazy-map -- bool )
-    cons>> nil? ;
-
-: lazy-map-with ( value list quot -- result )
-    with lazy-map ;
-
-TUPLE: lazy-take n cons ;
-
-C: <lazy-take> lazy-take
-
-: ltake ( n list -- result )
-        over zero? [ 2drop nil ] [ <lazy-take> ] if ;
-
-M: lazy-take car ( lazy-take -- car )
-    cons>> car ;
-
-M: lazy-take cdr ( lazy-take -- cdr )
-    [ n>> 1- ] keep
-    cons>> cdr ltake ;
-
-M: lazy-take nil? ( lazy-take -- bool )
-    dup n>> zero? [
-        drop t
-    ] [
-        cons>> nil?
-    ] if ;
-
-TUPLE: lazy-until cons quot ;
-
-C: <lazy-until> lazy-until
-
-: luntil ( list quot -- result )
-    over nil? [ drop ] [ <lazy-until> ] if ;
-
-M: lazy-until car ( lazy-until -- car )
-     cons>> car ;
-
-M: lazy-until cdr ( lazy-until -- cdr )
-     [ cons>> uncons ] keep quot>> tuck call
-     [ 2drop nil ] [ luntil ] if ;
-
-M: lazy-until nil? ( lazy-until -- bool )
-     drop f ;
-
-TUPLE: lazy-while cons quot ;
-
-C: <lazy-while> lazy-while
-
-: lwhile ( list quot -- result )
-    over nil? [ drop ] [ <lazy-while> ] if ;
-
-M: lazy-while car ( lazy-while -- car )
-     cons>> car ;
-
-M: lazy-while cdr ( lazy-while -- cdr )
-     [ cons>> cdr ] keep quot>> lwhile ;
-
-M: lazy-while nil? ( lazy-while -- bool )
-     [ car ] keep quot>> call not ;
-
-TUPLE: lazy-filter cons quot ;
-
-C: <lazy-filter> lazy-filter
-
-: lfilter ( list quot -- result )
-    over nil? [ 2drop nil ] [ <lazy-filter> <memoized-cons> ] if ;
-
-: car-filter? ( lazy-filter -- ? )
-    [ cons>> car ] [ quot>> ] bi call ;
-
-: skip ( lazy-filter -- )
-    dup cons>> cdr >>cons drop ;
-
-M: lazy-filter car ( lazy-filter -- car )
-    dup car-filter? [ cons>> ] [ dup skip ] if car ;
-
-M: lazy-filter cdr ( lazy-filter -- cdr )
-    dup car-filter? [
-        [ cons>> cdr ] [ quot>> ] bi lfilter
-    ] [
-        dup skip cdr
-    ] if ;
-
-M: lazy-filter nil? ( lazy-filter -- bool )
-    dup cons>> nil? [
-        drop t
-    ] [
-        dup car-filter? [
-            drop f
-        ] [
-            dup skip nil?
-        ] if
-    ] if ;
-
-: list>vector ( list -- vector )
-    [ [ , ] leach ] V{ } make ;
-
-: list>array ( list -- array )
-    [ [ , ] leach ] { } make ;
-
-TUPLE: lazy-append list1 list2 ;
-
-C: <lazy-append> lazy-append
-
-: lappend ( list1 list2 -- result )
-    over nil? [ nip ] [ <lazy-append> ] if ;
-
-M: lazy-append car ( lazy-append -- car )
-    list1>> car ;
-
-M: lazy-append cdr ( lazy-append -- cdr )
-    [ list1>> cdr    ] keep
-    list2>> lappend ;
-
-M: lazy-append nil? ( lazy-append -- bool )
-     drop f ;
-
-TUPLE: lazy-from-by n quot ;
-
-C: lfrom-by lazy-from-by ( n quot -- list )
-
-: lfrom ( n -- list )
-    [ 1+ ] lfrom-by ;
-
-M: lazy-from-by car ( lazy-from-by -- car )
-    n>> ;
-
-M: lazy-from-by cdr ( lazy-from-by -- cdr )
-    [ n>> ] keep
-    quot>> dup slip lfrom-by ;
-
-M: lazy-from-by nil? ( lazy-from-by -- bool )
-    drop f ;
-
-TUPLE: lazy-zip list1 list2 ;
-
-C: <lazy-zip> lazy-zip
-
-: lzip ( list1 list2 -- lazy-zip )
-        over nil? over nil? or
-        [ 2drop nil ] [ <lazy-zip> ] if ;
-
-M: lazy-zip car ( lazy-zip -- car )
-        [ list1>> car ] keep list2>> car 2array ;
-
-M: lazy-zip cdr ( lazy-zip -- cdr )
-        [ list1>> cdr ] keep list2>> cdr lzip ;
-
-M: lazy-zip nil? ( lazy-zip -- bool )
-        drop f ;
-
-TUPLE: sequence-cons index seq ;
-
-C: <sequence-cons> sequence-cons
-
-: seq>list ( index seq -- list )
-    2dup length >= [
-        2drop nil
-    ] [
-        <sequence-cons>
-    ] if ;
-
-M: sequence-cons car ( sequence-cons -- car )
-    [ index>> ] keep
-    seq>> nth ;
-
-M: sequence-cons cdr ( sequence-cons -- cdr )
-    [ index>> 1+ ] keep
-    seq>> seq>list ;
-
-M: sequence-cons nil? ( sequence-cons -- bool )
-    drop f ;
-
-: >list ( object -- list )
-    {
-        { [ dup sequence? ] [ 0 swap seq>list ] }
-        { [ dup list?         ] [ ] }
-        [ "Could not convert object to a list" throw ]
-    } cond ;
-
-TUPLE: lazy-concat car cdr ;
-
-C: <lazy-concat> lazy-concat
-
-DEFER: lconcat
-
-: (lconcat) ( car cdr -- list )
-    over nil? [
-        nip lconcat
-    ] [
-        <lazy-concat>
-    ] if ;
-
-: lconcat ( list -- result )
-    dup nil? [
-        drop nil
-    ] [
-        uncons swap (lconcat)
-    ] if ;
-
-M: lazy-concat car ( lazy-concat -- car )
-    car>> car ;
-
-M: lazy-concat cdr ( lazy-concat -- cdr )
-    [ car>> cdr ] keep cdr>> (lconcat) ;
-
-M: lazy-concat nil? ( lazy-concat -- bool )
-    dup car>> nil? [
-        cdr>> nil?
-    ] [
-        drop f
-    ] if ;
-
-: lcartesian-product ( list1 list2 -- result )
-    swap [ swap [ 2array ] lazy-map-with  ] lazy-map-with  lconcat ;
-
-: lcartesian-product* ( lists -- result )
-    dup nil? [
-        drop nil
-    ] [
-        [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [
-            swap [ swap [ suffix ] lazy-map-with  ] lazy-map-with  lconcat
-        ] reduce
-    ] if ;
-
-: lcomp ( list quot -- result )
-    [ lcartesian-product* ] dip lazy-map ;
-
-: lcomp* ( list guards quot -- result )
-    [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lazy-map ;
-
-DEFER: lmerge
-
-: (lmerge) ( list1 list2 -- result )
-    over [ car ] curry -rot
-    [
-        dup [ car ] curry -rot
-        [
-            [ cdr ] bi@ lmerge
-        ] 2curry lazy-cons
-    ] 2curry lazy-cons ;
-
-: lmerge ( list1 list2 -- result )
-    {
-        { [ over nil? ] [ nip     ] }
-        { [ dup nil?    ]    [ drop ] }
-        { [ t                 ]    [ (lmerge) ] }
-    } cond ;
-
-TUPLE: lazy-io stream car cdr quot ;
-
-C: <lazy-io> lazy-io
-
-: lcontents ( stream -- result )
-    f f [ stream-read1 ] <lazy-io> ;
-
-: llines ( stream -- result )
-    f f [ stream-readln ] <lazy-io> ;
-
-M: lazy-io car ( lazy-io -- car )
-    dup car>> dup [
-        nip
-    ] [
-        drop dup stream>> over quot>> call
-        >>car
-    ] if ;
-
-M: lazy-io cdr ( lazy-io -- cdr )
-    dup cdr>> dup [
-        nip
-    ] [
-        drop dup
-        [ stream>> ] keep
-        [ quot>> ] keep
-        car [
-            [ f f ] dip <lazy-io> [ >>cdr drop ] keep
-        ] [
-            3drop nil
-        ] if
-    ] if ;
-
-M: lazy-io nil? ( lazy-io -- bool )
-    car not ;
-
-INSTANCE: sequence-cons list
-INSTANCE: memoized-cons list
-INSTANCE: promise list
-INSTANCE: lazy-io list
-INSTANCE: lazy-concat list
-INSTANCE: lazy-cons list
-INSTANCE: lazy-map list
-INSTANCE: lazy-take list
-INSTANCE: lazy-append list
-INSTANCE: lazy-from-by list
-INSTANCE: lazy-zip list
-INSTANCE: lazy-while list
-INSTANCE: lazy-until list
-INSTANCE: lazy-filter list
diff --git a/extra/lists/lazy/old-doc.html b/extra/lists/lazy/old-doc.html
deleted file mode 100644 (file)
index 4c04301..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-<html>
-  <head>
-    <title>Lazy Evaluation</title>
-    <link rel="stylesheet" type="text/css" href="style.css">
-      </head>
-  <body>
-    <h1>Lazy Evaluation</h1>
-<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
-    ability to describe infinite structures, and to delay execution of
-    expressions until they are actually used.</p>
-<p>Lazy lists, like normal lists, are composed of a head and tail. In
-    a lazy list the head and tail are something called a 'promise'. 
-    To convert a
-    'promise' into its actual value a word called 'force' is used. To
-    convert a value into a 'promise' the word to use is 'delay'.</p>
-<table border="1">
-<tr><td><a href="#delay">delay</a></td></tr>
-<tr><td><a href="#force">force</a></td></tr>
-</table>
-
-<p>Many of the lazy list words are named similar to the standard list
-    words but with an 'l' suffixed to it. Here are the commonly used
-    words and their equivalent list operation:</p>
-<table border="1">
-<tr><th>Lazy List</th><th>Normal List</th></tr>
-<tr><td><a href="#lnil">lnil</a></td><td>[ ]</td></tr>
-<tr><td><a href="#lnilp">lnil?</a></td><td>Test for nil value</td></tr>
-<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
-<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
-<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
-<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
-<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
-<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
-<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
-<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
-<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
-<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
-</table>
-<p>A few additional words specific to lazy lists are:</p>
-<table border="1">
-<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
-number of items from the lazy list.</td></tr>
-<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
-concatenate them together in a lazy manner, returning a single lazy
-list.</td></tr>
-<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
-that contains the same elements as the normal list.</td></tr>
-</table>
-<h2>Reference</h2>
-<!-- delay description -->
-<a name="delay">
-<h3>delay ( quot -- &lt;promise&gt; )</h3>
-<p>'delay' is used to convert a value or expression into a promise.
-   The word 'force' is used to convert that promise back to its
-   value, or to force evaluation of the expression to return a value.
-</p>
-<p>The value on the stack that 'delay' expects must be quoted. This is
-   a requirement to prevent it from being evaluated.
-</p>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
-       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
-  ( 2 ) <a href="#force">force</a> .
-       => 42
-</pre>
-
-<!-- force description -->
-<a name="force">
-<h3>force ( &lt;promise&gt; -- value )</h3>
-<p>'force' will evaluate a promises original expression
-   and leave the value of that expression on the stack.
-</p>
-<p>A promise can be forced multiple times but the expression
-   is only evaluated once. Future calls of 'force' on the promise
-   will returned the cached value of the original force. If the
-   expression contains side effects, such as i/o, then that i/o
-   will only occur on the first 'force'. See below for an example
-   (steps 3-5).
-</p>
-<p>If a promise is itself delayed, a force will evaluate all promises
-   until a value is returned. Due to this behaviour it is generally not
-   possible to delay a promise. The example below shows what happens
-   in this case.
-</p>
-<pre class="code">       
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
-       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
-  ( 2 ) <a href="#force">force</a> .
-       => 42
-       
-        #! Multiple forces on a promise returns cached value
-  ( 3 ) [ "hello" print 42 ] <a href="#delay">delay</a> dup .
-       => << promise [ ] [ "hello" print 42 ] [ ] [ ] >>
-  ( 4 ) dup <a href="#force">force</a> .
-       => hello
-          42
-  ( 5 ) <a href="#force">force</a> .
-       => 42
-
-        #! Forcing a delayed promise cascades up to return
-        #! original value, rather than the promise.
-  ( 6 ) [ [ 42 ] <a href="#delay">delay</a> ] <a href="#delay">delay</a> dup .
-       => << promise [ ] [ [ 42 ] delay ] [ ] [ ] >>
-  ( 7 ) <a href="#force">force</a> .
-       => 42
-</pre>
-
-<!-- lnil description -->
-<a name="lnil">
-<h3>lnil ( -- lcons )</h3>
-<p>Returns a value representing the empty lazy list.</p>
-<pre class="code">
-  ( 1 ) <a href="#lnil">lnil</a> .
-       => << promise [ ] [ [ ] ] t [ ] >>
-</pre>
-
-<!-- lnil description -->
-<a name="lnilp">
-<h3>lnil? ( lcons -- bool )</h3>
-<p>Returns true if the given lazy cons is the value representing 
-   the empty lazy list.</p>
-<pre class="code">
-  ( 1 ) <a href="#lnil">lnil</a> <a href="#lnilp">lnil?</a> .
-       => t
-  ( 2 ) [ 1 ] <a href="#list2llist">list&gt;llist</a> dup <a href="#lnilp">lnil?</a> .
-       => [ ]
-  ( 3 ) <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
-       => t
-</pre>
-
-<!-- lcons description -->
-<a name="lcons">
-<h3>lcons ( car-promise cdr-promise -- lcons )</h3>
-<p>Provides the same effect as 'cons' does for normal lists. 
-   Both values provided must be promises (ie. expressions that have
-   had <a href="#delay">delay</a> called on them).
-</p>
-<p>As the car and cdr passed on the stack are promises, they are not
-   evaluated until <a href="#lcar">lcar</a> or <a href="#lcdr">lcdr</a>
-   are called on the lazy cons.</p>
-<pre class="code">
-  ( 1 ) [ "car" ] <a href="#delay">delay</a> [ "cdr" ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) dup <a href="#lcar">lcar</a> .
-       => "car"
-  ( 3 ) dup <a href="#lcdr">lcdr</a> .
-       => "cdr"
-</pre>
-  
-<!-- lunit description -->
-<a name="lunit">
-<h3>lunit ( value-promise -- llist )</h3>
-<p>Provides the same effect as 'unit' does for normal lists. It
-creates a lazy list where the first element is the value given.</p>
-<p>Like <a href="#lcons">lcons</a>, the value on the stack must be
-   a promise and is not evaluated until the <a href="#lcar">lcar</a>
-   of the list is requested.</a>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) dup <a href="#lcar">lcar</a> .
-       => 42
-  ( 3 ) dup <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
-       => t
-  ( 4 ) [ . ] <a href="#leach">leach</a>
-       => 42
-</pre>
-
-<!-- lcar description -->
-<a name="lcar">
-<h3>lcar ( lcons -- value )</h3>
-<p>Provides the same effect as 'car' does for normal lists. It
-returns the first element in a lazy cons cell. This will force
-the evaluation of that element.</p>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcar">lcar</a> .
-       => 42
-</pre>
-
-<!-- lcdr description -->
-<a name="lcdr">
-<h3>lcdr ( lcons -- value )</h3>
-<p>Provides the same effect as 'cdr' does for normal lists. It
-returns the second element in a lazy cons cell and forces it. This
-causes that element to be evaluated immediately.</p>
-<pre class="code">
-  ( 1 ) [ 1 ] <a href="#delay">delay</a> [ 5 6 + ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcdr">lcdr</a> .
-       => 11
-</pre>
-
-<pre class="code">
-  ( 1 ) 5 <a href="#lfrom">lfrom</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 6
-  ( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 7
-  ( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 8
-</pre>
-
-<!-- lnth description -->
-<a name="lnth">
-<h3>lnth ( n llist -- value )</h3>
-<p>Provides the same effect as 'nth' does for normal lists. It
-returns the nth value in the lazy list. It causes all the values up to
-'n' to be evaluated.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) 5 swap <a href="#lnth">lnth</a> .
-       => 6
-</pre>
-
-<!-- luncons description -->
-<a name="luncons">
-<h3>luncons ( lcons -- car cdr )</h3>
-<p>Provides the same effect as 'uncons' does for normal lists. It
-returns the car and cdr of the lazy list.</p>
-<pre class="code">
-  ( 1 ) [ 5 ] <a href="#delay">delay</a> [ 6 ] <a  href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#luncons">luncons</a> . .
-       => 6
-          5
-</pre>
-
-<!-- lmap description -->
-<a name="lmap">
-<h3>lmap ( llist quot -- llist )</h3>
-<p>Lazily maps over a lazy list applying the quotation to each element.
-A new lazy list is returned which contains the results of the
-quotation.</p>
-<p>When intially called nothing in the original lazy list is
-evaluated. Only when <a href="#lcar">lcar</a> is called will the item
-in the list be evaluated and applied to the quotation. Ditto with <a
-href="#lcdr">lcdr</a>, thus allowing infinite lists to be mapped over.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
-       => < infinite list of numbers incrementing by 2 >
-  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 2 4 6 8 10 ]
-</pre>
-
-<!-- lsubset description -->
-<a name="lsubset">
-<h3>lsubset ( llist pred -- llist )</h3>
-<p>Provides the same effect as 'subset' does for normal lists. It
-lazily iterates over a lazy list applying the predicate quotation to each
-element. If that quotation returns true, the element will be included
-in the resulting lazy list. If it is false, the element will be skipped.
-A new lazy list is returned which contains  all elements where the
-predicate returned true.</p>
-<p>Like <a href="#lmap">lmap</a>, when initially called no evaluation
-will occur. A lazy list is returned that when values are retrieved
-from in then items are evaluated and checked against the predicate.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ <a href="#primep">prime?</a> ] <a href="#lsubset">lsubset</a>
-       => < infinite list of prime numbers >
-  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 2 3 5 7 11 ]
-</pre>
-
-<!-- leach description -->
-<a name="leach">
-<h3>leach ( llist quot --  )</h3>
-<p>Provides the same effect as 'each' does for normal lists. It
-lazily iterates over a lazy list applying the quotation to each
-element. If this operation is applied to an infinite list it will
-never return unless the quotation escapes out by calling a continuation.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
-       => < infinite list of odd numbers >
-  ( 3 ) [ . ] <a href="#leach">leach</a> 
-       => 1
-          3
-          5
-          7
-          ... for ever ...
-</pre>
-
-<!-- ltake description -->
-<a name="ltake">
-<h3>ltake ( n llist -- llist )</h3>
-<p>Iterates over the lazy list 'n' times, appending each element to a
-lazy list. This provides a convenient way of getting elements out of
-an infinite lazy list.</p>
-<pre class="code">
-  ( 1 ) : ones [ 1 ] delay [ ones ] delay <a href="#lcons">lcons</a> ;
-  ( 2 ) 5 ones <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 1 1 1 1 1  ]
-</pre>
-
-<!-- lappend description -->
-<a name="lappend">
-<h3>lappend ( llist1 llist2 -- llist )</h3>
-<p>Lazily appends two lists together. The actual appending is done
-lazily on iteration rather than immediately so it works very fast no
-matter how large the list.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> <a href="#lappend">lappend</a>
-  ( 2 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-          4
-          5
-          6
-</pre>
-
-<!-- lappend* description -->
-<a name="lappendstar">
-<h3>lappend* ( llists -- llist )</h3>
-<p>Given a lazy list of lazy lists, concatenate them together in a
-lazy fashion. The actual appending is done lazily on iteration rather
-than immediately so it works very fast no matter how large the lists.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2>llist">list&gt;llist</a> 
-  ( 2 ) [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> 
-  ( 3 ) [ 7 8 9 ] <a href="#list2llist">list&gt;llist</a>
-  ( 4 ) 3list <a href="#list2llist">list&gt;llist</a> <a href="#lappendstar">lappend*</a>
-  ( 5 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-          4
-          5
-          6
-          7
-          8
-          9
-</pre>
-
-<!-- list>llist description -->
-<a name="list2llist">
-<h3>list&gt;llist ( list  -- llist )</h3>
-<p>Converts a normal list into a lazy list. This is done lazily so the
-initial list is not iterated through immediately.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> 
-  ( 2 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-</pre>
-
-<p class="footer">
-News and updates to this software can be obtained from the authors
-weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
-<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
-</body> </html>
diff --git a/extra/lists/lazy/summary.txt b/extra/lists/lazy/summary.txt
deleted file mode 100644 (file)
index 5d2f302..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Lazy lists
diff --git a/extra/lists/lazy/tags.txt b/extra/lists/lazy/tags.txt
deleted file mode 100644 (file)
index dd23829..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-extensions
-collections
diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor
deleted file mode 100644 (file)
index 8807c8c..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-! Copyright (C) 2006 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel help.markup help.syntax ;
-
-IN: lists
-
-{ car cons cdr nil nil? list? uncons } related-words
-
-HELP: cons 
-{ $values { "car" "the head of the lazy list" } { "cdr" "the tail of the lazy list" } { "cons" "a cons object" } }
-{ $description "Constructs a cons cell." } ;
-
-HELP: car
-{ $values { "cons" "a cons object" } { "car" "the first item in the list" } }
-{ $description "Returns the first item in the list." } ;
-
-HELP: cdr
-{ $values { "cons" "a cons object" } { "cdr" "a cons object" } }
-{ $description "Returns the tail of the list." } ;
-    
-HELP: nil 
-{ $values { "symbol" "The empty cons (+nil+)" } }
-{ $description "Returns a symbol representing the empty list" } ;
-
-HELP: nil? 
-{ $values { "object" object } { "?" "a boolean" } }
-{ $description "Return true if the cons object is the nil cons." } ;
-
-HELP: list? ( object -- ? )
-{ $values { "object" "an object" } { "?" "a boolean" } }
-{ $description "Returns true if the object conforms to the list protocol." } ;
-
-{ 1list 2list 3list } related-words
-
-HELP: 1list
-{ $values { "obj" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 1 element." } ;
-
-HELP: 2list
-{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 2 elements." } ;
-
-HELP: 3list
-{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 3 elements." } ;
-    
-HELP: lnth
-{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } }
-{ $description "Outputs the nth element of the list." } 
-{ $see-also llength cons car cdr } ;
-
-HELP: llength
-{ $values { "list" "a cons object" } { "n" "a non-negative integer" } }
-{ $description "Outputs the length of the list. This should not be called on an infinite list." } 
-{ $see-also lnth cons car cdr } ;
-
-HELP: uncons
-{ $values { "cons" "a cons object" }  { "cdr" "the tail of the list" } { "car" "the head of the list" } }
-{ $description "Put the head and tail of the list on the stack." } ;
-
-{ leach foldl lmap>array } related-words
-
-HELP: leach
-{ $values { "list" "a cons object" } { "quot" { $quotation "( obj -- )" } } }
-{ $description "Call the quotation for each item in the list." } ;
-
-HELP: foldl
-{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" { $quotation "( prev elt -- next )" } } { "result" "the final result" } }
-{ $description "Combines successive elements of the list (in a left-assocative order) using a binary operation and outputs the final result." } ;
-
-HELP: foldr
-{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" { $quotation "( prev elt -- next )" } } { "result" "the final result" } }
-{ $description "Combines successive elements of the list (in a right-assocative order) using a binary operation, and outputs the final result." } ;
-
-HELP: lmap
-{ $values { "list" "a cons object" } { "quot" { $quotation "( old -- new )" } } { "result" "the final result" } }
-{ $description "Applies the quotation to each element of the list in order, collecting the new elements into a new list." } ;
-    
-HELP: lreverse
-{ $values { "list" "a cons object" } { "newlist" "a new cons object" } }
-{ $description "Reverses the input list, outputing a new, reversed list" } ;
-    
-HELP: list>seq    
-{ $values { "list" "a cons object" } { "array" "an array object" } }
-{ $description "Turns the given cons object into an array, maintaing order." } ;
-    
-HELP: seq>list
-{ $values { "seq" "a sequence" } { "list" "a cons object" } }
-{ $description "Turns the given array into a cons object, maintaing order." } ;
-    
-HELP: cons>seq
-{ $values { "cons" "a cons object" } { "array" "an array object" } }
-{ $description "Recursively turns the given cons object into an array, maintaing order and also converting nested lists." } ;
-    
-HELP: seq>cons
-{ $values { "seq" "a sequence object" } { "cons" "a cons object" } }
-{ $description "Recursively turns the given sequence into a cons object, maintaing order and also converting nested lists." } ;
-    
-HELP: traverse    
-{ $values { "list"  "a cons object" } { "pred" { $quotation "( list/elt -- ? )" } }
-          { "quot" { $quotation "( list/elt -- result)" } }  { "result" "a new cons object" } }
-{ $description "Recursively traverses the list object, replacing any elements (which can themselves be sublists) that pred" 
-    " returns true for with the result of applying quot to." } ;
-    
diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor
deleted file mode 100644 (file)
index 4a08a4d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test lists math ;
-
-IN: lists.tests
-
-{ { 3 4 5 6 7 } } [
-    { 1 2 3 4 5 } seq>list [ 2 + ] lmap list>seq 
-] unit-test
-
-{ { 3 4 5 6 } } [
-    T{ cons f 1       
-        T{ cons f 2 
-            T{ cons f 3
-                T{ cons f 4
-                +nil+ } } } } [ 2 + ] lmap>array
-] unit-test
-
-{ 10 } [
-    T{ cons f 1       
-        T{ cons f 2 
-            T{ cons f 3
-                T{ cons f 4
-                +nil+ } } } } 0 [ + ] foldl
-] unit-test
-    
-{ T{ cons f
-      1
-      T{ cons f
-          2
-          T{ cons f
-              T{ cons f
-                  3
-                  T{ cons f
-                      4
-                      T{ cons f
-                          T{ cons f 5 +nil+ }
-                          +nil+ } } }
-          +nil+ } } }
-} [
-    { 1 2 { 3 4 { 5 } } } seq>cons
-] unit-test
-    
-{ { 1 2 { 3 4 { 5 } } } } [
-  { 1 2 { 3 4 { 5 } } } seq>cons cons>seq
-] unit-test
-    
-{ T{ cons f 2 T{ cons f 3 T{ cons f 4 T{ cons f 5 +nil+ } } } } } [
-    { 1 2 3 4 } seq>cons [ 1+ ] lmap
-] unit-test
-    
-{ 15 } [
- { 1 2 3 4 5 } seq>list 0 [ + ] foldr
-] unit-test
-    
-{ { 5 4 3 2 1 } } [
-    { 1 2 3 4 5 } seq>list lreverse list>seq
-] unit-test
-    
-{ 5 } [
-    { 1 2 3 4 5 } seq>list llength
-] unit-test
-    
-{ { 3 4 { 5 6 { 7 } } } } [
-  { 1 2 { 3 4 { 5 } } } seq>cons [ atom? ] [ 2 + ] traverse cons>seq
-] unit-test
-    
-{ { 1 2 3 4 5 6 } } [
-    { 1 2 3 } seq>list { 4 5 6 } seq>list lappend list>seq
-] unit-test
\ No newline at end of file
diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor
deleted file mode 100644 (file)
index bf82288..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences accessors math arrays vectors classes words locals ;
-
-IN: lists
-
-! List Protocol
-MIXIN: list
-GENERIC: car   ( cons -- car )
-GENERIC: cdr   ( cons -- cdr )
-GENERIC: nil?  ( object -- ?   )
-    
-TUPLE: cons car cdr ;
-
-C: cons cons
-
-M: cons car ( cons -- car )
-    car>> ;
-
-M: cons cdr ( cons -- cdr )
-    cdr>> ;
-    
-SYMBOL: +nil+
-M: word nil? +nil+ eq? ;
-M: object nil? drop f ;
-    
-: atom? ( obj -- ? ) [ list? ] [ nil? ] bi or not ;
-
-: nil ( -- symbol ) +nil+ ; 
-    
-: uncons ( cons -- cdr car )
-    [ cdr ] [ car ] bi ;
-    
-: 1list ( obj -- cons )
-    nil cons ;
-    
-: 2list ( a b -- cons )
-    nil cons cons ;
-
-: 3list ( a b c -- cons )
-    nil cons cons cons ;
-    
-: cadr ( cons -- elt )    
-    cdr car ;
-    
-: 2car ( cons -- car caar )    
-    [ car ] [ cdr car ] bi ;
-    
-: 3car ( cons -- car caar caaar )    
-    [ car ] [ cdr car ] [ cdr cdr car ] tri ;
-
-: lnth ( n list -- elt )
-    swap [ cdr ] times car ;
-    
-: (leach) ( list quot -- cdr quot )
-    [ [ car ] dip call ] [ [ cdr ] dip ] 2bi ; inline
-
-: leach ( list quot: ( elt -- ) -- )
-    over nil? [ 2drop ] [ (leach) leach ] if ; inline recursive
-
-: lmap ( list quot: ( elt -- ) -- result )
-    over nil? [ drop ] [ (leach) lmap cons ] if ; inline recursive
-
-: foldl ( list identity quot: ( obj1 obj2 -- obj ) -- result )
-    swapd leach ; inline
-
-: foldr ( list identity quot: ( obj1 obj2 -- obj ) -- result )
-    pick nil? [ [ drop ] [ ] [ drop ] tri* ] [
-        [ [ cdr ] 2dip foldr ] [ nip [ car ] dip ] 3bi
-        call
-    ] if ; inline recursive
-
-: llength ( list -- n )
-    0 [ drop 1+ ] foldl ;
-    
-: lreverse ( list -- newlist )    
-    nil [ swap cons ] foldl ;
-    
-: lappend ( list1 list2 -- newlist )    
-    [ lreverse ] dip [ swap cons ] foldl ;
-    
-: seq>list ( seq -- list )    
-    <reversed> nil [ swap cons ] reduce ;
-    
-: same? ( obj1 obj2 -- ? ) 
-    [ class ] bi@ = ;
-    
-: seq>cons ( seq -- cons )
-    [ <reversed> ] keep nil [ tuck same? [ seq>cons ] when f cons swap >>cdr ] with reduce ;
-    
-: (lmap>array) ( acc cons quot: ( elt -- elt' ) -- newcons )
-    over nil? [ 2drop ]
-    [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap>array) ] if ;
-    inline recursive
-    
-: lmap>array ( cons quot -- newcons )
-    { } -rot (lmap>array) ; inline
-    
-: lmap-as ( cons quot exemplar -- seq )
-    [ lmap>array ] dip like ;
-    
-: cons>seq ( cons -- array )    
-    [ dup cons? [ cons>seq ] when dup nil? [ drop { } ] when ] lmap>array ;
-    
-: list>seq ( list -- array )    
-    [ ] lmap>array ;
-    
-: traverse ( list pred quot: ( list/elt -- result ) -- result )
-    [ 2over call [ tuck [ call ] 2dip ] when
-      pick list? [ traverse ] [ 2drop ] if ] 2curry lmap ; inline recursive
-    
-INSTANCE: cons list
\ No newline at end of file
diff --git a/extra/lists/summary.txt b/extra/lists/summary.txt
deleted file mode 100644 (file)
index 60a1886..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Implementation of lisp-style linked lists
diff --git a/extra/lists/tags.txt b/extra/lists/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
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
index 8afbb2d03b88fa0dba45aa5d72f49591e65adf88..99e8099f38e38bc92b47d2e9d4ec72e0f438fdb1 100755 (executable)
@@ -17,7 +17,7 @@ ERROR: cannot-parse input ;
 
 : parse-1 ( input parser -- result )
     dupd parse dup nil? [
-        rot cannot-parse
+        swap cannot-parse
     ] [
         nip car parsed>>
     ] if ;
@@ -149,8 +149,8 @@ TUPLE: and-parser parsers ;
             [ parsed>> ] dip
             [ parsed>> 2array ] keep
             unparsed>> <parse-result>
-        ] lazy-map-with
-    ] lazy-map-with lconcat ;
+        ] with lazy-map
+    ] with lazy-map lconcat ;
 
 M: and-parser parse ( input parser -- list )
     #! Parse 'input' by sequentially combining the
@@ -173,7 +173,7 @@ M: or-parser parse ( input parser1 -- list )
     #! of parser1 and parser2 being applied to the same
     #! input. This implements the choice parsing operator.
     parsers>> 0 swap seq>list
-    [ parse ] lazy-map-with lconcat ;
+    [ parse ] with lazy-map lconcat ;
 
 : trim-head-slice ( string -- string )
     #! Return a new string without any leading whitespace
@@ -218,7 +218,7 @@ M: apply-parser parse ( input parser -- result )
     -rot parse [
         [ parsed>> swap call ] keep
         unparsed>> <parse-result>
-    ] lazy-map-with ;
+    ] with lazy-map ;
 
 TUPLE: some-parser p1 ;
 
index da20c874b5c5bb150619ccc89d2c427383f0b82d..9c462b6b2e23b5da48f7cee43a96c923ae49cddb 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer, Alexander Solovyov, Vishal Talwar.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math sequences shuffle ;
+USING: kernel math sequences ;
 IN: project-euler.002
 
 ! http://projecteuler.net/index.php?section=problems&id=2
@@ -41,7 +41,7 @@ PRIVATE>
 ! -------------------
 
 : fib-upto* ( n -- seq )
-    0 1 [ pick over >= ] [ tuck + dup ] [ ] produce 3nip
+    0 1 [ pick over >= ] [ tuck + dup ] [ ] produce [ 3drop ] dip
     but-last-slice { 0 1 } prepend ;
 
 : euler002a ( -- answer )
index e00e86865d9a1a99d2b4a863a3615b7d9d6b57b3..0f009919d9ddde0c399627540d54839e4d3c2caf 100644 (file)
@@ -39,7 +39,7 @@ IN: project-euler.134
 PRIVATE>
 
 : euler134 ( -- answer )
-    0 5 lprimes-from uncons swap [ 1000000 > ] luntil
+    0 5 lprimes-from uncons [ 1000000 > ] luntil
     [ [ s + ] keep ] leach drop ;
 
 ! [ euler134 ] 10 ave-time
index 38366697eac977c1d71291968d5ab0d725164342..bec2761e5337327253fee9efc4c9af31fc1f1540 100755 (executable)
@@ -1,10 +1,6 @@
-! Copyright (C) 2004 Chris Double.
+! Copyright (C) 2004, 2006 Chris Double, Matthew Willis.
 ! See http://factorcode.org/license.txt for BSD license.
-!
-! Updated by Matthew Willis, July 2006
-! Updated by Chris Double, September 2006
-
-USING: arrays kernel sequences math vectors arrays namespaces
+USING: arrays kernel sequences math vectors arrays namespaces call
 make quotations parser effects stack-checker words accessors ;
 IN: promises
 
@@ -24,7 +20,7 @@ TUPLE: promise quot forced? value ;
     #! promises quotation on the stack. Re-forcing the promise
     #! will return the same value and not recall the quotation.
     dup forced?>> [
-        dup quot>> call >>value
+        dup quot>> call( -- value ) >>value
         t >>forced?
     ] unless
     value>> ;
index 3e47adac0b08909ad5ed53db9e654110a8e5d71f..89e00f88c56670bb4dc05eeaf5b0f279cb9b96e4 100755 (executable)
@@ -25,7 +25,6 @@ IN: reports.noise
         { 3drop 1 }\r
         { 3dup 2 }\r
         { 3keep 3 }\r
-        { 3nip 4 }\r
         { 3slip 3 }\r
         { 4drop 2 }\r
         { 4dup 3 }\r
@@ -50,7 +49,6 @@ IN: reports.noise
         { ndrop 2 }\r
         { ndup 3 }\r
         { nip 2 }\r
-        { nipd 3 }\r
         { nkeep 5 }\r
         { npick 6 }\r
         { nrot 5 }\r
@@ -66,7 +64,6 @@ IN: reports.noise
         { swap 1 }\r
         { swapd 3 }\r
         { tuck 2 }\r
-        { tuckd 4 }\r
         { with 1/2 }\r
 \r
         { bi 1/2 }\r
index 00a49fb2a27851c69701e0eca9838d50c1657b58..b77e1fe64925260f2f6a4c00fccbb07c0949801a 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: unix alien alien.c-types kernel math sequences strings
-io.backend.unix splitting ;
+io.backend.unix splitting io.encodings.utf8 io.encodings.string ;
 IN: system-info.linux
 
 : (uname) ( buf -- int )
@@ -9,7 +9,7 @@ IN: system-info.linux
 
 : uname ( -- seq )
     65536 "char" <c-array> [ (uname) io-error ] keep
-    "\0" split harvest [ >string ] map
+    "\0" split harvest [ utf8 decode ] map
     6 "" pad-tail ;
 
 : sysname ( -- string ) uname first ;
index a4413c07b39f074f6b1114a766116af3f6c634f1..37c022fe43382c9b26b3f89d2e4ab3294afe6cab 100755 (executable)
@@ -5,8 +5,8 @@ system tools.hexdump io.encodings.binary summary accessors
 io.backend byte-arrays ;
 IN: tar
 
-: zero-checksum 256 ; inline
-: block-size 512 ; inline
+CONSTANT: zero-checksum 256
+CONSTANT: block-size 512
 
 TUPLE: tar-header name mode uid gid size mtime checksum typeflag
 linkname magic version uname gname devmajor devminor prefix ;
@@ -89,8 +89,7 @@ M: unknown-typeflag summary ( obj -- str )
 
 ! Symlink
 : typeflag-2 ( header -- )
-    [ name>> ] [ linkname>> ] bi
-    [ make-link ] 2curry ignore-errors ;
+    [ name>> ] [ linkname>> ] bi make-link ;
 
 ! character special
 : typeflag-3 ( header -- ) unknown-typeflag ;
index 7368aef8253ff3520c5c0fce1c700354325d6da1..9b862a8960407c513c5c20a0f479b4237139145f 100644 (file)
@@ -11,5 +11,4 @@ IN: taxes.usa.futa
 
 : futa-tax ( salary w4 -- x )
     drop futa-base-rate min
-    futa-tax-rate futa-tax-offset-credit -
-    * ;
+    futa-tax-rate futa-tax-offset-credit - * ;
index 27ff4aef989f40efd89280150e97380a2b401af4..bbfc33286877c8b73268d246b117aef1ba4db6c7 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs kernel math math.intervals
-namespaces sequences money math.order taxes.usa.w4 ;
+namespaces sequences money math.order taxes.usa.w4
+taxes.usa.futa math.finance ;
 IN: taxes.usa
 
 ! Withhold: FICA, Medicare, Federal (FICA is social security)
diff --git a/extra/twitter/twitter.factor b/extra/twitter/twitter.factor
new file mode 100644 (file)
index 0000000..2172d7c
--- /dev/null
@@ -0,0 +1,100 @@
+USING: accessors assocs combinators hashtables http
+http.client json.reader kernel macros namespaces sequences
+urls.secure urls.encoding ;
+IN: twitter
+
+SYMBOLS: twitter-username twitter-password twitter-source ;
+
+twitter-source [ "factor" ] initialize
+
+TUPLE: twitter-status
+    created-at
+    id
+    text
+    source
+    truncated?
+    in-reply-to-status-id
+    in-reply-to-user-id
+    favorited?
+    user ;
+TUPLE: twitter-user
+    id
+    name
+    screen-name
+    description
+    location
+    profile-image-url 
+    url
+    protected?
+    followers-count ;
+
+MACRO: keys-boa ( keys class -- )
+    [ [ \ swap \ at [ ] 3sequence ] map \ cleave ] dip \ boa [ ] 4sequence ;
+
+: <twitter-user> ( assoc -- user )
+    {
+        "id"
+        "name"
+        "screen_name"
+        "description"
+        "location"
+        "profile_image_url"
+        "url"
+        "protected"
+        "followers_count"
+    } twitter-user keys-boa ;
+
+: <twitter-status> ( assoc -- tweet )
+    clone "user" over [ <twitter-user> ] change-at 
+    {
+        "created_at"
+        "id"
+        "text"
+        "source"
+        "truncated"
+        "in_reply_to_status_id"
+        "in_reply_to_user_id"
+        "favorited"
+        "user"
+    } twitter-status keys-boa ;
+
+: json>twitter-statuses ( json-array -- tweets )
+    json> [ <twitter-status> ] map ;
+
+: json>twitter-status ( json-object -- tweet )
+    json> <twitter-status> ;
+
+: set-twitter-credentials ( username password -- )
+    [ twitter-username set ] [ twitter-password set ] bi* ; 
+
+: set-request-twitter-auth ( request -- request )
+    twitter-username twitter-password [ get ] bi@ set-basic-auth ;
+
+: update-post-data ( update -- assoc )
+    "status" associate
+    [ twitter-source get "source" ] dip [ set-at ] keep ;
+
+: (tweet) ( string -- json )
+    update-post-data "https://twitter.com/statuses/update.json" <post-request>
+        set-request-twitter-auth 
+    http-request nip ;
+
+: tweet* ( string -- tweet )
+    (tweet) json>twitter-status ;
+
+: tweet ( string -- ) (tweet) drop ;
+
+: public-timeline ( -- tweets )
+    "https://twitter.com/statuses/public_timeline.json" <get-request>
+        set-request-twitter-auth
+    http-request nip json>twitter-statuses ;
+
+: friends-timeline ( -- tweets )
+    "https://twitter.com/statuses/friends_timeline.json" <get-request>
+        set-request-twitter-auth
+    http-request nip json>twitter-statuses ;
+
+: user-timeline ( username -- tweets )
+    "https://twitter.com/statuses/user_timeline/" ".json" surround <get-request>
+        set-request-twitter-auth
+    http-request nip json>twitter-statuses ;
index 5d800981bf7eacfd0ddfc37a5f1ceeade07cace7..4123a836750a8a32d1a8daa49c05c937299296b8 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: help.markup help.syntax kernel quotations ui.gadgets
-graphics.bitmap strings ui.gadgets.worlds ;
+images.bitmap strings ui.gadgets.worlds ;
 IN: ui.offscreen
 
 HELP: <offscreen-world>
index 89c1c7f860940ec06fb152806c888e6c72f894dc..cf9370ed7fa6b050fe9e373bf33124743f165445 100755 (executable)
@@ -1,5 +1,5 @@
 ! (c) 2008 Joe Groff, see license for details
-USING: accessors continuations graphics.bitmap kernel math
+USING: accessors continuations images.bitmap kernel math
 sequences ui.gadgets ui.gadgets.worlds ui ui.backend
 destructors ;
 IN: ui.offscreen
index 2267c22a20677775f6f2c991183ff8e4ec77033a..bd3c0826529cafaf6612aa8e172f7f236bb1d743 100755 (executable)
@@ -1,10 +1,10 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors colors arrays kernel sequences math byte-arrays
-namespaces grouping fry cap graphics.bitmap
+namespaces grouping fry cap images.bitmap
 ui.gadgets ui.gadgets.packs ui.gadgets.borders ui.gadgets.grids
 ui.gadgets.grid-lines ui.gadgets.labels ui.gadgets.buttons
-ui.render ui opengl opengl.gl ;
+ui.render ui opengl opengl.gl images images.loader ;
 IN: ui.render.test
 
 SINGLETON: line-test
@@ -30,7 +30,7 @@ SYMBOL: render-output
 
 : bitmap= ( bitmap1 bitmap2 -- ? )
     [
-        [ [ array>> ] [ stride 4 align ] bi group ] [ stride ] bi
+        [ [ buffer>> ] [ stride 4 align ] bi group ] [ stride ] bi
         '[ _ head twiddle ] map
     ] bi@ = ;
 
@@ -38,7 +38,7 @@ SYMBOL: render-output
     screenshot
     [ render-output set-global ]
     [
-        "resource:extra/ui/render/test/reference.bmp" load-bitmap
+        "resource:extra/ui/render/test/reference.bmp" load-image
         bitmap= "is perfect" "needs work" ?
         "Your UI rendering " prepend
         message-window
index e1f6c8735a49aeacac268474002b374bf64ec300..6ef60c198facbf1bee8e72e5fa410b71c02b76ce 100755 (executable)
@@ -106,7 +106,8 @@ todo "TODO"
 
 : <todo-list> ( -- responder )
     todo-list new-dispatcher
-        <list-action>   ""       add-responder
+        <list-action>   "list"       add-responder
+        URL" /list" <redirect-responder> "" add-responder
         <view-action>   "view"   add-responder
         <new-action>    "new"    add-responder
         <edit-action>   "edit"   add-responder
@@ -115,3 +116,52 @@ todo "TODO"
         { todo-list "todo" } >>template
     <protected>
         "view your todo list" >>description ;
+
+USING: furnace.auth.features.registration
+furnace.auth.features.edit-profile
+furnace.auth.features.deactivate-user
+db.sqlite
+furnace.alloy
+io.servers.connection
+io.sockets.secure ;
+
+: <login-config> ( responder -- responder' )
+    "Todo list" <login-realm>
+        "Todo list" >>name
+        allow-registration
+        allow-edit-profile
+        allow-deactivation ;
+
+: todo-db ( -- db ) "resource:todo.db" <sqlite-db> ;
+
+: init-todo-db ( -- )
+    todo-db [
+        init-furnace-tables
+        todo ensure-table
+    ] with-db ;
+
+: <todo-secure-config> ( -- config )
+    ! This is only suitable for testing!
+    <secure-config>
+        "resource:basis/openssl/test/dh1024.pem" >>dh-file
+        "resource:basis/openssl/test/server.pem" >>key-file
+        "password" >>password ;
+
+: <todo-app> ( -- responder )
+    init-todo-db
+    <todo-list>
+        <login-config>
+        todo-db <alloy> ;
+
+: <todo-website-server> ( -- threaded-server )
+    <http-server>
+        <todo-secure-config> >>secure-config
+        8080 >>insecure
+        8431 >>secure ;
+
+: run-todo ( -- )
+    <todo-app> main-responder set-global
+    todo-db start-expiring
+    <todo-website-server> start-server ;
+
+MAIN: run-todo
index f7500cdad2b85c8b044a818c09cc9e98433a03e2..00ed63560c1c2083a2412108d3a4c9713801b68b 100644 (file)
@@ -2,7 +2,14 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
+<html>
+
        <t:style t:include="resource:extra/webapps/todo/todo.css" />
+       <t:style t:include="resource:extra/websites/concatenative/page.css" />
+
+    <head><t:write-title/><t:write-style/></head>
+
+    <body>
 
        <div class="navbar">
                  <t:a t:href="$todo-list/list">List Items</t:a>
@@ -19,4 +26,8 @@
 
        <t:call-next-template />
 
+    </body>
+
+</html>
+
 </t:chloe>
index c1d62c6cdaf7c7f7cb84c94e66fba5c622f93f31..35a1129338f4f6714b476aa47f3fb35248be997d 100644 (file)
@@ -65,7 +65,7 @@ SYMBOL: dh-file
     "concatenative.org" 25 <inet> smtp-server set-global
     "noreply@concatenative.org" lost-password-from set-global
     "website@concatenative.org" insomniac-sender set-global
-    "slava@factorcode.org" insomniac-recipients set-global
+    { "slava@factorcode.org" } insomniac-recipients set-global
     init-factor-db ;
 
 : init-testing ( -- )
index e6ec8b2dc93e5d04ef5c16a5f85fc905e55b436c..c21d25901f9e742a69adb5d98c973e7bf4d43213 100644 (file)
 (require 'fuel-eval)
 (require 'fuel-log)
 
+\f
+;;; Aux:
+
+(defvar fuel-completion--minibuffer-map
+  (let ((map (make-keymap)))
+    (set-keymap-parent map minibuffer-local-completion-map)
+    (define-key map "?" 'self-insert-command)
+    map))
+
 \f
 ;;; Vocabs dictionary:
 
@@ -33,7 +42,8 @@
   fuel-completion--vocabs)
 
 (defun fuel-completion--read-vocab (&optional reload init-input history)
-  (let ((vocabs (fuel-completion--vocabs reload)))
+  (let ((minibuffer-local-completion-map fuel-completion--minibuffer-map)
+        (vocabs (fuel-completion--vocabs reload)))
     (completing-read "Vocab name: " vocabs nil nil init-input history)))
 
 (defsubst fuel-completion--vocab-list (prefix)
@@ -170,12 +180,23 @@ terminates a current completion."
     (cons completions partial)))
 
 (defun fuel-completion--read-word (prompt &optional default history all)
-  (completing-read prompt
-                   (if all fuel-completion--all-words-list-func
-                     fuel-completion--word-list-func)
-                   nil nil nil
-                   history
-                   (or default (fuel-syntax-symbol-at-point))))
+  (let ((minibuffer-local-completion-map fuel-completion--minibuffer-map))
+    (completing-read prompt
+                     (if all fuel-completion--all-words-list-func
+                       fuel-completion--word-list-func)
+                     nil nil nil
+                     history
+                     (or default (fuel-syntax-symbol-at-point)))))
+
+(defvar fuel-completion--vocab-history nil)
+
+(defun fuel-completion--read-vocab (refresh)
+  (let ((minibuffer-local-completion-map fuel-completion--minibuffer-map)
+        (vocabs (fuel-completion--vocabs refresh))
+        (prompt "Vocabulary name: "))
+    (if vocabs
+        (completing-read prompt vocabs nil nil nil fuel-completion--vocab-history)
+      (read-string prompt nil fuel-completion--vocab-history))))
 
 (defun fuel-completion--complete-symbol ()
   "Complete the symbol at point.
index 14c4d0b36f8e1219858333eb01c098494ee9a137..f180d0f2b430beff7890475c69ff0159a51bb530 100644 (file)
   (add-hook 'comint-redirect-hook
             'fuel-con--comint-redirect-hook nil t))
 
-(defadvice comint-redirect-setup (after fuel-con--advice activate)
-  (setq comint-redirect-finished-regexp fuel-con--comint-finished-regex))
+(defadvice comint-redirect-setup
+  (after fuel-con--advice (output-buffer comint-buffer finished-regexp &optional echo))
+  (with-current-buffer comint-buffer
+    (when fuel-con--connection
+      (setq comint-redirect-finished-regexp fuel-con--comint-finished-regex))))
+(ad-activate 'comint-redirect-setup)
 
 (defun fuel-con--comint-preoutput-filter (str)
   (when (string-match fuel-con--comint-finished-regex str)
index e5f0ffd26fcc08bfe270d9fd546ec157a9396d3f..941f57140ec44af46350defd2c31196fa24d3e02 100644 (file)
     (fuel-edit--visit-file (car loc) fuel-edit-word-method)
     (goto-line (if (numberp (cadr loc)) (cadr loc) 1))))
 
-(defun fuel-edit--read-vocabulary-name (refresh)
-  (let* ((vocabs (fuel-completion--vocabs refresh))
-         (prompt "Vocabulary name: "))
-    (if vocabs
-        (completing-read prompt vocabs nil nil nil fuel-edit--vocab-history)
-      (read-string prompt nil fuel-edit--vocab-history))))
-
 (defun fuel-edit--edit-article (name)
   (let ((cmd `(:fuel* (,name fuel-get-article-location) "fuel" t)))
     (fuel-edit--try-edit (fuel-eval--send/wait cmd))))
@@ -72,7 +65,6 @@
 ;;; Editing commands:
 
 (defvar fuel-edit--word-history nil)
-(defvar fuel-edit--vocab-history nil)
 (defvar fuel-edit--previous-location nil)
 
 (defun fuel-edit-vocabulary (&optional refresh vocab)
@@ -80,7 +72,7 @@
 When called interactively, asks for vocabulary with completion.
 With prefix argument, refreshes cached vocabulary list."
   (interactive "P")
-  (let* ((vocab (or vocab (fuel-edit--read-vocabulary-name refresh)))
+  (let* ((vocab (or vocab (fuel-completion--read-vocab refresh)))
          (cmd `(:fuel* (,vocab fuel-get-vocab-location) "fuel" t)))
     (fuel-edit--try-edit (fuel-eval--send/wait cmd))))
 
index a82de388da955748f960d6e6c8d7ea21e68a068c..cfc8cab7f104397dcbf5e830257668b45c9e59c0 100644 (file)
@@ -257,7 +257,7 @@ buffer."
 
 (defun fuel-help-vocab (vocab)
   "Ask for a vocabulary name and show its help page."
-  (interactive (list (fuel-edit--read-vocabulary-name nil)))
+  (interactive (list (fuel-completion--read-vocab nil)))
   (fuel-help--get-vocab vocab))
 
 (defun fuel-help-next (&optional forget-current)
index d0898de04f78b7d986fd7a4fe7d439a90f6701bd..b8bf4d4b7f9a5465fa5b205c6bb5e4893f57f4b5 100644 (file)
@@ -32,7 +32,7 @@
 
 (defcustom fuel-listener-factor-binary
   (expand-file-name (cond ((eq system-type 'windows-nt)
-                           "factor.exe")
+                           "factor.com")
                           ((eq system-type 'darwin)
                            "Factor.app/Contents/MacOS/factor")
                           (t "factor"))
index 4844233ae78a80bb7d0fad12abad8b9d274678e4..980ea111a662dc16ca02626e3dbae45ede1a34a7 100644 (file)
   (fuel-markup--insert-newline)
   (dolist (s (cdr e))
     (fuel-markup--snippet (list '$snippet s))
-    (newline)))
+    (newline))
+  (newline))
 
 (defun fuel-markup--markup-example (e)
   (fuel-markup--insert-newline)
index 05d825593c56612b40fcdd669613111f803ea019..ac400c5622eaad22de7b1c2ed1adcd196d01022e 100644 (file)
@@ -71,7 +71,7 @@ You can configure `fuel-scaffold-developer-name' (set by default to
 `user-full-name') for the name to be inserted in the generated file."
   (interactive "P")
   (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
-                   (fuel-edit--read-vocabulary-name nil)))
+                    (fuel-completion--read-vocab nil)))
          (cmd `(:fuel* (,vocab ,fuel-scaffold-developer-name fuel-scaffold-help)
                        "fuel"))
          (ret (fuel-eval--send/wait cmd))
index 4d444ebe3e19f0a58848a221d03775bc53387857..faf1897304a97cb74fc193a95f8614cec7140950 100644 (file)
@@ -244,7 +244,7 @@ With prefix argument, force reload of vocabulary list."
 With prefix argument, ask for the vocab."
   (interactive "P")
   (let ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
-                   (fuel-edit--read-vocabulary-name))))
+                   (fuel-completion--read-vocab nil))))
     (when vocab
       (fuel-xref--show-vocab-words vocab
                                    (fuel-syntax--file-has-private)))))
index b49f7637afed3118ca057cc430ef24a29f64f68d..97c29d8c6e890a75df2bb67937bfb7305a4becd9 100755 (executable)
@@ -36,7 +36,7 @@ void init_ffi(void)
 
 void ffi_dlopen(F_DLL *dll)
 {
-       dll->dll = dlopen(alien_offset(dll->path), RTLD_LAZY|RTLD_GLOBAL);
+       dll->dll = dlopen(alien_offset(dll->path), RTLD_LAZY);
 }
 
 void *ffi_dlsym(F_DLL *dll, F_SYMBOL *symbol)