]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorWilliam Schlieper <schlieper@unc.edu>
Sun, 7 Dec 2008 01:42:14 +0000 (20:42 -0500)
committerWilliam Schlieper <schlieper@unc.edu>
Sun, 7 Dec 2008 01:42:14 +0000 (20:42 -0500)
1050 files changed:
README.txt
basis/alien/arrays/arrays-docs.factor
basis/alien/arrays/arrays.factor
basis/alien/c-types/c-types-docs.factor
basis/alien/c-types/c-types-tests.factor
basis/alien/c-types/c-types.factor
basis/alien/parser/parser.factor [new file with mode: 0644]
basis/alien/strings/strings.factor
basis/alien/structs/fields/fields.factor
basis/alien/structs/structs-tests.factor
basis/alien/structs/structs.factor
basis/alien/syntax/syntax-docs.factor
basis/alien/syntax/syntax.factor
basis/bit-arrays/bit-arrays.factor
basis/bit-vectors/bit-vectors-tests.factor
basis/bootstrap/compiler/compiler.factor
basis/bootstrap/image/image.factor
basis/bootstrap/stage2.factor
basis/boxes/boxes.factor
basis/calendar/calendar-docs.factor
basis/calendar/calendar-tests.factor
basis/calendar/calendar.factor
basis/calendar/format/format.factor
basis/channels/remote/remote.factor
basis/checksums/common/common.factor
basis/checksums/md5/md5.factor
basis/checksums/openssl/openssl.factor
basis/checksums/sha1/sha1.factor
basis/checksums/sha2/sha2.factor
basis/cocoa/application/application.factor
basis/cocoa/cocoa-tests.factor
basis/cocoa/dialogs/dialogs.factor
basis/cocoa/enumeration/enumeration.factor
basis/cocoa/messages/messages.factor
basis/cocoa/pasteboard/pasteboard.factor
basis/cocoa/subclassing/subclassing.factor
basis/cocoa/views/views.factor
basis/cocoa/windows/windows.factor
basis/combinators/short-circuit/short-circuit.factor
basis/command-line/command-line-docs.factor
basis/command-line/command-line-tests.factor [deleted file]
basis/command-line/command-line.factor
basis/compiler/alien/alien.factor
basis/compiler/cfg/alias-analysis/alias-analysis.factor
basis/compiler/cfg/builder/builder.factor
basis/compiler/cfg/def-use/def-use.factor
basis/compiler/cfg/hats/hats.factor
basis/compiler/cfg/instructions/instructions.factor
basis/compiler/cfg/intrinsics/fixnum/fixnum.factor
basis/compiler/cfg/intrinsics/intrinsics.factor
basis/compiler/cfg/intrinsics/misc/misc.factor [new file with mode: 0644]
basis/compiler/cfg/intrinsics/slots/slots.factor
basis/compiler/cfg/stack-frame/stack-frame.factor
basis/compiler/cfg/two-operand/two-operand.factor
basis/compiler/cfg/utilities/utilities.factor
basis/compiler/cfg/value-numbering/propagate/propagate.factor
basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/constants/constants.factor
basis/compiler/tests/alien.factor
basis/compiler/tests/codegen.factor
basis/compiler/tests/intrinsics.factor
basis/compiler/tests/optimizer.factor
basis/compiler/tests/spilling.factor
basis/compiler/tree/builder/builder.factor
basis/compiler/tree/cleanup/cleanup-tests.factor
basis/compiler/tree/cleanup/cleanup.factor
basis/compiler/tree/combinators/combinators.factor
basis/compiler/tree/dead-code/dead-code-tests.factor
basis/compiler/tree/dead-code/liveness/liveness.factor
basis/compiler/tree/debugger/debugger.factor
basis/compiler/tree/def-use/simplified/simplified.factor
basis/compiler/tree/escape-analysis/branches/branches.factor
basis/compiler/tree/escape-analysis/check/check.factor [new file with mode: 0644]
basis/compiler/tree/finalization/finalization.factor
basis/compiler/tree/normalization/normalization-tests.factor
basis/compiler/tree/normalization/normalization.factor
basis/compiler/tree/optimizer/optimizer.factor
basis/compiler/tree/propagation/branches/branches.factor
basis/compiler/tree/propagation/copy/copy.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/known-words/known-words.factor
basis/compiler/tree/propagation/nodes/nodes.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/propagation/propagation.factor
basis/compiler/tree/propagation/recursive/recursive.factor
basis/compiler/tree/propagation/simple/simple.factor
basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor
basis/compiler/utilities/utilities.factor [new file with mode: 0644]
basis/concurrency/conditions/conditions.factor
basis/concurrency/count-downs/count-downs.factor
basis/concurrency/distributed/distributed-tests.factor
basis/concurrency/exchangers/exchangers.factor
basis/concurrency/flags/flags-tests.factor
basis/concurrency/flags/flags.factor
basis/concurrency/futures/futures.factor
basis/concurrency/locks/locks-tests.factor
basis/concurrency/locks/locks.factor
basis/concurrency/mailboxes/mailboxes.factor
basis/concurrency/messaging/messaging-docs.factor
basis/concurrency/messaging/messaging.factor
basis/concurrency/promises/promises.factor
basis/concurrency/semaphores/semaphores.factor
basis/core-foundation/core-foundation.factor
basis/core-foundation/fsevents/fsevents.factor
basis/core-foundation/run-loop/run-loop.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32.factor [changed mode: 0644->0755]
basis/cpu/x86/64/64.factor
basis/cpu/x86/64/unix/unix.factor
basis/cpu/x86/64/winnt/winnt.factor
basis/cpu/x86/assembler/assembler.factor
basis/cpu/x86/assembler/syntax/syntax.factor
basis/cpu/x86/bootstrap.factor
basis/cpu/x86/x86.factor
basis/db/db.factor
basis/db/postgresql/lib/lib.factor
basis/db/postgresql/postgresql-tests.factor
basis/db/postgresql/postgresql.factor
basis/db/queries/queries.factor
basis/db/sqlite/sqlite.factor
basis/db/tuples/tuples-tests.factor
basis/db/types/types-docs.factor
basis/db/types/types.factor
basis/debugger/debugger-docs.factor
basis/debugger/debugger.factor
basis/delegate/delegate-docs.factor
basis/delegate/delegate.factor
basis/dlists/dlists-tests.factor
basis/dlists/dlists.factor
basis/documents/documents-tests.factor
basis/documents/documents.factor
basis/editors/editors.factor
basis/editors/emacs/emacs-docs.factor
basis/editors/scite/scite.factor
basis/environment/environment.factor
basis/farkup/farkup.factor
basis/float-arrays/authors.txt [deleted file]
basis/float-arrays/float-arrays-docs.factor [deleted file]
basis/float-arrays/float-arrays-tests.factor [deleted file]
basis/float-arrays/float-arrays.factor [deleted file]
basis/float-arrays/summary.txt [deleted file]
basis/float-arrays/tags.txt [deleted file]
basis/float-vectors/float-vectors-docs.factor [deleted file]
basis/float-vectors/float-vectors-tests.factor [deleted file]
basis/float-vectors/float-vectors.factor [deleted file]
basis/float-vectors/summary.txt [deleted file]
basis/float-vectors/tags.txt [deleted file]
basis/fry/fry-docs.factor
basis/fry/fry.factor
basis/ftp/client/authors.txt [new file with mode: 0644]
basis/ftp/client/client.factor [new file with mode: 0644]
basis/ftp/client/listing-parser/authors.txt [new file with mode: 0644]
basis/ftp/client/listing-parser/listing-parser.factor [new file with mode: 0644]
basis/ftp/client/tags.txt [new file with mode: 0644]
basis/ftp/ftp.factor [new file with mode: 0644]
basis/ftp/server/server.factor [new file with mode: 0644]
basis/ftp/server/tags.txt [new file with mode: 0644]
basis/ftp/tags.txt [new file with mode: 0644]
basis/functors/authors.txt [new file with mode: 0644]
basis/functors/functors-tests.factor [new file with mode: 0644]
basis/functors/functors.factor [new file with mode: 0644]
basis/functors/summary.txt [new file with mode: 0644]
basis/functors/tags.txt [new file with mode: 0644]
basis/furnace/actions/actions.factor
basis/furnace/asides/asides.factor
basis/furnace/auth/auth.factor
basis/furnace/auth/features/recover-password/recover-password.factor
basis/furnace/auth/features/registration/registration.factor
basis/furnace/auth/login/login.factor
basis/furnace/boilerplate/boilerplate.factor
basis/furnace/chloe-tags/chloe-tags.factor
basis/furnace/conversations/conversations.factor
basis/furnace/furnace-docs.factor
basis/furnace/furnace-tests.factor
basis/furnace/furnace.factor
basis/furnace/redirection/redirection.factor
basis/furnace/referrer/referrer-docs.factor
basis/furnace/referrer/referrer.factor
basis/furnace/sessions/sessions-tests.factor
basis/furnace/sessions/sessions.factor
basis/furnace/syndication/syndication.factor
basis/furnace/utilities/utilities-docs.factor [new file with mode: 0644]
basis/furnace/utilities/utilities.factor
basis/generalizations/generalizations-docs.factor
basis/generalizations/generalizations-tests.factor
basis/generalizations/generalizations.factor
basis/grouping/grouping.factor
basis/hash2/hash2.factor
basis/heaps/heaps.factor
basis/help/cookbook/cookbook.factor
basis/help/help.factor
basis/help/html/html.factor
basis/help/lint/lint.factor
basis/help/lint/summary.txt
basis/help/markup/markup.factor
basis/help/syntax/syntax.factor
basis/help/tutorial/tutorial.factor
basis/hints/hints-docs.factor
basis/hints/hints.factor
basis/html/elements/elements.factor
basis/html/streams/streams.factor
basis/html/templates/chloe/chloe.factor
basis/html/templates/chloe/compiler/compiler.factor
basis/http/http-tests.factor
basis/http/http.factor
basis/http/parsers/parsers.factor
basis/inspector/inspector.factor
basis/interpolate/interpolate-tests.factor
basis/interpolate/interpolate.factor
basis/interval-maps/interval-maps.factor
basis/io/buffers/buffers-tests.factor
basis/io/encodings/utf16/utf16.factor
basis/io/files/listing/authors.txt [deleted file]
basis/io/files/listing/listing-docs.factor [deleted file]
basis/io/files/listing/listing-tests.factor [deleted file]
basis/io/files/listing/listing.factor [deleted file]
basis/io/files/listing/tags.txt [deleted file]
basis/io/files/listing/unix/authors.txt [deleted file]
basis/io/files/listing/unix/tags.txt [deleted file]
basis/io/files/listing/unix/unix.factor [deleted file]
basis/io/files/listing/windows/authors.txt [deleted file]
basis/io/files/listing/windows/tags.txt [deleted file]
basis/io/files/listing/windows/windows.factor [deleted file]
basis/io/files/unique/backend/backend.factor [new file with mode: 0644]
basis/io/files/unique/unique-docs.factor [new file with mode: 0644]
basis/io/files/unique/unique-tests.factor [new file with mode: 0644]
basis/io/files/unique/unique.factor [new file with mode: 0644]
basis/io/launcher/launcher.factor
basis/io/mmap/alien/alien.factor [new file with mode: 0644]
basis/io/mmap/bool/bool.factor [new file with mode: 0644]
basis/io/mmap/char/char.factor [new file with mode: 0644]
basis/io/mmap/double/double.factor [new file with mode: 0644]
basis/io/mmap/float/float.factor [new file with mode: 0644]
basis/io/mmap/functor/functor.factor [new file with mode: 0644]
basis/io/mmap/int/int.factor [new file with mode: 0644]
basis/io/mmap/long/long.factor [new file with mode: 0644]
basis/io/mmap/longlong/longlong.factor [new file with mode: 0644]
basis/io/mmap/mmap-docs.factor
basis/io/mmap/mmap-tests.factor
basis/io/mmap/mmap.factor
basis/io/mmap/short/short.factor [new file with mode: 0644]
basis/io/mmap/uchar/uchar.factor [new file with mode: 0644]
basis/io/mmap/uint/uint.factor [new file with mode: 0644]
basis/io/mmap/ulong/ulong.factor [new file with mode: 0644]
basis/io/mmap/ulonglong/ulonglong.factor [new file with mode: 0644]
basis/io/mmap/ushort/ushort.factor [new file with mode: 0644]
basis/io/monitors/monitors.factor
basis/io/monitors/recursive/recursive.factor
basis/io/pipes/pipes.factor
basis/io/pools/pools.factor
basis/io/ports/ports.factor
basis/io/servers/connection/connection-docs.factor
basis/io/servers/connection/connection.factor
basis/io/sockets/secure/secure-docs.factor
basis/io/sockets/secure/secure.factor
basis/io/sockets/sockets-docs.factor
basis/io/sockets/sockets.factor
basis/io/streams/duplex/duplex.factor
basis/io/timeouts/timeouts.factor
basis/io/unix/backend/backend.factor
basis/io/unix/files/files.factor
basis/io/unix/files/freebsd/freebsd.factor [new file with mode: 0644]
basis/io/unix/files/freebsd/tags.txt [new file with mode: 0644]
basis/io/unix/files/linux/linux.factor [new file with mode: 0644]
basis/io/unix/files/linux/tags.txt [new file with mode: 0644]
basis/io/unix/files/macosx/macosx.factor [new file with mode: 0644]
basis/io/unix/files/macosx/tags.txt [new file with mode: 0644]
basis/io/unix/files/netbsd/netbsd.factor [new file with mode: 0644]
basis/io/unix/files/netbsd/tags.txt [new file with mode: 0644]
basis/io/unix/files/openbsd/openbsd.factor [new file with mode: 0644]
basis/io/unix/files/openbsd/tags.txt [new file with mode: 0644]
basis/io/unix/kqueue/kqueue.factor
basis/io/unix/launcher/launcher.factor
basis/io/unix/linux/monitors/monitors.factor
basis/io/unix/macosx/monitors/monitors.factor
basis/io/unix/pipes/pipes.factor
basis/io/unix/select/select.factor
basis/io/unix/sockets/secure/debug/debug.factor [new file with mode: 0644]
basis/io/unix/sockets/secure/secure-tests.factor
basis/io/unix/sockets/secure/secure.factor
basis/io/unix/sockets/sockets.factor
basis/io/unix/unix-tests.factor
basis/io/windows/files/files.factor
basis/io/windows/launcher/launcher.factor
basis/io/windows/mmap/mmap-tests.factor [deleted file]
basis/io/windows/nt/backend/backend.factor
basis/io/windows/nt/files/files.factor
basis/io/windows/nt/launcher/launcher.factor
basis/io/windows/nt/monitors/monitors.factor [changed mode: 0644->0755]
basis/io/windows/nt/privileges/privileges.factor [changed mode: 0644->0755]
basis/io/windows/nt/sockets/sockets.factor
basis/io/windows/sockets/sockets.factor
basis/io/windows/windows.factor
basis/libc/libc-docs.factor
basis/libc/libc.factor
basis/linked-assocs/linked-assocs.factor
basis/locals/backend/backend-tests.factor
basis/locals/backend/backend.factor
basis/locals/locals-docs.factor
basis/locals/locals-tests.factor
basis/locals/locals.factor
basis/logging/analysis/analysis.factor
basis/logging/logging-docs.factor
basis/logging/logging.factor
basis/logging/server/server.factor
basis/macros/macros.factor
basis/match/match.factor
basis/math/bitwise/bitwise-docs.factor
basis/math/bitwise/bitwise-tests.factor
basis/math/bitwise/bitwise.factor
basis/math/combinatorics/authors.txt [new file with mode: 0644]
basis/math/combinatorics/combinatorics-docs.factor [new file with mode: 0644]
basis/math/combinatorics/combinatorics-tests.factor [new file with mode: 0644]
basis/math/combinatorics/combinatorics.factor [new file with mode: 0644]
basis/math/combinatorics/summary.txt [new file with mode: 0644]
basis/math/complex/complex.factor
basis/math/functions/functions.factor
basis/math/geometry/rect/rect.factor
basis/math/libm/libm.factor
basis/math/partial-dispatch/partial-dispatch-tests.factor
basis/math/partial-dispatch/partial-dispatch.factor
basis/math/points/points.factor
basis/math/polynomials/authors.txt [new file with mode: 0644]
basis/math/polynomials/polynomials-docs.factor [new file with mode: 0644]
basis/math/polynomials/polynomials-tests.factor [new file with mode: 0644]
basis/math/polynomials/polynomials.factor [new file with mode: 0644]
basis/math/polynomials/summary.txt [new file with mode: 0644]
basis/math/quaternions/authors.txt [new file with mode: 0644]
basis/math/quaternions/quaternions-docs.factor [new file with mode: 0644]
basis/math/quaternions/quaternions-tests.factor [new file with mode: 0644]
basis/math/quaternions/quaternions.factor [new file with mode: 0755]
basis/math/quaternions/summary.txt [new file with mode: 0644]
basis/math/ranges/ranges.factor
basis/math/statistics/authors.txt [new file with mode: 0644]
basis/math/statistics/statistics-docs.factor [new file with mode: 0644]
basis/math/statistics/statistics-tests.factor [new file with mode: 0644]
basis/math/statistics/statistics.factor [new file with mode: 0644]
basis/math/statistics/summary.txt [new file with mode: 0644]
basis/math/vectors/vectors.factor
basis/mime/multipart/multipart-tests.factor
basis/mime/multipart/multipart.factor
basis/models/history/history.factor
basis/models/models.factor
basis/models/range/range.factor
basis/multiline/multiline.factor
basis/nibble-arrays/nibble-arrays-tests.factor [new file with mode: 0644]
basis/nibble-arrays/nibble-arrays.factor [new file with mode: 0644]
basis/opengl/gl/extensions/extensions.factor
basis/opengl/opengl.factor
basis/openssl/libssl/libssl.factor
basis/peg/parsers/parsers.factor
basis/peg/peg.factor
basis/present/present-docs.factor
basis/prettyprint/backend/backend.factor
basis/prettyprint/prettyprint-tests.factor
basis/prettyprint/prettyprint.factor
basis/prettyprint/sections/sections.factor
basis/qualified/qualified-docs.factor
basis/random/mersenne-twister/mersenne-twister.factor
basis/regexp/backend/backend.factor
basis/regexp/classes/classes.factor
basis/regexp/dfa/dfa.factor
basis/regexp/nfa/nfa.factor
basis/regexp/parser/parser-tests.factor
basis/regexp/parser/parser.factor
basis/regexp/regexp-docs.factor
basis/regexp/regexp-tests.factor
basis/regexp/regexp.factor
basis/regexp/transition-tables/transition-tables.factor
basis/regexp/traversal/traversal.factor
basis/regexp/utils/utils.factor
basis/sequences/deep/deep-docs.factor
basis/sequences/deep/deep-tests.factor
basis/sequences/deep/deep.factor
basis/sequences/next/next.factor
basis/serialize/serialize-tests.factor
basis/shuffle/shuffle-tests.factor
basis/shuffle/shuffle.factor
basis/smtp/server/server.factor
basis/smtp/smtp-docs.factor
basis/smtp/smtp-tests.factor
basis/smtp/smtp.factor
basis/specialized-arrays/alien/alien.factor [new file with mode: 0644]
basis/specialized-arrays/authors.txt [new file with mode: 0644]
basis/specialized-arrays/bool/bool.factor [new file with mode: 0644]
basis/specialized-arrays/char/char.factor [new file with mode: 0644]
basis/specialized-arrays/direct/alien/alien.factor [new file with mode: 0644]
basis/specialized-arrays/direct/bool/bool.factor [new file with mode: 0644]
basis/specialized-arrays/direct/char/char.factor [new file with mode: 0644]
basis/specialized-arrays/direct/direct-docs.factor [new file with mode: 0644]
basis/specialized-arrays/direct/direct-tests.factor [new file with mode: 0644]
basis/specialized-arrays/direct/direct.factor [new file with mode: 0644]
basis/specialized-arrays/direct/double/double.factor [new file with mode: 0644]
basis/specialized-arrays/direct/float/float.factor [new file with mode: 0644]
basis/specialized-arrays/direct/functor/functor.factor [new file with mode: 0755]
basis/specialized-arrays/direct/int/int.factor [new file with mode: 0644]
basis/specialized-arrays/direct/long/long.factor [new file with mode: 0644]
basis/specialized-arrays/direct/longlong/longlong.factor [new file with mode: 0644]
basis/specialized-arrays/direct/short/short.factor [new file with mode: 0644]
basis/specialized-arrays/direct/uchar/uchar.factor [new file with mode: 0644]
basis/specialized-arrays/direct/uint/uint.factor [new file with mode: 0644]
basis/specialized-arrays/direct/ulong/ulong.factor [new file with mode: 0644]
basis/specialized-arrays/direct/ulonglong/ulonglong.factor [new file with mode: 0644]
basis/specialized-arrays/direct/ushort/ushort.factor [new file with mode: 0644]
basis/specialized-arrays/double/double.factor [new file with mode: 0644]
basis/specialized-arrays/float/float.factor [new file with mode: 0644]
basis/specialized-arrays/functor/functor.factor [new file with mode: 0644]
basis/specialized-arrays/int/int.factor [new file with mode: 0644]
basis/specialized-arrays/long/long.factor [new file with mode: 0644]
basis/specialized-arrays/longlong/longlong.factor [new file with mode: 0644]
basis/specialized-arrays/short/short.factor [new file with mode: 0644]
basis/specialized-arrays/specialized-arrays-docs.factor [new file with mode: 0644]
basis/specialized-arrays/specialized-arrays-tests.factor [new file with mode: 0644]
basis/specialized-arrays/specialized-arrays.factor [new file with mode: 0644]
basis/specialized-arrays/summary.txt [new file with mode: 0644]
basis/specialized-arrays/tags.txt [new file with mode: 0644]
basis/specialized-arrays/uchar/uchar.factor [new file with mode: 0644]
basis/specialized-arrays/uint/uint.factor [new file with mode: 0644]
basis/specialized-arrays/ulong/ulong.factor [new file with mode: 0644]
basis/specialized-arrays/ulonglong/ulonglong.factor [new file with mode: 0644]
basis/specialized-arrays/ushort/ushort.factor [new file with mode: 0644]
basis/specialized-vectors/alien/alien.factor [new file with mode: 0644]
basis/specialized-vectors/authors.txt [new file with mode: 0644]
basis/specialized-vectors/bool/bool.factor [new file with mode: 0644]
basis/specialized-vectors/char/char.factor [new file with mode: 0644]
basis/specialized-vectors/double/double.factor [new file with mode: 0644]
basis/specialized-vectors/float/float.factor [new file with mode: 0644]
basis/specialized-vectors/functor/functor.factor [new file with mode: 0644]
basis/specialized-vectors/int/int.factor [new file with mode: 0644]
basis/specialized-vectors/long/long.factor [new file with mode: 0644]
basis/specialized-vectors/longlong/longlong.factor [new file with mode: 0644]
basis/specialized-vectors/short/short.factor [new file with mode: 0644]
basis/specialized-vectors/specialized-vectors-docs.factor [new file with mode: 0644]
basis/specialized-vectors/specialized-vectors-tests.factor [new file with mode: 0644]
basis/specialized-vectors/specialized-vectors.factor [new file with mode: 0644]
basis/specialized-vectors/summary.txt [new file with mode: 0644]
basis/specialized-vectors/tags.txt [new file with mode: 0644]
basis/specialized-vectors/uchar/uchar.factor [new file with mode: 0644]
basis/specialized-vectors/uint/uint.factor [new file with mode: 0644]
basis/specialized-vectors/ulong/ulong.factor [new file with mode: 0644]
basis/specialized-vectors/ulonglong/ulonglong.factor [new file with mode: 0644]
basis/specialized-vectors/ushort/ushort.factor [new file with mode: 0644]
basis/stack-checker/backend/backend-tests.factor
basis/stack-checker/backend/backend.factor
basis/stack-checker/branches/branches.factor
basis/stack-checker/errors/errors-docs.factor
basis/stack-checker/errors/errors.factor
basis/stack-checker/inlining/inlining.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/state/state.factor
basis/stack-checker/transforms/transforms.factor
basis/state-tables/authors.txt [deleted file]
basis/state-tables/state-tables-tests.factor [deleted file]
basis/state-tables/state-tables.factor [deleted file]
basis/struct-arrays/authors.txt [new file with mode: 0644]
basis/struct-arrays/struct-arrays-docs.factor [new file with mode: 0644]
basis/struct-arrays/struct-arrays-tests.factor [new file with mode: 0755]
basis/struct-arrays/struct-arrays.factor [new file with mode: 0755]
basis/struct-arrays/summary.txt [new file with mode: 0644]
basis/struct-arrays/tags.txt [new file with mode: 0644]
basis/syndication/syndication.factor
basis/threads/threads-docs.factor
basis/threads/threads.factor
basis/tools/annotations/annotations-docs.factor
basis/tools/annotations/annotations-tests.factor
basis/tools/annotations/annotations.factor
basis/tools/completion/completion.factor
basis/tools/deploy/config/config.factor
basis/tools/deploy/deploy-tests.factor
basis/tools/deploy/shaker/shaker.factor
basis/tools/deploy/test/8/8.factor [new file with mode: 0644]
basis/tools/deploy/test/8/deploy.factor [new file with mode: 0644]
basis/tools/files/authors.txt [new file with mode: 0644]
basis/tools/files/files-docs.factor [new file with mode: 0644]
basis/tools/files/files-tests.factor [new file with mode: 0644]
basis/tools/files/files.factor [new file with mode: 0755]
basis/tools/files/tags.txt [new file with mode: 0644]
basis/tools/files/unix/authors.txt [new file with mode: 0755]
basis/tools/files/unix/tags.txt [new file with mode: 0644]
basis/tools/files/unix/unix.factor [new file with mode: 0755]
basis/tools/files/windows/authors.txt [new file with mode: 0755]
basis/tools/files/windows/tags.txt [new file with mode: 0644]
basis/tools/files/windows/windows.factor [new file with mode: 0755]
basis/tools/hexdump/hexdump-docs.factor
basis/tools/hexdump/hexdump-tests.factor
basis/tools/hexdump/hexdump.factor
basis/tools/hexdump/summary.txt
basis/tools/memory/memory.factor
basis/tools/profiler/profiler.factor
basis/tools/scaffold/scaffold.factor
basis/tools/test/test-docs.factor
basis/tools/test/test-tests.factor [new file with mode: 0644]
basis/tools/test/test.factor
basis/tools/time/time.factor
basis/tools/vocabs/browser/browser-docs.factor
basis/tools/vocabs/browser/browser.factor
basis/tools/vocabs/monitor/monitor.factor
basis/tools/vocabs/vocabs.factor
basis/tools/walker/walker-tests.factor
basis/tools/walker/walker.factor
basis/tr/tr.factor
basis/ui/clipboards/clipboards.factor
basis/ui/cocoa/cocoa.factor
basis/ui/cocoa/tools/tools.factor
basis/ui/cocoa/views/views-tests.factor [new file with mode: 0644]
basis/ui/cocoa/views/views.factor
basis/ui/commands/commands.factor
basis/ui/freetype/freetype.factor
basis/ui/gadgets/books/books.factor
basis/ui/gadgets/buttons/buttons-docs.factor
basis/ui/gadgets/buttons/buttons.factor
basis/ui/gadgets/canvas/canvas.factor
basis/ui/gadgets/editors/editors-docs.factor
basis/ui/gadgets/editors/editors.factor [changed mode: 0644->0755]
basis/ui/gadgets/frames/frames-tests.factor
basis/ui/gadgets/frames/frames.factor
basis/ui/gadgets/gadgets.factor
basis/ui/gadgets/grid-lines/grid-lines.factor
basis/ui/gadgets/grids/grids.factor
basis/ui/gadgets/labelled/labelled.factor
basis/ui/gadgets/labels/labels.factor
basis/ui/gadgets/lists/lists.factor
basis/ui/gadgets/menus/menus-docs.factor
basis/ui/gadgets/menus/menus.factor
basis/ui/gadgets/packs/packs-tests.factor
basis/ui/gadgets/packs/packs.factor
basis/ui/gadgets/panes/panes.factor
basis/ui/gadgets/paragraphs/paragraphs.factor
basis/ui/gadgets/presentations/presentations.factor
basis/ui/gadgets/sliders/sliders.factor
basis/ui/gadgets/status-bar/status-bar.factor
basis/ui/gadgets/worlds/worlds-docs.factor
basis/ui/gadgets/worlds/worlds.factor
basis/ui/gestures/gestures-docs.factor
basis/ui/gestures/gestures.factor
basis/ui/operations/operations.factor
basis/ui/render/render-docs.factor
basis/ui/render/render.factor
basis/ui/tools/debugger/debugger.factor
basis/ui/tools/deploy/deploy.factor
basis/ui/tools/interactor/interactor.factor
basis/ui/tools/listener/listener.factor
basis/ui/tools/profiler/profiler.factor
basis/ui/tools/search/search-tests.factor
basis/ui/tools/tools-docs.factor
basis/ui/tools/tools.factor
basis/ui/tools/traceback/traceback.factor
basis/ui/tools/walker/walker.factor
basis/ui/tools/workspace/workspace.factor
basis/ui/traverse/traverse.factor
basis/ui/ui-docs.factor
basis/ui/windows/windows.factor
basis/ui/x11/x11.factor [changed mode: 0644->0755]
basis/unicode/breaks/breaks.factor
basis/unicode/case/case.factor
basis/unicode/collation/collation.factor
basis/unicode/data/data.factor
basis/unicode/normalize/normalize.factor
basis/unix/getfsstat/freebsd/authors.txt [new file with mode: 0644]
basis/unix/getfsstat/freebsd/freebsd.factor [new file with mode: 0644]
basis/unix/getfsstat/freebsd/tags.txt [new file with mode: 0644]
basis/unix/getfsstat/macosx/authors.txt [new file with mode: 0644]
basis/unix/getfsstat/macosx/macosx.factor [new file with mode: 0644]
basis/unix/getfsstat/macosx/tags.txt [new file with mode: 0644]
basis/unix/getfsstat/netbsd/authors.txt [new file with mode: 0644]
basis/unix/getfsstat/netbsd/netbsd.factor [new file with mode: 0644]
basis/unix/getfsstat/netbsd/tags.txt [new file with mode: 0644]
basis/unix/getfsstat/openbsd/authors.txt [new file with mode: 0644]
basis/unix/getfsstat/openbsd/openbsd.factor [new file with mode: 0644]
basis/unix/getfsstat/openbsd/tags.txt [new file with mode: 0644]
basis/unix/process/process.factor
basis/unix/statfs/authors.txt [deleted file]
basis/unix/statfs/freebsd/freebsd.factor
basis/unix/statfs/linux/32/32.factor [deleted file]
basis/unix/statfs/linux/32/authors.txt [deleted file]
basis/unix/statfs/linux/32/tags.txt [deleted file]
basis/unix/statfs/linux/64/64.factor [deleted file]
basis/unix/statfs/linux/64/authors.txt [deleted file]
basis/unix/statfs/linux/64/tags.txt [deleted file]
basis/unix/statfs/linux/linux.factor
basis/unix/statfs/macosx/macosx.factor
basis/unix/statfs/netbsd/authors.txt [deleted file]
basis/unix/statfs/netbsd/netbsd.factor [deleted file]
basis/unix/statfs/netbsd/tags.txt [deleted file]
basis/unix/statfs/openbsd/32/32.factor [deleted file]
basis/unix/statfs/openbsd/32/authors.txt [deleted file]
basis/unix/statfs/openbsd/32/tags.txt [deleted file]
basis/unix/statfs/openbsd/64/64.factor [deleted file]
basis/unix/statfs/openbsd/64/authors.txt [deleted file]
basis/unix/statfs/openbsd/64/tags.txt [deleted file]
basis/unix/statfs/openbsd/authors.txt [deleted file]
basis/unix/statfs/openbsd/openbsd.factor
basis/unix/statfs/statfs-tests.factor [deleted file]
basis/unix/statfs/statfs.factor [deleted file]
basis/unix/statfs/tags.txt [deleted file]
basis/unix/statvfs/authors.txt [new file with mode: 0644]
basis/unix/statvfs/freebsd/authors.txt [new file with mode: 0644]
basis/unix/statvfs/freebsd/freebsd.factor [new file with mode: 0644]
basis/unix/statvfs/freebsd/tags.txt [new file with mode: 0644]
basis/unix/statvfs/linux/authors.txt [new file with mode: 0644]
basis/unix/statvfs/linux/linux.factor [new file with mode: 0644]
basis/unix/statvfs/linux/tags.txt [new file with mode: 0644]
basis/unix/statvfs/macosx/authors.txt [new file with mode: 0644]
basis/unix/statvfs/macosx/macosx.factor [new file with mode: 0644]
basis/unix/statvfs/macosx/tags.txt [new file with mode: 0644]
basis/unix/statvfs/netbsd/authors.txt [new file with mode: 0644]
basis/unix/statvfs/netbsd/netbsd.factor [new file with mode: 0644]
basis/unix/statvfs/netbsd/tags.txt [new file with mode: 0644]
basis/unix/statvfs/openbsd/authors.txt [new file with mode: 0644]
basis/unix/statvfs/openbsd/openbsd.factor [new file with mode: 0644]
basis/unix/statvfs/openbsd/tags.txt [new file with mode: 0644]
basis/unix/statvfs/statvfs.factor [new file with mode: 0644]
basis/unix/statvfs/tags.txt [new file with mode: 0644]
basis/unix/unix.factor
basis/unix/utilities/utilities.factor
basis/urls/encoding/encoding.factor
basis/windows/com/com.factor
basis/windows/com/syntax/syntax.factor [changed mode: 0644->0755]
basis/windows/com/wrapper/wrapper.factor [changed mode: 0644->0755]
basis/windows/dinput/constants/constants.factor [changed mode: 0644->0755]
basis/windows/kernel32/kernel32.factor
basis/windows/ole32/ole32.factor [changed mode: 0644->0755]
basis/windows/types/types.factor
basis/x11/clipboard/clipboard.factor
basis/x11/glx/glx.factor
basis/x11/xim/xim.factor
basis/x11/xlib/xlib.factor
basis/xml/data/data.factor
basis/xml/entities/entities.factor
basis/xml/errors/errors-tests.factor
basis/xml/errors/errors.factor
basis/xml/generator/generator-tests.factor
basis/xml/generator/generator.factor
basis/xml/tests/arithmetic.factor
basis/xml/tests/funny-dtd.factor [new file with mode: 0644]
basis/xml/tests/funny-dtd.xml [new file with mode: 0644]
basis/xml/tests/templating.factor
basis/xml/tests/test.factor
basis/xml/tests/xmode-dtd.factor [new file with mode: 0644]
basis/xml/tokenize/tokenize.factor
basis/xml/utilities/utilities.factor
basis/xml/writer/writer.factor
basis/xml/xml-docs.factor
basis/xml/xml.factor
basis/xmode/utilities/utilities.factor
core/arrays/arrays.factor
core/assocs/assocs-tests.factor
core/assocs/assocs.factor
core/bootstrap/primitives.factor
core/byte-arrays/byte-arrays.factor
core/byte-vectors/byte-vectors.factor
core/classes/builtin/builtin.factor
core/classes/intersection/intersection.factor
core/classes/mixin/mixin.factor
core/classes/tuple/tuple-docs.factor
core/classes/tuple/tuple.factor
core/combinators/combinators-docs.factor
core/combinators/combinators.factor
core/continuations/continuations-docs.factor
core/continuations/continuations.factor
core/effects/effects.factor
core/generic/generic-docs.factor
core/generic/generic.factor
core/generic/math/math-docs.factor
core/generic/math/math.factor
core/generic/parser/parser.factor
core/generic/standard/engines/tag/tag.factor
core/generic/standard/standard-docs.factor
core/generic/standard/standard-tests.factor
core/generic/standard/standard.factor
core/hashtables/hashtables.factor
core/io/backend/backend.factor
core/io/encodings/encodings-docs.factor
core/io/files/files-tests.factor
core/io/files/files.factor
core/io/io-docs.factor
core/io/io.factor
core/io/streams/c/c-docs.factor
core/io/streams/c/c.factor
core/kernel/kernel-docs.factor
core/kernel/kernel-tests.factor
core/kernel/kernel.factor
core/math/floats/floats-docs.factor
core/math/floats/floats-tests.factor
core/math/floats/floats.factor
core/math/integers/integers.factor
core/math/math-docs.factor
core/math/math.factor
core/math/parser/parser.factor
core/memory/memory-docs.factor
core/namespaces/namespaces.factor
core/parser/parser-tests.factor
core/parser/parser.factor
core/sbufs/sbufs.factor
core/sequences/sequences-docs.factor
core/sequences/sequences-tests.factor
core/sequences/sequences.factor
core/strings/strings.factor
core/syntax/syntax.factor
core/system/system-docs.factor
core/vectors/vectors.factor
core/vocabs/loader/loader-docs.factor
core/vocabs/loader/loader-tests.factor
core/vocabs/loader/loader.factor
core/words/words.factor
extra/asn1/asn1.factor
extra/assocs/lib/lib.factor
extra/benchmark/benchmark.factor
extra/benchmark/dawes/dawes.factor
extra/benchmark/dispatch2/dispatch2.factor
extra/benchmark/dispatch3/dispatch3.factor
extra/benchmark/fannkuch/fannkuch.factor [new file with mode: 0644]
extra/benchmark/fasta/fasta.factor
extra/benchmark/knucleotide/knucleotide.factor
extra/benchmark/nbody/nbody.factor [new file with mode: 0644]
extra/benchmark/partial-sums/partial-sums.factor
extra/benchmark/raytracer/raytracer.factor
extra/benchmark/regex-dna/regex-dna.factor
extra/benchmark/spectral-norm/spectral-norm.factor
extra/benchmark/xml/xml.factor [new file with mode: 0644]
extra/bitfields/bitfields.factor
extra/boids/boids.factor
extra/boids/ui/authors.txt [deleted file]
extra/boids/ui/deploy.factor [deleted file]
extra/boids/ui/tags.txt [deleted file]
extra/boids/ui/ui.factor [deleted file]
extra/bunny/fixed-pipeline/fixed-pipeline.factor [changed mode: 0644->0755]
extra/bunny/model/model.factor
extra/cairo/samples/samples.factor
extra/cap/cap.factor
extra/cfdg/cfdg.factor
extra/combinators/cleave/enhanced/enhanced.factor [new file with mode: 0644]
extra/combinators/lib/lib.factor
extra/contributors/contributors.factor
extra/dns/dns.factor
extra/flatland/flatland.factor [new file with mode: 0644]
extra/ftp/client/authors.txt [deleted file]
extra/ftp/client/client.factor [deleted file]
extra/ftp/client/listing-parser/authors.txt [deleted file]
extra/ftp/client/listing-parser/listing-parser.factor [deleted file]
extra/ftp/client/tags.txt [deleted file]
extra/ftp/ftp.factor [deleted file]
extra/ftp/server/server.factor [deleted file]
extra/ftp/server/tags.txt [deleted file]
extra/ftp/tags.txt [deleted file]
extra/fuel/authors.txt [new file with mode: 0644]
extra/fuel/fuel-tests.factor [new file with mode: 0644]
extra/fuel/fuel.factor [new file with mode: 0644]
extra/golden-section/authors.txt [deleted file]
extra/golden-section/deploy.factor [deleted file]
extra/golden-section/golden-section.factor [deleted file]
extra/golden-section/summary.txt [deleted file]
extra/golden-section/tags.txt [deleted file]
extra/hardware-info/windows/ce/ce.factor
extra/hardware-info/windows/nt/nt.factor
extra/hardware-info/windows/windows.factor
extra/hello-world/deploy.factor
extra/html/parser/parser.factor
extra/inverse/inverse.factor
extra/io/files/unique/backend/backend.factor [deleted file]
extra/io/files/unique/unique-docs.factor [deleted file]
extra/io/files/unique/unique-tests.factor [deleted file]
extra/io/files/unique/unique.factor [deleted file]
extra/irc/client/client-tests.factor
extra/irc/client/client.factor
extra/irc/gitbot/gitbot.factor [new file with mode: 0644]
extra/irc/ui/commandparser/commandparser.factor
extra/irc/ui/ui.factor
extra/jamshred/authors.txt [deleted file]
extra/jamshred/deploy.factor [deleted file]
extra/jamshred/game/authors.txt [deleted file]
extra/jamshred/game/game.factor [deleted file]
extra/jamshred/gl/authors.txt [deleted file]
extra/jamshred/gl/gl.factor [deleted file]
extra/jamshred/jamshred.factor [deleted file]
extra/jamshred/log/log.factor [deleted file]
extra/jamshred/oint/authors.txt [deleted file]
extra/jamshred/oint/oint-tests.factor [deleted file]
extra/jamshred/oint/oint.factor [deleted file]
extra/jamshred/player/authors.txt [deleted file]
extra/jamshred/player/player.factor [deleted file]
extra/jamshred/sound/bang.wav [deleted file]
extra/jamshred/sound/sound.factor [deleted file]
extra/jamshred/summary.txt [deleted file]
extra/jamshred/tags.txt [deleted file]
extra/jamshred/tunnel/authors.txt [deleted file]
extra/jamshred/tunnel/tunnel-tests.factor [deleted file]
extra/jamshred/tunnel/tunnel.factor [deleted file]
extra/line-art/authors.txt [deleted file]
extra/line-art/summary.txt [deleted file]
extra/line-art/tags.txt [deleted file]
extra/lisp/authors.txt [deleted file]
extra/lisp/lisp-docs.factor [deleted file]
extra/lisp/lisp-tests.factor [deleted file]
extra/lisp/lisp.factor [deleted file]
extra/lisp/parser/authors.txt [deleted file]
extra/lisp/parser/parser-docs.factor [deleted file]
extra/lisp/parser/parser-tests.factor [deleted file]
extra/lisp/parser/parser.factor [deleted file]
extra/lisp/parser/summary.txt [deleted file]
extra/lisp/parser/tags.txt [deleted file]
extra/lisp/summary.txt [deleted file]
extra/lisp/tags.txt [deleted file]
extra/mason/common/common.factor
extra/mason/config/config.factor
extra/mason/release/branch/branch-tests.factor
extra/mason/release/branch/branch.factor
extra/mason/test/test.factor
extra/math/blas/cblas/cblas.factor
extra/math/blas/matrices/matrices-docs.factor
extra/math/blas/matrices/matrices.factor
extra/math/blas/syntax/syntax.factor
extra/math/blas/vectors/vectors-docs.factor
extra/math/blas/vectors/vectors.factor
extra/math/combinatorics/authors.txt [deleted file]
extra/math/combinatorics/combinatorics-docs.factor [deleted file]
extra/math/combinatorics/combinatorics-tests.factor [deleted file]
extra/math/combinatorics/combinatorics.factor [deleted file]
extra/math/combinatorics/summary.txt [deleted file]
extra/math/derivatives/authors.txt [deleted file]
extra/math/derivatives/derivatives-docs.factor [deleted file]
extra/math/derivatives/derivatives-tests.factor [deleted file]
extra/math/derivatives/derivatives.factor [deleted file]
extra/math/floating-point/floating-point-tests.factor
extra/math/floating-point/floating-point.factor
extra/math/matrices/matrices-tests.factor
extra/math/newtons-method/authors.txt [deleted file]
extra/math/newtons-method/newtons-method.factor [deleted file]
extra/math/polynomials/authors.txt [deleted file]
extra/math/polynomials/polynomials-docs.factor [deleted file]
extra/math/polynomials/polynomials-tests.factor [deleted file]
extra/math/polynomials/polynomials.factor [deleted file]
extra/math/polynomials/summary.txt [deleted file]
extra/math/quaternions/authors.txt [deleted file]
extra/math/quaternions/quaternions-docs.factor [deleted file]
extra/math/quaternions/quaternions-tests.factor [deleted file]
extra/math/quaternions/quaternions.factor [deleted file]
extra/math/quaternions/summary.txt [deleted file]
extra/math/statistics/authors.txt [deleted file]
extra/math/statistics/statistics-docs.factor [deleted file]
extra/math/statistics/statistics-tests.factor [deleted file]
extra/math/statistics/statistics.factor [deleted file]
extra/math/statistics/summary.txt [deleted file]
extra/math/text/english/english.factor
extra/maze/maze.factor
extra/money/money-tests.factor
extra/money/money.factor
extra/morse/authors.txt [deleted file]
extra/morse/morse-docs.factor [deleted file]
extra/morse/morse-tests.factor [deleted file]
extra/morse/morse.factor [deleted file]
extra/morse/summary.txt [deleted file]
extra/morse/tags.txt [deleted file]
extra/multi-method-syntax/multi-method-syntax.factor [new file with mode: 0644]
extra/nehe/2/2.factor [deleted file]
extra/nehe/2/authors.txt [deleted file]
extra/nehe/3/3.factor [deleted file]
extra/nehe/3/authors.txt [deleted file]
extra/nehe/4/4.factor [deleted file]
extra/nehe/4/authors.txt [deleted file]
extra/nehe/5/5.factor [deleted file]
extra/nehe/5/authors.txt [deleted file]
extra/nehe/authors.txt [deleted file]
extra/nehe/deploy.factor [deleted file]
extra/nehe/nehe.factor [deleted file]
extra/nehe/summary.txt [deleted file]
extra/nehe/tags.txt [deleted file]
extra/openal/authors.txt [deleted file]
extra/openal/backend/authors.txt [deleted file]
extra/openal/backend/backend.factor [deleted file]
extra/openal/example/authors.txt [deleted file]
extra/openal/example/example.factor [deleted file]
extra/openal/macosx/authors.txt [deleted file]
extra/openal/macosx/macosx.factor [deleted file]
extra/openal/macosx/tags.txt [deleted file]
extra/openal/openal.factor [deleted file]
extra/openal/other/authors.txt [deleted file]
extra/openal/other/other.factor [deleted file]
extra/openal/summary.txt [deleted file]
extra/openal/tags.txt [deleted file]
extra/opengl/shaders/shaders.factor
extra/pong/pong.factor [new file with mode: 0644]
extra/printf/printf.factor
extra/processing/shapes/shapes.factor
extra/project-euler/002/002-tests.factor
extra/project-euler/002/002.factor
extra/project-euler/050/050-tests.factor [new file with mode: 0644]
extra/project-euler/050/050.factor [new file with mode: 0644]
extra/project-euler/ave-time/ave-time.factor
extra/sequences/complex-components/authors.txt [new file with mode: 0644]
extra/sequences/complex-components/complex-components-docs.factor [new file with mode: 0644]
extra/sequences/complex-components/complex-components-tests.factor [new file with mode: 0644]
extra/sequences/complex-components/complex-components.factor [new file with mode: 0644]
extra/sequences/complex-components/summary.txt [new file with mode: 0644]
extra/sequences/complex-components/tags.txt [new file with mode: 0644]
extra/sequences/complex/authors.txt [new file with mode: 0644]
extra/sequences/complex/complex-docs.factor [new file with mode: 0644]
extra/sequences/complex/complex-tests.factor [new file with mode: 0644]
extra/sequences/complex/complex.factor [new file with mode: 0644]
extra/sequences/complex/summary.txt [new file with mode: 0644]
extra/sequences/complex/tags.txt [new file with mode: 0644]
extra/sequences/lib/lib.factor
extra/spheres/spheres.factor
extra/sto/sto.factor [new file with mode: 0644]
extra/synth/authors.txt [deleted file]
extra/synth/buffers/authors.txt [deleted file]
extra/synth/buffers/buffers.factor [deleted file]
extra/synth/example/authors.txt [deleted file]
extra/synth/example/example.factor [deleted file]
extra/synth/summary.txt [deleted file]
extra/synth/synth.factor [deleted file]
extra/taxes/usa/usa-tests.factor
extra/taxes/utils/utils.factor [deleted file]
extra/ui/gadgets/plot/plot.factor [deleted file]
extra/webapps/blogs/blogs.factor
extra/webapps/help/help.factor
extra/webapps/ip/ip.factor
extra/webapps/wee-url/wee-url.factor
extra/webapps/wiki/wiki.factor
extra/wordtimer/wordtimer.factor
extra/xml/syntax/syntax.factor [deleted file]
misc/factor.el
misc/fuel/README [new file with mode: 0644]
misc/fuel/factor-mode.el [new file with mode: 0644]
misc/fuel/fu.el [new file with mode: 0644]
misc/fuel/fuel-base.el [new file with mode: 0644]
misc/fuel/fuel-eval.el [new file with mode: 0644]
misc/fuel/fuel-font-lock.el [new file with mode: 0644]
misc/fuel/fuel-help.el [new file with mode: 0644]
misc/fuel/fuel-listener.el [new file with mode: 0644]
misc/fuel/fuel-mode.el [new file with mode: 0644]
misc/fuel/fuel-syntax.el [new file with mode: 0644]
unmaintained/golden-section/authors.txt [new file with mode: 0644]
unmaintained/golden-section/deploy.factor [new file with mode: 0755]
unmaintained/golden-section/golden-section.factor [new file with mode: 0644]
unmaintained/golden-section/summary.txt [new file with mode: 0644]
unmaintained/golden-section/tags.txt [new file with mode: 0644]
unmaintained/jamshred/authors.txt [new file with mode: 0644]
unmaintained/jamshred/deploy.factor [new file with mode: 0644]
unmaintained/jamshred/game/authors.txt [new file with mode: 0755]
unmaintained/jamshred/game/game.factor [new file with mode: 0644]
unmaintained/jamshred/gl/authors.txt [new file with mode: 0755]
unmaintained/jamshred/gl/gl.factor [new file with mode: 0644]
unmaintained/jamshred/jamshred.factor [new file with mode: 0755]
unmaintained/jamshred/log/log.factor [new file with mode: 0644]
unmaintained/jamshred/oint/authors.txt [new file with mode: 0755]
unmaintained/jamshred/oint/oint-tests.factor [new file with mode: 0644]
unmaintained/jamshred/oint/oint.factor [new file with mode: 0644]
unmaintained/jamshred/player/authors.txt [new file with mode: 0755]
unmaintained/jamshred/player/player.factor [new file with mode: 0644]
unmaintained/jamshred/sound/bang.wav [new file with mode: 0644]
unmaintained/jamshred/sound/sound.factor [new file with mode: 0644]
unmaintained/jamshred/summary.txt [new file with mode: 0644]
unmaintained/jamshred/tags.txt [new file with mode: 0644]
unmaintained/jamshred/tunnel/authors.txt [new file with mode: 0755]
unmaintained/jamshred/tunnel/tunnel-tests.factor [new file with mode: 0644]
unmaintained/jamshred/tunnel/tunnel.factor [new file with mode: 0755]
unmaintained/lisp/authors.txt [new file with mode: 0644]
unmaintained/lisp/lisp-docs.factor [new file with mode: 0644]
unmaintained/lisp/lisp-tests.factor [new file with mode: 0644]
unmaintained/lisp/lisp.factor [new file with mode: 0644]
unmaintained/lisp/parser/authors.txt [new file with mode: 0644]
unmaintained/lisp/parser/parser-docs.factor [new file with mode: 0644]
unmaintained/lisp/parser/parser-tests.factor [new file with mode: 0644]
unmaintained/lisp/parser/parser.factor [new file with mode: 0644]
unmaintained/lisp/parser/summary.txt [new file with mode: 0644]
unmaintained/lisp/parser/tags.txt [new file with mode: 0644]
unmaintained/lisp/summary.txt [new file with mode: 0644]
unmaintained/lisp/tags.txt [new file with mode: 0644]
unmaintained/math/derivatives/authors.txt [new file with mode: 0644]
unmaintained/math/derivatives/derivatives-docs.factor [new file with mode: 0644]
unmaintained/math/derivatives/derivatives-tests.factor [new file with mode: 0644]
unmaintained/math/derivatives/derivatives.factor [new file with mode: 0644]
unmaintained/math/newtons-method/authors.txt [new file with mode: 0644]
unmaintained/math/newtons-method/newtons-method.factor [new file with mode: 0644]
unmaintained/morse/authors.txt [new file with mode: 0644]
unmaintained/morse/morse-docs.factor [new file with mode: 0644]
unmaintained/morse/morse-tests.factor [new file with mode: 0644]
unmaintained/morse/morse.factor [new file with mode: 0644]
unmaintained/morse/summary.txt [new file with mode: 0644]
unmaintained/morse/tags.txt [new file with mode: 0644]
unmaintained/nehe/2/2.factor [new file with mode: 0644]
unmaintained/nehe/2/authors.txt [new file with mode: 0755]
unmaintained/nehe/3/3.factor [new file with mode: 0644]
unmaintained/nehe/3/authors.txt [new file with mode: 0755]
unmaintained/nehe/4/4.factor [new file with mode: 0644]
unmaintained/nehe/4/authors.txt [new file with mode: 0755]
unmaintained/nehe/5/5.factor [new file with mode: 0755]
unmaintained/nehe/5/authors.txt [new file with mode: 0755]
unmaintained/nehe/authors.txt [new file with mode: 0644]
unmaintained/nehe/deploy.factor [new file with mode: 0755]
unmaintained/nehe/nehe.factor [new file with mode: 0644]
unmaintained/nehe/summary.txt [new file with mode: 0644]
unmaintained/nehe/tags.txt [new file with mode: 0644]
unmaintained/openal/authors.txt [new file with mode: 0644]
unmaintained/openal/backend/authors.txt [new file with mode: 0755]
unmaintained/openal/backend/backend.factor [new file with mode: 0644]
unmaintained/openal/example/authors.txt [new file with mode: 0755]
unmaintained/openal/example/example.factor [new file with mode: 0644]
unmaintained/openal/macosx/authors.txt [new file with mode: 0755]
unmaintained/openal/macosx/macosx.factor [new file with mode: 0644]
unmaintained/openal/macosx/tags.txt [new file with mode: 0644]
unmaintained/openal/openal.factor [new file with mode: 0644]
unmaintained/openal/other/authors.txt [new file with mode: 0755]
unmaintained/openal/other/other.factor [new file with mode: 0644]
unmaintained/openal/summary.txt [new file with mode: 0644]
unmaintained/openal/tags.txt [new file with mode: 0644]
unmaintained/plot/plot.factor [new file with mode: 0644]
unmaintained/synth/authors.txt [new file with mode: 0644]
unmaintained/synth/buffers/authors.txt [new file with mode: 0644]
unmaintained/synth/buffers/buffers.factor [new file with mode: 0644]
unmaintained/synth/example/authors.txt [new file with mode: 0644]
unmaintained/synth/example/example.factor [new file with mode: 0644]
unmaintained/synth/summary.txt [new file with mode: 0644]
unmaintained/synth/synth.factor [new file with mode: 0644]
unmaintained/xml/syntax/syntax.factor [new file with mode: 0644]
vm/Config.macosx.x86.64
vm/bignum.c
vm/code_gc.c
vm/code_heap.c
vm/code_heap.h
vm/cpu-arm.S
vm/cpu-ppc.S
vm/cpu-x86.32.S
vm/cpu-x86.64.S
vm/cpu-x86.S
vm/data_gc.c
vm/data_gc.h
vm/debug.c
vm/image.c
vm/layouts.h
vm/math.c
vm/math.h
vm/os-macosx.m
vm/os-unix.h
vm/os-windows.c
vm/os-windows.h
vm/primitives.c
vm/quotations.c
vm/quotations.h
vm/run.c
vm/run.h
vm/types.c
vm/types.h
vm/utilities.c

index 754791aa1a39f47bcacd661f5d4aa55eac0606bd..98616539d20d9c6f6366928dadf0bf27b1a5549f 100755 (executable)
@@ -43,13 +43,10 @@ Compilation will yield an executable named 'factor' on Unix,
 
 For X11 support, you need recent development libraries for libc,
 Freetype, X11, OpenGL and GLUT. On a Debian-derived Linux distribution
-(like Ubuntu), you can use the line
+(like Ubuntu), you can use the following line to grab everything:
 
     sudo apt-get install libc6-dev libfreetype6-dev libx11-dev glutg3-dev
 
-to grab everything (if you're on a non-debian-derived distro please tell
-us what the equivalent command is on there and it can be added).
-
 * Bootstrapping the Factor image
 
 Once you have compiled the Factor runtime, you must bootstrap the Factor
index 09a09cdc6f97d7136053b2ea2f6dfddbe824d462..c5efe1e030e7e711278f984c21fe7c5aa782ec0f 100644 (file)
@@ -1,69 +1,7 @@
 IN: alien.arrays\r
 USING: help.syntax help.markup byte-arrays alien.c-types ;\r
 \r
-ARTICLE: "c-arrays-factor" "Converting C arrays to and from Factor arrays"\r
-"Each primitive C type has a pair of words, " { $snippet ">" { $emphasis "type" } "-array" } " and " { $snippet { $emphasis "type" } "-array>" } ", for converting an array of Factor objects to and from a " { $link byte-array } " of C values. This set of words consists of:"\r
-{ $subsection >c-bool-array      }\r
-{ $subsection >c-char-array      }\r
-{ $subsection >c-double-array    }\r
-{ $subsection >c-float-array     }\r
-{ $subsection >c-int-array       }\r
-{ $subsection >c-long-array      }\r
-{ $subsection >c-longlong-array  }\r
-{ $subsection >c-short-array     }\r
-{ $subsection >c-uchar-array     }\r
-{ $subsection >c-uint-array      }\r
-{ $subsection >c-ulong-array     }\r
-{ $subsection >c-ulonglong-array }\r
-{ $subsection >c-ushort-array    }\r
-{ $subsection >c-void*-array     }\r
-{ $subsection c-bool-array>      }\r
-{ $subsection c-char-array>      }\r
-{ $subsection c-double-array>    }\r
-{ $subsection c-float-array>     }\r
-{ $subsection c-int-array>       }\r
-{ $subsection c-long-array>      }\r
-{ $subsection c-longlong-array>  }\r
-{ $subsection c-short-array>     }\r
-{ $subsection c-uchar-array>     }\r
-{ $subsection c-uint-array>      }\r
-{ $subsection c-ulong-array>     }\r
-{ $subsection c-ulonglong-array> }\r
-{ $subsection c-ushort-array>    }\r
-{ $subsection c-void*-array>     } ;\r
-\r
-ARTICLE: "c-arrays-get/set" "Reading and writing elements in C arrays"\r
-"Each C type has a pair of words, " { $snippet { $emphasis "type" } "-nth" } " and " { $snippet "set-" { $emphasis "type" } "-nth" } ", for reading and writing values of this type stored in an array. This set of words includes but is not limited to:"\r
-{ $subsection char-nth }\r
-{ $subsection set-char-nth }\r
-{ $subsection uchar-nth }\r
-{ $subsection set-uchar-nth }\r
-{ $subsection short-nth }\r
-{ $subsection set-short-nth }\r
-{ $subsection ushort-nth }\r
-{ $subsection set-ushort-nth }\r
-{ $subsection int-nth }\r
-{ $subsection set-int-nth }\r
-{ $subsection uint-nth }\r
-{ $subsection set-uint-nth }\r
-{ $subsection long-nth }\r
-{ $subsection set-long-nth }\r
-{ $subsection ulong-nth }\r
-{ $subsection set-ulong-nth }\r
-{ $subsection longlong-nth }\r
-{ $subsection set-longlong-nth }\r
-{ $subsection ulonglong-nth }\r
-{ $subsection set-ulonglong-nth }\r
-{ $subsection float-nth }\r
-{ $subsection set-float-nth }\r
-{ $subsection double-nth }\r
-{ $subsection set-double-nth }\r
-{ $subsection void*-nth }\r
-{ $subsection set-void*-nth } ;\r
-\r
 ARTICLE: "c-arrays" "C arrays"\r
 "C arrays are allocated in the same manner as other C data; see " { $link "c-byte-arrays" } " and " { $link "malloc" } "."\r
 $nl\r
-"C type specifiers for array types are documented in " { $link "c-types-specs" } "."\r
-{ $subsection "c-arrays-factor" }\r
-{ $subsection "c-arrays-get/set" } ;\r
+"C type specifiers for array types are documented in " { $link "c-types-specs" } "." ;\r
index 94472e8261b092718bd7170c0912ba5e03722714..727492edb1567a44905df3ce9893c02ed94b9b3d 100644 (file)
@@ -8,6 +8,8 @@ UNION: value-type array struct-type ;
 
 M: array c-type ;
 
+M: array c-type-class drop object ;
+
 M: array heap-size unclip heap-size [ * ] reduce ;
 
 M: array c-type-align first c-type-align ;
index 739b45486f0fe89ae4224cc2978912115fb8a750..a2b555b05765fdf7e56d5ec4a0869315baddbf57 100644 (file)
@@ -89,16 +89,6 @@ HELP: malloc-byte-array
 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
 { $errors "Throws an error if memory allocation fails." } ;
 
-HELP: define-nth
-{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
-{ $description "Defines a word " { $snippet { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( n c-ptr -- value )" } " for reading the value with C type " { $snippet "name" } " stored at an alien pointer, displaced by a multiple of the C type's size." }
-{ $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
-
-HELP: define-set-nth
-{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
-{ $description "Defines a word " { $snippet "set-" { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( value n c-ptr -- )" } " for writing the value with C type " { $snippet "name" } " to an alien pointer, displaced by a multiple of the C type's size." }
-{ $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
-
 HELP: box-parameter
 { $values { "n" integer } { "ctype" string } }
 { $description "Generates code for converting a C value stored at  offset " { $snippet "n" } " from the top of the stack into a Factor object to be pushed on the data stack." }
@@ -115,12 +105,12 @@ HELP: unbox-return
 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
 
 HELP: define-deref
-{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
+{ $values { "name" "a word name" } }
 { $description "Defines a word " { $snippet "*name" } " with stack effect " { $snippet "( c-ptr -- value )" } " for reading a value with C type " { $snippet "name" } " stored at an alien pointer." }
 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
 
 HELP: define-out
-{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
+{ $values { "name" "a word name" } }
 { $description "Defines a word " { $snippet "<" { $emphasis "name" } ">" } " with stack effect " { $snippet "( value -- array )" } ". This word allocates a byte array large enough to hold a value with C type " { $snippet "name" } ", and writes the value at the top of the stack to the array." }
 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
 
@@ -230,9 +220,7 @@ $nl
 "You can copy a range of bytes from memory into a byte array:"
 { $subsection memory>byte-array }
 "You can copy a byte array to memory unsafely:"
-{ $subsection byte-array>memory }
-"A wrapper for temporarily allocating a block of memory:"
-{ $subsection with-malloc } ;
+{ $subsection byte-array>memory } ;
 
 ARTICLE: "c-data" "Passing data between Factor and C"
 "Two defining characteristics of Factor are dynamic typing and automatic memory management, which are somewhat incompatible with the machine-level data model exposed by C. Factor's C library interface defines its own set of C data types, distinct from Factor language types, together with automatic conversion between Factor values and C types. For example, C integer types must be declared and are fixed-width, whereas Factor supports arbitrary-precision integers."
index edda9e7fdb4fa13a7a16c1336f6ce9bbf36edd09..f57d102452ca132031787331aef8201729158683 100644 (file)
@@ -55,4 +55,6 @@ TYPEDEF: uchar* MyLPBYTE
     0 B{ 1 2 3 4 } <displaced-alien> <void*>
 ] must-fail
 
-[ t ] [ { t f t } >c-bool-array { 1 0 1 } >c-int-array = ] unit-test
+os windows? cpu x86.64? and [
+    [ -2147467259 ] [ 2147500037 <long> *long ] unit-test
+] when
index 543af8dee8ee605306fc0a62f06932d76f2b689a..c3ae644b47856cf1b4cd436a306a7ab408da1e6d 100644 (file)
@@ -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 ;
+accessors combinators effects continuations fry ;
 IN: alien.c-types
 
 DEFER: <int>
@@ -13,13 +13,15 @@ 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 ;
+        int-regs >>reg-class
+        object >>class ; inline
 
 : <c-type> ( -- type )
     \ c-type new-c-type ;
@@ -50,7 +52,7 @@ GENERIC: c-type ( name -- type ) foldable
 
 : parse-array-type ( name -- array )
     "[" split unclip
-    >r [ "]" ?tail drop string>number ] map r> prefix ;
+    [ [ "]" ?tail drop string>number ] map ] dip prefix ;
 
 M: string c-type ( name -- type )
     CHAR: ] over member? [
@@ -63,6 +65,12 @@ M: string c-type ( name -- type )
         ] ?if
     ] if ;
 
+GENERIC: c-type-class ( name -- class )
+
+M: c-type c-type-class class>> ;
+
+M: string c-type-class c-type c-type-class ;
+
 GENERIC: c-type-boxer ( name -- boxer )
 
 M: c-type c-type-boxer boxer>> ;
@@ -172,12 +180,12 @@ M: byte-array byte-length length ;
 
 : c-getter ( name -- quot )
     c-type-getter [
-        [ "Cannot read struct fields with type" throw ]
+        [ "Cannot read struct fields with this type" throw ]
     ] unless* ;
 
 : c-setter ( name -- quot )
     c-type-setter [
-        [ "Cannot write struct fields with type" throw ]
+        [ "Cannot write struct fields with this type" throw ]
     ] unless* ;
 
 : <c-array> ( n type -- array )
@@ -193,36 +201,21 @@ M: byte-array byte-length length ;
     1 swap malloc-array ; inline
 
 : malloc-byte-array ( byte-array -- alien )
-    dup length dup malloc [ -rot memcpy ] keep ;
+    dup length [ nip malloc dup ] 2keep memcpy ;
 
 : memory>byte-array ( alien len -- byte-array )
-    dup <byte-array> [ -rot memcpy ] keep ;
+    [ nip <byte-array> dup ] 2keep memcpy ;
 
 : byte-array>memory ( byte-array base -- )
     swap dup length memcpy ;
 
-: (define-nth) ( word type quot -- )
+: array-accessor ( type quot -- def )
     [
         \ swap , [ heap-size , [ * >fixnum ] % ] [ % ] bi*
-    ] [ ] make define-inline ;
-
-: nth-word ( name vocab -- word )
-    >r "-nth" append r> create ;
-
-: define-nth ( name vocab -- )
-    dupd nth-word swap dup c-getter (define-nth) ;
-
-: set-nth-word ( name vocab -- word )
-    >r "set-" swap "-nth" 3append r> create ;
-
-: define-set-nth ( name vocab -- )
-    dupd set-nth-word swap dup c-setter (define-nth) ;
+    ] [ ] make ;
 
 : typedef ( old new -- ) c-types get set-at ;
 
-: define-c-type ( type name vocab -- )
-    >r tuck typedef r> [ define-nth ] 2keep define-set-nth ;
-
 TUPLE: long-long-type < c-type ;
 
 : <long-long-type> ( -- type )
@@ -240,62 +233,34 @@ M: long-long-type box-parameter ( n type -- )
 M: long-long-type box-return ( type -- )
     f swap box-parameter ;
 
-: define-deref ( name vocab -- )
-    >r dup CHAR: * prefix r> create
-    swap c-getter 0 prefix define-inline ;
+: define-deref ( name -- )
+    [ CHAR: * prefix "alien.c-types" create ]
+    [ c-getter 0 prefix ] bi
+    define-inline ;
 
-: define-out ( name vocab -- )
-    over [ <c-object> tuck 0 ] over c-setter append swap
-    >r >r constructor-word r> r> prefix define-inline ;
+: define-out ( name -- )
+    [ "alien.c-types" constructor-word ]
+    [ dup c-setter '[ _ <c-object> [ 0 @ ] keep ] ]
+    bi define-inline ;
 
 : c-bool> ( int -- ? )
     zero? not ;
 
-: >c-array ( seq type word -- byte-array )
-    [ [ dup length ] dip <c-array> ] dip
-    [ [ execute ] 2curry each-index ] 2keep drop ; inline
-
-: >c-array-quot ( type vocab -- quot )
-    dupd set-nth-word [ >c-array ] 2curry ;
-
-: to-array-word ( name vocab -- word )
-    >r ">c-" swap "-array" 3append r> create ;
-
-: define-to-array ( type vocab -- )
-    [ to-array-word ] 2keep >c-array-quot
-    (( array -- byte-array )) define-declared ;
-
-: c-array>quot ( type vocab -- quot )
-    [
-        \ swap ,
-        nth-word 1quotation ,
-        [ curry map ] %
-    ] [ ] make ;
-
-: from-array-word ( name vocab -- word )
-    >r "c-" swap "-array>" 3append r> create ;
-
-: define-from-array ( type vocab -- )
-    [ from-array-word ] 2keep c-array>quot
-    (( c-ptr n -- array )) define-declared ;
-
 : define-primitive-type ( type name -- )
-    "alien.c-types"
-    {
-        [ define-c-type ]
-        [ define-deref ]
-        [ define-to-array ]
-        [ define-from-array ]
-        [ define-out ]
-    } 2cleave ;
+    [ typedef ]
+    [ define-deref ]
+    [ define-out ]
+    tri ;
 
 : expand-constants ( c-type -- c-type' )
     dup array? [
-        unclip >r [
-            dup word? [
-                def>> { } swap with-datastack first
-            ] when
-        ] map r> prefix
+        unclip [
+            [
+                dup word? [
+                    def>> { } swap with-datastack first
+                ] when
+            ] map
+        ] dip prefix
     ] when ;
 
 : malloc-file-contents ( path -- alien len )
@@ -304,8 +269,20 @@ M: long-long-type box-return ( type -- )
 : if-void ( type true false -- )
     pick "void" = [ drop nip call ] [ nip call ] if ; inline
 
+: primitive-types
+    {
+        "char" "uchar"
+        "short" "ushort"
+        "int" "uint"
+        "long" "ulong"
+        "longlong" "ulonglong"
+        "float" "double"
+        "void*" "bool"
+    } ;
+
 [
     <c-type>
+        c-ptr >>class
         [ alien-cell ] >>getter
         [ set-alien-cell ] >>setter
         bootstrap-cell >>size
@@ -315,6 +292,7 @@ M: long-long-type box-return ( type -- )
     "void*" define-primitive-type
 
     <long-long-type>
+        integer >>class
         [ alien-signed-8 ] >>getter
         [ set-alien-signed-8 ] >>setter
         8 >>size
@@ -324,6 +302,7 @@ M: long-long-type box-return ( type -- )
     "longlong" define-primitive-type
 
     <long-long-type>
+        integer >>class
         [ alien-unsigned-8 ] >>getter
         [ set-alien-unsigned-8 ] >>setter
         8 >>size
@@ -333,6 +312,7 @@ M: long-long-type box-return ( type -- )
     "ulonglong" define-primitive-type
 
     <c-type>
+        integer >>class
         [ alien-signed-cell ] >>getter
         [ set-alien-signed-cell ] >>setter
         bootstrap-cell >>size
@@ -342,6 +322,7 @@ M: long-long-type box-return ( type -- )
     "long" define-primitive-type
 
     <c-type>
+        integer >>class
         [ alien-unsigned-cell ] >>getter
         [ set-alien-unsigned-cell ] >>setter
         bootstrap-cell >>size
@@ -351,6 +332,7 @@ M: long-long-type box-return ( type -- )
     "ulong" define-primitive-type
 
     <c-type>
+        integer >>class
         [ alien-signed-4 ] >>getter
         [ set-alien-signed-4 ] >>setter
         4 >>size
@@ -360,6 +342,7 @@ M: long-long-type box-return ( type -- )
     "int" define-primitive-type
 
     <c-type>
+        integer >>class
         [ alien-unsigned-4 ] >>getter
         [ set-alien-unsigned-4 ] >>setter
         4 >>size
@@ -369,6 +352,7 @@ M: long-long-type box-return ( type -- )
     "uint" define-primitive-type
 
     <c-type>
+        fixnum >>class
         [ alien-signed-2 ] >>getter
         [ set-alien-signed-2 ] >>setter
         2 >>size
@@ -378,6 +362,7 @@ M: long-long-type box-return ( type -- )
     "short" define-primitive-type
 
     <c-type>
+        fixnum >>class
         [ alien-unsigned-2 ] >>getter
         [ set-alien-unsigned-2 ] >>setter
         2 >>size
@@ -387,6 +372,7 @@ M: long-long-type box-return ( type -- )
     "ushort" define-primitive-type
 
     <c-type>
+        fixnum >>class
         [ alien-signed-1 ] >>getter
         [ set-alien-signed-1 ] >>setter
         1 >>size
@@ -396,6 +382,7 @@ M: long-long-type box-return ( type -- )
     "char" define-primitive-type
 
     <c-type>
+        fixnum >>class
         [ alien-unsigned-1 ] >>getter
         [ set-alien-unsigned-1 ] >>setter
         1 >>size
@@ -414,6 +401,7 @@ M: long-long-type box-return ( type -- )
     "bool" define-primitive-type
 
     <c-type>
+        float >>class
         [ alien-float ] >>getter
         [ [ >float ] 2dip set-alien-float ] >>setter
         4 >>size
@@ -425,6 +413,7 @@ M: long-long-type box-return ( type -- )
     "float" define-primitive-type
 
     <c-type>
+        float >>class
         [ alien-double ] >>getter
         [ [ >float ] 2dip set-alien-double ] >>setter
         8 >>size
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
new file mode 100644 (file)
index 0000000..193893f
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.c-types arrays assocs effects grouping kernel
+parser sequences splitting words fry locals ;
+IN: alien.parser
+
+: parse-arglist ( parameters return -- types effect )
+    [ 2 group unzip [ "," ?tail drop ] map ]
+    [ [ { } ] [ 1array ] if-void ]
+    bi* <effect> ;
+
+: function-quot ( return library function types -- quot )
+    '[ _ _ _ _ alien-invoke ] ;
+
+:: define-function ( return library function parameters -- )
+    function create-in dup reset-generic
+    return library function
+    parameters return parse-arglist [ function-quot ] dip
+    define-declared ;
index 70bbe773ee685f85175453933e8cdd5e4f1eaa7b..d4826347726ca15867673f3e9f85c120e9373cd7 100644 (file)
@@ -3,13 +3,13 @@
 USING: arrays sequences kernel accessors math alien.accessors
 alien.c-types byte-arrays words io io.encodings
 io.streams.byte-array io.streams.memory io.encodings.utf8
-io.encodings.utf16 system alien strings cpu.architecture ;
+io.encodings.utf16 system alien strings cpu.architecture fry ;
 IN: alien.strings
 
 GENERIC# alien>string 1 ( c-ptr encoding -- string/f )
 
 M: c-ptr alien>string
-    >r <memory-stream> r> <decoder>
+    [ <memory-stream> ] [ <decoder> ] bi*
     "\0" swap stream-read-until drop ;
 
 M: f alien>string
@@ -40,6 +40,9 @@ PREDICATE: string-type < pair
 
 M: string-type c-type ;
 
+M: string-type c-type-class
+    drop object ;
+
 M: string-type heap-size
     drop "void*" heap-size ;
 
@@ -74,10 +77,10 @@ M: string-type c-type-unboxer
     drop "void*" c-type-unboxer ;
 
 M: string-type c-type-boxer-quot
-    second [ alien>string ] curry [ ] like ;
+    second '[ _ alien>string ] ;
 
 M: string-type c-type-unboxer-quot
-    second [ string>alien ] curry [ ] like ;
+    second '[ _ string>alien ] ;
 
 M: string-type c-type-getter
     drop [ alien-cell ] ;
index 19e5b8c326e17bd8043bd4504d2eabf9b1857548..abce91f56f45ecc86705f76b054beb77394596a0 100644 (file)
@@ -29,10 +29,10 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
     writer>> swap "writing" set-word-prop ;
 
 : reader-word ( class name vocab -- word )
-    >r >r "-" r> 3append r> create ;
+    [ "-" glue ] dip create ;
 
 : writer-word ( class name vocab -- word )
-    >r [ swap "set-" % % "-" % % ] "" make r> create ;
+    [ [ swap "set-" % % "-" % % ] "" make ] dip create ;
 
 : <field-spec> ( struct-name vocab type field-name -- spec )
     field-spec new
@@ -52,25 +52,21 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
         [ (>>offset) ] [ type>> heap-size + ] 2bi
     ] reduce ;
 
-: define-struct-slot-word ( spec word quot -- )
-    rot offset>> prefix define-inline ;
+: define-struct-slot-word ( word quot spec -- )
+    offset>> prefix define-inline ;
 
 : define-getter ( type spec -- )
     [ set-reader-props ] keep
-    [ ]
     [ reader>> ]
     [
         type>>
         [ c-getter ] [ c-type-boxer-quot ] bi append
-    ] tri
-    define-struct-slot-word ;
+    ]
+    [ ] tri define-struct-slot-word ;
 
 : define-setter ( type spec -- )
     [ set-writer-props ] keep
-    [ ]
-    [ writer>> ]
-    [ type>> c-setter ] tri
-    define-struct-slot-word ;
+    [ writer>> ] [ type>> c-setter ] [ ] tri define-struct-slot-word ;
 
 : define-field ( type spec -- )
     [ define-getter ] [ define-setter ] 2bi ;
index 8c7d9f9b29daadaffeb01beede959617e377a848..ec0c01c2e7088dad9054c87e6bb9b267035eea1d 100644 (file)
@@ -38,7 +38,7 @@ C-UNION: barx
 [ 120 ] [ "barx" heap-size ] unit-test
 
 "help" vocab [
-    "help" "help" lookup "help" set
+    "print-topic" "help" lookup "help" set
     [ ] [ \ foox-x "help" get execute ] unit-test
     [ ] [ \ set-foox-x "help" get execute ] unit-test
 ] when
index adb25aa977a33fffcbe8cb330a13d5f8e67175e3..a3c616cda2d8dee7f4d162357af8ead626e8f23c 100644 (file)
@@ -9,6 +9,8 @@ TUPLE: struct-type size align fields ;
 
 M: struct-type heap-size size>> ;
 
+M: struct-type c-type-class drop object ;
+
 M: struct-type c-type-align align>> ;
 
 M: struct-type c-type-stack-align? drop f ;
@@ -36,25 +38,26 @@ M: struct-type stack-size
 
 : c-struct? ( type -- ? ) (c-type) struct-type? ;
 
-: (define-struct) ( name vocab size align fields -- )
-    >r [ align ] keep r>
+: (define-struct) ( name size align fields -- )
+    [ [ align ] keep ] dip
     struct-type boa
-    -rot define-c-type ;
+    swap typedef ;
 
-: define-struct-early ( name vocab fields -- fields )
+: make-fields ( name vocab fields -- fields )
     [ first2 <field-spec> ] with with map ;
 
 : compute-struct-align ( types -- n )
     [ c-type-align ] map supremum ;
 
 : define-struct ( name vocab fields -- )
-    pick >r
-    [ struct-offsets ] keep
-    [ [ type>> ] map compute-struct-align ] keep
-    [ (define-struct) ] keep
-    r> [ swap define-field ] curry each ;
-
-: define-union ( name vocab members -- )
+    [
+        [ 2drop ] [ make-fields ] 3bi
+        [ struct-offsets ] keep
+        [ [ type>> ] map compute-struct-align ] keep
+        [ (define-struct) ] keep
+    ] [ 2drop '[ _ swap define-field ] ] 3bi each ;
+
+: define-union ( name members -- )
     [ expand-constants ] map
     [ [ heap-size ] map supremum ] keep
     compute-struct-align f (define-struct) ;
index 37cbd12801930fd2864c42e056a6ee6a2b1a59b9..586bb974028978b2e78e663c9b6061f21d49d0bf 100644 (file)
@@ -1,5 +1,5 @@
 IN: alien.syntax
-USING: alien alien.c-types alien.structs alien.syntax.private
+USING: alien alien.c-types alien.parser alien.structs
 help.markup help.syntax ;
 
 HELP: DLL"
@@ -54,12 +54,6 @@ HELP: TYPEDEF:
 { $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if ." }
 { $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
 
-HELP: TYPEDEF-IF:
-{ $syntax "TYPEDEF-IF: word old new" }
-{ $values { "word" "a word with stack effect " { $snippet "( -- ? )" } } { "old" "a C type" } { "new" "a C type" } }
-{ $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if " { $snippet "word" } " evaluates to a true value." }
-{ $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
-
 HELP: C-STRUCT:
 { $syntax "C-STRUCT: name pairs... ;" }
 { $values { "name" "a new C type name" } { "pairs" "C type / field name string pairs" } }
@@ -88,7 +82,7 @@ HELP: typedef
 { $description "Alises the C type " { $snippet "old" } " under the name " { $snippet "new" } "." }
 { $notes "Using this word in the same source file which defines C bindings can cause problems, because words are compiled before top-level forms are run. Use the " { $link POSTPONE: TYPEDEF: } " word instead." } ;
 
-{ POSTPONE: TYPEDEF-IF: POSTPONE: TYPEDEF: typedef } related-words
+{ POSTPONE: TYPEDEF: typedef } related-words
 
 HELP: c-struct?
 { $values { "type" "a string" } { "?" "a boolean" } }
index 7629897fc0fa48238ee5651e87f588fc21dfd56c..d10c97cd3ddd15033bd57dcf066e4c1eba48608f 100644 (file)
@@ -4,35 +4,9 @@ USING: accessors arrays alien alien.c-types alien.structs
 alien.arrays alien.strings kernel math namespaces parser
 sequences words quotations math.parser splitting grouping
 effects prettyprint prettyprint.sections prettyprint.backend
-assocs combinators lexer strings.parser ;
+assocs combinators lexer strings.parser alien.parser ;
 IN: alien.syntax
 
-<PRIVATE
-
-: parse-arglist ( return seq -- types effect )
-    2 group dup keys swap values [ "," ?tail drop ] map
-    rot dup "void" = [ drop { } ] [ 1array ] if <effect> ;
-
-: function-quot ( type lib func types -- quot )
-    [ alien-invoke ] 2curry 2curry ;
-
-: define-function ( return library function parameters -- )
-    >r pick r> parse-arglist
-    pick create-in dup reset-generic
-    >r >r function-quot r> r> 
-    -rot define-declared ;
-
-PRIVATE>
-
-: indirect-quot ( function-ptr-quot return types abi -- quot )
-    [ alien-indirect ] 3curry compose ;
-
-: define-indirect ( abi return function-ptr-quot function-name parameters -- )
-    >r pick r> parse-arglist
-    rot create-in dup reset-generic
-    >r >r swapd roll indirect-quot r> r>
-    -rot define-declared ;
-
 : DLL" lexer get skip-blank parse-string dlopen parsed ; parsing
 
 : ALIEN: scan string>number <alien> parsed ; parsing
@@ -49,22 +23,16 @@ PRIVATE>
 : TYPEDEF:
     scan scan typedef ; parsing
 
-: TYPEDEF-IF:
-    scan-word execute scan scan rot [ typedef ] [ 2drop ] if ; parsing
-
 : C-STRUCT:
-    scan in get
-    parse-definition
-    >r 2dup r> define-struct-early
-    define-struct ; parsing
+    scan in get parse-definition define-struct ; parsing
 
 : C-UNION:
-    scan in get parse-definition define-union ; parsing
+    scan parse-definition define-union ; parsing
 
 : C-ENUM:
     ";" parse-tokens
     dup length
-    [ >r create-in r> 1quotation define ] 2each ;
+    [ [ create-in ] dip 1quotation define ] 2each ;
     parsing
 
 M: alien pprint*
index 11601f7b63bf1464de68382ee4ccf3dc55be012c..4cb2032f4f27e8434dc3a8182a0c5efd9501ef79 100644 (file)
@@ -2,7 +2,7 @@
 ! 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
-parser prettyprint.backend ;
+parser prettyprint.backend fry ;
 IN: bit-arrays
 
 TUPLE: bit-array
@@ -24,9 +24,8 @@ TUPLE: bit-array
 : bits>bytes 7 + n>byte ; inline
 
 : (set-bits) ( bit-array n -- )
-    [ [ length bits>cells ] keep ] dip
-    [ -rot underlying>> set-uint-nth ] 2curry
-    each ; inline
+    [ [ length bits>cells ] keep ] dip swap underlying>>
+    '[ [ _ _ ] dip set-alien-unsigned-4 ] each ; inline
 
 PRIVATE>
 
@@ -84,9 +83,9 @@ M: bit-array byte-length length 7 + -3 shift ;
     ] if ;
 
 : bit-array>integer ( bit-array -- n )
-    0 swap underlying>> [ length ] keep [
-        uchar-nth swap 8 shift bitor
-    ] curry each ;
+    0 swap underlying>> dup length [
+        alien-unsigned-1 swap 8 shift bitor
+    ] with each ;
 
 INSTANCE: bit-array sequence
 
index dff9a8db37f2da33682a712da04a1e6961505471..31327999e73fceccb6ecd6c38ee9ff036cfaf3d2 100644 (file)
@@ -4,7 +4,7 @@ USING: tools.test bit-vectors vectors sequences kernel math ;
 [ 0 ] [ 123 <bit-vector> length ] unit-test\r
 \r
 : do-it\r
-    1234 swap [ >r even? r> push ] curry each ;\r
+    1234 swap [ [ even? ] dip push ] curry each ;\r
 \r
 [ t ] [\r
     3 <bit-vector> dup do-it\r
index dabdeea74148d28d25b54d7e9802d6b44bb6c12a..9968af4330e6c3b752b4e117ee7a3b6d57a45eb3 100644 (file)
@@ -60,7 +60,7 @@ nl
 "." write flush
 
 {
-    new-sequence nth push pop peek
+    new-sequence nth push pop peek flip
 } compile-uncompiled
 
 "." write flush
index d5f36db776335c94bfa4ea872aa1c7cddf75fdc6..380c9b2348a5bd61cacf29b0582433e10f9362ac 100644 (file)
@@ -72,7 +72,7 @@ SYMBOL: objects
 : put-object ( n obj -- ) (objects) set-at ;
 
 : cache-object ( obj quot -- value )
-    >r (objects) r> [ obj>> ] prepose cache ; inline
+    [ (objects) ] dip [ obj>> ] prepose cache ; inline
 
 ! Constants
 
@@ -97,10 +97,10 @@ SYMBOL: sub-primitives
     { [ { } make ] [ ] [ ] [ ] } spread 4array ; inline
 
 : jit-define ( quot rc rt offset name -- )
-    >r make-jit r> set ; inline
+    [ make-jit ] dip set ; inline
 
 : define-sub-primitive ( quot rc rt offset word -- )
-    >r make-jit r> sub-primitives get set-at ;
+    [ make-jit ] dip sub-primitives get set-at ;
 
 ! The image being constructed; a vector of word-size integers
 SYMBOL: image
@@ -124,10 +124,10 @@ SYMBOL: jit-primitive-word
 SYMBOL: jit-primitive
 SYMBOL: jit-word-jump
 SYMBOL: jit-word-call
-SYMBOL: jit-push-literal
 SYMBOL: jit-push-immediate
 SYMBOL: jit-if-word
-SYMBOL: jit-if-jump
+SYMBOL: jit-if-1
+SYMBOL: jit-if-2
 SYMBOL: jit-dispatch-word
 SYMBOL: jit-dispatch
 SYMBOL: jit-dip-word
@@ -155,9 +155,9 @@ SYMBOL: undefined-quot
         { jit-primitive 25 }
         { jit-word-jump 26 }
         { jit-word-call 27 }
-        { jit-push-literal 28 }
-        { jit-if-word 29 }
-        { jit-if-jump 30 }
+        { jit-if-word 28 }
+        { jit-if-1 29 }
+        { jit-if-2 30 }
         { jit-dispatch-word 31 }
         { jit-dispatch 32 }
         { jit-epilog 33 }
@@ -205,7 +205,7 @@ SYMBOL: undefined-quot
 : emit-fixnum ( n -- ) tag-fixnum emit ;
 
 : emit-object ( header tag quot -- addr )
-    swap here-as >r swap tag-fixnum emit call align-here r> ;
+    swap here-as [ swap tag-fixnum emit call align-here ] dip ;
     inline
 
 ! Write an object to the image.
@@ -351,7 +351,12 @@ M: wrapper '
 : pad-bytes ( seq -- newseq )
     dup length bootstrap-cell align 0 pad-right ;
 
+: check-string ( string -- )
+    [ 127 > ] contains?
+    [ "Bootstrap cannot emit non-ASCII strings" throw ] when ;
+
 : emit-string ( string -- ptr )
+    dup check-string
     string type-number object tag-number [
         dup length emit-fixnum
         f ' emit
@@ -469,10 +474,10 @@ M: quotation '
         jit-primitive
         jit-word-jump
         jit-word-call
-        jit-push-literal
         jit-push-immediate
         jit-if-word
-        jit-if-jump
+        jit-if-1
+        jit-if-2
         jit-dispatch-word
         jit-dispatch
         jit-dip-word
index ac8e5343e1eb4c94ca0383f5632cb0810c7ce415..4ab36ec94e9361a6efbf23a2a2550416735c9738 100644 (file)
@@ -32,8 +32,8 @@ SYMBOL: bootstrap-time
 : count-words ( pred -- )
     all-words swap count number>string write ;
 
-: print-time ( us -- )
-    1000000 /i
+: print-time ( ms -- )
+    1000 /i
     60 /mod swap
     number>string write
     " minutes and " write number>string write " seconds." print ;
@@ -52,16 +52,16 @@ SYMBOL: bootstrap-time
 
 [
     ! We time bootstrap
-    micros
+    millis
 
     default-image-name "output-image" set-global
 
     "math compiler threads help io tools ui ui.tools unicode handbook" "include" set-global
     "" "exclude" set-global
 
-    parse-command-line
+    (command-line) parse-command-line
 
-    "-no-crossref" cli-args member? [ do-crossref ] unless
+    do-crossref
 
     ! Set dll paths
     os wince? [ "windows.ce" require ] when
@@ -77,7 +77,7 @@ SYMBOL: bootstrap-time
     [
         load-components
 
-        micros over - core-bootstrap-time set-global
+        millis over - core-bootstrap-time set-global
 
         run-bootstrap-init
     ] with-compiler-errors
@@ -92,15 +92,10 @@ SYMBOL: bootstrap-time
         [
             boot
             do-init-hooks
-            [
-                parse-command-line
-                run-user-init
-                "run" get run
-                output-stream get [ stream-flush ] when*
-            ] [ print-error 1 exit ] recover
+            handle-command-line
         ] set-boot-quot
 
-        micros swap - bootstrap-time set-global
+        millis swap - bootstrap-time set-global
         print-report
 
         "output-image" get save-image-and-exit
index 9e2e8a4673a788ab744da1497f5c57ce95e43d91..39f8eb44cc354c3a68e19396a0dd69943e21d963 100644 (file)
@@ -23,4 +23,4 @@ ERROR: box-empty box ;
     dup occupied>> [ box> t ] [ drop f f ] if ;\r
 \r
 : if-box? ( box quot -- )\r
-    >r ?box r> [ drop ] if ; inline\r
+    [ ?box ] dip [ drop ] if ; inline\r
index 433459cb24457823fd5b61c253f88132580c0d19..748f9d124c0a7ad3fdd5e5ba91d3997daef27997 100644 (file)
@@ -99,6 +99,48 @@ HELP: seconds-per-year
 { $values { "integer" integer } }
 { $description "Returns the number of seconds in a year averaged over 400 years. Used internally for adding an arbitrary real number of seconds to a timestamp." } ;
 
+HELP: biweekly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of two week periods in a year." } ;
+
+HELP: daily-360
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of days in a 360-day year." } ;
+
+HELP: daily-365
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of days in a 365-day year." } ;
+
+HELP: monthly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of months in a year." } ;
+
+HELP: semimonthly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of half-months in a year. Note that biweekly has two more periods than semimonthly." } ;
+
+HELP: weekly
+{ $values
+     { "x" number }
+     { "y" number }
+}
+{ $description "Divides a number by the number of weeks in a year." } ;
+
 HELP: julian-day-number
 { $values { "year" integer } { "month" integer } { "day" integer } { "n" integer } }
 { $description "Calculates the Julian day number from a year, month, and day.  The difference between two Julian day numbers is the number of days that have elapsed between the two corresponding dates." }
@@ -540,6 +582,8 @@ ARTICLE: "calendar" "Calendar"
 { $subsection "years" }
 { $subsection "months" }
 { $subsection "days" }
+"Calculating amounts per period of time:"
+{ $subsection "time-period-calculations" }
 "Meta-data about the calendar:"
 { $subsection "calendar-facts" }
 ;
@@ -626,6 +670,18 @@ ARTICLE: "calendar-facts" "Calendar facts"
 { $subsection day-of-week }
 ;
 
+ARTICLE: "time-period-calculations" "Calculations over periods of time"
+{ $subsection monthly }
+{ $subsection semimonthly }
+{ $subsection biweekly }
+{ $subsection weekly }
+{ $subsection daily-360 }
+{ $subsection daily-365 }
+{ $subsection biweekly }
+{ $subsection biweekly }
+{ $subsection biweekly }
+;
+
 ARTICLE: "years" "Year operations"
 "Leap year predicate:"
 { $subsection leap-year? }
index 00d5730745728979aa94b2e49007e9e0f7327e07..943ba8c3d56eccb35a1f089f5d56a286e914e580 100644 (file)
@@ -167,3 +167,5 @@ IN: calendar.tests
 [ t ] [ now 50 milliseconds sleep now before? ] unit-test
 [ t ] [ now 50 milliseconds sleep now swap after? ] unit-test
 [ t ] [ now 50 milliseconds sleep now 50 milliseconds sleep now swapd between? ] unit-test
+
+[ 4+1/6 ] [ 100 semimonthly ] unit-test
index a78cf60eb0147d204966fbf8c5783df5ba639f47..e2564b5a28874f7294cb130b4eee0031aea16fa9 100644 (file)
@@ -89,6 +89,13 @@ PRIVATE>
 : minutes-per-year ( -- ratio ) 5259492/10 ; inline
 : seconds-per-year ( -- integer ) 31556952 ; inline
 
+: monthly ( x -- y ) 12 / ; inline
+: semimonthly ( x -- y ) 24 / ; inline
+: biweekly ( x -- y ) 26 / ; inline
+: weekly ( x -- y ) 52 / ; inline
+: daily-360 ( x -- y ) 360 / ; inline
+: daily-365 ( x -- y ) 365 / ; inline
+
 :: julian-day-number ( year month day -- n )
     #! Returns a composite date number
     #! Not valid before year -4800
@@ -173,7 +180,7 @@ M: real +year ( timestamp n -- timestamp )
     12 /rem dup zero? [ drop 1- 12 ] when swap ; inline
 
 M: integer +month ( timestamp n -- timestamp )
-    [ over month>> + months/years >r >>month r> +year ] unless-zero ;
+    [ over month>> + months/years [ >>month ] dip +year ] unless-zero ;
 
 M: real +month ( timestamp n -- timestamp )
     [ float>whole-part swapd average-month * +day swap +month ] unless-zero ;
@@ -181,7 +188,7 @@ M: real +month ( timestamp n -- timestamp )
 M: integer +day ( timestamp n -- timestamp )
     [
         over >date< julian-day-number + julian-day-number>date
-        >r >r >>year r> >>month r> >>day
+        [ >>year ] [ >>month ] [ >>day ] tri*
     ] unless-zero ;
 
 M: real +day ( timestamp n -- timestamp )
@@ -191,7 +198,7 @@ M: real +day ( timestamp n -- timestamp )
     24 /rem swap ;
 
 M: integer +hour ( timestamp n -- timestamp )
-    [ over hour>> + hours/days >r >>hour r> +day ] unless-zero ;
+    [ over hour>> + hours/days [ >>hour ] dip +day ] unless-zero ;
 
 M: real +hour ( timestamp n -- timestamp )
     float>whole-part swapd 60 * +minute swap +hour ;
@@ -200,7 +207,7 @@ M: real +hour ( timestamp n -- timestamp )
     60 /rem swap ;
 
 M: integer +minute ( timestamp n -- timestamp )
-    [ over minute>> + minutes/hours >r >>minute r> +hour ] unless-zero ;
+    [ over minute>> + minutes/hours [ >>minute ] dip +hour ] unless-zero ;
 
 M: real +minute ( timestamp n -- timestamp )
     [ float>whole-part swapd 60 * +second swap +minute ] unless-zero ;
@@ -209,7 +216,7 @@ M: real +minute ( timestamp n -- timestamp )
     60 /rem swap >integer ;
 
 M: number +second ( timestamp n -- timestamp )
-    [ over second>> + seconds/minutes >r >>second r> +minute ] unless-zero ;
+    [ over second>> + seconds/minutes [ >>second ] dip +minute ] unless-zero ;
 
 : (time+)
     [ second>> +second ] keep
@@ -226,7 +233,7 @@ PRIVATE>
 GENERIC# time+ 1 ( time1 time2 -- time3 )
 
 M: timestamp time+
-    >r clone r> (time+) drop ;
+    [ clone ] dip (time+) drop ;
 
 M: duration time+
     dup timestamp? [
@@ -284,7 +291,7 @@ M: timestamp <=> ( ts1 ts2 -- n )
 : (time-) ( timestamp timestamp -- n )
     [ >gmt ] bi@
     [ [ >date< julian-day-number ] bi@ - 86400 * ] 2keep
-    [ >time< >r >r 3600 * r> 60 * r> + + ] bi@ - + ;
+    [ >time< [ [ 3600 * ] [ 60 * ] bi* ] dip + + ] bi@ - + ;
 
 M: timestamp time-
     #! Exact calendar-time difference
@@ -320,13 +327,13 @@ M: duration time-
     1970 1 1 0 0 0 instant <timestamp> ;
 
 : millis>timestamp ( x -- timestamp )
-    >r unix-1970 r> milliseconds time+ ;
+    [ unix-1970 ] dip milliseconds time+ ;
 
 : timestamp>millis ( timestamp -- n )
     unix-1970 (time-) 1000 * >integer ;
 
 : micros>timestamp ( x -- timestamp )
-    >r unix-1970 r> microseconds time+ ;
+    [ unix-1970 ] dip microseconds time+ ;
 
 : timestamp>micros ( timestamp -- n )
     unix-1970 (time-) 1000000 * >integer ;
@@ -343,10 +350,11 @@ M: duration time-
     #! Zeller Congruence
     #! http://web.textfiles.com/computers/formulas.txt
     #! good for any date since October 15, 1582
-    >r dup 2 <= [ 12 + >r 1- r> ] when
-    >r dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + r>
-        [ 1+ 3 * 5 /i + ] keep 2 * + r>
-    1+ + 7 mod ;
+    [
+        dup 2 <= [ [ 1- ] [ 12 + ] bi* ] when
+        [ dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + ] dip
+        [ 1+ 3 * 5 /i + ] keep 2 * +
+    ] dip 1+ + 7 mod ;
 
 GENERIC: days-in-year ( obj -- n )
 
index b15da4240998ddd4ffeca4b9dbba53a347ec4a7c..8d34e8a3a4ee15dc76dc74d109227bd5ba4644b1 100644 (file)
@@ -138,11 +138,11 @@ M: timestamp year. ( timestamp -- )
 \r
 : read-rfc3339-gmt-offset ( ch -- dt )\r
     dup CHAR: Z = [ drop instant ] [\r
-        >r\r
-        read-00 hours\r
-        read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes\r
-        time+\r
-        r> signed-gmt-offset\r
+        [\r
+            read-00 hours\r
+            read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes\r
+            time+\r
+        ] dip signed-gmt-offset\r
     ] if ;\r
 \r
 : read-ymd ( -- y m d )\r
@@ -152,8 +152,9 @@ M: timestamp year. ( timestamp -- )
     read-00 ":" expect read-00 ":" expect read-00 ;\r
 \r
 : read-rfc3339-seconds ( s -- s' ch )\r
-    "+-Z" read-until >r\r
-    [ string>number ] [ length 10 swap ^ ] bi / + r> ;\r
+    "+-Z" read-until [\r
+        [ string>number ] [ length 10 swap ^ ] bi / +\r
+    ] dip ;\r
 \r
 : (rfc3339>timestamp) ( -- timestamp )\r
     read-ymd\r
@@ -181,9 +182,9 @@ ERROR: invalid-timestamp-format ;
 \r
 : parse-rfc822-gmt-offset ( string -- dt )\r
     dup "GMT" = [ drop instant ] [\r
-        unclip >r\r
-        2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+\r
-        r> signed-gmt-offset\r
+        unclip \r
+            2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+\r
+        ] dip signed-gmt-offset\r
     ] if ;\r
 \r
 : (rfc822>timestamp) ( -- timestamp )\r
index 1a7addac12583fcb5646e529951d40336f76db7a..6e10b23407f2630eda925ac253e889774a6a76ae 100644 (file)
@@ -14,7 +14,7 @@ IN: channels.remote
 PRIVATE>
 
 : publish ( channel -- id )
-    256 random-bits dup >r remote-channels set-at r> ;
+    256 random-bits dup [ remote-channels set-at ] dip ;
 
 : get-channel ( id -- channel )
     remote-channels at ;
index 1f25efef24c72e6a5c03de1a3790bed5d902a642..7d5f34777d74acc1f3de92d279272cda19e6ee94 100644 (file)
@@ -18,4 +18,4 @@ SYMBOL: bytes-read
     ] "" make 64 group ;
 
 : update-old-new ( old new -- )
-    [ get >r get r> ] 2keep >r >r w+ dup r> set r> set ; inline
+    [ [ get ] bi@ w+ dup ] 2keep [ set ] bi@ ; inline
index 6158254f84a589ac420a7196289b27095e0e6ba6..257fd930c46c08818d5d0830b50c4103c98f5d0c 100644 (file)
@@ -14,7 +14,7 @@ IN: checksums.md5
 SYMBOLS: a b c d old-a old-b old-c old-d ;
 
 : T ( N -- Y )
-    sin abs 4294967296 * >bignum ; foldable
+    sin abs 4294967296 * >integer ; foldable
 
 : initialize-md5 ( -- )
     0 bytes-read set
index d42febb541e15128edb62422b007ea7236ebf9f9..821cbe2f3afe282195aacc66dbd075cdb8d7e0c5 100644 (file)
@@ -28,7 +28,7 @@ M: evp-md-context dispose
     handle>> EVP_MD_CTX_cleanup drop ;
 
 : with-evp-md-context ( quot -- )
-    maybe-init-ssl >r <evp-md-context> r> with-disposal ; inline
+    maybe-init-ssl [ <evp-md-context> ] dip with-disposal ; inline
 
 : digest-named ( name -- md )
     dup EVP_get_digestbyname
index bbae421b16fe0d1d86e86c9d44e3be955ec8a5d7..3767af7c5590877907c9882380c8e58352e6edf6 100644 (file)
@@ -41,9 +41,9 @@ SYMBOLS: h0 h1 h2 h3 h4 A B C D E w K ;
 : sha1-f ( B C D t -- f_tbcd )
     20 /i
     {   
-        { 0 [ >r over bitnot r> bitand >r bitand r> bitor ] }
+        { 0 [ [ over bitnot ] dip bitand [ bitand ] dip bitor ] }
         { 1 [ bitxor bitxor ] }
-        { 2 [ 2dup bitand >r pick bitand >r bitand r> r> bitor bitor ] }
+        { 2 [ 2dup bitand [ pick bitand [ bitand ] dip ] dip bitor bitor ] }
         { 3 [ bitxor bitxor ] }
     } case ;
 
index 0a6d8c26ab335c53b69f1af41e9da3e18355d766..beb657bd3e1ab5b0b332ca64805e0f85959ebd7e 100644 (file)
@@ -59,7 +59,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ 15 - swap nth s0-256 ] 2keep
     [ 7 - swap nth ] 2keep
     [ 2 - swap nth s1-256 ] 2keep
-    >r >r + + w+ r> r> swap set-nth ; inline
+    [ + + w+ ] 2dip swap set-nth ; inline
 
 : prepare-message-schedule ( seq -- w-seq )
     word-size get group [ be> ] map block-size get 0 pad-right
@@ -71,7 +71,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ bitxor bitand ] keep bitxor ;
 
 : maj ( x y z -- x' )
-    >r [ bitand ] 2keep bitor r> bitand bitor ;
+    [ [ bitand ] 2keep bitor ] dip bitand bitor ;
 
 : S0-256 ( x -- x' )
     [ -2 bitroll-32 ] keep
@@ -83,7 +83,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     [ -11 bitroll-32 ] keep
     -25 bitroll-32 bitxor bitxor ; inline
 
-: slice3 ( n seq -- a b c ) >r dup 3 + r> <slice> first3 ; inline
+: slice3 ( n seq -- a b c ) [ dup 3 + ] dip <slice> first3 ; inline
 
 : T1 ( W n -- T1 )
     [ swap nth ] keep
@@ -105,7 +105,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
     d c pick exchange
     c b pick exchange
     b a pick exchange
-    >r w+ a r> set-nth ;
+    [ w+ a ] dip set-nth ;
 
 : process-chunk ( M -- )
     H get clone vars set
@@ -118,7 +118,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
 
 : preprocess-plaintext ( string big-endian? -- padded-string )
     #! pad 0x80 then 00 til 8 bytes left, then 64bit length in bits
-    >r >sbuf r> over [
+    [ >sbuf ] dip over [
         HEX: 80 ,
         dup length HEX: 3f bitand
         calculate-pad-length 0 <string> %
index 8f32782d765dc01055fd8f7f1d2506dbb40e4e17..ab12a93a31b86407a5746088bb19c53ee1bbda63 100644 (file)
@@ -27,35 +27,31 @@ IN: cocoa.application
 
 : NSApp ( -- app ) NSApplication -> sharedApplication ;
 
+: NSAnyEventMask ( -- mask ) HEX: ffffffff ; inline
+
 FUNCTION: void NSBeep ( ) ;
 
 : with-cocoa ( quot -- )
     [ NSApp drop call ] with-autorelease-pool ; inline
 
 : next-event ( app -- event )
-    0 f CFRunLoopDefaultMode 1
+    NSAnyEventMask f CFRunLoopDefaultMode 1
     -> nextEventMatchingMask:untilDate:inMode:dequeue: ;
 
 : do-event ( app -- ? )
-    dup next-event [ -> sendEvent: t ] [ drop f ] if* ;
+    dup next-event [ dupd -> sendEvent: -> updateWindows t ] [ drop f ] if* ;
 
 : add-observer ( observer selector name object -- )
-    >r >r >r >r NSNotificationCenter -> defaultCenter
-    r> r> sel_registerName
-    r> r> -> addObserver:selector:name:object: ;
+    [
+        [ NSNotificationCenter -> defaultCenter ] 2dip
+        sel_registerName
+    ] 2dip -> addObserver:selector:name:object: ;
 
 : remove-observer ( observer -- )
-    >r NSNotificationCenter -> defaultCenter r>
+    [ NSNotificationCenter -> defaultCenter ] dip
     -> removeObserver: ;
 
-: finish-launching ( -- ) NSApp -> finishLaunching ;
-
-: cocoa-app ( quot -- )
-    [
-        call
-        finish-launching
-        NSApp -> run
-    ] with-cocoa ; inline
+: cocoa-app ( quot -- ) [ call NSApp -> run ] with-cocoa ; inline
 
 : install-delegate ( receiver delegate -- )
     -> alloc -> init -> setDelegate: ;
@@ -80,6 +76,6 @@ M: objc-error summary ( error -- )
     running.app? [
         drop
     ] [
-        "The " swap " requires you to run Factor from an application bundle."
-        3append throw
+        "The " " requires you to run Factor from an application bundle."
+        surround throw
     ] if ;
index e1d6672872467432a5279ab080cb88bd80b58b4b..59ea91c3cfb87bbcca8ec0015ac07f09e35cee85 100644 (file)
@@ -1,7 +1,7 @@
 IN: cocoa.tests
 USING: cocoa cocoa.messages cocoa.subclassing cocoa.types
 compiler kernel namespaces cocoa.classes tools.test memory
-compiler.units ;
+compiler.units math ;
 
 CLASS: {
     { +superclass+ "NSObject" }
@@ -45,3 +45,27 @@ Bar [
 [ 2.0 ] [ "x" get NSRect-y ] unit-test
 [ 101.0 ] [ "x" get NSRect-w ] unit-test
 [ 102.0 ] [ "x" get NSRect-h ] unit-test
+
+! Make sure that we can add methods
+CLASS: {
+    { +superclass+ "NSObject" }
+    { +name+ "Bar" }
+} {
+    "bar"
+    "NSRect"
+    { "id" "SEL" }
+    [ 2drop test-foo "x" get ]
+} {
+    "babb"
+    "int"
+    { "id" "SEL" "int" }
+    [ 2nip sq ]
+} ;
+
+[ 144 ] [
+    Bar [
+        -> alloc -> init
+        dup 12 -> babb
+        swap -> release
+    ] compile-call
+] unit-test
index 662b4a7bae784f481dd92e5cf94434318185e87c..2b01c5d751215eced96995d3e87779e27f7c4930 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel cocoa cocoa.messages cocoa.classes
 cocoa.application sequences splitting core-foundation ;
@@ -29,6 +29,6 @@ IN: cocoa.dialogs
     "/" split1-last [ <NSString> ] bi@ ;
 
 : save-panel ( path -- paths )
-    <NSSavePanel> dup
-    rot split-path -> runModalForDirectory:file: NSOKButton =
+    [ <NSSavePanel> dup ] dip
+    split-path -> runModalForDirectory:file: NSOKButton =
     [ -> filename CF>string ] [ drop f ] if ;
index 7de1f24a3c6e04b1f0c57e287675a0e268d6cf6b..7f5b77728332eda4941093f4db1308abdd5d8f0c 100644 (file)
@@ -1,26 +1,31 @@
-USING: kernel cocoa cocoa.types alien.c-types locals math sequences
-vectors fry libc ;
+! Copyright (C) 2008 Joe Groff.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel cocoa cocoa.types alien.c-types locals math
+sequences vectors fry libc destructors
+specialized-arrays.direct.alien ;
 IN: cocoa.enumeration
 
 : NS-EACH-BUFFER-SIZE 16 ; inline
 
-: (with-enumeration-buffers) ( quot -- )
-    "NSFastEnumerationState" heap-size swap '[
-        NS-EACH-BUFFER-SIZE "id" heap-size * [
-            NS-EACH-BUFFER-SIZE @
-        ] with-malloc
-    ] with-malloc ; inline
+: with-enumeration-buffers ( quot -- )
+    [
+        [
+            "NSFastEnumerationState" malloc-object &free
+            NS-EACH-BUFFER-SIZE "id" heap-size * malloc-object &free
+            NS-EACH-BUFFER-SIZE
+        ] dip call
+    ] with-destructors ; inline
 
 :: (NSFastEnumeration-each) ( object quot: ( elt -- ) state stackbuf count -- )
     object state stackbuf count -> countByEnumeratingWithState:objects:count:
-    dup zero? [ drop ] [
+    dup 0 = [ drop ] [
         state NSFastEnumerationState-itemsPtr [ stackbuf ] unless*
-        '[ _ void*-nth quot call ] each
+        swap <direct-void*-array> quot each
         object quot state stackbuf count (NSFastEnumeration-each)
     ] if ; inline recursive
 
 : NSFastEnumeration-each ( object quot -- )
-    [ (NSFastEnumeration-each) ] (with-enumeration-buffers) ; inline
+    [ (NSFastEnumeration-each) ] with-enumeration-buffers ; inline
 
 : NSFastEnumeration-map ( object quot -- vector )
     NS-EACH-BUFFER-SIZE <vector>
index 09b225591359a19e098084977ea1ce5594e3524a..e33217a691cc9d35478c2b824debb7130e5363cd 100644 (file)
@@ -1,11 +1,12 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.c-types alien.strings arrays assocs
-combinators compiler compiler.alien kernel math namespaces make
-parser prettyprint prettyprint.sections quotations sequences
-strings words cocoa.runtime io macros memoize debugger
-io.encodings.ascii effects libc libc.private parser lexer init
-core-foundation fry ;
+continuations combinators compiler compiler.alien kernel math
+namespaces make parser prettyprint prettyprint.sections
+quotations sequences strings words cocoa.runtime io macros
+memoize debugger io.encodings.ascii effects libc libc.private
+parser lexer init core-foundation fry generalizations
+specialized-arrays.direct.alien ;
 IN: cocoa.messages
 
 : make-sender ( method function -- quot )
@@ -27,7 +28,7 @@ super-message-senders global [ H{ } assoc-like ] change-at
 
 : cache-stub ( method function hash -- )
     [
-        over get [ 2drop ] [ over >r sender-stub r> set ] if
+        over get [ 2drop ] [ over [ sender-stub ] dip set ] if
     ] bind ;
 
 : cache-stubs ( method -- )
@@ -37,7 +38,7 @@ super-message-senders global [ H{ } assoc-like ] change-at
 
 : <super> ( receiver -- super )
     "objc-super" <c-object> [
-        >r dup object_getClass class_getSuperclass r>
+        [ dup object_getClass class_getSuperclass ] dip
         set-objc-super-class
     ] keep
     [ set-objc-super-receiver ] keep ;
@@ -62,23 +63,18 @@ objc-methods global [ H{ } assoc-like ] change-at
     dup objc-methods get at
     [ ] [ "No such method: " prepend throw ] ?if ;
 
-: make-dip ( quot n -- quot' )
-    dup
-    \ >r <repetition> >quotation -rot
-    \ r> <repetition> >quotation 3append ;
-
 MEMO: make-prepare-send ( selector method super? -- quot )
     [
         [ \ <super> , ] when
         swap <selector> , \ selector ,
     ] [ ] make
-    swap second length 2 - make-dip ;
+    swap second length 2 - '[ _ _ ndip ] ;
 
 MACRO: (send) ( selector super? -- quot )
-    >r dup lookup-method r>
+    [ dup lookup-method ] dip
     [ make-prepare-send ] 2keep
     super-message-senders message-senders ? get at
-    [ slip execute ] 2curry ;
+    '[ _ call _ execute ] ;
 
 : send ( receiver args... selector -- return... ) f (send) ; inline
 
@@ -89,9 +85,17 @@ MACRO: (send) ( selector super? -- quot )
 \ super-send soft "break-after" set-word-prop
 
 ! Runtime introspection
-: (objc-class) ( string word -- class )
-    dupd execute
-    [ ] [ "No such class: " prepend throw ] ?if ; inline
+SYMBOL: class-init-hooks
+
+class-init-hooks global [ H{ } clone or ] change-at
+
+: (objc-class) ( name word -- class )
+    2dup execute dup [ 2nip ] [
+        drop over class-init-hooks get at [ assert-depth ] when*
+        2dup execute dup [ 2nip ] [
+            2drop "No such class: " prepend throw
+        ] if
+    ] if ; inline
 
 : objc-class ( string -- class )
     \ objc_getClass (objc-class) ;
@@ -165,14 +169,14 @@ objc>alien-types get [ swap ] assoc-map
 assoc-union alien>objc-types set-global
 
 : objc-struct-type ( i string -- ctype )
-    2dup CHAR: = -rot index-from swap subseq
+    [ CHAR: = ] 2keep index-from swap subseq
     dup c-types get key? [
         "Warning: no such C type: " write dup print
         drop "void*"
     ] unless ;
 
 : (parse-objc-type) ( i string -- ctype )
-    2dup nth >r >r 1+ r> r> {
+    [ [ 1+ ] dip ] [ nth ] 2bi {
         { [ dup "rnNoORV" member? ] [ drop (parse-objc-type) ] }
         { [ dup CHAR: ^ = ] [ 3drop "void*" ] }
         { [ dup CHAR: { = ] [ drop objc-struct-type ] }
@@ -203,8 +207,11 @@ assoc-union alien>objc-types set-global
     objc-methods get set-at ;
 
 : each-method-in-class ( class quot -- )
-    [ 0 <uint> [ class_copyMethodList ] keep *uint over ] dip
-    '[ _ void*-nth @ ] each (free) ; inline
+    [ 0 <uint> [ class_copyMethodList ] keep *uint ] dip
+    over 0 = [ 3drop ] [
+        [ <direct-void*-array> ] dip
+        [ each ] [ drop underlying>> (free) ] 2bi
+    ] if ; inline
 
 : register-objc-methods ( class -- )
     [ register-objc-method ] each-method-in-class ;
@@ -222,23 +229,20 @@ assoc-union alien>objc-types set-global
 
 : class-exists? ( string -- class ) objc_getClass >boolean ;
 
-: unless-defined ( class quot -- )
-    >r class-exists? r> unless ; inline
-
-: define-objc-class-word ( name quot -- )
+: define-objc-class-word ( quot name -- )
+    [ class-init-hooks get set-at ]
     [
-        over , , \ unless-defined , dup , \ objc-class ,
-    ] [ ] make >r "cocoa.classes" create r>
-    (( -- class )) define-declared ;
+        [ "cocoa.classes" create ] [ '[ _ objc-class ] ] bi
+        (( -- class )) define-declared
+    ] bi ;
 
 : import-objc-class ( name quot -- )
-    2dup unless-defined
-    dupd define-objc-class-word
-    [
-        dup
-        objc-class register-objc-methods
-        objc-meta-class register-objc-methods
-    ] curry try ;
+    over define-objc-class-word
+    '[
+        _
+        [ objc-class register-objc-methods ]
+        [ objc-meta-class register-objc-methods ] bi
+    ] try ;
 
 : root-class ( class -- root )
     dup class_getSuperclass [ root-class ] [ ] ?if ;
index d266c2452f849d0ad10e7d2fceffa3071a7bd8e0..b530ccbc3760620e0e1abb1a70d1f35efbe58c3b 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2006, 2007 Slava Pestov.
+! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types arrays kernel cocoa.messages
-cocoa.classes cocoa.application cocoa core-foundation
-sequences ;
+USING: alien.accessors arrays kernel cocoa.messages
+cocoa.classes cocoa.application cocoa core-foundation sequences
+;
 IN: cocoa.pasteboard
 
 : NSStringPboardType "NSStringPboardType" ;
@@ -20,11 +20,11 @@ IN: cocoa.pasteboard
 : set-pasteboard-string ( str pasteboard -- )
     NSStringPboardType <NSString>
     dup 1array pick set-pasteboard-types
-    >r swap <NSString> r> -> setString:forType: drop ;
+    [ swap <NSString> ] dip -> setString:forType: drop ;
 
 : pasteboard-error ( error -- f )
     "Pasteboard does not hold a string" <NSString>
-    0 spin set-void*-nth f ;
+    0 set-alien-cell f ;
 
 : ?pasteboard-string ( pboard error -- str/f )
     over pasteboard-string? [
index fd18c7fa89d738e07c95d3831fd8b238e8e0f6a4..b49d55a30b51a3ef884648e4f88a068dd4c53be7 100644 (file)
@@ -1,10 +1,9 @@
-! Copyright (C) 2006, 2008 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings arrays assocs
 combinators compiler hashtables kernel libc math namespaces
-parser sequences words cocoa.messages cocoa.runtime
-compiler.units io.encodings.ascii generalizations
-continuations make ;
+parser sequences words cocoa.messages cocoa.runtime locals
+compiler.units io.encodings.ascii continuations make fry ;
 IN: cocoa.subclassing
 
 : init-method ( method -- sel imp types )
@@ -12,22 +11,25 @@ IN: cocoa.subclassing
     [ sel_registerName ] [ execute ] [ ascii string>alien ]
     tri* ;
 
-: throw-if-false ( YES/NO -- )
-    zero? [ "Failed to add method or protocol to class" throw ]
-    when ;
+: throw-if-false ( obj what -- )
+    swap { f 0 } member?
+    [ "Failed to " prepend throw ] [ drop ] if ;
+
+: add-method ( class sel imp types -- )
+    class_addMethod "add method to class" throw-if-false ;
 
 : add-methods ( methods class -- )
-    swap
-    [ init-method class_addMethod throw-if-false ] with each ;
+    '[ [ _ ] dip init-method add-method ] each ;
+
+: add-protocol ( class protocol -- )
+    class_addProtocol "add protocol to class" throw-if-false ;
 
 : add-protocols ( protocols class -- )
-    swap [ objc-protocol class_addProtocol throw-if-false ]
-    with each ;
+    '[ [ _ ] dip objc-protocol add-protocol ] each ;
 
-: (define-objc-class) ( protocols superclass name imeth -- )
-    -rot
+: (define-objc-class) ( imeth protocols superclass name -- )
     [ objc-class ] dip 0 objc_allocateClassPair
-    [ add-methods ] [ add-protocols ] [ objc_registerClassPair ]
+    [ add-protocols ] [ add-methods ] [ objc_registerClassPair ]
     tri ;
 
 : encode-types ( return types -- encoding )
@@ -36,7 +38,7 @@ IN: cocoa.subclassing
     ] map concat ;
 
 : prepare-method ( ret types quot -- type imp )
-    >r [ encode-types ] 2keep r> [
+    [ [ encode-types ] 2keep ] dip [
         "cdecl" swap 4array % \ alien-callback ,
     ] [ ] make define-temp ;
 
@@ -45,28 +47,19 @@ IN: cocoa.subclassing
         [ first4 prepare-method 3array ] map
     ] with-compilation-unit ;
 
-: types= ( a b -- ? )
-    [ ascii alien>string ] bi@ = ;
-
-: (verify-method-type) ( class sel types -- )
-    [ class_getInstanceMethod method_getTypeEncoding ]
-    dip types=
-    [ "Objective-C method types cannot be changed once defined" throw ]
-    unless ;
-: verify-method-type ( class sel imp types -- class sel imp types )
-    4 ndup nip (verify-method-type) ;
-
-: (redefine-objc-method) ( class method -- )
-    init-method ! verify-method-type
-    drop
-    [ class_getInstanceMethod ] dip method_setImplementation drop ;
+:: (redefine-objc-method) ( class method -- )
+    method init-method [| sel imp types |
+        class sel class_getInstanceMethod [
+            imp method_setImplementation drop
+        ] [
+            class sel imp types add-method
+        ] if*
+    ] call ;
     
 : redefine-objc-methods ( imeth name -- )
     dup class-exists? [
-        objc_getClass swap [ (redefine-objc-method) ] with each
-    ] [
-        2drop
-    ] if ;
+        objc_getClass '[ [ _ ] dip (redefine-objc-method) ] each
+    ] [ 2drop ] if ;
 
 SYMBOL: +name+
 SYMBOL: +protocols+
@@ -76,10 +69,10 @@ SYMBOL: +superclass+
     clone [
         prepare-methods
         +name+ get "cocoa.classes" create drop
-        +name+ get 2dup redefine-objc-methods swap [
-            +protocols+ get , +superclass+ get , +name+ get , ,
-            \ (define-objc-class) ,
-        ] [ ] make import-objc-class
+        +name+ get 2dup redefine-objc-methods swap
+        +protocols+ get +superclass+ get +name+ get
+        '[ _ _ _ _ (define-objc-class) ]
+        import-objc-class
     ] bind ;
 
 : CLASS:
index d03688b2be701cc2c865e8fed622a7955de20854..be67f03184e12347b8596f897c6c3c8ce16b1663 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types arrays kernel math namespaces make cocoa
-cocoa.messages cocoa.classes cocoa.types sequences
-continuations ;
+USING: specialized-arrays.int arrays kernel math namespaces make
+cocoa cocoa.messages cocoa.classes cocoa.types sequences
+continuations accessors ;
 IN: cocoa.views
 
 : NSOpenGLPFAAllRenderers 1 ;
@@ -69,12 +69,12 @@ PRIVATE>
             NSOpenGLPFASamples , 8 ,
         ] when
         0 ,
-    ] { } make >c-int-array
+    ] int-array{ } make underlying>>
     -> initWithAttributes:
     -> autorelease ;
 
 : <GLView> ( class dim -- view )
-    >r -> alloc 0 0 r> first2 <NSRect> <PixelFormat>
+    [ -> alloc 0 0 ] dip first2 <NSRect> <PixelFormat>
     -> initWithFrame:pixelFormat:
     dup 1 -> setPostsBoundsChangedNotifications:
     dup 1 -> setPostsFrameChangedNotifications: ;
@@ -85,10 +85,11 @@ PRIVATE>
     swap NSRect-h >fixnum 2array ;
 
 : mouse-location ( view event -- loc )
-    over >r
-    -> locationInWindow f -> convertPoint:fromView:
-    dup NSPoint-x swap NSPoint-y
-    r> -> frame NSRect-h swap - 2array ;
+    [
+        -> locationInWindow f -> convertPoint:fromView:
+        [ NSPoint-x ] [ NSPoint-y ] bi
+    ] [ drop -> frame NSRect-h ] 2bi
+    swap - 2array ;
 
 USE: opengl.gl
 USE: alien.syntax
index dd2d1bfd41f3ad7a61359d1cc2037fd49b7570d6..3a53a1cc3cfde331251e64bb92cb6cc04052380d 100644 (file)
@@ -34,5 +34,6 @@ IN: cocoa.windows
     dup 0 -> setReleasedWhenClosed: ;
 
 : window-content-rect ( window -- rect )
-    NSWindow over -> frame rot -> styleMask
+    [ NSWindow ] dip
+    [ -> frame ] [ -> styleMask ] bi
     -> contentRectForFrameRect:styleMask: ;
index 2b4e522789f2cc4d1102c8b960d541c5fb779c35..d8bab4dd347b47a8cca0e4592b004c90fc679c19 100644 (file)
@@ -3,9 +3,13 @@ locals generalizations macros fry ;
 IN: combinators.short-circuit
 
 MACRO:: n&& ( quots n -- quot )
-    [ f ]
-    quots [| q | { [ drop n ndup q call dup not ] [ drop n ndrop f ] } ] map
-    [ n nnip ] suffix 1array
+    [ f ] quots [| q |
+        n
+        [ q '[ drop _ ndup @ dup not ] ]
+        [ '[ drop _ ndrop f ] ]
+        bi 2array
+    ] map
+    n '[ _ nnip ] suffix 1array
     [ cond ] 3append ;
 
 MACRO: 0&& ( quots -- quot ) '[ _ 0 n&& ] ;
@@ -14,10 +18,13 @@ MACRO: 2&& ( quots -- quot ) '[ _ 2 n&& ] ;
 MACRO: 3&& ( quots -- quot ) '[ _ 3 n&& ] ;
 
 MACRO:: n|| ( quots n -- quot )
-    [ f ]
-    quots
-    [| q | { [ drop n ndup q call dup ] [ n nnip ] } ] map
-    { [ drop n ndrop t ] [ f ] } suffix 1array
+    [ f ] quots [| q |
+        n
+        [ q '[ drop _ ndup @ dup ] ]
+        [ '[ _ nnip ] ]
+        bi 2array
+    ] map
+    n '[ drop _ ndrop t ] [ f ] 2array suffix 1array
     [ cond ] 3append ;
 
 MACRO: 0|| ( quots -- quot ) '[ _ 0 n|| ] ;
index 65d290df3ab9f8022c668e68619574ebd4b0367a..3d06bd97b7a88232a44a2ea69e222d893a4660f6 100644 (file)
@@ -1,4 +1,5 @@
-USING: help.markup help.syntax parser vocabs.loader strings ;
+USING: help.markup help.syntax parser vocabs.loader strings
+command-line.private ;
 IN: command-line
 
 HELP: run-bootstrap-init
@@ -7,7 +8,10 @@ HELP: run-bootstrap-init
 HELP: run-user-init
 { $description "Runs the startup initialization file in the user's home directory, unless the " { $snippet "-no-user-init" } " command line switch was given. This file is named " { $snippet ".factor-rc" } " on Unix and " { $snippet "factor-rc" } " on Windows." } ;
 
-HELP: cli-param
+HELP: load-vocab-roots
+{ $description "Loads the newline-separated list of additional vocabulary roots from the file named " { $snippet ".factor-roots" } " on Unix and " { $snippet "factor-roots" } " on Windows." } ;
+
+HELP: param
 { $values { "param" string } }
 { $description "Process a command-line switch."
 $nl
@@ -17,10 +21,13 @@ $nl
 $nl
 "Otherwise, sets the global variable named by the parameter to " { $link t } "." } ;
 
-HELP: cli-args
+HELP: (command-line)
 { $values { "args" "a sequence of strings" } }
 { $description "Outputs the command line parameters which were passed to the Factor VM on startup." } ;
 
+HELP: command-line
+{ $var-description "The command line parameters which follow the name of the script on the command line." } ;
+
 HELP: main-vocab-hook
 { $var-description "Global variable holding a quotation which outputs a vocabulary name. UI backends set this so that the UI can automatically start if the prerequisites are met (for example, " { $snippet "$DISPLAY" } " being set on X11)." } ;
 
@@ -35,9 +42,6 @@ HELP: ignore-cli-args?
 { $values { "?" "a boolean" } }
 { $description "On Mac OS X, source files to run are supplied by the Cocoa API, so to avoid running them twice the startup code has to call this word." } ;
 
-HELP: parse-command-line
-{ $description "Called on startup to process command line arguments. This sets global variables with " { $link cli-param } ", runs source files, and evaluates the string given by the " { $snippet "-e" } " switch, if there is one." } ;
-
 ARTICLE: "runtime-cli-args" "Command line switches for the VM"
 "A handful of command line switches are processed by the VM and not the library. They control low-level features."
 { $table
@@ -64,9 +68,12 @@ ARTICLE: "bootstrap-cli-args" "Command line switches for bootstrap"
 }
 "Bootstrap can load various optional components:"
 { $table
+    { { $snippet "math" } "Rational and complex number support." }
+    { { $snippet "threads" } "Thread support." }
     { { $snippet "compiler" } "The compiler." }
     { { $snippet "tools" } "Terminal-based developer tools." }
     { { $snippet "help" } "The help system." }
+    { { $snippet "help.handbook" } "The help handbook." }
     { { $snippet "ui" } "The graphical user interface." }
     { { $snippet "ui.tools" } "Graphical developer tools." }
     { { $snippet "io" } "Non-blocking I/O and networking." }
@@ -86,7 +93,6 @@ ARTICLE: "standard-cli-args" "Command line switches for general usage"
     { { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link POSTPONE: MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } ", " { $vocab-link "ui" } " or " { $vocab-link "none" } "." } }
     { { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } }
     { { $snippet "-quiet" } { "If set, " { $link run-file } " and " { $link require } " will not print load messages." } }
-    { { $snippet "-script" } { "Equivalent to " { $snippet "-quiet -run=none" } "." $nl "On Unix systems, Factor can be used for scripting - just create an executable text file whose first line is:" { $code "#! /usr/local/bin/factor -script" } "The space after " { $snippet "#!" } " is necessary because of Factor syntax." } }
 } ;
 
 ARTICLE: "factor-boot-rc" "Bootstrap initialization file"
@@ -102,11 +108,18 @@ $nl
 "A word to run this file from an existing Factor session:"
 { $subsection run-user-init } ;
 
+ARTICLE: "factor-roots" "Additional vocabulary roots file"
+"The vocabulary roots file is named " { $snippet "factor-roots" } " on Windows and " { $snippet ".factor-roots" } " on Unix. If it exists, it is loaded every time Factor starts. It contains a newline-separated list of " { $link "vocabs.roots" } "."
+$nl
+"A word to run this file from an existing Factor session:"
+{ $subsection load-vocab-roots } ;
+
 ARTICLE: "rc-files" "Running code on startup"
-"Factor looks for two files in your home directory."
+"Factor looks for three optional files in your home directory."
 { $subsection "factor-boot-rc" }
 { $subsection "factor-rc" }
-"The " { $snippet "-no-user-init" } " command line switch will inhibit the running of these files."
+{ $subsection "factor-roots" }
+"The " { $snippet "-no-user-init" } " command line switch will inhibit loading running of these files."
 $nl
 "If you are unsure where the files should be located, evaluate the following code:"
 { $code
@@ -122,8 +135,16 @@ $nl
     "100 dpi set-global"
 } ;
 
-ARTICLE: "cli" "Command line usage"
-"Zero or more command line arguments may be passed to the Factor runtime. Command line arguments starting with a dash (" { $snippet "-" } ") is interpreted as switches. All other arguments are taken to be file names to be run by " { $link run-file } "."
+ARTICLE: "cli" "Command line arguments"
+"Factor command line usage:"
+{ $code "factor [system switches...] [script args...]" }
+"Zero or more system switches can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup, any arguments after the script file are stored in a variable, with no further processing by Factor itself:"
+{ $subsection command-line }
+"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link POSTPONE: MAIN: } " word:"
+{ $code "factor [system switches...] -run=<vocab name>" }
+"If no script file or " { $snippet "-run=" } " switch is specified, Factor will start " { $link "listener" } " or " { $link "ui-tools" } ", depending on the operating system."
+$nl
+"As stated above, arguments in the first part of the command line, before the optional script name, are interpreted by to the Factor system. These arguments all start with a dash (" { $snippet "-" } ")."
 $nl
 "Switches can take one of the following three forms:"
 { $list
@@ -134,9 +155,9 @@ $nl
 { $subsection "runtime-cli-args" }
 { $subsection "bootstrap-cli-args" }
 { $subsection "standard-cli-args" }
-"The list of command line arguments can be obtained and inspected directly:"
-{ $subsection cli-args }
-"There is a way to override the default vocabulary to run on startup:"
+"The raw list of command line arguments can also be obtained and inspected directly:"
+{ $subsection (command-line) }
+"There is a way to override the default vocabulary to run on startup, if no script name or " { $snippet "-run" } " switch is specified:"
 { $subsection main-vocab-hook } ;
 
 ABOUT: "cli"
diff --git a/basis/command-line/command-line-tests.factor b/basis/command-line/command-line-tests.factor
deleted file mode 100644 (file)
index 226765b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: namespaces tools.test kernel command-line ;
-IN: command-line.tests
-
-[
-    [ f ] [ "-no-user-init" cli-arg ] unit-test
-    [ f ] [ "user-init" get ] unit-test
-
-    [ f ] [ "-user-init" cli-arg ] unit-test
-    [ t ] [ "user-init" get ] unit-test
-    
-    [ "sdl.factor" ] [ "sdl.factor" cli-arg ] unit-test
-] with-scope
index 7691f6877bb6ababbd9a7ce0c3b3412897074d21..1b58053b64d2af681760f542902957fb147bd51f 100644 (file)
@@ -1,10 +1,15 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: init continuations debugger hashtables io kernel
-kernel.private namespaces parser sequences strings system
-splitting io.files eval ;
+USING: init continuations debugger hashtables io
+io.encodings.utf8 io.files kernel kernel.private namespaces
+parser sequences strings system splitting eval vocabs.loader ;
 IN: command-line
 
+SYMBOL: script
+SYMBOL: command-line
+
+: (command-line) ( -- args ) 10 getenv sift ;
+
 : rc-path ( name -- path )
     os windows? [ "." prepend ] unless
     home prepend-path ;
@@ -19,17 +24,33 @@ IN: command-line
         "factor-rc" rc-path ?run-file
     ] when ;
 
-: cli-var-param ( name value -- ) swap set-global ;
+: load-vocab-roots ( -- )
+    "user-init" get [
+        "factor-roots" rc-path dup exists? [
+            utf8 file-lines [ add-vocab-root ] each
+        ] [ drop ] if
+    ] when ;
+
+<PRIVATE
+
+: var-param ( name value -- ) swap set-global ;
+
+: bool-param ( name -- ) "no-" ?head not var-param ;
 
-: cli-bool-param ( name -- ) "no-" ?head not cli-var-param ;
+: param ( param -- )
+    "=" split1 [ var-param ] [ bool-param ] if* ;
 
-: cli-param ( param -- )
-    "=" split1 [ cli-var-param ] [ cli-bool-param ] if* ;
+: run-script ( file -- )
+    t "quiet" set-global run-file ;
 
-: cli-arg ( argument -- argument )
-    "-" ?head [ cli-param f ] when ;
+PRIVATE>
 
-: cli-args ( -- args ) 10 getenv ;
+: parse-command-line ( args -- )
+    [ command-line off script off ] [
+        unclip "-" ?head
+        [ param parse-command-line ]
+        [ script set command-line set ] if
+    ] if-empty ;
 
 SYMBOL: main-vocab-hook
 
@@ -53,14 +74,17 @@ SYMBOL: main-vocab-hook
 : ignore-cli-args? ( -- ? )
     os macosx? "run" get "ui" = and ;
 
-: script-mode ( -- )
-    t "quiet" set-global
-    "none" "run" set-global ;
+: script-mode ( -- ) ;
 
-: parse-command-line ( -- )
-    cli-args [ cli-arg ] filter
-    "script" get [ script-mode ] when
-    ignore-cli-args? [ drop ] [ [ run-file ] each ] if
-    "e" get [ eval ] when* ;
+: handle-command-line ( -- )
+    [
+        (command-line) parse-command-line
+        load-vocab-roots
+        run-user-init
+        "e" get [ eval ] when*
+        ignore-cli-args? not script get and
+        [ run-script ] [ "run" get run ] if*
+        output-stream get [ stream-flush ] when*
+    ] [ print-error 1 exit ] recover ;
 
 [ default-cli-args ] "command-line" add-init-hook
index e414d6e29b7d8a31919cb94bf049b0651792e633..4a41014ab2c9ac7bae447d4b757c5fe4cd243893 100644 (file)
@@ -18,7 +18,7 @@ IN: compiler.alien
     dup c-type-stack-align? [ c-type-align ] [ drop cell ] if ;
 
 : parameter-align ( n type -- n delta )
-    over >r c-type-stack-align align dup r> - ;
+    [ c-type-stack-align align dup ] [ drop ] 2bi - ;
 
 : parameter-sizes ( types -- total offsets )
     #! Compute stack frame locations.
index 98569d868c1c2ea6424edbab05cd854ea28dfeb5..90227bb5dae9ffd79c26355f18cfa3f639b7396f 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math namespaces assocs hashtables sequences
+USING: kernel math namespaces assocs hashtables sequences arrays
 accessors vectors combinators sets classes compiler.cfg
 compiler.cfg.registers compiler.cfg.instructions
 compiler.cfg.copy-prop ;
@@ -194,6 +194,7 @@ M: ##slot insn-slot# slot>> constant ;
 M: ##slot-imm insn-slot# slot>> ;
 M: ##set-slot insn-slot# slot>> constant ;
 M: ##set-slot-imm insn-slot# slot>> ;
+M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ;
 
 M: ##peek insn-object loc>> class ;
 M: ##replace insn-object loc>> class ;
@@ -201,6 +202,7 @@ M: ##slot insn-object obj>> resolve ;
 M: ##slot-imm insn-object obj>> resolve ;
 M: ##set-slot insn-object obj>> resolve ;
 M: ##set-slot-imm insn-object obj>> resolve ;
+M: ##alien-global insn-object drop \ ##alien-global ;
 
 : init-alias-analysis ( -- )
     H{ } clone histories set
@@ -224,6 +226,9 @@ M: ##load-immediate analyze-aliases*
 M: ##load-indirect analyze-aliases*
     dup dst>> set-heap-ac ;
 
+M: ##alien-global analyze-aliases*
+    dup dst>> set-heap-ac ;
+
 M: ##allot analyze-aliases*
     #! A freshly allocated object is distinct from any other
     #! object.
index 7bad44f7a60cacc18839d1760c002c5edd5e9fb2..9ffe4a6aa05c50d3fc43c297ecbbbc48363e1fa4 100755 (executable)
@@ -21,8 +21,6 @@ IN: compiler.cfg.builder
 
 ! Convert tree SSA IR to CFG SSA IR.
 
-: stop-iterating ( -- next ) end-basic-block f ;
-
 SYMBOL: procedures
 SYMBOL: current-word
 SYMBOL: current-label
@@ -211,7 +209,7 @@ M: #dispatch emit-node
 ! #call
 M: #call emit-node
     dup word>> dup "intrinsic" word-prop
-    [ emit-intrinsic iterate-next ] [ nip emit-call ] if ;
+    [ emit-intrinsic ] [ nip emit-call ] if ;
 
 ! #call-recursive
 M: #call-recursive emit-node label>> id>> emit-call ;
@@ -262,7 +260,7 @@ M: #terminate emit-node drop stop-iterating ;
 
 : emit-alien-node ( node quot -- next )
     [ params>> ] dip [ drop alien-stack-frame ] [ call ] 2bi
-    begin-basic-block iterate-next ; inline
+    ##branch begin-basic-block iterate-next ; inline
 
 M: #alien-invoke emit-node
     [ ##alien-invoke ] emit-alien-node ;
index 7553407e00b8c3d3ef74498ea0fc6c2424a189ed..068a6a637745e8c2384743882372980fe20cf638 100644 (file)
@@ -12,9 +12,15 @@ M: ##write-barrier defs-vregs [ card#>> ] [ table>> ] bi 2array ;
 M: ##unary/temp defs-vregs dst/tmp-vregs ;
 M: ##allot defs-vregs dst/tmp-vregs ;
 M: ##dispatch defs-vregs temp>> 1array ;
-M: ##slot defs-vregs [ dst>> ] [ temp>> ] bi 2array ;
+M: ##slot defs-vregs dst/tmp-vregs ;
 M: ##set-slot defs-vregs temp>> 1array ;
-M: ##string-nth defs-vregs [ dst>> ] [ temp>> ] bi 2array ;
+M: ##string-nth defs-vregs dst/tmp-vregs ;
+M: ##set-string-nth-fast defs-vregs temp>> 1array ;
+M: ##compare defs-vregs dst/tmp-vregs ;
+M: ##compare-imm defs-vregs dst/tmp-vregs ;
+M: ##compare-float defs-vregs dst/tmp-vregs ;
+M: ##fixnum-mul defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ;
+M: ##fixnum-mul-tail defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ;
 M: insn defs-vregs drop f ;
 
 M: ##unary uses-vregs src>> 1array ;
@@ -26,11 +32,13 @@ M: ##slot-imm uses-vregs obj>> 1array ;
 M: ##set-slot uses-vregs [ src>> ] [ obj>> ] [ slot>> ] tri 3array ;
 M: ##set-slot-imm uses-vregs [ src>> ] [ obj>> ] bi 2array ;
 M: ##string-nth uses-vregs [ obj>> ] [ index>> ] bi 2array ;
+M: ##set-string-nth-fast uses-vregs [ src>> ] [ obj>> ] [ index>> ] tri 3array ;
 M: ##conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
 M: ##compare-imm-branch uses-vregs src1>> 1array ;
 M: ##dispatch uses-vregs src>> 1array ;
 M: ##alien-getter uses-vregs src>> 1array ;
 M: ##alien-setter uses-vregs [ src>> ] [ value>> ] bi 2array ;
+M: ##fixnum-overflow uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
 M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
 M: _compare-imm-branch uses-vregs src1>> 1array ;
 M: insn uses-vregs drop f ;
@@ -40,6 +48,7 @@ UNION: vreg-insn
 ##write-barrier
 ##dispatch
 ##effect
+##fixnum-overflow
 ##conditional-branch
 ##compare-imm-branch
 _conditional-branch
index e6e05abbd5eb89c8fae414b9eb6b7e4e0a69cdc1..c0d5bf79a6f7a24b993d546f91338f47c2c18666 100644 (file)
@@ -39,6 +39,7 @@ IN: compiler.cfg.hats
 : ^^shr-imm ( src1 src2 -- dst ) ^^i2 ##shr-imm ; inline
 : ^^sar-imm ( src1 src2 -- dst ) ^^i2 ##sar-imm ; inline
 : ^^not ( src -- dst ) ^^i1 ##not ; inline
+: ^^log2 ( src -- dst ) ^^i1 ##log2 ; inline
 : ^^bignum>integer ( src -- dst ) ^^i1 i ##bignum>integer ; inline
 : ^^integer>bignum ( src -- dst ) ^^i1 i ##integer>bignum ; inline
 : ^^add-float ( src1 src2 -- dst ) ^^d2 ##add-float ; inline
@@ -65,9 +66,10 @@ IN: compiler.cfg.hats
 : ^^alien-cell ( src -- dst ) ^^i1 ##alien-cell ; inline
 : ^^alien-float ( src -- dst ) ^^d1 ##alien-float ; inline
 : ^^alien-double ( src -- dst ) ^^d1 ##alien-double ; inline
-: ^^compare ( src1 src2 cc -- dst ) ^^i3 ##compare ; inline
-: ^^compare-imm ( src1 src2 cc -- dst ) ^^i3 ##compare-imm ; inline
-: ^^compare-float ( src1 src2 cc -- dst ) ^^i3 ##compare-float ; inline
+: ^^alien-global ( symbol library -- dst ) ^^i2 ##alien-global ; inline
+: ^^compare ( src1 src2 cc -- dst ) ^^i3 i ##compare ; inline
+: ^^compare-imm ( src1 src2 cc -- dst ) ^^i3 i ##compare-imm ; inline
+: ^^compare-float ( src1 src2 cc -- dst ) ^^i3 i ##compare-float ; inline
 : ^^offset>slot ( vreg -- vreg' ) cell 4 = [ 1 ^^shr-imm ] when ; inline
 : ^^tag-fixnum ( src -- dst ) ^^i1 ##tag-fixnum ; inline
 : ^^untag-fixnum ( src -- dst ) ^^i1 ##untag-fixnum ; inline
index b2c752e6121ec07c61e8529aec04c29eed859e5b..5619a70740bef3632cd7dbb2a198420907ebfd0f 100644 (file)
@@ -73,6 +73,7 @@ INSN: ##set-slot-imm < ##write { obj vreg } { slot integer } { tag integer } ;
 
 ! String element access
 INSN: ##string-nth < ##flushable { obj vreg } { index vreg } { temp vreg } ;
+INSN: ##set-string-nth-fast < ##effect { obj vreg } { index vreg } { temp vreg } ;
 
 ! Integer arithmetic
 INSN: ##add < ##commutative ;
@@ -91,6 +92,16 @@ INSN: ##shl-imm < ##binary-imm ;
 INSN: ##shr-imm < ##binary-imm ;
 INSN: ##sar-imm < ##binary-imm ;
 INSN: ##not < ##unary ;
+INSN: ##log2 < ##unary ;
+
+! Overflowing arithmetic
+TUPLE: ##fixnum-overflow < insn src1 src2 ;
+INSN: ##fixnum-add < ##fixnum-overflow ;
+INSN: ##fixnum-add-tail < ##fixnum-overflow ;
+INSN: ##fixnum-sub < ##fixnum-overflow ;
+INSN: ##fixnum-sub-tail < ##fixnum-overflow ;
+INSN: ##fixnum-mul < ##fixnum-overflow temp1 temp2 ;
+INSN: ##fixnum-mul-tail < ##fixnum-overflow temp1 temp2 ;
 
 : ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline
 : ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline
@@ -151,6 +162,8 @@ INSN: ##set-alien-double < ##alien-setter ;
 INSN: ##allot < ##flushable size class { temp vreg } ;
 INSN: ##write-barrier < ##effect card# table ;
 
+INSN: ##alien-global < ##read symbol library ;
+
 ! FFI
 INSN: ##alien-invoke params ;
 INSN: ##alien-indirect params ;
@@ -198,11 +211,11 @@ TUPLE: ##conditional-branch < insn { src1 vreg } { src2 vreg } cc ;
 INSN: ##compare-branch < ##conditional-branch ;
 INSN: ##compare-imm-branch { src1 vreg } { src2 integer } cc ;
 
-INSN: ##compare < ##binary cc ;
-INSN: ##compare-imm < ##binary-imm cc ;
+INSN: ##compare < ##binary cc temp ;
+INSN: ##compare-imm < ##binary-imm cc temp ;
 
 INSN: ##compare-float-branch < ##conditional-branch ;
-INSN: ##compare-float < ##binary cc ;
+INSN: ##compare-float < ##binary cc temp ;
 
 ! Instructions used by machine IR only.
 INSN: _prologue stack-frame ;
index 04c9097725a5ac7f9ef035bd9a37063f8e8270d8..3ad716d847f19a5066fb23b06b8f8e06d0278d55 100644 (file)
@@ -3,10 +3,21 @@
 USING: sequences accessors layouts kernel math namespaces
 combinators fry locals
 compiler.tree.propagation.info
-compiler.cfg.stacks compiler.cfg.hats compiler.cfg.instructions
-compiler.cfg.utilities ;
+compiler.cfg.hats
+compiler.cfg.stacks
+compiler.cfg.iterator
+compiler.cfg.instructions
+compiler.cfg.utilities
+compiler.cfg.registers ;
 IN: compiler.cfg.intrinsics.fixnum
 
+: emit-both-fixnums? ( -- )
+    2inputs
+    ^^or
+    tag-mask get ^^and-imm
+    0 cc= ^^compare-imm
+    ds-push ;
+
 : (emit-fixnum-imm-op) ( infos insn -- dst )
     ds-drop
     [ ds-pop ]
@@ -42,6 +53,9 @@ IN: compiler.cfg.intrinsics.fixnum
 : emit-fixnum-bitnot ( -- )
     ds-pop ^^not tag-mask get ^^xor-imm ds-push ;
 
+: emit-fixnum-log2 ( -- )
+    ds-pop ^^log2 tag-bits get ^^sub-imm ^^tag-fixnum ds-push ;
+
 : (emit-fixnum*fast) ( -- dst )
     2inputs ^^untag-fixnum ^^mul ;
 
@@ -64,3 +78,16 @@ IN: compiler.cfg.intrinsics.fixnum
 
 : emit-fixnum>bignum ( -- )
     ds-pop ^^untag-fixnum ^^integer>bignum ds-push ;
+
+: emit-fixnum-overflow-op ( quot quot-tail -- next )
+    [ 2inputs 1 ##inc-d ] 2dip
+    tail-call? [
+        ##epilogue
+        nip call
+        stop-iterating
+    ] [
+        drop call
+        ##branch
+        begin-basic-block
+        iterate-next
+    ] if ; inline
index ef1cde337a489fb5dc8e3abfa1be1c21c59dfef1..6656cd11f7646047e95e11317dfb6a7779a501c3 100644 (file)
@@ -8,7 +8,9 @@ compiler.cfg.intrinsics.alien
 compiler.cfg.intrinsics.allot
 compiler.cfg.intrinsics.fixnum
 compiler.cfg.intrinsics.float
-compiler.cfg.intrinsics.slots ;
+compiler.cfg.intrinsics.slots
+compiler.cfg.intrinsics.misc
+compiler.cfg.iterator ;
 QUALIFIED: kernel
 QUALIFIED: arrays
 QUALIFIED: byte-arrays
@@ -17,11 +19,17 @@ QUALIFIED: slots.private
 QUALIFIED: strings.private
 QUALIFIED: classes.tuple.private
 QUALIFIED: math.private
+QUALIFIED: math.integers.private
 QUALIFIED: alien.accessors
 IN: compiler.cfg.intrinsics
 
 {
     kernel.private:tag
+    kernel.private:getenv
+    math.private:both-fixnums?
+    math.private:fixnum+
+    math.private:fixnum-
+    math.private:fixnum*
     math.private:fixnum+fast
     math.private:fixnum-fast
     math.private:fixnum-bitand
@@ -40,6 +48,7 @@ IN: compiler.cfg.intrinsics
     slots.private:slot
     slots.private:set-slot
     strings.private:string-nth
+    strings.private:set-string-nth-fast
     classes.tuple.private:<tuple-boa>
     arrays:<array>
     byte-arrays:<byte-array>
@@ -85,60 +94,70 @@ IN: compiler.cfg.intrinsics
         alien.accessors:set-alien-double
     } [ t "intrinsic" set-word-prop ] each ;
 
-: emit-intrinsic ( node word -- )
+: enable-fixnum-log2 ( -- )
+    \ math.integers.private:fixnum-log2 t "intrinsic" set-word-prop ;
+
+: emit-intrinsic ( node word -- node/f )
     {
-        { \ kernel.private:tag [ drop emit-tag ] }
-        { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op ] }
-        { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op ] }
-        { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op ] }
-        { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op ] }
-        { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op ] }
-        { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast ] }
-        { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot ] }
-        { \ math.private:fixnum*fast [ emit-fixnum*fast ] }
-        { \ math.private:fixnum< [ cc< emit-fixnum-comparison ] }
-        { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison ] }
-        { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison ] }
-        { \ math.private:fixnum> [ cc> emit-fixnum-comparison ] }
-        { \ kernel:eq? [ cc= emit-fixnum-comparison ] }
-        { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum ] }
-        { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum ] }
-        { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op ] }
-        { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op ] }
-        { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op ] }
-        { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op ] }
-        { \ math.private:float< [ drop cc< emit-float-comparison ] }
-        { \ math.private:float<= [ drop cc<= emit-float-comparison ] }
-        { \ math.private:float>= [ drop cc>= emit-float-comparison ] }
-        { \ math.private:float> [ drop cc> emit-float-comparison ] }
-        { \ math.private:float= [ drop cc= emit-float-comparison ] }
-        { \ math.private:float>fixnum [ drop emit-float>fixnum ] }
-        { \ math.private:fixnum>float [ drop emit-fixnum>float ] }
-        { \ slots.private:slot [ emit-slot ] }
-        { \ slots.private:set-slot [ emit-set-slot ] }
-        { \ strings.private:string-nth [ drop emit-string-nth ] }
-        { \ classes.tuple.private:<tuple-boa> [ emit-<tuple-boa> ] }
-        { \ arrays:<array> [ emit-<array> ] }
-        { \ byte-arrays:<byte-array> [ emit-<byte-array> ] }
-        { \ math.private:<complex> [ emit-simple-allot ] }
-        { \ math.private:<ratio> [ emit-simple-allot ] }
-        { \ kernel:<wrapper> [ emit-simple-allot ] }
-        { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter ] }
-        { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter ] }
-        { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter ] }
-        { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter ] }
-        { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter ] }
-        { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter ] }
-        { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter ] }
-        { \ alien.accessors:alien-cell [ emit-alien-cell-getter ] }
-        { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter ] }
-        { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter ] }
-        { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter ] }
-        { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter ] }
-        { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter ] }
+        { \ kernel.private:tag [ drop emit-tag iterate-next ] }
+        { \ kernel.private:getenv [ emit-getenv iterate-next ] }
+        { \ math.private:both-fixnums? [ drop emit-both-fixnums? iterate-next ] }
+        { \ math.private:fixnum+ [ drop [ ##fixnum-add ] [ ##fixnum-add-tail ] emit-fixnum-overflow-op ] }
+        { \ math.private:fixnum- [ drop [ ##fixnum-sub ] [ ##fixnum-sub-tail ] emit-fixnum-overflow-op ] }
+        { \ math.private:fixnum* [ drop [ i i ##fixnum-mul ] [ i i ##fixnum-mul-tail ] emit-fixnum-overflow-op ] }
+        { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op iterate-next ] }
+        { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op iterate-next ] }
+        { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op iterate-next ] }
+        { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op iterate-next ] }
+        { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op iterate-next ] }
+        { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast iterate-next ] }
+        { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot iterate-next ] }
+        { \ math.integers.private:fixnum-log2 [ drop emit-fixnum-log2 iterate-next ] }
+        { \ math.private:fixnum*fast [ emit-fixnum*fast iterate-next ] }
+        { \ math.private:fixnum< [ cc< emit-fixnum-comparison iterate-next ] }
+        { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison iterate-next ] }
+        { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison iterate-next ] }
+        { \ math.private:fixnum> [ cc> emit-fixnum-comparison iterate-next ] }
+        { \ kernel:eq? [ cc= emit-fixnum-comparison iterate-next ] }
+        { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum iterate-next ] }
+        { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum iterate-next ] }
+        { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op iterate-next ] }
+        { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op iterate-next ] }
+        { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op iterate-next ] }
+        { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op iterate-next ] }
+        { \ math.private:float< [ drop cc< emit-float-comparison iterate-next ] }
+        { \ math.private:float<= [ drop cc<= emit-float-comparison iterate-next ] }
+        { \ math.private:float>= [ drop cc>= emit-float-comparison iterate-next ] }
+        { \ math.private:float> [ drop cc> emit-float-comparison iterate-next ] }
+        { \ math.private:float= [ drop cc= emit-float-comparison iterate-next ] }
+        { \ math.private:float>fixnum [ drop emit-float>fixnum iterate-next ] }
+        { \ math.private:fixnum>float [ drop emit-fixnum>float iterate-next ] }
+        { \ slots.private:slot [ emit-slot iterate-next ] }
+        { \ slots.private:set-slot [ emit-set-slot iterate-next ] }
+        { \ strings.private:string-nth [ drop emit-string-nth iterate-next ] }
+        { \ strings.private:set-string-nth-fast [ drop emit-set-string-nth-fast iterate-next ] }
+        { \ classes.tuple.private:<tuple-boa> [ emit-<tuple-boa> iterate-next ] }
+        { \ arrays:<array> [ emit-<array> iterate-next ] }
+        { \ byte-arrays:<byte-array> [ emit-<byte-array> iterate-next ] }
+        { \ math.private:<complex> [ emit-simple-allot iterate-next ] }
+        { \ math.private:<ratio> [ emit-simple-allot iterate-next ] }
+        { \ kernel:<wrapper> [ emit-simple-allot iterate-next ] }
+        { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter iterate-next ] }
+        { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter iterate-next ] }
+        { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter iterate-next ] }
+        { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter iterate-next ] }
+        { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter iterate-next ] }
+        { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter iterate-next ] }
+        { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter iterate-next ] }
+        { \ alien.accessors:alien-cell [ emit-alien-cell-getter iterate-next ] }
+        { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter iterate-next ] }
+        { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter iterate-next ] }
+        { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter iterate-next ] }
+        { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter iterate-next ] }
+        { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter iterate-next ] }
     } case ;
diff --git a/basis/compiler/cfg/intrinsics/misc/misc.factor b/basis/compiler/cfg/intrinsics/misc/misc.factor
new file mode 100644 (file)
index 0000000..f9f2182
--- /dev/null
@@ -0,0 +1,16 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: namespaces layouts sequences kernel
+accessors compiler.tree.propagation.info
+compiler.cfg.stacks compiler.cfg.hats
+compiler.cfg.instructions compiler.cfg.utilities ;
+IN: compiler.cfg.intrinsics.misc
+
+: emit-tag ( -- )
+    ds-pop tag-mask get ^^and-imm ^^tag-fixnum ds-push ;
+
+: emit-getenv ( node -- )
+    "userenv" f ^^alien-global
+    swap node-input-infos first literal>>
+    [ ds-drop 0 ^^slot-imm ] [ ds-pop ^^offset>slot 0 ^^slot ] if*
+    ds-push ;
index fec234a576abeaca0f609a2c84a324c608ea9e4e..bc46e6149c0d81dd8ed536b70b80ba8fa89957c8 100644 (file)
@@ -6,9 +6,6 @@ compiler.cfg.stacks compiler.cfg.hats compiler.cfg.instructions
 compiler.cfg.utilities ;
 IN: compiler.cfg.intrinsics.slots
 
-: emit-tag ( -- )
-    ds-pop tag-mask get ^^and-imm ^^tag-fixnum ds-push ;
-
 : value-tag ( info -- n ) class>> class-tag ; inline
 
 : (emit-slot) ( infos -- dst )
@@ -54,3 +51,7 @@ IN: compiler.cfg.intrinsics.slots
 
 : emit-string-nth ( -- )
     2inputs swap ^^untag-fixnum ^^string-nth ^^tag-fixnum ds-push ;
+
+: emit-set-string-nth-fast ( -- )
+    3inputs [ ^^untag-fixnum ] [ ^^untag-fixnum ] [ ] tri*
+    swap i ##set-string-nth-fast ;
index ec9ffaba49a5b30292f6b4c5d082d374a6904166..d545b6d15c988edf58271b30a681c2733cd6f362 100644 (file)
@@ -34,6 +34,12 @@ M: insn compute-stack-frame*
 
 \ _gc t frame-required? set-word-prop
 \ _spill t frame-required? set-word-prop
+\ ##fixnum-add t frame-required? set-word-prop
+\ ##fixnum-sub t frame-required? set-word-prop
+\ ##fixnum-mul t frame-required? set-word-prop
+\ ##fixnum-add-tail f frame-required? set-word-prop
+\ ##fixnum-sub-tail f frame-required? set-word-prop
+\ ##fixnum-mul-tail f frame-required? set-word-prop
 
 : compute-stack-frame ( insns -- )
     frame-required? off
index e943fb48280c28b6ac79979401b1c6390bed3345..dabecaeec4623888fa4be920dad61d040a6c2b09 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel sequences sequences.deep
+USING: accessors arrays kernel sequences compiler.utilities
 compiler.cfg.instructions cpu.architecture ;
 IN: compiler.cfg.two-operand
 
@@ -55,6 +55,6 @@ M: insn convert-two-operand* ;
 : convert-two-operand ( mr -- mr' )
     [
         two-operand? [
-            [ convert-two-operand* ] map flatten
+            [ convert-two-operand* ] map-flat
         ] when
     ] change-instructions ;
index cef14d06e4e2a6a8b9b8cd4625c6105a859c98ad..99a138a7636b6a95220a8ec18d886c0ae4690546 100644 (file)
@@ -33,5 +33,7 @@ IN: compiler.cfg.utilities
     building off
     basic-block off ;
 
+: stop-iterating ( -- next ) end-basic-block f ;
+
 : emit-primitive ( node -- )
     word>> ##call ##branch begin-basic-block ;
index a3c9725838fdf44de6e0b13fdf867fd0dea84d9d..d5c9830c0b27bf224973398c106ab38cee7e5ae1 100644 (file)
@@ -62,4 +62,8 @@ M: ##compare-imm-branch propagate
 M: ##dispatch propagate
     [ resolve ] change-src ;
 
+M: ##fixnum-overflow propagate
+    [ resolve ] change-src1
+    [ resolve ] change-src2 ;
+
 M: insn propagate ;
index 5f67f8097eec07db89e594f179ed39f60e4333ed..990543ed7acca8b73ee23d2332d6e19b3ae08a59 100644 (file)
@@ -2,6 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences layouts accessors combinators namespaces
 math fry
+compiler.cfg.hats
 compiler.cfg.instructions
 compiler.cfg.value-numbering.graph
 compiler.cfg.value-numbering.simplify
@@ -63,7 +64,7 @@ M: ##compare-imm-branch rewrite-tagged-comparison
 
 M: ##compare-imm rewrite-tagged-comparison
     [ dst>> ] [ (rewrite-tagged-comparison) ] bi
-    f \ ##compare-imm boa ;
+    f \ ##compare-imm boa ;
 
 M: ##compare-imm-branch rewrite
     dup rewrite-boolean-comparison? [ rewrite-boolean-comparison ] when
@@ -78,7 +79,7 @@ M: ##compare-imm-branch rewrite
     [ dst>> ]
     [ src2>> ]
     [ src1>> vreg>vn vn>constant ] tri
-    cc= f \ ##compare-imm boa ;
+    cc= f \ ##compare-imm boa ;
 
 M: ##compare rewrite
     dup flip-comparison? [
@@ -95,9 +96,9 @@ M: ##compare rewrite
 
 : rewrite-redundant-comparison ( insn -- insn' )
     [ cc>> ] [ dst>> ] [ src1>> vreg>expr dup op>> ] tri {
-        { \ ##compare [ >compare-expr< f \ ##compare boa ] }
-        { \ ##compare-imm [ >compare-imm-expr< f \ ##compare-imm boa ] }
-        { \ ##compare-float [ >compare-expr< f \ ##compare-float boa ] }
+        { \ ##compare [ >compare-expr< f \ ##compare boa ] }
+        { \ ##compare-imm [ >compare-imm-expr< f \ ##compare-imm boa ] }
+        { \ ##compare-float [ >compare-expr< f \ ##compare-float boa ] }
     } case
     swap cc= eq? [ [ negate-cc ] change-cc ] when ;
 
index b73736ed1427be93f6a73bd899496cece7ce8d20..8adeaa21f4ddd4485942102614a0d76542e21b9d 100644 (file)
@@ -1,6 +1,17 @@
 IN: compiler.cfg.value-numbering.tests
 USING: compiler.cfg.value-numbering compiler.cfg.instructions
-compiler.cfg.registers cpu.architecture tools.test kernel math ;
+compiler.cfg.registers cpu.architecture tools.test kernel math
+combinators.short-circuit accessors sequences ;
+
+: trim-temps ( insns -- insns )
+    [
+        dup {
+            [ ##compare? ]
+            [ ##compare-imm? ]
+            [ ##compare-float? ]
+        } 1|| [ f >>temp ] when
+    ] map ;
+
 [
     {
         T{ ##peek f V int-regs 45 D 1 }
@@ -82,7 +93,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ;
         T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc> }
         T{ ##compare-imm f V int-regs 6 V int-regs 4 7 cc/= }
         T{ ##replace f V int-regs 6 D 0 }
-    } value-numbering
+    } value-numbering trim-temps
 ] unit-test
 
 [
@@ -100,7 +111,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ;
         T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc<= }
         T{ ##compare-imm f V int-regs 6 V int-regs 4 7 cc= }
         T{ ##replace f V int-regs 6 D 0 }
-    } value-numbering
+    } value-numbering trim-temps
 ] unit-test
 
 [
@@ -122,7 +133,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ;
         T{ ##compare-float f V int-regs 12 V double-float-regs 10 V double-float-regs 11 cc< }
         T{ ##compare-imm f V int-regs 14 V int-regs 12 7 cc= }
         T{ ##replace f V int-regs 14 D 0 }
-    } value-numbering
+    } value-numbering trim-temps
 ] unit-test
 
 [
@@ -138,5 +149,5 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ;
         T{ ##peek f V int-regs 30 D -2 }
         T{ ##compare f V int-regs 33 V int-regs 29 V int-regs 30 cc<= }
         T{ ##compare-imm-branch f V int-regs 33 7 cc/= }
-    } value-numbering
+    } value-numbering trim-temps
 ] unit-test
index 9f6e8e9c9b758b60833f7007d55dfa9465d228b9..9f134c02d7f0a0112d246993964f36becbb2d7cb 100644 (file)
@@ -131,6 +131,14 @@ M: ##string-nth generate-insn
         [ temp>> register ]
     } cleave %string-nth ;
 
+M: ##set-string-nth-fast generate-insn
+    {
+        [ src>> register ]
+        [ obj>> register ]
+        [ index>> register ]
+        [ temp>> register ]
+    } cleave %set-string-nth-fast ;
+
 : dst/src ( insn -- dst src )
     [ dst>> register ] [ src>> register ] bi ; inline
 
@@ -155,6 +163,20 @@ M: ##shl-imm generate-insn dst/src1/src2 %shl-imm ;
 M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ;
 M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ;
 M: ##not     generate-insn dst/src       %not     ;
+M: ##log2    generate-insn dst/src       %log2    ;
+
+: src1/src2 ( insn -- src1 src2 )
+    [ src1>> register ] [ src2>> register ] bi ; inline
+
+: src1/src2/temp1/temp2 ( insn -- src1 src2 temp1 temp2 )
+    [ src1/src2 ] [ temp1>> register ] [ temp2>> register ] tri ; inline
+
+M: ##fixnum-add generate-insn src1/src2 %fixnum-add ;
+M: ##fixnum-add-tail generate-insn src1/src2 %fixnum-add-tail ;
+M: ##fixnum-sub generate-insn src1/src2 %fixnum-sub ;
+M: ##fixnum-sub-tail generate-insn src1/src2 %fixnum-sub-tail ;
+M: ##fixnum-mul generate-insn src1/src2/temp1/temp2 %fixnum-mul ;
+M: ##fixnum-mul-tail generate-insn src1/src2/temp1/temp2 %fixnum-mul-tail ;
 
 : dst/src/temp ( insn -- dst src temp )
     [ dst/src ] [ temp>> register ] bi ; inline
@@ -215,6 +237,10 @@ M: _gc generate-insn drop %gc ;
 
 M: ##loop-entry generate-insn drop %loop-entry ;
 
+M: ##alien-global generate-insn
+    [ dst>> register ] [ symbol>> ] [ library>> ] tri
+    %alien-global ;
+
 ! ##alien-invoke
 GENERIC: reg-size ( register-class -- n )
 
@@ -264,7 +290,7 @@ M: object reg-class-full?
 
 : spill-param ( reg-class -- n reg-class )
     stack-params get
-    >r reg-size cell align stack-params +@ r>
+    [ reg-size cell align stack-params +@ ] dip
     stack-params ;
 
 : fastcall-param ( reg-class -- n reg-class )
@@ -300,10 +326,10 @@ M: long-long-type flatten-value-type ( type -- types )
     ] { } make ;
 
 : each-parameter ( parameters quot -- )
-    >r [ parameter-sizes nip ] keep r> 2each ; inline
+    [ [ parameter-sizes nip ] keep ] dip 2each ; inline
 
 : reverse-each-parameter ( parameters quot -- )
-    >r [ parameter-sizes nip ] keep r> 2reverse-each ; inline
+    [ [ parameter-sizes nip ] keep ] dip 2reverse-each ; inline
 
 : reset-freg-counts ( -- )
     { int-regs float-regs stack-params } [ 0 swap set ] each ;
@@ -316,15 +342,13 @@ M: long-long-type flatten-value-type ( type -- types )
     #! Moves values from C stack to registers (if word is
     #! %load-param-reg) and registers to C stack (if word is
     #! %save-param-reg).
-    >r
-    alien-parameters
-    flatten-value-types
-    r> '[ alloc-parameter _ execute ] each-parameter ;
-    inline
+    [ alien-parameters flatten-value-types ]
+    [ '[ alloc-parameter _ execute ] ]
+    bi* each-parameter ; inline
 
 : unbox-parameters ( offset node -- )
     parameters>> [
-        %prepare-unbox >r over + r> unbox-parameter
+        %prepare-unbox [ over + ] dip unbox-parameter
     ] reverse-each-parameter drop ;
 
 : prepare-box-struct ( node -- offset )
@@ -432,7 +456,7 @@ M: ##alien-indirect generate-insn
 
 TUPLE: callback-context ;
 
-: current-callback 2 getenv ;
+: current-callback ( -- id ) 2 getenv ;
 
 : wait-to-return ( token -- )
     dup current-callback eq? [
@@ -491,9 +515,10 @@ M: _label generate-insn
 M: _branch generate-insn
     label>> lookup-label %jump-label ;
 
-: >compare< ( insn -- label cc src1 src2 )
+: >compare< ( insn -- dst temp cc src1 src2 )
     {
         [ dst>> register ]
+        [ temp>> register ]
         [ cc>> ]
         [ src1>> register ]
         [ src2>> ?register ]
index b25f1fa8fe7da8b29cbf8caec42e565cdea871cb..a56ae04a7b87de4248285afa0c7e426fe30f5bd8 100755 (executable)
@@ -9,7 +9,7 @@ IN: compiler.codegen.fixup
 
 GENERIC: fixup* ( obj -- )
 
-: code-format 22 getenv ;
+: code-format ( -- n ) 22 getenv ;
 
 : compiled-offset ( -- n ) building get length code-format * ;
 
@@ -46,28 +46,27 @@ M: integer fixup* , ;
 : indq ( elt seq -- n ) [ eq? ] with find drop ;
 
 : adjoin* ( obj table -- n )
-    2dup indq [ 2nip ] [ dup length >r push r> ] if* ;
+    2dup indq [ 2nip ] [ dup length [ push ] dip ] if* ;
 
 SYMBOL: literal-table
 
 : add-literal ( obj -- n ) literal-table get adjoin* ;
 
 : add-dlsym-literals ( symbol dll -- )
-    >r string>symbol r> 2array literal-table get push-all ;
+    [ string>symbol ] dip 2array literal-table get push-all ;
 
 : rel-dlsym ( name dll class -- )
-    >r literal-table get length >r
-    add-dlsym-literals
-    r> r> rt-dlsym rel-fixup ;
+    [ literal-table get length [ add-dlsym-literals ] dip ] dip
+    rt-dlsym rel-fixup ;
 
 : rel-word ( word class -- )
-    >r add-literal r> rt-xt rel-fixup ;
+    [ add-literal ] dip rt-xt rel-fixup ;
 
 : rel-primitive ( word class -- )
-    >r def>> first r> rt-primitive rel-fixup ;
+    [ def>> first ] dip rt-primitive rel-fixup ;
 
-: rel-literal ( literal class -- )
-    >r add-literal r> rt-literal rel-fixup ;
+: rel-immediate ( literal class -- )
+    [ add-literal ] dip rt-immediate rel-fixup ;
 
 : rel-this ( class -- )
     0 swap rt-label rel-fixup ;
index 86c1f6504900f359cd84fd0c89a7f328ed853921..48ea958818a38fd4344256163565941513421f41 100644 (file)
@@ -39,13 +39,12 @@ IN: compiler.constants
 ! Relocation types
 : rt-primitive   0 ; inline
 : rt-dlsym       1 ; inline
-: rt-literal     2 ; inline
-: rt-dispatch    3 ; inline
-: rt-xt          4 ; inline
-: rt-here        5 ; inline
-: rt-label       6 ; inline
-: rt-immediate   7 ; inline
-: rt-stack-chain 8 ; inline
+: rt-dispatch    2 ; inline
+: rt-xt          3 ; inline
+: rt-here        4 ; inline
+: rt-label       5 ; inline
+: rt-immediate   6 ; inline
+: rt-stack-chain 7 ; inline
 
 : rc-absolute? ( n -- ? )
     [ rc-absolute-ppc-2/2 = ]
index abcdb46ea2744e532c1773bb3a382fe285538bf3..230a7bf54213379bd5fcc0ccd66c31c05c4ed049 100644 (file)
@@ -3,7 +3,8 @@ USING: alien alien.c-types alien.syntax compiler kernel
 namespaces namespaces tools.test sequences stack-checker
 stack-checker.errors words arrays parser quotations
 continuations effects namespaces.private io io.streams.string
-memory system threads tools.test math accessors combinators ;
+memory system threads tools.test math accessors combinators
+specialized-arrays.float ;
 
 FUNCTION: void ffi_test_0 ;
 [ ] [ ffi_test_0 ] unit-test
@@ -196,7 +197,11 @@ FUNCTION: int ffi_test_12 int a int b rect c int d int e int f ;
 
 FUNCTION: float ffi_test_23 ( float[3] x, float[3] y ) ;
 
-[ 32.0 ] [ { 1.0 2.0 3.0 } >c-float-array { 4.0 5.0 6.0 } >c-float-array ffi_test_23 ] unit-test
+[ 32.0 ] [
+    { 1.0 2.0 3.0 } >float-array underlying>>
+    { 4.0 5.0 6.0 } >float-array underlying>>
+    ffi_test_23
+] unit-test
 
 ! Test odd-size structs
 C-STRUCT: test-struct-1 { { "char" 1 } "x" } ;
index a56ee55c82df5838188e1077bea8247fac944fb0..e743c8484bc3c2cc1e9786e5822380ab27bc822e 100644 (file)
@@ -3,7 +3,7 @@ kernel.private math hashtables.private math.private namespaces
 sequences sequences.private tools.test namespaces.private
 slots.private sequences.private byte-arrays alien
 alien.accessors layouts words definitions compiler.units io
-combinators vectors float-arrays ;
+combinators vectors grouping make ;
 IN: compiler.tests
 
 ! Originally, this file did black box testing of templating
@@ -241,3 +241,38 @@ TUPLE: id obj ;
 
 [ "a" ] [ 1 test-2 ] unit-test
 [ "b" ] [ 2 test-2 ] unit-test
+
+! I accidentally fixnum/i-fast on PowerPC
+[ { { 1 2 } { 3 4 } } ] [
+    { 1 2 3 4 }
+    [
+        [ { array } declare 2 <groups> [ , ] each ] compile-call
+    ] { } make
+] unit-test
+
+[ 2 ] [
+    { 1 2 3 4 }
+    [ { array } declare 2 <groups> length ] compile-call
+] unit-test
+
+! Oops with new intrinsics
+: fixnum-overflow-control-flow-test ( a b -- c )
+    [ 1 fixnum- ] [ 2 fixnum- ] if 3 fixnum+fast ;
+
+[ 3 ] [ 1 t fixnum-overflow-control-flow-test ] unit-test
+[ 2 ] [ 1 f fixnum-overflow-control-flow-test ] unit-test
+
+! LOL
+: blah ( a -- b )
+    { float } declare dup 0 =
+    [ drop 1 ] [
+        dup 0 >=
+        [ 2 "double" "libm" "pow" { "double" "double" } alien-invoke ]
+        [ -0.5 "double" "libm" "pow" { "double" "double" } alien-invoke ]
+        if
+    ] if ;
+
+[ 4.0 ] [ 2.0 blah ] unit-test
+
+[ 4 ] [ 2 [ dup fixnum* ] compile-call ] unit-test
+[ 7 ] [ 2 [ dup fixnum* 3 fixnum+fast ] compile-call ] unit-test
index c90a31fc612176e966dd9ddbd3aca1c26536869b..df5f484952b71a1df3c73cba2887ab1a9e6e98a8 100644 (file)
@@ -160,6 +160,11 @@ IN: compiler.tests
 [ -2 ] [ 4 [ -2 fixnum/i ] compile-call ] unit-test
 [ 3 1 ] [ 10 3 [ fixnum/mod ] compile-call ] unit-test
 
+[ 2 ] [ 4 2 [ fixnum/i-fast ] compile-call ] unit-test
+[ 2 ] [ 4 [ 2 fixnum/i-fast ] compile-call ] unit-test
+[ -2 ] [ 4 [ -2 fixnum/i-fast ] compile-call ] unit-test
+[ 3 1 ] [ 10 3 [ fixnum/mod-fast ] compile-call ] unit-test
+
 [ 4 ] [ 1 3 [ fixnum+ ] compile-call ] unit-test
 [ 4 ] [ 1 [ 3 fixnum+ ] compile-call ] unit-test
 [ 4 ] [ [ 1 3 fixnum+ ] compile-call ] unit-test
@@ -208,6 +213,7 @@ IN: compiler.tests
 [ -1 ] [ [ -123 -64 fixnum-shift ] compile-call ] unit-test
 [ -1 ] [ -123 -64 [ fixnum-shift ] compile-call ] unit-test
 
+[ HEX: 10000000 ] [ HEX: 1000000 HEX: 10 [ fixnum* ] compile-call ] unit-test
 [ HEX: 10000000 ] [ HEX: -10000000 >fixnum [ 0 swap fixnum- ] compile-call ] unit-test
 [ HEX: 10000000 ] [ HEX: -fffffff >fixnum [ 1 swap fixnum- ] compile-call ] unit-test
 
index f1b3e32eeda2b8c17ceaf40e873719fa8494cb9f..41df6e7ae589d9f93a10c461da22853ddddce528 100644 (file)
@@ -286,9 +286,7 @@ HINTS: recursive-inline-hang-2 array ;
 HINTS: recursive-inline-hang-3 array ;
 
 ! Regression
-USE: sequences.private
-
-[ ] [ { (3append) } compile ] unit-test
+[ ] [ { 3append-as } compile ] unit-test
 
 ! Wow
 : counter-example ( a b c d -- a' b' c' d' )
index 156fdfff028a4d9d3e4b0569125185db67eaecc4..ee8c2f056a97fecd2611224e24243b6595c63fce 100644 (file)
@@ -1,5 +1,5 @@
 USING: math.private kernel combinators accessors arrays
-generalizations float-arrays tools.test ;
+generalizations tools.test ;
 IN: compiler.tests
 
 : float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b )
index 4e79c4cd2d2a6d06306e2a7b267f2446f7e14ad1..b7152234452227e02cc5aa26805a0da2547c3b2d 100644 (file)
@@ -21,7 +21,7 @@ IN: compiler.tree.builder
 : build-tree-with ( in-stack quot -- nodes out-stack )
     #! Not safe to call from inference transforms.
     [
-        [ >vector meta-d set ]
+        [ >vector meta-d set ]
         [ f initial-recursive-state infer-quot ] bi*
     ] with-tree-builder nip
     unclip-last in-d>> ;
index 4a6198db37d99a4a5a79360d0dc0a3c2d34639d8..71c6fb56752943e859d0e6ce789433efa7898489 100644 (file)
@@ -71,7 +71,7 @@ M: object xyz ;
     2over fixnum>= [
         3drop
     ] [
-        [ swap >r call 1 fixnum+fast r> ] keep (fx-repeat)
+        [ swap [ call 1 fixnum+fast ] dip ] keep (fx-repeat)
     ] if ; inline recursive
 
 : fx-repeat ( n quot -- )
@@ -87,10 +87,10 @@ M: object xyz ;
     2over dup xyz drop >= [
         3drop
     ] [
-        [ swap >r call 1+ r> ] keep (i-repeat)
+        [ swap [ call 1+ ] dip ] keep (i-repeat)
     ] if ; inline recursive
 
-: i-repeat >r { integer } declare r> 0 -rot (i-repeat) ; inline
+: i-repeat [ { integer } declare ] dip 0 -rot (i-repeat) ; inline
 
 [ t ] [
     [ [ dup xyz drop ] i-repeat ] \ xyz inlined?
@@ -194,7 +194,7 @@ M: fixnum annotate-entry-test-1 drop ;
     2dup >= [
         2drop
     ] [
-        >r dup annotate-entry-test-1 1+ r> (annotate-entry-test-2)
+        [ dup annotate-entry-test-1 1+ ] dip (annotate-entry-test-2)
     ] if ; inline recursive
 
 : annotate-entry-test-2 0 -rot (annotate-entry-test-2) ; inline
@@ -448,7 +448,7 @@ cell-bits 32 = [
 ] unit-test
 
 [ ] [
-    [ [ >r "A" throw r> ] [ "B" throw ] if ]
+    [ [ [ "A" throw ] dip ] [ "B" throw ] if ]
     cleaned-up-tree drop
 ] unit-test
 
@@ -463,7 +463,7 @@ cell-bits 32 = [
 : buffalo-wings ( i seq -- )
     2dup < [
         2dup chicken-fingers
-        >r 1+ r> buffalo-wings
+        [ 1+ ] dip buffalo-wings
     ] [
         2drop
     ] if ; inline recursive
@@ -482,7 +482,7 @@ cell-bits 32 = [
 : ribs ( i seq -- )
     2dup < [
         steak
-        >r 1+ r> ribs
+        [ 1+ ] dip ribs
     ] [
         2drop
     ] if ; inline recursive
index becac01cd5355a957e857d47849dc68c912c71e4..1b0343faa991400e09a0c2b5799b1438b31c1851 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors sequences sequences.deep combinators fry
+USING: kernel accessors sequences combinators fry
 classes.algebra namespaces assocs words math math.private
 math.partial-dispatch math.intervals classes classes.tuple
 classes.tuple.private layouts definitions stack-checker.state
 stack-checker.branches
+compiler.utilities
 compiler.tree
 compiler.tree.combinators
 compiler.tree.propagation.info
@@ -33,7 +34,7 @@ GENERIC: cleanup* ( node -- node/nodes )
 : cleanup ( nodes -- nodes' )
     #! We don't recurse into children here, instead the methods
     #! do it since the logic is a bit more involved
-    [ cleanup* ] map flatten ;
+    [ cleanup* ] map-flat ;
 
 : cleanup-folding? ( #call -- ? )
     node-output-infos
index 40bbf81a03710a4ac7afa7c0c70258d0838f666d..030df8484fa164884320ec7345f80c744bf1b1df 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs fry kernel accessors sequences sequences.deep arrays
-stack-checker.inlining namespaces compiler.tree ;
+USING: assocs fry kernel accessors sequences compiler.utilities
+arrays stack-checker.inlining namespaces compiler.tree
+math.order ;
 IN: compiler.tree.combinators
 
 : each-node ( nodes quot: ( node -- ) -- )
@@ -27,7 +28,7 @@ IN: compiler.tree.combinators
                 [ _ map-nodes ] change-child
             ] when
         ] if
-    ] map flatten ; inline recursive
+    ] map-flat ; inline recursive
 
 : contains-node? ( nodes quot: ( node -- ? ) -- ? )
     dup dup '[
@@ -48,12 +49,6 @@ IN: compiler.tree.combinators
 : sift-children ( seq flags -- seq' )
     zip [ nip ] assoc-filter keys ;
 
-: (3each) [ 3array flip ] dip '[ first3 @ ] ; inline
-
-: 3each ( seq1 seq2 seq3 quot -- seq ) (3each) each ; inline
-
-: 3map ( seq1 seq2 seq3 quot -- seq ) (3each) map ; inline
-
 : until-fixed-point ( #recursive quot: ( node -- ) -- )
     over label>> t >>fixed-point drop
     [ with-scope ] 2keep
index 7b15fdf8563bdb1b82da3ca91d8c0ac4d0e84d62..b64e30d8f94394a9ac5914fe95035504a3ea4a94 100644 (file)
@@ -75,9 +75,9 @@ IN: compiler.tree.dead-code.tests
     remove-dead-code
     "no-check" get [ dup check-nodes ] unless nodes>quot ;
 
-[ [ drop 1 ] ] [ [ >r 1 r> drop ] optimize-quot ] unit-test
+[ [ drop 1 ] ] [ [ [ 1 ] dip drop ] optimize-quot ] unit-test
 
-[ [ read drop 1 2 ] ] [ [ read >r 1 2 r> drop ] optimize-quot ] unit-test
+[ [ read drop 1 2 ] ] [ [ read [ 1 2 ] dip drop ] optimize-quot ] unit-test
 
 [ [ over >r + r> ] ] [ [ [ + ] [ drop ] 2bi ] optimize-quot ] unit-test
 
index 44b71935c8f0fea7a6be46e18bf409329cf6bc9f..9ece5d340b60d497c1ee91b65483d48f6e3b277e 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry accessors namespaces assocs deques search-deques
-dlists kernel sequences sequences.deep words sets
+dlists kernel sequences compiler.utilities words sets
 stack-checker.branches compiler.tree compiler.tree.def-use
 compiler.tree.combinators ;
 IN: compiler.tree.dead-code.liveness
@@ -49,4 +49,4 @@ GENERIC: remove-dead-code* ( node -- node' )
 M: node remove-dead-code* ;
 
 : (remove-dead-code) ( nodes -- nodes' )
-    [ remove-dead-code* ] map flatten ;
+    [ remove-dead-code* ] map-flat ;
index a1d87734843f14af03f258b551c4a51b68d0dad4..8d764a28333c81d7092163e8f51e4c7b9fe33132 100644 (file)
@@ -93,7 +93,7 @@ M: #shuffle node>quot
         [ drop "COMPLEX SHUFFLE" , ]
     } cond ;
 
-M: #push node>quot literal>> , ;
+M: #push node>quot literal>> literalize , ;
 
 M: #call node>quot word>> , ;
 
@@ -125,9 +125,13 @@ M: node node>quot drop ;
 : nodes>quot ( node -- quot )
     [ [ node>quot ] each ] [ ] make ;
 
-: optimized. ( quot/word -- )
-    dup word? [ specialized-def ] when
-    build-tree optimize-tree nodes>quot . ;
+GENERIC: optimized. ( quot/word -- )
+
+M: method-spec optimized. first2 method optimized. ;
+
+M: word optimized. specialized-def optimized. ;
+
+M: callable optimized. build-tree optimize-tree nodes>quot . ;
 
 SYMBOL: words-called
 SYMBOL: generics-called
index edfe633057b72e99ad9f2b071581319f623f930f..9b2a2038da5a26512cce9a56aa09183fb7aaffba 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences sequences.deep kernel
+USING: sequences kernel fry vectors
 compiler.tree compiler.tree.def-use ;
 IN: compiler.tree.def-use.simplified
 
@@ -9,8 +9,6 @@ IN: compiler.tree.def-use.simplified
 ! A 'real' usage is a usage of a value that is not a #renaming.
 TUPLE: real-usage value node ;
 
-GENERIC: actually-used-by* ( value node -- real-usages )
-
 ! Def
 GENERIC: actually-defined-by* ( value node -- real-usage )
 
@@ -25,16 +23,18 @@ M: #return-recursive actually-defined-by* real-usage boa ;
 M: node actually-defined-by* real-usage boa ;
 
 ! Use
-: (actually-used-by) ( value -- real-usages )
-    dup used-by [ actually-used-by* ] with map ;
+GENERIC# actually-used-by* 1 ( value node accum -- )
+
+: (actually-used-by) ( value accum -- )
+    [ [ used-by ] keep ] dip '[ _ swap _ actually-used-by* ] each ;
 
 M: #renaming actually-used-by*
-    inputs/outputs [ indices ] dip nths
-    [ (actually-used-by) ] map ;
+    [ inputs/outputs [ indices ] dip nths ] dip
+    '[ _ (actually-used-by) ] each ;
 
-M: #return-recursive actually-used-by* real-usage boa ;
+M: #return-recursive actually-used-by* [ real-usage boa ] dip push ;
 
-M: node actually-used-by* real-usage boa ;
+M: node actually-used-by* [ real-usage boa ] dip push ;
 
 : actually-used-by ( value -- real-usages )
-    (actually-used-by) flatten ;
+    10 <vector> [ (actually-used-by) ] keep ;
index b728e9a1ba4b597def7482835d831f3e8b476303..2eee3e698bbfe9f428dcb868f5f3ec487a5a1eab 100644 (file)
@@ -33,4 +33,4 @@ M: #branch escape-analysis*
     2bi ;
 
 M: #phi escape-analysis*
-    [ phi-in-d>> <flipped> ] [ out-d>> ] bi merge-allocations ;
+    [ phi-in-d>> flip ] [ out-d>> ] bi merge-allocations ;
diff --git a/basis/compiler/tree/escape-analysis/check/check.factor b/basis/compiler/tree/escape-analysis/check/check.factor
new file mode 100644 (file)
index 0000000..333b3fa
--- /dev/null
@@ -0,0 +1,23 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: classes classes.tuple math math.private accessors
+combinators kernel compiler.tree compiler.tree.combinators
+compiler.tree.propagation.info ;
+IN: compiler.tree.escape-analysis.check
+
+GENERIC: run-escape-analysis* ( node -- ? )
+
+M: #push run-escape-analysis*
+    literal>> [ class immutable-tuple-class? ] [ complex? ] bi or ;
+
+M: #call run-escape-analysis*
+    {
+        { [ dup word>> \ <complex> eq? ] [ t ] }
+        { [ dup immutable-tuple-boa? ] [ t ] }
+        [ f ] 
+    } cond nip ;
+
+M: node run-escape-analysis* drop f ;
+
+: run-escape-analysis? ( nodes -- ? )
+    [ run-escape-analysis* ] contains-node? ;
index 16a27e020a13dfa6b8aab38619ba74638d1eedc5..ecd5429bafeb586e05d696ea0344a173eb3aba83 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors sequences words memoize classes.builtin
+USING: kernel accessors sequences words memoize combinators
+classes classes.builtin classes.tuple math.partial-dispatch
 fry assocs
 compiler.tree
 compiler.tree.combinators
@@ -12,7 +13,7 @@ IN: compiler.tree.finalization
 ! See the comment in compiler.tree.late-optimizations.
 
 ! This pass runs after propagation, so that it can expand
-! built-in type predicates; these cannot be expanded before
+! type predicates; these cannot be expanded before
 ! propagation since we need to see 'fixnum?' instead of
 ! 'tag 0 eq?' and so on, for semantic reasoning.
 
@@ -33,16 +34,24 @@ M: #shuffle finalize*
     [ [ in-r>> ] [ out-r>> ] [ mapping>> ] tri '[ _ at ] map sequence= ]
     bi and [ drop f ] when ;
 
-: builtin-predicate? ( #call -- ? )
-    word>> "predicating" word-prop builtin-class? ;
-
-MEMO: builtin-predicate-expansion ( word -- nodes )
+MEMO: cached-expansion ( word -- nodes )
     def>> splice-final ;
 
-: expand-builtin-predicate ( #call -- nodes )
-    word>> builtin-predicate-expansion ;
+GENERIC: finalize-word ( #call word -- nodes )
+
+M: predicate finalize-word
+    "predicating" word-prop {
+        { [ dup builtin-class? ] [ drop word>> cached-expansion ] }
+        { [ dup tuple-class? ] [ drop word>> def>> splice-final ] }
+        [ drop ]
+    } cond ;
+
+! M: math-partial finalize-word
+!     dup primitive? [ drop ] [ nip cached-expansion ] if ;
+
+M: word finalize-word drop ;
 
 M: #call finalize*
-    dup builtin-predicate? [ expand-builtin-predicate ] when ;
+    dup word>> finalize-word ;
 
 M: node finalize* ;
index c4a97fcc92a09a9b4337edb0fd8feab768bab494..5ac3c57abed18f0948335c50cfbaea511d430f7e 100644 (file)
@@ -34,8 +34,8 @@ sequences accessors tools.test kernel math ;
 [ ] [ [ [ 1 ] [ 2 ] if + * ] test-normalization ] unit-test
 
 DEFER: bbb
-: aaa ( x -- ) dup [ dup >r bbb r> aaa ] [ drop ] if ; inline recursive
-: bbb ( x -- ) >r drop 0 r> aaa ; inline recursive
+: aaa ( x -- ) dup [ dup [ bbb ] dip aaa ] [ drop ] if ; inline recursive
+: bbb ( x -- ) [ drop 0 ] dip aaa ; inline recursive
 
 [ ] [ [ bbb ] test-normalization ] unit-test
 
index bebe2e91b6521eb19ac1860566371f182b00c028..8c13de296a05952f9ebe1ff17c147981fde40682 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry namespaces sequences math accessors kernel arrays
-combinators sequences.deep assocs
+combinators compiler.utilities assocs
 stack-checker.backend
 stack-checker.branches
 stack-checker.inlining
+compiler.utilities
 compiler.tree
 compiler.tree.combinators
 compiler.tree.normalization.introductions
@@ -46,7 +47,7 @@ M: #branch normalize*
     [
         [
             [
-                [ normalize* ] map flatten
+                [ normalize* ] map-flat
                 introduction-stack get
                 2array
             ] with-scope
@@ -70,7 +71,7 @@ M: #phi normalize*
 
 : (normalize) ( nodes introductions -- nodes )
     introduction-stack [
-        [ normalize* ] map flatten
+        [ normalize* ] map-flat
     ] with-variable ;
 
 M: #recursive normalize*
index e37323a2ec69c4991e5497a27e2e1f5e583adf94..54c6c2c117b9c48ba58355ed72c4b605ed6f7ce8 100644 (file)
@@ -6,6 +6,7 @@ compiler.tree.normalization
 compiler.tree.propagation
 compiler.tree.cleanup
 compiler.tree.escape-analysis
+compiler.tree.escape-analysis.check
 compiler.tree.tuple-unboxing
 compiler.tree.identities
 compiler.tree.def-use
@@ -22,8 +23,10 @@ SYMBOL: check-optimizer?
     normalize
     propagate
     cleanup
-    escape-analysis
-    unbox-tuples
+    dup run-escape-analysis? [
+        escape-analysis
+        unbox-tuples
+    ] when
     apply-identities
     compute-def-use
     remove-dead-code
index 424cd8a01c404c25ace5a54047621ee9764b4779..f2613022fc21be595dda41ae6bc06a48c2f5d3ed 100644 (file)
@@ -3,6 +3,7 @@
 USING: fry kernel sequences assocs accessors namespaces
 math.intervals arrays classes.algebra combinators columns
 stack-checker.branches
+compiler.utilities
 compiler.tree
 compiler.tree.combinators
 compiler.tree.propagation.info
@@ -78,7 +79,7 @@ SYMBOL: condition-value
 
 M: #phi propagate-before ( #phi -- )
     [ annotate-phi-inputs ]
-    [ [ phi-info-d>> <flipped> ] [ out-d>> ] bi merge-value-infos ]
+    [ [ phi-info-d>> flip ] [ out-d>> ] bi merge-value-infos ]
     bi ;
 
 : branch-phi-constraints ( output values booleans -- )
@@ -137,8 +138,8 @@ M: #phi propagate-before ( #phi -- )
 M: #phi propagate-after ( #phi -- )
     condition-value get [
         [ out-d>> ]
-        [ phi-in-d>> <flipped> ]
-        [ phi-info-d>> <flipped> ] tri
+        [ phi-in-d>> flip ]
+        [ phi-info-d>> flip ] tri
         [
             [ possible-boolean-values ] map
             branch-phi-constraints
index 2452aba4aa2e8e3ea706ee1b897796c368613cc6..53b7d17326bb2d90e60c42b014dd92818c90447a 100644 (file)
@@ -49,7 +49,7 @@ M: #renaming compute-copy-equiv* inputs/outputs are-copies-of ;
     ] 2each ;
 
 M: #phi compute-copy-equiv*
-    [ phi-in-d>> <flipped> ] [ out-d>> ] bi compute-phi-equiv ;
+    [ phi-in-d>> flip ] [ out-d>> ] bi compute-phi-equiv ;
 
 M: node compute-copy-equiv* drop ;
 
index 8397a5fdbb4d1a0bfff542f289eee0ac866c8293..fcc3b01dc046cdf818ac4c4df52f1b3ddc166962 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors kernel arrays sequences math math.order
 math.partial-dispatch generic generic.standard generic.math
 classes.algebra classes.union sets quotations assocs combinators
-words namespaces continuations
+words namespaces continuations classes fry
 compiler.tree
 compiler.tree.builder
 compiler.tree.recursive
@@ -20,13 +20,17 @@ SYMBOL: node-count
 : count-nodes ( nodes -- )
     0 swap [ drop 1+ ] each-node node-count set ;
 
+! We try not to inline the same word too many times, to avoid
+! combinatorial explosion
+SYMBOL: inlining-count
+
 ! Splicing nodes
 GENERIC: splicing-nodes ( #call word/quot/f -- nodes )
 
 M: word splicing-nodes
     [ [ in-d>> ] [ out-d>> ] bi ] dip #call 1array ;
 
-M: quotation splicing-nodes
+M: callable splicing-nodes
     build-sub-tree analyze-recursive normalize ;
 
 : propagate-body ( #call -- )
@@ -85,6 +89,8 @@ DEFER: (flat-length)
 
 : word-flat-length ( word -- n )
     {
+        ! special-case
+        { [ dup { dip 2dip 3dip } memq? ] [ drop 1 ] }
         ! not inline
         { [ dup inline? not ] [ drop 1 ] }
         ! recursive and inline
@@ -118,17 +124,25 @@ DEFER: (flat-length)
         bi and
     ] contains? ;
 
+: node-count-bias ( -- n )
+    45 node-count get [-] 8 /i ;
+
+: body-length-bias ( word -- n )
+    [ flat-length ] [ inlining-count get at 0 or ] bi
+    over 2 <= [ drop ] [ 2/ 1+ * ] if 24 swap [-] 4 /i ;
+
 : inlining-rank ( #call word -- n )
     [ classes-known? 2 0 ? ]
     [
         {
-            [ drop node-count get 45 swap [-] 8 /i ]
-            [ flat-length 24 swap [-] 4 /i ]
+            [ body-length-bias ]
             [ "default" word-prop -4 0 ? ]
             [ "specializer" word-prop 1 0 ? ]
             [ method-body? 1 0 ? ]
         } cleave
-    ] bi* + + + + + ;
+        node-count-bias
+        loop-nesting get 0 or 2 *
+    ] bi* + + + + + + ;
 
 : should-inline? ( #call word -- ? )
     dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ;
@@ -136,20 +150,23 @@ DEFER: (flat-length)
 SYMBOL: history
 
 : remember-inlining ( word -- )
-    history [ swap suffix ] change ;
+    [ [ 1 ] dip inlining-count get at+ ]
+    [ history [ swap suffix ] change ]
+    bi ;
 
-: inline-word ( #call word -- ? )
-    dup history get memq? [
-        2drop f
-    ] [
+: inline-word-def ( #call word quot -- ? )
+    over history get memq? [ 3drop f ] [
         [
-            dup remember-inlining
-            dupd def>> splicing-nodes >>body
+            swap remember-inlining
+            dupd splicing-nodes >>body
             propagate-body
         ] with-scope
         t
     ] if ;
 
+: inline-word ( #call word -- ? )
+    dup def>> inline-word-def ;
+
 : inline-method-body ( #call word -- ? )
     2dup should-inline? [ inline-word ] [ 2drop f ] if ;
 
@@ -163,7 +180,11 @@ SYMBOL: history
     [ dup 1array ] [ "custom-inlining" word-prop ] bi* with-datastack
     first object swap eliminate-dispatch ;
 
-: do-inlining ( #call word -- ? )
+: inline-instance-check ( #call word -- ? )
+    over in-d>> second value-info literal>> dup class?
+    [ "predicate" word-prop '[ drop @ ] inline-word-def ] [ 3drop f ] if ;
+
+: (do-inlining) ( #call word -- ? )
     #! If the generic was defined in an outer compilation unit,
     #! then it doesn't have a definition yet; the definition
     #! is built at the end of the compilation unit. We do not
@@ -174,10 +195,17 @@ SYMBOL: history
     #! discouraged, but it should still work.)
     {
         { [ dup deferred? ] [ 2drop f ] }
-        { [ dup custom-inlining? ] [ inline-custom ] }
+        { [ dup \ instance? eq? ] [ inline-instance-check ] }
         { [ dup always-inline-word? ] [ inline-word ] }
         { [ dup standard-generic? ] [ inline-standard-method ] }
         { [ dup math-generic? ] [ inline-math-method ] }
         { [ dup method-body? ] [ inline-method-body ] }
         [ 2drop f ]
     } cond ;
+
+: do-inlining ( #call word -- ? )
+    #! Note the logic here: if there's a custom inlining hook,
+    #! it is permitted to return f, which means that we try the
+    #! normal inlining heuristic.
+    dup custom-inlining? [ 2dup inline-custom ] [ f ] if
+    [ 2drop t ] [ (do-inlining) ] if ;
index f6e2bc0940867861881231267658199c8f94347c..8242311287e0cbbf1b62b1074820597f552beca2 100644 (file)
@@ -5,7 +5,7 @@ math.partial-dispatch math.intervals math.parser math.order
 layouts words sequences sequences.private arrays assocs classes
 classes.algebra combinators generic.math splitting fry locals
 classes.tuple alien.accessors classes.tuple.private slots.private
-definitions
+definitions strings.private vectors hashtables
 stack-checker.state
 compiler.tree.comparisons
 compiler.tree.propagation.info
@@ -37,31 +37,6 @@ most-negative-fixnum most-positive-fixnum [a,b]
 
 \ bitnot { integer } "input-classes" set-word-prop
 
-{
-    fcosh
-    flog
-    fsinh
-    fexp
-    fasin
-    facosh
-    fasinh
-    ftanh
-    fatanh
-    facos
-    fpow
-    fatan
-    fatan2
-    fcos
-    ftan
-    fsin
-    fsqrt
-} [
-    dup stack-effect
-    [ in>> length real <repetition> "input-classes" set-word-prop ]
-    [ out>> length float <repetition> "default-output-classes" set-word-prop ]
-    2bi
-] each
-
 : ?change-interval ( info quot -- quot' )
     over interval>> [ [ clone ] dip change-interval ] [ 2drop ] if ; inline
 
@@ -169,10 +144,9 @@ most-negative-fixnum most-positive-fixnum [a,b]
 comparison-ops
 [ dup '[ _ define-comparison-constraints ] each-derived-op ] each
 
-generic-comparison-ops [
-    dup specific-comparison
-    '[ _ _ define-comparison-constraints ] each-derived-op
-] each
+! generic-comparison-ops [
+!     dup specific-comparison define-comparison-constraints
+! ] each
 
 ! Remove redundant comparisons
 : fold-comparison ( info1 info2 word -- info )
@@ -220,10 +194,22 @@ generic-comparison-ops [
     2bi and maybe-or-never
 ] "outputs" set-word-prop
 
+\ both-fixnums? [
+    [ class>> fixnum classes-intersect? not ] either?
+    f <literal-info> object-info ?
+] "outputs" set-word-prop
+
 {
     { >fixnum fixnum }
+    { bignum>fixnum fixnum }
+
     { >bignum bignum }
+    { fixnum>bignum bignum }
+    { float>bignum bignum }
+
     { >float float }
+    { fixnum>float float }
+    { bignum>float float }
 } [
     '[
         _
@@ -261,6 +247,10 @@ generic-comparison-ops [
     ] "custom-inlining" set-word-prop
 ] each
 
+\ string-nth [
+    2drop fixnum 0 23 2^ [a,b] <class/interval-info>
+] "outputs" set-word-prop
+
 {
     alien-signed-1
     alien-unsigned-1
@@ -302,6 +292,15 @@ generic-comparison-ops [
     "outputs" set-word-prop
 ] each
 
+! Generate more efficient code for common idiom
+\ clone [
+    in-d>> first value-info literal>> {
+        { V{ } [ [ drop { } 0 vector boa ] ] }
+        { H{ } [ [ drop hashtable new ] ] }
+        [ drop f ]
+    } case
+] "custom-inlining" set-word-prop
+
 \ slot [
     dup literal?>>
     [ literal>> swap value-info-slot ] [ 2drop object-info ] if
index 9e4d99e462abfefa35038b97e0eae8b3a9cee474..d676102bdea6270fb5d460752f625d18394e2c12 100644 (file)
@@ -6,6 +6,8 @@ compiler.tree.propagation.copy
 compiler.tree.propagation.info ;
 IN: compiler.tree.propagation.nodes
 
+SYMBOL: loop-nesting
+
 GENERIC: propagate-before ( node -- )
 
 GENERIC: propagate-after ( node -- )
index 760ff167aa8072e9cbb6be08bc3999a056e5d5a6..aa04b58de71b3517e77c671c4d4e58e3b1deb151 100644 (file)
@@ -8,7 +8,8 @@ math.functions math.private strings layouts
 compiler.tree.propagation.info compiler.tree.def-use
 compiler.tree.debugger compiler.tree.checker
 slots.private words hashtables classes assocs locals
-float-arrays system sorting ;
+specialized-arrays.double system sorting math.libm
+math.intervals ;
 IN: compiler.tree.propagation.tests
 
 \ propagate must-infer
@@ -167,7 +168,8 @@ IN: compiler.tree.propagation.tests
 
 [ V{ fixnum } ] [
     [
-        [ uchar-nth ] 2keep [ uchar-nth ] 2keep uchar-nth
+        { fixnum byte-array } declare
+        [ nth-unsafe ] 2keep [ nth-unsafe ] 2keep nth-unsafe
         >r >r 298 * r> 100 * - r> 208 * - 128 + -8 shift
         255 min 0 max
     ] final-classes
@@ -434,7 +436,7 @@ TUPLE: mixed-mutable-immutable { x integer } { y sequence read-only } ;
 ] unit-test
 
 : recursive-test-4 ( i n -- )
-    2dup < [ >r 1+ r> recursive-test-4 ] [ 2drop ] if ; inline recursive
+    2dup < [ [ 1+ ] dip recursive-test-4 ] [ 2drop ] if ; inline recursive
 
 [ ] [ [ recursive-test-4 ] final-info drop ] unit-test
 
@@ -588,12 +590,20 @@ MIXIN: empty-mixin
     [ { fixnum integer } declare bitand ] final-classes
 ] unit-test
 
-[ V{ float-array } ] [ [| | F{ } ] final-classes ] unit-test
+[ V{ double-array } ] [ [| | double-array{ } ] final-classes ] unit-test
 
 [ V{ t } ] [ [ netbsd unix? ] final-literals ] unit-test
 
 [ V{ array } ] [ [ [ <=> ] sort [ <=> ] sort ] final-classes ] unit-test
 
+[ V{ float } ] [ [ fsqrt ] final-classes ] unit-test
+
+[ V{ t } ] [ [ { fixnum } declare 10 mod >float -20 > ] final-literals ] unit-test
+
+[ T{ interval f { 0 t } { 127 t } } ] [
+    [ { integer } declare 127 bitand ] final-info first interval>>
+] unit-test
+
 ! [ V{ string } ] [
 !     [ dup string? t xor [ "A" throw ] [ ] if ] final-classes
 ! ] unit-test
index b9822d2c6bfa1d595b537ad20703fee724ef94f9..2a9825e3f1fdf1dfa707c80a63bc5d1fa13782fd 100644 (file)
@@ -19,5 +19,6 @@ IN: compiler.tree.propagation
     H{ } clone copies set
     H{ } clone 1array value-infos set
     H{ } clone 1array constraints set
+    H{ } clone inlining-count set
     dup count-nodes
     dup (propagate) ;
index 7f10f870165fca82fd201948aa17f9f2d4e23c03..ff9f262d28011c8745aa84ec4b47237778704ed1 100644 (file)
@@ -55,6 +55,8 @@ IN: compiler.tree.propagation.recursive
 M: #recursive propagate-around ( #recursive -- )
     constraints [ H{ } clone suffix ] change
     [
+        loop-nesting inc
+
         constraints [ but-last H{ } clone suffix ] change
 
         child>>
@@ -62,6 +64,8 @@ M: #recursive propagate-around ( #recursive -- )
         [ first propagate-recursive-phi ]
         [ (propagate) ]
         tri
+
+        loop-nesting dec
     ] until-fixed-point ;
 
 : recursive-phi-infos ( node -- infos )
index d586ff398ff6399e6a5afcf09a639dac1b5729d9..9937c6b9c4d51da1e2acc5f09442809cea9b6faf 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry accessors kernel sequences sequences.private assocs words
 namespaces classes.algebra combinators classes classes.tuple
-classes.tuple.private continuations arrays
+classes.tuple.private continuations arrays alien.c-types
 math math.private slots generic definitions
 stack-checker.state
 compiler.tree
@@ -137,11 +137,12 @@ M: #call propagate-after
     dup word>> "input-classes" word-prop dup
     [ propagate-input-classes ] [ 2drop ] if ;
 
-M: #alien-invoke propagate-before
-    out-d>> [ object-info swap set-value-info ] each ;
+: propagate-alien-invoke ( node -- )
+    [ out-d>> ] [ params>> return>> ] bi
+    [ drop ] [ c-type-class <class-info> swap first set-value-info ] if-void ;
 
-M: #alien-indirect propagate-before
-    out-d>> [ object-info swap set-value-info ] each ;
+M: #alien-invoke propagate-before propagate-alien-invoke ;
+
+M: #alien-indirect propagate-before propagate-alien-invoke ;
 
-M: #return annotate-node
-    dup in-d>> (annotate-node) ;
+M: #return annotate-node dup in-d>> (annotate-node) ;
index 52903fce8de3064ba14d6fc322f3b908720488de..f6726e44040a9f44d6a8809592f3bb9d2fa174ae 100644 (file)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces assocs accessors kernel combinators
-classes.algebra sequences sequences.deep slots.private
+classes.algebra sequences slots.private fry vectors
 classes.tuple.private math math.private arrays
 stack-checker.branches
+compiler.utilities
 compiler.tree
 compiler.tree.combinators
 compiler.tree.propagation.info
@@ -21,7 +22,7 @@ GENERIC: unbox-tuples* ( node -- node/nodes )
 : (expand-#push) ( object value -- nodes )
     dup unboxed-allocation dup [
         [ object-slots ] [ drop ] [ ] tri*
-        [ (expand-#push) ] 2map
+        [ (expand-#push) ] 2map-flat
     ] [
         drop #push
     ] if ;
@@ -38,11 +39,16 @@ M: #push unbox-tuples* ( #push -- nodes )
 : unbox-<complex> ( #call -- nodes )
     dup unbox-output? [ drop { } ] when ;
 
-: (flatten-values) ( values -- values' )
-    [ dup unboxed-allocation [ (flatten-values) ] [ ] ?if ] map ;
+: (flatten-values) ( values accum -- )
+    dup '[
+        dup unboxed-allocation
+        [ _ (flatten-values) ] [ _ push ] ?if
+    ] each ;
 
 : flatten-values ( values -- values' )
-    dup empty? [ (flatten-values) flatten ] unless ;
+    dup empty? [
+        10 <vector> [ (flatten-values) ] keep
+    ] unless ;
 
 : prepare-slot-access ( #call -- tuple-values outputs slot-values )
     [ in-d>> flatten-values ]
diff --git a/basis/compiler/utilities/utilities.factor b/basis/compiler/utilities/utilities.factor
new file mode 100644 (file)
index 0000000..1f488b3
--- /dev/null
@@ -0,0 +1,31 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences sequences.private arrays vectors fry
+math.order ;
+IN: compiler.utilities
+
+: flattener ( seq quot -- seq vector quot' )
+    over length <vector> [
+        dup
+        '[
+            @ [
+                dup array?
+                [ _ push-all ] [ _ push ] if
+            ] when*
+        ]
+    ] keep ; inline
+
+: flattening ( seq quot combinator -- seq' )
+    [ flattener ] dip dip { } like ; inline
+
+: map-flat ( seq quot -- seq' ) [ each ] flattening ; inline
+
+: 2map-flat ( seq quot -- seq' ) [ 2each ] flattening ; inline
+
+: (3each) ( seq1 seq2 seq3 quot -- n quot' )
+    [ [ [ length ] tri@ min min ] 3keep ] dip
+    '[ [ _ nth-unsafe ] [ _ nth-unsafe ] [ _ nth-unsafe ] tri @ ] ; inline
+
+: 3each ( seq1 seq2 seq3 quot -- seq ) (3each) each ; inline
+
+: 3map ( seq1 seq2 seq3 quot -- seq ) (3each) map ; inline
index 43374d312754d6d35d5ecb469eca432ee1c6934c..11e624110c634e790eb1d88cd4ba41f20c84da91 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: deques threads kernel arrays sequences alarms ;\r
+USING: deques threads kernel arrays sequences alarms fry ;\r
 IN: concurrency.conditions\r
 \r
 : notify-1 ( deque -- )\r
@@ -12,15 +12,18 @@ IN: concurrency.conditions
 : queue-timeout ( queue timeout -- alarm )\r
     #! Add an alarm which removes the current thread from the\r
     #! queue, and resumes it, passing it a value of t.\r
-    >r [ self swap push-front* ] keep [\r
-        [ delete-node ] [ drop node-value ] 2bi\r
-        t swap resume-with\r
-    ] 2curry r> later ;\r
+    [\r
+        [ self swap push-front* ] keep '[\r
+            _ _\r
+            [ delete-node ] [ drop node-value ] 2bi\r
+            t swap resume-with\r
+        ]\r
+    ] dip later ;\r
 \r
 : wait ( queue timeout status -- )\r
     over [\r
-        >r queue-timeout [ drop ] r> suspend\r
+        [ queue-timeout [ drop ] ] dip suspend\r
         [ "Timeout" throw ] [ cancel-alarm ] if\r
     ] [\r
-        >r drop [ push-front ] curry r> suspend drop\r
+        [ drop '[ _ push-front ] ] dip suspend drop\r
     ] if ;\r
index c4bc92c688145c09945c2354eef123fbb41982c6..d79cfbf1c91b9863801cd9dcc03eec2cae4634d0 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: dlists kernel math concurrency.promises\r
-concurrency.mailboxes debugger accessors ;\r
+concurrency.mailboxes debugger accessors fry ;\r
 IN: concurrency.count-downs\r
 \r
 ! http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html\r
@@ -26,12 +26,12 @@ ERROR: count-down-already-done ;
     [ 1- >>n count-down-check ] if ;\r
 \r
 : await-timeout ( count-down timeout -- )\r
-    >r promise>> r> ?promise-timeout ?linked t assert= ;\r
+    [ promise>> ] dip ?promise-timeout ?linked t assert= ;\r
 \r
 : await ( count-down -- )\r
     f await-timeout ;\r
 \r
 : spawn-stage ( quot count-down -- )\r
-    [ [ count-down ] curry compose ] keep\r
+    [ '[ @ _ count-down ] ] keep\r
     "Count down stage"\r
     swap promise>> mailbox>> spawn-linked-to drop ;\r
index 528e1956b88f88b52248d0a43cd4018af326ee17..1087823aa0ff2e93ee623c2068b2e8c58a8a3954 100644 (file)
@@ -15,7 +15,7 @@ concurrency.messaging continuations accessors prettyprint ;
 
 [ ] [
     [
-        receive first2 >r 3 + r> send
+        receive first2 [ 3 + ] dip send
         "thread-a" unregister-process
     ] "Thread A" spawn
     "thread-a" swap register-process
index 6b44886eda86cfb51edf467e094bb4ad180b552a..97b3c14fe41cd29c4ac1185119b10463fcece045 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: kernel threads boxes accessors ;\r
+USING: kernel threads boxes accessors fry ;\r
 IN: concurrency.exchangers\r
 \r
 ! Motivated by\r
@@ -14,8 +14,8 @@ TUPLE: exchanger thread object ;
 : exchange ( obj exchanger -- newobj )\r
     dup thread>> occupied>> [\r
         dup object>> box>\r
-        >r thread>> box> resume-with r>\r
+        [ thread>> box> resume-with ] dip\r
     ] [\r
         [ object>> >box ] keep\r
-        [ thread>> >box ] curry "exchange" suspend\r
+        '[ _ thread>> >box ] "exchange" suspend\r
     ] if ;\r
index 0f78183abaade2cd0d4aa2ed645f3c7dc3128a46..a66629331652532fed94f07fdbd0fb24496deed3 100644 (file)
@@ -2,7 +2,7 @@ IN: concurrency.flags.tests
 USING: tools.test concurrency.flags concurrency.combinators\r
 kernel threads locals accessors calendar ;\r
 \r
-:: flag-test-1 ( -- )\r
+:: flag-test-1 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ f raise-flag ] "Flag test" spawn drop\r
         f lower-flag\r
@@ -20,7 +20,7 @@ kernel threads locals accessors calendar ;
 \r
 [ f ] [ flag-test-2 ] unit-test\r
 \r
-:: flag-test-3 ( -- )\r
+:: flag-test-3 ( -- val )\r
     [let | f [ <flag> ] |\r
         f raise-flag\r
         f value>>\r
@@ -28,7 +28,7 @@ kernel threads locals accessors calendar ;
 \r
 [ t ] [ flag-test-3 ] unit-test\r
 \r
-:: flag-test-4 ( -- )\r
+:: flag-test-4 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ f raise-flag ] "Flag test" spawn drop\r
         f wait-for-flag\r
@@ -37,7 +37,7 @@ kernel threads locals accessors calendar ;
 \r
 [ t ] [ flag-test-4 ] unit-test\r
 \r
-:: flag-test-5 ( -- )\r
+:: flag-test-5 ( -- val )\r
     [let | f [ <flag> ] |\r
         [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
         f wait-for-flag\r
index ec260961d0417c7ca3a2407d2ba320cb92c2a3be..c65171a3f00b2d8c1c28c7d8ea6ccfcf8cbd240e 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: flag value threads ;
     dup value>> [ drop ] [ t >>value threads>> notify-all ] if ;
 
 : wait-for-flag-timeout ( flag timeout -- )
-    over value>> [ 2drop ] [ >r threads>> r> "flag" wait ] if ;
+    over value>> [ 2drop ] [ [ threads>> ] dip "flag" wait ] if ;
 
 : wait-for-flag ( flag -- )
     f wait-for-flag-timeout ;
index 132342aff1fdda735153304afbe2b959a01ffce2..a1f4f57af63eb417811d8405a1759f465bcfa13c 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: concurrency.promises concurrency.mailboxes kernel arrays\r
-continuations accessors ;\r
+continuations accessors fry ;\r
 IN: concurrency.futures\r
 \r
 : future ( quot -- future )\r
     <promise> [\r
-        [ [ >r call r> fulfill ] 2curry "Future" ] keep\r
+        [ '[ @ _ fulfill ] "Future" ] keep\r
         mailbox>> spawn-linked-to drop\r
     ] keep ; inline\r
 \r
index 7696e6c1ebe061a010ae0bf78da4cafda2a15863..8f82aa88baa997c56780e6b51e6b17117a7fa71f 100644 (file)
@@ -3,7 +3,7 @@ USING: tools.test concurrency.locks concurrency.count-downs
 concurrency.messaging concurrency.mailboxes locals kernel\r
 threads sequences calendar accessors ;\r
 \r
-:: lock-test-0 ( -- )\r
+:: lock-test-0 ( -- )\r
     [let | v [ V{ } clone ]\r
            c [ 2 <count-down> ] |\r
 \r
@@ -27,7 +27,7 @@ threads sequences calendar accessors ;
            v\r
     ] ;\r
 \r
-:: lock-test-1 ( -- )\r
+:: lock-test-1 ( -- )\r
     [let | v [ V{ } clone ]\r
            l [ <lock> ]\r
            c [ 2 <count-down> ] |\r
@@ -79,7 +79,7 @@ threads sequences calendar accessors ;
 \r
 [ ] [ <rw-lock> dup [ [ ] with-read-lock ] with-write-lock ] unit-test\r
 \r
-:: rw-lock-test-1 ( -- )\r
+:: rw-lock-test-1 ( -- )\r
     [let | l [ <rw-lock> ]\r
            c [ 1 <count-down> ]\r
            c' [ 1 <count-down> ]\r
@@ -129,7 +129,7 @@ threads sequences calendar accessors ;
 \r
 [ V{ 1 2 3 4 5 6 } ] [ rw-lock-test-1 ] unit-test\r
 \r
-:: rw-lock-test-2 ( -- )\r
+:: rw-lock-test-2 ( -- )\r
     [let | l [ <rw-lock> ]\r
            c [ 1 <count-down> ]\r
            c' [ 2 <count-down> ]\r
@@ -160,7 +160,7 @@ threads sequences calendar accessors ;
 [ V{ 1 2 3 } ] [ rw-lock-test-2 ] unit-test\r
 \r
 ! Test lock timeouts\r
-:: lock-timeout-test ( -- )\r
+:: lock-timeout-test ( -- )\r
     [let | l [ <lock> ] |\r
         [\r
             l [ 1 seconds sleep ] with-lock\r
@@ -177,19 +177,6 @@ threads sequences calendar accessors ;
     thread>> name>> "Lock timeout-er" =\r
 ] must-fail-with\r
 \r
-:: read/write-test ( -- )\r
-    [let | l [ <lock> ] |\r
-        [\r
-            l [ 1 seconds sleep ] with-lock\r
-        ] "Lock holder" spawn drop\r
-\r
-        [\r
-            l 1/10 seconds [ ] with-lock-timeout\r
-        ] "Lock timeout-er" spawn-linked drop\r
-\r
-        receive\r
-    ] ;\r
-\r
 [\r
     <rw-lock> dup [\r
         1 seconds [ ] with-write-lock-timeout\r
index 8c1392dbfb667cf84aa9d2621ddd98efc6c93787..0094f3323d709d26f22850b02ee2a206ab12a537 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: deques dlists kernel threads continuations math\r
-concurrency.conditions combinators.short-circuit accessors ;\r
+concurrency.conditions combinators.short-circuit accessors\r
+locals ;\r
 IN: concurrency.locks\r
 \r
 ! Simple critical sections\r
@@ -17,16 +18,16 @@ TUPLE: lock threads owner reentrant? ;
 \r
 : acquire-lock ( lock timeout -- )\r
     over owner>>\r
-    [ 2dup >r threads>> r> "lock" wait ] when drop\r
+    [ 2dup [ threads>> ] dip "lock" wait ] when drop\r
     self >>owner drop ;\r
 \r
 : release-lock ( lock -- )\r
     f >>owner\r
     threads>> notify-1 ;\r
 \r
-: do-lock ( lock timeout quot acquire release -- )\r
-    >r >r pick rot r> call ! use up  timeout acquire\r
-    swap r> curry [ ] cleanup ; inline\r
+:: do-lock ( lock timeout quot acquire release -- )\r
+    lock timeout acquire call\r
+    quot lock release curry [ ] cleanup ; inline\r
 \r
 : (with-lock) ( lock timeout quot -- )\r
     [ acquire-lock ] [ release-lock ] do-lock ; inline\r
@@ -60,7 +61,7 @@ TUPLE: rw-lock readers writers reader# writer ;
 \r
 : acquire-read-lock ( lock timeout -- )\r
     over writer>>\r
-    [ 2dup >r readers>> r> "read lock" wait ] when drop\r
+    [ 2dup [ readers>> ] dip "read lock" wait ] when drop\r
     add-reader ;\r
 \r
 : notify-writer ( lock -- )\r
@@ -75,7 +76,7 @@ TUPLE: rw-lock readers writers reader# writer ;
 \r
 : acquire-write-lock ( lock timeout -- )\r
     over writer>> pick reader#>> 0 > or\r
-    [ 2dup >r writers>> r> "write lock" wait ] when drop\r
+    [ 2dup [ writers>> ] dip "write lock" wait ] when drop\r
     self >>writer drop ;\r
 \r
 : release-write-lock ( lock -- )\r
index 39b21e0943d3571ba49f5e5d49548193ba531798..63707041a23f59b508e361ce22d2bf0c12305ced 100644 (file)
@@ -4,7 +4,7 @@ IN: concurrency.mailboxes
 USING: dlists deques threads sequences continuations\r
 destructors namespaces math quotations words kernel\r
 arrays assocs init system concurrency.conditions accessors\r
-debugger debugger.threads locals ;\r
+debugger debugger.threads locals fry ;\r
 \r
 TUPLE: mailbox threads data disposed ;\r
 \r
@@ -21,7 +21,7 @@ M: mailbox dispose* threads>> notify-all ;
     [ threads>> notify-all ] bi yield ;\r
 \r
 : wait-for-mailbox ( mailbox timeout -- )\r
-    >r threads>> r> "mailbox" wait ;\r
+    [ threads>> ] dip "mailbox" wait ;\r
 \r
 :: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )\r
     mailbox check-disposed\r
@@ -57,11 +57,11 @@ M: mailbox dispose* threads>> notify-all ;
     f mailbox-get-all-timeout ;\r
 \r
 : while-mailbox-empty ( mailbox quot -- )\r
-    [ [ mailbox-empty? ] curry ] dip [ ] while ; inline\r
+    [ '[ _ mailbox-empty? ] ] dip [ ] while ; inline\r
 \r
 : mailbox-get-timeout? ( mailbox timeout pred -- obj )\r
     [ block-unless-pred ]\r
-    [ nip >r data>> r> delete-node-if ]\r
+    [ [ drop data>> ] dip delete-node-if ]\r
     3bi ; inline\r
 \r
 : mailbox-get? ( mailbox pred -- obj )\r
@@ -90,7 +90,7 @@ M: linked-thread error-in-thread
     [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;\r
 \r
 : <linked-thread> ( quot name mailbox -- thread' )\r
-    >r linked-thread new-thread r> >>supervisor ;\r
+    [ linked-thread new-thread ] dip >>supervisor ;\r
 \r
 : spawn-linked-to ( quot name mailbox -- thread )\r
     <linked-thread> [ (spawn) ] keep ;\r
index 6c9e530d9b28ce6a84f6005c90a9f29c56a3facd..3bd2d330c36a39c57dd08cc6da8353ac8c0bd1cc 100644 (file)
@@ -8,20 +8,20 @@ HELP: send
 { $values { "message" object } 
           { "thread" thread } 
 }
-{ $description "Send the message to the thread by placing it in the threades mailbox. This is an asynchronous operation and will return immediately. The receving thread will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-thread the message must be a serializable Factor type." } 
+{ $description "Send the message to the thread by placing it in the threads mailbox. This is an asynchronous operation and will return immediately. The receving thread will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-thread the message must be a serializable Factor type." } 
 { $see-also receive receive-if } ;
 
 HELP: receive
 { $values { "message" object } 
 }
-{ $description "Return a message from the current threades mailbox. If the box is empty, suspend the thread until another thread places an item in the mailbox (usually via the " { $link send } " word." } 
+{ $description "Return a message from the current threads mailbox. If the box is empty, suspend the thread until another thread places an item in the mailbox (usually via the " { $link send } " word." } 
 { $see-also send receive-if } ;
 
 HELP: receive-if
 { $values { "pred" "a predicate with stack effect " { $snippet "( obj -- ? )" } }  
           { "message" object } 
 }
-{ $description "Return the first message from the current threades mailbox that satisfies the predicate. To satisfy the predicate, " { $snippet "pred" } " is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. If nothing in the mailbox satisfies the predicate then the thread will block until something does." } 
+{ $description "Return the first message from the current threads mailbox that satisfies the predicate. To satisfy the predicate, " { $snippet "pred" } " is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. If nothing in the mailbox satisfies the predicate then the thread will block until something does." } 
 { $see-also send receive } ;
 
 HELP: spawn-linked
@@ -29,7 +29,7 @@ HELP: spawn-linked
           { "name" string }
           { "thread" thread } 
 }
-{ $description "Start a thread which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the thread that spawned it. This can be used to set up 'supervisor' threades that restart child threades that crash due to uncaught errors.\n" } 
+{ $description "Start a thread which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the thread that spawned it. This can be used to set up 'supervisor' threads that restart child threads that crash due to uncaught errors.\n" } 
 { $see-also spawn } ;
 
 ARTICLE: { "concurrency" "messaging" } "Sending and receiving messages"
@@ -55,7 +55,7 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends"
 { $example
     "USING: concurrency.messaging kernel threads ;"
     ": pong-server ( -- )"
-    "    receive >r \"pong\" r> reply-synchronous ;"
+    "    receive [ \"pong\" ] dip reply-synchronous ;"
     "[ pong-server t ] \"pong-server\" spawn-server"
     "\"ping\" swap send-synchronous ."
     "\"pong\""
@@ -64,7 +64,7 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends"
 ARTICLE: { "concurrency" "exceptions" } "Linked exceptions"
 "A thread can handle exceptions using the standard Factor exception handling mechanism. If an exception is uncaught the thread will terminate. For example:" 
 { $code "[ 1 0 / \"This will not print\" print ] \"division-by-zero\" spawn" } 
-"Processes can be linked so that a parent thread can receive the exception that caused the child thread to terminate. In this way 'supervisor' threades can be created that are notified when child threades terminate and possibly restart them."
+"Processes can be linked so that a parent thread can receive the exception that caused the child thread to terminate. In this way 'supervisor' threads can be created that are notified when child threads terminate and possibly restart them."
 { $subsection spawn-linked }
 "This will create a unidirectional link, such that if an uncaught exception causes the child to terminate, the parent thread can catch it:"
 { $code "["
@@ -74,11 +74,11 @@ ARTICLE: { "concurrency" "exceptions" } "Linked exceptions"
 "Exceptions are only raised in the parent when the parent does a " { $link receive } " or " { $link receive-if } ". This is because the exception is sent from the child to the parent as a message." ;
 
 ARTICLE: "concurrency.messaging" "Message-passing concurrency"
-"The " { $vocab-link "concurrency.messaging" } " vocabulary is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of the standard Factor lightweight thread system."
+"The " { $vocab-link "concurrency.messaging" } " vocabulary is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of " { $link "threads" } "."
 $nl
-"A concurrency oriented program is one in which multiple threades run simultaneously in a single Factor image or across multiple running Factor instances. The threades can communicate with each other by asynchronous message sends."
+"A concurrency-oriented program is one in which multiple threads run simultaneously in a single Factor image or across multiple running Factor instances. The threads can communicate with each other by asynchronous message sends."
 $nl
-"Although threades can share data via Factor's mutable data structures it is not recommended to mix shared state with message passing as it can lead to confusing code."
+"Although threads can share data via Factor's mutable data structures it is not recommended to mix shared state with message passing as it can lead to confusing code."
 { $subsection { "concurrency" "messaging" } }
 { $subsection { "concurrency" "synchronous-sends" } } 
 { $subsection { "concurrency" "exceptions" } } ;
index 9aeb24ed723d12f889de09e86a05005819ca2734..7a00f62e9ebdc95bd7c06f2864713c768d984918 100644 (file)
@@ -1,10 +1,7 @@
 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-!\r
-! Concurrency library for Factor, based on Erlang/Termite style\r
-! concurrency.\r
 USING: kernel threads concurrency.mailboxes continuations\r
-namespaces assocs accessors summary ;\r
+namespaces assocs accessors summary fry ;\r
 IN: concurrency.messaging\r
 \r
 GENERIC: send ( message thread -- )\r
@@ -32,7 +29,7 @@ M: thread send ( message thread -- )
     my-mailbox -rot mailbox-get-timeout? ?linked ; inline\r
 \r
 : rethrow-linked ( error process supervisor -- )\r
-    >r <linked-error> r> send ;\r
+    [ <linked-error> ] dip send ;\r
 \r
 : spawn-linked ( quot name -- thread )\r
     my-mailbox spawn-linked-to ;\r
@@ -48,9 +45,7 @@ TUPLE: reply data tag ;
     tag>> \ reply boa ;\r
 \r
 : synchronous-reply? ( response synchronous -- ? )\r
-    over reply?\r
-    [ >r tag>> r> tag>> = ]\r
-    [ 2drop f ] if ;\r
+    over reply? [ [ tag>> ] bi@ = ] [ 2drop f ] if ;\r
 \r
 ERROR: cannot-send-synchronous-to-self message thread ;\r
 \r
@@ -61,8 +56,8 @@ M: cannot-send-synchronous-to-self summary
     dup self eq? [\r
         cannot-send-synchronous-to-self\r
     ] [\r
-        >r <synchronous> dup r> send\r
-        [ synchronous-reply? ] curry receive-if\r
+        [ <synchronous> dup ] dip send\r
+        '[ _ synchronous-reply? ] receive-if\r
         data>>\r
     ] if ;\r
 \r
index 382697e04f1c7cb2b9c409ff3cc312d96895ffa7..2ff338c4e33a6eef62b3f89945a643cb75f245fd 100644 (file)
@@ -20,7 +20,7 @@ ERROR: promise-already-fulfilled promise ;
     ] if ;\r
 \r
 : ?promise-timeout ( promise timeout -- result )\r
-    >r mailbox>> r> block-if-empty mailbox-peek ;\r
+    [ mailbox>> ] dip block-if-empty mailbox-peek ;\r
 \r
 : ?promise ( promise -- result )\r
     f ?promise-timeout ;\r
index 1b55c7afa5641ffde0cdf5b4763e70fdc25b15a5..59518f4c8d7320d449f092345d519a24ad322048 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: dlists kernel threads math concurrency.conditions\r
-continuations accessors summary ;\r
+continuations accessors summary locals fry ;\r
 IN: concurrency.semaphores\r
 \r
 TUPLE: semaphore count threads ;\r
@@ -30,9 +30,9 @@ M: negative-count-semaphore summary
     [ 1+ ] change-count\r
     threads>> notify-1 ;\r
 \r
-: with-semaphore-timeout ( semaphore timeout quot -- )\r
-    pick rot acquire-timeout swap\r
-    [ release ] curry [ ] cleanup ; inline\r
+:: with-semaphore-timeout ( semaphore timeout quot -- )\r
+    semaphore timeout acquire-timeout\r
+    quot [ semaphore release ] [ ] cleanup ; inline\r
 \r
 : with-semaphore ( semaphore quot -- )\r
-    over acquire swap [ release ] curry [ ] cleanup ; inline\r
+    swap dup acquire '[ _ release ] [ ] cleanup ; inline\r
index 00bf73e9ddc8329a2036961b66f9d5fd46d496da..d63a66dbe7f0b9dca903b1bad80fa9819d1d20ec 100644 (file)
@@ -16,13 +16,17 @@ TYPEDEF: void* CFStringRef
 TYPEDEF: void* CFURLRef
 TYPEDEF: void* CFUUIDRef
 TYPEDEF: void* CFTypeRef
+TYPEDEF: void* CFFileDescriptorRef
 TYPEDEF: bool Boolean
 TYPEDEF: long CFIndex
 TYPEDEF: int SInt32
 TYPEDEF: uint UInt32
 TYPEDEF: ulong CFTypeID
+TYPEDEF: UInt32 CFOptionFlags
 TYPEDEF: double CFTimeInterval
 TYPEDEF: double CFAbsoluteTime
+TYPEDEF: int CFFileDescriptorNativeDescriptor
+TYPEDEF: void* CFFileDescriptorCallBack
 
 TYPEDEF: int CFNumberType
 : kCFNumberSInt8Type 1 ; inline
@@ -90,25 +94,25 @@ FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
 : <CFArray> ( seq -- alien )
     [ f swap length f CFArrayCreateMutable ] keep
     [ length ] keep
-    [ >r dupd r> CFArraySetValueAtIndex ] 2each ;
+    [ [ dupd ] dip CFArraySetValueAtIndex ] 2each ;
 
 : <CFString> ( string -- alien )
     f swap dup length CFStringCreateWithCharacters ;
 
 : CF>string ( alien -- string )
     dup CFStringGetLength 1+ "ushort" <c-array> [
-        >r 0 over CFStringGetLength r> CFStringGetCharacters
+        [ 0 over CFStringGetLength ] dip CFStringGetCharacters
     ] keep utf16n alien>string ;
 
 : CF>string-array ( alien -- seq )
     CF>array [ CF>string ] map ;
 
 : <CFStringArray> ( seq -- alien )
-    [ <CFString> ] map dup <CFArray> swap [ CFRelease ] each ;
+    [ <CFString> ] map [ <CFArray> ] [ [ CFRelease ] each ] bi ;
 
 : <CFFileSystemURL> ( string dir? -- url )
-    >r <CFString> f over kCFURLPOSIXPathStyle
-    r> CFURLCreateWithFileSystemPath swap CFRelease ;
+    [ <CFString> f over kCFURLPOSIXPathStyle ] dip
+    CFURLCreateWithFileSystemPath swap CFRelease ;
 
 : <CFURL> ( string -- url )
     <CFString>
@@ -121,18 +125,35 @@ FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
     ] keep CFRelease ;
 
 GENERIC: <CFNumber> ( number -- alien )
+
 M: integer <CFNumber>
     [ f kCFNumberLongLongType ] dip <longlong> CFNumberCreate ;
+
 M: float <CFNumber>
     [ f kCFNumberDoubleType ] dip <double> CFNumberCreate ;
+
 M: t <CFNumber>
     drop f kCFNumberIntType 1 <int> CFNumberCreate ;
+
 M: f <CFNumber>
     drop f kCFNumberIntType 0 <int> CFNumberCreate ;
 
 : <CFData> ( byte-array -- alien )
     [ f ] dip dup length CFDataCreate ;
 
+FUNCTION: CFFileDescriptorRef CFFileDescriptorCreate (
+    CFAllocatorRef allocator,
+    CFFileDescriptorNativeDescriptor fd,
+    Boolean closeOnInvalidate,
+    CFFileDescriptorCallBack callout, 
+    CFFileDescriptorContext* context
+) ;
+
+FUNCTION: void CFFileDescriptorEnableCallBacks (
+    CFFileDescriptorRef f,
+    CFOptionFlags callBackTypes
+) ;
+
 : load-framework ( name -- )
     dup <CFBundle> [
         CFBundleLoadExecutable drop
@@ -141,8 +162,11 @@ M: f <CFNumber>
     ] ?if ;
 
 TUPLE: CFRelease-destructor alien disposed ;
+
 M: CFRelease-destructor dispose* alien>> CFRelease ;
+
 : &CFRelease ( alien -- alien )
     dup f CFRelease-destructor boa &dispose drop ; inline
+
 : |CFRelease ( alien -- alien )
     dup f CFRelease-destructor boa |dispose drop ; inline
index 6bec4b23c0958453baea559550e09fb818c27dc3..d4d5e88512e25c72c0e2c4d464a80c2b342d358f 100644 (file)
@@ -4,7 +4,9 @@ USING: alien alien.c-types alien.strings alien.syntax kernel
 math sequences namespaces make assocs init accessors
 continuations combinators core-foundation
 core-foundation.run-loop core-foundation.run-loop.thread
-io.encodings.utf8 destructors ;
+io.encodings.utf8 destructors locals arrays
+specialized-arrays.direct.alien specialized-arrays.direct.int
+specialized-arrays.direct.longlong ;
 IN: core-foundation.fsevents
 
 : kFSEventStreamCreateFlagUseCFTypes 2 ; inline
@@ -105,15 +107,14 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef
     "FSEventStreamContext" <c-object>
     [ set-FSEventStreamContext-info ] keep ;
 
-: <FSEventStream> ( callback info paths latency flags -- event-stream )
-    >r >r >r >r >r
+:: <FSEventStream> ( callback info paths latency flags -- event-stream )
     f ! allocator
-    r> ! callback
-    r> make-FSEventStreamContext
-    r> <CFStringArray> ! paths
+    callback
+    info make-FSEventStreamContext
+    paths <CFStringArray>
     FSEventStreamEventIdSinceNow ! sinceWhen
-    r> ! latency
-    r> ! flags
+    latency
+    flags
     FSEventStreamCreate ;
 
 : kCFRunLoopCommonModes ( -- string )
@@ -161,13 +162,12 @@ SYMBOL: event-stream-callbacks
 : remove-event-source-callback ( id -- )
     event-stream-callbacks get delete-at ;
 
-: >event-triple ( n eventPaths eventFlags eventIds -- triple )
-    [
-        >r >r >r dup dup
-        r> void*-nth utf8 alien>string ,
-        r> int-nth ,
-        r> longlong-nth ,
-    ] { } make ;
+:: (master-event-source-callback) ( eventStream info numEvents eventPaths eventFlags eventIds -- )
+    eventPaths numEvents <direct-void*-array> [ utf8 alien>string ] { } map-as
+    eventFlags numEvents <direct-int-array>
+    eventIds numEvents <direct-longlong-array>
+    3array flip
+    info event-stream-callbacks get at [ drop ] or call ;
 
 : master-event-source-callback ( -- alien )
     "void"
@@ -179,19 +179,15 @@ SYMBOL: event-stream-callbacks
         "FSEventStreamEventFlags*"
         "FSEventStreamEventId*"
     }
-    "cdecl" [
-        [ >event-triple ] 3curry map
-        swap event-stream-callbacks get at
-        dup [ call drop ] [ 3drop ] if
-    ] alien-callback ;
+    "cdecl" [ (master-event-source-callback) ] alien-callback ;
 
 TUPLE: event-stream info handle disposed ;
 
 : <event-stream> ( quot paths latency flags -- event-stream )
-    >r >r >r
-    add-event-source-callback dup
-    >r master-event-source-callback r>
-    r> r> r> <FSEventStream>
+    [
+        add-event-source-callback dup
+        [ master-event-source-callback ] dip
+    ] 3dip <FSEventStream>
     dup enable-event-stream
     f event-stream boa ;
 
index 9a5666b5d3b032b0c5be4e17594a9fd12a03cf6d..c334297122941f7a277a2778e1345a4992e8c0e6 100644 (file)
@@ -10,6 +10,7 @@ IN: core-foundation.run-loop
 : kCFRunLoopRunHandledSource 4 ; inline
 
 TYPEDEF: void* CFRunLoopRef
+TYPEDEF: void* CFRunLoopSourceRef
 
 FUNCTION: CFRunLoopRef CFRunLoopGetMain ( ) ;
 FUNCTION: CFRunLoopRef CFRunLoopGetCurrent ( ) ;
@@ -20,6 +21,18 @@ FUNCTION: SInt32 CFRunLoopRunInMode (
    Boolean returnAfterSourceHandled
 ) ;
 
+FUNCTION: CFRunLoopSourceRef CFFileDescriptorCreateRunLoopSource (
+    CFAllocatorRef allocator,
+    CFFileDescriptorRef f,
+    CFIndex order
+) ;
+
+FUNCTION: void CFRunLoopAddSource (
+   CFRunLoopRef rl,
+   CFRunLoopSourceRef source,
+   CFStringRef mode
+) ;
+
 : CFRunLoopDefaultMode ( -- alien )
     #! Ugly, but we don't have static NSStrings
     \ CFRunLoopDefaultMode get-global dup expired? [
index d26e7f6ff78e2c06b1b007fc510f836484bd6964..c609b9e98d6d011d635b6a5d0662d0365218d3f4 100644 (file)
@@ -59,6 +59,7 @@ HOOK: %set-slot cpu ( src obj slot tag temp -- )
 HOOK: %set-slot-imm cpu ( src obj slot tag -- )
 
 HOOK: %string-nth cpu ( dst obj index temp -- )
+HOOK: %set-string-nth-fast cpu ( ch obj index temp -- )
 
 HOOK: %add     cpu ( dst src1 src2 -- )
 HOOK: %add-imm cpu ( dst src1 src2 -- )
@@ -76,6 +77,14 @@ HOOK: %shl-imm cpu ( dst src1 src2 -- )
 HOOK: %shr-imm cpu ( dst src1 src2 -- )
 HOOK: %sar-imm cpu ( dst src1 src2 -- )
 HOOK: %not     cpu ( dst src -- )
+HOOK: %log2    cpu ( dst src -- )
+
+HOOK: %fixnum-add cpu ( src1 src2 -- )
+HOOK: %fixnum-add-tail cpu ( src1 src2 -- )
+HOOK: %fixnum-sub cpu ( src1 src2 -- )
+HOOK: %fixnum-sub-tail cpu ( src1 src2 -- )
+HOOK: %fixnum-mul cpu ( src1 src2 temp1 temp2 -- )
+HOOK: %fixnum-mul-tail cpu ( src1 src2 temp1 temp2 -- )
 
 HOOK: %integer>bignum cpu ( dst src temp -- )
 HOOK: %bignum>integer cpu ( dst src temp -- )
@@ -112,6 +121,8 @@ HOOK: %set-alien-cell      cpu ( ptr value -- )
 HOOK: %set-alien-float     cpu ( ptr value -- )
 HOOK: %set-alien-double    cpu ( ptr value -- )
 
+HOOK: %alien-global cpu ( dst symbol library -- )
+
 HOOK: %allot cpu ( dst size class temp -- )
 HOOK: %write-barrier cpu ( src card# table -- )
 HOOK: %gc cpu ( -- )
@@ -119,9 +130,9 @@ HOOK: %gc cpu ( -- )
 HOOK: %prologue cpu ( n -- )
 HOOK: %epilogue cpu ( n -- )
 
-HOOK: %compare cpu ( dst cc src1 src2 -- )
-HOOK: %compare-imm cpu ( dst cc src1 src2 -- )
-HOOK: %compare-float cpu ( dst cc src1 src2 -- )
+HOOK: %compare cpu ( dst temp cc src1 src2 -- )
+HOOK: %compare-imm cpu ( dst temp cc src1 src2 -- )
+HOOK: %compare-float cpu ( dst temp cc src1 src2 -- )
 
 HOOK: %compare-branch cpu ( label cc src1 src2 -- )
 HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
index 56ef89884c87031196b0e41ee72a5347212f2cbd..445c7082bcbce551b35a676a5fcbbf194f5d65b8 100644 (file)
@@ -24,7 +24,6 @@ big-endian on
 \r
 [\r
     0 6 LOAD32\r
-    6 dup 0 LWZ\r
     11 6 profile-count-offset LWZ\r
     11 11 1 tag-fixnum ADDI\r
     11 6 profile-count-offset STW\r
@@ -32,7 +31,7 @@ big-endian on
     11 11 compiled-header-size ADDI\r
     11 MTCTR\r
     BCTR\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-profiling jit-define\r
+] rc-absolute-ppc-2/2 rt-immediate 1 jit-profiling jit-define\r
 \r
 [\r
     0 6 LOAD32\r
@@ -44,12 +43,6 @@ big-endian on
     0 1 lr-save stack-frame + STW\r
 ] rc-absolute-ppc-2/2 rt-label 1 jit-prolog jit-define\r
 \r
-[\r
-    0 6 LOAD32\r
-    6 dup 0 LWZ\r
-    6 ds-reg 4 STWU\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-push-literal jit-define\r
-\r
 [\r
     0 6 LOAD32\r
     6 ds-reg 4 STWU\r
@@ -71,40 +64,32 @@ big-endian on
 \r
 [ 0 B ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define\r
 \r
+[\r
+    3 ds-reg 0 LWZ\r
+    ds-reg dup 4 SUBI\r
+    0 3 \ f tag-number CMPI\r
+    2 BEQ\r
+    0 B\r
+] rc-relative-ppc-3 rt-xt 4 jit-if-1 jit-define\r
+\r
+[\r
+    0 B\r
+] rc-relative-ppc-3 rt-xt 0 jit-if-2 jit-define\r
+\r
 : jit-jump-quot ( -- )\r
     4 3 quot-xt-offset LWZ\r
     4 MTCTR\r
     BCTR ;\r
 \r
-: jit-call-quot ( -- )\r
-    4 3 quot-xt-offset LWZ\r
-    4 MTLR\r
-    BLR ;\r
-\r
 [\r
     0 3 LOAD32\r
     6 ds-reg 0 LWZ\r
-    0 6 \ f tag-number CMPI\r
-    2 BNE\r
-    3 3 4 ADDI\r
-    3 3 0 LWZ\r
-    ds-reg dup 4 SUBI\r
-    jit-jump-quot\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-if-jump jit-define\r
-\r
-[\r
-    0 3 LOAD32\r
-    3 3 0 LWZ\r
-    6 ds-reg 0 LWZ\r
     6 6 1 SRAWI\r
     3 3 6 ADD\r
     3 3 array-start-offset LWZ\r
     ds-reg dup 4 SUBI\r
     jit-jump-quot\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define\r
-\r
-! These should not clobber r3 since we store a quotation in there\r
-! in jit-dip\r
+] rc-absolute-ppc-2/2 rt-immediate 1 jit-dispatch jit-define\r
 \r
 : jit->r ( -- )\r
     4 ds-reg 0 LWZ\r
@@ -130,9 +115,9 @@ big-endian on
     6 rs-reg -8 STW ;\r
 \r
 : jit-r> ( -- )\r
-    4 ds-reg 0 LWZ\r
-    ds-reg dup 4 SUBI\r
-    4 rs-reg 4 STWU ;\r
+    4 rs-reg 0 LWZ\r
+    rs-reg dup 4 SUBI\r
+    4 ds-reg 4 STWU ;\r
 \r
 : jit-2r> ( -- )\r
     4 rs-reg 0 LWZ\r
@@ -152,30 +137,23 @@ big-endian on
     5 ds-reg -4 STW\r
     6 ds-reg -8 STW ;\r
 \r
-: prepare-dip ( -- )\r
-    0 3 LOAD32\r
-    3 3 0 LWZ ;\r
-\r
 [\r
-    prepare-dip\r
     jit->r\r
-    jit-call-quot\r
+    0 BL\r
     jit-r>\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-dip jit-define\r
+] rc-relative-ppc-3 rt-xt 3 jit-dip jit-define\r
 \r
 [\r
-    prepare-dip\r
     jit-2>r\r
-    jit-call-quot\r
+    0 BL\r
     jit-2r>\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-2dip jit-define\r
+] rc-relative-ppc-3 rt-xt 6 jit-2dip jit-define\r
 \r
 [\r
-    prepare-dip\r
     jit-3>r\r
-    jit-call-quot\r
+    0 BL\r
     jit-3r>\r
-] rc-absolute-ppc-2/2 rt-literal 1 jit-3dip jit-define\r
+] rc-relative-ppc-3 rt-xt 8 jit-3dip jit-define\r
 \r
 [\r
     0 1 lr-save stack-frame + LWZ\r
@@ -331,7 +309,6 @@ big-endian on
 ! Comparisons\r
 : jit-compare ( insn -- )\r
     0 3 LOAD32\r
-    3 3 0 LWZ\r
     4 ds-reg 0 LWZ\r
     5 ds-reg -4 LWZU\r
     5 0 4 CMP\r
@@ -340,7 +317,7 @@ big-endian on
     3 ds-reg 0 STW ;\r
 \r
 : define-jit-compare ( insn word -- )\r
-    [ [ jit-compare ] curry rc-absolute-ppc-2/2 rt-literal 1 ] dip\r
+    [ [ jit-compare ] curry rc-absolute-ppc-2/2 rt-immediate 1 ] dip\r
     define-sub-primitive ;\r
 \r
 \ BEQ \ eq? define-jit-compare\r
@@ -350,6 +327,19 @@ big-endian on
 \ BLT \ fixnum< define-jit-compare\r
 \r
 ! Math\r
+[\r
+    3 ds-reg 0 LWZ\r
+    ds-reg ds-reg 4 SUBI\r
+    4 ds-reg 0 LWZ\r
+    3 3 4 OR\r
+    3 3 tag-mask get ANDI\r
+    \ f tag-number 4 LI\r
+    0 3 0 CMPI\r
+    2 BNE\r
+    1 tag-fixnum 4 LI\r
+    4 ds-reg 0 STW\r
+] f f f \ both-fixnums? define-sub-primitive\r
+\r
 : jit-math ( insn -- )\r
     3 ds-reg 0 LWZ\r
     4 ds-reg -4 LWZU\r
@@ -411,6 +401,7 @@ big-endian on
     ds-reg ds-reg 4 SUBI\r
     4 ds-reg 0 LWZ\r
     5 4 3 DIVW\r
+    5 5 tag-bits get SLWI\r
     5 ds-reg 0 STW\r
 ] f f f \ fixnum/i-fast define-sub-primitive\r
 \r
@@ -420,6 +411,7 @@ big-endian on
     5 4 3 DIVW\r
     6 5 3 MULLW\r
     7 6 4 SUBF\r
+    5 5 tag-bits get SLWI\r
     5 ds-reg -4 STW\r
     7 ds-reg 0 STW\r
 ] f f f \ fixnum/mod-fast define-sub-primitive\r
@@ -427,9 +419,7 @@ big-endian on
 [\r
     3 ds-reg 0 LWZ\r
     3 3 1 SRAWI\r
-    4 4 LI\r
-    4 3 4 SUBF\r
-    rs-reg 3 4 LWZX\r
+    rs-reg 3 3 LWZX\r
     3 ds-reg 0 STW\r
 ] f f f \ get-local define-sub-primitive\r
 \r
index c656ae4d89aaadcf86afe1aa5f7b08614b5f0c33..c555c4b8090ba60779b5e0f097d54e5ce8b2a876 100644 (file)
@@ -34,10 +34,11 @@ M: ppc two-operand? f ;
 
 M: ppc %load-immediate ( reg n -- ) swap LOAD ;
 
-M:: ppc %load-indirect ( reg obj -- )
-    0 reg LOAD32
-    obj rc-absolute-ppc-2/2 rel-literal
-    reg reg 0 LWZ ;
+M: ppc %load-indirect ( reg obj -- )
+    [ 0 swap LOAD32 ] [ rc-absolute-ppc-2/2 rel-immediate ] bi* ;
+
+M: ppc %alien-global ( register symbol dll -- )
+    [ 0 swap LOAD32 ] 2dip rc-absolute-ppc-2/2 rel-dlsym ;
 
 : ds-reg 29 ; inline
 : rs-reg 30 ; inline
@@ -138,17 +139,21 @@ M:: ppc %string-nth ( dst src index temp -- )
         "end" define-label
         temp src index ADD
         dst temp string-offset LBZ
+        0 dst HEX: 80 CMPI
+        "end" get BLT
         temp src string-aux-offset LWZ
-        0 temp \ f tag-number CMPI
-        "end" get BEQ
         temp temp index ADD
         temp temp index ADD
         temp temp byte-array-offset LHZ
-        temp temp 8 SLWI
-        dst dst temp OR
+        temp temp 7 SLWI
+        dst dst temp XOR
         "end" resolve-label
     ] with-scope ;
 
+M:: ppc %set-string-nth-fast ( ch obj index temp -- )
+    temp obj index ADD
+    ch temp string-offset STB ;
+
 M: ppc %add     ADD ;
 M: ppc %add-imm ADDI ;
 M: ppc %sub     swap SUBF ;
@@ -166,6 +171,91 @@ M: ppc %shr-imm swapd SRWI ;
 M: ppc %sar-imm SRAWI ;
 M: ppc %not     NOT ;
 
+: %alien-invoke-tail ( func dll -- )
+    [ scratch-reg ] 2dip %alien-global scratch-reg MTCTR BCTR ;
+
+:: exchange-regs ( r1 r2 -- )
+    scratch-reg r1 MR
+    r1 r2 MR
+    r2 scratch-reg MR ;
+
+: ?MR ( r1 r2 -- ) 2dup = [ 2drop ] [ MR ] if ;
+
+:: move>args ( src1 src2 -- )
+    {
+        { [ src1 4 = ] [ 3 src2 ?MR 3 4 exchange-regs ] }
+        { [ src1 3 = ] [ 4 src2 ?MR ] }
+        { [ src2 3 = ] [ 4 src1 ?MR 3 4 exchange-regs ] }
+        { [ src2 4 = ] [ 3 src1 ?MR ] }
+        [ 3 src1 MR 4 src2 MR ]
+    } cond ;
+
+: clear-xer ( -- )
+    0 0 LI
+    0 MTXER ; inline
+
+:: overflow-template ( src1 src2 insn func -- )
+    "no-overflow" define-label
+    clear-xer
+    scratch-reg src2 src1 insn call
+    scratch-reg ds-reg 0 STW
+    "no-overflow" get BNO
+    src1 src2 move>args
+    %prepare-alien-invoke
+    func f %alien-invoke
+    "no-overflow" resolve-label ; inline
+
+:: overflow-template-tail ( src1 src2 insn func -- )
+    "overflow" define-label
+    clear-xer
+    scratch-reg src2 src1 insn call
+    "overflow" get BO
+    scratch-reg ds-reg 0 STW
+    BLR
+    "overflow" resolve-label
+    src1 src2 move>args
+    %prepare-alien-invoke
+    func f %alien-invoke-tail ; inline
+
+M: ppc %fixnum-add ( src1 src2 -- )
+    [ ADDO. ] "overflow_fixnum_add" overflow-template ;
+
+M: ppc %fixnum-add-tail ( src1 src2 -- )
+    [ ADDO. ] "overflow_fixnum_add" overflow-template-tail ;
+
+M: ppc %fixnum-sub ( src1 src2 -- )
+    [ SUBFO. ] "overflow_fixnum_subtract" overflow-template ;
+
+M: ppc %fixnum-sub-tail ( src1 src2 -- )
+    [ SUBFO. ] "overflow_fixnum_subtract" overflow-template-tail ;
+
+M:: ppc %fixnum-mul ( src1 src2 temp1 temp2 -- )
+    "no-overflow" define-label
+    clear-xer
+    temp1 src1 tag-bits get SRAWI
+    temp2 temp1 src2 MULLWO.
+    temp2 ds-reg 0 STW
+    "no-overflow" get BNO
+    src2 src2 tag-bits get SRAWI
+    temp1 src2 move>args
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke
+    "no-overflow" resolve-label ;
+
+M:: ppc %fixnum-mul-tail ( src1 src2 temp1 temp2 -- )
+    "overflow" define-label
+    clear-xer
+    temp1 src1 tag-bits get SRAWI
+    temp2 temp1 src2 MULLWO.
+    "overflow" get BO
+    temp2 ds-reg 0 STW
+    BLR
+    "overflow" resolve-label
+    src2 src2 tag-bits get SRAWI
+    temp1 src2 move>args
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke-tail ;
+
 : bignum@ ( n -- offset ) cells bignum tag-number - ; inline
 
 M:: ppc %integer>bignum ( dst src temp -- )
@@ -320,11 +410,8 @@ M: ppc %set-alien-cell swap 0 STW ;
 M: ppc %set-alien-float swap 0 STFS ;
 M: ppc %set-alien-double swap 0 STFD ;
 
-: %load-dlsym ( symbol dll register -- )
-    0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ;
-
 : load-zone-ptr ( reg -- )
-    [ "nursery" f ] dip %load-dlsym ;
+    "nursery" f %alien-global ;
 
 : load-allot-ptr ( nursery-ptr allot-ptr -- )
     [ drop load-zone-ptr ] [ swap 4 LWZ ] 2bi ;
@@ -346,14 +433,11 @@ M:: ppc %allot ( dst size class nursery-ptr -- )
     dst class store-header
     dst class store-tagged ;
 
-: %alien-global ( dst name -- )
-    [ f rot %load-dlsym ] [ drop dup 0 LWZ ] 2bi ;
-
 : load-cards-offset ( dst -- )
-    "cards_offset" %alien-global ;
+    [ "cards_offset" f %alien-global ] [ dup 0 LWZ ] bi ;
 
 : load-decks-offset ( dst -- )
-    "decks_offset" %alien-global ;
+    [ "decks_offset" f %alien-global ] [ dup 0 LWZ ] bi  ;
 
 M:: ppc %write-barrier ( src card# table -- )
     card-mark scratch-reg LI
@@ -398,14 +482,14 @@ M: ppc %epilogue ( n -- )
     1 1 rot ADDI
     0 MTLR ;
 
-:: (%boolean) ( dst word -- )
+:: (%boolean) ( dst temp word -- )
     "end" define-label
     dst \ f tag-number %load-immediate
     "end" get word execute
     dst \ t %load-indirect
     "end" get resolve-label ; inline
 
-: %boolean ( dst cc -- )
+: %boolean ( dst temp cc -- )
     negate-cc {
         { cc< [ \ BLT (%boolean) ] }
         { cc<= [ \ BLE (%boolean) ] }
@@ -540,14 +624,14 @@ M: ppc %prepare-alien-invoke
     #! Save Factor stack pointers in case the C code calls a
     #! callback which does a GC, which must reliably trace
     #! all roots.
-    "stack_chain" f 11 %load-dlsym
-    11 11 0 LWZ
-    1 11 0 STW
-    ds-reg 11 8 STW
-    rs-reg 11 12 STW ;
+    scratch-reg "stack_chain" f %alien-global
+    scratch-reg scratch-reg 0 LWZ
+    1 scratch-reg 0 STW
+    ds-reg scratch-reg 8 STW
+    rs-reg scratch-reg 12 STW ;
 
 M: ppc %alien-invoke ( symbol dll -- )
-    11 %load-dlsym 11 MTLR BLRL ;
+    [ 11 ] 2dip %alien-global 11 MTLR BLRL ;
 
 M: ppc %alien-callback ( quot -- )
     3 swap %load-indirect "c_to_factor" f %alien-invoke ;
old mode 100644 (file)
new mode 100755 (executable)
index f892271..5e06e72
@@ -23,8 +23,8 @@ M: x86.32 machine-registers
 M: x86.32 ds-reg ESI ;
 M: x86.32 rs-reg EDI ;
 M: x86.32 stack-reg ESP ;
-M: x86.32 temp-reg-1 EAX ;
-M: x86.32 temp-reg-2 ECX ;
+M: x86.32 temp-reg-1 ECX ;
+M: x86.32 temp-reg-2 EDX ;
 
 M:: x86.32 %dispatch ( src temp offset -- )
     ! Load jump table base.
@@ -38,12 +38,16 @@ M:: x86.32 %dispatch ( src temp offset -- )
     [ align-code ]
     bi ;
 
-M: x86.32 reserved-area-size 0 ;
+! Registers for fastcall
+M: x86.32 param-reg-1 EAX ;
+M: x86.32 param-reg-2 EDX ;
 
-M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ;
+M: x86.32 reserved-area-size 0 ;
 
 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 ;
@@ -88,8 +92,6 @@ M: float-regs store-return-reg
     [ [ align-sub ] [ call ] bi* ]
     [ [ align-add ] [ drop ] bi* ] 2bi ; inline
 
-M: x86.32 rel-literal-x86 rc-absolute-cell rel-literal ;
-
 M: x86.32 %prologue ( n -- )
     dup PUSH
     0 PUSH rc-absolute-cell rel-this
@@ -303,7 +305,7 @@ FUNCTION: bool check_sse2 ( ) ;
 : sse2? ( -- ? )
     check_sse2 ;
 
-"-no-sse2" cli-args member? [
+"-no-sse2" (command-line) member? [
     [ optimized-recompile-hook ] recompile-hook
     [ { check_sse2 } compile ] with-variable
 
index 75c808b50a405bec492dd04d46375825289a02e5..2077f51e0a7c8b5b1302bfb7ddf58f556d6e92f7 100644 (file)
@@ -21,8 +21,6 @@ M: x86.64 machine-registers
 M: x86.64 ds-reg R14 ;
 M: x86.64 rs-reg R15 ;
 M: x86.64 stack-reg RSP ;
-M: x86.64 temp-reg-1 RAX ;
-M: x86.64 temp-reg-2 RCX ;
 
 M:: x86.64 %dispatch ( src temp offset -- )
     ! Load jump table base.
@@ -37,15 +35,13 @@ M:: x86.64 %dispatch ( src temp offset -- )
     [ align-code ]
     bi ;
 
-: param-reg-1 int-regs param-regs first ; inline
-: param-reg-2 int-regs param-regs second ; inline
+M: x86.64 param-reg-1 int-regs param-regs first ;
+M: x86.64 param-reg-2 int-regs param-regs second ;
 : param-reg-3 int-regs param-regs third ; inline
 
 M: int-regs return-reg drop RAX ;
 M: float-regs return-reg drop XMM0 ;
 
-M: x86.64 rel-literal-x86 rc-relative rel-literal ;
-
 M: x86.64 %prologue ( n -- )
     temp-reg-1 0 MOV rc-absolute-cell rel-this
     dup PUSH
@@ -162,14 +158,16 @@ M: x86.64 %prepare-box-struct ( -- )
 
 M: x86.64 %prepare-var-args RAX RAX XOR ;
 
-M: x86.64 %alien-global
-    [ 0 MOV rc-absolute-cell rel-dlsym ] [ dup [] MOV ] bi ;
-
 M: x86.64 %alien-invoke
     R11 0 MOV
     rc-absolute-cell rel-dlsym
     R11 CALL ;
 
+M: x86.64 %alien-invoke-tail
+    R11 0 MOV
+    rc-absolute-cell rel-dlsym
+    R11 JMP ;
+
 M: x86.64 %prepare-alien-indirect ( -- )
     "unbox_alien" f %alien-invoke
     RBP RAX MOV ;
index ddb412873a60be0e136f177befa93b41d0b80b1f..f5fb5b9640c3f1eb16be0fd3428eda6dbf55dc80 100644 (file)
@@ -52,3 +52,7 @@ M: x86.64 dummy-stack-params? f ;
 M: x86.64 dummy-int-params? f ;
 
 M: x86.64 dummy-fp-params? f ;
+
+M: x86.64 temp-reg-1 R8 ;
+
+M: x86.64 temp-reg-2 R9 ;
index 9108c0e8f77b16a7d3fb55f40fba171bfd212861..4c6af6c1e71242074560fe7893bca715210f9e2c 100644 (file)
@@ -20,9 +20,13 @@ M: x86.64 dummy-int-params? t ;
 
 M: x86.64 dummy-fp-params? t ;
 
+M: x86.64 temp-reg-1 RAX ;
+
+M: x86.64 temp-reg-2 RCX ;
+
 <<
 "longlong" "ptrdiff_t" typedef
 "longlong" "intptr_t" typedef
-"int" "long" typedef
-"uint" "ulong" typedef
+"int" c-type "long" define-primitive-type
+"uint" c-type "ulong" define-primitive-type
 >>
index 5c6fff23485831653d0237f06953f82f14a009bc..2bea8872959c25e721db740bcd4de08c99878dfd 100644 (file)
@@ -130,7 +130,7 @@ M: register modifier drop BIN: 11 ;
 GENERIC# n, 1 ( value n -- )
 
 M: integer n, >le % ;
-M: byte n, >r value>> r> n, ;
+M: byte n, [ value>> ] dip n, ;
 : 1, ( n -- ) 1 n, ; inline
 : 4, ( n -- ) 4 n, ; inline
 : 2, ( n -- ) 2 n, ; inline
@@ -209,7 +209,7 @@ M: object operand-64? drop f ;
 : short-operand ( reg rex.w n -- )
     #! Some instructions encode their single operand as part of
     #! the opcode.
-    >r dupd prefix-1 reg-code r> + , ;
+    [ dupd prefix-1 reg-code ] dip + , ;
 
 : opcode, ( opcode -- ) dup array? [ % ] [ , ] if ;
 
@@ -224,7 +224,7 @@ M: object operand-64? drop f ;
 : 1-operand ( op reg,rex.w,opcode -- )
     #! The 'reg' is not really a register, but a value for the
     #! 'reg' field of the mod-r/m byte.
-    first3 >r >r over r> prefix-1 r> opcode, swap addressing ;
+    first3 [ [ over ] dip prefix-1 ] dip opcode, swap addressing ;
 
 : immediate-operand-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode )
     pick integer? [ first3 BIN: 1 opcode-or 3array ] when ;
@@ -250,7 +250,7 @@ M: object operand-64? drop f ;
     ] if ;
 
 : (2-operand) ( dst src op -- )
-    >r 2dup t rex-prefix r> opcode,
+    [ 2dup t rex-prefix ] dip opcode,
     reg-code swap addressing ;
 
 : direction-bit ( dst src op -- dst' src' op' )
@@ -271,11 +271,11 @@ M: object operand-64? drop f ;
 PRIVATE>
 
 : [] ( reg/displacement -- indirect )
-    dup integer? [ >r f f f r> ] [ f f f ] if <indirect> ;
+    dup integer? [ [ f f f ] dip ] [ f f f ] if <indirect> ;
 
 : [+] ( reg displacement -- indirect )
     dup integer?
-    [ dup zero? [ drop f ] when >r f f r> ]
+    [ dup zero? [ drop f ] when [ f f ] dip ]
     [ f f ] if
     <indirect> ;
 
@@ -300,7 +300,7 @@ PREDICATE: callable < word register? not ;
 
 GENERIC: MOV ( dst src -- )
 M: immediate MOV swap (MOV-I) ;
-M: callable MOV 0 rot (MOV-I) rc-absolute-cell rel-word ;
+M: callable MOV [ 0 ] 2dip (MOV-I) rc-absolute-cell rel-word ;
 M: operand MOV HEX: 88 2-operand ;
 
 : LEA ( dst src -- ) swap HEX: 8d 2-operand ;
@@ -308,18 +308,21 @@ M: operand MOV HEX: 88 2-operand ;
 ! Control flow
 GENERIC: JMP ( op -- )
 : (JMP) ( -- rel-class ) HEX: e9 , 0 4, rc-relative ;
+M: f JMP (JMP) 2drop ;
 M: callable JMP (JMP) rel-word ;
 M: label JMP (JMP) label-fixup ;
 M: operand JMP { BIN: 100 t HEX: ff } 1-operand ;
 
 GENERIC: CALL ( op -- )
 : (CALL) ( -- rel-class ) HEX: e8 , 0 4, rc-relative ;
+M: f CALL (CALL) 2drop ;
 M: callable CALL (CALL) rel-word ;
 M: label CALL (CALL) label-fixup ;
 M: operand CALL { BIN: 010 t HEX: ff } 1-operand ;
 
 GENERIC# JUMPcc 1 ( addr opcode -- )
 : (JUMPcc) ( n -- rel-class ) extended-opcode, 0 4, rc-relative ;
+M: f JUMPcc nip (JUMPcc) drop ;
 M: callable JUMPcc (JUMPcc) rel-word ;
 M: label JUMPcc (JUMPcc) label-fixup ;
 
@@ -381,6 +384,8 @@ M: operand CMP OCT: 070 2-operand ;
 
 : XCHG ( dst src -- ) OCT: 207 2-operand ;
 
+: BSR ( dst src -- ) swap { HEX: 0f HEX: bd } (2-operand) ;
+
 : NOT  ( dst -- ) { BIN: 010 t HEX: f7 } 1-operand ;
 : NEG  ( dst -- ) { BIN: 011 t HEX: f7 } 1-operand ;
 : MUL  ( dst -- ) { BIN: 100 t HEX: f7 } 1-operand ;
index d267baaf4f02abc46a6e85b9f036a0798b4b68f7..6ddec4af07e87ff914a9339b47c8ed68f2677058 100644 (file)
@@ -4,8 +4,8 @@ USING: kernel words sequences lexer parser fry ;
 IN: cpu.x86.assembler.syntax
 
 : define-register ( name num size -- )
-    >r >r "cpu.x86.assembler" create dup define-symbol r> r>
-    >r dupd "register" set-word-prop r>
+    [ "cpu.x86.assembler" create dup define-symbol ] 2dip
+    [ dupd "register" set-word-prop ] dip
     "register-size" set-word-prop ;
 
 : define-registers ( names size -- )
index af7c9e2f0f8222fb01fcf4eaffdb33f33a92f031..597a2c9d319963f2c20730686a5f62c0f1a9a5de 100644 (file)
@@ -13,7 +13,6 @@ big-endian off
 [
     ! Load word
     temp-reg 0 MOV
-    temp-reg dup [] MOV
     ! Bump profiling counter
     temp-reg profile-count-offset [+] 1 tag-fixnum ADD
     ! Load word->code
@@ -22,7 +21,7 @@ big-endian off
     temp-reg compiled-header-size ADD
     ! Jump to XT
     temp-reg JMP
-] rc-absolute-cell rt-literal 1 rex-length + jit-profiling jit-define
+] rc-absolute-cell rt-immediate 1 rex-length + jit-profiling jit-define
 
 [
     temp-reg 0 MOV                             ! load XT
@@ -31,13 +30,6 @@ big-endian off
     stack-reg stack-frame-size 3 bootstrap-cells - SUB   ! alignment
 ] rc-absolute-cell rt-label 1 rex-length + jit-prolog jit-define
 
-[
-    arg0 0 MOV                                 ! load literal
-    arg0 dup [] MOV
-    ds-reg bootstrap-cell ADD                  ! increment datastack pointer
-    ds-reg [] arg0 MOV                         ! store literal on datastack
-] rc-absolute-cell rt-literal 1 rex-length + jit-push-literal jit-define
-
 [
     arg0 0 MOV                                 ! load literal
     ds-reg bootstrap-cell ADD                  ! increment datastack pointer
@@ -45,107 +37,99 @@ big-endian off
 ] rc-absolute-cell rt-immediate 1 rex-length + jit-push-immediate jit-define
 
 [
-    (JMP) drop
+    f JMP
 ] rc-relative rt-xt 1 jit-word-jump jit-define
 
 [
-    (CALL) drop
+    f CALL
 ] rc-relative rt-xt 1 jit-word-call jit-define
 
 [
-    arg1 0 MOV                                 ! load addr of true quotation
     arg0 ds-reg [] MOV                         ! load boolean
     ds-reg bootstrap-cell SUB                  ! pop boolean
-    arg0 \ f tag-number CMP                    ! compare it with f
-    arg0 arg1 [] CMOVNE                        ! load true branch if not equal
-    arg0 arg1 bootstrap-cell [+] CMOVE         ! load false branch if equal
-    arg0 quot-xt-offset [+] JMP                ! jump to quotation-xt
-] rc-absolute-cell rt-literal 1 rex-length + jit-if-jump jit-define
+    arg0 \ f tag-number CMP                    ! compare boolean with f
+    f JNE                                      ! jump to true branch if not equal
+] rc-relative rt-xt 10 rex-length 3 * + jit-if-1 jit-define
+
+[
+    f JMP                                      ! jump to false branch if equal
+] rc-relative rt-xt 1 jit-if-2 jit-define
 
 [
     arg1 0 MOV                                 ! load dispatch table
-    arg1 dup [] MOV
     arg0 ds-reg [] MOV                         ! load index
     fixnum>slot@                               ! turn it into an array offset
     ds-reg bootstrap-cell SUB                  ! pop index
     arg0 arg1 ADD                              ! compute quotation location
     arg0 arg0 array-start-offset [+] MOV       ! load quotation
     arg0 quot-xt-offset [+] JMP                ! execute branch
-] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define
-
-! The jit->r words cannot clobber arg0
+] rc-absolute-cell rt-immediate 1 rex-length + jit-dispatch jit-define
 
 : jit->r ( -- )
     rs-reg bootstrap-cell ADD
-    temp-reg ds-reg [] MOV
+    arg0 ds-reg [] MOV
     ds-reg bootstrap-cell SUB
-    rs-reg [] temp-reg MOV ;
+    rs-reg [] arg0 MOV ;
 
 : jit-2>r ( -- )
     rs-reg 2 bootstrap-cells ADD
-    temp-reg ds-reg [] MOV
+    arg0 ds-reg [] MOV
     arg1 ds-reg -1 bootstrap-cells [+] MOV
     ds-reg 2 bootstrap-cells SUB
-    rs-reg [] temp-reg MOV
+    rs-reg [] arg0 MOV
     rs-reg -1 bootstrap-cells [+] arg1 MOV ;
 
 : jit-3>r ( -- )
     rs-reg 3 bootstrap-cells ADD
-    temp-reg ds-reg [] MOV
+    arg0 ds-reg [] MOV
     arg1 ds-reg -1 bootstrap-cells [+] MOV
     arg2 ds-reg -2 bootstrap-cells [+] MOV
     ds-reg 3 bootstrap-cells SUB
-    rs-reg [] temp-reg MOV
+    rs-reg [] arg0 MOV
     rs-reg -1 bootstrap-cells [+] arg1 MOV
     rs-reg -2 bootstrap-cells [+] arg2 MOV ;
 
 : jit-r> ( -- )
     ds-reg bootstrap-cell ADD
-    temp-reg rs-reg [] MOV
+    arg0 rs-reg [] MOV
     rs-reg bootstrap-cell SUB
-    ds-reg [] temp-reg MOV ;
+    ds-reg [] arg0 MOV ;
 
 : jit-2r> ( -- )
     ds-reg 2 bootstrap-cells ADD
-    temp-reg rs-reg [] MOV
+    arg0 rs-reg [] MOV
     arg1 rs-reg -1 bootstrap-cells [+] MOV
     rs-reg 2 bootstrap-cells SUB
-    ds-reg [] temp-reg MOV
+    ds-reg [] arg0 MOV
     ds-reg -1 bootstrap-cells [+] arg1 MOV ;
 
 : jit-3r> ( -- )
     ds-reg 3 bootstrap-cells ADD
-    temp-reg rs-reg [] MOV
+    arg0 rs-reg [] MOV
     arg1 rs-reg -1 bootstrap-cells [+] MOV
     arg2 rs-reg -2 bootstrap-cells [+] MOV
     rs-reg 3 bootstrap-cells SUB
-    ds-reg [] temp-reg MOV
+    ds-reg [] arg0 MOV
     ds-reg -1 bootstrap-cells [+] arg1 MOV
     ds-reg -2 bootstrap-cells [+] arg2 MOV ;
 
 [
-    arg0 0 MOV                                 ! load quotation addr
-    arg0 arg0 [] MOV                           ! load quotation
     jit->r
-    arg0 quot-xt-offset [+] CALL               ! call quotation
+    f CALL
     jit-r>
-] rc-absolute-cell rt-literal 1 rex-length + jit-dip jit-define
+] rc-relative rt-xt 11 rex-length 4 * + jit-dip jit-define
 
 [
-    arg0 0 MOV                                 ! load quotation addr
-    arg0 arg0 [] MOV                           ! load quotation
     jit-2>r
-    arg0 quot-xt-offset [+] CALL               ! call quotation
+    f CALL
     jit-2r>
-] rc-absolute-cell rt-literal 1 rex-length + jit-2dip jit-define
+] rc-relative rt-xt 17 rex-length 6 * + jit-2dip jit-define
 
 [
-    arg0 0 MOV                                 ! load quotation addr
-    arg0 arg0 [] MOV                           ! load quotation
     jit-3>r                                    
-    arg0 quot-xt-offset [+] CALL               ! call quotation
+    f CALL
     jit-3r>
-] rc-absolute-cell rt-literal 1 rex-length + jit-3dip jit-define
+] rc-relative rt-xt 23 rex-length 8 * + jit-3dip jit-define
 
 [
     stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame
@@ -303,9 +287,8 @@ big-endian off
 
 ! Comparisons
 : jit-compare ( insn -- )
-    arg1 0 MOV                                 ! load t
-    arg1 dup [] MOV
-    temp-reg \ f tag-number MOV                ! load f
+    temp-reg 0 MOV                             ! load t
+    arg1 \ f tag-number MOV                    ! load f
     arg0 ds-reg [] MOV                         ! load first value
     ds-reg bootstrap-cell SUB                  ! adjust stack pointer
     ds-reg [] arg0 CMP                         ! compare with second value
@@ -314,14 +297,14 @@ big-endian off
     ;
 
 : define-jit-compare ( insn word -- )
-    [ [ jit-compare ] curry rc-absolute-cell rt-literal 1 rex-length + ] dip
+    [ [ jit-compare ] curry rc-absolute-cell rt-immediate 1 rex-length + ] dip
     define-sub-primitive ;
 
-\ CMOVNE \ eq? define-jit-compare
-\ CMOVL \ fixnum>= define-jit-compare
-\ CMOVG \ fixnum<= define-jit-compare
-\ CMOVLE \ fixnum> define-jit-compare
-\ CMOVGE \ fixnum< define-jit-compare
+\ CMOVE \ eq? define-jit-compare
+\ CMOVGE \ fixnum>= define-jit-compare
+\ CMOVLE \ fixnum<= define-jit-compare
+\ CMOVG \ fixnum> define-jit-compare
+\ CMOVL \ fixnum< define-jit-compare
 
 ! Math
 : jit-math ( insn -- )
@@ -396,12 +379,21 @@ big-endian off
     ds-reg bootstrap-cell neg [+] div-arg MOV
 ] f f f \ fixnum/mod-fast define-sub-primitive
 
+[
+    arg0 ds-reg [] MOV
+    ds-reg bootstrap-cell SUB
+    arg0 ds-reg [] OR
+    arg0 tag-mask get AND
+    arg0 \ f tag-number MOV
+    arg1 1 tag-fixnum MOV
+    arg0 arg1 CMOVE
+    ds-reg [] arg0 MOV
+] f f f \ both-fixnums? define-sub-primitive
+
 [
     arg0 ds-reg [] MOV                         ! load local number
     fixnum>slot@                               ! turn local number into offset
-    arg1 bootstrap-cell MOV                    ! load base
-    arg1 arg0 SUB                              ! turn it into a stack offset
-    arg0 rs-reg arg1 [+] MOV                   ! load local value
+    arg0 rs-reg arg0 [+] MOV                   ! load local value
     ds-reg [] arg0 MOV                         ! push to stack
 ] f f f \ get-local define-sub-primitive
 
index 58d95ffcde0670265bd5668cac76610165b92dbb..44300a75f97368194ab5b0e0d60c7dc663525cb4 100644 (file)
@@ -5,20 +5,23 @@ cpu.x86.assembler cpu.x86.assembler.private cpu.architecture
 kernel kernel.private math memory namespaces make sequences
 words system layouts combinators math.order fry locals
 compiler.constants compiler.cfg.registers
-compiler.cfg.instructions compiler.codegen
-compiler.codegen.fixup ;
+compiler.cfg.instructions compiler.cfg.intrinsics
+compiler.codegen compiler.codegen.fixup ;
 IN: cpu.x86
 
+<< enable-fixnum-log2 >>
+
 M: x86 two-operand? t ;
 
 HOOK: temp-reg-1 cpu ( -- reg )
 HOOK: temp-reg-2 cpu ( -- reg )
 
-M: x86 %load-immediate MOV ;
+HOOK: param-reg-1 cpu ( -- reg )
+HOOK: param-reg-2 cpu ( -- reg )
 
-HOOK: rel-literal-x86 cpu ( literal -- )
+M: x86 %load-immediate MOV ;
 
-M: x86 %load-indirect swap 0 [] MOV rel-literal-x86 ;
+M: x86 %load-indirect swap 0 MOV rc-absolute-cell rel-immediate ;
 
 HOOK: ds-reg cpu ( -- reg )
 HOOK: rs-reg cpu ( -- reg )
@@ -91,6 +94,88 @@ M: x86 %shl-imm nip SHL ;
 M: x86 %shr-imm nip SHR ;
 M: x86 %sar-imm nip SAR ;
 M: x86 %not     drop NOT ;
+M: x86 %log2    BSR ;
+
+: ?MOV ( dst src -- )
+    2dup = [ 2drop ] [ MOV ] if ; inline
+
+:: move>args ( src1 src2 -- )
+    {
+        { [ src1 param-reg-2 = ] [ param-reg-1 src2 ?MOV param-reg-1 param-reg-2 XCHG ] }
+        { [ src1 param-reg-1 = ] [ param-reg-2 src2 ?MOV ] }
+        { [ src2 param-reg-1 = ] [ param-reg-2 src1 ?MOV param-reg-1 param-reg-2 XCHG ] }
+        { [ src2 param-reg-2 = ] [ param-reg-1 src1 ?MOV ] }
+        [
+            param-reg-1 src1 MOV
+            param-reg-2 src2 MOV
+        ]
+    } cond ;
+
+HOOK: %alien-invoke-tail cpu ( func dll -- )
+
+:: overflow-template ( src1 src2 insn inverse func -- )
+    <label> "no-overflow" set
+    src1 src2 insn call
+    ds-reg [] src1 MOV
+    "no-overflow" get JNO
+    src1 src2 inverse call
+    src1 src2 move>args
+    %prepare-alien-invoke
+    func f %alien-invoke
+    "no-overflow" resolve-label ; inline
+
+:: overflow-template-tail ( src1 src2 insn inverse func -- )
+    <label> "no-overflow" set
+    src1 src2 insn call
+    "no-overflow" get JNO
+    src1 src2 inverse call
+    src1 src2 move>args
+    %prepare-alien-invoke
+    func f %alien-invoke-tail
+    "no-overflow" resolve-label
+    ds-reg [] src1 MOV
+    0 RET ; inline
+
+M: x86 %fixnum-add ( src1 src2 -- )
+    [ ADD ] [ SUB ] "overflow_fixnum_add" overflow-template ;
+
+M: x86 %fixnum-add-tail ( src1 src2 -- )
+    [ ADD ] [ SUB ] "overflow_fixnum_add" overflow-template-tail ;
+
+M: x86 %fixnum-sub ( src1 src2 -- )
+    [ SUB ] [ ADD ] "overflow_fixnum_subtract" overflow-template ;
+
+M: x86 %fixnum-sub-tail ( src1 src2 -- )
+    [ SUB ] [ ADD ] "overflow_fixnum_subtract" overflow-template-tail ;
+
+M:: x86 %fixnum-mul ( src1 src2 temp1 temp2 -- )
+    "no-overflow" define-label
+    temp1 src1 MOV
+    temp1 tag-bits get SAR
+    src2 temp1 IMUL2
+    ds-reg [] temp1 MOV
+    "no-overflow" get JNO
+    src1 src2 move>args
+    param-reg-1 tag-bits get SAR
+    param-reg-2 tag-bits get SAR
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke
+    "no-overflow" resolve-label ;
+
+M:: x86 %fixnum-mul-tail ( src1 src2 temp1 temp2 -- )
+    "overflow" define-label
+    temp1 src1 MOV
+    temp1 tag-bits get SAR
+    src2 temp1 IMUL2
+    "overflow" get JO
+    ds-reg [] temp1 MOV
+    0 RET
+    "overflow" resolve-label
+    src1 src2 move>args
+    param-reg-1 tag-bits get SAR
+    param-reg-2 tag-bits get SAR
+    %prepare-alien-invoke
+    "overflow_fixnum_multiply" f %alien-invoke-tail ;
 
 : bignum@ ( reg n -- op )
     cells bignum tag-number - [+] ; inline
@@ -160,9 +245,6 @@ M: x86 %div-float nip DIVSD ;
 M: x86 %integer>float CVTSI2SD ;
 M: x86 %float>integer CVTTSD2SI ;
 
-: ?MOV ( dst src -- )
-    2dup = [ 2drop ] [ MOV ] if ; inline
-
 M: x86 %copy ( dst src -- ) ?MOV ;
 
 M: x86 %copy-float ( dst src -- )
@@ -286,23 +368,38 @@ M:: x86 %box-alien ( dst src temp -- )
 M:: x86 %string-nth ( dst src index temp -- )
     "end" define-label
     dst { src index temp } [| new-dst |
+        ! Load the least significant 7 bits into new-dst.
+        ! 8th bit indicates whether we have to load from
+        ! the aux vector or not.
         temp src index [+] LEA
         new-dst 1 small-reg temp string-offset [+] MOV
         new-dst new-dst 1 small-reg MOVZX
+        ! Do we have to look at the aux vector?
+        new-dst HEX: 80 CMP
+        "end" get JL
+        ! Yes, this is a non-ASCII character. Load aux vector
         temp src string-aux-offset [+] MOV
-        temp \ f tag-number CMP
-        "end" get JE
         new-dst temp XCHG
+        ! Compute index
         new-dst index ADD
         new-dst index ADD
+        ! Load high 16 bits
         new-dst 2 small-reg new-dst byte-array-offset [+] MOV
         new-dst new-dst 2 small-reg MOVZX
-        new-dst 8 SHL
-        new-dst temp OR
+        new-dst 7 SHL
+        ! Compute code point
+        new-dst temp XOR
         "end" resolve-label
         dst new-dst ?MOV
     ] with-small-register ;
 
+M:: x86 %set-string-nth-fast ( ch str index temp -- )
+    ch { index str temp } [| new-ch |
+        new-ch ch ?MOV
+        temp str index [+] LEA
+        temp string-offset [+] new-ch 1 small-reg MOV
+    ] with-small-register ;
+
 :: %alien-integer-getter ( dst src size quot -- )
     dst { src } [| new-dst |
         new-dst dup size small-reg dup src [] MOV
@@ -364,19 +461,19 @@ M:: x86 %allot ( dst size class nursery-ptr -- )
     dst class store-tagged
     nursery-ptr size inc-allot-ptr ;
 
-HOOK: %alien-global cpu ( symbol dll register -- )
-
 M:: x86 %write-barrier ( src card# table -- )
     #! Mark the card pointed to by vreg.
     ! Mark the card
     card# src MOV
     card# card-bits SHR
-    "cards_offset" f table %alien-global
+    table "cards_offset" f %alien-global
+    table table [] MOV
     table card# [+] card-mark <byte> MOV
 
     ! Mark the card deck
     card# deck-bits card-bits - SHR
-    "decks_offset" f table %alien-global
+    table "decks_offset" f %alien-global
+    table table [] MOV
     table card# [+] card-mark <byte> MOV ;
 
 M: x86 %gc ( -- )
@@ -391,6 +488,9 @@ M: x86 %gc ( -- )
     "minor_gc" f %alien-invoke
     "end" resolve-label ;
 
+M: x86 %alien-global
+    [ 0 MOV ] 2dip rc-absolute-cell rel-dlsym ;
+
 HOOK: stack-reg cpu ( -- reg )
 
 : decr-stack-reg ( n -- )
@@ -401,12 +501,12 @@ HOOK: stack-reg cpu ( -- reg )
 
 M: x86 %epilogue ( n -- ) cell - incr-stack-reg ;
 
-: %boolean ( dst word -- )
-    over \ f tag-number MOV
-    0 [] swap execute
-    \ t rel-literal-x86 ; inline
+:: %boolean ( dst temp word -- )
+    dst \ f tag-number MOV
+    temp 0 MOV \ t rc-absolute-cell rel-immediate
+    dst temp word execute ; inline
 
-M: x86 %compare ( dst cc src1 src2 -- )
+M: x86 %compare ( dst temp cc src1 src2 -- )
     CMP {
         { cc< [ \ CMOVL %boolean ] }
         { cc<= [ \ CMOVLE %boolean ] }
@@ -416,10 +516,10 @@ M: x86 %compare ( dst cc src1 src2 -- )
         { cc/= [ \ CMOVNE %boolean ] }
     } case ;
 
-M: x86 %compare-imm ( dst cc src1 src2 -- )
+M: x86 %compare-imm ( dst temp cc src1 src2 -- )
     %compare ;
 
-M: x86 %compare-float ( dst cc src1 src2 -- )
+M: x86 %compare-float ( dst temp cc src1 src2 -- )
     UCOMISD {
         { cc< [ \ CMOVB %boolean ] }
         { cc<= [ \ CMOVBE %boolean ] }
@@ -482,7 +582,7 @@ M: x86 %reload-float ( dst n -- ) spill-float@ MOVSD ;
 
 M: x86 %loop-entry 16 code-alignment [ NOP ] times ;
 
-M: int-regs %save-param-reg drop >r param@ r> MOV ;
+M: int-regs %save-param-reg drop [ param@ ] dip MOV ;
 M: int-regs %load-param-reg drop swap param@ MOV ;
 
 GENERIC: MOVSS/D ( dst src reg-class -- )
@@ -490,8 +590,8 @@ GENERIC: MOVSS/D ( dst src reg-class -- )
 M: single-float-regs MOVSS/D drop MOVSS ;
 M: double-float-regs MOVSS/D drop MOVSD ;
 
-M: float-regs %save-param-reg >r >r param@ r> r> MOVSS/D ;
-M: float-regs %load-param-reg >r swap param@ r> MOVSS/D ;
+M: float-regs %save-param-reg [ param@ ] 2dip MOVSS/D ;
+M: float-regs %load-param-reg [ swap param@ ] dip MOVSS/D ;
 
 GENERIC: push-return-reg ( reg-class -- )
 GENERIC: load-return-reg ( n reg-class -- )
@@ -501,7 +601,8 @@ M: x86 %prepare-alien-invoke
     #! Save Factor stack pointers in case the C code calls a
     #! callback which does a GC, which must reliably trace
     #! all roots.
-    "stack_chain" f temp-reg-1 %alien-global
+    temp-reg-1 "stack_chain" f %alien-global
+    temp-reg-1 temp-reg-1 [] MOV
     temp-reg-1 [] stack-reg MOV
     temp-reg-1 [] cell SUB
     temp-reg-1 2 cells [+] ds-reg MOV
index 3ee0fe3d09a3e1c9d2c355f8316c95279c735604..b7bd8218a2e0d832e9083ec95d75a78ed4cd2e98 100644 (file)
@@ -48,7 +48,7 @@ GENERIC: more-rows? ( result-set -- ? )
 : new-result-set ( query handle class -- result-set )
     new
         swap >>handle
-        >r [ sql>> ] [ in-params>> ] [ out-params>> ] tri r>
+        [ [ sql>> ] [ in-params>> ] [ out-params>> ] tri ] dip
         swap >>out-params
         swap >>in-params
         swap >>sql ;
index 63284b28a30d985b908a4125cb37dd5e3c6498e4..5149d14f3d8986d5a77c1b015b970cc010244e45 100644 (file)
@@ -5,7 +5,8 @@ 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
 accessors strings serialize io.encodings.binary io.encodings.utf8
-alien.strings io.streams.byte-array summary present urls ;
+alien.strings io.streams.byte-array summary present urls
+specialized-arrays.uint specialized-arrays.alien ;
 IN: db.postgresql.lib
 
 : postgresql-result-error-message ( res -- str/f )
@@ -64,7 +65,7 @@ M: postgresql-result-null summary ( obj -- str )
     } case ;
 
 : param-types ( statement -- seq )
-    in-params>> [ type>> type>oid ] map >c-uint-array ;
+    in-params>> [ type>> type>oid ] uint-array{ } map-as underlying>> ;
 
 : malloc-byte-array/length ( byte-array -- alien length )
     [ malloc-byte-array &free ] [ length ] bi ;
@@ -75,7 +76,7 @@ M: postgresql-result-null summary ( obj -- str )
 : param-values ( statement -- seq seq2 )
     [ bind-params>> ] [ in-params>> ] bi
     [
-        >r value>> r> type>> {
+        [ value>> ] [ type>> ] bi* {
             { FACTOR-BLOB [
                 dup [ object>bytes malloc-byte-array/length ] [ 0 ] if
             ] }
@@ -90,15 +91,15 @@ M: postgresql-result-null summary ( obj -- str )
     ] 2map flip [
         f f
     ] [
-        first2 [ >c-void*-array ] [ >c-uint-array ] bi*
+        first2 [ >void*-array underlying>> ] [ >uint-array underlying>> ] bi*
     ] if-empty ;
 
 : param-formats ( statement -- seq )
-    in-params>> [ type>> type>param-format ] map >c-uint-array ;
+    in-params>> [ type>> type>param-format ] uint-array{ } map-as underlying>> ;
 
 : do-postgresql-bound-statement ( statement -- res )
     [
-        >r db get handle>> r>
+        [ db get handle>> ] dip
         {
             [ sql>> ]
             [ bind-params>> length ]
@@ -116,7 +117,7 @@ M: postgresql-result-null summary ( obj -- str )
 
 : pq-get-string ( handle row column -- obj )
     3dup PQgetvalue utf8 alien>string
-    dup empty? [ >r pq-get-is-null f r> ? ] [ 3nip ] if ;
+    dup empty? [ [ pq-get-is-null f ] dip ? ] [ 3nip ] if ;
 
 : pq-get-number ( handle row column -- obj )
     pq-get-string dup [ string>number ] when ;
index fe53e2416e8a147df5a6ef2be605942c6a805ea2..bc5ec2f0c5d10633319240f7eb86cec6dc0e5cac 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel db.postgresql alien continuations io classes
 prettyprint sequences namespaces tools.test db
-db.tuples db.types unicode.case accessors ;
+db.tuples db.types unicode.case accessors system ;
 IN: db.postgresql.tests
 
 : test-db ( -- postgresql-db )
@@ -10,86 +10,88 @@ IN: db.postgresql.tests
         "thepasswordistrust" >>password
         "factor-test" >>database ;
 
-[ ] [ test-db [ ] with-db ] unit-test
+os windows? cpu x86.64? and [
+    [ ] [ test-db [ ] with-db ] unit-test
 
-[ ] [
-    test-db [
-        [ "drop table person;" sql-command ] ignore-errors
-        "create table person (name varchar(30), country varchar(30));"
-            sql-command
+    [ ] [
+        test-db [
+            [ "drop table person;" sql-command ] ignore-errors
+            "create table person (name varchar(30), country varchar(30));"
+                sql-command
 
-        "insert into person values('John', 'America');" sql-command
-        "insert into person values('Jane', 'New Zealand');" sql-command
-    ] with-db
-] unit-test
+            "insert into person values('John', 'America');" sql-command
+            "insert into person values('Jane', 'New Zealand');" sql-command
+        ] with-db
+    ] unit-test
 
-[
-    {
-        { "John" "America" }
-        { "Jane" "New Zealand" }
-    }
-] [
-    test-db [
-        "select * from person" sql-query
-    ] with-db
-] unit-test
+    [
+        {
+            { "John" "America" }
+            { "Jane" "New Zealand" }
+        }
+    ] [
+        test-db [
+            "select * from person" sql-query
+        ] with-db
+    ] unit-test
 
-[
-    {
-        { "John" "America" }
-        { "Jane" "New Zealand" }
-    }
-] [ test-db [ "select * from person" sql-query ] with-db ] unit-test
+    [
+        {
+            { "John" "America" }
+            { "Jane" "New Zealand" }
+        }
+    ] [ test-db [ "select * from person" sql-query ] with-db ] unit-test
 
-[
-] [
-    test-db [
-        "insert into person(name, country) values('Jimmy', 'Canada')"
-        sql-command
-    ] with-db
-] unit-test
+    [
+    ] [
+        test-db [
+            "insert into person(name, country) values('Jimmy', 'Canada')"
+            sql-command
+        ] with-db
+    ] unit-test
 
-[
-    {
-        { "John" "America" }
-        { "Jane" "New Zealand" }
-        { "Jimmy" "Canada" }
-    }
-] [ test-db [ "select * from person" sql-query ] with-db ] unit-test
+    [
+        {
+            { "John" "America" }
+            { "Jane" "New Zealand" }
+            { "Jimmy" "Canada" }
+        }
+    ] [ test-db [ "select * from person" sql-query ] with-db ] unit-test
 
-[
-    test-db [
-        [
-            "insert into person(name, country) values('Jose', 'Mexico')" sql-command
-            "insert into person(name, country) values('Jose', 'Mexico')" sql-command
-            "oops" throw
-        ] with-transaction
-    ] with-db
-] must-fail
+    [
+        test-db [
+            [
+                "insert into person(name, country) values('Jose', 'Mexico')" sql-command
+                "insert into person(name, country) values('Jose', 'Mexico')" sql-command
+                "oops" throw
+            ] with-transaction
+        ] with-db
+    ] must-fail
 
-[ 3 ] [
-    test-db [
-        "select * from person" sql-query length
-    ] with-db
-] unit-test
+    [ 3 ] [
+        test-db [
+            "select * from person" sql-query length
+        ] with-db
+    ] unit-test
 
-[
-] [
-    test-db [
-        [
-            "insert into person(name, country) values('Jose', 'Mexico')"
-            sql-command
-            "insert into person(name, country) values('Jose', 'Mexico')"
-            sql-command
-        ] with-transaction
-    ] with-db
-] unit-test
+    [
+    ] [
+        test-db [
+            [
+                "insert into person(name, country) values('Jose', 'Mexico')"
+                sql-command
+                "insert into person(name, country) values('Jose', 'Mexico')"
+                sql-command
+            ] with-transaction
+        ] with-db
+    ] unit-test
 
-[ 5 ] [
-    test-db [
-        "select * from person" sql-query length
-    ] with-db
-] unit-test
+    [ 5 ] [
+        test-db [
+            "select * from person" sql-query length
+        ] with-db
+    ] unit-test
+] unless
 
 
 : with-dummy-db ( quot -- )
index 57a16fc8efa3115b682be11c4d64b4b51014d864..90a875b8fff6f4992731f1073ffd538d79a596e5 100644 (file)
@@ -266,8 +266,8 @@ M: postgresql-db persistent-table ( -- hashtable )
 ERROR: no-compound-found string object ;
 M: postgresql-db compound ( string object -- string' )
     over {
-        { "default" [ first number>string join-space ] }
-        { "varchar" [ first number>string paren append ] }
+        { "default" [ first number>string " " glue ] }
+        { "varchar" [ first number>string "(" ")" surround append ] }
         { "references" [ >reference-string ] }
         [ drop no-compound-found ]
     } case ;
index 49de6ee5fcfd15def5bd8116360312486929b489..a96398ff2c88c93be25c58583ead3f50386a6927 100644 (file)
@@ -95,7 +95,7 @@ M: random-id-generator eval-generator ( singleton -- obj )
         3drop
     ] [
         pick column-name>> 0%
-        >r first2 r> interval-comparison 0%
+        [ first2 ] dip interval-comparison 0%
         bind#
     ] if ;
 
@@ -162,22 +162,19 @@ M: db <select-by-slots-statement> ( tuple class -- statement )
         where-clause
     ] query-make ;
 
-: splice ( string1 string2 string3 -- string )
-    swap 3append ;
-
 : do-group ( tuple groups -- )
     dup string? [ 1array ] when
-    [ ", " join " group by " splice ] curry change-sql drop ;
+    [ ", " join " group by " glue ] curry change-sql drop ;
 
 : do-order ( tuple order -- )
     dup string? [ 1array ] when
-    [ ", " join " order by " splice ] curry change-sql drop ;
+    [ ", " join " order by " glue ] curry change-sql drop ;
 
 : do-offset ( tuple n -- )
-    [ number>string " offset " splice ] curry change-sql drop ;
+    [ number>string " offset " glue ] curry change-sql drop ;
 
 : do-limit ( tuple n -- )
-    [ number>string " limit " splice ] curry change-sql drop ;
+    [ number>string " limit " glue ] curry change-sql drop ;
 
 : make-query* ( tuple query -- tuple' )
     dupd
@@ -201,7 +198,7 @@ M: db <count-statement> ( query -- statement )
 
 : create-index ( index-name table-name columns -- )
     [
-        >r >r "create index " % % r> " on " % % r> "(" %
+        [ [ "create index " % % ] dip " on " % % ] dip "(" %
         "," join % ")" %
     ] "" make sql-command ;
 
index c22bb3a2d8a2bc464a39f04dc36c0eff735741db..4e96fb5a4deea6d48893ddc61b2234d005eed7a7 100644 (file)
@@ -308,7 +308,7 @@ M: sqlite-db persistent-table ( -- assoc )
 
 M: sqlite-db compound ( string seq -- new-string )
     over {
-        { "default" [ first number>string join-space ] }
+        { "default" [ first number>string " " glue ] }
         { "references" [
             [ >reference-string ] keep
             first2 [ "foreign-table" set ]
index 192986484ec022395227c33bacf4d06605342d72..0432f3868381da552a5228240f38ee141e05e9f8 100644 (file)
@@ -3,7 +3,7 @@
 USING: io.files kernel tools.test db db.tuples classes
 db.types continuations namespaces math math.ranges
 prettyprint calendar sequences db.sqlite math.intervals
-db.postgresql accessors random math.bitwise
+db.postgresql accessors random math.bitwise system
 math.ranges strings urls fry db.tuples.private ;
 IN: db.tuples.tests
 
@@ -26,7 +26,9 @@ IN: db.tuples.tests
 
 : test-postgresql ( quot -- )
     '[
-        [ ] [ postgresql-db _ with-db ] unit-test
+        os windows? cpu x86.64? and [
+            [ ] [ postgresql-db _ with-db ] unit-test
+        ] unless
     ] call ; inline
 
 ! These words leak resources, but are useful for interactivel testing 
index f1a6ba6c6c9085981601b506e5149c90caddb7e9..bd0b443fbe860f15a43ec36f41d1c49fe327f4fa 100644 (file)
@@ -147,12 +147,6 @@ HELP: get-slot-named
      { "value" "the value stored in the slot" } }
 { $description "Returns the value stored in a tuple slot, where the tuple slot is a string." } ;
 
-HELP: join-space
-{ $values
-     { "string1" string } { "string2" string }
-     { "new-string" null } }
-{ $description "" } ;
-
 HELP: literal-bind
 { $description "" } ;
 
index 6a889689ce0c91416706d77a169cbd2fd73cb29a..da9fe39b8065aeef2fac5558a2bdc2958657ea6d 100644 (file)
@@ -158,12 +158,6 @@ ERROR: no-sql-type type ;
     modifiers>> [ lookup-modifier ] map " " join
     [ "" ] [ " " prepend ] if-empty ;
 
-: join-space ( string1 string2 -- new-string )
-    " " swap 3append ;
-
-: paren ( string -- new-string )
-    "(" swap ")" 3append ;
-
 HOOK: bind% db ( spec -- )
 HOOK: bind# db ( spec obj -- )
 
@@ -171,7 +165,7 @@ ERROR: no-column column ;
 
 : >reference-string ( string pair -- string )
     first2
-    [ [ unparse join-space ] [ db-columns ] bi ] dip
+    [ [ unparse " " glue ] [ db-columns ] bi ] dip
     swap [ column-name>> = ] with find nip
     [ no-column ] unless*
-    column-name>> paren append ;
+    column-name>> "(" ")" surround append ;
index fe00d011c366a05892259bb1c36a7754afb7fcb0..30c9fd37abf529c106699bfe84bd1a84e1a460ca 100644 (file)
@@ -131,11 +131,11 @@ HELP: datastack-overflow.
 { $notes "This error usually indicates a run-away recursion, however if you legitimately need a data stack larger than the default, see " { $link "runtime-cli-args" } "." } ;
 
 HELP: retainstack-underflow.
-{ $error-description "Thrown by the Factor VM if " { $link r> } " is called while the retain stack is empty." }
+{ $error-description "Thrown by the Factor VM if an attempt is made to access the retain stack in an invalid manner. This bug should never come up in practice and indicates a bug in Factor." }
 { $notes "You can use the stack effect tool to statically check stack effects of quotations. See " { $link "inference" } "." } ;
 
 HELP: retainstack-overflow.
-{ $error-description "Thrown by the Factor VM if " { $link >r } " is called when the retain stack is full." }
+{ $error-description "Thrown by the Factor VM if " { $link dip } " is called when the retain stack is full." }
 { $notes "This error usually indicates a run-away recursion, however if you legitimately need a retain stack larger than the default, see " { $link "runtime-cli-args" } "." } ;
 
 HELP: memory-error.
index 0e7a56ee5f471cdef17e0332e7fac74d70fed825..35b09713d3c7da0558e9db448e3f2bd24d87955a 100644 (file)
@@ -3,13 +3,13 @@
 USING: slots arrays definitions generic hashtables summary io
 kernel math namespaces make prettyprint prettyprint.config
 sequences assocs sequences.private strings io.styles io.files
-vectors words system splitting math.parser classes.tuple
-continuations continuations.private combinators generic.math
-classes.builtin classes compiler.units generic.standard vocabs
-init kernel.private io.encodings accessors math.order
-destructors source-files parser classes.tuple.parser
-effects.parser lexer compiler.errors generic.parser
-strings.parser ;
+vectors words system splitting math.parser classes.mixin
+classes.tuple continuations continuations.private combinators
+generic.math classes.builtin classes compiler.units
+generic.standard vocabs init kernel.private io.encodings
+accessors math.order destructors source-files parser
+classes.tuple.parser effects.parser lexer compiler.errors
+generic.parser strings.parser ;
 IN: debugger
 
 GENERIC: error. ( error -- )
@@ -72,12 +72,6 @@ M: string error. print ;
 : try ( quot -- )
     [ print-error-and-restarts ] recover ;
 
-M: relative-underflow summary
-    drop "Too many items removed from data stack" ;
-
-M: relative-overflow summary
-    drop "Superfluous items pushed to data stack" ;
-
 : expired-error. ( obj -- )
     "Object did not survive image save/load: " write third . ;
 
@@ -327,3 +321,5 @@ M: bad-effect summary
 M: bad-escape summary drop "Bad escape code" ;
 
 M: bad-literal-tuple summary drop "Bad literal tuple" ;
+
+M: check-mixin-class summary drop "Not a mixin class" ;
index 0d2f94c13de177daa4bed07f63c20eb45945fc35..5a2f4802e9bc85f4234d9e392dcfb2cd8dc4bb7f 100644 (file)
@@ -28,21 +28,21 @@ HELP: group-words
 { $values { "group" "a group" } { "words" "an array of words" } }
 { $description "Given a protocol or tuple class, this returns the corresponding generic words that this group contains." } ;
 
-ARTICLE: { "delegate" "intro" } "Delegation"
+ARTICLE: "delegate" "Delegation"
 "The " { $vocab-link "delegate" } " vocabulary implements run-time consultation for method dispatch."
 $nl
-"Fundamental to the concept of " { $emphasis "protocols" } ", which are groups of tuple slot accessors, or groups of arbtirary generic words."
+"A " { $emphasis "protocol" } " is a collection of related generic words. An object is said to " { $emphasis "consult" } " another object if it implements a protocol by forwarding all methods onto the other object."
 $nl
-"This allows an object to implement a certain protocol by passing the method calls to another object."
+"Using this vocabulary, protocols can be defined and consulation can be set up without any repetitive boilerplate."
 $nl
 "Unlike " { $link "tuple-subclassing" } ", which expresses " { $emphasis "is-a" } " relationships by statically including the methods and slots of the superclass in all subclasses, consultation forwards generic word calls to another distinct object."
 $nl
-"Fundamentally, a protocol is a word which has a method for " { $link group-words } ". One type of protocol is a tuple, which consists of the slot accessors. To define a protocol as a set of words, use"
+"Defining new protocols:"
 { $subsection POSTPONE: PROTOCOL: }
 { $subsection define-protocol }
-"The literal syntax and defining word are:"
+"Defining consultation:"
 { $subsection POSTPONE: CONSULT: }
 { $subsection define-consult }
-"The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
+"Every tuple class has an associated protocol consisting of all of its slot accessor methods. The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
 
-ABOUT: { "delegate" "intro" }
+ABOUT: "delegate"
index 12860337ffb9b2deef642ae652aa1c77fec058e7..e7ea370b8dc3335ebe7b5b67a1befed3cc434ceb 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors parser generic kernel classes classes.tuple
 words slots assocs sequences arrays vectors definitions
-prettyprint math hashtables sets macros namespaces make ;
+prettyprint math hashtables sets generalizations namespaces make ;
 IN: delegate
 
 : protocol-words ( protocol -- words )
@@ -25,15 +25,7 @@ M: tuple-class group-words
 
 : consult-method ( word class quot -- )
     [ drop swap first create-method ]
-    [
-        nip
-        [
-            over second saver %
-            %
-            dup second restorer %
-            first ,
-        ] [ ] make
-    ] 3bi
+    [ nip [ , dup second , \ ndip , first , ] [ ] make ] 3bi
     define ;
 
 : change-word-prop ( word prop quot -- )
@@ -44,7 +36,7 @@ M: tuple-class group-words
 
 : define-consult ( group class quot -- )
     [ register-protocol ]
-    [ rot group-words -rot [ consult-method ] 2curry each ]
+    [ [ group-words ] 2dip [ consult-method ] 2curry each ]
     3bi ;
 
 : CONSULT:
index 6df3e306ddb97345a7a5962ebce82aad427fc583..084aa0ac8951050ce75f2d90d309281babd66416 100644 (file)
@@ -75,3 +75,7 @@ IN: dlists.tests
     dup clone 3 over push-back
     [ dlist>seq ] bi@
 ] unit-test
+
+[ V{ f 3 1 f } ] [ <dlist> 1 over push-front 3 over push-front f over push-front f over push-back dlist>seq ] unit-test
+
+[ V{ } ] [ <dlist> dlist>seq ] unit-test
index 549dbf947de90910d631b9447ef0bdc1a67ac468..dcff476166ac47545274c5ce907fc4850057c3fc 100644 (file)
@@ -57,11 +57,11 @@ M: dlist-node node-value obj>> ;
 : (dlist-find-node) ( dlist-node quot: ( node -- ? ) -- node/f ? )
     over [
         [ call ] 2keep rot
-        [ drop t ] [ >r next>> r> (dlist-find-node) ] if
+        [ drop t ] [ [ next>> ] dip (dlist-find-node) ] if
     ] [ 2drop f f ] if ; inline recursive
 
 : dlist-find-node ( dlist quot -- node/f ? )
-    >r front>> r> (dlist-find-node) ; inline
+    [ front>> ] dip (dlist-find-node) ; inline
 
 : dlist-each-node ( dlist quot -- )
     [ f ] compose dlist-find-node 2drop ; inline
@@ -93,11 +93,11 @@ M: dlist peek-front ( dlist -- obj )
 
 M: dlist pop-front* ( dlist -- )
     [
-        dup front>> [ empty-dlist ] unless*
-        dup next>>
-        f rot (>>next)
-        f over set-prev-when
-        swap (>>front)
+        [
+            [ empty-dlist ] unless*
+            [ f ] change-next drop
+            f over set-prev-when
+        ] change-front drop
     ] keep
     normalize-back ;
 
@@ -106,11 +106,11 @@ M: dlist peek-back ( dlist -- obj )
 
 M: dlist pop-back* ( dlist -- )
     [
-        dup back>> [ empty-dlist ] unless*
-        dup prev>>
-        f rot (>>prev)
-        f over set-next-when
-        swap (>>back)
+        [
+            [ empty-dlist ] unless*
+            [ f ] change-prev drop
+            f over set-next-when
+        ] change-back drop
     ] keep
     normalize-front ;
 
@@ -154,7 +154,7 @@ M: dlist clear-deque ( dlist -- )
     [ obj>> ] prepose dlist-each-node ; inline
 
 : dlist>seq ( dlist -- seq )
-    [ ] pusher [ dlist-each ] dip ;
+    [ ] accumulator [ dlist-each ] dip ;
 
 : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 
index e09afebfc24fe8ac85ba2f7db2d1a6b29f166208..88e471cce1eca37b1b77de6a8a451b40dc2ba3e7 100644 (file)
@@ -1,8 +1,37 @@
 IN: documents.tests
-USING: documents namespaces tools.test ;
+USING: documents namespaces tools.test make arrays kernel fry ;
 
 ! Tests
 
+[ { } ] [
+    [
+        { 1 10 }
+        { 1 10 } [ , "HI" , ] each-line
+    ] { } make
+] unit-test
+
+[ { 1 "HI" } ] [
+    [
+        { 1 10 }
+        { 1 11 } [ , "HI" , ] each-line
+    ] { } make
+] unit-test
+
+[ { 1 "HI" 2 "HI" } ] [
+    [
+        { 1 10 }
+        { 2 11 } [ , "HI" , ] each-line
+    ] { } make
+] unit-test
+
+[ { { t f 1 } { t f 2 } } ] [
+    [
+        { 1 10 } { 2 11 }
+        t f
+        '[ [ _ _ ] dip 3array , ] each-line
+    ] { } make
+] unit-test
+
 [ { 10 4 } ] [ { "a" } { 10 3 } text+loc ] unit-test
 [ { 10 4 } ] [ { "a" } { 10 3 } text+loc ] unit-test
 
index a82437ba40bcec2767b1237ae7969a8ef51fe359..6993bcb65bf4ab0973d883f9406e850171ba5e78 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays io kernel math models namespaces make
 sequences strings splitting combinators unicode.categories
-math.order ;
+math.order math.ranges ;
 IN: documents
 
 : +col ( loc n -- newloc ) [ first2 ] dip + 2array ;
@@ -47,7 +47,7 @@ TUPLE: document < model locs ;
     2over = [
         3drop
     ] [
-        [ [ first ] bi@ 1+ dup <slice> ] dip each
+        [ [ first ] bi@ [a,b] ] dip each
     ] if ; inline
 
 : start/end-on-line ( from to line# -- n1 n2 )
index 7dfceafe59e3268ddcffec0c2e1139e2503e749a..6b49c939c38ba2723479e702309382332d0afe44 100644 (file)
@@ -26,8 +26,7 @@ SYMBOL: edit-hook
     require ;
 
 : edit-location ( file line -- )
-    >r (normalize-path) r>
-    edit-hook get-global
+    [ (normalize-path) ] dip edit-hook get-global
     [ call ] [ no-edit-hook edit-location ] if* ;
 
 : edit ( defspec -- )
@@ -64,10 +63,13 @@ M: object error-file
 M: object error-line
     drop f ;
 
-: :edit ( -- )
-    error get [ error-file ] [ error-line ] bi
+: (:edit) ( error -- )
+    [ error-file ] [ error-line ] bi
     2dup and [ edit-location ] [ 2drop ] if ;
 
+: :edit ( -- )
+    error get (:edit) ;
+
 : edit-each ( seq -- )
     [
         [ "Editing " write . ]
index 2ef1ced5ec7d37397199d808571e55a456a9382e..f55068e143d542c51b8afe7b8df60af48683b6a4 100644 (file)
@@ -1,13 +1,11 @@
 USING: help help.syntax help.markup ;
+IN: editors.emacs
 
-ARTICLE: { "emacs" "emacs" } "Integration with Emacs"
-
-"Put this in your .emacs file:"
-
+ARTICLE: "editors.emacs" "Integration with Emacs"
+"Put this in your " { $snippet ".emacs" } " file:"
 { $code "(server-start)" }
-
-"If you would like a new window to open when you ask Factor to edit an object, put this in your .emacs file:"
-
+"If you would like a new window to open when you ask Factor to edit an object, put this in your " { $snippet ".emacs" } " file:"
 { $code "(setq server-window 'switch-to-buffer-other-frame)" }
-
 { $see-also "editor" } ;
+
+ABOUT: "editors.emacs"
\ No newline at end of file
index aa5c5ef2a1e2f7fd5798dca1e975b057ca527280..10152f53d5d9bdfb8825cb6648b84edd1c43cc16 100644 (file)
@@ -14,7 +14,10 @@ IN: editors.scite
 
 : scite-path ( -- path )
     \ scite-path get-global [
-        program-files "wscite\\SciTE.exe" append-path
+        program-files "ScITE Source Code Editor\\SciTE.exe" append-path
+        dup exists? [
+            drop program-files "wscite\\SciTE.exe" append-path
+        ] unless
     ] unless* ;
 
 : scite-command ( file line -- cmd )
index 492925c7c0f86ebdce5bac74a5e251843ec30226..e60a52c995b94fb2613c4b272242ff1a88663a9c 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs combinators kernel sequences splitting system
-vocabs.loader ;
+vocabs.loader init ;
 IN: environment
 
 HOOK: os-env os ( key -- value )
@@ -18,10 +18,18 @@ HOOK: (set-os-envs) os ( seq -- )
     (os-envs) [ "=" split1 ] H{ } map>assoc ;
 
 : set-os-envs ( assoc -- )
-    [ "=" swap 3append ] { } assoc>map (set-os-envs) ;
+    [ "=" glue ] { } assoc>map (set-os-envs) ;
 
 {
     { [ os unix? ] [ "environment.unix" require ] }
     { [ os winnt? ] [ "environment.winnt" require ] }
     { [ os wince? ] [ ] }
 } cond
+
+[
+    "FACTOR_ROOTS" os-env
+    [
+        os windows? ";" ":" ? split
+        [ add-vocab-root ] each
+    ] when*    
+] "environment" add-init-hook
index 77a9038cd990aec6d3ec462d8d15a0ff4c5c73ac..284d5758a334b24fbc0c2cf4014e3110840fe2ae 100644 (file)
@@ -167,7 +167,7 @@ stand-alone
     } cond ;
 
 : escape-link ( href text -- href-esc text-esc )
-    >r check-url escape-quoted-string r> escape-string ;
+    [ check-url escape-quoted-string ] dip escape-string ;
 
 : write-link ( href text -- )
     escape-link
@@ -185,7 +185,7 @@ stand-alone
     ] if ;
 
 : render-code ( string mode -- string' )
-    >r string-lines r>
+    [ string-lines ] dip
     [
         <pre>
             htmlize-lines
diff --git a/basis/float-arrays/authors.txt b/basis/float-arrays/authors.txt
deleted file mode 100755 (executable)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/float-arrays/float-arrays-docs.factor b/basis/float-arrays/float-arrays-docs.factor
deleted file mode 100644 (file)
index 6c775db..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-USING: arrays bit-arrays vectors strings sbufs
-kernel help.markup help.syntax math ;
-IN: float-arrays
-
-ARTICLE: "float-arrays" "Float arrays"
-"Float arrays are fixed-size mutable sequences (" { $link "sequence-protocol" } ") whose elements are instances of " { $link float } ". Elements are unboxed, hence the memory usage is lower than an equivalent " { $link array } " of floats."
-$nl
-"Float array words are in the " { $vocab-link "float-arrays" } " vocabulary."
-$nl
-"Float arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-byte-arrays" } "."
-$nl
-"Float arrays form a class of objects."
-{ $subsection float-array }
-{ $subsection float-array? }
-"There are several ways to construct float arrays."
-{ $subsection >float-array }
-{ $subsection <float-array> }
-"Creating a float array from several elements on the stack:"
-{ $subsection 1float-array }
-{ $subsection 2float-array }
-{ $subsection 3float-array }
-{ $subsection 4float-array }
-"Float array literal syntax:"
-{ $subsection POSTPONE: F{ } ;
-
-ABOUT: "float-arrays"
-
-HELP: F{
-{ $syntax "F{ elements... }" }
-{ $values { "elements" "a list of real numbers" } }
-{ $description "Marks the beginning of a literal float array. Literal float arrays are terminated by " { $link POSTPONE: } } "." } 
-{ $examples { $code "F{ 1.0 2.0 3.0 }" } } ;
-
-HELP: float-array
-{ $description "The class of float arrays." } ;
-
-HELP: <float-array> ( n -- float-array )
-{ $values { "n" "a non-negative integer" } { "float-array" "a new float array" } }
-{ $description "Creates a new float array holding " { $snippet "n" } " floats with all elements initially set to " { $snippet "0.0" } "." } ;
-
-HELP: >float-array
-{ $values { "seq" "a sequence" } { "float-array" float-array } }
-{ $description "Outputs a freshly-allocated float array whose elements have the same floating-point values as a given sequence." }
-{ $errors "Throws an error if the sequence contains elements other than real numbers." } ;
-
-HELP: 1float-array
-{ $values { "x" object } { "array" float-array } }
-{ $description "Create a new float array with one element." } ;
-
-{ 1array 2array 3array 4array } related-words
-
-HELP: 2float-array
-{ $values { "x" object } { "y" object } { "array" float-array } }
-{ $description "Create a new float array with two elements, with " { $snippet "x" } " appearing first." } ;
-
-HELP: 3float-array
-{ $values { "x" object } { "y" object } { "z" object } { "array" float-array } }
-{ $description "Create a new float array with three elements, with " { $snippet "x" } " appearing first." } ;
-
-HELP: 4float-array
-{ $values { "w" object } { "x" object } { "y" object } { "z" object } { "array" float-array } }
-{ $description "Create a new float array with four elements, with " { $snippet "w" } " appearing first." } ;
diff --git a/basis/float-arrays/float-arrays-tests.factor b/basis/float-arrays/float-arrays-tests.factor
deleted file mode 100644 (file)
index 64070b9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-IN: float-arrays.tests
-USING: float-arrays tools.test sequences.private ;
-
-[ F{ 0.0 0.0 0.0 } ] [ 3 <float-array> ] unit-test
-
-[ F{ 1 2 3 0 0 0 } ] [ 6 F{ 1 2 3 } resize ] unit-test
-
-[ F{ 1 2 } ] [ 2 F{ 1 2 3 4 5 6 7 8 9 } resize ] unit-test
-
-[ -10 F{ } resize ] must-fail
-
-[ F{ 1.3 } ] [ 1.3 1float-array ] unit-test
diff --git a/basis/float-arrays/float-arrays.factor b/basis/float-arrays/float-arrays.factor
deleted file mode 100644 (file)
index ab3eef6..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel kernel.private alien.accessors sequences
-sequences.private math math.private byte-arrays accessors
-alien.c-types parser prettyprint.backend ;
-IN: float-arrays
-
-TUPLE: float-array
-{ length array-capacity read-only }
-{ underlying byte-array read-only } ;
-
-: <float-array> ( n -- float-array )
-    dup "double" <c-array> float-array boa ; inline
-
-M: float-array clone
-    [ length>> ] [ underlying>> clone ] bi float-array boa ;
-
-M: float-array length length>> ;
-
-M: float-array nth-unsafe
-    underlying>> double-nth ;
-
-M: float-array set-nth-unsafe
-    [ >float ] 2dip underlying>> set-double-nth ;
-
-: >float-array ( seq -- float-array )
-    T{ float-array } clone-like ; inline
-
-M: float-array like
-    drop dup float-array? [ >float-array ] unless ;
-
-M: float-array new-sequence
-    drop <float-array> ;
-
-M: float-array equal?
-    over float-array? [ sequence= ] [ 2drop f ] if ;
-
-M: float-array resize
-    [ drop ] [
-        [ "double" heap-size * ] [ underlying>> ] bi*
-        resize-byte-array
-    ] 2bi
-    float-array boa ;
-
-M: float-array byte-length length "double" heap-size * ;
-
-INSTANCE: float-array sequence
-
-: 1float-array ( x -- array )
-    1 <float-array> [ set-first ] keep ; inline
-
-: 2float-array ( x y -- array )
-    T{ float-array } 2sequence ; inline
-
-: 3float-array ( x y z -- array )
-    T{ float-array } 3sequence ; inline
-
-: 4float-array ( w x y z -- array )
-    T{ float-array } 4sequence ; inline
-
-: F{ \ } [ >float-array ] parse-literal ; parsing
-
-M: float-array pprint-delims drop \ F{ \ } ;
-M: float-array >pprint-sequence ;
-M: float-array pprint* pprint-object ;
-
-! Rice
-USING: hints math.vectors arrays ;
-
-HINTS: vneg { float-array } { array } ;
-HINTS: v*n { float-array float } { array object } ;
-HINTS: n*v { float float-array } { array object } ;
-HINTS: v/n { float-array float } { array object } ;
-HINTS: n/v { float float-array } { object array } ;
-HINTS: v+ { float-array float-array } { array array } ;
-HINTS: v- { float-array float-array } { array array } ;
-HINTS: v* { float-array float-array } { array array } ;
-HINTS: v/ { float-array float-array } { array array } ;
-HINTS: vmax { float-array float-array } { array array } ;
-HINTS: vmin { float-array float-array } { array array } ;
-HINTS: v. { float-array float-array } { array array } ;
-HINTS: norm-sq { float-array } { array } ;
-HINTS: norm { float-array } { array } ;
-HINTS: normalize { float-array } { array } ;
-
-! More rice. Experimental, currently causes a slowdown in raytracer
-! for some odd reason.
-
-USING: words classes.algebra compiler.tree.propagation.info ;
-
-{ v+ v- v* v/ vmax vmin } [
-    [
-        [ class>> float-array class<= ] both?
-        float-array object ? <class-info>
-    ] "outputs" set-word-prop
-] each
-
-{ n*v n/v } [
-    [
-        nip class>> float-array class<= float-array object ? <class-info>
-    ] "outputs" set-word-prop
-] each
-
-{ v*n v/n } [
-    [
-        drop class>> float-array class<= float-array object ? <class-info>
-    ] "outputs" set-word-prop
-] each
-
-{ vneg normalize } [
-    [
-        class>> float-array class<= float-array object ? <class-info>
-    ] "outputs" set-word-prop
-] each
-
-\ norm-sq [
-    class>> float-array class<= float object ? <class-info>
-] "outputs" set-word-prop
-
-\ v. [
-    [ class>> float-array class<= ] both?
-    float object ? <class-info>
-] "outputs" set-word-prop
diff --git a/basis/float-arrays/summary.txt b/basis/float-arrays/summary.txt
deleted file mode 100644 (file)
index 0eac3b0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Efficient fixed-length floating point number arrays
diff --git a/basis/float-arrays/tags.txt b/basis/float-arrays/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
diff --git a/basis/float-vectors/float-vectors-docs.factor b/basis/float-vectors/float-vectors-docs.factor
deleted file mode 100644 (file)
index 714c851..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-USING: arrays float-arrays help.markup help.syntax kernel\r
-combinators ;\r
-IN: float-vectors\r
-\r
-ARTICLE: "float-vectors" "Float vectors"\r
-"A float vector is a resizable mutable sequence of unsigned floats. Float vector words are found in the " { $vocab-link "float-vectors" } " vocabulary."\r
-$nl\r
-"Float vectors form a class:"\r
-{ $subsection float-vector }\r
-{ $subsection float-vector? }\r
-"Creating float vectors:"\r
-{ $subsection >float-vector }\r
-{ $subsection <float-vector> }\r
-"Literal syntax:"\r
-{ $subsection POSTPONE: FV{ }\r
-"If you don't care about initial capacity, a more elegant way to create a new float vector is to write:"\r
-{ $code "FV{ } clone" } ;\r
-\r
-ABOUT: "float-vectors"\r
-\r
-HELP: float-vector\r
-{ $description "The class of resizable float vectors. See " { $link "float-vectors" } " for information." } ;\r
-\r
-HELP: <float-vector>\r
-{ $values { "n" "a positive integer specifying initial capacity" } { "float-vector" float-vector } }\r
-{ $description "Creates a new float vector that can hold " { $snippet "n" } " floats before resizing." } ;\r
-\r
-HELP: >float-vector\r
-{ $values { "seq" "a sequence" } { "float-vector" float-vector } }\r
-{ $description "Outputs a freshly-allocated float vector with the same elements as a given sequence." }\r
-{ $errors "Throws an error if the sequence contains elements other than real numbers." } ;\r
-\r
-HELP: FV{\r
-{ $syntax "FV{ elements... }" }\r
-{ $values { "elements" "a list of real numbers" } }\r
-{ $description "Marks the beginning of a literal float vector. Literal float vectors are terminated by " { $link POSTPONE: } } "." } \r
-{ $examples { $code "FV{ 1.0 2.0 3.0 }" } } ;\r
diff --git a/basis/float-vectors/float-vectors-tests.factor b/basis/float-vectors/float-vectors-tests.factor
deleted file mode 100644 (file)
index 1483b26..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-USING: tools.test float-vectors vectors sequences kernel math ;\r
-IN: float-vectors.tests\r
-\r
-[ 0 ] [ 123 <float-vector> length ] unit-test\r
-\r
-: do-it\r
-    12345 [ >float over push ] each ;\r
-\r
-[ t ] [\r
-    3 <float-vector> do-it\r
-    3 <vector> do-it sequence=\r
-] unit-test\r
-\r
-[ t ] [ FV{ } float-vector? ] unit-test\r
diff --git a/basis/float-vectors/float-vectors.factor b/basis/float-vectors/float-vectors.factor
deleted file mode 100644 (file)
index 8e93582..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: arrays kernel kernel.private math sequences\r
-sequences.private growable float-arrays prettyprint.backend\r
-parser accessors ;\r
-IN: float-vectors\r
-\r
-TUPLE: float-vector\r
-{ underlying float-array initial: F{ } }\r
-{ length array-capacity } ;\r
-\r
-: <float-vector> ( n -- float-vector )\r
-    <float-array> 0 float-vector boa ; inline\r
-\r
-: >float-vector ( seq -- float-vector )\r
-    T{ float-vector f F{ } 0 } clone-like ;\r
-\r
-M: float-vector like\r
-    drop dup float-vector? [\r
-        dup float-array?\r
-        [ dup length float-vector boa ] [ >float-vector ] if\r
-    ] unless ;\r
-\r
-M: float-vector new-sequence\r
-    drop [ <float-array> ] [ >fixnum ] bi float-vector boa ;\r
-\r
-M: float-vector equal?\r
-    over float-vector? [ sequence= ] [ 2drop f ] if ;\r
-\r
-M: float-array new-resizable drop <float-vector> ;\r
-\r
-INSTANCE: float-vector growable\r
-\r
-: FV{ \ } [ >float-vector ] parse-literal ; parsing\r
-\r
-M: float-vector >pprint-sequence ;\r
-M: float-vector pprint-delims drop \ FV{ \ } ;\r
-M: float-vector pprint* pprint-object ;\r
diff --git a/basis/float-vectors/summary.txt b/basis/float-vectors/summary.txt
deleted file mode 100644 (file)
index c476f41..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Growable float arrays
diff --git a/basis/float-vectors/tags.txt b/basis/float-vectors/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
index b5d1b8d8d21708fcdfd8c91d6d15d6c82e44b1a2..1dff0942bd301327bbb077ef6cf1d90bf5e37401 100644 (file)
@@ -46,10 +46,10 @@ $nl
     "{ 10 20 30 } [ sq ] [ . ] compose each"\r
     "{ 10 20 30 } [ sq . ] each"\r
 }\r
-"The " { $link _ } " and " { $link @ } " specifiers may be freely mixed:"\r
+"The " { $link _ } " and " { $link @ } " specifiers may be freely mixed, and the result is considerably more concise and readable than the version using " { $link curry } " and " { $link compose } " directly:"\r
 { $code\r
     "{ 8 13 14 27 } [ even? ] 5 '[ @ dup _ ? ] map"\r
-    "{ 8 13 14 27 } [ even? ] 5 [ dup ] swap [ ? ] curry 3compose map"\r
+    "{ 8 13 14 27 } [ even? ] 5 [ dup ] swap [ ? ] curry compose compose map"\r
     "{ 8 13 14 27 } [ even? dup 5 ? ] map"\r
 }\r
 "The following is a no-op:"\r
@@ -75,12 +75,6 @@ ARTICLE: "fry.philosophy" "Fried quotation philosophy"
     "[let | a [ ] b [ ] | [ 3 a + 4 b / ] ]"\r
 } ;\r
 \r
-ARTICLE: "fry.limitations" "Fried quotation limitations"\r
-"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead."\r
-$nl\r
-"An error thrown if a fried quotation contains calls to " { $link >r } " and " { $link r> } ":"\r
-{ $subsection >r/r>-in-fry-error } ;\r
-\r
 ARTICLE: "fry" "Fried quotations"\r
 "The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with ``holes'' (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack."\r
 $nl\r
@@ -92,7 +86,6 @@ $nl
 "The holes are filled in with the top of stack going in the rightmost hole, the second item on the stack going in the second hole from the right, and so on."\r
 { $subsection "fry.examples" }\r
 { $subsection "fry.philosophy" }\r
-{ $subsection "fry.limitations" }\r
 "Fry is implemented as a parsing word which reads a quotation and scans for occurrences of " { $link _ } " and " { $link @ } "; these words are not actually executed, and doing so raises an error (this can happen if they're accidentally used outside of a fry)."\r
 $nl\r
 "Fried quotations can also be constructed without using a parsing word; this is useful when meta-programming:"\r
index ac036f58ad261ad45cc5b5979d3f3c3d994e73d1..f84ad233cd8b5c1b9420e3efb0eb950b3d209fe8 100644 (file)
@@ -28,11 +28,6 @@ M: >r/r>-in-fry-error summary
     dup { >r r> load-locals get-local drop-locals } intersect
     empty? [ >r/r>-in-fry-error ] unless ;
 
-: shallow-fry ( quot -- quot' )
-    check-fry
-    [ dup \ @ = [ drop [ _ call ] ] [ 1array ] if ] map concat
-    { _ } split [ length 1- [ncurry] ] [ spread>quot ] bi prefix ;
-
 PREDICATE: fry-specifier < word { _ @ } memq? ;
 
 GENERIC: count-inputs ( quot -- n )
@@ -41,15 +36,21 @@ M: callable count-inputs [ count-inputs ] sigma ;
 M: fry-specifier count-inputs drop 1 ;
 M: object count-inputs drop 0 ;
 
+GENERIC: deep-fry ( obj -- )
+
+: shallow-fry ( quot -- quot' curry# )
+    check-fry
+    [ [ deep-fry ] each ] [ ] make
+    [ dup \ @ = [ drop [ _ call ] ] [ 1array ] if ] map concat
+    { _ } split [ spread>quot ] [ length 1- ] bi ;
+
 PRIVATE>
 
-: fry ( quot -- quot' )
-    [
-        [
-            dup callable? [
-                [ count-inputs \ _ <repetition> % ] [ fry % ] bi
-            ] [ , ] if
-        ] each
-    ] [ ] make shallow-fry ;
+: fry ( quot -- quot' ) shallow-fry [ncurry] swap prefix ;
+
+M: callable deep-fry
+    [ count-inputs \ _ <repetition> % ] [ fry % ] bi ;
+
+M: object deep-fry , ;
 
 : '[ \ ] parse-until fry over push-all ; parsing
diff --git a/basis/ftp/client/authors.txt b/basis/ftp/client/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/ftp/client/client.factor b/basis/ftp/client/client.factor
new file mode 100644 (file)
index 0000000..9c82cdb
--- /dev/null
@@ -0,0 +1,110 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays classes.singleton combinators
+continuations io io.encodings.binary io.encodings.utf8
+io.files io.sockets kernel io.streams.duplex math
+math.parser sequences splitting namespaces strings fry ftp
+ftp.client.listing-parser urls ;
+IN: ftp.client
+
+: (ftp-response-code) ( str -- n )
+    3 head string>number ;
+
+: ftp-response-code ( string -- n/f )
+    dup fourth CHAR: - = [ drop f ] [ (ftp-response-code) ] if ;
+
+: read-response-loop ( ftp-response -- ftp-response )
+    readln
+    [ add-response-line ] [ ftp-response-code ] bi
+    over n>> = [ read-response-loop ] unless ;
+
+: read-response ( -- ftp-response )
+    <ftp-response> readln
+    [ (ftp-response-code) >>n ]
+    [ add-response-line ]
+    [ fourth CHAR: - = ] tri
+    [ read-response-loop ] when ;
+
+ERROR: ftp-error got expected ;
+
+: ftp-assert ( ftp-response n -- )
+    2dup [ n>> ] dip = [ 2drop ] [ ftp-error ] if ;
+
+: ftp-command ( string -- ftp-response )
+    ftp-send read-response ;
+
+: ftp-user ( url -- ftp-response )
+    username>> "USER " prepend ftp-command ;
+
+: ftp-password ( url -- ftp-response )
+    password>> "PASS " prepend ftp-command ;
+
+: ftp-cwd ( directory -- ftp-response )
+    "CWD " prepend ftp-command ;
+
+: ftp-retr ( filename -- ftp-response )
+    "RETR " prepend ftp-command ;
+
+: ftp-set-binary ( -- ftp-response ) "TYPE I" ftp-command ;
+
+: ftp-pwd ( -- ftp-response ) "PWD" ftp-command ;
+
+: ftp-list ( -- )
+    "LIST" ftp-command 150 ftp-assert ;
+
+: ftp-quit ( -- ftp-response ) "QUIT" ftp-command ;
+
+: ftp-epsv ( -- ftp-response )
+    "EPSV" ftp-command dup 229 ftp-assert ;
+
+: parse-epsv ( ftp-response -- port )
+    strings>> first "|" split 2 tail* first string>number ;
+
+: open-passive-client ( url protocol -- stream )
+    [ host>> ftp-epsv parse-epsv <inet> ] dip <client> drop ;
+
+: list ( url -- ftp-response )
+    utf8 open-passive-client
+    ftp-list
+    lines
+    <ftp-response> swap >>strings
+    read-response 226 ftp-assert
+    parse-list ;
+
+: (ftp-get) ( url path -- )
+    [ binary open-passive-client ] dip
+    [ ftp-retr 150 ftp-assert drop ]
+    [ binary <file-writer> stream-copy ] 2bi
+    read-response 226 ftp-assert ;
+
+: ftp-login ( url -- )
+    read-response 220 ftp-assert
+    [ ftp-user 331 ftp-assert ]
+    [ ftp-password 230 ftp-assert ] bi
+    ftp-set-binary 200 ftp-assert ;
+
+: ftp-connect ( url -- stream )
+    [ host>> ] [ port>> ] bi <inet> utf8 <client> drop ;
+
+: with-ftp-client ( url quot -- )
+    [ [ ftp-connect ] keep ] dip
+    '[ _ [ ftp-login ] _ bi ftp-quit drop ] with-stream ; inline
+
+: ensure-login ( url -- url )
+    dup username>> [
+        "anonymous" >>username
+        "ftp-client" >>password
+    ] unless ;
+
+: >ftp-url ( url -- url' ) >url ensure-port ensure-login ;
+
+: ftp-get ( url -- )
+    >ftp-url [
+        dup path>>
+        [ nip parent-directory ftp-cwd drop ]
+        [ file-name (ftp-get) ] 2bi
+    ] with-ftp-client ;
+
+
+
+
diff --git a/basis/ftp/client/listing-parser/authors.txt b/basis/ftp/client/listing-parser/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/ftp/client/listing-parser/listing-parser.factor b/basis/ftp/client/listing-parser/listing-parser.factor
new file mode 100644 (file)
index 0000000..04e96ed
--- /dev/null
@@ -0,0 +1,89 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators io.files kernel math.parser
+sequences splitting ;
+IN: ftp.client.listing-parser
+
+: ch>file-type ( ch -- type )
+    {
+        { CHAR: b [ +block-device+ ] }
+        { CHAR: c [ +character-device+ ] }
+        { CHAR: d [ +directory+ ] }
+        { CHAR: l [ +symbolic-link+ ] }
+        { CHAR: s [ +socket+ ] }
+        { CHAR: p [ +fifo+ ] }
+        { CHAR: - [ +regular-file+ ] }
+        [ drop +unknown+ ]
+    } case ;
+
+: file-type>ch ( type -- string )
+    {
+        { +block-device+ [ CHAR: b ] }
+        { +character-device+ [ CHAR: c ] }
+        { +directory+ [ CHAR: d ] }
+        { +symbolic-link+ [ CHAR: l ] }
+        { +socket+ [ CHAR: s ] }
+        { +fifo+ [ CHAR: p ] }
+        { +regular-file+ [ CHAR: - ] }
+        [ drop CHAR: - ]
+    } case ;
+
+: parse-permissions ( remote-file str -- remote-file )
+    [ first ch>file-type >>type ] [ rest >>permissions ] bi ;
+
+TUPLE: remote-file
+type permissions links owner group size month day time year
+name target ;
+
+: <remote-file> ( -- remote-file ) remote-file new ;
+
+: parse-list-11 ( lines -- seq )
+    [
+        11 f pad-right
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>owner ]
+            [ 3 swap nth >>group ]
+            [ 4 swap nth string>number >>size ]
+            [ 5 swap nth >>month ]
+            [ 6 swap nth >>day ]
+            [ 7 swap nth >>time ]
+            [ 8 swap nth >>name ]
+            [ 10 swap nth >>target ]
+        } cleave
+    ] map ;
+
+: parse-list-8 ( lines -- seq )
+    [
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>owner ]
+            [ 3 swap nth >>size ]
+            [ 4 swap nth >>month ]
+            [ 5 swap nth >>day ]
+            [ 6 swap nth >>time ]
+            [ 7 swap nth >>name ]
+        } cleave
+    ] map ;
+
+: parse-list-3 ( lines -- seq )
+    [
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>name ]
+        } cleave
+    ] map ;
+
+: parse-list ( ftp-response -- ftp-response )
+    dup strings>>
+    [ " " split harvest ] map
+    dup length {
+        { 11 [ parse-list-11 ] }
+        { 9 [ parse-list-11 ] }
+        { 8 [ parse-list-8 ] }
+        { 3 [ parse-list-3 ] }
+        [ drop ]
+    } case >>parsed ;
diff --git a/basis/ftp/client/tags.txt b/basis/ftp/client/tags.txt
new file mode 100644 (file)
index 0000000..992ae12
--- /dev/null
@@ -0,0 +1 @@
+network
diff --git a/basis/ftp/ftp.factor b/basis/ftp/ftp.factor
new file mode 100644 (file)
index 0000000..adf7d5b
--- /dev/null
@@ -0,0 +1,21 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs combinators io io.files kernel
+math.parser sequences strings ;
+IN: ftp
+
+SINGLETON: active
+SINGLETON: passive
+
+TUPLE: ftp-response n strings parsed ;
+
+: <ftp-response> ( -- ftp-response )
+    ftp-response new
+        V{ } clone >>strings ;
+
+: add-response-line ( ftp-response string -- ftp-response )
+    over strings>> push ;
+
+: ftp-send ( string -- ) write "\r\n" write flush ;
+: ftp-ipv4 1 ; inline
+: ftp-ipv6 2 ; inline
diff --git a/basis/ftp/server/server.factor b/basis/ftp/server/server.factor
new file mode 100644 (file)
index 0000000..b0ec340
--- /dev/null
@@ -0,0 +1,353 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators.short-circuit accessors combinators io
+io.encodings.8-bit io.encodings io.encodings.binary
+io.encodings.utf8 io.files io.sockets kernel math.parser
+namespaces make sequences ftp io.unix.launcher.parser
+unicode.case splitting assocs classes io.servers.connection
+destructors calendar io.timeouts io.streams.duplex threads
+continuations math concurrency.promises byte-arrays
+io.backend tools.hexdump tools.files io.streams.string ;
+IN: ftp.server
+
+TUPLE: ftp-client url mode state command-promise user password ;
+
+: <ftp-client> ( url -- ftp-client )
+    ftp-client new
+        swap >>url ;
+    
+SYMBOL: client
+
+: ftp-server-directory ( -- str )
+    \ ftp-server-directory get-global "resource:temp" or
+    normalize-path ;
+
+TUPLE: ftp-command raw tokenized ;
+
+: <ftp-command> ( -- obj )
+    ftp-command new ;
+
+TUPLE: ftp-get path ;
+
+: <ftp-get> ( path -- obj )
+    ftp-get new
+        swap >>path ;
+
+TUPLE: ftp-put path ;
+
+: <ftp-put> ( path -- obj )
+    ftp-put new
+        swap >>path ;
+
+TUPLE: ftp-list ;
+
+C: <ftp-list> ftp-list
+
+: read-command ( -- ftp-command )
+    <ftp-command> readln
+    [ >>raw ] [ tokenize-command >>tokenized ] bi ;
+
+: (send-response) ( n string separator -- )
+    rot number>string write write ftp-send ;
+
+: send-response ( ftp-response -- )
+    [ n>> ] [ strings>> ] bi
+    [ but-last-slice [ "-" (send-response) ] with each ]
+    [ first " " (send-response) ] 2bi ;
+
+: server-response ( n string -- )
+    <ftp-response>
+        swap add-response-line
+        swap >>n
+    send-response ;
+
+: ftp-error ( string -- )
+    500 "Unrecognized command: " rot append server-response ;
+
+: send-banner ( -- )
+    220 "Welcome to " host-name append server-response ;
+
+: anonymous-only ( -- )
+    530 "This FTP server is anonymous only." server-response ;
+
+: handle-QUIT ( obj -- )
+    drop 221 "Goodbye." server-response ;
+
+: handle-USER ( ftp-command -- )
+    [
+        tokenized>> second client get (>>user)
+        331 "Please specify the password." server-response
+    ] [
+        2drop "bad USER" ftp-error
+    ] recover ;
+
+: handle-PASS ( ftp-command -- )
+    [
+        tokenized>> second client get (>>password)
+        230 "Login successful" server-response
+    ] [
+        2drop "PASS error" ftp-error
+    ] recover ;
+
+ERROR: type-error type ;
+
+: parse-type ( string -- string' )
+    >upper {
+        { "IMAGE" [ "Binary" ] }
+        { "I" [ "Binary" ] }
+        [ type-error ]
+    } case ;
+
+: handle-TYPE ( obj -- )
+    [
+        tokenized>> second parse-type
+        200 "Switching to " rot " mode" 3append server-response
+    ] [
+        2drop "TYPE is binary only" ftp-error
+    ] recover ;
+
+: random-local-server ( -- server )
+    remote-address get class new 0 >>port binary <server> ;
+
+: port>bytes ( port -- hi lo )
+    [ -8 shift ] keep [ HEX: ff bitand ] bi@ ;
+
+: handle-PWD ( obj -- )
+    drop
+    257 current-directory get "\"" "\"" surround server-response ;
+
+: handle-SYST ( obj -- )
+    drop
+    215 "UNIX Type: L8" server-response ;
+
+: if-command-promise ( quot -- )
+    [ client get command-promise>> ] dip
+    [ "Establish an active or passive connection first" ftp-error ] if* ;
+
+: handle-STOR ( obj -- )
+    [
+        tokenized>> second
+        [ [ <ftp-put> ] dip fulfill ] if-command-promise
+    ] [
+        2drop
+    ] recover ;
+
+! EPRT |2|::1|62138|
+! : handle-EPRT ( obj -- )
+    ! tokenized>> second "|" split harvest ;
+
+: start-directory ( -- )
+    150 "Here comes the directory listing." server-response ;
+
+: finish-directory ( -- )
+    226 "Directory send OK." server-response ;
+
+GENERIC: service-command ( stream obj -- )
+
+M: ftp-list service-command ( stream obj -- )
+    drop
+    start-directory [
+        utf8 encode-output
+        [ current-directory get directory. ] with-string-writer string-lines
+        harvest [ ftp-send ] each
+    ] with-output-stream
+    finish-directory ;
+
+: transfer-outgoing-file ( path -- )
+    150 "Opening BINARY mode data connection for "
+    rot   
+    [ file-name ] [
+        " " swap  file-info size>> number>string
+        "(" " bytes)." surround append
+    ] bi 3append server-response ;
+
+: transfer-incoming-file ( path -- )
+    150 "Opening BINARY mode data connection for " rot append
+    server-response ;
+
+: finish-file-transfer ( -- )
+    226 "File send OK." server-response ;
+
+M: ftp-get service-command ( stream obj -- )
+    [
+        path>>
+        [ transfer-outgoing-file ]
+        [ binary <file-reader> swap stream-copy ] bi
+        finish-file-transfer
+    ] [
+        3drop "File transfer failed" ftp-error
+    ] recover ;
+
+M: ftp-put service-command ( stream obj -- )
+    [
+        path>>
+        [ transfer-incoming-file ]
+        [ binary <file-writer> stream-copy ] bi
+        finish-file-transfer
+    ] [
+        3drop "File transfer failed" ftp-error
+    ] recover ;
+
+: passive-loop ( server -- )
+    [
+        [
+            |dispose
+            30 seconds over set-timeout
+            accept drop &dispose
+            client get command-promise>>
+            30 seconds ?promise-timeout
+            service-command
+        ]
+        [ client get f >>command-promise drop ]
+        [ drop ] cleanup
+    ] with-destructors ;
+
+: handle-LIST ( obj -- )
+    drop
+    [ [ <ftp-list> ] dip fulfill ] if-command-promise ;
+
+: handle-SIZE ( obj -- )
+    [
+        tokenized>> second file-info size>>
+        213 swap number>string server-response
+    ] [
+        2drop
+        550 "Could not get file size" server-response
+    ] recover ;
+
+: handle-RETR ( obj -- )
+    [ tokenized>> second <ftp-get> swap fulfill ]
+    curry if-command-promise ;
+
+: expect-connection ( -- port )
+    random-local-server
+    client get <promise> >>command-promise drop
+    [ [ passive-loop ] curry in-thread ]
+    [ addr>> port>> ] bi ;
+
+: handle-PASV ( obj -- )
+    drop client get passive >>mode drop
+    expect-connection
+    [
+        "Entering Passive Mode (127,0,0,1," %
+        port>bytes [ number>string ] bi@ "," glue %
+        ")" %
+    ] "" make 227 swap server-response ;
+
+: handle-EPSV ( obj -- )
+    drop
+    client get command-promise>> [
+        "You already have a passive stream" ftp-error
+    ] [
+        229 "Entering Extended Passive Mode (|||"
+        expect-connection number>string
+        "|)" 3append server-response
+    ] if ;
+
+! LPRT 6,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,242,186
+! : handle-LPRT ( obj -- ) tokenized>> "," split ;
+
+ERROR: not-a-directory ;
+ERROR: no-permissions ;
+
+: handle-CWD ( obj -- )
+    [
+        tokenized>> second dup normalize-path
+        dup ftp-server-directory head? [
+            no-permissions
+        ] unless
+
+        file-info directory? [
+            set-current-directory
+            250 "Directory successully changed." server-response
+        ] [
+            not-a-directory
+        ] if
+    ] [
+        2drop
+        550 "Failed to change directory." server-response
+    ] recover ;
+
+: unrecognized-command ( obj -- ) raw>> ftp-error ;
+
+: handle-client-loop ( -- )
+    <ftp-command> readln
+    USE: prettyprint    global [ dup . flush ] bind
+    [ >>raw ]
+    [ tokenize-command >>tokenized ] bi
+    dup tokenized>> first >upper {
+        { "USER" [ handle-USER t ] }
+        { "PASS" [ handle-PASS t ] }
+        { "ACCT" [ drop "ACCT unimplemented" ftp-error t ] }
+        { "CWD" [ handle-CWD t ] }
+        ! { "XCWD" [ ] }
+        ! { "CDUP" [ ] }
+        ! { "SMNT" [ ] }
+
+        ! { "REIN" [ drop client get reset-ftp-client t ] }
+        { "QUIT" [ handle-QUIT f ] }
+
+        ! { "PORT" [  ] } ! TODO
+        { "PASV" [ handle-PASV t ] }
+        ! { "MODE" [ ] }
+        { "TYPE" [ handle-TYPE t ] }
+        ! { "STRU" [ ] }
+
+        ! { "ALLO" [ ] }
+        ! { "REST" [ ] }
+        { "STOR" [ handle-STOR t ] }
+        ! { "STOU" [ ] }
+        { "RETR" [ handle-RETR t ] }
+        { "LIST" [ handle-LIST t ] }
+        { "SIZE" [ handle-SIZE t ] }
+        ! { "NLST" [ ] }
+        ! { "APPE" [ ] }
+        ! { "RNFR" [ ] }
+        ! { "RNTO" [ ] }
+        ! { "DELE" [ handle-DELE t ] }
+        ! { "RMD" [ handle-RMD t ] }
+        ! ! { "XRMD" [ handle-XRMD t ] }
+        ! { "MKD" [ handle-MKD t ] }
+        { "PWD" [ handle-PWD t ] }
+        ! { "ABOR" [ ] }
+
+        { "SYST" [ handle-SYST t ] }
+        ! { "STAT" [ ] }
+        ! { "HELP" [ ] }
+
+        ! { "SITE" [ ] }
+        ! { "NOOP" [ ] }
+
+        ! { "EPRT" [ handle-EPRT ] }
+        ! { "LPRT" [ handle-LPRT ] }
+        { "EPSV" [ handle-EPSV t ] }
+        ! { "LPSV" [ drop handle-LPSV t ] }
+        [ drop unrecognized-command t ]
+    } case [ handle-client-loop ] when ;
+
+TUPLE: ftp-server < threaded-server ;
+
+M: ftp-server handle-client* ( server -- )
+    drop
+    [
+        ftp-server-directory [
+            host-name <ftp-client> client set
+            send-banner handle-client-loop
+        ] with-directory
+    ] with-destructors ;
+
+: <ftp-server> ( port -- server )
+    ftp-server new-threaded-server
+        swap >>insecure
+        "ftp.server" >>name
+        5 minutes >>timeout
+        latin1 >>encoding ;
+
+: ftpd ( port -- )
+    <ftp-server> start-server ;
+
+: ftpd-main ( -- ) 2100 ftpd ;
+
+MAIN: ftpd-main
+
+! sudo tcpdump -i en1 -A -s 10000  tcp port 21
diff --git a/basis/ftp/server/tags.txt b/basis/ftp/server/tags.txt
new file mode 100644 (file)
index 0000000..992ae12
--- /dev/null
@@ -0,0 +1 @@
+network
diff --git a/basis/ftp/tags.txt b/basis/ftp/tags.txt
new file mode 100644 (file)
index 0000000..992ae12
--- /dev/null
@@ -0,0 +1 @@
+network
diff --git a/basis/functors/authors.txt b/basis/functors/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/functors/functors-tests.factor b/basis/functors/functors-tests.factor
new file mode 100644 (file)
index 0000000..39923af
--- /dev/null
@@ -0,0 +1,47 @@
+IN: functors.tests
+USING: functors tools.test math words kernel ;
+
+<<
+
+FUNCTOR: define-box ( T -- )
+
+B DEFINES ${T}-box
+<B> DEFINES <${B}>
+
+WHERE
+
+TUPLE: B { value T } ;
+
+C: <B> B
+
+;FUNCTOR
+
+\ float define-box
+
+>>
+
+{ 1 0 } [ define-box ] must-infer-as
+
+[ T{ float-box f 5.0 } ] [ 5.0 <float-box> ] unit-test
+
+: twice ( word -- )
+    [ execute ] [ execute ] bi ; inline
+<<
+
+FUNCTOR: wrapper-test ( W -- )
+
+WW DEFINES ${W}${W}
+
+WHERE
+
+: WW W twice ; inline
+
+;FUNCTOR
+
+\ sq wrapper-test
+
+>>
+
+\ sqsq must-infer
+
+[ 16 ] [ 2 sqsq ] unit-test
diff --git a/basis/functors/functors.factor b/basis/functors/functors.factor
new file mode 100644 (file)
index 0000000..7126806
--- /dev/null
@@ -0,0 +1,106 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel locals.private quotations classes.tuple make
+combinators generic words interpolate namespaces sequences
+io.streams.string fry classes.mixin effects lexer parser
+classes.tuple.parser effects.parser ;
+IN: functors
+
+: scan-param ( -- obj )
+    scan-object dup special? [ literalize ] unless ;
+
+: define* ( word def effect -- ) pick set-word define-declared ;
+
+: DEFINE* ( accum -- accum ) effect get parsed \ define* parsed ;
+
+: `TUPLE:
+    scan-param parsed
+    scan {
+        { ";" [ tuple parsed f parsed ] }
+        { "<" [ scan-param parsed [ parse-tuple-slots ] { } make parsed ] }
+        [
+            [ tuple parsed ] dip
+            [ parse-slot-name [ parse-tuple-slots ] when ] { }
+            make parsed
+        ]
+    } case
+    \ define-tuple-class parsed ; parsing
+
+: `M:
+    effect off
+    scan-param parsed
+    scan-param parsed
+    \ create-method parsed
+    parse-definition parsed
+    DEFINE* ; parsing
+
+: `C:
+    effect off
+    scan-param parsed
+    scan-param parsed
+    [ [ boa ] curry ] over push-all
+    DEFINE* ; parsing
+
+: `:
+    effect off
+    scan-param parsed
+    parse-definition parsed
+    DEFINE* ; parsing
+
+: `INSTANCE:
+    scan-param parsed
+    scan-param parsed
+    \ add-mixin-instance parsed ; parsing
+
+: `inline \ inline parsed ; parsing
+
+: `parsing \ parsing parsed ; parsing
+
+: `(
+    ")" parse-effect effect set ; parsing
+
+: (INTERPOLATE) ( accum quot -- accum )
+    [ scan interpolate-locals ] dip
+    '[ _ with-string-writer @ ] parsed ;
+
+: IS [ dup search [ ] [ no-word ] ?if ] (INTERPOLATE) ; parsing
+
+: DEFINES [ create-in ] (INTERPOLATE) ; parsing
+
+DEFER: ;FUNCTOR delimiter
+
+: functor-words ( -- assoc )
+    H{
+        { "TUPLE:" POSTPONE: `TUPLE: }
+        { "M:" POSTPONE: `M: }
+        { "C:" POSTPONE: `C: }
+        { ":" POSTPONE: `: }
+        { "INSTANCE:" POSTPONE: `INSTANCE: }
+        { "inline" POSTPONE: `inline }
+        { "parsing" POSTPONE: `parsing }
+        { "(" POSTPONE: `( }
+    } ;
+
+: push-functor-words ( -- )
+    functor-words use get push ;
+
+: pop-functor-words ( -- )
+    functor-words use get delq ;
+
+: parse-functor-body ( -- form )
+    t in-lambda? [
+        V{ } clone
+        push-functor-words
+        "WHERE" parse-bindings* \ ;FUNCTOR (parse-lambda)
+        <let*> parsed-lambda
+        pop-functor-words
+        >quotation
+    ] with-variable ;
+
+: (FUNCTOR:) ( -- word def )
+    CREATE
+    parse-locals
+    parse-functor-body swap pop-locals <lambda>
+    lambda-rewrite first ;
+
+: FUNCTOR: (FUNCTOR:) define ; parsing
diff --git a/basis/functors/summary.txt b/basis/functors/summary.txt
new file mode 100644 (file)
index 0000000..d95b366
--- /dev/null
@@ -0,0 +1 @@
+First-class syntax
diff --git a/basis/functors/tags.txt b/basis/functors/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 6c56a8ad7babe82ad3d98a762c6ab59381e352eb..72a7b76d23b086188e99d14fcd09cc3892dee05e 100644 (file)
@@ -6,7 +6,7 @@ io arrays math boxes splitting urls
 xml.entities\r
 http.server\r
 http.server.responses\r
-furnace\r
+furnace.utilities\r
 furnace.redirection\r
 furnace.conversations\r
 html.forms\r
index 6d4196cf0b73ae928186aa7f2ff15bf1cdee46cf..7489d19f944e52d33e537873ec396036ef54665f 100644 (file)
@@ -4,9 +4,9 @@ USING: namespaces assocs kernel sequences accessors hashtables
 urls db.types db.tuples math.parser fry logging combinators
 html.templates.chloe.syntax
 http http.server http.server.filters http.server.redirection
-furnace
 furnace.cache
 furnace.sessions
+furnace.utilities
 furnace.redirection ;
 IN: furnace.asides
 
index 1b5c5f9e73b940a83aa629d64e0c45349144425b..b9c961941c94b808395bb74f47c9fdd718805f0b 100644 (file)
@@ -8,8 +8,8 @@ html.forms
 http.server\r
 http.server.filters\r
 http.server.dispatchers\r
-furnace\r
 furnace.actions\r
+furnace.utilities\r
 furnace.redirection\r
 furnace.boilerplate\r
 furnace.auth.providers\r
index 5885aaef616d238def6106072dbd3b7cd94d6887..77be30a2d184d6c39bfb0be0adef97c5bb3cd107 100644 (file)
@@ -1,11 +1,10 @@
 ! Copyright (c) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces make accessors kernel assocs arrays io.sockets
-threads fry urls smtp validators html.forms present
-http http.server.responses http.server.redirection
-http.server.dispatchers
-furnace furnace.actions furnace.auth furnace.auth.providers
-furnace.redirection ;
+threads fry urls smtp validators html.forms present http
+http.server.responses http.server.redirection
+http.server.dispatchers furnace.actions furnace.auth
+furnace.auth.providers furnace.redirection furnace.utilities ;
 IN: furnace.auth.features.recover-password
 
 SYMBOL: lost-password-from
index 0484c11727dd4e47f5a6773240da7bdd20adf3d8..7f73f0c4045370bde1bc16e10ccfd4eb5f23e928 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs kernel namespaces validators html.forms urls
 http.server.dispatchers
-furnace furnace.auth furnace.auth.providers furnace.actions
+furnace.auth furnace.auth.providers furnace.actions
 furnace.redirection ;
 IN: furnace.auth.features.registration
 
index 4fc4e7e8be517783d15b8365d43df58a4b5946c3..fff301eb2f76379fbcd08bec032daf7ef21fd53f 100644 (file)
@@ -3,7 +3,6 @@
 USING: kernel accessors namespaces sequences math.parser\r
 calendar validators urls logging html.forms\r
 http http.server http.server.dispatchers\r
-furnace\r
 furnace.auth\r
 furnace.asides\r
 furnace.actions\r
index 946372e1f8c3f62dd14f47d3ceb4b4f3d05838e1..95e93f2ee8b067be02aa980f57c43b9d61990c7c 100644 (file)
@@ -1,12 +1,13 @@
 ! Copyright (c) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel math.order namespaces furnace combinators.short-circuit
+USING: accessors kernel math.order namespaces combinators.short-circuit
 html.forms
 html.templates
 html.templates.chloe
 locals
 http.server
-http.server.filters ;
+http.server.filters
+furnace.utilities ;
 IN: furnace.boilerplate
 
 TUPLE: boilerplate < filter-responder template init ;
index 697c885a0143c7a0fc8d6b3362fb29f8937f5350..8ab70ded7b1c7d1ae4016d151bbed48e5635cdd2 100644 (file)
@@ -19,7 +19,7 @@ http
 http.server
 http.server.redirection
 http.server.responses
-furnace ;
+furnace.utilities ;
 QUALIFIED-WITH: assocs a
 IN: furnace.chloe-tags
 
index 671296ce575975d871f694be5aaf8a45e2d96a2f..266958c8a4cebb26cec2c6bfec998c50b45ea7c2 100644 (file)
@@ -4,10 +4,10 @@ USING: namespaces assocs kernel sequences accessors hashtables
 urls db.types db.tuples math.parser fry logging combinators
 html.templates.chloe.syntax
 http http.server http.server.filters http.server.redirection
-furnace
 furnace.cache
 furnace.scopes
 furnace.sessions
+furnace.utilities
 furnace.redirection ;
 IN: furnace.conversations
 
index 911433d100ee0476d56cdbc4441116ef85298994..c6191b295e41815bef0c0646f73a9c9b5e556529 100644 (file)
@@ -2,129 +2,6 @@ USING: assocs help.markup help.syntax kernel
 quotations sequences strings urls xml.data http ;
 IN: furnace
 
-HELP: adjust-redirect-url
-{ $values { "url" url } { "url'" url } }
-{ $description "Adjusts a redirection URL by filtering the URL's query parameters through the " { $link modify-redirect-query } " generic word on every responder involved in handling the current request." } ;
-
-HELP: adjust-url
-{ $values { "url" url } { "url'" url } }
-{ $description "Adjusts a link URL by filtering the URL's query parameters through the " { $link modify-query } " generic word on every responder involved in handling the current request." } ;
-
-HELP: client-state
-{ $values { "key" string } { "value/f" { $maybe string } } }
-{ $description "Looks up a cookie (if the current request is a GET or HEAD request) or a POST parameter (if the current request is a POST request)." }
-{ $notes "This word is used by session management, conversation scope and asides." } ;
-
-HELP: each-responder
-{ $values { "quot" { $quotation "( 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." }
-{ $notes "This word is used by session management, conversation scope and asides." }
-{ $examples
-    { $example
-        "USING: furnace io ;"
-        "\"bar\" \"foo\" hidden-form-field nl"
-        "<input type='hidden' name='foo' value='bar'/>"
-    }
-} ;
-
-HELP: link-attr
-{ $values { "tag" tag } { "responder" "a responder" } }
-{ $contract "Modifies an XHTML " { $snippet "a" } " tag." }
-{ $notes "This word is called by " { $link "html.templates.chloe.tags.form" } "." }
-{ $examples "Conversation scope adds attributes to link tags." } ;
-
-HELP: modify-form
-{ $values { "responder" "a responder" } }
-{ $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." } ;
-
-HELP: modify-query
-{ $values { "query" assoc } { "responder" "a responder" } { "query'" assoc } }
-{ $contract "Modifies the query parameters of a URL destined to be displayed as a link." }
-{ $notes "This word is called by " { $link "html.templates.chloe.tags.form" } "." }
-{ $examples "Asides add query parameters to URLs." } ;
-
-HELP: modify-redirect-query
-{ $values { "query" assoc } { "responder" "a responder" } { "query'" assoc } }
-{ $contract "Modifies the query parameters of a URL destined to be used with a redirect." }
-{ $notes "This word is called by " { $link "furnace.redirection" } "." }
-{ $examples "Conversation scope and asides add query parameters to redirect URLs." } ;
-
-HELP: nested-responders
-{ $values { "seq" "a sequence of responders" } }
-{ $description "" } ;
-
-HELP: referrer
-{ $values { "referrer/f" { $maybe string } } }
-{ $description "Outputs the current request's referrer URL." } ;
-
-HELP: request-params
-{ $values { "request" request } { "assoc" assoc } }
-{ $description "Outputs the query parameters (if the current request is a GET or HEAD request) or the POST parameters (if the current request is a POST request)." } ;
-
-HELP: resolve-base-path
-{ $values { "string" string } { "string'" string } }
-{ $description "" } ;
-
-HELP: resolve-template-path
-{ $values { "pair" "a pair with shape " { $snippet "{ class string }" } } { "path" "a pathname string" } }
-{ $description "" } ;
-
-HELP: same-host?
-{ $values { "url" url } { "?" "a boolean" } }
-{ $description "Tests if the given URL is located on the same host as the URL of the current request." } ;
-
-HELP: user-agent
-{ $values { "user-agent" { $maybe string } } }
-{ $description "Outputs the user agent reported by the client for the current request." } ;
-
-HELP: vocab-path
-{ $values { "vocab" "a vocabulary specifier" } { "path" "a pathname string" } }
-{ $description "" } ;
-
-HELP: exit-with
-{ $values { "value" object } }
-{ $description "Exits from an outer " { $link with-exit-continuation } "." } ;
-
-HELP: with-exit-continuation
-{ $values { "quot" { $quotation { "( -- value )" } } } { "value" "a value returned by the quotation or an " { $link exit-with } " invocation" } }
-{ $description "Runs a quotation with the " { $link exit-continuation } " variable bound. Calling " { $link exit-with } " in the quotation will immediately return." }
-{ $notes "Furnace actions and authentication realms wrap their execution in this combinator, allowing form validation failures and login requests, respectively, to immediately return an HTTP response to the client without running any more responder code." } ;
-
-ARTICLE: "furnace.extension-points" "Furnace extension points"
-"Furnace features such as session management, conversation scope and asides need to modify URLs in links and redirects, and insert hidden form fields, to implement state on top of the stateless HTTP protocol. In order to decouple the server-side state management code from the HTML templating code, a series of hooks are used."
-$nl
-"Responders can implement methods on the following generic words:"
-{ $subsection modify-query }
-{ $subsection modify-redirect-query }
-{ $subsection link-attr }
-{ $subsection modify-form }
-"Presentation-level code can call the following words:"
-{ $subsection adjust-url }
-{ $subsection adjust-redirect-url } ;
-
-ARTICLE: "furnace.misc" "Miscellaneous Furnace features"
-"Inspecting the chain of responders handling the current request:"
-{ $subsection nested-responders }
-{ $subsection each-responder }
-{ $subsection resolve-base-path }
-"Vocabulary root-relative resources:"
-{ $subsection vocab-path }
-{ $subsection resolve-template-path }
-"Early return from a responder:"
-{ $subsection with-exit-continuation }
-{ $subsection exit-with }
-"Other useful words:"
-{ $subsection hidden-form-field }
-{ $subsection request-params }
-{ $subsection client-state }
-{ $subsection user-agent } ;
-
 ARTICLE: "furnace.persistence" "Furnace persistence layer"
 { $subsection "furnace.db" }
 "Server-side state:"
index 00e4f6f152584903da3a5e6840eccffc9b59547c..f6e543499768997bb5624d3988f741456d0d5875 100644 (file)
@@ -1,7 +1,7 @@
 IN: furnace.tests
 USING: http http.server.dispatchers http.server.responses
-http.server furnace tools.test kernel namespaces accessors
-io.streams.string urls ;
+http.server furnace furnace.utilities tools.test kernel
+namespaces accessors io.streams.string urls ;
 TUPLE: funny-dispatcher < dispatcher ;
 
 : <funny-dispatcher> funny-dispatcher new-dispatcher ;
index 29eb00a8f4a44f8fd1dea230ea6a4c9fda9fdafb..adafb215242dc85aee1849c832acf3ac75da4cad 100644 (file)
@@ -1,133 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces make assocs sequences kernel classes splitting
-vocabs.loader accessors strings combinators arrays
-continuations present fry
-urls html.elements
-http http.server http.server.redirection http.server.remapping ;
 IN: furnace
 
-: nested-responders ( -- seq )
-    responder-nesting get values ;
-
-: each-responder ( quot -- )
-   nested-responders swap each ; inline
-
-: base-path ( string -- pair )
-    dup responder-nesting get
-    [ second class superclasses [ name>> = ] with contains? ] with find nip
-    [ first ] [ "No such responder: " swap append throw ] ?if ;
-
-: resolve-base-path ( string -- string' )
-    "$" ?head [
-        [
-            "/" split1 [ base-path [  "/" % % ] each "/" % ] dip %
-        ] "" make
-    ] when ;
-
-: vocab-path ( vocab -- path )
-    dup vocab-dir vocab-append-path ;
-
-: resolve-template-path ( pair -- path )
-    [
-        first2 [ vocabulary>> vocab-path % ] [ "/" % % ] bi*
-    ] "" make ;
-
-GENERIC: modify-query ( query responder -- query' )
-
-M: object modify-query drop ;
-
-GENERIC: modify-redirect-query ( query responder -- query' )
-
-M: object modify-redirect-query drop ;
-
-GENERIC: adjust-url ( url -- url' )
-
-M: url adjust-url
-    clone
-        [ [ modify-query ] each-responder ] change-query
-        [ resolve-base-path ] change-path
-    relative-to-request ;
-
-M: string adjust-url ;
-
-GENERIC: adjust-redirect-url ( url -- url' )
-
-M: url adjust-redirect-url
-    adjust-url
-    [ [ modify-redirect-query ] each-responder ] change-query ;
-
-M: string adjust-redirect-url ;
-
-GENERIC: link-attr ( tag responder -- )
-
-M: object link-attr 2drop ;
-
-GENERIC: modify-form ( responder -- )
-
-M: object modify-form drop ;
-
-: hidden-form-field ( value name -- )
-    over [
-        <input
-            "hidden" =type
-            =name
-            present =value
-        input/>
-    ] [ 2drop ] if ;
-
-: nested-forms-key "__n" ;
-
-: request-params ( request -- assoc )
-    dup method>> {
-        { "GET" [ url>> query>> ] }
-        { "HEAD" [ url>> query>> ] }
-        { "POST" [
-            post-data>>
-            dup content-type>> "application/x-www-form-urlencoded" =
-            [ content>> ] [ drop f ] if
-        ] }
-    } case ;
-
-: referrer ( -- referrer/f )
-    #! Typo is intentional, it's in the HTTP spec!
-    "referer" request get header>> at
-    dup [ >url ensure-port [ remap-port ] change-port ] when ;
-
-: user-agent ( -- user-agent )
-    "user-agent" request get header>> at "" or ;
-
-: same-host? ( url -- ? )
-    dup [
-        url get [
-            [ protocol>> ]
-            [ host>> ]
-            [ port>> remap-port ]
-            tri 3array
-        ] bi@ =
-    ] when ;
-
-: cookie-client-state ( key request -- value/f )
-    swap get-cookie dup [ value>> ] when ;
-
-: post-client-state ( key request -- value/f )
-    request-params at ;
-
-: client-state ( key -- value/f )
-    request get dup method>> {
-        { "GET" [ cookie-client-state ] }
-        { "HEAD" [ cookie-client-state ] }
-        { "POST" [ post-client-state ] }
-    } case ;
-
-SYMBOL: exit-continuation
-
-: exit-with ( value -- )
-    exit-continuation get continue-with ;
-
-: with-exit-continuation ( quot -- value )
-    '[ exit-continuation set @ ] callcc1 exit-continuation off ;
-
 USE: vocabs.loader
 "furnace.actions" require
 "furnace.alloy" require
index c5a63a795c7aff7de58eea2e677967334f2bfcac..01297288dc8fb4274320854ce9aaeec20f63191a 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors combinators namespaces fry urls http
 http.server http.server.redirection http.server.responses
-http.server.remapping http.server.filters furnace ;
+http.server.remapping http.server.filters furnace.utilities ;
 IN: furnace.redirection
 
 : <redirect> ( url -- response )
index 599461c37c5e99fe472e43cf1af6071463f221a7..b57bcb262bd1a66879ddb7d85f7dbe474683807b 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax io.streams.string
-furnace ;
+furnace.utilities ;
 IN: furnace.referrer
 
 HELP: <check-form-submissions>
index 003028ab1ea787e2e173f5f2590acf2f4b5c78ca..e5666c269849d4e63bdaa6aad7739b6a25e97066 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel http.server http.server.filters
-http.server.responses furnace ;
+http.server.responses furnace.utilities ;
 IN: furnace.referrer
 
 TUPLE: referrer-check < filter-responder quot ;
index 6bb3c1cd6927bdfa73c949184a9bf7355d9e9294..907e657125b514e65ba2107003929b1beb24d35c 100644 (file)
@@ -3,7 +3,8 @@ USING: tools.test http furnace.sessions furnace.actions
 http.server http.server.responses math namespaces make kernel\r
 accessors io.sockets io.servers.connection prettyprint\r
 io.streams.string io.files splitting destructors sequences db\r
-db.tuples db.sqlite continuations urls math.parser furnace ;\r
+db.tuples db.sqlite continuations urls math.parser furnace\r
+furnace.utilities ;\r
 \r
 : with-session\r
     [\r
index b7120aaf11cc765a98ffc2f62d17021f7932ad3b..8b7e1ab83f1789550b0d129a4245921dfe622a59 100644 (file)
@@ -1,13 +1,11 @@
 ! Copyright (C) 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs kernel math.intervals math.parser namespaces
-strings random accessors quotations hashtables sequences continuations
-fry calendar combinators combinators.short-circuit destructors alarms
-io.servers.connection
-db db.tuples db.types
+strings random accessors quotations hashtables sequences
+continuations fry calendar combinators combinators.short-circuit
+destructors alarms io.sockets db db.tuples db.types
 http http.server http.server.dispatchers http.server.filters
-html.elements
-furnace furnace.cache furnace.scopes ;
+html.elements furnace.cache furnace.scopes furnace.utilities ;
 IN: furnace.sessions
 
 TUPLE: session < scope user-agent client ;
index a326e62f02c94907c0c381c05bcbc3ec20512a5c..876aaf8c98ab45f46aaacd37fdda2206ac81f5d6 100644 (file)
@@ -1,9 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel sequences fry
-combinators syndication
-http.server.responses http.server.redirection
-furnace furnace.actions ;
+USING: accessors kernel sequences fry combinators syndication
+http.server.responses http.server.redirection furnace.actions
+furnace.utilities ;
 IN: furnace.syndication
 
 GENERIC: feed-entry-title ( object -- string )
diff --git a/basis/furnace/utilities/utilities-docs.factor b/basis/furnace/utilities/utilities-docs.factor
new file mode 100644 (file)
index 0000000..1402e9c
--- /dev/null
@@ -0,0 +1,126 @@
+USING: assocs help.markup help.syntax kernel
+quotations sequences strings urls xml.data http ;
+IN: furnace.utilities
+
+HELP: adjust-redirect-url
+{ $values { "url" url } { "url'" url } }
+{ $description "Adjusts a redirection URL by filtering the URL's query parameters through the " { $link modify-redirect-query } " generic word on every responder involved in handling the current request." } ;
+
+HELP: adjust-url
+{ $values { "url" url } { "url'" url } }
+{ $description "Adjusts a link URL by filtering the URL's query parameters through the " { $link modify-query } " generic word on every responder involved in handling the current request." } ;
+
+HELP: client-state
+{ $values { "key" string } { "value/f" { $maybe string } } }
+{ $description "Looks up a cookie (if the current request is a GET or HEAD request) or a POST parameter (if the current request is a POST request)." }
+{ $notes "This word is used by session management, conversation scope and asides." } ;
+
+HELP: each-responder
+{ $values { "quot" { $quotation "( 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." }
+{ $notes "This word is used by session management, conversation scope and asides." }
+{ $examples
+    { $example
+        "USING: furnace.utilities io ;"
+        "\"bar\" \"foo\" hidden-form-field nl"
+        "<input type='hidden' name='foo' value='bar'/>"
+    }
+} ;
+
+HELP: link-attr
+{ $values { "tag" tag } { "responder" "a responder" } }
+{ $contract "Modifies an XHTML " { $snippet "a" } " tag." }
+{ $notes "This word is called by " { $link "html.templates.chloe.tags.form" } "." }
+{ $examples "Conversation scope adds attributes to link tags." } ;
+
+HELP: modify-form
+{ $values { "responder" "a responder" } }
+{ $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." } ;
+
+HELP: modify-query
+{ $values { "query" assoc } { "responder" "a responder" } { "query'" assoc } }
+{ $contract "Modifies the query parameters of a URL destined to be displayed as a link." }
+{ $notes "This word is called by " { $link "html.templates.chloe.tags.form" } "." }
+{ $examples "Asides add query parameters to URLs." } ;
+
+HELP: modify-redirect-query
+{ $values { "query" assoc } { "responder" "a responder" } { "query'" assoc } }
+{ $contract "Modifies the query parameters of a URL destined to be used with a redirect." }
+{ $notes "This word is called by " { $link "furnace.redirection" } "." }
+{ $examples "Conversation scope and asides add query parameters to redirect URLs." } ;
+
+HELP: nested-responders
+{ $values { "seq" "a sequence of responders" } }
+{ $description "" } ;
+
+HELP: referrer
+{ $values { "referrer/f" { $maybe string } } }
+{ $description "Outputs the current request's referrer URL." } ;
+
+HELP: request-params
+{ $values { "request" request } { "assoc" assoc } }
+{ $description "Outputs the query parameters (if the current request is a GET or HEAD request) or the POST parameters (if the current request is a POST request)." } ;
+
+HELP: resolve-base-path
+{ $values { "string" string } { "string'" string } }
+{ $description "" } ;
+
+HELP: resolve-template-path
+{ $values { "pair" "a pair with shape " { $snippet "{ class string }" } } { "path" "a pathname string" } }
+{ $description "" } ;
+
+HELP: same-host?
+{ $values { "url" url } { "?" "a boolean" } }
+{ $description "Tests if the given URL is located on the same host as the URL of the current request." } ;
+
+HELP: user-agent
+{ $values { "user-agent" { $maybe string } } }
+{ $description "Outputs the user agent reported by the client for the current request." } ;
+
+HELP: vocab-path
+{ $values { "vocab" "a vocabulary specifier" } { "path" "a pathname string" } }
+{ $description "" } ;
+
+HELP: exit-with
+{ $values { "value" object } }
+{ $description "Exits from an outer " { $link with-exit-continuation } "." } ;
+
+HELP: with-exit-continuation
+{ $values { "quot" { $quotation { "( -- value )" } } } { "value" "a value returned by the quotation or an " { $link exit-with } " invocation" } }
+{ $description "Runs a quotation with the " { $link exit-continuation } " variable bound. Calling " { $link exit-with } " in the quotation will immediately return." }
+{ $notes "Furnace actions and authentication realms wrap their execution in this combinator, allowing form validation failures and login requests, respectively, to immediately return an HTTP response to the client without running any more responder code." } ;
+
+ARTICLE: "furnace.extension-points" "Furnace extension points"
+"Furnace features such as session management, conversation scope and asides need to modify URLs in links and redirects, and insert hidden form fields, to implement state on top of the stateless HTTP protocol. In order to decouple the server-side state management code from the HTML templating code, a series of hooks are used."
+$nl
+"Responders can implement methods on the following generic words:"
+{ $subsection modify-query }
+{ $subsection modify-redirect-query }
+{ $subsection link-attr }
+{ $subsection modify-form }
+"Presentation-level code can call the following words:"
+{ $subsection adjust-url }
+{ $subsection adjust-redirect-url } ;
+
+ARTICLE: "furnace.misc" "Miscellaneous Furnace features"
+"Inspecting the chain of responders handling the current request:"
+{ $subsection nested-responders }
+{ $subsection each-responder }
+{ $subsection resolve-base-path }
+"Vocabulary root-relative resources:"
+{ $subsection vocab-path }
+{ $subsection resolve-template-path }
+"Early return from a responder:"
+{ $subsection with-exit-continuation }
+{ $subsection exit-with }
+"Other useful words:"
+{ $subsection hidden-form-field }
+{ $subsection request-params }
+{ $subsection client-state }
+{ $subsection user-agent } ;
index 4bfbdcd943888c82ff58e331761847cfdced9ee8..7f71a131eda164a1103ccc882516bc9380c5b2fe 100644 (file)
@@ -1,10 +1,13 @@
-! Copyright (c) 2008 Slava Pestov
+! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors words kernel sequences splitting ;
+USING: namespaces make assocs sequences kernel classes splitting
+words vocabs.loader accessors strings combinators arrays
+continuations present fry urls html.elements http http.server
+http.server.redirection http.server.remapping ;
 IN: furnace.utilities
 
 : word>string ( word -- string )
-    [ vocabulary>> ] [ name>> ] bi ":" swap 3append ;
+    [ vocabulary>> ] [ name>> ] bi ":" glue ;
 
 : words>strings ( seq -- seq' )
     [ word>string ] map ;
@@ -17,3 +20,124 @@ ERROR: no-such-word name vocab ;
 
 : strings>words ( seq -- seq' )
     [ string>word ] map ;
+
+: nested-responders ( -- seq )
+    responder-nesting get values ;
+
+: each-responder ( quot -- )
+   nested-responders swap each ; inline
+
+: base-path ( string -- pair )
+    dup responder-nesting get
+    [ second class superclasses [ name>> = ] with contains? ] with find nip
+    [ first ] [ "No such responder: " swap append throw ] ?if ;
+
+: resolve-base-path ( string -- string' )
+    "$" ?head [
+        [
+            "/" split1 [ base-path [  "/" % % ] each "/" % ] dip %
+        ] "" make
+    ] when ;
+
+: vocab-path ( vocab -- path )
+    dup vocab-dir vocab-append-path ;
+
+: resolve-template-path ( pair -- path )
+    [
+        first2 [ vocabulary>> vocab-path % ] [ "/" % % ] bi*
+    ] "" make ;
+
+GENERIC: modify-query ( query responder -- query' )
+
+M: object modify-query drop ;
+
+GENERIC: modify-redirect-query ( query responder -- query' )
+
+M: object modify-redirect-query drop ;
+
+GENERIC: adjust-url ( url -- url' )
+
+M: url adjust-url
+    clone
+        [ [ modify-query ] each-responder ] change-query
+        [ resolve-base-path ] change-path
+    relative-to-request ;
+
+M: string adjust-url ;
+
+GENERIC: adjust-redirect-url ( url -- url' )
+
+M: url adjust-redirect-url
+    adjust-url
+    [ [ modify-redirect-query ] each-responder ] change-query ;
+
+M: string adjust-redirect-url ;
+
+GENERIC: link-attr ( tag responder -- )
+
+M: object link-attr 2drop ;
+
+GENERIC: modify-form ( responder -- )
+
+M: object modify-form drop ;
+
+: hidden-form-field ( value name -- )
+    over [
+        <input
+            "hidden" =type
+            =name
+            present =value
+        input/>
+    ] [ 2drop ] if ;
+
+: nested-forms-key "__n" ;
+
+: request-params ( request -- assoc )
+    dup method>> {
+        { "GET" [ url>> query>> ] }
+        { "HEAD" [ url>> query>> ] }
+        { "POST" [
+            post-data>>
+            dup content-type>> "application/x-www-form-urlencoded" =
+            [ content>> ] [ drop f ] if
+        ] }
+    } case ;
+
+: referrer ( -- referrer/f )
+    #! Typo is intentional, it's in the HTTP spec!
+    "referer" request get header>> at
+    dup [ >url ensure-port [ remap-port ] change-port ] when ;
+
+: user-agent ( -- user-agent )
+    "user-agent" request get header>> at "" or ;
+
+: same-host? ( url -- ? )
+    dup [
+        url get [
+            [ protocol>> ]
+            [ host>> ]
+            [ port>> remap-port ]
+            tri 3array
+        ] bi@ =
+    ] when ;
+
+: cookie-client-state ( key request -- value/f )
+    swap get-cookie dup [ value>> ] when ;
+
+: post-client-state ( key request -- value/f )
+    request-params at ;
+
+: client-state ( key -- value/f )
+    request get dup method>> {
+        { "GET" [ cookie-client-state ] }
+        { "HEAD" [ cookie-client-state ] }
+        { "POST" [ post-client-state ] }
+    } case ;
+
+SYMBOL: exit-continuation
+
+: exit-with ( value -- )
+    exit-continuation get continue-with ;
+
+: with-exit-continuation ( quot -- value )
+    '[ exit-continuation set @ ] callcc1 exit-continuation off ;
index ba53e6c591172d8b77222a36531e9040e9769055..2380f5614d784cfadd0b97ee0b4c057adaea9452 100644 (file)
@@ -17,6 +17,15 @@ HELP: narray
 { $description "A generalization of " { $link 1array } ", "\r
 { $link 2array } ", " { $link 3array } " and " { $link 4array } " "\r
 "that constructs an array from the top " { $snippet "n" } " elements of the stack."\r
+}\r
+{ $examples\r
+    "Some core words expressed in terms of " { $link narray } ":"\r
+    { $table\r
+        { { $link 1array } { $snippet "1 narray" } }\r
+        { { $link 2array } { $snippet "2 narray" } }\r
+        { { $link 3array } { $snippet "3 narray" } }\r
+        { { $link 4array } { $snippet "4 narray" } }\r
+    }\r
 } ;\r
 \r
 { nsequence narray } related-words\r
@@ -26,6 +35,15 @@ HELP: firstn
 { $description "A generalization of " { $link first } ", "\r
 { $link first2 } ", " { $link first3 } " and " { $link first4 } " "\r
 "that pushes the first " { $snippet "n" } " elements of a sequence on the stack."\r
+}\r
+{ $examples\r
+    "Some core words expressed in terms of " { $link firstn } ":"\r
+    { $table\r
+        { { $link first } { $snippet "1 firstn" } }\r
+        { { $link first2 } { $snippet "2 firstn" } }\r
+        { { $link first3 } { $snippet "3 firstn" } }\r
+        { { $link first4 } { $snippet "4 firstn" } }\r
+    }\r
 } ;\r
 \r
 HELP: npick\r
@@ -37,8 +55,13 @@ HELP: npick
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 npick .s" "1\n2\n3\n4\n1" }\r
-}\r
-{ $see-also dup over pick } ;\r
+  "Some core words expressed in terms of " { $link npick } ":"\r
+    { $table\r
+        { { $link dup } { $snippet "1 npick" } }\r
+        { { $link over } { $snippet "2 npick" } }\r
+        { { $link pick } { $snippet "3 npick" } }\r
+    }\r
+} ;\r
 \r
 HELP: ndup\r
 { $values { "n" integer } }\r
@@ -49,8 +72,13 @@ HELP: ndup
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 ndup .s" "1\n2\n3\n4\n1\n2\n3\n4" }\r
-}\r
-{ $see-also dup 2dup 3dup } ;\r
+  "Some core words expressed in terms of " { $link ndup } ":"\r
+    { $table\r
+        { { $link dup } { $snippet "1 ndup" } }\r
+        { { $link 2dup } { $snippet "2 ndup" } }\r
+        { { $link 3dup } { $snippet "3 ndup" } }\r
+    }\r
+} ;\r
 \r
 HELP: nnip\r
 { $values { "n" integer } }\r
@@ -60,8 +88,12 @@ HELP: nnip
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 3 nnip .s" "4" }\r
-}\r
-{ $see-also nip 2nip } ;\r
+  "Some core words expressed in terms of " { $link nnip } ":"\r
+    { $table\r
+        { { $link nip } { $snippet "1 nnip" } }\r
+        { { $link 2nip } { $snippet "2 nnip" } }\r
+    }\r
+} ;\r
 \r
 HELP: ndrop\r
 { $values { "n" integer } }\r
@@ -71,8 +103,13 @@ HELP: ndrop
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 3 ndrop .s" "1" }\r
-}\r
-{ $see-also drop 2drop 3drop } ;\r
+  "Some core words expressed in terms of " { $link ndrop } ":"\r
+    { $table\r
+        { { $link drop } { $snippet "1 ndrop" } }\r
+        { { $link 2drop } { $snippet "2 ndrop" } }\r
+        { { $link 3drop } { $snippet "3 ndrop" } }\r
+    }\r
+} ;\r
 \r
 HELP: nrot\r
 { $values { "n" integer } }\r
@@ -81,8 +118,12 @@ HELP: nrot
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 nrot .s" "2\n3\n4\n1" }\r
-}\r
-{ $see-also rot -nrot } ;\r
+  "Some core words expressed in terms of " { $link nrot } ":"\r
+    { $table\r
+        { { $link swap } { $snippet "1 nrot" } }\r
+        { { $link rot } { $snippet "2 nrot" } }\r
+    }\r
+} ;\r
 \r
 HELP: -nrot\r
 { $values { "n" integer } }\r
@@ -91,8 +132,12 @@ HELP: -nrot
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 -nrot .s" "4\n1\n2\n3" }\r
-}\r
-{ $see-also rot nrot } ;\r
+  "Some core words expressed in terms of " { $link -nrot } ":"\r
+    { $table\r
+        { { $link swap } { $snippet "1 -nrot" } }\r
+        { { $link -rot } { $snippet "2 -nrot" } }\r
+    }\r
+} ;\r
 \r
 HELP: nrev\r
 { $values { "n" integer } }\r
@@ -100,11 +145,11 @@ HELP: nrev
 }\r
 { $examples\r
   { $example "USING: prettyprint generalizations ;" "1 2 3 4 4 nrev .s" "4\n3\n2\n1" }\r
-}\r
-{ $see-also rot nrot } ;\r
+  "The " { $link spin } " word is equivalent to " { $snippet "3 nrev" } "."\r
+} ;\r
 \r
 HELP: ndip\r
-{ $values { "quot" quotation } { "n" number } }\r
+{ $values { "quot" quotation } { "n" integer } }\r
 { $description "A generalization of " { $link dip } " that can work " \r
 "for any stack depth. The quotation will be called with a stack that "\r
 "has 'n' items removed first. The 'n' items are then put back on the "\r
@@ -113,30 +158,93 @@ HELP: ndip
 { $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
-}\r
-{ $see-also dip 2dip } ;\r
+  "Some core words expressed in terms of " { $link ndip } ":"\r
+    { $table\r
+        { { $link dip } { $snippet "1 ndip" } }\r
+        { { $link 2dip } { $snippet "2 ndip" } }\r
+        { { $link 3dip } { $snippet "3 ndip" } }\r
+    }\r
+} ;\r
 \r
 HELP: nslip\r
-{ $values { "n" number } }\r
+{ $values { "n" integer } }\r
 { $description "A generalization of " { $link slip } " that can work " \r
 "for any stack depth. The first " { $snippet "n" } " items after the quotation will be "\r
 "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
-}\r
-{ $see-also slip nkeep } ;\r
+  "Some core words expressed in terms of " { $link nslip } ":"\r
+    { $table\r
+        { { $link slip } { $snippet "1 nslip" } }\r
+        { { $link 2slip } { $snippet "2 nslip" } }\r
+        { { $link 3slip } { $snippet "3 nslip" } }\r
+    }\r
+} ;\r
 \r
 HELP: nkeep\r
-{ $values { "quot" quotation } { "n" number } }\r
+{ $values { "quot" quotation } { "n" integer } }\r
 { $description "A generalization of " { $link keep } " that can work " \r
 "for any stack depth. The first " { $snippet "n" } " items after the quotation will be "\r
 "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
-}\r
-{ $see-also keep nslip } ;\r
+  "Some core words expressed in terms of " { $link nkeep } ":"\r
+    { $table\r
+        { { $link keep } { $snippet "1 nkeep" } }\r
+        { { $link 2keep } { $snippet "2 nkeep" } }\r
+        { { $link 3keep } { $snippet "3 nkeep" } }\r
+    }\r
+} ;\r
+\r
+HELP: ncurry\r
+{ $values { "quot" quotation } { "n" integer } }\r
+{ $description "A generalization of " { $link curry } " that can work for any stack depth."\r
+} \r
+{ $examples\r
+  "Some core words expressed in terms of " { $link ncurry } ":"\r
+    { $table\r
+        { { $link curry } { $snippet "1 ncurry" } }\r
+        { { $link 2curry } { $snippet "2 ncurry" } }\r
+        { { $link 3curry } { $snippet "3 ncurry" } }\r
+    }\r
+} ;\r
+\r
+HELP: nwith\r
+{ $values { "quot" quotation } { "n" integer } }\r
+{ $description "A generalization of " { $link with } " that can work for any stack depth."\r
+} \r
+{ $examples\r
+  "Some core words expressed in terms of " { $link nwith } ":"\r
+    { $table\r
+        { { $link with } { $snippet "1 nwith" } }\r
+    }\r
+} ;\r
+\r
+HELP: napply\r
+{ $values { "quot" quotation } { "n" integer } }\r
+{ $description "A generalization of " { $link bi@ } " and " { $link tri@ } " that can work for any stack depth."\r
+} \r
+{ $examples\r
+  "Some core words expressed in terms of " { $link napply } ":"\r
+    { $table\r
+        { { $link bi@ } { $snippet "1 napply" } }\r
+        { { $link tri@ } { $snippet "2 napply" } }\r
+    }\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
+{ $examples\r
+  "Some core words expressed in terms of " { $link mnswap } ":"\r
+    { $table\r
+        { { $link swap } { $snippet "1 1 mnswap" } }\r
+        { { $link rot } { $snippet "2 1 mnswap" } }\r
+        { { $link -rot } { $snippet "1 2 mnswap" } }\r
+    }\r
+} ;\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
@@ -155,12 +263,14 @@ $nl
 { $subsection nnip }\r
 { $subsection ndrop }\r
 { $subsection nrev }\r
+{ $subsection mnswap }\r
 "Generalized combinators:"\r
 { $subsection ndip }\r
 { $subsection nslip }\r
 { $subsection nkeep }\r
+{ $subsection napply }\r
+"Generalized quotation construction:"\r
 { $subsection ncurry } \r
-{ $subsection nwith } \r
-{ $subsection napply } ;\r
+{ $subsection nwith } ;\r
 \r
 ABOUT: "generalizations"\r
index 1ebe528f35c2a0971301277b32b2d0fba77f6fee..1291012700c608f78529ed097e73c1867810880b 100644 (file)
@@ -38,3 +38,7 @@ IN: generalizations.tests
 [ "a" ] [ { "a" } 1 firstn ] unit-test\r
 \r
 [ [ 1 2 ] ] [ 1 2 2 [ ] nsequence ] unit-test\r
+\r
+[ 4 5 1 2 3 ] [ 1 2 3 4 5 2 3 mnswap ] unit-test\r
+\r
+[ 1 2 3 4 5 6 ] [ 1 2 3 4 5 6 2 4 mnswap 4 2 mnswap ] unit-test\r
index c63c2b66caa1b42cc97650cdb89dc104d2cb3b10..3c24d20c8a15b24ecb376c8481f13754f79804e4 100644 (file)
@@ -1,68 +1,78 @@
-! Copyright (C) 2007, 2008 Chris Double, Doug Coleman, Eduardo\r
-! Cavazos, Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: kernel sequences sequences.private namespaces math\r
-math.ranges combinators macros quotations fry arrays ;\r
-IN: generalizations\r
-\r
-MACRO: nsequence ( n seq -- quot )\r
-    [\r
-        [ drop <reversed> ] [ '[ _ _ new-sequence ] ] 2bi\r
-        [ '[ @ [ _ swap set-nth-unsafe ] keep ] ] reduce\r
-    ] keep\r
-    '[ @ _ like ] ;\r
-\r
-MACRO: narray ( n -- quot )\r
-    '[ _ { } nsequence ] ;\r
-\r
-MACRO: firstn ( n -- )\r
-    dup zero? [ drop [ drop ] ] [\r
-        [ [ '[ [ _ ] dip nth-unsafe ] ] map ]\r
-        [ 1- '[ [ _ ] dip bounds-check 2drop ] ]\r
-        bi prefix '[ _ cleave ]\r
-    ] if ;\r
-\r
-MACRO: npick ( n -- )\r
-    1- dup saver [ dup ] rot [ r> swap ] n*quot 3append ;\r
-\r
-MACRO: ndup ( n -- )\r
-    dup '[ _ npick ] n*quot ;\r
-\r
-MACRO: nrot ( n -- )\r
-    1- dup saver swap [ r> swap ] n*quot append ;\r
-\r
-MACRO: -nrot ( n -- )\r
-    1- dup [ swap >r ] n*quot swap restorer append ;\r
-\r
-MACRO: ndrop ( n -- )\r
-    [ drop ] n*quot ;\r
-\r
-: nnip ( n -- )\r
-    swap >r ndrop r> ; inline\r
-\r
-MACRO: ntuck ( n -- )\r
-    2 + [ dupd -nrot ] curry ;\r
-\r
-MACRO: nrev ( n -- quot )\r
-    1 [a,b] [ ] [ '[ @ _ -nrot ] ] reduce ;\r
-\r
-MACRO: ndip ( quot n -- )\r
-    dup saver -rot restorer 3append ;\r
-\r
-MACRO: nslip ( n -- )\r
-    dup saver [ call ] rot restorer 3append ;\r
-\r
-MACRO: nkeep ( n -- )\r
-    [ ] [ 1+ ] [ ] tri\r
-    '[ [ _ ndup ] dip _ -nrot _ nslip ] ;\r
-\r
-MACRO: ncurry ( n -- )\r
-    [ curry ] n*quot ;\r
-\r
-MACRO: nwith ( n -- )\r
-    [ with ] n*quot ;\r
-\r
-MACRO: napply ( n -- )\r
-    2 [a,b]\r
-    [ [ 1- ] keep '[ _ ntuck _ nslip ] ]\r
-    map concat >quotation [ call ] append ;\r
+! Copyright (C) 2007, 2008 Chris Double, Doug Coleman, Eduardo
+! Cavazos, Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences sequences.private math math.ranges
+combinators macros quotations fry ;
+IN: generalizations
+
+<<
+
+: n*quot ( n seq -- seq' ) <repetition> concat >quotation ;
+
+: repeat ( n obj quot -- ) swapd times ; inline
+
+>>
+
+MACRO: nsequence ( n seq -- )
+    [
+        [ drop <reversed> ] [ '[ _ _ new-sequence ] ] 2bi
+        [ '[ @ [ _ swap set-nth-unsafe ] keep ] ] reduce
+    ] keep
+    '[ @ _ like ] ;
+
+MACRO: narray ( n -- )
+    '[ _ { } nsequence ] ;
+
+MACRO: firstn ( n -- )
+    dup zero? [ drop [ drop ] ] [
+        [ [ '[ [ _ ] dip nth-unsafe ] ] map ]
+        [ 1- '[ [ _ ] dip bounds-check 2drop ] ]
+        bi prefix '[ _ cleave ]
+    ] if ;
+
+MACRO: npick ( n -- )
+    1- [ dup ] [ '[ _ dip swap ] ] repeat ;
+
+MACRO: ndup ( n -- )
+    dup '[ _ npick ] n*quot ;
+
+MACRO: nrot ( n -- )
+    1- [ ] [ '[ _ dip swap ] ] repeat ;
+
+MACRO: -nrot ( n -- )
+    1- [ ] [ '[ swap _ dip ] ] repeat ;
+
+MACRO: ndrop ( n -- )
+    [ drop ] n*quot ;
+
+MACRO: nnip ( n -- )
+    '[ [ _ ndrop ] dip ] ;
+
+MACRO: ntuck ( n -- )
+    2 + '[ dup _ -nrot ] ;
+
+MACRO: nrev ( n -- )
+    1 [a,b] [ ] [ '[ @ _ -nrot ] ] reduce ;
+
+MACRO: ndip ( quot n -- )
+    [ '[ _ dip ] ] times ;
+
+MACRO: nslip ( n -- )
+    '[ [ call ] _ ndip ] ;
+
+MACRO: nkeep ( quot n -- )
+    tuck '[ _ ndup _ _ ndip ] ;
+
+MACRO: ncurry ( n -- )
+    [ curry ] n*quot ;
+
+MACRO: nwith ( n -- )
+    [ with ] n*quot ;
+
+MACRO: napply ( n -- )
+    2 [a,b]
+    [ [ 1- ] [ ] bi '[ _ ntuck _ nslip ] ]
+    map concat >quotation [ call ] append ;
+
+MACRO: mnswap ( m n -- )
+    1+ '[ _ -nrot ] <repetition> spread>quot ;
index 4a1b8c7b90c3a39071b058fbce6c670a43c2ccee..0fa20b41fc43b63918a6c20cc0892625bfbb11b2 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: chunking-seq { seq read-only } { n read-only } ;
 : check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
 
 : new-groups ( seq n class -- groups )
-    >r check-groups r> boa ; inline
+    [ check-groups ] dip boa ; inline
 
 GENERIC: group@ ( n groups -- from to seq )
 
index 893273e6647c843c57d64b78ee2f242025ebf917..6e8c7ee63a7e9fa6d32fa5e43542420b942b3240 100644 (file)
@@ -14,25 +14,25 @@ IN: hash2
 : <hash2> ( size -- hash2 ) f <array> ;
 
 : 2= ( a b pair -- ? )
-    first2 swapd >r >r = r> r> = and ; inline
+    first2 swapd [ = ] 2bi@ and ; inline
 
 : (assoc2) ( a b alist -- {a,b,val} )
-    [ >r 2dup r> 2= ] find >r 3drop r> ; inline
+    [ 2= ] with with find nip ; inline
 
 : assoc2 ( a b alist -- value )
     (assoc2) dup [ third ] when ; inline
 
 : set-assoc2 ( value a b alist -- alist )
-    >r rot 3array r> ?push ; inline
+    [ rot 3array ] dip ?push ; inline
 
 : hash2@ ( a b hash2 -- a b bucket hash2 )
-    >r 2dup hashcode2 r> [ length mod ] keep ; inline
+    [ 2dup hashcode2 ] dip [ length mod ] keep ; inline
 
 : hash2 ( a b hash2 -- value/f )
-    hash2@ nth [ assoc2 ] [ 2drop f ] if* ;
+    hash2@ nth dup [ assoc2 ] [ 3drop f ] if ;
 
 : set-hash2 ( a b value hash2 -- )
-    >r -rot r> hash2@ [ set-assoc2 ] change-nth ;
+    [ -rot ] dip hash2@ [ set-assoc2 ] change-nth ;
 
 : alist>hash2 ( alist size -- hash2 )
-    <hash2> [ over >r first3 r> set-hash2 ] reduce ; inline
+    <hash2> [ over [ first3 ] dip set-hash2 ] reduce ; inline
index 92146755d9db30cb2060510961b220340a825a00..ba95a9f249d201ba841cb53c7ee5029bf07f62a0 100644 (file)
@@ -18,7 +18,7 @@ GENERIC: heap-size ( heap -- n )
 TUPLE: heap data ;
 
 : <heap> ( class -- heap )
-    >r V{ } clone r> boa ; inline
+    [ V{ } clone ] dip boa ; inline
 
 TUPLE: entry value key heap index ;
 
@@ -52,16 +52,16 @@ M: heap heap-size ( heap -- n )
     data>> nth-unsafe ; inline
 
 : up-value ( n heap -- entry )
-    >r up r> data-nth ; inline
+    [ up ] dip data-nth ; inline
 
 : left-value ( n heap -- entry )
-    >r left r> data-nth ; inline
+    [ left ] dip data-nth ; inline
 
 : right-value ( n heap -- entry )
-    >r right r> data-nth ; inline
+    [ right ] dip data-nth ; inline
 
 : data-set-nth ( entry n heap -- )
-    >r [ >>index drop ] 2keep r>
+    [ [ >>index drop ] 2keep ] dip
     data>> set-nth-unsafe ; inline
 
 : data-push ( entry heap -- n )
@@ -82,8 +82,8 @@ M: heap heap-size ( heap -- n )
     data>> first ; inline
 
 : data-exchange ( m n heap -- )
-    [ tuck data-nth >r data-nth r> ] 3keep
-    tuck >r >r data-set-nth r> r> data-set-nth ; inline
+    [ tuck data-nth [ data-nth ] dip ] 3keep
+    tuck [ data-set-nth ] 2dip data-set-nth ; inline
 
 GENERIC: heap-compare ( pair1 pair2 heap -- ? )
 
@@ -97,10 +97,10 @@ M: max-heap heap-compare (heap-compare) +lt+ eq? ;
     heap-size >= ; inline
 
 : left-bounds-check? ( m heap -- ? )
-    >r left r> heap-bounds-check? ; inline
+    [ left ] dip heap-bounds-check? ; inline
 
 : right-bounds-check? ( m heap -- ? )
-    >r right r> heap-bounds-check? ; inline
+    [ right ] dip heap-bounds-check? ; inline
 
 : continue? ( m up[m] heap -- ? )
     [ data-nth swap ] keep [ data-nth ] keep
@@ -109,7 +109,7 @@ M: max-heap heap-compare (heap-compare) +lt+ eq? ;
 DEFER: up-heap
 
 : (up-heap) ( n heap -- )
-    >r dup up r>
+    [ dup up ] dip
     3dup continue? [
         [ data-exchange ] 2keep up-heap
     ] [
@@ -121,7 +121,7 @@ DEFER: up-heap
 
 : (child) ( m heap -- n )
     2dup right-value
-    >r 2dup left-value r>
+    [ 2dup left-value ] dip
     rot heap-compare
     [ right ] [ left ] if ;
 
index 6e27bd9256c678885b1f91468533c8a9028ffd82..e72fbb439c125baeb80edb1d09303c890c097bed 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax io kernel math namespaces parser
 prettyprint sequences vocabs.loader namespaces stack-checker
-help ;
+help command-line multiline ;
 IN: help.cookbook
 
 ARTICLE: "cookbook-syntax" "Basic syntax cookbook"
@@ -205,10 +205,10 @@ ARTICLE: "cookbook-io" "Input and output cookbook"
 }
 "Convert a file of 4-byte cells from little to big endian or vice versa, by directly mapping it into memory and operating on it with sequence words:"
 { $code
-    "USING: accessors grouping io.files io.mmap kernel sequences ;"
-    "\"mydata.dat\" dup file-info size>> ["
+    "USING: accessors grouping io.files io.mmap.char kernel sequences ;"
+    "\"mydata.dat\" ["
     "    4 <sliced-groups> [ reverse-here ] change-each"
-    "] with-mapped-file"
+    "] with-mapped-char-file"
 }
 "Send some bytes to a remote host:"
 { $code
@@ -263,15 +263,65 @@ ARTICLE: "cookbook-application" "Application cookbook"
 ARTICLE: "cookbook-scripts" "Scripting cookbook"
 "Factor can be used for command-line scripting on Unix-like systems."
 $nl
-"A text file can begin with a comment like the following, and made executable:"
-{ $code "#! /usr/bin/env factor -script" }
-"Running the text file will run it through Factor, assuming the " { $snippet "factor" } " binary is in your " { $snippet "$PATH" } "."
+"To run a script, simply pass it as an argument to the Factor executable:"
+{ $code "./factor cleanup.factor" }
+"The script may access command line arguments by inspecting the value of the " { $link command-line } " variable. It can also get its own path from the " { $link script } " variable."
+{ $heading "Example: ls" }
+"Here is an example implementing a simplified version of the Unix " { $snippet "ls" } " command in Factor:"
+{ $code
+    <" USING: command-line namespaces io io.files tools.files
+sequences kernel ;
+
+command-line get [
+    current-directory get directory.
+] [
+    dup length 1 = [ first directory. ] [
+        [ [ nl write ":" print ] [ directory. ] bi ] each
+    ] if
+] if-empty">
+}
+"You can put it in a file named " { $snippet "ls.factor" } ", and then run it, to list the " { $snippet "/usr/bin" } " directory for example:"
+{ $code "./factor ls.factor /usr/bin" }
+{ $heading "Example: grep" }
+"The following is a more complicated example, implementing something like the Unix " { $snippet "grep" } " command:"
+{ $code <" USING: kernel fry io io.files io.encodings.ascii sequences
+regexp command-line namespaces ;
+IN: grep
+
+: grep-lines ( pattern -- )
+    '[ dup _ matches? [ print ] [ drop ] if ] each-line ;
+
+: grep-file ( pattern filename -- )
+    ascii [ grep-lines ] with-file-reader ;
+
+: grep-usage ( -- )
+    "Usage: factor grep.factor <pattern> [<file>...]" print ;
+
+command-line get [
+    grep-usage
+] [
+    unclip <regexp> swap [
+        grep-lines
+    ] [
+        [ grep-file ] with each
+    ] if-empty
+] if-empty"> }
+"You can run it like so,"
+{ $code "./factor grep.factor '.*hello.*' myfile.txt" }
+"You'll notice this script takes a while to start. This is because it is loading and compiling the " { $vocab-link "regexp" } " vocabulary every time. To speed up startup, load the vocabulary into your image, and save the image:"
+{ $code "USE: regexp" "save" }
+"Now, the " { $snippet "grep.factor" } " script will start up much faster. See " { $link "images" } " for details."
+{ $heading "Executable scripts" }
+"It is also possible to make executable scripts. A Factor file can begin with a comment like the following:"
+{ $code "#! /usr/bin/env factor" }
+"If the text file is made executable, then it can be run, assuming the " { $snippet "factor" } " binary is in your " { $snippet "$PATH" } "."
 $nl
-"The space between " { $snippet "#!" } " and " { $snippet "/usr/bin/env" } " is necessary, since " { $link POSTPONE: #! } " is a parsing word, and a syntax error would otherwise result. The " { $snippet "-script" } " switch suppresses compiler messages, and exits Factor when the script finishes."
+"The space between " { $snippet "#!" } " and " { $snippet "/usr/bin/env" } " is necessary, since " { $link POSTPONE: #! } " is a parsing word, and a syntax error would otherwise result."
 { $references
     { }
     "cli"
     "cookbook-application"
+    "images"
 } ;
 
 ARTICLE: "cookbook-philosophy" "Factor philosophy"
index a3e38906871819ffcdce9353ba15c000608fc835..5d12438e0d4b1bdf459c0e94b1e4c29355ea295c 100644 (file)
@@ -155,10 +155,13 @@ help-hook global [ [ print-topic ] or ] change-at
     ":get  ( var -- value ) accesses variables at time of the error" print
     ":vars - list all variables at error time" print ;
 
-: :help ( -- )
-    error get error-help [ help ] [ "No help for this error. " print ] if*
+: (:help) ( error -- )
+    error-help [ help ] [ "No help for this error. " print ] if*
     :help-debugger ;
 
+: :help ( -- )
+    error get (:help) ;
+
 : remove-article ( name -- )
     dup articles get key? [
         dup unxref-article
index 6b90ba6937acb2294944ebd99123e05699346db1..a9df0bea811e49a37f554a217db98d8d387e8cdf 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.encodings.utf8 io.encodings.ascii io.encodings.binary
-io.files html.streams html.elements html.components help kernel
+io.files html.streams html.elements help kernel
 assocs sequences make words accessors arrays help.topics vocabs
 tools.vocabs tools.vocabs.browser namespaces prettyprint io
 vocabs.loader serialize fry memoize unicode.case math.order
@@ -104,10 +104,6 @@ MEMO: load-index ( name -- index )
 
 TUPLE: result title href ;
 
-M: result link-title title>> ;
-
-M: result link-href href>> ;
-
 : offline-apropos ( string index -- results )
     load-index swap >lower
     '[ [ drop _ ] dip >lower subseq? ] assoc-filter
index c7d505d86afbe24a08ed3a1c5dc5756c4340953f..0a392733acc12d02cc575a4ab8415e5ad383f4d2 100644 (file)
@@ -67,7 +67,7 @@ IN: help.lint
         vocab-exists? [ "$vocab-link to non-existent vocabulary" throw ] unless
     ] each ;
 
-: check-rendering ( word element -- )
+: check-rendering ( element -- )
     [ print-topic ] with-string-writer drop ;
 
 : all-word-help ( words -- seq )
@@ -87,13 +87,14 @@ M: help-error error.
 : check-word ( word -- )
     dup word-help [
         [
-            dup word-help [
-                2dup check-examples
-                2dup check-values
-                2dup check-see-also
-                2dup nip check-modules
-                2dup drop check-rendering
-            ] assert-depth 2drop
+            dup word-help '[
+                _ _ {
+                    [ check-examples ]
+                    [ check-values ]
+                    [ check-see-also ]
+                    [ [ check-rendering ] [ check-modules ] bi* ]
+                } 2cleave
+            ] assert-depth
         ] check-something
     ] [ drop ] if ;
 
@@ -101,9 +102,9 @@ M: help-error error.
 
 : check-article ( article -- )
     [
-        dup article-content [
-            2dup check-modules check-rendering
-        ] assert-depth 2drop
+        dup article-content
+        '[ _ check-rendering _ check-modules ]
+        assert-depth
     ] check-something ;
 
 : files>vocabs ( -- assoc )
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d4d7034a8fde4d63a3e33660ac64f111ae15a9d2 100644 (file)
@@ -0,0 +1 @@
+Help lint tool
index 899cad24042763dc227febd43edd2d9bd61008b6..a7501dc242615256f9d926c04a7930e7d4ecfc08 100644 (file)
@@ -97,7 +97,7 @@ ALIAS: $slot $snippet
     [
         snippet-style get [
             last-element off
-            >r ($code-style) r> with-nesting
+            [ ($code-style) ] dip with-nesting
         ] with-style
     ] ($block) ; inline
 
@@ -285,15 +285,16 @@ M: f ($instance)
 
 : $see ( element -- ) first [ see ] ($see) ;
 
-: $see-methods ( element -- ) first [ see-methods ] ($see) ;
-
 : $synopsis ( element -- ) first [ synopsis write ] ($see) ;
 
 : $definition ( element -- )
     "Definition" $heading $see ;
 
 : $methods ( element -- )
-    "Methods" $heading $see-methods ;
+    first methods [
+        "Methods" $heading
+        [ see-all ] ($see)
+    ] unless-empty ;
 
 : $value ( object -- )
     "Variable value" $heading
index 42d5ba1781e7cf2229d15a8f944f16bf1cd9b000..9a372174ba581d4f371111a56dfcfd3f79319f82 100644 (file)
@@ -11,9 +11,10 @@ IN: help.syntax
     \ ; parse-until >array swap set-word-help ; parsing
 
 : ARTICLE:
-    location >r
-    \ ; parse-until >array [ first2 ] keep 2 tail <article>
-    over add-article >link r> remember-definition ; parsing
+    location [
+        \ ; parse-until >array [ first2 ] keep 2 tail <article>
+        over add-article >link
+    ] dip remember-definition ; parsing
 
 : ABOUT:
     in get vocab
index afa16bbf8a966a610950614bdc51c0d9c64aae53..9ed36ac77cbf453e53c7c9ad930b23e4ca686894 100644 (file)
@@ -13,6 +13,8 @@ $nl
 { $code "\"resource:work\" \"palindrome\" scaffold-vocab" }
 "If you look at the output, you will see that a few files were created in your ``work'' directory. The following phrase will print the full path of your work directory:"
 { $code "\"work\" resource-path ." }
+"The work directory is one of several " { $link "vocabs.roots" } " where Factor searches for vocabularies. It is possible to define new vocabulary roots; see " { $link "add-vocab-roots" } ". To keep things simple in this tutorial, we'll just use the work directory, though."
+$nl
 "Open the work directory in your file manager, and open the subdirectory named " { $snippet "palindrome" } ". Inside this subdirectory you will see a file named " { $snippet "palindrome.factor" } ". We will be editing this file."
 $nl
 "Notice that the file ends with an " { $link POSTPONE: IN: } " form telling Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:"
index 347cfd3ef43f0120e785d864d1ef8cb2ed8dcd33..b8bda22ddc5889f855bb69e4e0364dcafbfc9a35 100644 (file)
@@ -1,10 +1,10 @@
 IN: hints
-USING: help.markup help.syntax words quotations sequences ;
+USING: help.markup help.syntax words quotations sequences kernel ;
 
 ARTICLE: "hints" "Compiler specialization hints"
 "Specialization hints help the compiler generate efficient code."
 $nl
-"Specialization hints can help words which call a lot of generic words on the same object - perhaps in a loop - and in most cases, it is anticipated that this object is of a certain class. Using specialization hints, the compiler can be instructed to compile a branch at the beginning of the word; if the branch is taken, the input object has the assumed class, and inlining of generic methods can take place."
+"Specialization hints can help words which call a lot of generic words on the same object - perhaps in a loop - and in most cases, it is anticipated that this object is of a certain class, or even " { $link eq? } " to some literal. Using specialization hints, the compiler can be instructed to compile a branch at the beginning of the word; if the branch is taken, the input object has the assumed class or value, and inlining of generic methods can take place."
 $nl
 "Specialization hints are not declarations; if the inputs do not match what is specified, the word will still run, possibly slower if the compiled code cannot inline methods because of insufficient static type information."
 $nl
@@ -20,10 +20,10 @@ HELP: specialized-def
 { $description "Outputs the definition of a word after it has been split into specialized branches. This is the definition which will actually be compiled by the compiler." } ;
 
 HELP: HINTS:
-{ $values { "defspec" "a definition specifier" } { "hints..." "a list of sequences of classes" } }
+{ $values { "defspec" "a definition specifier" } { "hints..." "a list of sequences of classes or literals" } }
 { $description "Defines specialization hints for a word or a method."
 $nl
-"Each sequence of classes in the list will cause a specialized version of the word to be compiled." }
+"Each sequence in the list will cause a specialized version of the word to be compiled. Classes are tested for using their predicate, and literals are tested using " { $link eq? } "." }
 { $examples "The " { $link append } " word has a specializer for the very common case where two strings or two arrays are appended:"
 { $code "HINTS: append { string string } { array array } ;" }
 "Specializers can also be defined on methods:"
index 06ca209caee2e86cca04003c09df9bea62ad0166..240acf74b1fa073672d34158b5f30fbe3f555402 100644 (file)
@@ -3,25 +3,34 @@
 USING: parser words definitions kernel sequences assocs arrays
 kernel.private fry combinators accessors vectors strings sbufs
 byte-arrays byte-vectors io.binary io.streams.string splitting
-math generic generic.standard generic.standard.engines ;
+math generic generic.standard generic.standard.engines classes ;
 IN: hints
 
-: (make-specializer) ( class picker -- quot )
-    swap "predicate" word-prop append ;
+GENERIC: specializer-predicate ( spec -- quot )
 
-: make-specializer ( classes -- quot )
+M: class specializer-predicate "predicate" word-prop ;
+
+M: object specializer-predicate '[ _ eq? ] ;
+
+GENERIC: specializer-declaration ( spec -- class )
+
+M: class specializer-declaration ;
+
+M: object specializer-declaration class ;
+
+: make-specializer ( specs -- quot )
     dup length <reversed>
     [ (picker) 2array ] 2map
     [ drop object eq? not ] assoc-filter
     [ [ t ] ] [
-        [ (make-specializer) ] { } assoc>map
+        [ swap specializer-predicate append ] { } assoc>map
         unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
     ] if-empty ;
 
 : specializer-cases ( quot word -- default alist )
     dup [ array? ] all? [ 1array ] unless [
         [ make-specializer ] keep
-        '[ _ declare ] pick append
+        [ specializer-declaration ] map '[ _ declare ] pick append
     ] { } map>assoc ;
 
 : method-declaration ( method -- quot )
index 0ee6955e292246889ec1bda71df4c225ba8147ff..fa92f18d3480e0e238fde94992c3991e8ed7965c 100644 (file)
@@ -24,7 +24,7 @@ SYMBOL: html
 : html-word ( name def effect -- )
     #! Define 'word creating' word to allow
     #! dynamically creating words.
-    >r >r elements-vocab create r> r> define-declared ;
+    [ elements-vocab create ] 2dip define-declared ;
 
 : <foo> ( str -- <str> ) "<" swap ">" 3append ;
 
index fa81a69bb403bfb4fc44cdcd9e8ad2b8b22041fe..709b65761e749448f42c345ea587a93a5fa8b154 100644 (file)
@@ -77,7 +77,7 @@ TUPLE: html-sub-stream < html-stream style parent ;
     "font-family: " % % "; " % ;
 
 : apply-style ( style key quot -- style gadget )
-    >r over at r> when* ; inline
+    [ over at ] dip when* ; inline
 
 : make-css ( style quot -- str )
     "" make nip ; inline
@@ -163,13 +163,13 @@ M: html-stream stream-flush
     stream>> stream-flush ;
 
 M: html-stream stream-write1
-    >r 1string r> stream-write ;
+    [ 1string ] dip stream-write ;
 
 M: html-stream stream-write
-    not-a-div >r escape-string r> stream>> stream-write ;
+    not-a-div [ escape-string ] dip stream>> stream-write ;
 
 M: html-stream stream-format
-    >r html over at [ >r escape-string r> ] unless r>
+    [ html over at [ [ escape-string ] dip ] unless ] dip
     format-html-span ;
 
 M: html-stream stream-nl
index da3f80e9a5d9c54440cab55f48b3066cb0f9db8c..73cc239a56de12a63b391214a042e514c2c3e07b 100644 (file)
@@ -4,6 +4,7 @@ USING: accessors kernel sequences combinators kernel fry
 namespaces make classes.tuple assocs splitting words arrays io
 io.files io.encodings.utf8 io.streams.string unicode.case
 mirrors math urls present multiline quotations xml logging
+continuations
 xml.data
 html.forms
 html.elements
index 4f2eaafe269698ab406850a19f818d4f14729cff..d4f34ab8aa969ef9ad8bb8ac0b395389b6113dad 100644 (file)
@@ -3,7 +3,7 @@
 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 ;
+html.templates html.templates.chloe.syntax continuations ;
 IN: html.templates.chloe.compiler
 
 : chloe-attrs-only ( assoc -- assoc' )
@@ -87,7 +87,7 @@ DEFER: compile-element
         { [ dup [ tag? ] [ xml? ] bi or ] [ compile-tag ] }
         { [ dup string? ] [ escape-string [write] ] }
         { [ dup comment? ] [ drop ] }
-        [ [ write-item ] [code-with] ]
+        [ [ write-xml-chunk ] [code-with] ]
     } cond ;
 
 : with-compiler ( quot -- quot' )
index 96320b7d125fcf8436bf64fd4bb92bf6122dea53..6e93d5ee3acbab7592cb6a1dea7b824d0c9ddf29 100644 (file)
@@ -2,7 +2,7 @@ USING: http http.server http.client tools.test multiline
 io.streams.string io.encodings.utf8 io.encodings.8-bit
 io.encodings.binary io.encodings.string kernel arrays splitting
 sequences assocs io.sockets db db.sqlite continuations urls
-hashtables accessors ;
+hashtables accessors namespaces ;
 IN: http.tests
 
 [ "text/plain" latin1 ] [ "text/plain" parse-content-type ] unit-test
@@ -11,6 +11,12 @@ IN: http.tests
 
 [ "application/octet-stream" binary ] [ "application/octet-stream" parse-content-type ] unit-test
 
+[ { } ] [ "" parse-cookie ] unit-test
+[ { } ] [ "" parse-set-cookie ] unit-test
+
+! Make sure that totally invalid cookies don't confuse us
+[ { } ] [ "hello world; how are you" parse-cookie ] unit-test
+
 : lf>crlf "\n" split "\r\n" join ;
 
 STRING: read-request-test-1
@@ -126,6 +132,7 @@ content-type: text/html; charset=UTF-8
 ;
 
 read-response-test-1' 1array [
+    URL" http://localhost/" url set
     read-response-test-1 lf>crlf
     [ read-response ] with-string-reader
     [ write-response ] with-string-writer
index c90a1872ce979068c24c2ab6d43369921caf906b..d006c86462c944f47680919cea2ed87cf5ba1191 100644 (file)
@@ -111,7 +111,7 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s
                 { [ dup real? ] [ number>string ] }
                 [ ]
             } cond
-            [ check-cookie-string ] bi@ "=" swap 3append ,
+            [ check-cookie-string ] bi@ "=" glue ,
         ]
     } case ;
 
index 8e8e7358d1602eb273084f08eb47b286c9ba63d6..d72147b3813caa854edae9b2d339cd18ad3f8b3c 100644 (file)
@@ -142,16 +142,15 @@ PEG: parse-header-line ( string -- pair )
         'space' ,
         'attr' ,
         'space' ,
-            [ "=" token , 'space' , 'value' , ] seq* [ peek ] action
-            epsilon [ drop f ] action
-        2choice ,
+        [ "=" token , 'space' , 'value' , ] seq* [ peek ] action optional ,
         'space' ,
     ] seq* ;
 
 : 'av-pairs' ( -- parser )
     'av-pair' ";" token list-of optional ;
 
-PEG: (parse-set-cookie) ( string -- alist ) 'av-pairs' just ;
+PEG: (parse-set-cookie) ( string -- alist )
+    'av-pairs' just [ sift ] action ;
 
 : 'cookie-value' ( -- parser )
     [
@@ -162,7 +161,10 @@ PEG: (parse-set-cookie) ( string -- alist ) 'av-pairs' just ;
         'space' ,
         'value' ,
         'space' ,
-    ] seq* ;
+    ] seq*
+    [ ";,=" member? not ] satisfy repeat1 [ drop f ] action
+    2choice ;
 
 PEG: (parse-cookie) ( string -- alist )
-    'cookie-value' [ ";," member? ] satisfy list-of optional just ;
+    'cookie-value' [ ";," member? ] satisfy list-of
+    optional just [ sift ] action ;
index 7b451d5266e29b485ba8b5f8bc9f719e2199a045..b47426f5bbd9ce140f69239f649baece62fde7ce 100644 (file)
@@ -49,10 +49,8 @@ SYMBOL: +editable+
     ] [ keys ] if ;
 
 : describe* ( obj mirror keys -- )
-    rot summary.
-    [
-        drop
-    ] [
+    [ summary. ] 2dip
+    [ drop ] [
         dup enum? [ +sequence+ on ] when
         standard-table-style [
             swap [ -rot describe-row ] curry each-index
index 005ae87746c33cdca26da4e7f2065be7e5d79822..c15debd9b546c193df96febfaeb88954d15056da 100644 (file)
@@ -1,4 +1,22 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test interpolate ;
+USING: interpolate io.streams.string namespaces tools.test locals ;
 IN: interpolate.tests
+
+[ "Hello, Jane." ] [
+    "Jane" "name" set
+    [ "Hello, ${name}." interpolate ] with-string-writer
+] unit-test
+
+[ "Sup Dawg, we heard you liked rims, so we put rims on your rims so you can roll while you roll." ] [
+    "Dawg" "name" set
+    "rims" "noun" set
+    "roll" "verb" set
+    [ "Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your ${noun} so you can ${verb} while you ${verb}." interpolate ] with-string-writer
+] unit-test
+
+[ "Oops, I accidentally the whole economy..." ] [
+    [let | noun [ "economy" ] |
+        [ I[ Oops, I accidentally the whole ${noun}...]I ] with-string-writer
+    ]
+] unit-test
index 27f0756f1f2eb6a124881ab68e9d2b90c826ad97..5e4805a8ac4ed825da2a9f5b6dc620d531cc2c87 100644 (file)
@@ -1,21 +1,40 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io kernel macros make multiline namespaces parser
-peg.ebnf present sequences strings ;
+present sequences strings splitting fry accessors ;
 IN: interpolate
 
+TUPLE: interpolate-var name ;
+
+: (parse-interpolate) ( string -- )
+    [
+        "${" split1-slice [ >string , ] [
+            [
+                "}" split1-slice
+                [ >string interpolate-var boa , ]
+                [ (parse-interpolate) ] bi*
+            ] when*
+        ] bi*
+    ] unless-empty ;
+
+: parse-interpolate ( string -- seq )
+    [ (parse-interpolate) ] { } make ;
+
 MACRO: interpolate ( string -- )
-[EBNF
-var = "${" [^}]+ "}" => [[ second >string [ get present write ] curry ]]
-text = [^$]+ => [[ >string [ write ] curry ]]
-interpolate = (var|text)* => [[ [ ] join ]]
-EBNF] ;
+    parse-interpolate [
+        dup interpolate-var?
+        [ name>> '[ _ get present write ] ]
+        [ '[ _ write ] ]
+        if
+    ] map [ ] join ;
 
-EBNF: interpolate-locals
-var = "${" [^}]+ "}" => [[ [ second >string search , [ present write ] % ] [ ] make ]]
-text = [^$]+ => [[ [ >string , [ write ] % ] [ ] make ]]
-interpolate = (var|text)* => [[ [ ] join ]]
-;EBNF
+: interpolate-locals ( string -- quot )
+    parse-interpolate [
+        dup interpolate-var?
+        [ name>> search '[ _ present write ] ]
+        [ '[ _ write ] ]
+        if
+    ] map [ ] join ;
 
 : I[ "]I" parse-multiline-string
     interpolate-locals parsed \ call parsed ; parsing
index 99da00ceab5fb62a62c21b16a60475ff46f99fec..34e43ddc7583729f804830f35233377e83e5b9cf 100644 (file)
@@ -15,7 +15,7 @@ TUPLE: interval-map array ;
     first2 between? ;\r
 \r
 : all-intervals ( sequence -- intervals )\r
-    [ >r dup number? [ dup 2array ] when r> ] { } assoc-map-as ;\r
+    [ [ dup number? [ dup 2array ] when ] dip ] { } assoc-map-as ;\r
 \r
 : disjoint? ( node1 node2 -- ? )\r
     [ second ] [ first ] bi* < ;\r
index b3c5c4ee905751ead7fb1d51e90d86aecfc2075d..4425e081069a5e198578910cca2f7af95e009130 100644 (file)
@@ -5,7 +5,7 @@ destructors ;
 
 : buffer-set ( string buffer -- )
     over >byte-array over ptr>> byte-array>memory
-    >r length r> buffer-reset ;
+    [ length ] dip buffer-reset ;
 
 : string>buffer ( string -- buffer )
     dup length <buffer> tuck buffer-set ;
index 037087e452ee6518591f39146a7d75154dfaa632..167d7534d101a6eab87fef09cf76ebf060ea4ab4 100644 (file)
@@ -25,7 +25,7 @@ ERROR: missing-bom ;
 : quad-be ( stream byte -- stream char )
     double-be over stream-read1 [
         dup -2 shift BIN: 110111 number= [
-            >r 2 shift r> BIN: 11 bitand bitor
+            [ 2 shift ] dip BIN: 11 bitand bitor
             over stream-read1 swap append-nums HEX: 10000 +
         ] [ 2drop dup stream-read1 drop replacement-char ] if
     ] when* ;
diff --git a/basis/io/files/listing/authors.txt b/basis/io/files/listing/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/io/files/listing/listing-docs.factor b/basis/io/files/listing/listing-docs.factor
deleted file mode 100644 (file)
index 6b19e9b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax io.streams.string strings ;
-IN: io.files.listing
-
-HELP: directory.
-{ $values
-     { "path" "a pathname string" }
-}
-{ $description "Prints information about all files in a directory to the output stream in a cross-platform way similar to the Unix " { $snippet "ls" } " command." } ;
-
-ARTICLE: "io.files.listing" "Listing files"
-"The " { $vocab-link "io.files.listing" } " vocabulary implements directory file listing in a cross-platform way." $nl
-"Listing a directory:"
-{ $subsection directory. } ;
-
-ABOUT: "io.files.listing"
diff --git a/basis/io/files/listing/listing-tests.factor b/basis/io/files/listing/listing-tests.factor
deleted file mode 100644 (file)
index 8c2dc28..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-! Copyright (C) 2008 Your name.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test io.files.listing strings kernel ;
-IN: io.files.listing.tests
-
-\ directory. must-infer
-
-[ ] [ "" directory. ] unit-test
diff --git a/basis/io/files/listing/listing.factor b/basis/io/files/listing/listing.factor
deleted file mode 100755 (executable)
index f88fcec..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays combinators io io.files kernel
-math.parser sequences system vocabs.loader calendar ;
-
-IN: io.files.listing
-
-<PRIVATE
-
-: ls-time ( timestamp -- string )
-    [ hour>> ] [ minute>> ] bi
-    [ number>string 2 CHAR: 0 pad-left ] bi@ ":" swap 3append ;
-
-: ls-timestamp ( timestamp -- string )
-    [ month>> month-abbreviation ]
-    [ day>> number>string 2 CHAR: \s pad-left ]
-    [
-        dup year>> dup now year>> =
-        [ drop ls-time ] [ nip number>string ] if
-        5 CHAR: \s pad-left
-    ] tri 3array " " join ;
-
-: read>string ( ? -- string ) "r" "-" ? ; inline
-
-: write>string ( ? -- string ) "w" "-" ? ; inline
-
-: execute>string ( ? -- string ) "x" "-" ? ; inline
-
-HOOK: (directory.) os ( path -- lines )
-
-PRIVATE>
-
-: directory. ( path -- )
-    [ (directory.) ] with-directory-files [ print ] each ;
-
-{
-    { [ os unix? ] [ "io.files.listing.unix" ] }
-    { [ os windows? ] [ "io.files.listing.windows" ] }
-} cond require
diff --git a/basis/io/files/listing/tags.txt b/basis/io/files/listing/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/listing/unix/authors.txt b/basis/io/files/listing/unix/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/io/files/listing/unix/tags.txt b/basis/io/files/listing/unix/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/listing/unix/unix.factor b/basis/io/files/listing/unix/unix.factor
deleted file mode 100755 (executable)
index bef8d3d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators kernel system unicode.case
-io.unix.files io.files.listing generalizations strings
-arrays sequences io.files math.parser unix.groups unix.users
-io.files.listing.private unix.stat math ;
-IN: io.files.listing.unix
-
-<PRIVATE
-
-: unix-execute>string ( str bools -- str' )
-    swap {
-        { { t t } [ >lower ] }
-        { { t f } [ >upper ] }
-        { { f t } [ drop "x" ] }
-        [ 2drop "-" ]
-    } case ;
-
-: permissions-string ( permissions -- str )
-    {
-        [ type>> file-type>ch 1string ]
-        [ user-read? read>string ]
-        [ user-write? write>string ]
-        [ [ uid? ] [ user-execute? ] bi 2array "s" unix-execute>string ]
-        [ group-read? read>string ]
-        [ group-write? write>string ]
-        [ [ gid? ] [ group-execute? ] bi 2array "s" unix-execute>string ]
-        [ other-read? read>string ]
-        [ other-write? write>string ]
-        [ [ sticky? ] [ other-execute? ] bi 2array "t" unix-execute>string ]
-    } cleave 10 narray concat ;
-
-: mode>symbol ( mode -- ch )
-    S_IFMT bitand
-    {
-        { [ dup S_IFDIR = ] [ drop "/" ] }
-        { [ dup S_IFIFO = ] [ drop "|" ] }
-        { [ dup any-execute? ] [ drop "*" ] }
-        { [ dup S_IFLNK = ] [ drop "@" ] }
-        { [ dup S_IFWHT = ] [ drop "%" ] }
-        { [ dup S_IFSOCK = ] [ drop "=" ] }
-        { [ t ] [ drop "" ] }
-    } cond ;
-
-M: unix (directory.) ( path -- lines )
-    [ [
-        [
-            dup file-info
-            {
-                [ permissions-string ]
-                [ nlink>> number>string 3 CHAR: \s pad-left ]
-                ! [ uid>> ]
-                ! [ gid>> ]
-                [ size>> number>string 15 CHAR: \s pad-left ]
-                [ modified>> ls-timestamp ]
-            } cleave 4 narray swap suffix " " join
-        ] map
-    ] with-group-cache ] with-user-cache ;
-
-PRIVATE>
diff --git a/basis/io/files/listing/windows/authors.txt b/basis/io/files/listing/windows/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/io/files/listing/windows/tags.txt b/basis/io/files/listing/windows/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/listing/windows/windows.factor b/basis/io/files/listing/windows/windows.factor
deleted file mode 100755 (executable)
index 33ab47a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors calendar.format combinators io.files
-kernel math.parser sequences splitting system io.files.listing
-generalizations io.files.listing.private ;
-IN: io.files.listing.windows
-
-<PRIVATE
-
-: directory-or-size ( file-info -- str )
-    dup directory? [
-        drop "<DIR>" 20 CHAR: \s pad-right
-    ] [
-        size>> number>string 20 CHAR: \s pad-left
-    ] if ;
-
-M: windows (directory.) ( entries -- lines )
-    [
-        dup file-info {
-            [ modified>> timestamp>ymdhms ]
-            [ directory-or-size ]
-        } cleave 2 narray swap suffix " " join
-    ] map ;
-
-PRIVATE>
diff --git a/basis/io/files/unique/backend/backend.factor b/basis/io/files/unique/backend/backend.factor
new file mode 100644 (file)
index 0000000..7b9809f
--- /dev/null
@@ -0,0 +1,5 @@
+USING: io.backend ;
+IN: io.files.unique.backend
+
+HOOK: (make-unique-file) io-backend ( path -- )
+HOOK: temporary-path io-backend ( -- path )
diff --git a/basis/io/files/unique/unique-docs.factor b/basis/io/files/unique/unique-docs.factor
new file mode 100644 (file)
index 0000000..825eb21
--- /dev/null
@@ -0,0 +1,38 @@
+USING: help.markup help.syntax io io.ports kernel math
+io.files.unique.private math.parser io.files ;
+IN: io.files.unique
+
+HELP: make-unique-file ( prefix suffix -- path )
+{ $values { "prefix" "a string" } { "suffix" "a string" }
+{ "path" "a pathname string" } }
+{ $description "Creates a file that is guaranteed not to exist in a platform-specific temporary directory. The file name is composed of a prefix, a number of random digits and letters, and the suffix. Returns the full pathname." }
+{ $errors "Throws an error if a new unique file cannot be created after a number of tries. The most likely error is incorrect directory permissions on the temporary directory." }
+{ $see-also with-unique-file } ;
+
+HELP: with-unique-file ( prefix suffix quot: ( path -- ) -- )
+{ $values { "prefix" "a string" } { "suffix" "a string" }
+{ "quot" "a quotation" } }
+{ $description "Creates a file with " { $link make-unique-file } " and calls the quotation with the path name on the stack." }
+{ $notes "The unique file will be deleted after calling this word." } ;
+
+HELP: make-unique-directory ( -- path )
+{ $values { "path" "a pathname string" } }
+{ $description "Creates a directory that is guaranteed not to exist in a platform-specific temporary directory and returns the full pathname." }
+{ $errors "Throws an error if the directory cannot be created after a number of tries. The most likely error is incorrect directory permissions on the temporary directory." }
+{ $see-also with-unique-directory } ;
+
+HELP: with-unique-directory ( quot -- )
+{ $values { "quot" "a quotation" } }
+{ $description "Creates a directory with " { $link make-unique-directory } " and calls the quotation with the pathname on the stack using the " { $link with-directory } " combinator. The quotation can access the " { $link current-directory } " symbol for the name of the temporary directory." }
+{ $notes "The directory will be deleted after calling this word, even if an error is thrown in the quotation." } ;
+
+ARTICLE: "io.files.unique" "Temporary files"
+"The " { $vocab-link "io.files.unique" } " vocabulary implements cross-platform temporary file creation in a high-level and secure way." $nl
+"Files:"
+{ $subsection make-unique-file }
+{ $subsection with-unique-file }
+"Directories:"
+{ $subsection make-unique-directory }
+{ $subsection with-unique-directory } ;
+
+ABOUT: "io.files.unique"
diff --git a/basis/io/files/unique/unique-tests.factor b/basis/io/files/unique/unique-tests.factor
new file mode 100644 (file)
index 0000000..178e457
--- /dev/null
@@ -0,0 +1,20 @@
+USING: io.encodings.ascii sequences strings io io.files accessors
+tools.test kernel io.files.unique namespaces continuations ;
+IN: io.files.unique.tests
+
+[ 123 ] [
+    "core" ".test" [
+        [ [ 123 CHAR: a <repetition> ] dip ascii set-file-contents ]
+        [ file-info size>> ] bi
+    ] with-unique-file
+] unit-test
+
+[ t ] [
+    [ current-directory get file-info directory? ] with-unique-directory
+] unit-test
+
+[ t ] [
+    current-directory get
+    [ [ "FAILDOG" throw ] with-unique-directory ] [ drop ] recover
+    current-directory get =
+] unit-test
diff --git a/basis/io/files/unique/unique.factor b/basis/io/files/unique/unique.factor
new file mode 100644 (file)
index 0000000..ec89517
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.bitwise math.parser
+random sequences continuations namespaces
+io.files io arrays io.files.unique.backend system
+combinators vocabs.loader fry ;
+IN: io.files.unique
+
+SYMBOL: unique-length
+SYMBOL: unique-retries
+
+10 unique-length set-global
+10 unique-retries set-global
+
+<PRIVATE
+
+: random-letter ( -- ch )
+    26 random { CHAR: a CHAR: A } random + ;
+
+: random-ch ( -- ch )
+    { t f } random
+    [ 10 random CHAR: 0 + ] [ random-letter ] if ;
+
+: random-name ( n -- string )
+    [ random-ch ] "" replicate-as ;
+
+PRIVATE>
+
+: make-unique-file ( prefix suffix -- path )
+    temporary-path -rot
+    [
+        unique-length get random-name glue append-path
+        dup (make-unique-file)
+    ] 3curry unique-retries get retry ;
+
+: with-unique-file ( prefix suffix quot: ( path -- ) -- )
+    [ make-unique-file ] dip [ delete-file ] bi ; inline
+
+: make-unique-directory ( -- path )
+    [
+        temporary-path unique-length get random-name append-path
+        dup make-directory
+    ] unique-retries get retry ;
+
+: with-unique-directory ( quot: ( -- ) -- )
+    [ make-unique-directory ] dip
+    '[ _ with-directory ] [ delete-tree ] bi ; inline
+
+{
+    { [ os unix? ] [ "io.unix.files.unique" ] }
+    { [ os windows? ] [ "io.windows.files.unique" ] }
+} cond require
index bdccfc3f5713375ac66349497b3fb233a3402d56..0ed10e63c3418330775c111090bcddce7293c596 100644 (file)
@@ -183,16 +183,18 @@ M: object run-pipeline-element
 
 : <process-reader*> ( desc encoding -- stream process )
     [
-        >r (pipe) {
-            [ |dispose drop ]
-            [
-                swap >process
-                    [ swap out>> or ] change-stdout
-                run-detached
-            ]
-            [ out>> dispose ]
-            [ in>> <input-port> ]
-        } cleave r> <decoder> swap
+        [
+            (pipe) {
+                [ |dispose drop ]
+                [
+                    swap >process
+                        [ swap out>> or ] change-stdout
+                    run-detached
+                ]
+                [ out>> dispose ]
+                [ in>> <input-port> ]
+            } cleave
+        ] dip <decoder> swap
     ] with-destructors ;
 
 : <process-reader> ( desc encoding -- stream )
@@ -205,16 +207,18 @@ M: object run-pipeline-element
 
 : <process-writer*> ( desc encoding -- stream process )
     [
-        >r (pipe) {
-            [ |dispose drop ]
-            [
-                swap >process
-                    [ swap in>> or ] change-stdin
-                run-detached
-            ]
-            [ in>> dispose ]
-            [ out>> <output-port> ]
-        } cleave r> <encoder> swap
+        [
+            (pipe) {
+                [ |dispose drop ]
+                [
+                    swap >process
+                        [ swap in>> or ] change-stdin
+                    run-detached
+                ]
+                [ in>> dispose ]
+                [ out>> <output-port> ]
+            } cleave
+        ] dip <encoder> swap
     ] with-destructors ;
 
 : <process-writer> ( desc encoding -- stream )
@@ -227,17 +231,19 @@ M: object run-pipeline-element
 
 : <process-stream*> ( desc encoding -- stream process )
     [
-        >r (pipe) (pipe) {
-            [ [ |dispose drop ] bi@ ]
-            [
-                rot >process
-                    [ swap in>> or ] change-stdin
-                    [ swap out>> or ] change-stdout
-                run-detached
-            ]
-            [ [ out>> dispose ] [ in>> dispose ] bi* ]
-            [ [ in>> <input-port> ] [ out>> <output-port> ] bi* ]
-        } 2cleave r> <encoder-duplex> swap
+        [
+            (pipe) (pipe) {
+                [ [ |dispose drop ] bi@ ]
+                [
+                    rot >process
+                        [ swap in>> or ] change-stdin
+                        [ swap out>> or ] change-stdout
+                    run-detached
+                ]
+                [ [ out>> dispose ] [ in>> dispose ] bi* ]
+                [ [ in>> <input-port> ] [ out>> <output-port> ] bi* ]
+            } 2cleave
+        ] dip <encoder-duplex> swap
     ] with-destructors ;
 
 : <process-stream> ( desc encoding -- stream )
@@ -254,23 +260,6 @@ M: object run-pipeline-element
     f >>handle
     drop ;
 
-GENERIC: underlying-handle ( stream -- handle )
-
-M: port underlying-handle handle>> ;
-
-ERROR: invalid-duplex-stream ;
-
-M: duplex-stream underlying-handle
-    [ in>> underlying-handle ]
-    [ out>> underlying-handle ] bi
-    [ = [ invalid-duplex-stream ] when ] keep ;
-
-M: encoder underlying-handle
-    stream>> underlying-handle ;
-
-M: decoder underlying-handle
-    stream>> underlying-handle ;
-
 {
     { [ os unix? ] [ "io.unix.launcher" require ] }
     { [ os winnt? ] [ "io.windows.nt.launcher" require ] }
diff --git a/basis/io/mmap/alien/alien.factor b/basis/io/mmap/alien/alien.factor
new file mode 100644 (file)
index 0000000..4b0a532
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.alien ;
+IN: io.mmap.alien
+
+<< "void*" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/bool/bool.factor b/basis/io/mmap/bool/bool.factor
new file mode 100644 (file)
index 0000000..a2b596f
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.bool ;
+IN: io.mmap.bool
+
+<< "bool" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/char/char.factor b/basis/io/mmap/char/char.factor
new file mode 100644 (file)
index 0000000..453e7e9
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.char ;
+IN: io.mmap.char
+
+<< "char" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/double/double.factor b/basis/io/mmap/double/double.factor
new file mode 100644 (file)
index 0000000..919c006
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.double ;
+IN: io.mmap.double
+
+<< "double" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/float/float.factor b/basis/io/mmap/float/float.factor
new file mode 100644 (file)
index 0000000..33cf16c
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.float ;
+IN: io.mmap.float
+
+<< "float" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/functor/functor.factor b/basis/io/mmap/functor/functor.factor
new file mode 100644 (file)
index 0000000..4587a75
--- /dev/null
@@ -0,0 +1,28 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.mmap functors accessors alien.c-types math kernel
+words fry ;
+IN: io.mmap.functor
+
+SLOT: address
+SLOT: length
+
+: mapped-file>direct ( mapped-file type -- alien length )
+    [ [ address>> ] [ length>> ] bi ] dip
+    heap-size [ 1- + ] keep /i ;
+
+FUNCTOR: define-mapped-array ( T -- )
+
+<mapped-A>         DEFINES <mapped-${T}-array>
+<A>                IS      <direct-${T}-array>
+with-mapped-A-file DEFINES with-mapped-${T}-file
+
+WHERE
+
+: <mapped-A> ( mapped-file -- direct-array )
+    T mapped-file>direct <A> execute ; inline
+
+: with-mapped-A-file ( path length quot -- )
+    '[ <mapped-A> execute @ ] with-mapped-file ; inline
+
+;FUNCTOR
diff --git a/basis/io/mmap/int/int.factor b/basis/io/mmap/int/int.factor
new file mode 100644 (file)
index 0000000..400e81e
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.int ;
+IN: io.mmap.int
+
+<< "int" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/long/long.factor b/basis/io/mmap/long/long.factor
new file mode 100644 (file)
index 0000000..190dd28
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.long ;
+IN: io.mmap.long
+
+<< "long" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/longlong/longlong.factor b/basis/io/mmap/longlong/longlong.factor
new file mode 100644 (file)
index 0000000..4d0a2aa
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.longlong ;
+IN: io.mmap.longlong
+
+<< "longlong" define-mapped-array >>
\ No newline at end of file
index 09922fc9290f5c8d9dd725ef0d6afae14ed4100d..bd971656d4dee588ad87866df4353db53fce1898 100644 (file)
@@ -11,13 +11,13 @@ HELP: mapped-file
 } ;
 
 HELP: <mapped-file>
-{ $values { "path" "a pathname string" } { "length" integer } { "mmap" mapped-file } }
-{ $contract "Opens a file and maps the first " { $snippet "length" } " bytes into memory. The length is permitted to exceed the length of the file on disk, in which case the remaining space is padded with zero bytes." }
-{ $notes "You must call " { $link close-mapped-file } " when you are finished working with the returned object, to reclaim resources. The " { $link with-mapped-file } " provides an abstraction which can close the mapped file for you." }
+{ $values { "path" "a pathname string" }  { "mmap" mapped-file } }
+{ $contract "Opens a file and maps its contents into memory. The length is permitted to exceed the length of the file on disk, in which case the remaining space is padded with zero bytes." }
+{ $notes "You must call " { $link dispose } " when you are finished working with the returned object, to reclaim resources. The " { $link with-mapped-file } " provides an abstraction which can close the mapped file for you." }
 { $errors "Throws an error if a memory mapping could not be established." } ;
 
 HELP: with-mapped-file
-{ $values { "path" "a pathname string" } { "length" integer } { "quot" { $quotation "( mmap -- )" } } }
+{ $values { "path" "a pathname string" } { "quot" { $quotation "( mmap -- )" } } }
 { $contract "Opens a file and maps its contents into memory, passing the " { $link mapped-file } " instance to the quotation. The mapped file is disposed of when the quotation returns, or if an error is thrown." }
 { $errors "Throws an error if a memory mapping could not be established." } ;
 
@@ -26,6 +26,33 @@ HELP: close-mapped-file
 { $contract "Releases system resources associated with the mapped file. This word should not be called by user code; use " { $link dispose } " instead." }
 { $errors "Throws an error if a memory mapping could not be established." } ;
 
+ARTICLE: "io.mmap.arrays" "Memory-mapped arrays"
+"Mapped file can be viewed as a sequence using the words in sub-vocabularies of " { $vocab-link "io.mmap" } ". For each primitive C type " { $snippet "T" } ", a set of words are defined in the vocabulary named " { $snippet "io.mmap.T" } ":"
+{ $table
+    { { $snippet "<mapped-T-array>" } { "Wraps a " { $link mapped-file } " in a sequence; stack effect " { $snippet "( mapped-file -- direct-array )" } } }
+    { { $snippet "with-mapped-T-file" } { "Maps a file into memory and wraps it in a sequence by combining " { $link with-mapped-file } " and " { $snippet "<mapped-T-array>" } "; stack effect " { $snippet "( path quot -- )" } } }
+}
+"The primitive C types for which mapped arrays exist:"
+{ $list
+    { $snippet "char" }
+    { $snippet "uchar" }
+    { $snippet "short" }
+    { $snippet "ushort" }
+    { $snippet "int" }
+    { $snippet "uint" }
+    { $snippet "long" }
+    { $snippet "ulong" }
+    { $snippet "longlong" }
+    { $snippet "ulonglong" }
+    { $snippet "float" }
+    { $snippet "double" }
+    { $snippet "void*" }
+    { $snippet "bool" }
+} ;
+
+ARTICLE: "io.mmap.low-level" "Reading and writing mapped files directly"
+"Data can be read and written from the " { $link mapped-file } " by applying low-level alien words to the " { $slot "address" } " slot. See " { $link "reading-writing-memory" } "." ;
+
 ARTICLE: "io.mmap" "Memory-mapped files"
 "The " { $vocab-link "io.mmap" } " vocabulary implements support for memory-mapped files."
 { $subsection <mapped-file> }
@@ -33,7 +60,8 @@ ARTICLE: "io.mmap" "Memory-mapped files"
 $nl
 "A utility combinator which wraps the above:"
 { $subsection with-mapped-file }
-"Memory mapped files implement the " { $link "sequence-protocol" } " and present themselves as a sequence of bytes. The underlying memory area can also be accessed directly with the " { $snippet "address" } " slot." $nl
-"Data can be read and written from the memory area using alien words. See " { $link "reading-writing-memory" } "." ;
+"Instances of " { $link mapped-file } " don't support any interesting operations in themselves. There are two facilities for accessing their contents:"
+{ $subsection "io.mmap.arrays" }
+{ $subsection "io.mmap.low-level" } ;
 
 ABOUT: "io.mmap"
index 57faca01c734e8812b01c436e26d64f8a3247da4..dc2f0b4687a76c48b5928ad803c8d2c34625e726 100644 (file)
@@ -1,10 +1,10 @@
-USING: io io.mmap io.files kernel tools.test continuations
-sequences io.encodings.ascii accessors ;
+USING: io io.mmap io.mmap.char io.files kernel tools.test
+continuations sequences io.encodings.ascii accessors ;
 IN: io.mmap.tests
 
 [ "mmap-test-file.txt" temp-file delete-file ] ignore-errors
 [ ] [ "12345" "mmap-test-file.txt" temp-file ascii set-file-contents ] unit-test
-[ ] [ "mmap-test-file.txt" temp-file dup file-info size>> [ CHAR: 2 0 pick set-nth drop ] with-mapped-file ] unit-test
-[ 5 ] [ "mmap-test-file.txt" temp-file dup file-info size>> [ length ] with-mapped-file ] unit-test
+[ ] [ "mmap-test-file.txt" temp-file [ CHAR: 2 0 pick set-nth drop ] with-mapped-char-file ] unit-test
+[ 5 ] [ "mmap-test-file.txt" temp-file [ length ] with-mapped-char-file ] unit-test
 [ "22345" ] [ "mmap-test-file.txt" temp-file ascii file-contents ] unit-test
 [ "mmap-test-file.txt" temp-file delete-file ] ignore-errors
index 01e7054ef1f3c670723aab54406a7079959c078d..3cf451bd036f432af4ae12aecbf38a691cd04164 100644 (file)
@@ -1,34 +1,24 @@
 ! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: continuations destructors io.backend kernel quotations
-sequences system alien alien.accessors accessors
-sequences.private system vocabs.loader combinators ;
+USING: continuations destructors io.files io.backend kernel
+quotations system alien alien.accessors accessors system
+vocabs.loader combinators alien.c-types ;
 IN: io.mmap
 
 TUPLE: mapped-file address handle length disposed ;
 
-M: mapped-file length dup check-disposed length>> ;
-
-M: mapped-file nth-unsafe
-    dup check-disposed address>> swap alien-unsigned-1 ;
-
-M: mapped-file set-nth-unsafe
-    dup check-disposed address>> swap set-alien-unsigned-1 ;
-
-INSTANCE: mapped-file sequence
-
 HOOK: (mapped-file) io-backend ( path length -- address handle )
 
-: <mapped-file> ( path length -- mmap )
-    [ >r normalize-path r> (mapped-file) ] keep
+: <mapped-file> ( path -- mmap )
+    [ normalize-path ] [ file-info size>> ] bi [ (mapped-file) ] keep
     f mapped-file boa ;
 
 HOOK: close-mapped-file io-backend ( mmap -- )
 
 M: mapped-file dispose* ( mmap -- ) close-mapped-file ;
 
-: with-mapped-file ( path length quot -- )
-    >r <mapped-file> r> with-disposal ; inline
+: with-mapped-file ( path quot -- )
+    [ <mapped-file> ] dip with-disposal ; inline
 
 {
     { [ os unix? ] [ "io.unix.mmap" require ] }
diff --git a/basis/io/mmap/short/short.factor b/basis/io/mmap/short/short.factor
new file mode 100644 (file)
index 0000000..add5815
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.short ;
+IN: io.mmap.short
+
+<< "short" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/uchar/uchar.factor b/basis/io/mmap/uchar/uchar.factor
new file mode 100644 (file)
index 0000000..d30fb60
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.uchar ;
+IN: io.mmap.uchar
+
+<< "uchar" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/uint/uint.factor b/basis/io/mmap/uint/uint.factor
new file mode 100644 (file)
index 0000000..926a0f4
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.uint ;
+IN: io.mmap.uint
+
+<< "uint" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/ulong/ulong.factor b/basis/io/mmap/ulong/ulong.factor
new file mode 100644 (file)
index 0000000..80f70b3
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.ulong ;
+IN: io.mmap.ulong
+
+<< "ulong" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/ulonglong/ulonglong.factor b/basis/io/mmap/ulonglong/ulonglong.factor
new file mode 100644 (file)
index 0000000..91f481c
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.ulonglong ;
+IN: io.mmap.ulonglong
+
+<< "ulonglong" define-mapped-array >>
\ No newline at end of file
diff --git a/basis/io/mmap/ushort/ushort.factor b/basis/io/mmap/ushort/ushort.factor
new file mode 100644 (file)
index 0000000..6d5ac01
--- /dev/null
@@ -0,0 +1,4 @@
+USING: io.mmap.functor specialized-arrays.direct.ushort ;
+IN: io.mmap.ushort
+
+<< "ushort" define-mapped-array >>
\ No newline at end of file
index 7f33f0caa69c62d7e27b1ac778355ee927e3ff92..72f2bc80c5d1be305770596b082ae5089b5dba52 100644 (file)
@@ -53,7 +53,7 @@ SYMBOL: +rename-file-new+
 SYMBOL: +rename-file+
 
 : with-monitor ( path recursive? quot -- )
-    >r <monitor> r> with-disposal ; inline
+    [ <monitor> ] dip with-disposal ; inline
 
 {
     { [ os macosx? ] [ "io.unix.macosx.monitors" require ] }
index 45979363c9d5110d19e13eb863e3a16277d2eefa..a96c6f04f14123723d0d97133b374bc1e4b700d5 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors sequences assocs arrays continuations
 destructors combinators kernel threads concurrency.messaging
 concurrency.mailboxes concurrency.promises io.files io.monitors
-debugger ;
+debugger fry ;
 IN: io.monitors.recursive
 
 ! Simulate recursive monitors on platforms that don't have them
@@ -29,10 +29,10 @@ DEFER: add-child-monitor
     qualify-path dup link-info directory? [
         [ add-child-monitors ]
         [
-            [
-                [ f my-mailbox (monitor) ] keep
+            '[
+                [ f my-mailbox (monitor) ] keep
                 monitor tget children>> set-at
-            ] curry ignore-errors
+            ] ignore-errors
         ] bi
     ] [ drop ] if ;
 
@@ -48,7 +48,7 @@ M: recursive-monitor dispose*
     monitor tget children>> [ nip dispose ] assoc-each ;
 
 : pump-step ( msg -- )
-    first3 path>> swap >r prepend-path r> monitor tget 3array
+    first3 path>> swap [ prepend-path ] dip monitor tget 3array
     monitor tget queue>>
     mailbox-put ;
 
@@ -71,9 +71,9 @@ M: recursive-monitor dispose*
 
 : pump-loop ( -- )
     receive dup synchronous? [
-        >r stop-pump t r> reply-synchronous
+        [ stop-pump t ] dip reply-synchronous
     ] [
-        [ [ update-hierarchy ] curry ignore-errors ] [ pump-step ] bi
+        [ '[ _ update-hierarchy ] ignore-errors ] [ pump-step ] bi
         pump-loop
     ] if ;
 
@@ -88,7 +88,7 @@ M: recursive-monitor dispose*
     pump-loop ;
 
 : start-pump-thread ( monitor -- )
-    dup [ pump-thread ] curry
+    dup '[ _ pump-thread ]
     "Recursive monitor pump" spawn
     >>thread drop ;
 
@@ -96,7 +96,7 @@ M: recursive-monitor dispose*
     ready>> ?promise ?linked drop ;
 
 : <recursive-monitor> ( path mailbox -- monitor )
-    >r (normalize-path) r>
+    [ (normalize-path) ] dip
     recursive-monitor new-monitor
         H{ } clone >>children
         <promise> >>ready
index ca4046fe0783abbb62cb86ddac4e44a82d14b604..3a7fa5a2e09366cf8163919729ae4c4578a7c639 100644 (file)
@@ -15,9 +15,10 @@ HOOK: (pipe) io-backend ( -- pipe )
 
 : <pipe> ( encoding -- stream )
     [
-        >r (pipe) |dispose
-        [ in>> <input-port> ] [ out>> <output-port> ] bi
-        r> <encoder-duplex>
+        [
+            (pipe) |dispose
+            [ in>> <input-port> ] [ out>> <output-port> ] bi
+        ] dip <encoder-duplex>
     ] with-destructors ;
 
 <PRIVATE
@@ -32,8 +33,7 @@ GENERIC: run-pipeline-element ( input-fd output-fd obj -- quot )
 
 M: callable run-pipeline-element
     [
-        >r [ ?reader ] [ ?writer ] bi*
-        r> with-streams*
+        [ [ ?reader ] [ ?writer ] bi* ] dip with-streams*
     ] with-destructors ;
 
 : <pipes> ( n -- pipes )
@@ -48,8 +48,8 @@ PRIVATE>
 : run-pipeline ( seq -- results )
     [ length dup zero? [ drop { } ] [ 1- <pipes> ] if ] keep
     [
-        >r [ first in>> ] [ second out>> ] bi
-        r> run-pipeline-element
+        [ [ first in>> ] [ second out>> ] bi ] dip
+        run-pipeline-element
     ] 2parallel-map ;
 
 {
index aa734e68094c552d56c7908e71aeb7e7824db7bd..2c1f8ea3c3632db3b188679af0c2fcea10c96452 100644 (file)
@@ -42,7 +42,7 @@ GENERIC: make-connection ( pool -- conn )
     [ nip call ] [ drop return-connection ] 3bi ; inline
 
 : with-pooled-connection ( pool quot -- )
-    >r [ acquire-connection ] keep r>
+    [ [ acquire-connection ] keep ] dip
     [ (with-pooled-connection) ] [ ] [ 2drop dispose ] cleanup ; inline
 
 M: return-connection dispose
index 9fb9755d4b16ee0d7f58c63e0a3d8d86b99ee2b4..0432fe4a396c6090b25c4584a698c957d789624b 100644 (file)
@@ -46,7 +46,7 @@ M: input-port stream-read1
 
 M: input-port stream-read-partial ( max stream -- byte-array/f )
     dup check-disposed
-    >r 0 max >integer r> read-step ;
+    [ 0 max >integer ] dip read-step ;
 
 : read-loop ( count port accum -- )
     pick over length - dup 0 > [
@@ -61,7 +61,7 @@ M: input-port stream-read-partial ( max stream -- byte-array/f )
 
 M: input-port stream-read
     dup check-disposed
-    >r 0 max >fixnum r>
+    [ 0 max >fixnum ] dip
     2dup read-step dup [
         pick over length > [
             pick <byte-vector>
@@ -76,21 +76,21 @@ M: input-port stream-read
 
 : read-until-loop ( seps port buf -- separator/f )
     2over read-until-step over [
-        >r over push-all r> dup [
-            >r 3drop r>
+        [ over push-all ] dip dup [
+            [ 3drop ] dip
         ] [
             drop read-until-loop
         ] if
     ] [
-        >r 2drop 2drop r>
+        [ 2drop 2drop ] dip
     ] if ;
 
 M: input-port stream-read-until ( seps port -- str/f sep/f )
-    2dup read-until-step dup [ >r 2nip r> ] [
+    2dup read-until-step dup [ [ 2drop ] 2dip ] [
         over [
             drop
             BV{ } like [ read-until-loop ] keep B{ } like swap
-        ] [ >r 2nip r> ] if
+        ] [ [ 2drop ] 2dip ] if
     ] if ;
 
 TUPLE: output-port < buffered-port ;
@@ -114,7 +114,7 @@ M: output-port stream-write
         [ [ stream-write ] curry ] bi
         each
     ] [
-        [ >r length r> wait-to-write ]
+        [ [ length ] dip wait-to-write ]
         [ buffer>> >buffer ] 2bi
     ] if ;
 
@@ -153,6 +153,18 @@ M: port dispose*
         bi
     ] with-destructors ;
 
+GENERIC: underlying-port ( stream -- port )
+
+M: port underlying-port ;
+
+M: encoder underlying-port stream>> underlying-port ;
+
+M: decoder underlying-port stream>> underlying-port ;
+
+GENERIC: underlying-handle ( stream -- handle )
+
+M: object underlying-handle underlying-port handle>> ;
+
 ! Fast-path optimization
 USING: hints strings io.encodings.utf8 io.encodings.ascii
 io.encodings.private ;
index b093840987d7545f5aea06c23c5cf4815faa1dc0..67c7cb13dda8a8d2075038828af63ff6ee46dbc3 100644 (file)
@@ -66,11 +66,11 @@ ARTICLE: "io.servers.connection" "Threaded servers"
 "Stopping the server:"
 { $subsection stop-server }
 "From within the dynamic scope of a client handler, several words can be used to interact with the threaded server:"
-{ $subsection remote-address }
 { $subsection stop-this-server }
 { $subsection secure-port }
 { $subsection insecure-port }
-"Additionally, the " { $link local-address } " variable is set, as in " { $link with-client } "." ;
+"Additionally, the " { $link local-address } " and "
+{ $subsection remote-address } " variables are set, as in " { $link with-client } "." ;
 
 ABOUT: "io.servers.connection"
 
index 942bdb041d6bd593089df516581132cabad1abe0..2d990e64835bab80f8b667ac7be2cb49fb79b6ef 100644 (file)
@@ -39,8 +39,6 @@ ready ;
 : <threaded-server> ( -- threaded-server )
     threaded-server new-threaded-server ;
 
-SYMBOL: remote-address
-
 GENERIC: handle-client* ( threaded-server -- )
 
 <PRIVATE
@@ -81,7 +79,7 @@ M: threaded-server handle-client* handler>> call ;
 \ handle-client ERROR add-error-logging
 
 : thread-name ( server-name addrspec -- string )
-    unparse-short " connection from " swap 3append ;
+    unparse-short " connection from " glue ;
 
 : accept-connection ( threaded-server -- )
     [ accept ] [ addr>> ] bi
index 632af969ca266b39af4f55e8503940b27b0eb1c3..01f64dfccfd061175de6b07a578ad377e0996e4e 100644 (file)
@@ -1,5 +1,5 @@
+USING: io help.markup help.syntax calendar quotations io.sockets ;
 IN: io.sockets.secure
-USING: help.markup help.syntax calendar quotations io.sockets ;
 
 HELP: secure-socket-timeout
 { $var-description "Timeout for operations not associated with a constructed port instance, such as SSL handshake and shutdown. Represented as a " { $link duration } "." } ;
@@ -99,6 +99,23 @@ $nl
 { $subsection <secure> }
 "Instances of this class can wrap an " { $link inet } ", " { $link inet4 } " or an " { $link inet6 } ", although note that certificate validation is only performed for instances of " { $link inet } " since otherwise the host name is not available." ;
 
+HELP: send-secure-handshake
+{ $contract "Upgrades the socket connection of the current " { $link with-client } " scope to a secure connection and initiates a SSL/TLS handshake." }
+{ $errors "Throws " { $link upgrade-on-non-socket } " or " { $link upgrade-buffers-full } " if used improperly." }
+{ $examples "This word is used by the " { $vocab-link "smtp" } " library to implement SMTP-TLS." } ;
+
+HELP: accept-secure-handshake
+{ $contract "Upgrades the socket connection stored in the " { $link input-stream } " and " { $link output-stream } " variables to a secure connection and waits for an SSL/TLS handshake." }
+{ $errors "Throws " { $link upgrade-on-non-socket } " or " { $link upgrade-buffers-full } " if used improperly." } ;
+
+ARTICLE: "ssl-upgrade" "Upgrading existing connections"
+"Some protocols, such as HTTPS, require that the connection be established as an SSL/TLS connection. Others, such as secure SMTP and POP3 require that the client and server initiate an SSL/TLS handshake upon the client sending a plain-text request. The latter use-case is accomodated by a pair of words."
+$nl
+"Upgrading a connection to a secure socket by initiating an SSL/TLS handshake with the server:"
+{ $subsection send-secure-handshake }
+"Upgrading a connection to a secure socket by waiting for an SSL/TLS handshake from the client:"
+{ $subsection accept-secure-handshake } ;
+
 HELP: premature-close
 { $error-description "Thrown if an SSL connection is closed without the proper " { $snippet "close_notify" } " sequence. This error is never reported for " { $link SSLv2 } " connections because there is no distinction between expected and unexpected connection closure in that case." } ;
 
@@ -106,20 +123,34 @@ HELP: certificate-verify-error
 { $error-description "Thrown if certificate verification failed. The " { $snippet "result" } " slot contains an object identifying the low-level error that occurred." } ;
 
 HELP: common-name-verify-error
-{ $error-description "Thrown during certificate verification if the host name on the certificate does not match the host name the socket was connected to. This indicates a potential man-in-the-middle attack. The " { $snippet "expected" } " and " { $snippet "got" } " slots contain the mismatched host names." } ;
+{ $error-description "Thrown during certificate verification if the host name on the certificate does not match the host name the socket was connected to. This indicates a potential man-in-the-middle attack. The " { $slot "expected" } " and " { $slot "got" } " slots contain the mismatched host names." } ;
+
+HELP: upgrade-on-non-socket
+{ $error-description "Thrown if " { $link send-secure-handshake } " or " { $link accept-secure-handshake } " is called with the " { $link input-stream } " and " { $link output-stream } " variables not set to a socket. This error can also indicate that the connection has already been upgraded to a secure connection." } ;
+
+HELP: upgrade-buffers-full
+{ $error-description "Thrown if " { $link send-secure-handshake } " or " { $link accept-secure-handshake } " is called when there is still data which hasn't been read or written." }
+{ $notes "Clients should ensure to " { $link flush } " their last command to the server before calling " { $link send-secure-handshake } "." } ;
 
 ARTICLE: "ssl-errors" "Secure socket errors"
 "Secure sockets can throw one of several errors in addition to the usual I/O errors:"
 { $subsection premature-close }
 { $subsection certificate-verify-error }
-{ $subsection common-name-verify-error } ;
+{ $subsection common-name-verify-error }
+"The " { $link send-secure-handshake } " word can throw one of two errors:"
+{ $subsection upgrade-on-non-socket }
+{ $subsection upgrade-buffers-full } ;
 
 ARTICLE: "io.sockets.secure" "Secure sockets (SSL, TLS)"
 "The " { $vocab-link "io.sockets.secure" } " vocabulary implements secure, encrypted sockets using the OpenSSL library."
+$nl
+"At present, this vocabulary only works on Unix, and not on Windows."
+$nl
+"This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (" { $url "http://www.openssl.org/" } "), cryptographic software written by Eric Young (eay@cryptsoft.com) and software written by Tim Hudson (tjh@cryptsoft.com)."
 { $subsection "ssl-config" }
 { $subsection "ssl-contexts" }
 { $subsection "ssl-addresses" }
-{ $subsection "ssl-errors" }
-"This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (" { $url "http://www.openssl.org/" } "), cryptographic software written by Eric Young (eay@cryptsoft.com) and software written by Tim Hudson (tjh@cryptsoft.com)." ;
+{ $subsection "ssl-upgrade" }
+{ $subsection "ssl-errors" } ;
 
 ABOUT: "io.sockets.secure"
index 42ca7276530e9f58f3160cdcf1c7fb7f2b2f4c62..e752e7c328d02d86425a7bfdc0ae3275afc3319a 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel symbols namespaces continuations
-destructors io.sockets sequences summary calendar delegate
-system vocabs.loader combinators present ;
+destructors io debugger io.sockets sequences summary calendar
+delegate system vocabs.loader combinators present ;
 IN: io.sockets.secure
 
 SYMBOL: secure-socket-timeout
@@ -52,10 +52,10 @@ M: secure resolve-host ( secure -- seq )
 
 HOOK: check-certificate secure-socket-backend ( host handle -- )
 
-<PRIVATE
-
 PREDICATE: secure-inet < secure addrspec>> inet? ;
 
+<PRIVATE
+
 M: secure-inet (client)
     [
         [ resolve-host (client) [ |dispose ] dip ] keep
@@ -79,6 +79,23 @@ ERROR: common-name-verify-error expected got ;
 M: common-name-verify-error summary
     drop "Common name verification failed" ;
 
+ERROR: upgrade-on-non-socket ;
+
+M: upgrade-on-non-socket summary
+    drop
+    "send-secure-handshake can only be used if input-stream and" print
+    "output-stream are a socket" ;
+
+ERROR: upgrade-buffers-full ;
+
+M: upgrade-buffers-full summary
+    drop
+    "send-secure-handshake can only be used if buffers are empty" ;
+
+HOOK: send-secure-handshake secure-socket-backend ( -- )
+
+HOOK: accept-secure-handshake secure-socket-backend ( -- )
+
 {
     { [ os unix? ] [ "io.unix.sockets.secure" require ] }
     { [ os windows? ] [ "openssl" require ] }
index 25401293f5c3130af4f333f308adf44962736d01..cfc33a02f6a29b0658cf276679cf14e44a2cea08 100644 (file)
@@ -105,7 +105,7 @@ HELP: <client>
 
 HELP: with-client
 { $values { "remote" "an address specifier" } { "encoding" "an encoding descriptor" } { "quot" quotation } }
-{ $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is bound to is stored in the " { $link local-address } " variable." }
+{ $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is connected to is stored in the " { $link local-address } " variable, and the remote address is stored in the " { $link remote-address } " variable." }
 { $errors "Throws an error if the connection cannot be established." } ;
 
 HELP: <server>
index c704382dd447ecc9eb8863c57a26f0ffe7bb1821..fbfae333c08b91eae2569caefcff96c3d999ab90 100644 (file)
@@ -6,7 +6,7 @@ sequences arrays io.encodings io.ports io.streams.duplex
 io.encodings.ascii alien.strings io.binary accessors destructors
 classes debugger byte-arrays system combinators parser
 alien.c-types math.parser splitting grouping math assocs summary
-system vocabs.loader combinators present ;
+system vocabs.loader combinators present fry ;
 IN: io.sockets
 
 << {
@@ -89,7 +89,7 @@ M: inet4 make-sockaddr ( inet -- sockaddr )
     rot inet-pton *uint over set-sockaddr-in-addr ;
 
 M: inet4 parse-sockaddr
-    >r dup sockaddr-in-addr <uint> r> inet-ntop
+    [ dup sockaddr-in-addr <uint> ] dip inet-ntop
     swap sockaddr-in-port ntohs <inet4> ;
 
 TUPLE: inet6 < abstract-inet ;
@@ -115,7 +115,7 @@ M: invalid-inet6 summary drop "Invalid IPv6 address" ;
 : pad-inet6 ( string1 string2 -- seq )
     2dup [ length ] bi@ + 8 swap -
     dup 0 < [ "More than 8 components" throw ] when
-    <byte-array> swap 3append ;
+    <byte-array> glue ;
 
 : inet6-bytes ( seq -- bytes )
     [ 2 >be ] { } map-as concat >byte-array ;
@@ -144,7 +144,7 @@ M: inet6 make-sockaddr ( inet -- sockaddr )
     rot inet-pton over set-sockaddr-in6-addr ;
 
 M: inet6 parse-sockaddr
-    >r dup sockaddr-in6-addr r> inet-ntop
+    [ dup sockaddr-in6-addr ] dip inet-ntop
     swap sockaddr-in6-port ntohs <inet6> ;
 
 : addrspec-of-family ( af -- addrspec )
@@ -184,7 +184,7 @@ M: object (client) ( remote -- client-in client-out local )
     [
         [ ((client)) ] keep
         [
-            >r <ports> [ |dispose ] bi@ dup r>
+            [ <ports> [ |dispose ] bi@ dup ] dip
             establish-connection
         ]
         [ get-local-address ]
@@ -192,13 +192,19 @@ M: object (client) ( remote -- client-in client-out local )
     ] with-destructors ;
 
 : <client> ( remote encoding -- stream local )
-    >r (client) -rot r> <encoder-duplex> swap ;
+    [ (client) -rot ] dip <encoder-duplex> swap ;
 
 SYMBOL: local-address
 
+SYMBOL: remote-address
+
 : with-client ( remote encoding quot -- )
-    >r <client> [ local-address set ] curry
-    r> compose with-stream ; inline
+    [
+        [
+            over remote-address set
+            <client> local-address set
+        ] dip with-stream
+    ] with-scope ; inline
 
 TUPLE: server-port < port addr encoding ;
 
@@ -209,10 +215,11 @@ TUPLE: server-port < port addr encoding ;
 GENERIC: (server) ( addrspec -- handle )
 
 : <server> ( addrspec encoding -- server )
-    >r
-    [ (server) ] keep
-    [ drop server-port <port> ] [ get-local-address ] 2bi
-    >>addr r> >>encoding ;
+    [
+        [ (server) ] keep
+        [ drop server-port <port> ] [ get-local-address ] 2bi
+        >>addr
+    ] dip >>encoding ;
 
 GENERIC: (accept) ( server addrspec -- handle sockaddr )
 
@@ -281,7 +288,7 @@ C: <inet> inet
     IPPROTO_TCP over set-addrinfo-protocol ;
 
 : fill-in-ports ( addrspecs port -- addrspecs )
-    [ >>port ] curry map ;
+    '[ _ >>port ] map ;
 
 M: inet resolve-host
     [ port>> ] [ host>> ] bi [
index 6f3be15016b5d0b6e0bb791f4433ba91ebe5a60a..9bf637432f1a6326e929f76604b66173230d8883 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel continuations destructors io io.encodings
-io.encodings.private io.timeouts debugger summary listener
-accessors delegate delegate.protocols ;
+io.encodings.private io.timeouts io.ports debugger summary
+listener accessors delegate delegate.protocols ;
 IN: io.streams.duplex
 
 TUPLE: duplex-stream in out ;
@@ -27,10 +27,18 @@ M: duplex-stream dispose
     ] with-destructors ;
 
 : <encoder-duplex> ( stream-in stream-out encoding -- duplex )
-    tuck re-encode >r re-decode r> <duplex-stream> ;
+    tuck [ re-decode ] [ re-encode ] 2bi* <duplex-stream> ;
 
 : with-stream* ( stream quot -- )
-    >r [ in>> ] [ out>> ] bi r> with-streams* ; inline
+    [ [ in>> ] [ out>> ] bi ] dip with-streams* ; inline
 
 : with-stream ( stream quot -- )
-    >r [ in>> ] [ out>> ] bi r> with-streams ; inline
+    [ [ in>> ] [ out>> ] bi ] dip with-streams ; inline
+
+ERROR: invalid-duplex-stream ;
+
+M: duplex-stream underlying-handle
+    [ in>> underlying-handle ]
+    [ out>> underlying-handle ] bi
+    [ = [ invalid-duplex-stream ] when ] keep ;
+
index 029cf6cac0a871b854ba3c286c6895e54fd8820d..fd1b14de19ff4fa755a5253b62b4fbfde282ff7f 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov, Doug Coleman\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: kernel calendar alarms io io.encodings accessors\r
-namespaces ;\r
+namespaces fry ;\r
 IN: io.timeouts\r
 \r
 GENERIC: timeout ( obj -- dt/f )\r
@@ -14,14 +14,14 @@ M: encoder set-timeout stream>> set-timeout ;
 GENERIC: cancel-operation ( obj -- )\r
 \r
 : queue-timeout ( obj timeout -- alarm )\r
-    >r [ cancel-operation ] curry r> later ;\r
+    [ '[ _ cancel-operation ] ] dip later ;\r
 \r
 : with-timeout* ( obj timeout quot -- )\r
-    3dup drop queue-timeout >r nip call r> cancel-alarm ;\r
+    3dup drop queue-timeout [ nip call ] dip cancel-alarm ;\r
     inline\r
 \r
 : with-timeout ( obj quot -- )\r
-    over timeout [ >r dup timeout r> with-timeout* ] [ call ] if ;\r
+    over timeout [ [ dup timeout ] dip with-timeout* ] [ call ] if ;\r
     inline\r
 \r
 : timeouts ( dt -- )\r
index 5bb0b825552d889c1ce094097fc04148b018a126..85363c8404c7274acd79f05f5b641ae9c7753593 100644 (file)
@@ -5,7 +5,7 @@ math io.ports sequences strings sbufs threads unix
 vectors io.buffers io.backend io.encodings math.parser
 continuations system libc qualified namespaces make io.timeouts
 io.encodings.utf8 destructors accessors summary combinators
-locals unix.time ;
+locals unix.time fry ;
 QUALIFIED: io
 IN: io.unix.backend
 
@@ -88,19 +88,16 @@ M: io-timeout summary drop "I/O operation timed out" ;
 
 : wait-for-fd ( handle event -- )
     dup +retry+ eq? [ 2drop ] [
-        [
-            >r
-            swap handle-fd
-            mx get-global
-            r> {
+        '[
+            swap handle-fd mx get-global _ {
                 { +input+ [ add-input-callback ] }
                 { +output+ [ add-output-callback ] }
             } case
-        ] curry "I/O" suspend nip [ io-timeout ] when
+        ] "I/O" suspend nip [ io-timeout ] when
     ] if ;
 
 : wait-for-port ( port event -- )
-    [ >r handle>> r> wait-for-fd ] curry with-timeout ;
+    '[ handle>> _ wait-for-fd ] with-timeout ;
 
 ! Some general stuff
 : file-mode OCT: 0666 ;
index 9fa1727e16c241dadd46f9b40e2e46a381dfdea5..1fc5fe92261b5770fb189e84c62589fb9949d65c 100644 (file)
@@ -6,7 +6,7 @@ math.bitwise byte-arrays alien combinators calendar
 io.encodings.binary accessors sequences strings system
 io.files.private destructors vocabs.loader calendar.unix
 unix.stat alien.c-types arrays unix.users unix.groups
-environment fry io.encodings.utf8 alien.strings unix.statfs
+environment fry io.encodings.utf8 alien.strings
 combinators.short-circuit ;
 IN: io.unix.files
 
@@ -76,15 +76,65 @@ M: unix copy-file ( from to -- )
     [ swap file-info permissions>> chmod io-error ]
     2bi ;
 
-HOOK: stat>file-info os ( stat -- file-info )
+TUPLE: unix-file-system-info < file-system-info
+block-size preferred-block-size
+blocks blocks-free blocks-available
+files files-free files-available
+name-max flags id ;
 
-HOOK: stat>type os ( stat -- file-info )
+HOOK: new-file-system-info os ( --  file-system-info )
+
+M: unix new-file-system-info ( -- ) unix-file-system-info new ;
+
+HOOK: file-system-statfs os ( path -- statfs )
+
+M: unix file-system-statfs drop f ;
+
+HOOK: file-system-statvfs os ( path -- statvfs )
+
+M: unix file-system-statvfs drop f ;
+
+HOOK: statfs>file-system-info os ( file-system-info statfs -- file-system-info' )
+
+M: unix statfs>file-system-info drop ;
+
+HOOK: statvfs>file-system-info os ( file-system-info statvfs -- file-system-info' )
+
+M: unix statvfs>file-system-info drop ;
+
+: file-system-calculations ( file-system-info -- file-system-info' )
+    {
+        [ dup [ blocks-available>> ] [ block-size>> ] bi * >>available-space drop ]
+        [ dup [ blocks-free>> ] [ block-size>> ] bi * >>free-space drop ]
+        [ dup [ blocks>> ] [ block-size>> ] bi * >>total-space drop ]
+        [ dup [ total-space>> ] [ free-space>> ] bi - >>used-space drop ]
+        [ ]
+    } cleave ;
 
-HOOK: new-file-info os ( -- class )
+M: unix file-system-info
+    normalize-path
+    [ new-file-system-info ] dip
+    [ file-system-statfs statfs>file-system-info ]
+    [ file-system-statvfs statvfs>file-system-info ] bi
+    file-system-calculations ;
+
+os {
+    { linux   [ "io.unix.files.linux"   require ] }
+    { macosx  [ "io.unix.files.macosx"  require ] }
+    { freebsd [ "io.unix.files.freebsd" require ] }
+    { netbsd  [ "io.unix.files.netbsd"  require ] }
+    { openbsd [ "io.unix.files.openbsd" require ] }
+} case
 
 TUPLE: unix-file-info < file-info uid gid dev ino
 nlink rdev blocks blocksize ;
 
+HOOK: new-file-info os ( -- file-info )
+
+HOOK: stat>file-info os ( stat -- file-info )
+
+HOOK: stat>type os ( stat -- file-info )
+
 M: unix file-info ( path -- info )
     normalize-path file-status stat>file-info ;
 
@@ -167,19 +217,23 @@ M: unix (directory-entries) ( path -- seq )
 
 : stat-mode ( path -- mode )
     normalize-path file-status stat-st_mode ;
-    
-: chmod-set-bit ( path mask ? -- ) 
-    [ dup stat-mode ] 2dip 
+
+: chmod-set-bit ( path mask ? -- )
+    [ dup stat-mode ] 2dip
     [ bitor ] [ unmask ] if chmod io-error ;
 
-: file-mode? ( path mask -- ? ) [ stat-mode ] dip mask? ;
+GENERIC# file-mode? 1 ( obj mask -- ? )
+
+M: integer file-mode? mask? ;
+M: string file-mode? [ stat-mode ] dip mask? ;
+M: file-info file-mode? [ permissions>> ] dip mask? ;
 
 PRIVATE>
 
 : ch>file-type ( ch -- type )
     {
         { CHAR: b [ +block-device+ ] }
-        { CHAR: c [ +character-device+ ] }   
+        { CHAR: c [ +character-device+ ] }
         { CHAR: d [ +directory+ ] }
         { CHAR: l [ +symbolic-link+ ] }
         { CHAR: s [ +socket+ ] }
@@ -205,29 +259,29 @@ PRIVATE>
 : STICKY        OCT: 0001000 ; inline
 : USER-ALL      OCT: 0000700 ; inline
 : USER-READ     OCT: 0000400 ; inline
-: USER-WRITE    OCT: 0000200 ; inline 
-: USER-EXECUTE  OCT: 0000100 ; inline   
+: USER-WRITE    OCT: 0000200 ; inline
+: USER-EXECUTE  OCT: 0000100 ; inline
 : GROUP-ALL     OCT: 0000070 ; inline
-: GROUP-READ    OCT: 0000040 ; inline 
-: GROUP-WRITE   OCT: 0000020 ; inline  
-: GROUP-EXECUTE OCT: 0000010 ; inline    
+: GROUP-READ    OCT: 0000040 ; inline
+: GROUP-WRITE   OCT: 0000020 ; inline
+: GROUP-EXECUTE OCT: 0000010 ; inline
 : OTHER-ALL     OCT: 0000007 ; inline
 : OTHER-READ    OCT: 0000004 ; inline
-: OTHER-WRITE   OCT: 0000002 ; inline  
-: OTHER-EXECUTE OCT: 0000001 ; inline    
-
-GENERIC: uid? ( obj -- ? )
-GENERIC: gid? ( obj -- ? )
-GENERIC: sticky? ( obj -- ? )
-GENERIC: user-read? ( obj -- ? )
-GENERIC: user-write? ( obj -- ? )
-GENERIC: user-execute? ( obj -- ? )
-GENERIC: group-read? ( obj -- ? )
-GENERIC: group-write? ( obj -- ? )
-GENERIC: group-execute? ( obj -- ? )
-GENERIC: other-read? ( obj -- ? )
-GENERIC: other-write? ( obj -- ? )
-GENERIC: other-execute? ( obj -- ? )
+: OTHER-WRITE   OCT: 0000002 ; inline
+: OTHER-EXECUTE OCT: 0000001 ; inline
+
+: uid? ( obj -- ? ) UID file-mode? ;
+: gid? ( obj -- ? ) GID file-mode? ;
+: sticky? ( obj -- ? ) STICKY file-mode? ;
+: user-read? ( obj -- ? ) USER-READ file-mode? ;
+: user-write? ( obj -- ? ) USER-WRITE file-mode? ;
+: user-execute? ( obj -- ? ) USER-EXECUTE file-mode? ;
+: group-read? ( obj -- ? ) GROUP-READ file-mode? ;
+: group-write? ( obj -- ? ) GROUP-WRITE file-mode? ;
+: group-execute? ( obj -- ? ) GROUP-EXECUTE file-mode? ;
+: other-read? ( obj -- ? ) OTHER-READ file-mode? ;
+: other-write? ( obj -- ? ) OTHER-WRITE file-mode? ;
+: other-execute? ( obj -- ? ) OTHER-EXECUTE file-mode? ;
 
 : any-read? ( obj -- ? )
     { [ user-read? ] [ group-read? ] [ other-read? ] } 1|| ;
@@ -238,56 +292,17 @@ GENERIC: other-execute? ( obj -- ? )
 : any-execute? ( obj -- ? )
     { [ user-execute? ] [ group-execute? ] [ other-execute? ] } 1|| ;
 
-M: integer uid? ( integer -- ? ) UID mask? ;
-M: integer gid? ( integer -- ? ) GID mask? ;
-M: integer sticky? ( integer -- ? ) STICKY mask? ;
-M: integer user-read? ( integer -- ? ) USER-READ mask? ;
-M: integer user-write? ( integer -- ? ) USER-WRITE mask? ;
-M: integer user-execute? ( integer -- ? ) USER-EXECUTE mask? ;
-M: integer group-read? ( integer -- ? ) GROUP-READ mask? ;
-M: integer group-write? ( integer -- ? ) GROUP-WRITE mask? ;
-M: integer group-execute? ( integer -- ? ) GROUP-EXECUTE mask? ;
-M: integer other-read? ( integer -- ? ) OTHER-READ mask? ;
-M: integer other-write? ( integer -- ? ) OTHER-WRITE mask? ; 
-M: integer other-execute? ( integer -- ? ) OTHER-EXECUTE mask? ;
-
-M: file-info uid? ( file-info -- ? ) permissions>> uid? ;
-M: file-info gid? ( file-info -- ? ) permissions>> gid? ;
-M: file-info sticky? ( file-info -- ? ) permissions>> sticky? ;
-M: file-info user-read? ( file-info -- ? ) permissions>> user-read? ;
-M: file-info user-write? ( file-info -- ? ) permissions>> user-write? ;
-M: file-info user-execute? ( file-info -- ? ) permissions>> user-execute? ;
-M: file-info group-read? ( file-info -- ? ) permissions>> group-read? ;
-M: file-info group-write? ( file-info -- ? ) permissions>> group-write? ;
-M: file-info group-execute? ( file-info -- ? ) permissions>> group-execute? ;
-M: file-info other-read? ( file-info -- ? ) permissions>> other-read? ;
-M: file-info other-write? ( file-info -- ? ) permissions>> other-write? ;
-M: file-info other-execute? ( file-info -- ? ) permissions>> other-execute? ;
-
-M: string uid? ( path -- ? ) UID file-mode? ;
-M: string gid? ( path -- ? ) GID file-mode? ;
-M: string sticky? ( path -- ? ) STICKY file-mode? ;
-M: string user-read? ( path -- ? ) USER-READ file-mode? ;
-M: string user-write? ( path -- ? ) USER-WRITE file-mode? ;
-M: string user-execute? ( path -- ? ) USER-EXECUTE file-mode? ;
-M: string group-read? ( path -- ? ) GROUP-READ file-mode? ;
-M: string group-write? ( path -- ? ) GROUP-WRITE file-mode? ;
-M: string group-execute? ( path -- ? ) GROUP-EXECUTE file-mode? ;
-M: string other-read? ( path -- ? ) OTHER-READ file-mode? ;
-M: string other-write? ( path -- ? ) OTHER-WRITE file-mode? ; 
-M: string other-execute? ( path -- ? ) OTHER-EXECUTE file-mode? ;
-
 : set-uid ( path ? -- ) UID swap chmod-set-bit ;
 : set-gid ( path ? -- ) GID swap chmod-set-bit ;
 : set-sticky ( path ? -- ) STICKY swap chmod-set-bit ;
 : set-user-read ( path ? -- ) USER-READ swap chmod-set-bit ;
-: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ; 
+: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ;
 : set-user-execute ( path ? -- ) USER-EXECUTE swap chmod-set-bit ;
 : set-group-read ( path ? -- ) GROUP-READ swap chmod-set-bit ;
-: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ; 
+: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ;
 : set-group-execute ( path ? -- ) GROUP-EXECUTE swap chmod-set-bit ;
 : set-other-read ( path ? -- ) OTHER-READ swap chmod-set-bit ;
-: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ; 
+: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ;
 : set-other-execute ( path ? -- ) OTHER-EXECUTE swap chmod-set-bit ;
 
 : set-file-permissions ( path n -- )
@@ -299,8 +314,7 @@ M: string other-execute? ( path -- ? ) OTHER-EXECUTE file-mode? ;
 <PRIVATE
 
 : make-timeval-array ( array -- byte-array )
-    [ length "timeval" <c-array> ] keep
-    dup length [ over [ pick set-timeval-nth ] [ 2drop ] if ] 2each ;
+    [ [ "timeval" <c-object> ] unless* ] map concat ;
 
 : timestamp>timeval ( timestamp -- timeval )
     unix-1970 time- duration>microseconds make-timeval ;
@@ -334,10 +348,10 @@ M: integer set-file-user ( path uid -- )
 
 M: string set-file-user ( path string -- )
     user-id f set-file-ids ;
-    
+
 M: integer set-file-group ( path gid -- )
     f swap set-file-ids ;
-    
+
 M: string set-file-group ( path string -- )
     group-id
     f swap set-file-ids ;
diff --git a/basis/io/unix/files/freebsd/freebsd.factor b/basis/io/unix/files/freebsd/freebsd.factor
new file mode 100644 (file)
index 0000000..3786a82
--- /dev/null
@@ -0,0 +1,54 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types alien.syntax combinators
+io.backend io.files io.unix.files kernel math system unix
+unix.statfs.freebsd unix.statvfs.freebsd unix.getfsstat.freebsd
+sequences grouping alien.strings io.encodings.utf8 ;
+IN: io.unix.files.freebsd
+
+TUPLE: freebsd-file-system-info < unix-file-system-info
+version io-size owner syncreads syncwrites asyncreads asyncwrites ;
+
+M: freebsd new-file-system-info freebsd-file-system-info new ;
+
+M: freebsd file-system-statfs ( path -- byte-array )
+    "statfs" <c-object> tuck statfs io-error ;
+
+M: freebsd statfs>file-system-info ( file-system-info statvfs -- file-system-info )
+    {
+        [ statfs-f_version >>version ]
+        [ statfs-f_type >>type ]
+        [ statfs-f_flags >>flags ]
+        [ statfs-f_bsize >>block-size ]
+        [ statfs-f_iosize >>io-size ]
+        [ statfs-f_blocks >>blocks ]
+        [ statfs-f_bfree >>blocks-free ]
+        [ statfs-f_bavail >>blocks-available ]
+        [ statfs-f_files >>files ]
+        [ statfs-f_ffree >>files-free ]
+        [ statfs-f_syncwrites >>syncwrites ]
+        [ statfs-f_asyncwrites >>asyncwrites ]
+        [ statfs-f_syncreads >>syncreads ]
+        [ statfs-f_asyncreads >>asyncreads ]
+        [ statfs-f_namemax >>name-max ]
+        [ statfs-f_owner >>owner ]
+        [ statfs-f_fsid >>id ]
+        [ statfs-f_fstypename utf8 alien>string >>type ]
+        [ statfs-f_mntfromname utf8 alien>string >>device-name ]
+        [ statfs-f_mntonname utf8 alien>string >>mount-point ]
+    } cleave ;
+
+M: freebsd file-system-statvfs ( path -- byte-array )
+    "statvfs" <c-object> tuck statvfs io-error ;
+
+M: freebsd statvfs>file-system-info ( file-system-info statvfs -- file-system-info )
+    {
+        [ statvfs-f_favail >>files-available ]
+        [ statvfs-f_frsize >>preferred-block-size ]
+    } cleave ;
+
+M: freebsd file-systems ( -- array )
+    f 0 0 getfsstat dup io-error
+    "statfs" <c-array> dup dup length 0 getfsstat io-error
+    "statfs" heap-size group
+    [ statfs-f_mntonname alien>native-string file-system-info ] map ;
diff --git a/basis/io/unix/files/freebsd/tags.txt b/basis/io/unix/files/freebsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/unix/files/linux/linux.factor b/basis/io/unix/files/linux/linux.factor
new file mode 100644 (file)
index 0000000..3e4e1c0
--- /dev/null
@@ -0,0 +1,89 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types alien.syntax combinators csv
+io.backend io.encodings.utf8 io.files io.streams.string
+io.unix.files kernel math.order namespaces sequences sorting
+system unix unix.statfs.linux unix.statvfs.linux ;
+IN: io.unix.files.linux
+
+TUPLE: linux-file-system-info < unix-file-system-info
+namelen ;
+
+M: linux new-file-system-info linux-file-system-info new ;
+
+M: linux file-system-statfs ( path -- byte-array )
+    "statfs64" <c-object> tuck statfs64 io-error ;
+
+M: linux statfs>file-system-info ( struct -- statfs )
+    {
+        [ statfs64-f_type >>type ]
+        [ statfs64-f_bsize >>block-size ]
+        [ statfs64-f_blocks >>blocks ]
+        [ statfs64-f_bfree >>blocks-free ]
+        [ statfs64-f_bavail >>blocks-available ]
+        [ statfs64-f_files >>files ]
+        [ statfs64-f_ffree >>files-free ]
+        [ statfs64-f_fsid >>id ]
+        [ statfs64-f_namelen >>namelen ]
+        [ statfs64-f_frsize >>preferred-block-size ]
+        ! [ statfs64-f_spare >>spare ]
+    } cleave ;
+
+M: linux file-system-statvfs ( path -- byte-array )
+    "statvfs64" <c-object> tuck statvfs64 io-error ;
+
+M: linux statvfs>file-system-info ( struct -- statfs )
+    {
+        [ statvfs64-f_flag >>flags ]
+        [ statvfs64-f_namemax >>name-max ]
+    } cleave ;
+
+TUPLE: mtab-entry file-system-name mount-point type options
+frequency pass-number ;
+
+: mtab-csv>mtab-entry ( csv -- mtab-entry )
+    [ mtab-entry new ] dip
+    {
+        [ first >>file-system-name ]
+        [ second >>mount-point ]
+        [ third >>type ]
+        [ fourth <string-reader> csv first >>options ]
+        [ 4 swap nth >>frequency ]
+        [ 5 swap nth >>pass-number ]
+    } cleave ;
+
+: parse-mtab ( -- array )
+    [
+        "/etc/mtab" utf8 <file-reader>
+        CHAR: \s delimiter set csv
+    ] with-scope
+    [ mtab-csv>mtab-entry ] map ;
+
+M: linux file-systems
+    parse-mtab [
+        [ mount-point>> file-system-info ] keep
+        {
+            [ file-system-name>> >>device-name ]
+            [ mount-point>> >>mount-point ]
+            [ type>> >>type ]
+        } cleave
+    ] map ;
+
+ERROR: file-system-not-found ;
+
+M: linux file-system-info ( path -- )
+    normalize-path
+    [
+        [ new-file-system-info ] dip
+        [ file-system-statfs statfs>file-system-info ]
+        [ file-system-statvfs statvfs>file-system-info ] bi
+        file-system-calculations
+    ] keep
+    
+    parse-mtab [ [ mount-point>> ] bi@ <=> invert-comparison ] sort
+    [ mount-point>> head? ] with find nip [ file-system-not-found ] unless*
+    {
+        [ file-system-name>> >>device-name drop ]
+        [ mount-point>> >>mount-point drop ]
+        [ type>> >>type ]
+    } 2cleave ;
diff --git a/basis/io/unix/files/linux/tags.txt b/basis/io/unix/files/linux/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/unix/files/macosx/macosx.factor b/basis/io/unix/files/macosx/macosx.factor
new file mode 100644 (file)
index 0000000..5b12814
--- /dev/null
@@ -0,0 +1,50 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types alien.strings combinators
+grouping io.encodings.utf8 io.files kernel math sequences
+system unix io.unix.files
+unix.statfs.macosx unix.statvfs.macosx unix.getfsstat.macosx ;
+IN: io.unix.files.macosx
+
+TUPLE: macosx-file-system-info < unix-file-system-info
+io-size owner type-id filesystem-subtype ;
+
+M: macosx file-systems ( -- array )
+    f <void*> dup 0 getmntinfo64 dup io-error
+    [ *void* ] dip
+    "statfs64" heap-size [ * memory>byte-array ] keep group
+    [ [ new-file-system-info ] dip statfs>file-system-info ] map ;
+
+M: macosx new-file-system-info macosx-file-system-info new ;
+
+M: macosx file-system-statfs ( normalized-path -- statfs )
+    "statfs64" <c-object> tuck statfs64 io-error ;
+
+M: macosx file-system-statvfs ( normalized-path -- statvfs )
+    "statvfs" <c-object> tuck statvfs io-error ;
+
+M: macosx statfs>file-system-info ( file-system-info byte-array -- file-system-info' )
+    {
+        [ statfs64-f_bsize >>block-size ]
+        [ statfs64-f_iosize >>io-size ]
+        [ statfs64-f_blocks >>blocks ]
+        [ statfs64-f_bfree >>blocks-free ]
+        [ statfs64-f_bavail >>blocks-available ]
+        [ statfs64-f_files >>files ]
+        [ statfs64-f_ffree >>files-free ]
+        [ statfs64-f_fsid >>id ]
+        [ statfs64-f_owner >>owner ]
+        [ statfs64-f_type >>type-id ]
+        [ statfs64-f_flags >>flags ]
+        [ statfs64-f_fssubtype >>filesystem-subtype ]
+        [ statfs64-f_fstypename utf8 alien>string >>type ]
+        [ statfs64-f_mntonname utf8 alien>string >>mount-point ]
+        [ statfs64-f_mntfromname utf8 alien>string >>device-name ]
+    } cleave ;
+
+M: macosx statvfs>file-system-info ( file-system-info byte-array -- file-system-info' )
+    {
+        [ statvfs-f_frsize >>preferred-block-size ]
+        [ statvfs-f_favail >>files-available ]
+        [ statvfs-f_namemax >>name-max ]
+    } cleave ;
diff --git a/basis/io/unix/files/macosx/tags.txt b/basis/io/unix/files/macosx/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/unix/files/netbsd/netbsd.factor b/basis/io/unix/files/netbsd/netbsd.factor
new file mode 100644 (file)
index 0000000..23717b4
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax kernel unix.stat math unix
+combinators system io.backend accessors alien.c-types
+io.encodings.utf8 alien.strings unix.types io.unix.files
+io.files unix.statvfs.netbsd unix.getfsstat.netbsd
+grouping sequences io.encodings.utf8 ;
+IN: io.unix.files.netbsd
+
+TUPLE: netbsd-file-system-info < unix-file-system-info
+blocks-reserved files-reserved
+owner io-size sync-reads sync-writes async-reads async-writes
+idx mount-from ;
+
+M: netbsd new-file-system-info netbsd-file-system-info new ;
+
+M: netbsd file-system-statvfs
+    "statvfs" <c-object> tuck statvfs io-error ;
+
+M: netbsd statvfs>file-system-info ( file-system-info statvfs -- file-system-info' )
+    {
+        [ statvfs-f_flag >>flags ]
+        [ statvfs-f_bsize >>block-size ]
+        [ statvfs-f_frsize >>preferred-block-size ]
+        [ statvfs-f_iosize >>io-size ]
+        [ statvfs-f_blocks >>blocks ]
+        [ statvfs-f_bfree >>blocks-free ]
+        [ statvfs-f_bavail >>blocks-available ]
+        [ statvfs-f_bresvd >>blocks-reserved ]
+        [ statvfs-f_files >>files ]
+        [ statvfs-f_ffree >>files-free ]
+        [ statvfs-f_favail >>files-available ]
+        [ statvfs-f_fresvd >>files-reserved ]
+        [ statvfs-f_syncreads >>sync-reads ]
+        [ statvfs-f_syncwrites >>sync-writes ]
+        [ statvfs-f_asyncreads >>async-reads ]
+        [ statvfs-f_asyncwrites >>async-writes ]
+        [ statvfs-f_fsidx >>idx ]
+        [ statvfs-f_fsid >>id ]
+        [ statvfs-f_namemax >>name-max ]
+        [ statvfs-f_owner >>owner ]
+        ! [ statvfs-f_spare >>spare ]
+        [ statvfs-f_fstypename utf8 alien>string >>type ]
+        [ statvfs-f_mntonname utf8 alien>string >>mount-point ]
+        [ statvfs-f_mntfromname utf8 alien>string >>device-name ]
+    } cleave ;
+
+M: netbsd file-systems ( -- array )
+    f 0 0 getvfsstat dup io-error
+    "statvfs" <c-array> dup dup length 0 getvfsstat io-error
+    "statvfs" heap-size group
+    [ statvfs-f_mntonname utf8 alien>string file-system-info ] map ;
diff --git a/basis/io/unix/files/netbsd/tags.txt b/basis/io/unix/files/netbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/unix/files/openbsd/openbsd.factor b/basis/io/unix/files/openbsd/openbsd.factor
new file mode 100644 (file)
index 0000000..8c8f7c1
--- /dev/null
@@ -0,0 +1,54 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types alien.strings alien.syntax
+combinators io.backend io.files io.unix.files kernel math
+sequences system unix unix.getfsstat.openbsd grouping
+unix.statfs.openbsd unix.statvfs.openbsd unix.types ;
+IN: io.unix.files.openbsd
+
+TUPLE: freebsd-file-system-info < unix-file-system-info
+io-size sync-writes sync-reads async-writes async-reads 
+owner ;
+
+M: openbsd new-file-system-info freebsd-file-system-info new ;
+
+M: openbsd file-system-statfs
+    "statfs" <c-object> tuck statfs io-error ;
+
+M: openbsd statfs>file-system-info ( file-system-info statfs -- file-system-info' )
+    {
+        [ statfs-f_flags >>flags ]
+        [ statfs-f_bsize >>block-size ]
+        [ statfs-f_iosize >>io-size ]
+        [ statfs-f_blocks >>blocks ]
+        [ statfs-f_bfree >>blocks-free ]
+        [ statfs-f_bavail >>blocks-available ]
+        [ statfs-f_files >>files ]
+        [ statfs-f_ffree >>files-free ]
+        [ statfs-f_favail >>files-available ]
+        [ statfs-f_syncwrites >>sync-writes ]
+        [ statfs-f_syncreads >>sync-reads ]
+        [ statfs-f_asyncwrites >>async-writes ]
+        [ statfs-f_asyncreads >>async-reads ]
+        [ statfs-f_fsid >>id ]
+        [ statfs-f_namemax >>name-max ]
+        [ statfs-f_owner >>owner ]
+        ! [ statfs-f_spare >>spare ]
+        [ statfs-f_fstypename alien>native-string >>type ]
+        [ statfs-f_mntonname alien>native-string >>mount-point ]
+        [ statfs-f_mntfromname alien>native-string >>device-name ]
+    } cleave ;
+
+M: openbsd file-system-statvfs ( normalized-path -- statvfs )
+    "statvfs" <c-object> tuck statvfs io-error ;
+
+M: openbsd statvfs>file-system-info ( file-system-info statvfs -- file-system-info' )
+    {
+        [ statvfs-f_frsize >>preferred-block-size ]
+    } cleave ;
+
+M: openbsd file-systems ( -- seq )
+    f 0 0 getfsstat dup io-error
+    "statfs" <c-array> dup dup length 0 getfsstat io-error 
+    "statfs" heap-size group 
+    [ statfs-f_mntonname alien>native-string file-system-info ] map ;
diff --git a/basis/io/unix/files/openbsd/tags.txt b/basis/io/unix/files/openbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index ba4240de7ff8d94b3835ae391cf5732b4c204fdd..6b687a8afb06a7eb9e8e9c7933d81df254e756c9 100644 (file)
@@ -1,11 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types kernel math math.bitwise namespaces
-locals accessors combinators threads vectors hashtables
-sequences assocs continuations sets
-unix unix.time unix.kqueue unix.process
-io.ports io.unix.backend io.launcher io.unix.launcher
-io.monitors ;
+USING: accessors alien.c-types combinators io.unix.backend
+kernel math.bitwise sequences struct-arrays unix unix.kqueue
+unix.time ;
 IN: io.unix.kqueue
 
 TUPLE: kqueue-mx < mx events monitors ;
@@ -19,131 +16,66 @@ TUPLE: kqueue-mx < mx events monitors ;
     kqueue-mx new-mx
         H{ } clone >>monitors
         kqueue dup io-error >>fd
-        max-events "kevent" <c-array> >>events ;
+        max-events "kevent" <struct-array> >>events ;
 
-GENERIC: io-task-filter ( task -- n )
-
-M: input-task io-task-filter drop EVFILT_READ ;
-
-M: output-task io-task-filter drop EVFILT_WRITE ;
-
-GENERIC: io-task-fflags ( task -- n )
-
-M: io-task io-task-fflags drop 0 ;
-
-: make-kevent ( task flags -- event )
+: make-kevent ( fd filter flags -- event )
     "kevent" <c-object>
-    tuck set-kevent-flags
-    over io-task-fd over set-kevent-ident
-    over io-task-fflags over set-kevent-fflags
-    swap io-task-filter over set-kevent-filter ;
+    [ set-kevent-flags ] keep
+    [ set-kevent-filter ] keep
+    [ set-kevent-ident ] keep ;
 
 : register-kevent ( kevent mx -- )
-    fd>> swap 1 f 0 f kevent
-    0 < [ err_no ESRCH = [ (io-error) ] unless ] when ;
+    fd>> swap 1 f 0 f kevent io-error ;
 
-M: kqueue-mx register-io-task ( task mx -- )
-    [ >r EV_ADD make-kevent r> register-kevent ]
-    [ call-next-method ]
-    2bi ;
+M: kqueue-mx add-input-callback ( thread fd mx -- )
+    [ call-next-method ] [
+        [ EVFILT_READ { EV_ADD EV_ONESHOT } flags make-kevent ] dip
+        register-kevent
+    ] 2bi ;
 
-M: kqueue-mx unregister-io-task ( task mx -- )
-    [ call-next-method ]
-    [ >r EV_DELETE make-kevent r> register-kevent ]
-    2bi ;
+M: kqueue-mx add-output-callback ( thread fd mx -- )
+    [ call-next-method ] [
+        [ EVFILT_WRITE EV_DELETE make-kevent ] dip
+        register-kevent
+    ] 2bi ;
 
-: wait-kevent ( mx timespec -- n )
-    >r [ fd>> f 0 ] keep events>> max-events r> kevent
-    dup multiplexer-error ;
-
-:: kevent-read-task ( mx fd kevent -- )
-    mx fd mx reads>> at perform-io-task ;
-
-:: kevent-write-task ( mx fd kevent -- )
-    mx fd mx writes>> at perform-io-task ;
-
-:: kevent-proc-task ( mx pid kevent -- )
-    pid wait-for-pid
-    pid find-process
-    dup [ swap notify-exit ] [ 2drop ] if ;
+: cancel-input-callbacks ( fd mx -- seq )
+    [
+        [ EVFILT_READ EV_DELETE make-kevent ] dip
+        register-kevent
+    ] [ remove-input-callbacks ] 2bi ;
 
-: parse-action ( mask -- changed )
+: cancel-output-callbacks ( fd mx -- seq )
     [
-        NOTE_DELETE +remove-file+ ?flag
-        NOTE_WRITE +modify-file+ ?flag
-        NOTE_EXTEND +modify-file+ ?flag
-        NOTE_ATTRIB +modify-file+ ?flag
-        NOTE_RENAME +rename-file+ ?flag
-        NOTE_REVOKE +remove-file+ ?flag
-        drop
-    ] { } make prune ;
+        [ EVFILT_WRITE EV_DELETE make-kevent ] dip
+        register-kevent
+    ] [ remove-output-callbacks ] 2bi ;
+
+M: fd cancel-operation ( fd -- )
+    dup disposed>> [ drop ] [
+        fd>>
+        mx get-global
+        [ cancel-input-callbacks [ t swap resume-with ] each ]
+        [ cancel-output-callbacks [ t swap resume-with ] each ]
+        2bi
+    ] if ;
 
-:: kevent-vnode-task ( mx kevent fd -- )
-    ""
-    kevent kevent-fflags parse-action
-    fd mx monitors>> at queue-change ;
+: wait-kevent ( mx timespec -- n )
+    [
+        [ fd>> f 0 ]
+        [ events>> [ underlying>> ] [ length ] bi ] bi
+    ] dip kevent
+    dup multiplexer-error ;
 
 : handle-kevent ( mx kevent -- )
-    [ ] [ kevent-ident ] [ kevent-filter ] tri {
-        { [ dup EVFILT_READ = ] [ drop kevent-read-task ] }
-        { [ dup EVFILT_WRITE = ] [ drop kevent-write-task ] }
-        { [ dup EVFILT_PROC = ] [ drop kevent-proc-task ] }
-        { [ dup EVFILT_VNODE = ] [ drop kevent-vnode-task ] }
-    } cond ;
+    [ kevent-ident swap ] [ kevent-filter ] bi {
+        { EVFILT_READ [ input-available ] }
+        { EVFILT_WRITE [ output-available ] }
+    } case ;
 
 : handle-kevents ( mx n -- )
-    [ over events>> kevent-nth handle-kevent ] with each ;
+    [ dup events>> ] dip head-slice [ handle-kevent ] with each ;
 
 M: kqueue-mx wait-for-events ( us mx -- )
     swap dup [ make-timespec ] when
     dupd wait-kevent handle-kevents ;
-
-! Procs
-: make-proc-kevent ( pid -- kevent )
-    "kevent" <c-object>
-    tuck set-kevent-ident
-    EV_ADD over set-kevent-flags
-    EVFILT_PROC over set-kevent-filter
-    NOTE_EXIT over set-kevent-fflags ;
-
-: register-pid-task ( pid mx -- )
-    swap make-proc-kevent swap register-kevent ;
-
-! VNodes
-TUPLE: vnode-monitor < monitor fd ;
-
-: vnode-fflags ( -- n )
-    {
-        NOTE_DELETE
-        NOTE_WRITE
-        NOTE_EXTEND
-        NOTE_ATTRIB
-        NOTE_LINK
-        NOTE_RENAME
-        NOTE_REVOKE
-    } flags ;
-
-: make-vnode-kevent ( fd flags -- kevent )
-    "kevent" <c-object>
-    tuck set-kevent-flags
-    tuck set-kevent-ident
-    EVFILT_VNODE over set-kevent-filter
-    vnode-fflags over set-kevent-fflags ;
-
-: register-monitor ( monitor mx -- )
-    >r dup fd>> r>
-    [ >r EV_ADD EV_CLEAR bitor make-vnode-kevent r> register-kevent drop ]
-    [ monitors>> set-at ] 3bi ;
-
-: unregister-monitor ( monitor mx -- )
-    >r fd>> r>
-    [ monitors>> delete-at ]
-    [ >r EV_DELETE make-vnode-kevent r> register-kevent ] 2bi ;
-
-: <vnode-monitor> ( path mailbox -- monitor )
-    >r [ O_RDONLY 0 open dup io-error ] keep r>
-    vnode-monitor new-monitor swap >>fd
-    [ dup kqueue-mx get register-monitor ] [ ] [ fd>> close ] cleanup ;
-
-M: vnode-monitor dispose
-    [ kqueue-mx get unregister-monitor ] [ fd>> close ] bi ;
index 421e12a92fbe994008212321a91d9a755e224eb8..c81da60e121667dd9726327ac5dd0af9dc412129 100644 (file)
@@ -16,7 +16,7 @@ USE: unix
     command>> dup string? [ tokenize-command ] when ;
 
 : assoc>env ( assoc -- env )
-    [ "=" swap 3append ] { } assoc>map ;
+    [ "=" glue ] { } assoc>map ;
 
 : setup-priority ( process -- process )
     dup priority>> [
@@ -40,14 +40,13 @@ USE: unix
     3drop ;
 
 : redirect-file ( obj mode fd -- )
-    >r >r normalize-path r> file-mode
-    open-file r> redirect-fd ;
+    [ [ normalize-path ] dip file-mode open-file ] dip redirect-fd ;
 
 : redirect-file-append ( obj mode fd -- )
-    >r drop path>> normalize-path open-append r> redirect-fd ;
+    [ drop path>> normalize-path open-append ] dip redirect-fd ;
 
 : redirect-closed ( obj mode fd -- )
-    >r >r drop "/dev/null" r> r> redirect-file ;
+    [ drop "/dev/null" ] 2dip redirect-file ;
 
 : redirect ( obj mode fd -- )
     {
@@ -55,8 +54,8 @@ USE: unix
         { [ pick string? ] [ redirect-file ] }
         { [ pick appender? ] [ redirect-file-append ] }
         { [ pick +closed+ eq? ] [ redirect-closed ] }
-        { [ pick fd? ] [ >r drop fd>> dup reset-fd r> redirect-fd ] }
-        [ >r >r underlying-handle r> r> redirect ]
+        { [ pick fd? ] [ [ drop fd>> dup reset-fd ] dip redirect-fd ] }
+        [ [ underlying-handle ] 2dip redirect ]
     } cond ;
 
 : ?closed ( obj -- obj' )
index 12b1cf779b860abd07f05eff67071c015a631140..f27d48c6b0b3391254498e10329876f75ae59c66 100644 (file)
@@ -36,9 +36,7 @@ TUPLE: linux-monitor < monitor wd inotify watches disposed ;
     inotify-fd -rot inotify_add_watch dup io-error dup check-existing ;
 
 : add-watch ( path mask mailbox -- monitor )
-    >r
-    >r (normalize-path) r>
-    [ (add-watch) ] [ drop ] 2bi r>
+    [ [ (normalize-path) ] dip [ (add-watch) ] [ drop ] 2bi ] dip
     <linux-monitor> [ ] [ ] [ wd>> ] tri watches get set-at ;
 
 : check-inotify ( -- )
@@ -103,12 +101,12 @@ M: linux-monitor dispose* ( monitor -- )
 : next-event ( i buffer -- i buffer )
     2dup inotify-event@
     inotify-event-len "inotify-event" heap-size +
-    swap >r + r> ;
+    swap [ + ] dip ;
 
 : parse-file-notifications ( i buffer -- )
     2dup events-exhausted? [ 2drop ] [
         2dup inotify-event@ dup inotify-event-wd wd>monitor
-        >r parse-file-notify r> queue-change
+        [ parse-file-notify ] dip queue-change
         next-event parse-file-notifications
     ] if ;
 
index a5f36aa93b91f547b5650ab02fad12961f98c5be..cde1d6339a31296c21350dd0ce6f5e535b4712df 100644 (file)
@@ -2,15 +2,13 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.backend io.monitors
 core-foundation.fsevents continuations kernel sequences
-namespaces arrays system locals accessors destructors ;
+namespaces arrays system locals accessors destructors fry ;
 IN: io.unix.macosx.monitors
 
 TUPLE: macosx-monitor < monitor handle ;
 
 : enqueue-notifications ( triples monitor -- )
-    [
-        >r first { +modify-file+ } r> queue-change
-    ] curry each ;
+    '[ first { +modify-file+ } _ queue-change ] each ;
 
 M:: macosx (monitor) ( path recursive? mailbox -- monitor )
     [let | path [ path normalize-path ] |
index 53c336c5555ac2135bbc8c2383e44be36ecba956..a28738e14705112dd377f656b3e300a8a0104348 100644 (file)
@@ -1,11 +1,11 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: system alien.c-types kernel unix math sequences
-qualified io.unix.backend io.ports ;
+USING: system kernel unix math sequences qualified
+io.unix.backend io.ports specialized-arrays.int accessors ;
 IN: io.unix.pipes
 QUALIFIED: io.pipes
 
 M: unix io.pipes:(pipe) ( -- pair )
-    2 "int" <c-array>
-    dup pipe io-error
-    2 c-int-array> first2 [ <fd> init-fd ] bi@ io.pipes:pipe boa ;
+    2 <int-array>
+    [ underlying>> pipe io-error ]
+    [ first2 [ <fd> init-fd ] bi@ io.pipes:pipe boa ] bi ;
index 530dfe7ab3467b99ac644c81a957d9bec6275b83..27231aee5a8adc56e303ae7ac4cba27d38c4e20f 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types kernel io.ports io.unix.backend
 bit-arrays sequences assocs unix math namespaces
-accessors math.order locals unix.time ;
+accessors math.order locals unix.time fry ;
 IN: io.unix.select
 
 TUPLE: select-mx < mx read-fdset write-fdset ;
@@ -19,7 +19,7 @@ TUPLE: select-mx < mx read-fdset write-fdset ;
         FD_SETSIZE 8 * <bit-array> >>write-fdset ;
 
 : clear-nth ( n seq -- ? )
-    [ nth ] [ f -rot set-nth ] 2bi ;
+    [ nth ] [ [ f ] 2dip set-nth ] 2bi ;
 
 :: check-fd ( fd fdset mx quot -- )
     fd munge fdset clear-nth [ fd mx quot call ] when ; inline
@@ -28,7 +28,7 @@ TUPLE: select-mx < mx read-fdset write-fdset ;
     [ check-fd ] 3curry each ; inline
 
 : init-fdset ( fds fdset -- )
-    [ >r t swap munge r> set-nth ] curry each ;
+    '[ t swap munge _ set-nth ] each ;
 
 : read-fdset/tasks ( mx -- seq fdset )
     [ reads>> keys ] [ read-fdset>> ] bi ;
diff --git a/basis/io/unix/sockets/secure/debug/debug.factor b/basis/io/unix/sockets/secure/debug/debug.factor
new file mode 100644 (file)
index 0000000..cd5353e
--- /dev/null
@@ -0,0 +1,11 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors io.sockets.secure kernel ;
+IN: io.unix.sockets.secure.debug
+
+: with-test-context ( quot -- )
+    <secure-config>
+        "resource:basis/openssl/test/server.pem" >>key-file
+        "resource:basis/openssl/test/dh1024.pem" >>dh-file
+        "password" >>password
+    swap with-secure-context ; inline
index d2a1649686796dfb89d4914d48643459d689ac83..0816dd270b6f0395cc3475ab0608d33fd0e788a3 100644 (file)
@@ -2,20 +2,14 @@ IN: io.sockets.secure.tests
 USING: accessors kernel namespaces io io.sockets
 io.sockets.secure io.encodings.ascii io.streams.duplex
 io.unix.backend classes words destructors threads tools.test
-concurrency.promises byte-arrays locals calendar io.timeouts ;
+concurrency.promises byte-arrays locals calendar io.timeouts
+io.unix.sockets.secure.debug ;
 
 \ <secure-config> must-infer
 { 1 0 } [ [ ] with-secure-context ] must-infer-as
 
 [ ] [ <promise> "port" set ] unit-test
 
-: with-test-context ( quot -- )
-    <secure-config>
-        "resource:basis/openssl/test/server.pem" >>key-file
-        "resource:basis/openssl/test/dh1024.pem" >>dh-file
-        "password" >>password
-    swap with-secure-context ; inline
-
 :: server-test ( quot -- )
     [
         [
index fb5ed939781a3b7868a98ccfa7ad6557dfbefb36..a096380b74b8ca9adc6008e60f44481223697c19 100644 (file)
@@ -3,10 +3,10 @@
 USING: accessors unix byte-arrays kernel debugger sequences
 namespaces math math.order combinators init alien alien.c-types
 alien.strings libc continuations destructors openssl
-openssl.libcrypto openssl.libssl io.files io.ports
+openssl.libcrypto openssl.libssl io io.files io.ports
 io.unix.backend io.unix.sockets io.encodings.ascii io.buffers
 io.sockets io.sockets.secure io.sockets.secure.openssl
-io.timeouts system summary ;
+io.timeouts system summary fry ;
 IN: io.unix.sockets.secure
 
 M: ssl-handle handle-fd file>> handle-fd ;
@@ -18,9 +18,7 @@ M: ssl-handle handle-fd file>> handle-fd ;
             { -1 [ err_no ECONNRESET = [ premature-close ] [ (io-error) ] if ] }
             { 0 [ premature-close ] }
         } case
-    ] [
-        nip (ssl-error)
-    ] if ;
+    ] [ nip (ssl-error) ] if ;
 
 : check-accept-response ( handle r -- event )
     over handle>> over SSL_get_error
@@ -36,7 +34,7 @@ M: ssl-handle handle-fd file>> handle-fd ;
 
 : do-ssl-accept ( ssl-handle -- )
     dup dup handle>> SSL_accept check-accept-response dup
-    [ >r dup file>> r> wait-for-fd do-ssl-accept ] [ 2drop ] if ;
+    [ [ dup file>> ] dip wait-for-fd do-ssl-accept ] [ 2drop ] if ;
 
 : maybe-handshake ( ssl-handle -- )
     dup connected>> [ drop ] [
@@ -130,24 +128,23 @@ M: secure (get-local-address) addrspec>> (get-local-address) ;
     [ [ handle>> SSL_get1_session ] dip save-session ]
     2bi ;
 
-: secure-connection ( ssl-handle addrspec -- )
-    dup get-session [ resume-session ] [ begin-session ] ?if ;
+: secure-connection ( client-out addrspec -- )
+    [ handle>> ] dip
+    [
+        '[
+            _ dup get-session
+            [ resume-session ] [ begin-session ] ?if
+        ] with-timeout
+    ] [ drop t >>connected drop ] 2bi ;
 
 M: secure establish-connection ( client-out remote -- )
-    addrspec>>
-    [ establish-connection ]
-    [
-        [ handle>> ] dip
-        [ [ secure-connection ] curry with-timeout ]
-        [ drop t >>connected drop ]
-        2bi
-    ] 2bi ;
+    addrspec>> [ establish-connection ] [ secure-connection ] 2bi ;
 
 M: secure (server) addrspec>> (server) ;
 
 M: secure (accept)
     [
-        addrspec>> (accept) >r |dispose <ssl-socket> r>
+        addrspec>> (accept) [ |dispose <ssl-socket> ] dip
     ] with-destructors ;
 
 : check-shutdown-response ( handle r -- event )
@@ -172,3 +169,32 @@ M: ssl-handle shutdown
     dup connected>> [
         f >>connected [ (shutdown) ] with-timeout
     ] [ drop ] if ;
+
+: check-buffer ( port -- port )
+    dup buffer>> buffer-empty? [ upgrade-buffers-full ] unless ;
+
+: input/output-ports ( -- input output )
+    input-stream output-stream
+    [ get underlying-port check-buffer ] bi@
+    2dup [ handle>> ] bi@ eq? [ upgrade-on-non-socket ] unless ;
+
+: make-input/output-secure ( input output -- )
+    dup handle>> fd? [ upgrade-on-non-socket ] unless
+    [ <ssl-socket> ] change-handle
+    handle>> >>handle drop ;
+
+: (send-secure-handshake) ( output -- )
+    remote-address get [ upgrade-on-non-socket ] unless*
+    secure-connection ;
+
+M: openssl send-secure-handshake
+    input/output-ports
+    [ make-input/output-secure ] keep
+    [ (send-secure-handshake) ] keep
+    remote-address get dup inet? [
+        host>> swap handle>> check-certificate
+    ] [ 2drop ] if ;
+
+M: openssl accept-secure-handshake
+    input/output-ports
+    make-input/output-secure ;
index 8f9ff4f06673fed038317307ef7c3931999fe742..5fba7badb01084c1e59467060447c4a5f8979489 100644 (file)
@@ -16,18 +16,18 @@ IN: io.unix.sockets
     0 socket dup io-error <fd> init-fd |dispose ;
 
 : set-socket-option ( fd level opt -- )
-    >r >r handle-fd r> r> 1 <int> "int" heap-size setsockopt io-error ;
+    [ handle-fd ] 2dip 1 <int> "int" heap-size setsockopt io-error ;
 
 M: unix addrinfo-error ( n -- )
     dup zero? [ drop ] [ gai_strerror throw ] if ;
 
 ! Client sockets - TCP and Unix domain
 M: object (get-local-address) ( handle remote -- sockaddr )
-    >r handle-fd r> empty-sockaddr/size <int>
+    [ handle-fd ] dip empty-sockaddr/size <int>
     [ getsockname io-error ] 2keep drop ;
 
 M: object (get-remote-address) ( handle local -- sockaddr )
-    >r handle-fd r> empty-sockaddr/size <int>
+    [ handle-fd ] dip empty-sockaddr/size <int>
     [ getpeername io-error ] 2keep drop ;
 
 : init-client-socket ( fd -- )
@@ -60,7 +60,7 @@ M: object ((client)) ( addrspec -- fd )
     SOL_SOCKET SO_REUSEADDR set-socket-option ;
 
 : server-socket-fd ( addrspec type -- fd )
-    >r dup protocol-family r> socket-fd
+    [ dup protocol-family ] dip socket-fd
     dup init-server-socket
     dup handle-fd rot make-sockaddr/size bind io-error ;
 
@@ -77,7 +77,7 @@ M: object (server) ( addrspec -- handle )
 M: object (accept) ( server addrspec -- fd sockaddr )
     2dup do-accept
     {
-        { [ over 0 >= ] [ >r 2nip <fd> init-fd r> ] }
+        { [ over 0 >= ] [ [ 2nip <fd> init-fd ] dip ] }
         { [ err_no EINTR = ] [ 2drop (accept) ] }
         { [ err_no EAGAIN = ] [
             2drop
@@ -114,7 +114,7 @@ SYMBOL: receive-buffer
     ] call ;
 
 M: unix (receive) ( datagram -- packet sockaddr )
-    dup do-receive dup [ rot drop ] [
+    dup do-receive dup [ [ drop ] 2dip ] [
         2drop [ +input+ wait-for-port ] [ (receive) ] bi
     ] if ;
 
index 7e1dc48e5f1147677c64eab4c1efa94864aa29b7..df61420c77501e2a50b0da2cccd577ea8d05f419 100644 (file)
@@ -46,7 +46,7 @@ yield
 
         "Receive 1" print
 
-        "d" get receive >r reverse r>
+        "d" get receive [ reverse ] dip
         
         "Send 1" print
         dup .
@@ -55,7 +55,7 @@ yield
 
         "Receive 2" print
 
-        "d" get receive >r " world" append r>
+        "d" get receive [ " world" append ] dip
         
         "Send 1" print
         dup .
@@ -86,7 +86,7 @@ datagram-client <local> <datagram>
 [ "olleh" t ] [
     "d" get receive
     datagram-server <local> =
-    >r >string r>
+    [ >string ] dip
 ] unit-test
 
 [ ] [
@@ -98,7 +98,7 @@ datagram-client <local> <datagram>
 [ "hello world" t ] [
     "d" get receive
     datagram-server <local> =
-    >r >string r>
+    [ >string ] dip
 ] unit-test
 
 [ ] [ "d" get dispose ] unit-test
index 7f84b9d9e54b01e96a03fb12760687f3e944bd53..83954e045bbe31ce8f1a2e365d8ffdbaded118bd 100755 (executable)
@@ -10,7 +10,7 @@ IN: io.windows.files
 
 : open-file ( path access-mode create-mode flags -- handle )
     [
-        >r >r share-mode default-security-attributes r> r>
+        [ share-mode default-security-attributes ] 2dip
         CreateFile-flags f CreateFile opened-file
     ] with-destructors ;
 
@@ -46,7 +46,7 @@ IN: io.windows.files
     GetLastError ERROR_ALREADY_EXISTS = not ;
 
 : set-file-pointer ( handle length method -- )
-    >r dupd d>w/w <uint> r> SetFilePointer
+    [ dupd d>w/w <uint> ] dip SetFilePointer
     INVALID_SET_FILE_POINTER = [
         CloseHandle "SetFilePointer failed" throw
     ] when drop ;
@@ -257,9 +257,6 @@ M: winnt link-info ( path -- info )
 
 HOOK: root-directory os ( string -- string' )
 
-TUPLE: winnt-file-system-info < file-system-info
-total-bytes total-free-bytes ;
-
 : file-system-type ( normalized-path -- str )
     MAX_PATH 1+ <byte-array>
     MAX_PATH 1+
@@ -269,21 +266,28 @@ total-bytes total-free-bytes ;
     [ GetVolumeInformation win32-error=0/f ] 2keep drop
     utf16n alien>string ;
 
-: file-system-space ( normalized-path -- free-space total-bytes total-free-bytes )
+: file-system-space ( normalized-path -- available-space total-space free-space )
     "ULARGE_INTEGER" <c-object>
     "ULARGE_INTEGER" <c-object>
     "ULARGE_INTEGER" <c-object>
     [ GetDiskFreeSpaceEx win32-error=0/f ] 3keep ;
 
+: calculate-file-system-info ( file-system-info -- file-system-info' )
+    {
+        [ dup [ total-space>> ] [ free-space>> ] bi - >>used-space drop ]
+        [ ]
+    } cleave ;
+
 M: winnt file-system-info ( path -- file-system-info )
     normalize-path root-directory
     dup [ file-system-type ] [ file-system-space ] bi
-    \ winnt-file-system-info new
-        swap *ulonglong >>total-free-bytes
-        swap *ulonglong >>total-bytes
+    \ file-system-info new
         swap *ulonglong >>free-space
+        swap *ulonglong >>total-space
+        swap *ulonglong >>available-space
         swap >>type
-        swap >>mount-point ;
+        swap >>mount-point
+    calculate-file-system-info ;
 
 : volume>paths ( string -- array )
     16384 "ushort" <c-array> tuck dup length
@@ -324,7 +328,7 @@ M: winnt file-systems ( -- array )
     find-volumes [ volume>paths ] map
     concat [
         [ file-system-info ]
-        [ drop winnt-file-system-info new swap >>mount-point ] recover
+        [ drop file-system-info new swap >>mount-point ] recover
     ] map ;
 
 : file-times ( path -- timestamp timestamp timestamp )
@@ -344,23 +348,23 @@ M: winnt file-systems ( -- array )
 : set-file-times ( path timestamp/f timestamp/f timestamp/f -- )
     #! timestamp order: creation access write
     [
-        >r >r >r
+        [
             normalize-path open-existing &dispose handle>>
-        r> r> r> (set-file-times)
+        ] 3dip (set-file-times)
     ] with-destructors ;
 
 : set-file-create-time ( path timestamp -- )
     f f set-file-times ;
 
 : set-file-access-time ( path timestamp -- )
-    >r f r> f set-file-times ;
+    [ f ] dip f set-file-times ;
 
 : set-file-write-time ( path timestamp -- )
-    >r f f r> set-file-times ;
+    [ f f ] dip set-file-times ;
 
 M: winnt touch-file ( path -- )
     [
         normalize-path
-        maybe-create-file >r &dispose r>
+        maybe-create-file [ &dispose ] dip
         [ drop ] [ handle>> f now dup (set-file-times) ] if
     ] with-destructors ;
index d1ad309dd5b9cf14df8408d82494566c83380871..212b405a54e0413da03d91495c0d3711bfd6f667 100644 (file)
@@ -6,7 +6,8 @@ windows.types math windows.kernel32
 namespaces make io.launcher kernel sequences windows.errors
 splitting system threads init strings combinators
 io.backend accessors concurrency.flags io.files assocs
-io.files.private windows destructors ;
+io.files.private windows destructors specialized-arrays.ushort
+specialized-arrays.alien ;
 IN: io.windows.launcher
 
 TUPLE: CreateProcess-args
@@ -45,7 +46,7 @@ TUPLE: CreateProcess-args
     CreateProcess win32-error=0/f ;
 
 : count-trailing-backslashes ( str n -- str n )
-    >r "\\" ?tail r> swap [
+    [ "\\" ?tail ] dip swap [
         1+ count-trailing-backslashes
     ] when ;
 
@@ -84,8 +85,7 @@ TUPLE: CreateProcess-args
 
 : fill-lpApplicationName ( process args -- process args )
     over app-name/cmd-line
-    >r >>lpApplicationName
-    r> >>lpCommandLine ;
+    [ >>lpApplicationName ] [ >>lpCommandLine ] bi* ;
 
 : fill-lpCommandLine ( process args -- process args )
     over cmd-line >>lpCommandLine ;
@@ -103,7 +103,7 @@ TUPLE: CreateProcess-args
             over get-environment
             [ swap % "=" % % "\0" % ] assoc-each
             "\0" %
-        ] "" make >c-ushort-array
+        ] ushort-array{ } make underlying>>
         >>lpEnvironment
     ] when ;
 
@@ -157,8 +157,8 @@ M: windows kill-process* ( handle -- )
 
 M: windows wait-for-processes ( -- ? )
     processes get keys dup
-    [ handle>> PROCESS_INFORMATION-hProcess ] map
-    dup length swap >c-void*-array 0 0
+    [ handle>> PROCESS_INFORMATION-hProcess ] void*-array{ } map-as
+    [ length ] [ underlying>> ] bi 0 0
     WaitForMultipleObjects
     dup HEX: ffffffff = [ win32-error ] when
     dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth process-exited f ] if ;
diff --git a/basis/io/windows/mmap/mmap-tests.factor b/basis/io/windows/mmap/mmap-tests.factor
deleted file mode 100644 (file)
index a843010..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-USING: io io.mmap io.files kernel tools.test continuations
-sequences io.encodings.ascii accessors ;
-IN: io.windows.mmap.tests
-
-[ ] [ "a" "mmap-grow-test.txt" temp-file ascii set-file-contents ] unit-test
-[ 1 ] [ "mmap-grow-test.txt" temp-file file-info size>> ] unit-test
-[ ] [ "mmap-grow-test.txt" temp-file 100 [ [ ] change-each ] with-mapped-file ] unit-test
-[ 100 ] [ "mmap-grow-test.txt" temp-file file-info size>> ] unit-test
index 73b77508b7b36b39f592fe666c7f652932c8a2a9..8035bd66e99bd2c89c8f4dd619e31f571013f4e7 100644 (file)
@@ -18,8 +18,8 @@ C: <io-callback> io-callback
     "OVERLAPPED" malloc-object &free ;
 
 : make-overlapped ( port -- overlapped-ext )
-    >r (make-overlapped)
-    r> handle>> ptr>> [ over set-OVERLAPPED-offset ] when* ;
+    [ (make-overlapped) ] dip
+    handle>> ptr>> [ over set-OVERLAPPED-offset ] when* ;
 
 : <completion-port> ( handle existing -- handle )
      f 1 CreateIoCompletionPort dup win32-error=0/f ;
@@ -48,12 +48,12 @@ M: winnt add-completion ( win32-handle -- )
         } cond
     ] with-timeout ;
 
-:: wait-for-overlapped ( ms -- bytes-transferred overlapped error? )
+:: wait-for-overlapped ( us -- bytes-transferred overlapped error? )
     master-completion-port get-global
     0 <int> [ ! bytes
         f <void*> ! key
         f <void*> [ ! overlapped
-            ms INFINITE or ! timeout
+            us [ 1000 /i ] [ INFINITE ] if* ! timeout
             GetQueuedCompletionStatus zero?
         ] keep *void*
     ] keep *int spin ;
@@ -61,21 +61,17 @@ M: winnt add-completion ( win32-handle -- )
 : resume-callback ( result overlapped -- )
     pending-overlapped get-global delete-at* drop resume-with ;
 
-: handle-overlapped ( timeout -- ? )
+: handle-overlapped ( us -- ? )
     wait-for-overlapped [
         dup [
-            >r drop GetLastError 1array r> resume-callback t
-        ] [
-            2drop f
-        ] if
-    ] [
-        resume-callback t
-    ] if ;
+            [ drop GetLastError 1array ] dip resume-callback t
+        ] [ 2drop f ] if
+    ] [ resume-callback t ] if ;
 
 M: win32-handle cancel-operation
     [ check-disposed ] [ handle>> CancelIo drop ] bi ;
 
-M: winnt io-multiplex ( ms -- )
+M: winnt io-multiplex ( us -- )
     handle-overlapped [ 0 io-multiplex ] when ;
 
 M: winnt init-io ( -- )
@@ -94,7 +90,7 @@ M: winnt init-io ( -- )
 
 : wait-for-file ( FileArgs n port -- n )
     swap file-error?
-    [ 2drop 0 ] [ >r lpOverlapped>> r> twiddle-thumbs ] if ;
+    [ 2drop 0 ] [ [ lpOverlapped>> ] dip twiddle-thumbs ] if ;
 
 : update-file-ptr ( n port -- )
     handle>> dup ptr>> [ rot + >>ptr drop ] [ 2drop ] if* ;
index 2fbc8092636efc31b5ff4b0f923c3ec9d80c1518..9f25eb5eb15600760fca0adbf10146eefdbcf876 100644 (file)
@@ -59,6 +59,6 @@ M: winnt FileArgs-overlapped ( port -- overlapped )
 
 M: winnt open-append
     [ dup file-info size>> ] [ drop 0 ] recover
-    >r (open-append) r> >>ptr ;
+    [ (open-append) ] dip >>ptr ;
 
 M: winnt home "USERPROFILE" os-env ;
index 9d02fbe2fd1780a9ee741d30c05775607f624da2..de4fb99c64393063ef408d9dbbd7d603eb7b0099 100644 (file)
@@ -52,7 +52,7 @@ IN: io.windows.nt.launcher
     CreateFile dup invalid-handle? <win32-file> &dispose handle>> ;
 
 : redirect-append ( path access-mode create-mode -- handle )
-    >r >r path>> r> r>
+    [ path>> ] 2dip
     drop OPEN_ALWAYS
     redirect-file
     dup 0 FILE_END set-file-pointer ;
@@ -61,7 +61,7 @@ IN: io.windows.nt.launcher
     2drop handle>> duplicate-handle ;
 
 : redirect-stream ( stream access-mode create-mode -- handle )
-    >r >r underlying-handle handle>> r> r> redirect-handle ;
+    [ underlying-handle handle>> ] 2dip redirect-handle ;
 
 : redirect ( obj access-mode create-mode -- handle )
     {
old mode 100644 (file)
new mode 100755 (executable)
index 2680b40..30345c8
@@ -1,11 +1,12 @@
 ! Copyright (C) 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types libc destructors locals kernel math
-assocs namespaces make continuations sequences hashtables
-sorting arrays combinators math.bitwise strings system accessors
-threads splitting io.backend io.windows io.windows.nt.backend
-io.windows.nt.files io.monitors io.ports io.buffers io.files
-io.timeouts io windows windows.kernel32 windows.types ;
+USING: alien alien.c-types alien.strings libc destructors locals
+kernel math assocs namespaces make continuations sequences
+hashtables sorting arrays combinators math.bitwise strings
+system accessors threads splitting io.backend io.windows
+io.windows.nt.backend io.windows.nt.files io.monitors io.ports
+io.buffers io.files io.timeouts io.encodings.string io
+windows windows.kernel32 windows.types ;
 IN: io.windows.nt.monitors
 
 : open-directory ( path -- handle )
@@ -50,7 +51,7 @@ TUPLE: win32-monitor < monitor port ;
     } case 1array ;
 
 : memory>u16-string ( alien len -- string )
-    [ memory>byte-array ] keep 2/ c-ushort-array> >string ;
+    memory>byte-array utf16n decode ;
 
 : parse-notify-record ( buffer -- path changed )
     [
old mode 100644 (file)
new mode 100755 (executable)
index 8418d09..264f337
@@ -20,12 +20,12 @@ TYPEDEF: TOKEN_PRIVILEGES* PTOKEN_PRIVILEGES
 \r
 : with-process-token ( quot -- )\r
     #! quot: ( token-handle -- token-handle )\r
-    >r open-process-token r>\r
+    [ open-process-token ] dip\r
     [ keep ] curry\r
     [ CloseHandle drop ] [ ] cleanup ; inline\r
 \r
 : lookup-privilege ( string -- luid )\r
-    >r f r> "LUID" <c-object>\r
+    [ f ] dip "LUID" <c-object>\r
     [ LookupPrivilegeValue win32-error=0/f ] keep ;\r
 \r
 : make-token-privileges ( name ? -- obj )\r
@@ -39,10 +39,9 @@ TYPEDEF: TOKEN_PRIVILEGES* PTOKEN_PRIVILEGES
         set-LUID_AND_ATTRIBUTES-Attributes\r
     ] when\r
 \r
-    >r lookup-privilege r>\r
+    [ lookup-privilege ] dip\r
     [\r
         TOKEN_PRIVILEGES-Privileges\r
-        >r 0 r> LUID_AND_ATTRIBUTES-nth\r
         set-LUID_AND_ATTRIBUTES-Luid\r
     ] keep ;\r
 \r
index 5d94cf2d4a55ff82f34650c6a90f893fd12bde61..ecd9ea9d9b433bcbc697a3b8f763d3901677bd84 100644 (file)
@@ -176,8 +176,8 @@ TUPLE: WSASendTo-args port
 
 : make-send-buffer ( packet -- WSABUF )
     "WSABUF" malloc-object &free
-    [ >r malloc-byte-array &free r> set-WSABUF-buf ]
-    [ >r length r> set-WSABUF-len ]
+    [ [ malloc-byte-array &free ] dip set-WSABUF-buf ]
+    [ [ length ] dip set-WSABUF-len ]
     [ nip ]
     2tri ; inline
 
@@ -186,8 +186,8 @@ TUPLE: WSASendTo-args port
         swap >>port
         dup port>> handle>> handle>> >>s
         swap make-sockaddr/size
-            >r malloc-byte-array &free
-            r> [ >>lpTo ] [ >>iToLen ] bi*
+            [ malloc-byte-array &free ] dip
+            [ >>lpTo ] [ >>iToLen ] bi*
         swap make-send-buffer >>lpBuffers
         1 >>dwBufferCount
         0 >>dwFlags
index d9ab10d5e391e0bb1b56c368384a6646cbdf8f15..809af605e02090b751609af9668e9604b7707ede 100644 (file)
@@ -20,21 +20,21 @@ M: win32-socket dispose ( stream -- )
     <win32-socket> |dispose dup add-completion ;\r
 \r
 : open-socket ( addrspec type -- win32-socket )\r
-    >r protocol-family r>\r
+    [ protocol-family ] dip\r
     0 f 0 WSASocket-flags WSASocket\r
     dup socket-error\r
     opened-socket ;\r
 \r
 M: object (get-local-address) ( socket addrspec -- sockaddr )\r
-    >r handle>> r> empty-sockaddr/size <int>\r
+    [ handle>> ] dip empty-sockaddr/size <int>\r
     [ getsockname socket-error ] 2keep drop ;\r
 \r
 M: object (get-remote-address) ( socket addrspec -- sockaddr )\r
-    >r handle>> r> empty-sockaddr/size <int>\r
+    [ handle>> ] dip empty-sockaddr/size <int>\r
     [ getpeername socket-error ] 2keep drop ;\r
 \r
 : bind-socket ( win32-socket sockaddr len -- )\r
-    >r >r handle>> r> r> bind socket-error ;\r
+    [ handle>> ] 2dip bind socket-error ;\r
 \r
 M: object ((client)) ( addrspec -- handle )\r
     [ SOCK_STREAM open-socket ] keep\r
index ce75293b38a57528ad03e629d5f894af1ad6f375..94304edc05bf480a4ff0b670a127537280c2b1ba 100755 (executable)
@@ -8,7 +8,8 @@ splitting continuations math.bitwise system accessors ;
 IN: io.windows
 
 : set-inherit ( handle ? -- )
-    >r HANDLE_FLAG_INHERIT r> >BOOLEAN SetHandleInformation win32-error=0/f ;
+    [ HANDLE_FLAG_INHERIT ] dip
+    >BOOLEAN SetHandleInformation win32-error=0/f ;
 
 TUPLE: win32-handle handle disposed ;
 
index 37a3b7068fd20a5262aabe83b3892171ba5fe4d7..b89f4174bfa3776a4a8e7c8fbcee053f062c04db 100644 (file)
@@ -32,10 +32,6 @@ HELP: free
 { $values { "alien" c-ptr } }
 { $description "Deallocates a block of memory allocated by " { $link malloc } ", " { $link calloc } " or " { $link realloc } "." } ;
 
-HELP: with-malloc
-{ $values { "size" "a positive integer" } { "quot" { $quotation "( c-ptr -- )" } } }
-{ $description "Allocates a zeroed block of " { $snippet "n" } " bytes and passes it to the quotation. When the quotation returns, the block is freed." } ;
-
 HELP: &free
 { $values { "alien" c-ptr } }
 { $description "Marks the block of memory for unconditional deallocation at the end of the current " { $link with-destructors } " scope." } ;
index cf4e2fb72299a4861b3f4d2240cfa3bf5f8eec77..c4d351e6a0fea9436c29bb0d7c4bd0a454b47774 100644 (file)
@@ -87,9 +87,6 @@ PRIVATE>
 : memcpy ( dst src size -- )
     "void" "libc" "memcpy" { "void*" "void*" "ulong" } alien-invoke ;
 
-: with-malloc ( size quot -- )
-    swap 1 calloc [ swap keep ] [ free ] [ ] cleanup ; inline
-
 : strlen ( alien -- len )
     "size_t" "libc" "strlen" { "char*" } alien-invoke ;
 
index 7330ac1a567c658d6b0874a5f0fca7d73400a283..f9f84fbbaed2338e8a12ec1cc9437d99aafe94cf 100644 (file)
@@ -28,9 +28,6 @@ M: linked-assoc set-at
     [ 2dup assoc>> key? [ 2dup delete-at ] when add-to-dlist ] 2keep
     assoc>> set-at ;
 
-: dlist>seq ( dlist -- seq )
-    [ ] pusher [ dlist-each ] dip ;
-
 M: linked-assoc >alist
     dlist>> dlist>seq ;
 
index 935271450947509a8c54105b7ab4ceaf265bf2ab..ee714f7ef76cf731997c1bc0c26ee60f7a5443db 100644 (file)
@@ -1,39 +1,14 @@
 IN: locals.backend.tests
 USING: tools.test locals.backend kernel arrays ;
 
-[ 3 ] [ 3 >r 1 get-local r> drop ] unit-test
-
-[ 4 ] [ 3 4 >r >r 2 get-local 2 drop-locals ] unit-test
-
-: get-local-test-1 ( -- x ) 3 >r 1 get-local r> drop ;
+: get-local-test-1 ( -- x ) 3 1 load-locals 0 get-local 1 drop-locals ;
 
 \ get-local-test-1 must-infer
 
 [ 3 ] [ get-local-test-1 ] unit-test
 
-: get-local-test-2 ( -- x ) 3 4 >r >r 2 get-local 2 drop-locals ;
+: get-local-test-2 ( -- x ) 3 4 2 load-locals -1 get-local 2 drop-locals ;
 
 \ get-local-test-2 must-infer
 
-[ 4 ] [ get-local-test-2 ] unit-test
-
-: get-local-test-3 ( -- a b ) 3 4 >r >r 2 get-local r> r> 2array ;
-
-\ get-local-test-3 must-infer
-
-[ 4 { 3 4 } ] [ get-local-test-3 ] unit-test
-
-: get-local-test-4 ( -- a b )
-    3 4 >r >r r> r> dup swap >r swap >r r> r> 2array ;
-
-\ get-local-test-4 must-infer
-
-[ 4 { 3 4 } ] [ get-local-test-4 ] unit-test
-
-[ 1 2 ] [ 1 2 2 load-locals r> r> ] unit-test
-
-: load-locals-test-1 ( -- a b ) 1 2 2 load-locals r> r> ;
-
-\ load-locals-test-1 must-infer
-
-[ 1 2 ] [ load-locals-test-1 ] unit-test
+[ 3 ] [ get-local-test-2 ] unit-test
index 0d9ee6a64eadda7821400ef6936bf838556ae1b0..ece5c1d20021617643364ccacc569c77fc8ccc9e 100644 (file)
@@ -1,11 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.private kernel slots.private sequences effects words ;
+USING: slots.private ;
 IN: locals.backend
 
-: load-locals ( n -- )
-    dup 0 eq? [ drop ] [ swap >r 1 fixnum-fast load-locals ] if ;
-
 : local-value 2 slot ; inline
 
 : set-local-value 2 set-slot ; inline
index 18488ed1ddd4c204c56e9e4effff076c5dfcbc6f..89314aadc512e42a5e6248c031c88eef07d24359 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.syntax help.markup kernel macros prettyprint
-memoize combinators arrays ;
+memoize combinators arrays generalizations ;
 IN: locals
 
 HELP: [|
@@ -131,10 +131,40 @@ $nl
 $nl
 "Unlike some languages such as Python and Java, writing to mutable locals in outer scopes is fully supported and has the expected semantics." ;
 
+ARTICLE: "locals-fry" "Locals and fry"
+"Locals integrate with " { $link "fry" } " so that mixing locals with fried quotations gives intuitive results."
+$nl
+"Recall that the following two code snippets are equivalent:"
+{ $code "'[ sq _ + ]" }
+{ $code "[ [ sq ] dip + ] curry" }
+"The semantics of " { $link dip } " and " { $link curry } " are such that the first example behaves as if the top of the stack as ``inserted'' in the ``hole'' in the quotation's second element."
+$nl
+"Conceptually, " { $link curry } " is defined so that the following two code snippets are equivalent:"
+{ $code "3 [ - ] curry" }
+{ $code "[ 3 - ]" }
+"With lambdas, " { $link curry } " behaves differently. Rather than prepending an element, it fills in named parameters from right to left. The following two snippets are equivalent:"
+{ $code "3 [| a b | a b - ] curry" }
+{ $code "[| a | a 3 - ]" }
+"Because of this, the behavior of fry changes when applied to a lambda, to ensure that conceptually, fry behaves as with quotations. So the following snippets are no longer equivalent:"
+{ $code "'[ [| a | _ a - ] ]" }
+{ $code "'[ [| a | a - ] curry ] call" }
+"Instead, the first line above expands into something like the following:"
+{ $code "[ [ swap [| a | a - ] ] curry call ]" }
+"This ensures that the fried value appears ``underneath'' the local variable " { $snippet "a" } " when the quotation calls."
+$nl
+"The precise behavior is the following. When frying a lambda, a stack shuffle (" { $link mnswap } ") is prepended to the lambda so that the " { $snippet "m" } " curried values, which start off at the top of the stack, are transposed with the " { $snippet "n" } " inputs to the lambda." ;
+
 ARTICLE: "locals-limitations" "Limitations of locals"
-"The first limitation is also shared by " { $vocab-link "fry" } ": the " { $link >r } " and " { $link r> } " words may not be used together with locals. Instead, use the " { $link dip } " combinator. An error is thrown at parse time if an attempt is made to use " { $link >r } " and " { $link r> } " inside a lambda body:"
-{ $subsection >r/r>-in-lambda-error }
-"Another limitation concerns combinators implemented as macros. Locals can only be used with such combinators if the input array immediately precedes the combinator call. For example, the following will work:"
+"There are two main limitations of the current locals implementation, and both concern macros."
+{ $heading "Macro expansions with free variables" }
+"The expansion of a macro cannot reference local variables bound in the outer scope. For example, the following macro is invalid:"
+{ $code "MACRO:: twice ( quot -- ) [ quot call quot call ] ;" }
+"The following is fine, though:"
+{ $code "MACRO:: twice ( quot -- ) quot quot '[ @ @ ] ;" }
+{ $heading "Static stack effect inference and macros" }
+"Recall that a macro will only expand at compile-time, and the word containing it will only get a static stack effect, if all inputs to the macro are literal. When locals are used, there is an additional restriction; the literals must immediately precede the macro call, lexically."
+$nl
+"For example, all of the following three examples are equivalent semantically, but only the first will have a static stack effect and compile with the optimizing compiler:"
 { $code
     ":: good-cond-usage ( a -- ... )"
     "    {"
@@ -143,7 +173,7 @@ ARTICLE: "locals-limitations" "Limitations of locals"
     "        { [ a 0 = ] [ ... ] }"
     "    } cond ;"
 }
-"But not the following:"
+"The following two will not, and will run slower as a result:"
 { $code
     ": my-cond ( alist -- ) cond ; inline"
     ""
@@ -154,6 +184,14 @@ ARTICLE: "locals-limitations" "Limitations of locals"
     "        { [ a 0 = ] [ ... ] }"
     "    } my-cond ;"
 }
+{ $code
+    ":: bad-cond-usage ( a -- ... )"
+    "    {"
+    "        { [ a 0 < ] [ ... ] }"
+    "        { [ a 0 > ] [ ... ] }"
+    "        { [ a 0 = ] [ ... ] }"
+    "    } swap swap cond ;"
+}
 "The reason is that locals are rewritten into stack code at parse time, whereas macro expansion is performed later during compile time. To circumvent this problem, the " { $vocab-link "macros.expander" } " vocabulary is used to rewrite simple macro usages prior to local transformation, however "{ $vocab-link "macros.expander" } " does not deal with more complicated cases where the literal inputs to the macro do not immediately precede the macro call in the source." ;
 
 ARTICLE: "locals" "Local variables and lexical closures"
@@ -174,6 +212,7 @@ $nl
 "Additional topics:"
 { $subsection "locals-literals" }
 { $subsection "locals-mutable" }
+{ $subsection "locals-fry" }
 { $subsection "locals-limitations" }
 "Locals complement dynamically scoped variables implemented in the " { $vocab-link "namespaces" } " vocabulary." ;
 
index 44c04da1a14dade304009ad1409483b488f2eb16..f13c1d57fa30c00e82d836ded7e78d2d13e210d4 100644 (file)
@@ -398,7 +398,7 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
 
 [ ] [ [ { integer lambda-method-forget-test } forget ] with-compilation-unit ] unit-test
 
-[ { [ 10 ] } ] [ 10 [| A | { [ A ] } ] call ] unit-test
+[ 10 ] [ 10 [| A | { [ A ] } ] call first call ] unit-test
 
 [
     "USING: locals fry math ; [ 0 '[ [let | A [ 10 ] | A _ + ] ] ]" eval
@@ -418,14 +418,66 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
 [ "USE: locals [let | a" eval ] [ error>> unexpected-eof? ] must-fail-with
 [ "USE: locals [|" eval ] [ error>> unexpected-eof? ] must-fail-with
 
-! :: wlet-&&-test ( a -- ? )
-!     [wlet | is-integer? [ a integer? ]
-!             is-even? [ a even? ]
-!             >10? [ a 10 > ] |
-!         { [ is-integer? ] [ is-even? ] [ >10? ] } &&
-!     ] ;
-
-! [ f ] [ 1.5 wlet-&&-test ] unit-test
-! [ f ] [ 3 wlet-&&-test ] unit-test
-! [ f ] [ 8 wlet-&&-test ] unit-test
-! [ t ] [ 12 wlet-&&-test ] unit-test
\ No newline at end of file
+[ 25 ] [ 5 [| a | { [ a sq ] } cond ] call ] unit-test
+[ 25 ] [ 5 [| | { [| a | a sq ] } ] call first call ] unit-test
+
+:: FAILdog-1 ( -- b ) { [| c | c ] } ;
+
+\ FAILdog-1 must-infer
+
+:: FAILdog-2 ( a -- b ) a { [| c | c ] } cond ;
+
+\ FAILdog-2 must-infer
+
+[ 3 ] [ 3 [| a | \ a ] call ] unit-test
+
+[ "USE: locals [| | { [let | a [ 0 ] | a ] } ]" eval ] must-fail
+
+[ "USE: locals [| | { [wlet | a [ 0 ] | a ] } ]" eval ] must-fail
+
+[ "USE: locals [| | { [let* | a [ 0 ] | a ] } ]" eval ] must-fail
+
+[ "USE: locals [| | [let | a! [ 0 ] | { a! } ] ]" eval ] must-fail
+
+[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval ] must-fail
+
+:: wlet-&&-test ( a -- ? )
+    [wlet | is-integer? [ a integer? ]
+            is-even? [ a even? ]
+            >10? [ a 10 > ] |
+        { [ is-integer? ] [ is-even? ] [ >10? ] } &&
+    ] ;
+
+\ wlet-&&-test must-infer
+[ f ] [ 1.5 wlet-&&-test ] unit-test
+[ f ] [ 3 wlet-&&-test ] unit-test
+[ f ] [ 8 wlet-&&-test ] unit-test
+[ t ] [ 12 wlet-&&-test ] unit-test
+
+: fry-locals-test-1 ( -- n )
+    [let | | 6 '[ [let | A [ 4 ] | A _ + ] ] call ] ;
+
+\ fry-locals-test-1 must-infer
+[ 10 ] [ fry-locals-test-1 ] unit-test
+
+:: fry-locals-test-2 ( -- n )
+    [let | | 6 '[ [let | A [ 4 ] | A _ + ] ] call ] ;
+
+\ fry-locals-test-2 must-infer
+[ 10 ] [ fry-locals-test-2 ] unit-test
+
+[ 1 ] [ 3 4 [| | '[ [ _ swap - ] call ] call ] call ] unit-test
+[ -1 ] [ 3 4 [| | [| a | a - ] call ] call ] unit-test
+[ -1 ] [ 3 4 [| | [| a | a - ] curry call ] call ] unit-test
+[ -1 ] [ 3 4 [| a | a - ] curry call ] unit-test
+[ 1 ] [ 3 4 [| | '[ [| a | _ a - ] call ] call ] call ] unit-test
+[ -1 ] [ 3 4 [| | '[ [| a | a _ - ] call ] call ] call ] unit-test
+
+[ { 1 2 3 4 } ] [
+    1 3 2 4
+    [| | '[ [| a b | a _ b _ 4array ] call ] call ] call
+] unit-test
+
+[ 10 ] [
+    [| | 0 '[ [let | A [ 10 ] | A _ + ] ] call ] call
+] unit-test
\ No newline at end of file
index e66b1531d206c7dfafdabfa8f64986ffb9a00d47..b78b95bc245bd05142ce5bd540770c21f84e36e4 100644 (file)
@@ -6,18 +6,36 @@ quotations debugger macros arrays macros splitting combinators
 prettyprint.backend definitions prettyprint hashtables
 prettyprint.sections sets sequences.private effects
 effects.parser generic generic.parser compiler.units accessors
-locals.backend memoize macros.expander lexer classes summary ;
+locals.backend memoize macros.expander lexer classes summary fry
+fry.private ;
 IN: locals
 
-! Inspired by
-! http://cat-language.googlecode.com/svn/trunk/CatPointFreeForm.cs
-
 ERROR: >r/r>-in-lambda-error ;
 
 M: >r/r>-in-lambda-error summary
     drop
     "Explicit retain stack manipulation is not permitted in lambda bodies" ;
 
+ERROR: binding-form-in-literal-error ;
+
+M: binding-form-in-literal-error summary
+    drop "[let, [let* and [wlet not permitted inside literals" ;
+
+ERROR: local-writer-in-literal-error ;
+
+M: local-writer-in-literal-error summary
+    drop "Local writer words not permitted inside literals" ;
+
+ERROR: local-word-in-literal-error ;
+
+M: local-word-in-literal-error summary
+    drop "Local words not permitted inside literals" ;
+
+ERROR: bad-lambda-rewrite output ;
+
+M: bad-lambda-rewrite summary
+    drop "You have found a bug in locals. Please report." ;
+
 <PRIVATE
 
 TUPLE: lambda vars body ;
@@ -85,60 +103,53 @@ C: <quote> quote
     [ dup quote? [ local>> ] when eq? ] with find drop ;
 
 : read-local-quot ( obj args -- quot )
-    local-index 1+ [ get-local ] curry ;
+    local-index neg [ get-local ] curry ;
+
+GENERIC# localize 1 ( obj args -- quot )
+
+M: local localize read-local-quot ;
+
+M: quote localize [ local>> ] dip read-local-quot ;
 
-: localize-writer ( obj args -- quot )
-    >r "local-reader" word-prop r>
+M: local-word localize read-local-quot [ call ] append ;
+
+M: local-reader localize read-local-quot [ local-value ] append ;
+
+M: local-writer localize
+    [ "local-reader" word-prop ] dip
     read-local-quot [ set-local-value ] append ;
 
-: localize ( obj args -- quot )
-    {
-        { [ over local? ]        [ read-local-quot ] }
-        { [ over quote? ]        [ >r local>> r> read-local-quot ] }
-        { [ over local-word? ]   [ read-local-quot [ call ] append ] }
-        { [ over local-reader? ] [ read-local-quot [ local-value ] append ] }
-        { [ over local-writer? ] [ localize-writer ] }
-        { [ over \ lambda eq? ]  [ 2drop [ ] ] }
-        { [ t ]                  [ drop 1quotation ] }
-    } cond ;
+M: object localize drop 1quotation ;
 
 UNION: special local quote local-word local-reader local-writer ;
 
 : load-locals-quot ( args -- quot )
-    [
-        [ ]
-    ] [
+    [ [ ] ] [
         dup [ local-reader? ] contains? [
-            <reversed> [
-                local-reader? [ 1array >r ] [ >r ] ?
-            ] map concat
-        ] [
-            length [ load-locals ] curry >quotation
-        ] if
+            dup [ local-reader? [ 1array ] [ ] ? ] map spread>quot
+        ] [ [ ] ] if swap length [ load-locals ] curry append
     ] if-empty ;
 
 : drop-locals-quot ( args -- quot )
     [ [ ] ] [ length [ drop-locals ] curry ] if-empty ;
 
 : point-free-body ( quot args -- newquot )
-    >r but-last-slice r> [ localize ] curry map concat ;
+    [ but-last-slice ] dip '[ _ localize ] map concat ;
 
 : point-free-end ( quot args -- newquot )
     over peek special?
-    [ dup drop-locals-quot >r >r peek r> localize r> append ]
-    [ dup drop-locals-quot nip swap peek suffix ]
+    [ dup drop-locals-quot [ [ peek ] dip localize ] dip append ]
+    [ drop-locals-quot swap peek suffix ]
     if ;
 
 : (point-free) ( quot args -- newquot )
     [ nip load-locals-quot ]
-    [ point-free-body ]
-    [ point-free-end ]
-    2tri 3append >quotation ;
+    [ reverse point-free-body ]
+    [ reverse point-free-end ]
+    2tri [ ] 3append-as ;
 
 : point-free ( quot args -- newquot )
-    over empty?
-    [ nip length \ drop <repetition> >quotation ]
-    [ (point-free) ] if ;
+    over empty? [ nip length '[ _ ndrop ] ] [ (point-free) ] if ;
 
 UNION: lexical local local-reader local-writer local-word ;
 
@@ -206,6 +217,8 @@ M: array rewrite-literal? [ rewrite-literal? ] contains? ;
 
 M: quotation rewrite-literal? [ rewrite-literal? ] contains? ;
 
+M: wrapper rewrite-literal? drop t ;
+
 M: hashtable rewrite-literal? drop t ;
 
 M: vector rewrite-literal? drop t ;
@@ -225,9 +238,6 @@ GENERIC: rewrite-element ( obj -- )
 M: array rewrite-element
     dup rewrite-literal? [ rewrite-sequence ] [ , ] if ;
 
-M: quotation rewrite-element
-    dup rewrite-literal? [ rewrite-sequence ] [ , ] if ;
-
 M: vector rewrite-element rewrite-sequence ;
 
 M: hashtable rewrite-element >alist rewrite-sequence \ >hashtable , ;
@@ -235,12 +245,27 @@ M: hashtable rewrite-element >alist rewrite-sequence \ >hashtable , ;
 M: tuple rewrite-element
     [ tuple-slots rewrite-elements ] [ class literalize , ] bi \ boa , ;
 
+M: quotation rewrite-element local-rewrite* ;
+
+M: lambda rewrite-element local-rewrite* ;
+
+M: binding-form rewrite-element binding-form-in-literal-error ;
+
 M: local rewrite-element , ;
 
 M: local-reader rewrite-element , ;
 
+M: local-writer rewrite-element
+    local-writer-in-literal-error ;
+
+M: local-word rewrite-element
+    local-word-in-literal-error ;
+
 M: word rewrite-element literalize , ;
 
+M: wrapper rewrite-element
+    dup rewrite-literal? [ wrapped>> rewrite-element ] [ , ] if ;
+
 M: object rewrite-element , ;
 
 M: array local-rewrite* rewrite-element ;
@@ -251,8 +276,10 @@ M: tuple local-rewrite* rewrite-element ;
 
 M: hashtable local-rewrite* rewrite-element ;
 
+M: wrapper local-rewrite* rewrite-element ;
+
 M: word local-rewrite*
-    dup { >r r> } memq?
+    dup { >r r> load-locals get-local drop-locals } memq?
     [ >r/r>-in-lambda-error ] [ call-next-method ] if ;
 
 M: object lambda-rewrite* , ;
@@ -269,8 +296,9 @@ M: object local-rewrite* , ;
 : make-locals ( seq -- words assoc )
     [ [ make-local ] map ] H{ } make-assoc ;
 
-: make-local-word ( name -- word )
-    <local-word> dup dup name>> set ;
+: make-local-word ( name def -- word )
+    [ <local-word> [ dup name>> set ] [ ] [ ] tri ] dip
+    "local-word-def" set-word-prop ;
 
 : push-locals ( assoc -- )
     use get push ;
@@ -288,27 +316,26 @@ SYMBOL: in-lambda?
     "|" parse-tokens make-locals dup push-locals
     \ ] (parse-lambda) <lambda> ;
 
-: parse-binding ( -- pair/f )
+: parse-binding ( end -- pair/f )
     scan {
         { [ dup not ] [ unexpected-eof ] }
-        { [ dup "|" = ] [ drop f ] }
-        { [ dup "!" = ] [ drop POSTPONE: ! parse-binding ] }
-        [ scan-object 2array ]
+        { [ 2dup = ] [ 2drop f ] }
+        [ nip scan-object 2array ]
     } cond ;
 
-: (parse-bindings) ( -- )
-    parse-binding [
+: (parse-bindings) ( end -- )
+    dup parse-binding dup [
         first2 [ make-local ] dip 2array ,
         (parse-bindings)
-    ] when* ;
+    ] [ 2drop ] if ;
 
-: parse-bindings ( -- bindings vars )
+: parse-bindings ( end -- bindings vars )
     [
         [ (parse-bindings) ] H{ } make-assoc
         dup push-locals
     ] { } make swap ;
 
-: parse-bindings* ( -- words assoc )
+: parse-bindings* ( end -- words assoc )
     [
         [
             namespace push-locals
@@ -317,13 +344,13 @@ SYMBOL: in-lambda?
         ] { } make-assoc
     ] { } make swap ;
 
-: (parse-wbindings) ( -- )
-    parse-binding [
-        first2 >r make-local-word r> 2array ,
+: (parse-wbindings) ( end -- )
+    dup parse-binding dup [
+        first2 [ make-local-word ] keep 2array ,
         (parse-wbindings)
-    ] when* ;
+    ] [ 2drop ] if ;
 
-: parse-wbindings ( -- bindings vars )
+: parse-wbindings ( end -- bindings vars )
     [
         [ (parse-wbindings) ] H{ } make-assoc
         dup push-locals
@@ -331,7 +358,7 @@ SYMBOL: in-lambda?
 
 : let-rewrite ( body bindings -- )
     <reversed> [
-        >r 1array r> spin <lambda> [ call ] curry compose
+        [ 1array ] dip spin <lambda> '[ @ @ ]
     ] assoc-each local-rewrite* \ call , ;
 
 M: let local-rewrite*
@@ -342,18 +369,18 @@ M: let* local-rewrite*
 
 M: wlet local-rewrite*
     [ body>> ] [ bindings>> ] bi
-    [ [ ] curry ] assoc-map
+    [ '[ _ ] ] assoc-map
     let-rewrite ;
 
 : parse-locals ( -- vars assoc )
-    ")" parse-effect
+    "(" expect ")" parse-effect
     word [ over "declared-effect" set-word-prop ] when*
     in>> [ dup pair? [ first ] when ] map make-locals dup push-locals ;
 
 : parse-locals-definition ( word -- word quot )
-    "(" expect parse-locals \ ; (parse-lambda) <lambda>
+    parse-locals \ ; (parse-lambda) <lambda>
     2dup "lambda" set-word-prop
-    lambda-rewrite first ;
+    lambda-rewrite dup length 1 = [ first ] [ bad-lambda-rewrite ] if ;
 
 : (::) ( -- word def ) CREATE-WORD parse-locals-definition ;
 
@@ -369,15 +396,15 @@ PRIVATE>
 : [| parse-lambda parsed-lambda ; parsing
 
 : [let
-    "|" expect parse-bindings
+    "|" expect "|" parse-bindings
     \ ] (parse-lambda) <let> parsed-lambda ; parsing
 
 : [let*
-    "|" expect parse-bindings*
+    "|" expect "|" parse-bindings*
     \ ] (parse-lambda) <let*> parsed-lambda ; parsing
 
 : [wlet
-    "|" expect parse-wbindings
+    "|" expect "|" parse-wbindings
     \ ] (parse-lambda) <wlet> parsed-lambda ; parsing
 
 : :: (::) define ; parsing
@@ -417,7 +444,7 @@ M: lambda pprint*
     \ | pprint-word
     t <inset
     <block
-    [ <block >r pprint-var r> pprint* block> ] assoc-each
+    [ <block [ pprint-var ] dip pprint* block> ] assoc-each
     block>
     \ | pprint-word
     <block pprint-elements block>
@@ -483,3 +510,15 @@ M: lambda-method synopsis*
     method-stack-effect effect>string comment. ;
 
 PRIVATE>
+
+! Locals and fry
+M: binding-form count-inputs body>> count-inputs ;
+
+M: lambda count-inputs body>> count-inputs ;
+
+M: lambda deep-fry
+    clone [ shallow-fry swap ] change-body
+    [ [ vars>> length ] keep '[ _ _ mnswap @ ] , ] [ drop [ncurry] % ] 2bi ;
+
+M: binding-form deep-fry
+    clone [ fry '[ @ call ] ] change-body , ;
index 1e1e31c501fc5d9ef87b057c20fae1dd4034417a..d84e49f784cb63781bcf1c18e414e9ae1fde1d2b 100644 (file)
@@ -38,8 +38,8 @@ SYMBOL: message-histogram
 \r
 : histogram. ( assoc quot -- )\r
     standard-table-style [\r
-        >r >alist sort-values <reversed> r> [\r
-            [ >r swap r> with-cell pprint-cell ] with-row\r
+        [ >alist sort-values <reversed> ] dip [\r
+            [ swapd with-cell pprint-cell ] with-row\r
         ] curry assoc-each\r
     ] tabular-output ;\r
 \r
@@ -69,7 +69,7 @@ SYMBOL: message-histogram
     errors. ;\r
 \r
 : analyze-log ( lines word-names -- )\r
-    >r parse-log r> analyze-entries analysis. ;\r
+    [ parse-log ] dip analyze-entries analysis. ;\r
 \r
 : analyze-log-file ( service word-names -- )\r
-    >r parse-log-file r> analyze-entries analysis. ;\r
+    [ parse-log-file ] dip analyze-entries analysis. ;\r
index 7c14cae78e150068baa3c002c53866fbe56ae356..275d900f3dff82c29120d396d930bff0bfb22816 100644 (file)
@@ -117,7 +117,6 @@ ARTICLE: "logging" "Logging framework"
 { $subsection "logging.rotation" }
 { $subsection "logging.parser" }
 { $subsection "logging.analysis" }
-{ $subsection "logging.insomniac" }
 { $subsection "logging.server" } ;
 
 ABOUT: "logging"
index ae9ef877dd74e79d9da34efa16ead6ea24dfaafd..47de8805598411d4423597c7b38089b5ad5f6c65 100644 (file)
@@ -123,4 +123,3 @@ USE: vocabs.loader
 \r
 "logging.parser" require\r
 "logging.analysis" require\r
-"logging.insomniac" require\r
index 47656e86555d0476580c6b396e83e81312345424..1872bb0af2045b8646b6186d360d2cbb4319df7a 100644 (file)
@@ -26,7 +26,7 @@ SYMBOL: log-files
 : log-stream ( service -- stream )\r
     log-files get [ open-log-stream ] cache ;\r
 \r
-: multiline-header 20 CHAR: - <string> ; foldable\r
+: multiline-header ( -- string ) 20 CHAR: - <string> ; foldable\r
 \r
 : (write-message) ( msg name>> level multi? -- )\r
     [\r
index 794d523d006c11504c32aeb16db8ea3950d3cfd7..1481e6eea57d832bc177a0207e26e156d1c5feb7 100644 (file)
@@ -22,9 +22,3 @@ M: macro definition "macro" word-prop ;
 
 M: macro reset-word
     [ call-next-method ] [ f "macro" set-word-prop ] bi ;
-
-: n*quot ( n seq -- seq' ) <repetition> concat >quotation ;
-
-: saver ( n -- quot ) \ >r <repetition> >quotation ;
-
-: restorer ( n -- quot ) \ r> <repetition> >quotation ;
index c546555d077c26dcd5eb3d4e34b3d5e8100cdc2c..7d393dadc9a2bab92567ec252275d2009915e97c 100644 (file)
@@ -73,7 +73,7 @@ MACRO: match-cond ( assoc -- )
     2dup [ length ] bi@ < [ 2drop f f ]
     [
         2dup length head over match
-        [ nip swap ?1-tail ] [ >r rest r> (match-first) ] if*
+        [ nip swap ?1-tail ] [ [ rest ] dip (match-first) ] if*
     ] if ;
     
 : match-first ( seq pattern-seq -- bindings )
index 9ed164330bcd3edfc6fa3cfe6f14fa4deb4e267d..18ae8e1497f4aef45b150bc2479adb104c871a24 100644 (file)
@@ -204,8 +204,25 @@ HELP: on-bits
         "64 on-bits .h"
         "ffffffffffffffff"
     }
+} ;
+
+HELP: toggle-bit
+{ $values
+     { "m" integer }
+     { "n" integer }
+     { "m'" integer }
 }
-;
+{ $description "Toggles the nth bit of an integer." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "0 3 toggle-bit .b"
+        "1000"
+    }
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "BIN: 1000 3 toggle-bit .b"
+        "0"
+    }
+} ;
 
 HELP: set-bit
 { $values
index 442299295633dfa3e7f2134a9f8236faa5f46551..979c62dcfbdd6f0daff316229fd38f1ed219a593 100644 (file)
@@ -29,3 +29,6 @@ IN: math.bitwise.tests
 \ foo must-infer
 
 [ 1 ] [ { 1 } flags ] unit-test
+
+[ 8 ] [ 0 3 toggle-bit ] unit-test
+[ 0 ] [ 8 3 toggle-bit ] unit-test
index afd83d44585fdad313e5f651f503f88cbb55923f..89a21b65ab4555c021b63c2d07b063bd24c5c8d6 100644 (file)
@@ -17,23 +17,19 @@ IN: math.bitwise
 : bits ( m n -- m' ) 2^ wrap ; inline
 : mask-bit ( m n -- m' ) 2^ mask ; inline
 : on-bits ( n -- m ) 2^ 1- ; inline
+: toggle-bit ( m n -- m' ) 2^ bitxor ; inline
 
 : shift-mod ( n s w -- n )
     [ shift ] dip 2^ wrap ; inline
 
 : bitroll ( x s w -- y )
     [ wrap ] keep
-    [ shift-mod ]
-    [ [ - ] keep shift-mod ] 3bi bitor ; inline
+    [ shift-mod ] [ [ - ] keep shift-mod ] 3bi bitor ; inline
 
 : bitroll-32 ( n s -- n' ) 32 bitroll ; inline
 
-HINTS: bitroll-32 bignum fixnum ;
-
 : bitroll-64 ( n s -- n' ) 64 bitroll ; inline
 
-HINTS: bitroll-64 bignum fixnum ;
-
 ! 32-bit arithmetic
 : w+ ( int int -- int ) + 32 bits ; inline
 : w- ( int int -- int ) - 32 bits ; inline
diff --git a/basis/math/combinatorics/authors.txt b/basis/math/combinatorics/authors.txt
new file mode 100644 (file)
index 0000000..708cc3e
--- /dev/null
@@ -0,0 +1,3 @@
+Slava Pestov
+Doug Coleman
+Aaron Schaefer
diff --git a/basis/math/combinatorics/combinatorics-docs.factor b/basis/math/combinatorics/combinatorics-docs.factor
new file mode 100644 (file)
index 0000000..514c808
--- /dev/null
@@ -0,0 +1,49 @@
+USING: help.markup help.syntax kernel math math.order sequences ;
+IN: math.combinatorics
+
+HELP: factorial
+{ $values { "n" "a non-negative integer" } { "n!" integer } }
+{ $description "Outputs the product of all positive integers less than or equal to " { $snippet "n" } "." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "4 factorial ." "24" } } ;
+
+HELP: nPk
+{ $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nPk" integer } }
+{ $description "Outputs the total number of unique permutations of size " { $snippet "k" } " (order does matter) that can be taken from a set of size " { $snippet "n" } "." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nPk ." "5040" } } ;
+
+HELP: nCk
+{ $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nCk" integer } }
+{ $description "Outputs the total number of unique combinations of size " { $snippet "k" } " (order does not matter) that can be taken from a set of size " { $snippet "n" } ". Commonly written as \"n choose k\"." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nCk ." "210" } } ;
+
+HELP: permutation
+{ $values { "n" "a non-negative integer" } { "seq" sequence } { "seq" sequence } }
+{ $description "Outputs the " { $snippet "nth" } " lexicographical permutation of " { $snippet "seq" } "." }
+{ $notes "Permutations are 0-based and a bounds error will be thrown if " { $snippet "n" } " is larger than " { $snippet "seq length factorial 1-" } "." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "1 3 permutation ." "{ 0 2 1 }" } { $example "USING: math.combinatorics prettyprint ;" "5 { \"apple\" \"banana\" \"orange\" } permutation ." "{ \"orange\" \"banana\" \"apple\" }" } } ;
+
+HELP: all-permutations
+{ $values { "seq" sequence } { "seq" sequence } }
+{ $description "Outputs a sequence containing all permutations of " { $snippet "seq" } " in lexicographical order." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "3 all-permutations ." "{ { 0 1 2 } { 0 2 1 } { 1 0 2 } { 1 2 0 } { 2 0 1 } { 2 1 0 } }" } } ;
+
+HELP: inverse-permutation
+{ $values { "seq" sequence } { "permutation" sequence } }
+{ $description "Outputs a sequence of indices representing the lexicographical permutation of " { $snippet "seq" } "." }
+{ $notes "All items in " { $snippet "seq" } " must be comparable by " { $link <=> } "." }
+{ $examples { $example "USING: math.combinatorics prettyprint ;" "\"dcba\" inverse-permutation ." "{ 3 2 1 0 }" } { $example "USING: math.combinatorics prettyprint ;" "{ 12 56 34 78 } inverse-permutation ." "{ 0 2 1 3 }" } } ;
+
+
+IN: math.combinatorics.private
+
+HELP: factoradic
+{ $values { "n" integer } { "factoradic" sequence } }
+{ $description "Converts a positive integer " { $snippet "n" } " to factoradic form.  The factoradic of an integer is its representation based on a mixed radix numerical system that corresponds to the values of " { $snippet "n" } " factorial." }
+{ $examples { $example "USING: math.combinatorics.private  prettyprint ;" "859 factoradic ." "{ 1 1 0 3 0 1 0 }" } } ;
+
+HELP: >permutation
+{ $values { "factoradic" sequence } { "permutation" sequence } }
+{ $description "Converts an integer represented in factoradic form into its corresponding unique permutation (0-based)." }
+{ $notes "For clarification, the following two statements are equivalent:" { $code "10 factoradic >permutation" "{ 1 2 0 0 } >permutation" } }
+{ $examples { $example "USING: math.combinatorics.private prettyprint ;" "{ 0 0 0 0 } >permutation ." "{ 0 1 2 3 }" } } ;
+
diff --git a/basis/math/combinatorics/combinatorics-tests.factor b/basis/math/combinatorics/combinatorics-tests.factor
new file mode 100644 (file)
index 0000000..5ef435a
--- /dev/null
@@ -0,0 +1,45 @@
+USING: math.combinatorics math.combinatorics.private tools.test ;
+IN: math.combinatorics.tests
+
+[ { } ] [ 0 factoradic ] unit-test
+[ { 1 0 } ] [ 1 factoradic ] unit-test
+[ { 1 1 0 3 0 1 0 } ] [ 859 factoradic ] unit-test
+
+[ { 0 1 2 3 } ] [ { 0 0 0 0 } >permutation ] unit-test
+[ { 0 1 3 2 } ] [ { 0 0 1 0 } >permutation ] unit-test
+[ { 1 2 0 6 3 5 4 } ] [ { 1 1 0 3 0 1 0 } >permutation ] unit-test
+
+[ { 0 1 2 3 } ] [ 0 4 permutation-indices ] unit-test
+[ { 0 1 3 2 } ] [ 1 4 permutation-indices ] unit-test
+[ { 1 2 0 6 3 5 4 } ] [ 859 7 permutation-indices ] unit-test
+
+[ 1 ] [ 0 factorial ] unit-test
+[ 1 ] [ 1 factorial ] unit-test
+[ 3628800 ] [ 10 factorial ] unit-test
+
+[ 1 ] [ 3 0 nPk ] unit-test
+[ 6 ] [ 3 2 nPk ] unit-test
+[ 6 ] [ 3 3 nPk ] unit-test
+[ 0 ] [ 3 4 nPk ] unit-test
+[ 311875200 ] [ 52 5 nPk ] unit-test
+[ 672151459757865654763838640470031391460745878674027315200000000000 ] [ 52 47 nPk ] unit-test
+
+[ 1 ] [ 3 0 nCk ] unit-test
+[ 3 ] [ 3 2 nCk ] unit-test
+[ 1 ] [ 3 3 nCk ] unit-test
+[ 0 ] [ 3 4 nCk ] unit-test
+[ 2598960 ] [ 52 5 nCk ] unit-test
+[ 2598960 ] [ 52 47 nCk ] unit-test
+
+[ { "a" "b" "c" "d" } ] [ 0 { "a" "b" "c" "d" } permutation ] unit-test
+[ { "d" "c" "b" "a" } ] [ 23 { "a" "b" "c" "d" } permutation ] unit-test
+[ { "d" "a" "b" "c" } ] [ 18 { "a" "b" "c" "d" } permutation ] unit-test
+
+[ { { "a" "b" "c" } { "a" "c" "b" }
+    { "b" "a" "c" } { "b" "c" "a" }
+    { "c" "a" "b" } { "c" "b" "a" } } ] [ { "a" "b" "c" } all-permutations ] unit-test
+
+[ { 0 1 2 } ] [ { "a" "b" "c" } inverse-permutation ] unit-test
+[ { 2 1 0 } ] [ { "c" "b" "a" } inverse-permutation ] unit-test
+[ { 3 0 2 1 } ] [ { 12 45 34 2 } inverse-permutation ] unit-test
+
diff --git a/basis/math/combinatorics/combinatorics.factor b/basis/math/combinatorics/combinatorics.factor
new file mode 100644 (file)
index 0000000..1bc692c
--- /dev/null
@@ -0,0 +1,55 @@
+! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs kernel math math.order math.ranges mirrors
+namespaces sequences sorting fry ;
+IN: math.combinatorics
+
+<PRIVATE
+
+: possible? ( n m -- ? )
+    0 rot between? ; inline
+
+: twiddle ( n k -- n k )
+    2dup - dupd > [ dupd - ] when ; inline
+
+! See this article for explanation of the factoradic-based permutation methodology:
+! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
+
+: factoradic ( n -- factoradic )
+    0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
+
+: (>permutation) ( seq n -- seq )
+    [ '[ _ dupd >= [ 1+ ] when ] map ] keep prefix ;
+
+: >permutation ( factoradic -- permutation )
+    reverse 1 cut [ (>permutation) ] each ;
+
+: permutation-indices ( n seq -- permutation )
+    length [ factoradic ] dip 0 pad-left >permutation ;
+
+PRIVATE>
+
+: factorial ( n -- n! )
+    1 [ 1+ * ] reduce ;
+
+: nPk ( n k -- nPk )
+    2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
+
+: nCk ( n k -- nCk )
+    twiddle [ nPk ] keep factorial / ;
+
+: permutation ( n seq -- seq )
+    [ permutation-indices ] keep nths ;
+
+: all-permutations ( seq -- seq )
+    [ length factorial ] keep '[ _ permutation ] map ;
+
+: each-permutation ( seq quot -- )
+    [ [ length factorial ] keep ] dip
+    '[ _ permutation @ ] each ; inline
+
+: reduce-permutations ( seq initial quot -- result )
+    swapd each-permutation ; inline
+
+: inverse-permutation ( seq -- permutation )
+    <enum> >alist sort-values keys ;
diff --git a/basis/math/combinatorics/summary.txt b/basis/math/combinatorics/summary.txt
new file mode 100644 (file)
index 0000000..ecd43de
--- /dev/null
@@ -0,0 +1 @@
+Permutations and combinations
index acc8a9d6d6f9505da81b43b1bb436d9ddd8ec059..c228684e321f1ae61ef091af4bf16793aee5abdd 100644 (file)
@@ -14,8 +14,8 @@ M: complex imaginary-part imaginary>> ;
 M: complex absq >rect [ sq ] bi@ + ;
 
 : 2>rect ( x y -- xr yr xi yi )
-    [ [ real-part ] bi@ ] 2keep
-    [ imaginary-part ] bi@ ; inline
+    [ [ real-part ] bi@ ]
+    [ [ imaginary-part ] bi@ ] 2bi ; inline
 
 M: complex hashcode*
     nip >rect [ hashcode ] bi@ bitxor ;
@@ -28,21 +28,21 @@ M: complex equal?
 M: complex number=
     2>rect number= [ number= ] [ 2drop f ] if ;
 
-: *re ( x y -- xr*yr xi*ri ) 2>rect * >r * r> ; inline
-: *im ( x y -- xi*yr xr*yi ) 2>rect >r * swap r> * ; inline
+: *re ( x y -- xr*yr xi*ri ) 2>rect [ * ] 2bi@ ; inline
+: *im ( x y -- xi*yr xr*yi ) 2>rect [ * swap ] dip * ; inline
 
-M: complex + 2>rect + >r + r> (rect>) ;
-M: complex - 2>rect - >r - r> (rect>) ;
-M: complex * 2dup *re - -rot *im + (rect>) ;
+M: complex + 2>rect [ + ] 2bi@ (rect>) ;
+M: complex - 2>rect [ - ] 2bi@ (rect>) ;
+M: complex * [ *re - ] [ *im + ] 2bi (rect>) ;
 
 : complex/ ( x y -- r i m )
-    dup absq >r 2dup *re + -rot *im - r> ; inline
+    [ [ *re + ] [ *im - ] 2bi ] keep absq ; inline
 
-M: complex / complex/ tuck / >r / r> (rect>) ;
+M: complex / complex/ tuck [ / ] 2bi@ (rect>) ;
 
 M: complex abs absq >float fsqrt ;
 
-M: complex sqrt >polar swap fsqrt swap 2.0 / polar> ;
+M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ;
 
 IN: syntax
 
index c582c560a9c867a20ef32598c8914572e8789a59..8411baf94ca310e063e7a68150985ab9d725b773 100644 (file)
@@ -92,16 +92,6 @@ PRIVATE>
 : 0^ ( x -- z )
     dup zero? [ drop 0./0. ] [ 0 < 1./0. 0 ? ] if ; inline
 
-PRIVATE>
-
-: ^ ( x y -- z )
-    {
-        { [ over zero? ] [ nip 0^ ] }
-        { [ dup integer? ] [ integer^ ] }
-        { [ 2dup real^? ] [ fpow ] }
-        [ ^complex ]
-    } cond ;
-
 : (^mod) ( n x y -- z )
     1 swap [
         [ dupd * pick mod ] when [ sq over mod ] dip
@@ -114,6 +104,16 @@ PRIVATE>
         swap [ /mod [ over * swapd - ] dip ] keep (gcd)
     ] if ;
 
+PRIVATE>
+
+: ^ ( x y -- z )
+    {
+        { [ over zero? ] [ nip 0^ ] }
+        { [ dup integer? ] [ integer^ ] }
+        { [ 2dup real^? ] [ fpow ] }
+        [ ^complex ]
+    } cond ; inline
+
 : gcd ( x y -- a d )
     [ 0 1 ] 2dip (gcd) dup 0 < [ neg ] when ; foldable
 
@@ -174,47 +174,61 @@ M: real log dup 0.0 >= [ flog ] [ 0.0 rect> log ] if ;
 
 M: complex log >polar swap flog swap rect> ;
 
-: cos ( x -- y )
-    dup complex? [
-        >float-rect 2dup
-        fcosh swap fcos * -rot
-        fsinh swap fsin neg * rect>
-    ] [ fcos ] if ; foldable
+GENERIC: cos ( x -- y ) foldable
+
+M: complex cos
+    >float-rect
+    [ [ fcos ] [ fcosh ] bi* * ]
+    [ [ fsin neg ] [ fsinh ] bi* * ] 2bi rect> ;
+
+M: real cos fcos ;
 
 : sec ( x -- y ) cos recip ; inline
 
-: cosh ( x -- y )
-    dup complex? [
-        >float-rect 2dup
-        fcos swap fcosh * -rot
-        fsin swap fsinh * rect>
-    ] [ fcosh ] if ; foldable
+GENERIC: cosh ( x -- y ) foldable
+
+M: complex cosh
+    >float-rect
+    [ [ fcosh ] [ fcos ] bi* * ]
+    [ [ fsinh ] [ fsin ] bi* * ] 2bi rect> ;
+
+M: real cosh fcosh ;
 
 : sech ( x -- y ) cosh recip ; inline
 
-: sin ( x -- y )
-    dup complex? [
-        >float-rect 2dup
-        fcosh swap fsin * -rot
-        fsinh swap fcos * rect>
-    ] [ fsin ] if ; foldable
+GENERIC: sin ( x -- y ) foldable
+
+M: complex sin
+    >float-rect
+    [ [ fsin ] [ fcosh ] bi* * ]
+    [ [ fcos ] [ fsinh ] bi* * ] 2bi rect> ;
+
+M: real sin fsin ;
 
 : cosec ( x -- y ) sin recip ; inline
 
-: sinh ( x -- y )
-    dup complex? [
-        >float-rect 2dup
-        fcos swap fsinh * -rot
-        fsin swap fcosh * rect>
-    ] [ fsinh ] if ; foldable
+GENERIC: sinh ( x -- y ) foldable
+
+M: complex sinh 
+    >float-rect
+    [ [ fsinh ] [ fcos ] bi* * ]
+    [ [ fcosh ] [ fsin ] bi* * ] 2bi rect> ;
+
+M: real sinh fsinh ;
 
 : cosech ( x -- y ) sinh recip ; inline
 
-: tan ( x -- y )
-    dup complex? [ dup sin swap cos / ] [ ftan ] if ; inline
+GENERIC: tan ( x -- y ) foldable
+
+M: complex tan [ sin ] [ cos ] bi / ;
+
+M: real tan ftan ;
 
-: tanh ( x -- y )
-    dup complex? [ dup sinh swap cosh / ] [ ftanh ] if ; inline
+GENERIC: tanh ( x -- y ) foldable
+
+M: complex tanh [ sinh ] [ cosh ] bi / ;
+
+M: real tanh ftanh ;
 
 : cot ( x -- y ) tan recip ; inline
 
@@ -231,7 +245,7 @@ M: complex log >polar swap flog swap rect> ;
 : acosech ( x -- y ) recip asinh ; inline
 
 : atanh ( x -- y )
-    dup 1+ swap 1- neg / log 2 / ; inline
+    [ 1+ ] [ 1- neg ] bi / log 2 / ; inline
 
 : acoth ( x -- y ) recip atanh ; inline
 
@@ -246,8 +260,11 @@ M: complex log >polar swap flog swap rect> ;
     dup [-1,1]? [ facos ] [ asin pi 2 / swap - ] if ;
     inline
 
-: atan ( x -- y )
-    dup complex? [ i* atanh i* ] [ fatan ] if ; inline
+GENERIC: atan ( x -- y ) foldable
+
+M: complex atan i* atanh i* ;
+
+M: real atan fatan ;
 
 : asec ( x -- y ) recip acos ; inline
 
index dd634f4a3b7a0c823a3a14031c4c2818e0a75713..a7cefceae82c50f918310dce7bc05017590853dc 100644 (file)
@@ -37,7 +37,7 @@ M: rect rect-dim dim>> ;
     over rect-loc v+ swap rect-dim <rect> ;
 
 : (rect-intersect) ( rect rect -- array array )
-    2rect-extent vmin >r vmax r> ;
+    2rect-extent [ vmax ] [ vmin ] 2bi* ;
 
 : rect-intersect ( rect1 rect2 -- newrect )
     (rect-intersect) <extent-rect> ;
@@ -46,7 +46,7 @@ M: rect rect-dim dim>> ;
     (rect-intersect) [v-] { 0 0 } = ;
 
 : (rect-union) ( rect rect -- array array )
-    2rect-extent vmax >r vmin r> ;
+    2rect-extent [ vmin ] [ vmax ] 2bi* ;
 
 : rect-union ( rect1 rect2 -- newrect )
     (rect-union) <extent-rect> ;
index 8bda6a6dd0421cedbfc92b9d7fc64cc722ced5b9..96f5f134cc7ce047f62f0735ebf884f7b869f74b 100644 (file)
@@ -5,69 +5,69 @@ IN: math.libm
 
 : facos ( x -- y )
     "double" "libm" "acos" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fasin ( x -- y )
     "double" "libm" "asin" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fatan ( x -- y )
     "double" "libm" "atan" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fatan2 ( x y -- z )
     "double" "libm" "atan2" { "double" "double" } alien-invoke ;
-    foldable
+    inline
 
 : fcos ( x -- y )
     "double" "libm" "cos" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fsin ( x -- y )
     "double" "libm" "sin" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : ftan ( x -- y )
     "double" "libm" "tan" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fcosh ( x -- y )
     "double" "libm" "cosh" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fsinh ( x -- y )
     "double" "libm" "sinh" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : ftanh ( x -- y )
     "double" "libm" "tanh" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fexp ( x -- y )
     "double" "libm" "exp" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : flog ( x -- y )
     "double" "libm" "log" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fpow ( x y -- z )
     "double" "libm" "pow" { "double" "double" } alien-invoke ;
-    foldable
+    inline
 
 : fsqrt ( x -- y )
     "double" "libm" "sqrt" { "double" } alien-invoke ;
-    foldable
+    inline
     
 ! Windows doesn't have these...
 : facosh ( x -- y )
     "double" "libm" "acosh" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fasinh ( x -- y )
     "double" "libm" "asinh" { "double" } alien-invoke ;
-    foldable
+    inline
 
 : fatanh ( x -- y )
     "double" "libm" "atanh" { "double" } alien-invoke ;
-    foldable
+    inline
index 388b4127cdac380d7e64ae584358a4afa55e908d..bcf7bb77b0c7fde12eec3732ec5ef99513be1d27 100644 (file)
@@ -11,6 +11,8 @@ tools.test math kernel sequences ;
 [ f ] [ \ number= fixnum object math-both-known? ] unit-test
 [ t ] [ \ number= integer fixnum math-both-known? ] unit-test
 [ f ] [ \ >fixnum \ shift derived-ops memq? ] unit-test
+[ f ] [ \ >integer \ /i derived-ops memq? ] unit-test
+[ t ] [ \ fixnum-shift \ shift derived-ops memq? ] unit-test
 
 [ { integer fixnum } ] [ \ +-integer-fixnum integer-op-input-classes ] unit-test
 [ { fixnum fixnum } ] [ \ fixnum+ integer-op-input-classes ] unit-test
@@ -24,4 +26,3 @@ tools.test math kernel sequences ;
 [ fixnum-bitnot ] [ \ bitnot modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+ modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+fast modular-variant ] unit-test
-
index ddde4e124498ae1a7b590b9c9d69085aa7de2ae5..19715357eec1c77c03349820ea1e33bc36e13e08 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel kernel.private math math.private words
-sequences parser namespaces make assocs quotations arrays locals
+sequences parser namespaces make assocs quotations arrays
 generic generic.math hashtables effects compiler.units
-classes.algebra ;
+classes.algebra fry combinators ;
 IN: math.partial-dispatch
 
 PREDICATE: math-partial < word
@@ -45,60 +45,62 @@ M: word integer-op-input-classes
         { bitnot fixnum-bitnot }
     } at swap or ;
 
-:: fixnum-integer-op ( a b fix-word big-word -- c )
-    b tag 0 eq? [
-        a b fix-word execute
-    ] [
-       a fixnum>bignum b big-word execute
-    ] if ; inline
-
-:: integer-fixnum-op ( a b fix-word big-word -- c )
-    a tag 0 eq? [
-        a b fix-word execute
-    ] [
-        a b fixnum>bignum big-word execute
-    ] if ; inline
+: integer-fixnum-op-quot ( fix-word big-word -- quot )
+    [
+        [ over fixnum? ] %
+        [ '[ _ execute ] , ]
+        [ '[ fixnum>bignum _ execute ] , ] bi*
+        \ if ,
+    ] [ ] make ;
 
-:: integer-integer-op ( a b fix-word big-word -- c )
-    b tag 0 eq? [
-        a b fix-word big-word integer-fixnum-op
-    ] [
-        a dup tag 0 eq? [ fixnum>bignum ] when
-        b big-word execute
-    ] if ; inline
+: fixnum-integer-op-quot ( fix-word big-word -- quot )
+    [
+        [ dup fixnum? ] %
+        [ '[ _ execute ] , ]
+        [ '[ [ fixnum>bignum ] dip _ execute ] , ] bi*
+        \ if ,
+    ] [ ] make ;
 
-: integer-op-combinator ( triple -- word )
+: integer-integer-op-quot ( fix-word big-word -- quot )
     [
-        [ second name>> % "-" % ]
-        [ third name>> % "-op" % ]
-        bi
-    ] "" make "math.partial-dispatch" lookup ;
+        [ dup fixnum? ] %
+        2dup integer-fixnum-op-quot ,
+        [
+            [ over fixnum? [ [ fixnum>bignum ] dip ] when ] %
+            nip ,
+        ] [ ] make ,
+        \ if ,
+    ] [ ] make ;
 
 : integer-op-word ( triple -- word )
     [ name>> ] map "-" join "math.partial-dispatch" create ;
 
-: integer-op-quot ( triple fix-word big-word -- quot )
-    rot integer-op-combinator 1quotation 2curry ;
+: integer-op-quot ( fix-word big-word triple -- quot )
+    [ second ] [ third ] bi 2array {
+        { { fixnum integer } [ fixnum-integer-op-quot ] }
+        { { integer fixnum } [ integer-fixnum-op-quot ] }
+        { { integer integer } [ integer-integer-op-quot ] }
+    } case ;
 
-: define-integer-op-word ( triple fix-word big-word -- )
+: define-integer-op-word ( fix-word big-word triple -- )
     [
-        [ 2drop integer-op-word ] [ integer-op-quot ] 3bi
+        [ 2nip integer-op-word ] [ integer-op-quot ] 3bi
         (( x y -- z )) define-declared
     ] [
-        2drop
+        2nip
         [ integer-op-word ] keep
         "derived-from" set-word-prop
     ] 3bi ;
 
 : define-integer-op-words ( triples fix-word big-word -- )
-    [ define-integer-op-word ] 2curry each ;
+    '[ [ _ _ ] dip define-integer-op-word ] each ;
 
 : integer-op-triples ( word -- triples )
     {
         { fixnum integer }
         { integer fixnum }
         { integer integer }
-    } swap [ prefix ] curry map ;
+    } swap '[ _ prefix ] map ;
 
 : define-integer-ops ( word fix-word big-word -- )
     [
@@ -117,7 +119,9 @@ M: word integer-op-input-classes
     { fixnum bignum float }
     [ [ dup 3array ] [ swap method ] 2bi ] with { } map>assoc
     [ nip ] assoc-filter
-    [ def>> peek ] assoc-map % ;
+    [ def>> ] assoc-map
+    [ nip length 1 = ] assoc-filter
+    [ first ] assoc-map % ;
 
 SYMBOL: math-ops
 
@@ -136,7 +140,7 @@ SYMBOL: fast-math-ops
     [ drop math-class-max swap specific-method >boolean ] if ;
 
 : (derived-ops) ( word assoc -- words )
-    swap [ rot first eq? nip ] curry assoc-filter ;
+    swap '[ swap first _ eq? nip ] assoc-filter ;
 
 : derived-ops ( word -- words )
     [ 1array ] [ math-ops get (derived-ops) values ] bi append ;
@@ -150,7 +154,7 @@ SYMBOL: fast-math-ops
 : integer-derived-ops ( word -- words )
     [ math-ops get (derived-ops) ] [ fast-math-ops get (derived-ops) ] bi
     [
-            [
+        [
             drop
             [ second integer class<= ]
             [ third integer class<= ]
@@ -172,7 +176,6 @@ SYMBOL: fast-math-ops
         \ +       define-math-ops
         \ -       define-math-ops
         \ *       define-math-ops
-        \ shift   define-math-ops
         \ mod     define-math-ops
         \ /i      define-math-ops
 
@@ -186,6 +189,9 @@ SYMBOL: fast-math-ops
         \ >=      define-math-ops
         \ number= define-math-ops
 
+        { { shift bignum bignum } bignum-shift } ,
+        { { shift fixnum fixnum } fixnum-shift } ,
+
         \ + \ fixnum+ \ bignum+ define-integer-ops
         \ - \ fixnum- \ bignum- define-integer-ops
         \ * \ fixnum* \ bignum* define-integer-ops
index c8654869e2d727ce99330188a1d5540db7f28bdc..107e81d51f5ea14b1a57321e616fec9f3b22b07f 100644 (file)
@@ -22,6 +22,5 @@ PRIVATE>
 : rise ( pt2 pt1 -- n ) [ second ] bi@ - ;
 : run ( pt2 pt1 -- n ) [ first ] bi@ - ;
 : slope ( pt pt -- slope ) [ rise ] [ run ] 2bi / ;
-: distance ( point point -- float ) v- norm ;
 : midpoint ( point point -- point ) v+ 2 v/n ;
 : linear-solution ( pt pt -- x ) [ drop first2 ] [ slope ] 2bi / - ;
\ No newline at end of file
diff --git a/basis/math/polynomials/authors.txt b/basis/math/polynomials/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/math/polynomials/polynomials-docs.factor b/basis/math/polynomials/polynomials-docs.factor
new file mode 100644 (file)
index 0000000..edffa53
--- /dev/null
@@ -0,0 +1,99 @@
+USING: help.markup help.syntax math sequences ;
+IN: math.polynomials
+
+ARTICLE: "polynomials" "Polynomials"
+"A polynomial is a vector with the highest powers on the right:"
+{ $code "{ 1 1 0 1 } -> 1 + x + x^3" "{ } -> 0" }
+"Numerous words are defined to help with polynomial arithmetic:"
+{ $subsection p= }
+{ $subsection p+ }
+{ $subsection p- }
+{ $subsection p* }
+{ $subsection p-sq }
+{ $subsection powers }
+{ $subsection n*p }
+{ $subsection p/mod }
+{ $subsection pgcd }
+{ $subsection polyval }
+{ $subsection pdiff }
+{ $subsection pextend-conv }
+{ $subsection ptrim }
+{ $subsection 2ptrim } ;
+
+ABOUT: "polynomials"
+
+HELP: powers
+{ $values { "n" integer } { "x" number } { "seq" sequence } }
+{ $description "Output a sequence having " { $snippet "n" } " elements in the format: " { $snippet "{ 1 x x^2 x^3 ... }" } "." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "4 2 powers ." "{ 1 2 4 8 }" } } ;
+
+HELP: p=
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "?" "a boolean" } }
+{ $description "Tests if two polynomials are equal." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 } { 0 1 0 } p= ." "t" } } ;
+
+HELP: ptrim
+{ $values { "p" "a polynomial" } { "p" "a polynomial" } }
+{ $description "Trims excess zeros from a polynomial." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 0 0 } ptrim ." "{ 0 1 }" } } ;
+
+HELP: 2ptrim
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
+{ $description "Trims excess zeros from two polynomials." }
+{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 0 1 0 0 } { 1 0 0 } 2ptrim [ . ] bi@" "{ 0 1 }\n{ 1 }" } } ;
+
+HELP: p+
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
+{ $description "Adds " { $snippet "p" } " and " { $snippet "q" } " component-wise." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 0 1 } { 0 1 } p+ ." "{ 1 1 1 }" } } ;
+
+HELP: p-
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
+{ $description "Subtracts " { $snippet "q" } " from " { $snippet "p" } " component-wise." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 1 1 } { 0 1 } p- ." "{ 1 0 1 }" } } ;
+
+HELP: n*p
+{ $values { "n" number } { "p" "a polynomial" } { "n*p" "a polynomial" } }
+{ $description "Multiplies each element of " { $snippet "p" } " by " { $snippet "n" } "." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "4 { 3 0 1 } n*p ." "{ 12 0 4 }" } } ;
+
+HELP: pextend-conv
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
+{ $description "Convulution, extending to " { $snippet "p_m + q_n - 1" } "." }
+{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 1 0 1 } { 0 1 } pextend-conv [ . ] bi@" "V{ 1 0 1 0 }\nV{ 0 1 0 0 }" } } ;
+
+HELP: p*
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
+{ $description "Multiplies two polynomials." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 2 3 0 0 0 } { 1 2 0 0 } p* ." "{ 1 4 7 6 0 0 0 0 0 }" } } ;
+
+HELP: p-sq
+{ $values { "p" "a polynomial" } { "p^2" "a polynomial" } }
+{ $description "Squares a polynomial." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 2 0 } p-sq ." "{ 1 4 4 0 0 }" } } ;
+
+HELP: p/mod
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "z" "a polynomial" } { "w" "a polynomial" } }
+{ $description "Computes to quotient " { $snippet "z" } " and remainder " { $snippet "w" } " of dividing " { $snippet "p" } " by " { $snippet "q" } "." }
+{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 1 1 1 1 } { 3 1 } p/mod [ . ] bi@" "V{ 7 -2 1 }\nV{ -20 0 0 }" } } ;
+
+HELP: pgcd
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "a" "a polynomial" } { "d" "a polynomial" } }
+{ $description "Computes the greatest common divisor " { $snippet "d" } " of " { $snippet "p" } " and " { $snippet "q" } ", and another value " { $snippet "a" } " satisfying:" { $code "a*q = d mod p" } }
+{ $notes "GCD in the case of polynomials is a monic polynomial of the highest possible degree that divides into both " { $snippet "p" } " and " { $snippet "q" } "." }
+{ $examples
+    { $example "USING: kernel math.polynomials prettyprint ;"
+               "{ 1 1 1 1 } { 1 1 } pgcd [ . ] bi@"
+               "{ 0 0 }\n{ 1 1 }"
+    }
+} ;
+
+HELP: pdiff
+{ $values { "p" "a polynomial" } { "p'" "a polynomial" } }
+{ $description "Finds the derivative of " { $snippet "p" } "." } ;
+
+HELP: polyval
+{ $values { "p" "a polynomial" } { "x" number } { "p[x]" number } }
+{ $description "Evaluate " { $snippet "p" } " with the input " { $snippet "x" } "." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 0 1 } 2 polyval ." "5" } } ;
+
diff --git a/basis/math/polynomials/polynomials-tests.factor b/basis/math/polynomials/polynomials-tests.factor
new file mode 100644 (file)
index 0000000..cd88d19
--- /dev/null
@@ -0,0 +1,30 @@
+USING: kernel math math.polynomials tools.test ;
+IN: math.polynomials.tests
+
+[ { 0 1 } ] [ { 0 1 0 0 } ptrim ] unit-test
+[ { 1 } ] [ { 1 0 0 } ptrim ] unit-test
+[ { 0 } ] [ { 0 } ptrim ] unit-test
+[ { 3 10 8 } ] [ { 1 2 } { 3 4 } p* ] unit-test
+[ { 3 10 8 } ] [ { 3 4 } { 1 2 } p* ] unit-test
+[ { 0 0 0 0 0 0 0 0 0 0 } ] [ { 0 0 0 } { 0 0 0 0 0 0 0 0 } p* ] unit-test
+[ { 0 1 } ] [ { 0 1 } { 1 } p* ] unit-test
+[ { 0 } ] [ { } { } p* ] unit-test
+[ { 0 } ] [ { 0 } { } p* ] unit-test
+[ { 0 } ] [ { } { 0 } p* ] unit-test
+[ { 0 0 0 } ] [ { 0 0 0 } { 0 0 0 } p+ ] unit-test
+[ { 0 0 0 } ] [ { 0 0 0 } { 0 0 0 } p- ] unit-test
+[ { 0 0 0 } ] [ 4 { 0 0 0 } n*p ] unit-test
+[ { 4 8 0 12 } ] [ 4 { 1 2 0 3 } n*p ] unit-test
+[ { 1 4 7 6 0 0 0 0 0 } ] [ { 1 2 3 0 0 0 } { 1 2 0 0 } p* ] unit-test
+[ V{ 7 -2 1 } V{ -20 0 0 } ] [ { 1 1 1 1 } { 3 1 } p/mod ] unit-test
+[ V{ 0 0 } V{ 1 1 } ] [ { 1 1 } { 1 1 1 1 } p/mod ] unit-test
+[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 } { 1 1 } p/mod ] unit-test
+[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 } { 1 1 0 0 0 0 0 0 } p/mod ] unit-test
+[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 0 0 0 0 } { 1 1 0 0 } p/mod ] unit-test
+[ V{ 5.0 } V{ 0 } ] [ { 10.0 } { 2.0 } p/mod ] unit-test
+[ V{ 15/16 } V{ 0 } ] [ { 3/4 } { 4/5 } p/mod ] unit-test
+[ t ] [ { 0 1 } { 0 1 0 } p= ] unit-test
+[ f ] [ { 0 0 1 } { 0 1 0 } p= ] unit-test
+[ t ] [ { 1 1 1 } { 1 1 1 } p= ] unit-test
+[ { 0 0 } { 1 1 } ] [ { 1 1 1 1 } { 1 1 } pgcd ] unit-test
+
diff --git a/basis/math/polynomials/polynomials.factor b/basis/math/polynomials/polynomials.factor
new file mode 100644 (file)
index 0000000..13090b6
--- /dev/null
@@ -0,0 +1,84 @@
+! 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
+    splitting vectors ;
+IN: math.polynomials
+
+<PRIVATE
+
+: 2pad-left ( p q n -- p q ) [ 0 pad-left ] curry bi@ ;
+: 2pad-right ( p q n -- p q ) [ 0 pad-right ] curry bi@ ;
+: pextend ( p q -- p q ) 2dup [ length ] bi@ max 2pad-right ;
+: pextend-left ( p q -- p q ) 2dup [ length ] bi@ max 2pad-left ;
+: unempty ( seq -- seq ) [ { 0 } ] when-empty ;
+: 2unempty ( seq seq -- seq seq ) [ unempty ] bi@ ;
+
+PRIVATE>
+
+: powers ( n x -- seq )
+    <array> 1 [ * ] accumulate nip ;
+
+: p= ( p q -- ? ) pextend = ;
+
+: ptrim ( p -- p )
+    dup length 1 = [ [ zero? ] trim-right ] unless ;
+
+: 2ptrim ( p q -- p q ) [ ptrim ] bi@ ;
+: p+ ( p q -- r ) pextend v+ ;
+: p- ( p q -- r ) pextend v- ;
+: n*p ( n p -- n*p ) n*v ;
+
+: pextend-conv ( p q -- p q )
+    2dup [ length ] bi@ + 1- 2pad-right [ >vector ] bi@ ;
+
+: p* ( p q -- r )
+    2unempty pextend-conv <reversed> dup length
+    [ over length pick <slice> pick [ * ] 2map sum ] map 2nip reverse ;
+
+: p-sq ( p -- p^2 )
+    dup p* ;
+
+<PRIVATE
+
+: p/mod-setup ( p p -- p p n )
+    2ptrim
+    2dup [ length ] bi@ -
+    dup 1 < [ drop 1 ] when
+    [ over length + 0 pad-left pextend ] keep 1+ ;
+
+: /-last ( seq seq -- a )
+    #! divide the last two numbers in the sequences
+    [ peek ] bi@ / ;
+
+: (p/mod) ( p p -- p p )
+    2dup /-last
+    2dup , n*p swapd
+    p- >vector
+    dup pop* swap rest-slice ;
+
+PRIVATE>
+
+: p/mod ( p q -- z w )
+    p/mod-setup [ [ (p/mod) ] times ] V{ } make
+    reverse nip swap 2ptrim pextend ;
+
+<PRIVATE
+
+: (pgcd) ( b a y x -- a d )
+    dup V{ 0 } clone p= [
+        drop nip
+    ] [
+        tuck p/mod [ pick p* swap [ swapd p- ] dip ] dip (pgcd)
+    ] if ;
+
+PRIVATE>
+
+: pgcd ( p q -- a d )
+    swap V{ 0 } clone V{ 1 } clone 2swap (pgcd) [ >array ] bi@ ;
+
+: pdiff ( p -- p' )
+    dup length v* { 0 } ?head drop ;
+
+: polyval ( p x -- p[x] )
+    [ dup length ] dip powers v. ;
+
diff --git a/basis/math/polynomials/summary.txt b/basis/math/polynomials/summary.txt
new file mode 100644 (file)
index 0000000..5c237a2
--- /dev/null
@@ -0,0 +1 @@
+Polynomial arithmetic
diff --git a/basis/math/quaternions/authors.txt b/basis/math/quaternions/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/math/quaternions/quaternions-docs.factor b/basis/math/quaternions/quaternions-docs.factor
new file mode 100644 (file)
index 0000000..bb34ec8
--- /dev/null
@@ -0,0 +1,46 @@
+USING: help.markup help.syntax math math.vectors vectors ;
+IN: math.quaternions
+
+HELP: q*
+{ $values { "u" "a quaternion" } { "v" "a quaternion" } { "u*v" "a quaternion" } }
+{ $description "Multiply quaternions." }
+{ $examples { $example "USING: math.quaternions prettyprint ;" "{ C{ 0 1 } 0 } { 0 1 } q* ." "{ 0 C{ 0 1 } }" } } ;
+
+HELP: qconjugate
+{ $values { "u" "a quaternion" } { "u'" "a quaternion" } }
+{ $description "Quaternion conjugate." } ;
+
+HELP: qrecip
+{ $values { "u" "a quaternion" } { "1/u" "a quaternion" } }
+{ $description "Quaternion inverse." } ;
+
+HELP: q/
+{ $values { "u" "a quaternion" } { "v" "a quaternion" } { "u/v" "a quaternion" } }
+{ $description "Divide quaternions." }
+{ $examples { $example "USING: math.quaternions prettyprint ;" "{ 0 C{ 0 1 } } { 0 1 } q/ ." "{ C{ 0 1 } 0 }" } } ;
+
+HELP: q*n
+{ $values { "q" "a quaternion" } { "n" number } { "q" "a quaternion" } }
+{ $description "Multiplies each element of " { $snippet "q" } " by " { $snippet "n" } "." }
+{ $notes "You will get the wrong result if you try to multiply a quaternion by a complex number on the right using " { $link v*n } ". Use this word instead."
+    $nl "Note that " { $link v*n } " with a quaternion and a real is okay." } ;
+
+HELP: c>q
+{ $values { "c" number } { "q" "a quaternion" } }
+{ $description "Turn a complex number into a quaternion." }
+{ $examples { $example "USING: math.quaternions prettyprint ;" "C{ 0 1 } c>q ." "{ C{ 0 1 } 0 }" } } ;
+
+HELP: v>q
+{ $values { "v" vector } { "q" "a quaternion" } }
+{ $description "Turn a 3-vector into a quaternion with real part 0." }
+{ $examples { $example "USING: math.quaternions prettyprint ;" "{ 1 0 0 } v>q ." "{ C{ 0 1 } 0 }" } } ;
+
+HELP: q>v
+{ $values { "q" "a quaternion" } { "v" vector } }
+{ $description "Get the vector part of a quaternion, discarding the real part." }
+{ $examples { $example "USING: math.quaternions prettyprint ;" "{ C{ 0 1 } 0 } q>v ." "{ 1 0 0 }" } } ;
+
+HELP: euler
+{ $values { "phi" number } { "theta" number } { "psi" number } { "q" "a quaternion" } }
+{ $description "Convert a rotation given by Euler angles (phi, theta, and psi) to a quaternion." } ;
+
diff --git a/basis/math/quaternions/quaternions-tests.factor b/basis/math/quaternions/quaternions-tests.factor
new file mode 100644 (file)
index 0000000..a6d255e
--- /dev/null
@@ -0,0 +1,26 @@
+IN: math.quaternions.tests
+USING: tools.test math.quaternions kernel math.vectors
+math.constants ;
+
+[ 1.0 ] [ qi norm ] unit-test
+[ 1.0 ] [ qj norm ] unit-test
+[ 1.0 ] [ qk norm ] unit-test
+[ 1.0 ] [ q1 norm ] unit-test
+[ 0.0 ] [ q0 norm ] unit-test
+[ t ] [ qi qj q* qk = ] unit-test
+[ t ] [ qj qk q* qi = ] unit-test
+[ t ] [ qk qi q* qj = ] unit-test
+[ t ] [ qi qi q* q1 v+ q0 = ] unit-test
+[ t ] [ qj qj q* q1 v+ q0 = ] unit-test
+[ t ] [ qk qk q* q1 v+ q0 = ] unit-test
+[ t ] [ qi qj qk q* q* q1 v+ q0 = ] unit-test
+[ t ] [ C{ 0 1 } qj n*v qk = ] unit-test
+[ t ] [ qj C{ 0 1 } q*n qk v+ q0 = ] unit-test
+[ t ] [ qk qj q/ qi = ] unit-test
+[ t ] [ qi qk q/ qj = ] unit-test
+[ t ] [ qj qi q/ qk = ] unit-test
+[ t ] [ qi q>v v>q qi = ] unit-test
+[ t ] [ qj q>v v>q qj = ] unit-test
+[ t ] [ qk q>v v>q qk = ] unit-test
+[ t ] [ 1 c>q q1 = ] unit-test
+[ t ] [ C{ 0 1 } c>q qi = ] unit-test
diff --git a/basis/math/quaternions/quaternions.factor b/basis/math/quaternions/quaternions.factor
new file mode 100755 (executable)
index 0000000..bb0d025
--- /dev/null
@@ -0,0 +1,66 @@
+! Copyright (C) 2005, 2007 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays kernel math math.functions math.vectors sequences ;
+IN: math.quaternions
+
+! Everybody's favorite non-commutative skew field, the quaternions!
+
+! Quaternions are represented as pairs of complex numbers, using the
+! identity: (a+bi)+(c+di)j = a+bi+cj+dk.
+
+<PRIVATE
+
+: ** conjugate * ; inline
+
+: 2q ( u v -- u' u'' v' v'' ) [ first2 ] bi@ ; inline
+
+: q*a ( u v -- a ) 2q swapd ** [ * ] dip - ; inline
+
+: q*b ( u v -- b ) 2q [ ** swap ] dip * + ; inline
+
+PRIVATE>
+
+: q* ( u v -- u*v )
+    [ q*a ] [ q*b ] 2bi 2array ;
+
+: qconjugate ( u -- u' )
+    first2 [ conjugate ] [ neg  ] bi* 2array ;
+
+: qrecip ( u -- 1/u )
+    qconjugate dup norm-sq v/n ;
+
+: q/ ( u v -- u/v )
+    qrecip q* ;
+
+: q*n ( q n -- q )
+    conjugate v*n ;
+
+: c>q ( c -- q )
+    0 2array ;
+
+: v>q ( v -- q )
+    first3 rect> [ 0 swap rect> ] dip 2array ;
+
+: q>v ( q -- v )
+    first2 [ imaginary-part ] dip >rect 3array ;
+
+! Zero
+: q0 { 0 0 } ;
+
+! Units
+: q1 { 1 0 } ;
+: qi { C{ 0 1 } 0 } ;
+: qj { 0 1 } ;
+: qk { 0 C{ 0 1 } } ;
+
+! Euler angles
+
+<PRIVATE
+
+: (euler) ( theta unit -- q )
+    [ -0.5 * [ cos c>q ] [ sin ] bi ] dip n*v v- ;
+
+PRIVATE>
+
+: euler ( phi theta psi -- q )
+  [ qi (euler) ] [ qj (euler) ] [ qk (euler) ] tri* q* q* ;
diff --git a/basis/math/quaternions/summary.txt b/basis/math/quaternions/summary.txt
new file mode 100644 (file)
index 0000000..756750b
--- /dev/null
@@ -0,0 +1 @@
+Quaternion arithmetic and Euler angles
index 41fd28e441d6190791bbe7c16b2b208e31f1f13f..f7b3b37e257c5ba6c19681ae17dd234ae5a2f633 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
 USING: kernel layouts math math.order namespaces sequences
 sequences.private accessors ;
 IN: math.ranges
@@ -8,9 +10,7 @@ TUPLE: range
 { step read-only } ;
 
 : <range> ( a b step -- range )
-    [ over - ] dip
-    [ / 1+ 0 max >integer ] keep
-    range boa ; inline
+    [ over - ] dip [ /i 1+ 0 max ] keep range boa ; inline
 
 M: range length ( seq -- n )
     length>> ;
@@ -22,9 +22,9 @@ INSTANCE: range immutable-sequence
 
 : twiddle 2dup > -1 1 ? ; inline
 
-: (a, dup roll + -rot ; inline
+: (a, dup [ + ] curry 2dip ; inline
 
-: ,b) dup neg rot + swap ; inline
+: ,b) dup [ - ] curry dip ; inline
 
 : [a,b] ( a b -- range ) twiddle <range> ; inline
 
diff --git a/basis/math/statistics/authors.txt b/basis/math/statistics/authors.txt
new file mode 100644 (file)
index 0000000..176ca5c
--- /dev/null
@@ -0,0 +1,2 @@
+Doug Coleman
+Michael Judge
diff --git a/basis/math/statistics/statistics-docs.factor b/basis/math/statistics/statistics-docs.factor
new file mode 100644 (file)
index 0000000..7a7eb70
--- /dev/null
@@ -0,0 +1,60 @@
+USING: help.markup help.syntax debugger ;
+IN: math.statistics
+
+HELP: geometric-mean
+{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
+{ $description "Computes the geometric mean of all elements in " { $snippet "seq" } ". The geometric mean measures the central tendency of a data set that minimizes the effects of extreme values." }
+{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } geometric-mean ." "1.81712059283214" } }
+{ $errors "Throws a " { $link signal-error. } " (square-root of 0) if the sequence is empty." } ;
+
+HELP: harmonic-mean
+{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
+{ $description "Computes the harmonic mean of the elements in " { $snippet "seq" } ". The harmonic mean is appropriate when the average of rates is desired." }
+{ $notes "Positive reals only." }
+{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } harmonic-mean ." "6/11" } }
+{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
+
+HELP: mean
+{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
+{ $description "Computes the arithmetic mean of all elements in " { $snippet "seq" } "." }
+{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } mean ." "2" } }
+{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
+
+HELP: median
+{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
+{ $description "Computes the median of " { $snippet "seq" } " by sorting the sequence from lowest value to highest and outputting the middle one. If there is an even number of elements in the sequence, the median is not unique, so the mean of the two middle values is outputted." }
+{ $examples
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } median ." "2" }
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } median ." "2+1/2" } }
+{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
+
+HELP: range
+{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
+{ $description "Computes the distance of the maximum and minimum values in " { $snippet "seq" } "." }
+{ $examples
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } range ." "2" }
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } range ." "3" } }  ;
+
+HELP: std
+{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
+{ $description "Computes the standard deviation of " { $snippet "seq" } ", which is the square root of the variance. It measures how widely spread the values in a sequence are about the mean." }
+{ $examples
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } std ." "1.0" }
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } std ." "1.290994448735806" } } ;
+
+HELP: ste
+  { $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
+  { $description "Computes the standard error of the mean for " { $snippet "seq" } ". It's defined as the standard deviation divided by the square root of the length of the sequence, and measures uncertainty associated with the estimate of the mean." }
+  { $examples
+    { $example "USING: math.statistics prettyprint ;" "{ -2 2 } ste ." "2.0" }
+    { $example "USING: math.statistics prettyprint ;" "{ -2 2 2 } ste ." "1.333333333333333" } } ;
+
+HELP: var
+{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
+{ $description "Computes the variance of " { $snippet "seq" } ". It's a measurement of the spread of values in a sequence. The larger the variance, the larger the distance of values from the mean." }
+{ $notes "If the number of elements in " { $snippet "seq" } " is 1 or less, it outputs 0." }
+{ $examples
+  { $example "USING: math.statistics prettyprint ;" "{ 1 } var ." "0" }
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } var ." "1" }
+  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } var ." "1+2/3" } } ;
+
diff --git a/basis/math/statistics/statistics-tests.factor b/basis/math/statistics/statistics-tests.factor
new file mode 100644 (file)
index 0000000..b6ff421
--- /dev/null
@@ -0,0 +1,24 @@
+USING: kernel math math.functions math.statistics tools.test ;
+IN: math.statistics.tests
+
+[ 1 ] [ { 1 } mean ] unit-test
+[ 3/2 ] [ { 1 2 } mean ] unit-test
+[ 0 ] [ { 0 0 0 } geometric-mean ] unit-test
+[ t ] [ { 2 2 2 2 } geometric-mean 2.0 .0001 ~ ] unit-test
+[ 1.0 ] [ { 1 1 1 } geometric-mean ] unit-test
+[ 1/3 ] [ { 1 1 1 } harmonic-mean ] unit-test
+
+[ 0 ] [ { 1 } range ] unit-test
+[ 89 ] [ { 1 2 30 90 } range ] unit-test
+[ 2 ] [ { 1 2 3 } median ] unit-test
+[ 5/2 ] [ { 1 2 3 4 } median ] unit-test
+
+[ 1 ] [ { 1 2 3 } var ] unit-test
+[ 1.0 ] [ { 1 2 3 } std ] unit-test
+[ t ] [ { 1 2 3 4 } ste 0.6454972243679028 - .0001 < ] unit-test
+
+[ t ] [ { 23.2 33.4 22.5 66.3 44.5 } std 18.1906 - .0001 < ] unit-test
+
+[ 0 ] [ { 1 } var ] unit-test
+[ 0.0 ] [ { 1 } std ] unit-test
+[ 0.0 ] [ { 1 } ste ] unit-test
diff --git a/basis/math/statistics/statistics.factor b/basis/math/statistics/statistics.factor
new file mode 100644 (file)
index 0000000..d2494ee
--- /dev/null
@@ -0,0 +1,63 @@
+! Copyright (C) 2008 Doug Coleman, Michael Judge.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays combinators kernel math math.analysis math.functions sequences
+    sequences.lib sorting ;
+IN: math.statistics
+
+: mean ( seq -- n )
+    [ sum ] [ length ] bi / ;
+
+: geometric-mean ( seq -- n )
+    [ length ] [ product ] bi nth-root ;
+
+: harmonic-mean ( seq -- n )
+    [ recip ] sigma recip ;
+
+: median ( seq -- n )
+    natural-sort dup length even? [
+        [ midpoint@ dup 1- 2array ] keep nths mean
+    ] [
+        [ midpoint@ ] keep nth
+    ] if ;
+
+: range ( seq -- n )
+    minmax swap - ;
+
+: var ( seq -- x )
+    #! normalize by N-1
+    dup length 1 <= [
+        drop 0
+    ] [
+        [ [ mean ] keep [ - sq ] with sigma ] keep
+        length 1- /
+    ] if ;
+
+: std ( seq -- x )
+    var sqrt ;
+
+: ste ( seq -- x )
+    [ std ] [ length ] bi sqrt / ;
+
+: ((r)) ( mean(x) mean(y) {x} {y} -- (r) )
+    ! finds sigma((xi-mean(x))(yi-mean(y))
+    0 [ [ [ pick ] dip swap - ] bi@ * + ] 2reduce 2nip ;
+
+: (r) ( mean(x) mean(y) {x} {y} sx sy -- r )
+    * recip [ [ ((r)) ] keep length 1- / ] dip * ;
+
+: [r] ( {{x,y}...} -- mean(x) mean(y) {x} {y} sx sy )
+    first2 [ [ [ mean ] bi@ ] 2keep ] 2keep [ std ] bi@ ;
+
+: r ( {{x,y}...} -- r )
+    [r] (r) ;
+
+: r^2 ( {{x,y}...} -- r )
+    r sq ;
+
+: least-squares ( {{x,y}...} -- alpha beta )
+    [r] { [ 2dup ] [ ] [ ] [ ] [ ] } spread
+    ! stack is mean(x) mean(y) mean(x) mean(y) {x} {y} sx sy
+    [ (r) ] 2keep ! stack is mean(x) mean(y) r sx sy
+    swap / * ! stack is mean(x) mean(y) beta
+    [ swapd * - ] keep ;
+
diff --git a/basis/math/statistics/summary.txt b/basis/math/statistics/summary.txt
new file mode 100644 (file)
index 0000000..628c9ad
--- /dev/null
@@ -0,0 +1 @@
+Mean, median, standard deviation, and other statistical routines
index 01a421b4e7e210d41161743452b71986de1da5e6..a6967a7218bb86be4343ff188d380e4d0bfe891b 100644 (file)
@@ -24,6 +24,8 @@ IN: math.vectors
 : norm ( v -- x ) norm-sq sqrt ;
 : normalize ( u -- v ) dup norm v/n ;
 
+: distance ( u v -- x ) [ - absq ] [ + ] 2map-reduce sqrt ;
+
 : set-axis ( u v axis -- w )
     [ [ zero? 2over ? ] dip swap nth ] map-index 2nip ;
 
@@ -31,6 +33,7 @@ HINTS: vneg { array } ;
 HINTS: norm-sq { array } ;
 HINTS: norm { array } ;
 HINTS: normalize { array } ;
+HINTS: distance { array array } ;
 
 HINTS: n*v { object array } ;
 HINTS: v*n { array object } ;
index 68b4bff26651f708d2c87f0ec1a78e90bfa1b7f1..1445af8309e38566c8442944224ac9c824d92fa9 100644 (file)
-USING: accessors io io.streams.string kernel mime.multipart
-tools.test make multiline strings ;
+USING: accessors checksums checksums.md5 io io.encodings.ascii
+io.encodings.binary io.files io.streams.byte-array
+io.streams.string kernel make mime.multipart
+mime.multipart.private multiline sequences strings tools.test ;
 IN: mime.multipart.tests
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
-[ { "a" "a" } ] [
+[ { "a" "a" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "aa" } ] [
+[ { "aa" } ] [
     [
         "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
 
-[ { "a" } ] [
+[ { "a" } ] [
     [
         "azzbzzczzdzz" <string-reader> "zz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 [ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [
     [
         "azzbzzczzdzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" } ] [
+[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "az" "zb" "zz" "cz" "zd" } ] [
+[ { "az" "zb" "zz" "cz" "zd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "a" "zzb" "zzc" "zzd" } ] [
+[ { "a" "zzb" "zzc" "zzd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "az" "zbzz" "czzd" } ] [
+[ { "az" "zbzz" "czzd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
-[ { "azz" "bzzcz" "zd" } ] [
+[ { "azz" "bzzcz" "zd" } ] [
     [
         "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-step-loop drop
+        [ , ] multipart-step-loop drop
     ] { } make
 ] unit-test
 
 
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
 
+: dog-test-empty-bytes-safari ( -- bytes )
+    B{
+        45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
+        111 117 110 100 97 114 121 74 57 98 119 65 87 115 51 121
+        110 112 113 115 72 53 75 13 10 67 111 110 116 101 110 116
+        45 68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
+        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
+        108 101 49 34 59 32 102 105 108 101 110 97 109 101 61 34
+        100 111 103 46 106 112 103 34 13 10 67 111 110 116 101 110
+        116 45 84 121 112 101 58 32 105 109 97 103 101 47 106 112
+        101 103 13 10 13 10 255 216 255 224 0 16 74 70 73 70 0 1 1
+        0 0 1 0 1 0 0 255 219 0 67 0 5 3 4 4 4 3 5 4 4 4 5 5 5 6 7
+        12 8 7 7 7 7 15 11 11 9 12 17 15 18 18 17 15 17 17 19 22 28
+        23 19 20 26 21 17 17 24 33 24 26 29 29 31 31 31 19 23 34 36
+        34 30 36 28 30 31 30 255 219 0 67 1 5 5 5 7 6 7 14 8 8 14
+        30 20 17 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 255 192 0 17 8 1
+        49 1 64 3 1 34 0 2 17 1 3 17 1 255 196 0 29 0 0 2 2 3 1 1 1
+        0 0 0 0 0 0 0 0 0 4 5 6 7 2 3 8 0 1 9 255 196 0 74 16 0 2 1
+        3 3 2 4 4 3 4 5 10 5 3 5 1 1 2 3 0 4 17 5 18 33 6 49 19 34
+        65 81 7 50 97 113 20 35 129 21 51 66 82 36 52 145 161 177 8
+        53 83 98 114 115 147 178 193 209 22 37 67 116 241 99 130
+        240 23 68 84 100 146 225 255 196 0 25 1 0 3 1 1 1 0 0 0 0 0
+        0 0 0 0 0 0 1 2 3 0 4 5 255 196 0 39 17 0 2 2 2 2 3 0 2 1 5
+        1 0 0 0 0 0 0 1 2 17 3 33 18 49 34 50 65 19 81 4 5 20 35 66
+        97 82 255 218 0 12 3 1 0 2 17 3 17 0 63 0 228 200 149 136
+        219 131 200 207 233 68 196 145 112 60 21 45 234 91 181 57
+        177 178 138 75 56 95 111 152 196 51 250 209 11 167 198 14
+        118 138 22 138 153 104 150 118 82 46 217 45 161 98 79 242
+        102 157 38 151 98 174 64 211 237 72 247 49 46 104 11 8 140
+        111 229 247 166 194 70 137 12 146 112 61 235 57 36 172 31
+        82 7 154 199 78 244 176 178 255 0 132 41 100 195 76 15 183
+        240 118 60 31 244 85 237 126 241 237 237 157 213 176 113
+        197 66 158 254 234 82 74 49 45 187 144 42 49 155 158 217
+        108 152 99 21 68 214 88 116 217 83 17 218 218 171 250 109
+        138 180 254 6 221 83 205 109 1 199 115 225 10 141 90 106 23
+        106 187 95 59 73 239 237 77 44 111 89 79 136 24 186 250 131
+        235 86 199 166 71 143 20 52 181 211 237 24 143 232 150 236
+        61 140 66 155 65 167 233 251 64 252 5 158 127 221 45 3 99
+        42 220 42 186 240 79 247 83 139 38 86 92 21 57 20 76 246
+        140 78 155 98 88 31 217 246 125 191 209 45 108 253 159 97
+        255 0 240 44 255 0 225 45 22 216 200 199 181 99 88 74 98 77
+        99 78 178 69 111 14 194 213 23 28 226 48 15 246 212 30 242
+        21 252 105 8 145 170 103 178 213 137 172 121 162 127 181 87
+        151 141 182 247 31 235 210 180 216 209 28 88 217 219 120 99
+        250 52 100 255 0 172 155 168 248 108 109 11 103 240 208 127
+        194 173 118 82 71 225 47 148 246 163 11 169 30 74 81 140
+        102 182 178 35 203 97 104 62 162 46 104 41 45 109 119 127
+        86 131 254 21 48 144 225 9 198 104 105 198 24 118 53 76 77
+        81 141 73 105 109 143 234 176 127 193 21 146 89 219 110 63
+        209 97 255 0 131 69 65 183 110 15 39 218 182 144 160 159 41
+        6 169 102 5 22 54 138 114 109 45 216 123 24 184 53 177 45
+        44 137 231 79 179 237 254 138 179 118 101 112 167 159 181
+        102 131 140 212 35 236 99 95 224 172 119 143 252 190 207
+        254 21 18 186 125 129 92 254 2 207 254 16 172 15 148 230
+        182 71 46 225 198 106 178 78 204 40 213 237 109 83 33 45
+        224 237 223 195 199 247 214 189 30 222 222 69 45 37 165 187
+        156 227 12 161 177 245 230 143 214 212 8 75 123 138 15 69
+        96 7 220 214 159 169 135 31 129 177 192 198 159 102 120 255
+        0 68 181 240 216 217 12 15 217 214 156 246 252 165 230 137
+        139 205 235 128 7 204 123 80 183 154 148 118 202 66 225 156
+        118 62 148 169 174 38 91 55 193 167 233 191 60 214 22 96 14
+        249 137 107 84 199 69 137 246 174 157 100 255 0 65 18 210
+        43 237 82 105 148 188 108 64 254 31 102 164 243 223 204 146
+        249 155 39 233 73 38 50 84 137 156 112 233 19 200 4 118 54
+        201 238 22 33 68 54 153 166 52 96 173 149 163 15 115 16 205
+        66 244 189 77 141 226 40 115 143 90 155 91 73 192 116 245
+        29 141 77 233 140 177 169 46 64 109 167 88 45 203 31 217
+        246 92 127 244 171 19 97 99 226 16 218 125 152 227 63 186
+        20 100 204 56 247 245 175 66 84 145 191 147 235 246 174 140
+        125 18 180 125 183 211 108 72 7 246 125 158 63 221 45 109
+        151 77 177 219 254 111 179 255 0 132 180 68 76 163 133 206
+        51 197 103 43 0 184 166 158 144 72 133 244 54 113 220 5 91
+        120 50 59 254 77 7 120 109 188 48 22 8 1 207 242 98 152 106
+        170 191 137 45 239 218 149 93 41 97 129 239 73 97 143 96 19
+        172 103 204 161 23 232 181 164 71 152 93 143 173 110 117
+        101 67 90 142 239 195 55 165 97 229 251 37 122 124 138 182
+        48 118 253 210 81 66 116 250 82 123 2 205 103 108 55 30 99
+        31 221 218 140 134 63 56 221 200 169 147 26 90 229 159 56
+        20 109 242 171 89 16 217 251 80 214 190 80 49 197 110 212
+        63 168 147 234 107 74 62 44 166 36 156 209 17 234 235 140
+        193 26 170 182 230 227 21 40 248 113 208 240 234 214 169 53
+        194 224 63 166 57 168 167 85 55 136 34 5 87 126 124 170 123
+        26 233 15 129 214 42 221 59 108 123 112 51 27 14 223 90 142
+        61 68 233 206 227 249 58 35 7 224 252 57 252 133 141 91 25
+        82 71 24 255 0 189 44 212 254 21 222 99 16 171 120 139 234
+        160 97 171 165 99 81 143 5 145 74 142 199 29 171 239 225 99
+        121 138 149 80 127 133 241 205 22 229 96 121 19 84 145 199
+        250 231 77 106 61 62 210 25 35 114 189 212 1 198 43 237 133
+        210 72 71 24 56 228 125 107 167 186 179 163 236 245 93 61
+        149 35 76 148 42 43 154 186 195 167 175 58 123 85 149 9 37
+        67 103 63 74 117 39 123 37 151 26 110 226 20 14 64 53 246
+        132 211 174 22 234 21 216 217 111 83 69 22 80 72 197 89 245
+        103 61 238 128 117 60 155 121 15 174 218 174 239 8 23 141
+        158 251 170 192 213 36 219 11 175 169 28 85 123 169 237 93
+        64 240 57 52 99 32 142 45 89 191 15 229 231 154 46 201 155
+        60 214 141 48 43 69 141 163 24 162 109 227 61 199 21 57 118
+        96 244 57 92 227 52 43 198 219 143 126 244 68 18 3 88 202
+        172 141 134 108 147 205 8 107 64 62 65 223 145 131 239 91
+        25 188 199 39 38 181 163 99 191 122 250 112 199 118 59 213
+        83 160 114 54 59 46 211 239 89 39 203 90 93 89 88 115 197
+        110 64 74 113 83 138 169 5 59 62 183 35 214 189 16 193 197
+        124 109 202 123 154 251 19 13 199 35 38 170 242 69 62 194
+        105 214 255 0 171 138 85 166 169 82 204 164 237 60 103 235
+        77 181 129 226 66 184 98 163 220 82 155 73 24 202 45 34 81
+        201 239 75 44 138 141 7 114 72 110 146 203 36 73 12 42 207
+        150 193 197 73 52 191 135 215 186 168 241 220 180 113 177
+        206 49 200 90 153 124 40 248 122 110 151 241 183 65 66 12
+        48 207 191 189 94 54 186 61 165 156 94 28 123 10 149 10 78
+        59 138 231 109 252 58 163 8 163 159 236 254 19 73 53 176 86
+        80 176 175 171 1 197 107 185 248 77 101 105 103 51 204 187
+        36 199 24 25 39 255 0 249 93 18 176 195 18 157 177 168 30
+        212 191 85 132 201 109 39 134 138 204 227 110 8 160 175 232
+        210 227 196 226 14 170 210 27 66 215 60 46 54 110 5 72 31
+        227 82 141 57 214 72 145 137 198 64 237 70 127 148 13 146
+        219 107 208 145 150 5 240 91 211 245 165 58 75 237 130 48
+        72 36 47 117 237 71 39 113 4 23 248 216 202 224 96 100 114
+        107 24 148 183 126 62 213 182 101 57 231 145 89 70 6 7 2
+        174 221 35 133 71 102 248 84 40 245 172 110 57 38 182 175 3
+        140 86 19 1 142 194 145 182 199 34 250 129 197 226 100 241
+        154 211 52 121 77 194 182 234 67 117 238 223 236 162 150 17
+        248 81 218 138 116 52 72 228 225 183 246 21 241 148 126 30
+        79 76 46 234 62 234 16 27 181 7 34 55 135 55 63 250 116 232
+        210 118 168 117 167 172 127 132 183 220 224 15 13 127 187
+        189 16 10 135 194 144 69 43 176 144 155 88 23 212 71 70 32
+        110 251 129 165 170 25 99 99 139 78 127 182 179 213 220 199
+        167 141 190 86 35 191 189 42 241 228 132 174 50 65 246 162
+        53 9 89 172 227 221 158 212 178 151 139 54 61 100 68 118
+        241 86 227 89 182 132 121 247 72 1 2 186 187 225 157 184
+        131 70 182 143 28 162 128 203 234 167 235 92 181 211 246 87
+        23 221 92 145 198 173 133 144 121 192 249 107 170 250 103
+        242 236 35 241 147 194 157 84 6 99 252 85 36 169 34 249 98
+        229 34 100 89 89 139 43 6 97 192 35 211 233 95 94 86 17 2
+        199 56 238 105 119 226 188 171 223 183 39 222 190 27 172 16
+        95 113 79 95 173 16 199 30 134 246 242 11 133 60 242 59 212
+        75 226 103 77 91 235 58 101 204 138 159 154 145 147 145 235
+        78 97 152 171 248 145 200 10 31 65 222 138 155 100 200 21
+        178 222 167 29 171 5 87 211 144 110 214 109 31 80 240 36
+        111 32 39 57 244 57 237 77 224 152 92 69 226 174 49 142 126
+        149 105 124 86 232 27 125 70 22 187 178 132 9 2 229 177 247
+        53 76 66 38 209 181 65 109 48 111 8 156 18 123 81 229 20
+        170 201 101 196 253 163 208 94 161 14 251 105 27 217 106
+        189 213 20 11 226 125 51 138 177 181 70 205 153 104 249 87
+        28 85 117 117 253 117 247 251 241 84 87 240 231 26 233 108
+        192 5 3 131 77 145 78 243 74 180 213 193 7 138 115 18 229
+        137 172 227 33 27 48 183 64 24 26 202 126 13 108 140 169
+        242 142 9 236 79 106 26 92 150 228 250 209 140 93 140 124
+        254 48 107 34 195 39 154 215 255 0 231 122 247 191 253 234
+        188 65 196 223 27 151 24 144 101 253 40 152 179 130 49 233
+        90 109 85 29 124 217 163 226 218 19 28 98 163 123 176 165
+        64 46 219 13 122 22 223 39 28 147 216 86 219 133 4 19 90 1
+        240 161 50 28 131 252 52 91 131 219 55 144 62 189 56 91 68
+        133 88 110 245 30 213 37 248 49 210 178 106 58 188 51 73
+        144 138 119 19 233 140 208 189 61 210 211 245 12 232 193 79
+        204 57 32 226 186 51 161 250 90 195 65 211 161 138 8 255 0
+        51 104 46 125 106 115 146 78 145 124 17 113 143 146 37 26
+        85 188 122 109 132 113 68 184 96 49 159 165 125 185 185 85
+        59 90 64 119 124 198 180 205 43 5 43 156 31 79 181 10 178
+        36 44 26 70 222 205 223 30 148 165 210 177 139 150 149 10
+        227 98 142 192 250 214 155 147 253 28 199 177 88 122 238
+        244 250 208 171 52 155 134 88 98 133 150 237 164 36 46 112
+        15 53 129 56 190 145 65 255 0 148 77 158 235 69 153 118 182
+        199 218 54 118 239 154 175 116 73 72 181 129 135 204 203
+        218 174 31 142 22 18 234 26 36 203 2 72 21 60 229 64 253
+        225 207 106 165 244 67 38 194 37 36 178 240 51 90 91 175
+        248 104 234 13 18 169 228 221 230 127 46 43 5 151 196 228
+        214 55 127 186 221 238 43 85 187 100 227 158 213 94 71 20
+        180 232 103 23 43 197 125 145 84 168 201 230 176 135 182 43
+        100 156 40 165 9 22 212 144 45 249 247 163 161 254 174 40
+        93 79 157 67 62 153 166 22 234 166 1 197 96 53 98 235 149
+        12 167 222 147 234 3 242 102 81 220 71 82 41 99 12 59 129
+        74 117 91 114 45 167 117 31 250 103 251 169 148 140 129 45
+        55 44 17 99 253 29 23 12 204 28 6 3 20 20 19 127 71 139 159
+        253 42 223 28 129 136 7 156 154 103 208 255 0 153 177 205
+        170 120 204 3 12 12 240 69 111 213 199 134 145 66 163 36
+        143 90 246 154 141 148 231 143 74 203 89 138 67 123 11 6 57
+        199 21 63 134 139 243 68 211 224 110 159 102 218 140 243
+        189 188 178 60 152 249 192 192 171 213 173 128 140 176 141
+        15 25 193 244 168 39 193 43 63 15 79 19 76 7 140 199 206
+        184 171 30 250 50 146 43 42 228 48 193 168 219 163 177 55
+        200 71 226 254 97 228 140 28 99 210 183 69 117 30 226 31
+        105 30 222 148 46 161 152 75 141 229 148 156 226 149 60 140
+        70 248 137 80 189 241 75 143 34 186 101 158 54 201 25 102
+        241 55 70 35 3 216 118 162 108 39 87 144 66 242 108 61 243
+        239 244 168 180 119 82 49 253 233 136 123 10 206 207 82 89
+        36 88 174 150 38 195 121 37 76 247 250 213 123 36 224 214
+        201 204 169 20 145 60 61 148 240 72 245 170 127 227 23 70
+        172 150 134 226 214 223 107 103 141 130 173 155 70 86 183
+        66 28 179 3 250 26 58 242 194 43 232 66 92 66 187 79 189
+        115 201 108 56 230 163 105 156 115 105 60 208 196 214 23 80
+        148 145 71 5 135 122 132 235 145 201 29 249 42 188 22 245
+        174 164 248 151 240 207 198 70 212 45 21 81 145 142 204 10
+        160 186 163 71 154 222 77 183 49 8 157 84 246 254 35 239 93
+        112 206 180 145 203 60 93 201 116 37 211 39 10 0 126 41 220
+        119 81 1 144 213 22 120 174 35 92 237 226 135 146 250 234
+        33 235 143 65 87 228 217 13 50 87 226 199 254 144 126 149
+        245 166 141 200 243 10 133 46 162 232 115 146 72 172 206
+        175 41 238 191 223 67 147 9 51 12 132 227 114 214 82 120
+        106 56 113 80 209 170 72 88 5 76 31 189 20 215 178 152 212
+        149 201 197 50 102 37 118 211 195 242 150 227 222 140 18 71
+        129 181 137 168 84 119 151 1 73 197 49 180 191 153 148 110
+        200 199 106 231 250 104 246 74 29 148 174 230 227 29 177 89
+        232 58 77 246 183 172 195 20 112 177 141 125 135 6 153 244
+        151 75 234 157 65 36 113 136 241 9 0 230 186 15 162 250 19
+        79 208 225 79 42 25 145 130 183 31 74 76 146 138 71 84 49
+        211 183 209 143 68 244 245 174 149 167 6 252 56 86 28 246
+        169 45 207 130 182 134 66 222 30 61 187 214 251 192 182 235
+        26 15 40 39 210 144 107 247 22 176 249 46 37 36 124 193 127
+        155 233 83 91 118 86 172 214 151 14 236 220 228 103 130 222
+        213 147 204 138 164 48 86 39 185 168 228 218 149 196 206 56
+        17 91 129 133 81 243 17 88 53 227 180 137 28 114 56 92 122
+        247 170 27 241 177 225 187 24 231 251 171 43 85 241 50 170
+        14 15 36 154 87 109 34 151 27 134 121 167 54 108 225 129 12
+        118 251 82 185 168 151 112 226 129 250 130 194 222 77 30
+        118 120 247 237 140 250 122 215 48 107 54 169 103 169 201
+        224 163 129 188 240 195 138 235 187 203 101 109 50 82 205
+        130 227 143 181 115 71 197 11 55 183 214 228 88 219 17 239
+        224 1 244 162 157 171 57 102 252 68 107 48 54 234 27 24 175
+        68 15 114 49 158 213 166 218 19 37 160 207 38 140 137 120
+        10 220 145 86 198 173 108 227 123 9 130 182 203 218 181 195
+        216 240 59 214 215 70 49 131 73 244 196 91 80 99 248 197 62
+        230 152 193 145 111 145 75 245 24 207 226 147 159 90 109
+        103 31 244 97 158 115 84 140 28 140 40 184 185 117 148 100
+        12 118 173 183 172 143 165 92 48 193 34 39 175 186 149 168
+        14 24 142 49 64 220 201 183 78 157 87 129 225 61 43 84 232
+        196 94 55 155 195 207 134 216 61 168 155 89 101 241 16 108
+        61 232 168 236 220 219 161 11 198 208 223 219 91 173 172
+        157 100 86 32 119 166 109 80 30 201 95 79 166 228 30 245
+        150 187 129 127 18 255 0 101 110 209 23 195 43 246 175 107
+        136 5 253 171 30 119 29 181 54 44 125 209 127 252 28 119
+        147 73 72 230 142 40 215 60 31 122 156 223 199 182 38 200
+        192 3 32 212 119 225 21 138 174 131 12 155 67 115 220 84
+        183 91 141 148 97 89 64 199 32 251 84 228 244 119 67 216
+        175 53 163 38 215 30 25 199 112 213 29 69 63 48 152 73 159
+        65 233 83 13 65 48 37 1 124 167 249 170 55 61 169 40 20 109
+        200 254 90 129 218 4 247 78 190 70 24 83 220 214 80 238 154
+        69 16 176 14 14 87 234 104 11 230 104 238 90 118 5 84 252
+        202 125 190 148 126 152 158 21 202 220 69 135 4 103 13 217
+        215 233 250 215 70 55 226 38 88 187 39 154 13 208 252 34
+        163 33 141 193 243 231 212 251 211 251 121 149 85 1 97 130
+        112 191 90 135 90 206 197 188 64 27 45 201 207 127 214 134
+        215 181 195 98 143 189 138 237 77 203 207 99 70 147 236 131
+        99 174 169 234 43 123 77 62 84 37 70 88 247 53 203 223 20
+        122 138 214 234 127 203 100 102 12 71 7 177 230 180 252 80
+        248 131 123 168 93 92 217 90 92 48 143 126 11 3 85 179 199
+        52 132 72 237 36 140 199 144 125 105 163 26 232 132 230 210
+        164 48 75 217 26 50 178 31 175 216 86 192 177 179 120 114
+        70 67 241 199 223 181 123 78 176 141 158 25 60 57 29 36 94
+        123 112 125 170 77 160 116 237 205 192 152 92 70 3 69 180
+        142 14 72 30 149 94 150 201 70 42 93 246 70 127 3 111 32 5
+        156 28 246 30 245 190 13 46 213 184 24 7 252 106 204 181
+        232 39 188 134 25 214 2 158 110 1 167 211 252 45 149 128
+        217 22 112 6 10 158 230 167 249 25 79 192 83 113 90 218 43
+        149 217 141 188 156 214 187 150 139 38 69 97 207 165 90 154
+        223 195 91 168 237 85 150 18 178 103 7 158 226 163 250 159
+        68 74 152 183 104 138 133 245 230 154 51 108 73 97 165 178
+        2 110 35 93 185 140 228 246 250 214 22 218 145 75 144 79 49
+        169 237 237 76 239 180 139 136 30 225 167 183 116 136 113
+        19 250 19 244 164 87 118 130 221 66 140 239 113 150 255 0
+        84 123 26 210 236 17 199 79 146 58 87 225 47 85 90 20 133
+        99 120 217 252 48 184 7 154 188 44 181 72 110 33 115 28 138
+        189 178 107 243 247 73 212 245 13 34 238 43 139 91 150 86
+        86 224 103 130 43 161 190 21 117 252 218 133 187 199 52 195
+        196 199 42 79 57 169 101 130 173 150 89 37 47 133 243 123
+        62 27 184 205 66 250 153 228 158 87 72 219 242 128 203 31
+        230 250 83 11 125 67 241 86 98 67 184 239 92 140 119 20 179
+        85 146 97 108 214 246 225 124 118 236 237 217 7 169 53 139
+        136 77 210 199 8 240 215 106 142 5 122 9 94 225 177 34 149
+        251 208 119 94 29 164 113 164 108 89 229 206 11 127 16 254
+        111 181 21 167 69 35 196 145 178 183 3 230 247 165 148 171
+        163 166 41 164 130 109 86 72 238 147 99 239 32 246 21 50
+        208 67 51 13 202 70 225 138 143 217 91 1 54 246 198 79 106
+        149 105 49 31 46 210 1 250 210 91 125 141 149 166 135 114
+        167 244 87 221 194 162 96 31 173 115 103 199 23 118 190 241
+        36 82 160 55 148 159 90 234 47 194 238 179 39 25 59 121 246
+        174 109 255 0 40 116 120 110 193 194 99 119 97 84 199 217
+        231 101 232 129 88 15 19 77 12 127 74 223 28 124 80 182 50
+        40 176 133 70 70 70 236 125 40 181 124 40 198 106 216 211
+        226 206 89 109 155 34 93 166 136 112 118 10 12 51 23 28 26
+        222 242 16 170 190 227 251 40 168 180 18 63 170 115 121 30
+        61 233 149 159 238 69 44 213 124 179 41 200 224 209 54 210
+        55 130 49 197 27 163 25 220 166 238 105 102 167 24 91 9 200
+        239 225 63 20 222 94 35 207 189 5 169 47 244 9 255 0 221 61
+        43 70 54 233 208 175 236 235 101 33 79 228 35 103 244 175
+        52 113 171 249 177 244 197 37 178 189 151 240 22 235 26 231
+        108 64 22 250 14 212 76 115 74 236 190 76 156 214 148 120
+        148 135 25 116 137 30 154 114 195 142 115 199 181 103 212 2
+        69 22 211 42 134 41 38 15 181 97 165 135 104 187 109 230
+        137 213 70 52 183 247 83 145 247 160 73 170 154 103 65 124
+        33 150 245 186 106 18 99 120 198 121 199 106 156 223 50 181
+        177 103 80 95 24 21 0 248 17 121 29 215 79 197 27 206 216 7
+        154 178 245 45 63 242 188 72 206 83 28 87 61 118 206 200 63
+        34 5 170 47 149 155 113 35 212 123 82 11 169 21 163 11 24
+        218 71 114 106 73 171 90 72 204 237 27 21 199 124 122 212
+        102 246 53 149 138 188 133 0 61 197 37 89 217 29 136 53 75
+        171 111 21 13 192 196 108 112 91 218 137 211 97 109 58 34
+        151 18 135 183 97 186 25 129 206 207 245 126 212 171 82 145
+        33 117 180 155 5 91 129 159 74 81 38 165 119 166 23 181 185
+        13 36 64 111 140 154 120 107 68 242 77 217 59 186 215 99
+        183 178 109 201 135 81 232 121 199 215 235 84 183 196 238
+        182 55 119 18 90 219 202 225 135 145 142 107 221 79 213 32
+        192 235 24 33 241 140 3 233 239 85 212 183 17 202 254 44
+        222 116 39 42 87 230 253 106 177 77 156 83 157 61 31 45 237
+        237 239 1 102 27 100 118 207 29 137 246 21 186 210 206 226
+        234 117 88 99 32 227 102 0 229 79 210 134 131 114 220 179
+        91 169 147 235 31 106 184 62 29 116 188 215 205 14 160 145
+        168 115 141 216 236 79 184 250 85 23 138 217 40 183 116 197
+        93 13 210 179 94 74 18 230 213 114 14 72 92 240 106 230 233
+        14 149 201 182 205 143 49 182 210 72 249 254 245 48 233 30
+        132 176 210 209 47 24 174 233 57 97 252 167 218 167 186 85
+        149 188 100 34 145 133 57 28 122 212 102 220 186 58 97 20
+        182 200 190 129 210 227 194 72 103 183 201 140 229 192 28
+        17 78 83 165 195 162 4 143 96 7 111 126 245 58 210 108 148
+        90 143 40 231 191 214 137 154 200 237 77 168 54 171 110 34
+        137 185 113 123 101 115 115 210 176 184 101 150 223 113 81
+        198 106 35 212 61 46 204 146 44 118 104 3 38 204 227 176
+        247 251 213 241 45 180 101 119 0 9 35 251 41 14 173 104 170
+        73 101 10 153 224 208 119 240 50 148 89 202 157 87 210 48
+        77 60 202 214 110 145 193 229 140 1 199 222 169 174 161 208
+        175 22 242 86 75 117 218 95 31 252 215 114 106 218 69 181
+        227 52 71 111 57 46 113 223 138 169 250 227 225 231 131 110
+        90 216 198 94 224 22 231 209 126 149 162 223 45 154 81 168
+        156 164 246 105 35 152 164 140 41 67 203 122 15 160 172 244
+        205 66 77 47 82 51 89 54 17 78 55 19 203 125 233 247 94 105
+        223 178 174 22 205 16 237 44 124 64 125 90 162 182 234 136
+        155 102 138 70 62 137 31 173 94 124 90 57 84 156 54 116 39
+        195 190 179 134 247 78 137 124 92 52 99 12 24 250 84 190
+        125 74 222 228 22 13 148 35 12 7 241 125 15 210 185 131 65
+        214 164 211 239 247 12 162 231 205 138 181 180 30 166 140
+        66 173 183 114 133 221 180 251 251 212 163 217 104 57 61
+        217 45 187 183 48 52 154 150 161 34 137 37 242 67 26 246 81
+        232 61 233 182 153 49 100 85 229 112 63 90 138 45 212 147
+        203 251 79 82 37 80 183 229 102 164 26 9 252 67 120 146 72
+        85 91 145 72 227 114 59 160 237 18 88 219 116 161 128 194
+        250 98 164 218 66 175 145 152 176 31 74 141 233 144 188 234
+        35 221 177 148 246 247 169 118 137 110 210 97 23 142 49 73
+        246 131 54 146 29 92 206 230 219 109 190 115 183 140 251 87
+        51 255 0 148 20 183 13 170 120 78 170 124 221 249 174 164
+        185 130 27 123 23 50 76 82 69 143 129 239 92 167 241 178
+        239 241 93 84 144 43 29 170 196 55 214 169 141 83 103 14 94
+        136 60 113 50 75 18 174 79 229 246 52 94 226 2 231 223 154
+        250 84 199 50 150 228 142 7 218 177 118 12 221 171 162 18
+        75 71 56 79 139 25 101 81 243 99 244 172 165 198 194 27 185
+        239 143 74 24 174 210 24 112 43 207 32 216 41 219 179 8 181
+        86 62 48 237 222 143 178 93 208 45 3 170 168 241 215 143 90
+        105 166 46 97 24 246 169 72 198 115 174 16 41 251 208 58
+        145 99 167 93 28 124 176 57 31 217 76 167 70 35 147 64 234
+        8 223 179 47 121 255 0 246 207 255 0 45 82 49 209 133 58
+        116 91 236 237 155 215 195 163 214 53 35 105 60 208 186 71
+        245 59 111 247 99 251 232 167 39 120 199 189 115 61 187 58
+        49 244 62 211 27 106 40 244 11 138 206 245 131 90 52 110
+        112 15 124 250 80 182 59 150 60 230 183 93 131 52 5 27 128
+        123 98 175 195 198 206 121 123 23 111 194 141 25 19 165 163
+        146 25 150 25 163 228 146 123 213 139 166 235 6 72 132 55
+        16 182 244 227 196 61 136 170 231 225 154 76 186 12 22 208
+        179 49 99 134 250 138 156 221 168 180 182 82 216 81 234 125
+        123 87 36 175 164 117 198 187 96 58 228 214 203 59 186 202
+        20 145 242 147 193 53 1 215 181 21 183 159 204 200 184 60
+        224 240 43 87 94 245 125 134 157 20 166 73 17 216 118 25
+        230 168 174 178 235 171 237 81 90 222 215 114 199 158 72
+        239 250 86 132 91 208 207 34 142 209 51 235 190 160 181 86
+        120 81 64 43 192 57 245 168 68 189 85 123 61 177 130 95 57
+        67 149 63 78 212 133 26 107 169 12 183 147 177 200 245 61
+        205 1 113 118 200 204 145 224 15 173 118 67 29 171 100 178
+        229 182 25 125 127 150 37 188 197 251 168 238 15 189 39 185
+        59 88 239 96 227 233 90 204 153 36 243 156 250 214 80 71 44
+        242 42 170 239 102 56 81 158 230 153 164 142 87 119 100 211
+        225 206 159 38 163 172 70 24 180 11 24 192 157 144 149 39
+        254 181 215 159 13 186 114 107 91 40 63 18 33 155 114 143
+        204 72 246 156 125 126 149 76 255 0 147 198 143 171 90 193
+        29 212 150 211 92 187 159 201 137 149 118 238 29 192 231 57
+        31 95 210 186 179 67 253 204 19 79 111 28 23 17 128 94 51
+        243 21 255 0 10 231 148 172 183 14 42 205 194 198 51 182 56
+        212 246 239 76 244 141 60 52 109 25 57 246 62 245 140 23
+        182 18 93 21 158 101 66 237 144 163 184 167 169 60 62 42
+        219 197 177 155 211 111 183 189 78 154 232 101 145 208 77
+        140 91 97 53 181 215 56 86 224 19 201 175 182 255 0 153 207
+        99 244 237 88 207 34 169 11 131 222 155 95 72 74 219 179 99
+        70 54 96 118 28 10 87 127 110 100 144 112 118 47 115 77 147
+        204 156 80 119 141 180 129 42 159 15 233 220 208 119 240
+        104 57 39 178 37 117 96 85 213 147 200 51 198 125 105 102
+        187 166 69 54 157 34 149 46 249 193 30 255 0 74 152 93 203
+        101 248 35 47 136 164 33 198 65 165 111 61 188 182 243 165
+        187 70 230 70 249 143 96 43 36 238 217 105 100 109 81 202
+        255 0 26 122 94 231 240 119 19 36 177 69 30 60 177 32 36
+        177 255 0 189 115 30 160 38 130 83 13 194 52 108 59 6 24 56
+        175 208 63 136 208 223 92 105 207 21 134 158 207 19 103 243
+        21 87 43 199 98 73 239 92 75 241 71 69 212 236 122 138 225
+        174 109 229 104 249 35 198 24 32 125 72 227 251 234 139 100
+        114 69 209 22 180 152 162 121 78 1 245 167 218 70 173 115
+        107 34 186 254 98 142 224 122 138 138 6 100 227 248 79 106
+        221 5 228 177 159 47 98 49 85 171 22 46 145 97 69 213 51 92
+        95 197 248 179 182 5 249 99 61 254 245 105 116 222 187 111
+        113 98 30 50 170 84 236 7 61 207 181 115 221 153 241 206
+        226 88 47 185 244 52 108 26 166 163 165 220 175 225 238 11
+        170 182 229 0 240 77 35 196 213 179 170 57 18 143 103 91
+        244 253 212 110 23 116 170 167 102 50 125 13 77 116 75 168
+        109 109 131 33 103 25 229 147 214 185 131 161 190 34 36 211
+        8 175 36 104 229 7 140 227 7 251 234 246 233 77 90 222 254
+        213 26 9 55 2 61 235 145 220 101 208 202 74 107 178 77 121
+        113 115 170 188 145 70 36 181 135 30 99 47 241 253 171 159
+        62 46 90 90 218 245 34 77 104 193 54 183 0 213 253 169 91
+        200 150 203 113 19 96 168 36 227 218 185 235 226 187 51 106
+        194 86 112 70 227 192 239 84 199 53 100 178 105 82 35 18 57
+        99 90 7 239 43 4 155 33 91 156 123 86 107 203 110 174 142
+        36 101 166 19 130 0 200 199 21 237 170 121 39 154 248 155
+        177 230 32 214 71 129 156 142 105 210 179 8 245 140 248 163
+        138 109 163 200 162 223 130 51 138 85 173 224 74 87 190 61
+        69 29 163 254 235 244 161 40 152 57 183 51 103 6 131 213 8
+        93 58 247 60 127 71 127 249 104 238 62 180 22 177 183 246
+        101 239 127 234 239 255 0 45 20 233 24 85 167 73 26 216 65
+        158 254 18 86 70 100 50 129 159 90 89 104 199 240 86 236
+        199 63 150 63 186 178 133 100 146 225 112 199 147 197 69 37
+        101 99 145 116 137 133 143 154 42 223 50 31 8 149 228 138
+        209 167 127 87 0 247 94 9 162 157 136 78 14 51 222 171 242
+        136 228 246 39 127 8 122 155 193 211 165 220 219 222 54 192
+        218 113 254 52 71 92 124 78 134 206 23 182 242 187 28 252
+        196 228 113 244 170 88 223 220 219 207 44 80 206 241 239
+        239 180 227 38 144 234 211 205 121 49 73 228 101 63 206 79
+        45 244 169 180 145 73 78 162 107 234 29 90 235 92 212 101
+        113 39 229 150 254 34 104 102 133 173 146 56 230 104 163 6
+        61 202 249 206 107 11 155 118 183 143 115 52 123 72 227 117
+        42 184 144 147 183 57 35 142 15 24 167 142 136 115 114 14
+        212 175 140 155 18 48 170 23 212 122 208 18 51 72 219 155
+        143 181 124 141 89 188 217 237 82 45 15 165 239 239 228 64
+        35 220 172 50 60 164 211 60 180 168 122 182 34 182 181 150
+        105 22 52 83 150 56 21 119 124 40 232 61 22 11 120 117 14
+        162 91 71 193 223 137 156 141 163 244 168 207 76 244 169
+        183 63 136 212 18 225 18 57 54 168 100 219 185 135 63 225
+        91 58 183 90 125 107 82 255 0 195 61 62 206 225 188 133 223
+        130 120 244 164 82 82 209 69 162 234 185 248 149 211 250 36
+        150 134 27 173 53 90 60 43 62 205 196 168 237 185 135 124
+        122 30 226 143 31 29 52 104 209 202 95 254 32 5 27 100 36
+        236 45 159 148 10 175 236 62 14 116 119 78 233 49 106 29
+        125 173 188 6 78 209 228 140 254 148 143 173 126 25 244 255
+        0 254 31 184 234 111 135 186 191 237 75 11 33 253 58 212
+        252 240 131 193 111 211 138 203 18 248 105 41 203 127 11 55
+        77 248 167 13 230 169 52 150 247 62 32 50 141 165 57 219
+        192 206 71 176 171 175 165 122 166 5 180 105 218 238 57 174
+        14 11 190 120 198 63 135 233 92 19 209 178 53 191 80 219
+        134 145 158 37 96 36 8 112 28 122 30 61 49 87 123 245 75
+        105 182 99 207 52 183 69 118 195 26 0 16 169 237 74 213 104
+        10 171 71 82 105 125 92 178 27 168 173 231 133 252 12 41 37
+        143 45 235 68 75 172 79 115 181 162 5 128 229 177 233 84
+        103 195 200 167 142 199 241 23 49 151 121 21 93 163 36 242
+        199 230 63 165 90 218 115 72 203 28 109 148 86 95 48 30 130
+        163 46 131 68 134 62 164 146 22 88 78 21 152 231 46 120 197
+        44 126 179 134 226 226 72 124 104 153 146 79 13 129 39 0
+        251 253 170 55 212 64 44 102 54 86 40 36 33 28 158 7 21 76
+        245 62 169 115 211 218 200 159 30 37 165 208 49 206 224 240
+        62 181 88 250 152 177 62 34 245 140 58 102 239 2 121 12 14
+        222 120 80 249 147 237 244 168 54 141 241 163 78 211 141
+        197 165 197 196 110 210 203 184 16 199 40 158 223 78 113
+        222 160 191 17 53 127 196 104 134 75 123 167 145 74 17 20
+        217 230 63 175 255 0 62 245 82 116 190 137 169 117 70 175
+        107 165 233 240 120 183 183 79 225 199 158 199 156 150 111
+        160 28 213 97 20 214 197 201 168 218 58 99 87 248 221 161
+        73 107 36 48 234 16 164 172 70 232 230 77 202 62 162 133
+        213 239 186 63 173 172 13 173 252 186 108 175 26 9 160 13
+        46 213 115 245 3 147 81 85 248 123 240 135 79 184 58 54 177
+        212 210 207 171 96 36 146 110 10 187 253 64 250 103 181 70
+        126 35 124 48 190 232 99 6 191 161 221 181 213 145 243 70
+        249 7 2 179 138 55 41 69 121 116 68 62 34 244 106 232 154
+        139 73 100 209 61 179 246 17 146 66 253 179 80 146 152 39
+        131 199 28 213 195 105 171 105 157 87 161 143 26 59 165 188
+        183 127 13 178 23 185 254 44 14 194 162 250 143 68 106 158
+        61 204 107 110 234 144 30 119 14 228 250 214 186 216 120
+        166 66 226 186 146 33 181 64 42 79 57 166 150 183 81 221 67
+        28 108 18 34 131 27 135 115 75 245 13 58 230 209 218 57 151
+        105 30 148 26 50 169 243 12 143 106 111 201 100 165 221 14
+        110 45 100 30 29 202 108 93 231 201 176 249 179 245 169 239
+        195 46 190 155 65 116 134 233 140 202 14 56 39 138 173 172
+        165 241 167 102 114 65 246 205 29 45 139 162 248 204 228
+        123 82 154 13 217 214 154 111 94 193 127 103 35 13 219 89
+        59 103 214 170 30 176 184 55 250 195 158 200 28 241 237 81
+        14 158 212 46 196 42 137 52 136 163 140 3 222 158 137 55
+        121 155 204 199 185 62 181 62 153 119 177 106 33 86 39 146
+        15 247 81 80 227 28 214 137 102 84 57 35 143 81 91 33 60 96
+        250 242 42 184 246 182 77 236 45 72 53 242 65 229 28 154
+        249 12 110 20 229 189 107 50 141 142 244 244 97 14 171 216
+        100 246 245 166 26 88 99 0 35 218 130 215 35 41 149 62 180
+        126 145 34 139 101 76 115 75 35 4 237 124 253 43 70 167 206
+        153 122 63 254 179 255 0 203 71 73 185 87 191 122 7 80 255
+        0 54 94 255 0 237 223 254 90 41 42 48 158 198 216 61 132 13
+        234 34 76 10 223 4 91 101 25 226 129 180 188 95 192 192 168
+        74 159 13 123 253 40 136 174 55 56 243 115 92 231 71 24 168
+        162 77 103 194 133 29 143 173 23 183 3 142 104 29 53 183 69
+        159 173 28 161 137 32 48 31 122 183 250 156 242 236 132 107
+        158 77 85 199 161 245 165 154 157 228 75 20 143 224 147 38
+        208 160 254 180 95 83 57 138 255 0 123 28 143 97 222 163 23
+        119 6 86 113 187 3 28 3 64 73 118 105 188 158 75 137 188 71
+        96 196 142 62 149 164 43 30 194 155 233 90 68 247 146 69 24
+        134 76 56 200 101 82 71 247 84 150 223 225 254 169 117 125
+        13 172 54 206 217 30 128 228 208 177 150 50 61 211 246 17
+        93 221 197 19 50 151 102 24 78 228 254 149 210 29 55 105 99
+        164 244 220 104 153 154 237 211 1 35 143 5 190 134 190 116
+        95 193 91 125 52 67 53 238 212 144 12 22 9 206 126 149 105
+        216 232 54 58 126 158 27 240 202 229 60 161 207 115 250 84
+        178 100 101 225 138 145 205 127 16 35 235 141 54 194 107
+        169 173 82 194 202 102 43 28 64 121 177 238 126 181 183 252
+        152 180 184 110 186 206 59 139 153 55 120 114 255 0 23 124
+        138 184 254 36 90 166 177 166 141 46 104 35 142 4 39 108
+        140 60 196 227 176 199 115 84 102 142 215 157 3 174 165 245
+        152 155 98 49 145 210 65 182 66 185 239 131 86 197 41 73 81
+        57 175 22 75 126 54 92 222 106 189 105 168 45 206 80 193 62
+        200 131 127 20 127 74 19 225 245 222 151 210 147 38 181 113
+        169 69 121 103 125 101 56 212 44 99 102 221 6 60 168 178
+        103 131 158 249 20 247 171 250 255 0 225 55 87 218 197 168
+        106 38 238 29 67 24 153 33 139 7 31 169 239 80 253 42 199
+        77 234 9 221 244 173 34 120 116 93 223 60 242 238 146 225
+        135 191 176 197 36 63 140 227 147 155 122 59 223 245 28 95
+        218 44 42 62 68 123 167 116 185 33 117 214 20 71 109 12 210
+        51 36 95 197 180 158 0 171 51 165 244 73 181 27 215 191 191
+        183 154 71 150 61 177 2 56 219 239 254 213 35 135 77 93 99
+        94 75 88 99 72 173 161 199 135 10 231 9 138 187 122 35 69
+        184 136 199 113 225 112 23 204 91 181 105 61 158 122 116
+        182 109 183 177 142 215 72 137 99 152 44 139 202 169 238
+        135 220 211 173 10 247 84 145 37 105 49 49 72 240 127 183
+        230 20 195 195 180 216 86 107 115 34 158 225 69 108 183 146
+        21 220 177 126 90 40 200 92 115 82 158 217 76 73 209 23 188
+        188 186 187 184 17 77 43 73 110 173 231 66 57 205 36 235 93
+        26 222 248 180 239 3 92 196 188 182 206 202 49 86 11 61 188
+        190 105 20 200 254 158 80 48 43 69 253 168 184 183 219 28
+        107 27 24 246 133 127 95 236 162 131 61 28 197 173 216 222
+        88 217 13 44 226 43 73 31 242 89 255 0 139 239 65 124 52
+        190 183 232 190 169 212 34 186 137 37 188 186 211 165 252
+        20 241 182 10 183 7 106 159 114 1 171 31 226 39 74 188 150
+        165 68 82 126 72 47 156 241 159 165 66 44 180 219 125 107
+        79 75 123 168 137 187 181 36 199 112 14 10 48 237 131 86
+        134 153 9 78 169 175 217 28 191 211 109 173 111 109 205 190
+        165 6 167 45 196 98 226 89 34 13 152 157 143 40 229 191 136
+        122 213 219 240 252 182 169 240 123 92 211 245 15 204 134
+        221 191 163 153 62 94 59 129 85 78 147 168 244 85 173 233
+        139 172 44 181 29 51 80 138 76 59 194 229 163 155 253 110
+        121 201 246 169 111 88 252 86 233 143 252 53 7 76 244 23
+        143 35 72 140 37 121 34 218 50 125 205 8 97 148 95 43 61 95
+        231 255 0 59 22 124 80 140 35 180 82 80 254 51 75 234 219
+        152 244 185 25 31 199 17 162 17 228 111 191 210 174 222 139
+        139 169 109 103 71 234 59 16 208 73 134 91 132 28 99 218
+        162 191 15 58 89 110 181 4 213 181 39 113 32 199 134 93 114
+        142 255 0 82 43 162 180 147 22 161 107 2 222 219 198 147
+        162 132 64 7 148 175 189 35 200 250 103 18 132 111 179 158
+        126 54 232 182 47 178 234 216 143 12 182 230 34 169 75 216
+        226 86 62 11 7 25 238 43 184 58 167 161 44 181 120 36 73 6
+        204 140 99 195 4 19 238 42 138 248 143 240 98 250 192 126
+        51 78 18 73 30 114 219 87 3 251 40 197 162 83 195 78 202 44
+        103 52 211 78 187 145 54 164 135 122 127 47 168 167 119 125
+        31 117 14 158 39 146 60 72 6 74 169 228 212 106 230 9 109
+        91 44 172 185 28 110 20 233 139 199 137 59 211 30 223 194 6
+        21 216 9 228 123 154 117 19 21 183 101 35 181 68 58 114 224
+        52 41 184 147 232 64 247 169 58 179 120 108 164 130 77 35
+        236 22 8 208 254 98 209 16 202 21 112 8 197 15 63 136 172 6
+        112 125 43 234 35 110 238 0 255 0 173 87 23 65 24 66 236
+        121 193 197 109 144 238 21 170 15 42 121 151 28 214 213 59
+        184 170 24 79 174 144 84 145 216 246 173 250 79 238 135 218
+        133 214 206 213 17 144 115 69 105 35 49 45 99 12 223 228
+        160 245 15 243 101 239 254 217 255 0 229 163 101 24 10 191
+        74 11 81 227 77 189 255 0 219 191 252 181 140 66 237 225
+        152 136 216 103 105 143 138 42 222 57 150 117 57 39 154 107
+        103 110 162 194 219 10 63 171 171 126 167 189 98 177 159 20
+        10 230 67 56 162 65 166 16 176 15 122 57 202 178 141 172
+        115 64 88 198 124 49 205 27 28 101 92 179 114 41 211 177 27
+        43 190 181 38 61 66 76 115 159 127 74 142 91 196 102 157 87
+        146 88 212 151 174 163 111 198 6 254 126 212 171 167 182
+        166 169 24 144 2 50 57 62 156 208 151 236 120 165 106 206
+        132 248 59 209 94 38 135 22 165 116 100 87 219 133 80 70 49
+        138 180 58 43 73 68 189 154 226 52 220 241 182 23 35 56 160
+        58 34 72 173 250 58 47 54 209 225 129 24 247 207 173 79 186
+        31 77 16 218 248 219 67 25 6 226 42 13 203 224 242 236 123
+        167 216 226 13 203 26 128 188 231 57 255 0 26 95 212 86 203
+        14 38 0 224 17 188 125 42 75 20 6 20 41 26 240 252 40 164
+        186 234 187 174 24 60 133 78 89 87 218 149 187 209 148 221
+        236 138 245 22 157 60 140 183 218 74 1 34 249 247 204 160
+        162 241 142 213 79 245 47 72 111 89 117 61 99 84 182 187
+        158 103 33 174 166 206 10 255 0 42 133 245 251 213 175 213
+        218 164 50 217 172 77 44 214 192 54 8 65 153 36 250 40 165
+        235 164 216 95 233 145 223 73 17 140 91 201 143 195 177 220
+        227 244 236 198 173 6 250 55 37 118 206 124 181 232 213 212
+        181 136 196 118 238 246 80 74 54 160 1 90 97 239 159 229
+        171 3 81 179 134 222 91 125 63 77 88 108 247 70 21 97 132
+        238 43 245 53 45 120 119 180 159 135 218 145 202 124 24 230
+        10 1 96 59 138 144 116 239 76 219 104 202 250 174 165 4 101
+        194 238 201 94 91 218 157 201 213 11 26 91 162 47 209 221
+        26 52 117 23 55 18 44 146 183 32 241 146 126 181 97 105 233
+        20 118 239 243 120 107 243 2 121 52 161 18 107 251 179 117
+        35 164 17 70 249 66 107 125 213 247 138 230 59 119 1 148
+        224 149 236 106 118 51 105 187 99 27 235 207 20 237 133 85
+        51 237 90 163 140 144 27 36 55 175 214 176 176 141 3 171 57
+        220 128 242 222 212 213 32 181 101 44 179 99 53 59 41 141
+        241 20 200 230 41 119 134 56 245 197 31 105 121 29 194 42
+        177 193 3 134 254 42 198 107 120 2 16 178 100 251 210 153
+        213 161 184 13 20 228 145 243 173 50 86 9 53 123 50 234 11
+        11 107 132 41 134 60 99 35 4 255 0 125 85 157 71 210 82 232
+        87 15 123 4 237 225 49 203 32 28 15 92 241 86 153 120 245
+        40 4 33 140 12 220 54 239 152 214 173 37 225 148 75 165 223
+        70 178 197 38 80 59 12 213 185 19 139 75 225 77 117 119 76
+        218 117 23 78 199 47 225 99 146 248 121 146 242 54 243 3
+        252 172 191 245 164 29 51 210 246 205 122 209 95 27 104 110
+        162 249 76 132 248 83 143 117 43 87 61 247 76 54 135 118
+        243 89 248 81 68 91 43 159 95 113 205 124 211 116 235 59
+        199 54 23 81 195 110 249 202 133 64 54 122 231 39 248 104
+        114 98 73 236 91 209 125 35 169 105 98 107 75 29 66 7 178
+        150 60 155 57 0 59 121 244 39 154 176 161 130 56 45 161 131
+        240 242 36 164 237 44 221 179 244 168 206 172 145 216 106
+        169 111 43 77 19 68 121 184 135 229 199 250 223 79 168 169
+        93 165 218 234 150 209 172 106 222 64 48 87 215 30 166 167
+        40 219 177 137 5 164 77 225 36 102 48 236 7 36 210 254 160
+        178 221 27 70 208 171 41 249 151 210 159 105 140 205 10 22
+        12 209 109 192 217 232 126 191 90 251 119 110 165 6 236 183
+        213 187 209 72 45 183 217 69 183 75 195 125 121 61 155 100
+        5 30 184 205 115 207 198 174 155 151 68 213 222 32 25 161
+        83 228 98 7 34 186 207 88 181 139 79 234 23 149 155 247 220
+        10 163 255 0 202 41 80 99 115 120 135 178 3 252 67 6 155 28
+        147 208 117 84 202 79 164 121 159 185 198 123 26 153 3 129
+        233 81 14 155 253 250 152 252 188 224 129 233 82 233 50 23
+        235 76 227 178 79 197 31 83 243 62 113 147 239 69 69 10 17
+        207 56 237 66 70 234 20 224 115 68 71 56 0 125 120 167 197
+        209 141 160 49 250 250 86 74 25 125 43 234 28 14 56 205 101
+        147 239 84 48 155 89 82 249 46 54 159 165 109 209 219 49
+        125 171 29 96 150 206 121 226 190 232 192 180 71 21 140 53
+        145 153 136 192 29 168 109 70 54 253 151 120 205 192 54 207
+        255 0 45 18 119 46 57 244 172 117 94 116 59 175 253 179 255
+        0 202 107 24 142 89 51 27 24 6 15 238 146 183 163 13 224
+        100 103 53 170 197 15 224 160 237 251 164 175 174 140 178
+        175 110 245 199 99 146 109 59 247 127 173 22 85 73 60 208
+        90 110 68 32 159 122 34 114 206 190 203 233 142 245 117 29
+        89 39 221 16 158 179 54 177 220 6 150 54 101 29 212 54 9
+        253 107 111 65 52 119 55 208 199 14 159 167 164 123 191 120
+        209 111 147 191 189 1 214 76 222 33 221 130 113 71 252 41
+        88 255 0 104 199 36 165 130 171 100 227 214 150 79 84 58
+        126 71 78 217 170 67 162 91 71 31 38 76 42 17 235 86 191 71
+        218 226 40 183 157 227 104 3 30 245 85 116 252 107 47 224
+        147 147 26 121 176 106 212 209 200 68 130 221 153 131 103
+        118 229 237 138 136 242 236 147 52 74 210 101 92 7 94 113
+        81 206 163 180 146 65 45 212 115 0 66 224 212 170 13 172 85
+        149 148 48 60 230 163 157 92 118 146 241 130 177 200 118 96
+        251 227 63 244 167 125 0 170 250 146 107 143 26 41 174 154
+        105 32 81 183 100 67 37 142 104 141 62 226 225 44 37 156
+        192 167 127 149 93 184 194 251 154 34 85 150 107 205 145
+        176 9 27 121 178 56 175 107 55 45 34 236 114 145 219 47 4
+        142 9 164 10 179 239 79 89 193 97 27 94 77 34 162 47 152 51
+        30 13 9 170 235 147 234 243 24 80 18 177 156 130 61 69 71
+        239 239 159 88 188 88 85 21 45 226 60 5 39 154 51 80 158
+        223 65 182 73 37 184 54 225 70 230 4 14 70 59 81 76 106 190
+        198 23 55 145 91 233 127 141 105 132 48 198 48 238 199 3
+        255 0 154 174 58 155 227 6 147 167 135 139 69 183 123 233
+        84 238 241 230 249 11 85 101 241 47 174 53 30 162 190 154
+        40 100 123 125 56 54 216 237 225 111 46 51 220 253 106 53
+        162 195 249 223 155 143 15 235 70 43 147 7 137 100 15 139
+        93 115 122 210 203 111 115 4 1 223 248 98 193 3 233 91 224
+        235 142 190 159 44 117 201 23 112 254 17 66 244 246 143 9
+        132 58 170 159 165 53 93 29 113 226 5 35 43 144 0 167 81
+        127 161 185 68 15 255 0 212 47 136 86 174 118 234 178 76 23
+        130 28 113 138 249 167 124 105 234 91 59 198 143 87 180 181
+        188 182 99 229 35 190 62 148 116 154 76 126 31 238 219 44
+        57 200 168 119 85 233 118 246 170 74 40 12 79 4 246 20 90
+        111 224 27 139 46 222 152 235 237 19 169 151 109 140 198
+        218 240 156 61 180 237 134 79 246 126 181 34 212 21 229 41
+        26 161 241 147 204 8 244 250 215 29 239 158 206 100 158 41
+        36 142 88 206 229 120 216 130 167 220 123 213 223 240 171
+        175 165 212 172 19 76 214 36 205 194 174 216 238 9 229 135
+        177 164 118 129 73 244 93 58 63 80 195 169 35 105 23 135
+        108 177 46 6 238 198 129 182 183 146 199 89 146 65 27 74
+        210 38 207 15 196 194 129 244 164 122 189 171 181 132 55 80
+        183 134 20 238 18 47 175 222 138 210 117 111 218 67 240 247
+        18 5 184 78 3 10 91 12 83 110 168 207 85 150 225 110 90 222
+        68 144 6 95 202 42 60 195 234 79 173 72 186 125 111 38 252
+        53 180 146 166 118 124 222 189 251 26 213 115 190 234 201 0
+        88 214 88 142 85 241 233 68 116 235 184 34 119 145 222 69
+        109 187 113 253 244 108 220 75 31 72 181 120 160 48 25 4
+        128 12 144 43 116 176 199 248 15 13 99 98 8 230 182 105 222
+        91 96 164 129 43 97 183 30 216 199 106 209 172 188 98 216
+        198 172 195 234 180 91 36 221 58 43 158 186 142 72 46 32
+        154 67 149 13 159 189 85 31 25 237 148 233 226 85 240 156
+        21 220 168 235 184 30 61 69 91 221 94 127 21 104 95 4 140
+        121 126 149 89 245 117 172 87 90 116 126 59 200 27 105 92
+        142 64 21 37 26 118 91 134 172 230 221 62 226 221 53 16 143
+        103 28 110 78 73 133 246 47 255 0 230 164 55 238 134 37 218
+        70 61 57 165 29 89 165 92 104 218 195 188 136 230 34 124
+        178 122 99 222 178 134 224 188 74 172 114 64 239 86 82 100
+        166 188 67 34 108 46 115 69 71 38 229 238 41 100 47 199 122
+        54 221 129 166 140 184 137 45 58 24 219 252 167 62 245 183
+        156 103 210 180 68 234 171 94 150 96 20 14 106 139 34 97 0
+        213 121 25 29 141 124 210 37 111 8 166 59 26 245 243 6 77
+        163 248 123 159 122 195 70 238 212 121 196 195 144 196 247
+        21 163 84 35 246 77 208 245 17 57 63 109 180 65 27 87 60 80
+        154 145 255 0 203 111 127 246 207 254 24 173 206 38 21 233
+        188 216 219 159 254 146 127 133 110 4 9 121 25 161 108 37
+        85 177 183 95 85 140 110 250 226 136 143 243 36 7 208 26
+        228 41 30 199 214 25 240 78 71 173 109 150 64 16 143 95 65
+        239 88 90 16 109 248 227 28 86 139 146 119 231 60 142 213
+        107 124 73 201 121 16 206 172 95 26 80 23 191 175 210 166
+        191 9 186 121 141 170 220 180 51 57 39 129 129 239 222 144
+        217 105 82 234 218 199 131 179 11 184 110 53 209 157 23 211
+        214 182 122 44 81 201 48 241 182 0 61 49 74 24 251 14 122
+        66 214 229 94 48 208 133 80 63 139 189 88 90 72 96 192 54
+        56 236 105 7 78 88 164 31 52 129 163 94 88 231 204 79 181
+        74 32 134 75 123 116 196 68 156 118 110 226 145 143 46 198
+        179 58 65 18 179 74 219 207 112 59 84 115 170 46 217 180
+        249 95 121 44 62 81 237 245 251 209 183 119 81 180 108 184
+        238 42 25 212 90 162 174 228 102 93 157 155 119 96 41 152
+        42 207 186 29 184 107 71 154 87 35 185 99 238 106 35 214 90
+        132 78 5 157 187 22 99 232 41 157 222 169 44 26 83 52 101
+        76 44 48 54 118 53 26 208 109 228 190 214 33 145 162 12 12
+        152 25 246 164 47 12 111 76 155 124 53 233 149 16 45 197
+        218 110 64 114 115 235 84 239 199 221 101 78 177 123 102
+        140 26 56 188 160 102 186 123 67 179 75 123 51 101 8 13 193
+        12 127 147 235 92 107 241 198 27 139 126 176 212 98 152 146
+        230 124 159 246 105 148 28 132 134 68 242 52 200 12 48 44
+        118 198 237 149 195 183 37 15 202 62 213 165 53 63 1 131 60
+        39 195 251 84 155 168 46 180 217 180 109 62 218 212 51 92
+        54 12 161 7 205 247 165 87 82 89 54 159 36 87 22 142 140 62
+        94 59 85 34 168 156 161 110 209 97 124 56 215 45 245 8 28
+        170 12 227 145 237 86 5 215 225 226 75 113 12 108 254 77
+        217 110 56 170 35 225 13 243 91 235 38 53 243 161 111 238
+        171 123 169 245 84 91 139 104 17 137 65 24 17 253 15 181
+        116 66 105 160 113 67 109 70 91 88 173 214 118 0 239 5 72
+        81 218 169 78 186 234 56 127 27 45 154 167 136 55 144 49
+        222 173 110 160 212 29 58 101 228 42 5 202 198 66 12 122
+        123 215 62 233 243 164 250 255 0 141 116 60 92 49 242 142
+        237 247 161 55 72 220 80 93 188 222 50 8 230 132 164 141
+        199 110 5 49 209 255 0 242 221 97 24 23 216 28 40 223 199
+        127 181 107 189 186 73 119 50 219 202 189 176 224 114 121
+        166 125 93 62 159 113 248 25 172 29 213 196 65 164 200 238
+        213 12 177 114 141 153 73 69 209 212 95 8 26 223 168 186 54
+        104 166 219 35 68 72 81 246 21 27 234 77 54 125 23 88 18
+        236 216 132 242 69 51 255 0 37 139 27 166 208 175 174 74
+        150 141 66 149 95 114 123 212 179 226 94 151 227 217 181
+        196 42 36 98 114 19 249 126 149 25 174 40 188 50 46 64 61
+        45 117 107 170 89 51 69 38 14 57 7 189 109 179 111 194 245
+        10 13 196 46 60 195 211 25 168 15 76 222 92 88 234 70 5 5
+        73 60 113 145 82 150 213 51 126 143 112 34 19 99 128 135
+        119 30 249 255 0 165 104 116 52 210 79 69 167 109 119 185
+        17 22 66 87 119 13 235 138 35 83 11 140 198 229 199 166 106
+        45 162 220 120 138 36 207 25 230 164 81 75 226 40 88 227
+        223 143 74 214 115 53 228 70 181 136 157 225 117 141 64 227
+        133 53 93 235 150 179 52 130 23 132 62 14 0 95 191 173 90
+        250 196 56 152 49 219 150 249 75 118 6 161 215 246 48 139
+        215 146 105 24 130 48 71 240 211 36 55 39 209 207 127 20 33
+        179 180 212 101 79 6 102 89 24 46 201 62 82 113 220 84 6 88
+        22 44 52 44 206 159 94 226 174 175 140 58 47 137 104 38 179
+        101 148 71 150 81 184 6 83 244 205 83 54 30 42 72 232 246
+        243 3 159 48 200 110 126 244 64 246 104 220 241 131 186 137
+        182 184 64 57 110 107 102 161 110 172 9 141 65 30 254 212
+        166 104 218 35 156 253 42 148 128 210 100 129 46 99 63 197
+        95 39 148 99 200 115 72 34 149 193 201 99 138 221 248 229
+        67 207 106 87 20 128 208 222 233 129 143 30 222 190 245 142
+        151 235 247 165 175 125 226 2 84 226 143 210 100 5 194 255
+        0 53 40 7 133 191 44 80 90 144 206 153 122 114 127 171 61
+        109 150 224 46 87 219 138 26 250 101 109 34 233 189 225 112
+        126 213 168 70 221 137 52 247 111 194 91 140 28 136 249 166
+        118 114 121 192 160 116 224 166 24 71 111 203 163 173 194
+        248 234 5 98 204 146 89 170 152 115 187 239 66 223 99 5 148
+        225 63 157 62 106 105 99 25 48 42 199 183 39 190 104 203
+        189 29 230 179 1 21 83 112 249 143 111 238 172 37 48 14 133
+        210 188 109 107 241 144 164 50 46 209 151 99 130 13 116 78
+        131 56 158 218 20 150 81 189 80 13 158 131 235 85 223 195
+        94 156 59 143 226 99 12 217 225 135 21 108 90 233 166 36 79
+        10 30 0 239 88 172 152 218 198 23 133 149 225 96 185 238
+        126 148 254 207 12 187 34 137 143 243 63 165 35 182 146 88
+        80 35 67 128 79 239 15 240 253 41 148 55 50 71 3 198 155
+        223 63 59 227 185 250 86 20 246 175 9 49 238 137 75 194 7
+        14 59 26 171 122 185 101 146 252 170 221 70 138 79 57 171
+        19 90 190 184 150 223 207 136 198 60 160 85 91 173 91 79
+        121 123 35 126 42 20 85 57 229 143 253 169 39 236 52 59 21
+        95 71 52 120 85 189 141 19 24 193 61 254 181 38 232 109 62
+        56 84 95 120 139 52 177 12 70 23 208 251 210 8 45 33 102 62
+        35 69 113 183 143 43 28 138 150 244 28 129 53 1 12 177 109
+        133 56 69 30 223 90 89 71 145 87 58 90 44 222 153 135 108
+        45 112 24 137 64 59 200 35 39 138 160 63 202 143 164 236
+        110 35 77 90 16 177 220 71 31 157 207 118 63 203 255 0 95
+        210 186 59 76 240 101 45 113 224 67 10 200 219 34 218 152
+        57 168 199 95 116 226 234 154 109 212 19 66 158 32 207 206
+        14 8 193 237 93 81 141 66 145 199 109 202 217 193 218 38
+        143 125 172 92 206 182 82 120 115 194 3 167 250 199 216 81
+        186 229 182 179 114 195 76 184 142 52 153 64 252 208 57 63
+        83 79 238 108 238 58 51 172 102 142 72 93 32 119 36 100 119
+        25 197 72 174 109 109 245 43 132 213 172 128 119 83 202 159
+        81 83 166 116 173 171 43 142 148 209 167 210 53 87 186 109
+        225 20 130 8 29 254 212 255 0 168 117 88 99 189 18 151 121
+        75 184 112 15 163 10 115 169 205 104 214 160 109 219 47 168
+        3 24 168 70 191 34 35 161 50 198 74 190 79 218 171 23 76 95
+        199 68 203 87 214 37 213 236 26 53 97 28 146 199 220 255 0
+        102 42 186 135 166 111 237 101 123 191 50 170 19 133 35 150
+        251 84 183 68 104 4 177 177 98 112 6 125 170 84 82 27 248
+        197 189 188 97 156 253 56 169 202 77 176 113 118 65 83 78
+        215 58 130 206 36 216 150 214 208 121 188 131 131 250 210
+        254 157 210 219 80 215 226 210 252 97 8 241 48 197 189 106
+        194 214 117 11 77 19 76 125 54 215 30 57 82 9 28 3 79 255 0
+        201 219 162 228 212 181 51 171 222 70 35 241 27 10 204 14
+        59 131 237 70 9 216 217 101 20 182 116 135 194 61 10 223 71
+        233 107 107 59 21 100 11 15 159 61 137 250 208 157 71 12 97
+        154 215 143 1 137 222 171 83 13 26 218 43 88 139 75 108 35
+        139 110 197 57 225 143 189 38 234 185 161 181 211 101 183
+        48 140 177 224 142 226 182 98 56 211 178 137 234 75 3 103
+        126 235 13 210 69 179 144 73 173 130 222 67 20 99 241 145
+        191 102 220 13 27 168 199 28 215 18 77 53 184 93 195 130 79
+        106 16 88 52 155 213 111 32 12 167 182 227 255 0 106 132
+        186 59 155 209 97 116 84 108 85 3 72 36 56 192 34 167 80 70
+        200 128 172 81 179 175 24 61 234 176 232 167 154 223 242
+        154 101 45 191 131 159 165 88 208 95 93 44 106 165 81 128
+        31 50 250 211 199 212 228 105 169 108 211 171 31 16 177 142
+        51 27 145 202 159 74 142 94 195 25 140 200 192 22 94 114 87
+        52 250 250 105 35 117 104 83 45 234 27 185 165 119 214 183
+        19 184 62 25 85 110 227 183 52 76 85 255 0 17 132 154 166
+        147 37 186 248 46 20 21 7 110 222 125 170 129 155 79 252 60
+        230 39 32 182 79 145 107 171 122 135 68 142 75 86 221 25 92
+        100 146 59 26 162 186 143 167 38 135 88 220 138 165 119 28
+        30 107 24 133 203 14 207 44 159 150 79 240 175 99 75 110 45
+        85 216 243 83 62 164 210 229 135 108 166 18 138 125 248 34
+        163 110 129 92 228 86 17 232 71 37 152 0 226 130 158 215
+        239 82 48 136 202 124 190 180 37 197 190 92 129 142 244 105
+        152 143 205 19 33 242 127 109 63 233 213 252 149 242 146
+        217 228 214 155 139 85 10 78 40 189 15 8 59 113 154 120 166
+        96 249 147 50 29 220 26 211 168 68 19 72 186 62 190 11 147
+        246 162 174 15 230 134 247 21 167 84 255 0 50 221 55 24 107
+        119 24 162 97 14 159 36 102 218 32 205 180 248 116 198 213
+        226 87 83 188 147 154 81 107 167 220 53 140 18 7 35 242 249
+        163 44 237 37 105 17 119 28 131 147 82 28 156 233 82 143 18
+        49 232 69 79 180 187 75 121 32 92 220 73 28 184 249 68 69
+        133 65 186 106 197 231 158 36 49 201 38 61 87 210 174 190
+        145 211 94 68 137 95 195 66 171 140 177 231 245 172 97 191
+        72 233 106 109 6 103 93 195 186 142 230 167 58 110 155 149
+        2 36 4 1 146 204 199 138 15 167 44 108 128 241 124 25 230
+        127 226 240 71 203 82 107 123 49 34 172 113 248 241 71 156
+        226 65 131 88 87 42 6 22 110 1 241 219 196 92 121 84 129
+        138 211 5 149 227 238 88 149 84 19 252 93 170 65 111 103
+        146 84 149 104 151 251 65 172 166 82 241 42 66 205 41 31
+        194 220 17 253 148 44 28 209 92 245 109 181 212 113 110 220
+        74 129 192 30 181 84 206 151 127 141 151 198 194 3 192 4
+        213 229 213 154 108 146 218 14 114 49 230 95 229 174 127
+        235 72 166 211 53 41 87 12 242 147 223 39 129 83 156 188
+        139 225 142 218 26 233 208 201 11 157 171 16 82 114 78 78
+        106 95 211 141 17 148 180 69 153 211 137 31 248 84 253 106
+        187 210 229 27 98 154 234 102 10 87 29 253 106 99 211 247
+        50 71 229 137 138 237 243 73 143 226 31 90 220 138 100 73
+        45 23 31 79 177 184 177 104 84 141 225 195 120 141 198 71
+        208 83 253 66 55 75 114 242 175 137 43 240 0 25 207 21 16
+        233 137 18 107 104 217 110 11 55 0 15 166 123 84 230 250
+        120 225 136 200 204 200 137 128 8 25 197 118 65 218 60 188
+        146 119 163 156 190 49 244 36 186 173 171 92 181 143 225
+        228 44 85 153 187 143 94 42 128 158 223 90 233 105 158 56
+        219 198 133 143 215 143 181 117 247 196 9 154 123 217 165
+        105 34 104 200 206 194 249 195 127 241 84 31 89 91 238 184
+        157 99 133 30 82 55 40 29 143 214 169 197 23 199 41 112 162
+        186 185 214 103 186 102 123 219 95 57 239 33 24 3 251 42 61
+        172 120 51 36 69 109 119 3 47 206 61 78 15 21 33 184 142
+        230 221 222 9 70 84 15 54 125 169 116 176 205 24 93 141 132
+        241 6 6 59 26 159 17 249 72 198 214 241 98 108 27 117 4 224
+        149 92 211 111 252 65 168 64 98 75 43 87 17 129 229 44 56
+        199 233 205 3 107 110 99 99 52 152 50 150 56 99 237 154 123
+        211 176 77 38 160 37 101 223 31 177 237 70 43 246 110 82 10
+        232 190 141 212 53 205 71 241 87 143 28 140 88 121 125 43
+        171 254 26 232 50 233 22 137 111 248 16 144 42 133 223 142
+        9 170 163 225 212 126 10 143 13 109 192 115 128 31 230 253
+        42 249 232 235 223 11 77 134 25 36 73 90 110 236 15 57 166
+        215 194 25 174 84 55 189 178 97 21 188 74 235 225 15 54 210
+        121 53 5 235 9 86 234 105 118 131 187 119 150 33 243 84 243
+        168 21 134 153 148 145 35 216 255 0 49 238 56 170 163 172
+        110 246 221 148 183 185 203 147 193 90 134 99 163 9 14 213
+        90 57 49 224 176 111 230 87 226 144 79 4 139 52 147 43 196
+        140 253 129 124 12 209 122 205 212 6 227 198 110 1 242 103
+        63 197 239 81 141 94 238 226 25 194 40 87 70 244 127 81 244
+        174 103 45 29 138 28 145 48 233 15 198 27 192 146 18 27 119
+        163 2 63 76 85 189 164 89 221 73 26 42 185 200 28 131 85
+        191 195 29 42 75 141 146 194 172 24 159 144 255 0 15 30 149
+        113 233 150 55 16 170 135 252 206 60 210 123 85 99 234 114
+        229 146 230 1 29 155 9 135 226 87 9 252 254 162 190 157 54
+        73 150 76 206 179 156 121 119 112 64 253 42 68 34 23 10 4
+        109 226 159 76 208 151 54 110 238 87 196 43 32 237 232 7
+        222 137 62 104 132 107 26 118 99 219 226 136 152 14 121 205
+        86 125 99 167 175 237 5 105 110 23 96 62 102 65 87 101 229
+        188 101 30 59 139 121 159 159 51 70 50 13 67 181 253 46 209
+        204 177 194 198 53 217 156 74 7 6 176 201 217 68 117 172 48
+        8 222 72 228 50 38 223 33 116 108 230 160 19 129 180 62 59
+        174 113 87 71 94 233 47 38 158 234 139 184 43 97 86 169 187
+        184 158 34 241 200 48 85 138 129 236 43 2 74 221 128 250
+        103 222 176 101 39 229 25 53 159 210 179 135 230 170 115 85
+        64 52 201 22 80 150 24 56 161 172 78 217 8 0 119 166 23 142
+        190 27 113 233 75 237 10 155 130 2 253 105 224 237 24 105
+        58 110 10 223 74 18 255 0 63 178 110 193 244 129 218 143
+        149 149 99 11 142 72 160 117 31 243 85 217 61 204 78 15 218
+        131 236 193 186 90 198 116 139 76 50 159 232 201 254 21 240
+        8 214 109 220 18 57 24 165 154 124 231 246 109 170 238 218
+        22 221 20 215 212 185 118 155 195 29 189 234 35 147 62 151
+        185 63 180 227 85 109 196 243 145 232 125 170 240 233 87
+        154 98 130 117 42 224 113 159 90 231 254 159 141 77 220 110
+        210 109 243 14 213 208 95 13 174 45 209 81 90 100 44 23 203
+        187 146 127 178 177 139 91 167 68 45 106 163 233 147 24 238
+        194 164 246 194 223 193 93 177 201 193 236 190 159 122 65
+        161 25 226 95 204 138 16 51 198 79 27 105 254 159 226 186
+        121 152 39 60 39 253 105 146 178 13 219 8 84 102 112 4 112
+        237 246 207 52 108 80 71 23 155 240 209 243 245 175 145 32
+        81 150 82 62 181 181 229 80 128 114 126 212 234 128 38 234
+        59 17 121 1 113 181 118 131 149 240 176 107 157 254 36 105
+        145 172 225 132 94 57 82 119 47 168 174 150 190 241 164 6
+        72 31 195 35 212 142 106 176 235 237 5 174 124 86 101 12
+        216 221 187 24 57 164 156 20 138 96 157 62 69 19 13 184 134
+        214 71 243 120 132 102 52 147 248 105 222 141 61 221 194
+        172 215 18 131 50 12 125 90 134 154 19 103 168 120 18 237
+        96 217 0 125 104 103 241 173 101 252 106 134 27 79 111 74
+        229 105 166 119 57 114 90 45 126 140 184 86 180 102 55 40 8
+        237 205 78 191 31 60 86 95 135 107 229 220 190 111 47 36
+        241 242 213 27 163 234 202 176 41 241 140 81 191 112 123
+        211 185 186 180 219 217 198 209 221 168 144 143 56 99 206
+        43 167 30 95 140 228 201 141 223 67 62 185 190 0 22 88 89
+        78 194 89 166 24 85 62 245 68 234 173 20 200 146 120 151 15
+        39 140 216 192 249 177 223 21 100 234 93 81 167 222 233 242
+        121 135 138 27 206 9 24 97 75 172 109 244 123 201 222 118
+        186 72 146 21 59 6 6 11 55 106 235 82 137 57 41 69 21 69
+        244 107 60 211 93 169 222 178 249 75 55 4 26 2 230 55 93
+        145 140 130 91 129 142 245 120 75 240 222 29 147 220 75 118
+        30 222 100 81 28 157 134 226 70 72 166 215 191 0 76 154 124
+        23 81 107 2 210 70 149 7 157 187 131 233 218 133 196 73 100
+        226 172 231 200 35 12 21 130 144 9 218 51 234 105 173 147
+        53 180 47 106 237 55 154 81 38 213 29 143 181 92 250 183
+        193 155 93 2 226 207 241 55 27 217 230 97 184 158 15 181 0
+        157 15 107 160 194 127 107 93 71 0 157 155 135 97 207 177
+        173 113 30 18 114 86 36 232 155 166 181 212 229 142 20 15
+        143 149 27 248 143 181 95 61 33 125 178 213 99 141 94 2 163
+        115 73 32 242 131 237 84 149 189 254 147 167 202 177 171
+        167 138 174 4 135 0 227 235 82 24 186 206 56 238 36 138 210
+        113 176 227 37 143 31 165 36 164 146 26 172 183 53 139 233
+        37 145 47 13 228 65 72 33 147 61 170 172 234 89 213 239 76
+        97 195 43 49 243 10 217 127 212 139 61 152 48 202 93 149
+        124 192 17 222 162 154 181 244 173 190 4 254 177 41 201 39
+        176 251 87 62 73 166 138 98 139 176 77 70 226 105 110 227
+        128 248 50 89 41 255 0 238 31 106 9 108 115 118 169 36 98
+        88 216 249 95 209 13 31 102 134 210 220 137 35 60 142 239
+        220 83 222 137 209 164 212 174 195 188 108 235 158 0 251
+        215 53 72 232 121 20 116 139 19 225 174 154 190 12 107 17
+        119 219 130 199 244 255 0 10 182 236 213 161 183 40 171 147
+        237 81 142 150 210 174 172 237 217 18 40 227 82 0 5 187 212
+        174 22 216 118 158 113 234 59 26 234 132 93 108 243 231 92
+        172 209 53 180 127 188 240 78 87 156 30 213 161 217 164 25
+        154 48 24 118 49 242 113 76 193 89 99 56 237 67 205 20 120
+        199 202 125 13 55 16 8 111 196 76 140 161 37 39 25 203 14
+        213 1 234 117 1 164 101 229 74 96 55 189 88 23 183 19 70
+        204 138 137 142 217 62 181 21 215 72 134 54 150 70 183 84
+        245 221 158 63 186 183 18 176 119 162 142 235 107 139 179
+        101 112 48 74 131 149 250 213 55 169 21 153 101 109 195 118
+        226 49 87 143 197 11 59 89 172 228 240 238 163 86 11 193 86
+        242 213 7 168 41 183 153 227 13 189 119 119 20 133 31 26 4
+        138 53 225 183 114 56 162 35 249 141 99 16 93 166 190 134
+        10 199 218 177 51 11 207 221 183 218 128 179 230 224 227
+        154 97 117 242 31 181 45 179 202 206 87 215 189 82 14 145
+        135 197 65 136 103 142 40 13 74 48 116 219 220 28 255 0 70
+        122 48 73 249 67 52 22 160 196 88 93 242 60 240 56 20 89
+        132 246 173 33 176 131 211 242 147 181 25 98 164 202 55 122
+        241 90 172 99 38 202 223 63 232 146 141 137 10 48 53 33 195
+        237 36 17 76 55 59 140 28 241 86 191 194 221 82 71 187 85
+        134 86 137 241 229 144 138 169 145 73 66 203 220 28 154 150
+        252 57 214 154 199 83 71 134 72 163 97 235 39 106 198 58
+        223 67 121 30 205 68 246 178 34 103 201 57 60 49 250 84 166
+        202 250 59 114 171 42 153 28 140 2 7 97 80 110 157 214 5
+        238 147 18 27 150 57 60 113 156 126 149 55 208 161 152 66
+        38 143 136 200 198 120 57 63 173 89 164 186 57 199 169 35
+        72 23 119 0 142 213 189 35 81 233 199 181 13 8 118 33 179
+        192 224 209 101 148 32 227 154 6 62 50 174 119 99 129 233
+        74 122 130 205 110 173 152 236 11 246 29 233 163 72 161 114
+        71 21 131 48 145 10 178 239 83 233 237 65 179 45 20 167 88
+        244 52 211 91 27 203 104 80 178 18 119 122 231 218 171 11
+        187 123 200 110 31 78 189 93 162 67 243 123 87 79 107 176
+        53 157 147 186 43 75 17 238 139 232 125 234 136 248 146 177
+        73 114 100 84 96 155 185 13 195 126 181 25 70 203 225 156
+        147 164 35 210 116 152 166 184 16 52 171 42 149 202 236 247
+        170 207 226 54 139 175 105 90 204 242 61 196 190 11 28 198
+        83 149 219 237 83 222 151 214 197 133 218 194 100 240 225
+        249 67 96 114 61 170 196 212 52 152 117 189 17 90 56 209
+        212 12 238 35 56 21 60 77 73 157 83 132 226 185 72 228 251
+        45 112 139 146 26 86 59 20 134 4 156 22 162 52 205 98 226
+        222 203 242 166 62 57 186 18 54 227 193 3 211 237 83 78 185
+        248 112 99 190 184 149 45 13 188 32 231 116 125 152 213 121
+        169 104 183 182 101 130 238 0 252 153 238 5 116 62 206 120
+        228 82 123 39 58 151 88 245 117 197 134 159 165 75 124 86
+        218 24 205 202 70 184 218 7 177 53 60 215 254 43 117 237
+        199 75 232 182 247 182 18 89 199 225 44 214 243 173 187 21
+        184 10 123 130 51 199 189 115 249 107 184 36 221 151 221
+        141 188 156 241 237 82 109 7 226 31 89 104 177 71 109 109
+        172 94 4 130 217 160 129 50 8 138 54 238 160 17 218 154 133
+        88 87 254 139 31 226 175 196 126 181 234 43 13 48 94 88 61
+        132 70 63 26 222 88 247 33 125 191 196 51 233 144 106 29
+        212 157 103 212 58 189 165 140 186 165 244 83 35 32 88 176
+        131 32 47 114 126 181 19 213 186 147 168 117 153 33 159 81
+        212 174 238 154 217 12 80 120 178 110 240 211 249 71 211
+        147 66 44 55 19 90 71 181 75 159 155 25 236 115 90 135 73
+        46 221 140 238 53 67 251 78 238 95 20 178 77 146 50 121 205
+        104 210 245 75 139 217 34 181 134 232 137 3 16 192 3 154 47
+        67 232 251 173 64 201 227 187 71 35 225 148 14 248 207 106
+        185 62 27 244 16 178 195 61 132 105 48 148 18 242 96 22 95
+        214 132 163 171 4 230 170 162 7 208 29 47 125 30 141 53 238
+        172 242 178 203 251 188 30 64 199 253 232 177 103 28 123
+        100 241 137 149 120 84 110 199 239 83 126 177 191 182 208
+        237 37 183 143 116 44 56 85 36 55 24 244 170 238 202 83 123
+        118 94 66 67 19 148 106 228 116 203 168 73 18 94 153 233
+        253 83 95 144 76 202 76 46 112 163 31 227 87 31 73 116 153
+        210 204 49 204 170 14 1 194 210 111 135 23 11 20 34 8 35
+        145 159 56 201 3 21 104 90 90 27 93 175 36 126 35 176 206
+        242 79 31 74 233 199 7 86 206 60 143 97 118 241 133 77 187
+        118 129 233 239 91 90 53 199 28 125 171 21 155 60 50 225
+        171 238 252 119 170 217 42 53 58 136 187 51 42 250 129 65
+        234 23 94 12 69 100 143 35 221 123 138 60 149 151 229 20 27
+        169 71 219 252 62 223 90 1 35 215 115 43 40 113 32 251 55
+        124 84 47 171 100 186 49 179 184 154 201 65 231 124 91 149
+        170 85 173 98 202 233 252 103 42 224 121 152 199 145 223
+        251 170 186 248 147 214 183 90 125 177 91 107 171 105 7 250
+        223 246 53 138 68 162 190 47 107 186 95 138 214 49 248 190
+        48 28 73 25 198 223 211 181 87 209 0 214 161 139 51 100 247
+        110 244 87 94 106 67 88 234 55 186 240 194 31 92 113 154 14
+        73 213 85 87 233 82 4 244 244 124 133 130 190 211 235 68 52
+        89 229 73 52 2 183 155 121 163 109 174 50 160 131 233 88 17
+        102 171 131 149 35 233 75 163 27 110 179 76 238 20 96 210
+        213 254 179 85 198 149 14 54 149 179 26 231 142 61 41 102
+        163 41 252 21 194 142 194 39 166 50 168 48 131 244 165 151
+        202 63 5 63 251 167 162 251 17 183 102 122 48 63 179 160
+        224 254 233 43 126 71 137 143 90 203 72 79 252 174 220 129
+        222 36 197 18 45 198 75 17 81 101 227 217 227 251 146 61 77
+        15 111 122 246 87 65 149 118 227 187 30 213 235 171 133 141
+        128 57 237 90 226 219 121 34 110 71 40 7 56 28 154 186 143
+        40 137 47 99 167 126 4 117 157 174 161 167 172 63 153 44
+        136 120 24 171 231 78 212 65 81 225 218 249 118 231 115 28
+        0 107 144 190 28 89 173 188 130 77 54 89 34 32 231 105 56
+        39 237 138 178 180 238 161 234 84 87 102 17 76 136 48 6 9
+        199 215 154 14 60 65 197 51 163 45 102 103 1 100 216 170
+        121 5 78 69 99 169 220 54 192 163 201 236 199 214 170 77 11
+        171 245 39 17 71 112 168 23 28 248 35 183 223 62 181 53 209
+        175 226 185 45 33 153 131 255 0 44 188 98 164 251 19 36 117
+        72 147 192 159 42 72 164 38 120 62 244 112 27 80 5 35 111
+        160 165 118 19 120 142 1 96 223 202 1 230 152 44 168 80 110
+        202 243 142 105 211 64 173 30 154 21 153 25 100 25 82 48 69
+        84 255 0 18 122 82 19 35 155 101 32 179 100 10 183 3 46 56
+        96 104 109 66 202 27 200 240 200 140 222 153 173 40 218 27
+        28 169 232 228 91 238 152 186 91 147 43 63 135 20 71 60 142
+        255 0 74 125 211 93 69 117 98 88 93 200 22 221 92 4 207 160
+        171 91 173 250 76 108 150 72 227 80 51 187 143 106 165 250
+        146 41 68 141 111 29 187 8 213 253 185 205 113 188 124 37
+        103 124 36 178 42 147 44 121 46 108 53 205 177 220 69 249
+        108 155 65 247 250 212 119 170 190 23 217 155 104 37 134
+        225 10 63 203 143 240 164 218 37 252 214 58 188 112 204 228
+        64 202 48 79 189 89 90 93 253 188 177 237 89 214 103 253
+        214 210 123 15 113 245 170 71 43 229 103 52 177 46 52 138
+        27 93 248 99 116 151 210 44 86 251 160 69 196 44 163 211
+        220 84 30 247 64 107 107 182 140 171 56 31 46 7 173 118 133
+        237 180 90 149 144 93 194 54 141 118 57 42 57 250 138 137
+        106 125 33 167 197 120 100 88 86 104 216 96 101 107 174 50
+        199 37 105 28 235 179 155 116 14 140 186 212 193 240 55 51
+        49 206 208 188 226 167 125 55 240 195 54 203 45 210 186 72
+        143 198 70 55 15 122 186 52 46 153 179 177 138 55 182 217
+        20 217 228 99 140 83 173 90 104 225 84 141 97 141 86 49 134
+        36 96 181 53 165 234 138 37 201 144 171 110 135 210 116 79
+        10 226 121 20 205 225 229 4 124 130 107 238 173 212 150 246
+        54 203 105 24 72 156 55 151 216 241 254 53 171 169 181 136
+        109 237 36 219 112 30 68 114 145 166 114 77 87 147 73 121
+        168 91 139 182 87 46 210 121 71 176 174 73 101 116 209 214
+        176 213 51 45 96 106 26 245 227 195 122 216 99 204 45 232 5
+        54 233 30 147 152 202 177 205 147 199 3 20 227 163 244 134
+        213 30 40 228 140 164 138 70 25 187 26 185 250 111 167 99
+        183 132 60 209 70 37 3 154 92 80 79 108 76 217 56 233 25
+        116 63 79 219 217 233 161 221 79 138 125 79 165 74 23 229
+        25 227 28 115 88 194 137 12 33 19 140 119 175 179 58 38 55
+        56 31 90 233 163 142 105 182 99 58 163 46 230 96 160 118
+        165 215 146 52 67 197 102 150 48 222 168 51 69 207 44 126
+        25 60 176 250 14 212 174 246 96 84 171 178 178 5 200 32 240
+        69 103 163 40 114 26 137 15 135 230 81 199 203 187 179 80
+        83 95 73 202 136 33 56 255 0 91 154 134 235 29 68 108 99 48
+        219 9 166 0 124 199 24 63 110 106 11 172 117 110 189 53 203
+        197 225 196 233 140 169 112 114 181 135 88 210 44 46 168
+        215 33 143 79 157 228 73 85 84 16 222 249 250 87 37 124 96
+        235 11 91 205 78 75 11 75 153 21 131 19 137 70 56 171 39 86
+        212 53 237 70 57 32 188 185 82 161 14 28 13 187 87 254 188
+        213 69 213 58 29 188 241 201 42 67 113 123 118 92 225 136 0
+        99 251 107 112 79 232 106 136 45 172 37 228 105 14 112 123
+        31 122 33 161 221 231 60 55 108 125 40 217 99 104 81 97 112
+        145 183 177 239 65 22 96 73 244 237 74 218 163 27 60 53 9
+        206 43 43 104 195 112 57 172 21 183 33 251 215 212 98 157
+        142 13 32 12 175 65 7 145 74 155 137 197 57 148 111 83 187
+        154 73 38 127 24 71 165 60 69 147 25 187 226 49 142 120 165
+        247 103 117 189 217 247 183 113 250 209 172 165 163 31 106
+        22 244 40 211 231 199 205 225 62 105 133 25 233 30 109 42
+        213 113 140 198 159 225 154 57 216 44 44 48 59 119 160 52
+        103 85 211 44 148 142 76 8 127 93 180 85 196 171 225 242 42
+        71 74 116 70 181 2 242 94 14 113 199 97 247 169 87 65 219
+        36 215 177 195 40 220 8 228 47 113 253 180 141 109 252 107
+        213 37 60 184 239 237 83 174 143 211 149 39 87 0 110 35 200
+        195 131 138 180 102 170 137 190 236 187 58 103 166 236 35
+        48 52 114 32 24 221 133 249 170 91 107 165 194 210 5 148 4
+        24 192 56 168 247 77 204 176 89 68 222 55 138 83 229 76 14
+        126 149 52 209 238 55 145 226 76 129 217 126 87 3 129 90 82
+        85 70 74 194 44 116 24 227 153 78 119 103 182 208 48 71 214
+        155 92 104 236 214 174 17 76 111 252 203 220 211 109 38 72
+        100 140 6 240 164 218 118 249 123 230 152 203 11 109 9 28
+        140 152 244 32 100 84 69 110 136 158 149 251 66 218 111 194
+        218 184 47 158 78 114 5 72 45 159 86 128 156 172 114 40 93
+        204 199 57 253 41 93 196 81 199 127 137 15 131 38 120 34
+        155 219 106 64 58 195 28 121 80 57 111 115 72 60 23 137 178
+        29 74 89 38 86 154 45 171 252 195 176 251 209 173 121 8 5
+        150 64 9 249 72 245 173 55 48 174 4 182 234 178 49 30 104
+        207 111 191 222 180 189 188 19 219 238 145 124 39 95 238
+        166 78 76 87 75 160 203 219 113 121 98 20 190 254 57 35 214
+        161 183 93 11 13 220 146 220 54 84 224 236 80 7 38 165 58
+        35 53 189 185 93 199 104 244 166 73 134 1 135 108 230 179
+        175 160 230 215 69 41 170 244 5 221 179 37 204 176 248 171
+        17 59 84 14 231 235 81 248 244 109 67 78 159 196 11 34 144
+        251 184 245 174 141 101 220 140 49 201 239 154 73 168 104
+        208 238 105 240 173 207 153 113 72 240 193 236 172 103 162
+        162 147 168 46 237 252 56 132 78 217 143 156 131 205 101
+        107 212 23 37 89 165 134 70 77 222 78 15 53 53 189 211 108
+        154 225 166 107 120 194 42 144 191 65 65 219 221 104 214 54
+        107 248 235 88 252 36 82 219 206 125 234 111 148 53 101 249
+        127 194 40 122 138 227 204 86 41 3 231 142 15 106 211 125
+        123 169 234 176 162 109 146 54 3 146 163 189 74 236 166 211
+        53 75 176 109 97 70 129 135 151 138 145 105 90 109 177 111
+        195 248 9 145 242 253 41 146 151 105 153 78 190 21 78 149
+        210 55 151 72 200 33 98 31 141 199 146 15 189 75 116 79 135
+        114 8 209 111 35 196 123 118 140 119 31 90 179 52 205 54 27
+        24 246 140 125 168 227 207 113 84 73 62 200 203 249 18 122
+        100 95 167 186 102 29 46 97 225 64 133 23 213 187 231 222
+        164 83 203 28 108 25 164 31 111 122 251 43 108 224 71 147
+        239 154 80 109 218 109 77 228 152 17 30 121 25 239 77 72
+        156 83 126 193 247 23 107 26 144 60 205 232 40 24 111 174
+        166 111 14 8 145 142 78 75 103 138 222 87 50 5 130 208 2 59
+        190 79 21 153 11 103 110 207 18 6 62 173 236 105 28 218 10
+        236 85 123 38 178 45 252 88 165 81 144 67 32 30 148 134 222
+        198 235 80 184 114 210 22 10 249 108 30 62 195 233 79 46 46
+        86 123 98 100 102 137 7 30 94 228 214 26 28 69 220 52 56 95
+        109 180 109 181 108 51 175 245 23 221 104 208 203 25 13 31
+        229 129 194 251 210 27 221 6 56 84 182 239 46 120 12 163 2
+        172 115 20 110 160 110 19 183 169 110 21 62 216 168 230 179
+        52 101 156 43 64 138 157 234 170 104 69 127 74 251 80 209
+        225 184 180 144 51 194 168 14 15 166 106 191 234 221 39 75
+        179 211 165 184 146 21 154 112 126 84 98 23 245 171 39 87
+        185 202 186 49 71 82 114 25 71 106 174 122 230 37 156 40 50
+        77 55 180 64 0 15 246 86 228 53 20 87 81 74 130 251 153 35
+        67 39 101 143 36 99 238 104 9 50 234 54 142 213 35 235 13
+        19 195 45 36 96 65 27 252 170 57 231 245 168 229 186 201 20
+        4 73 195 103 24 247 20 128 122 116 122 47 148 253 235 9 178
+        172 72 247 172 226 32 3 159 122 215 63 53 128 213 133 195
+        34 136 200 60 253 233 61 209 254 151 156 12 102 155 69 26
+        176 198 222 244 166 249 130 92 5 250 211 196 70 168 105 11
+        47 131 230 224 80 87 255 0 212 238 63 221 191 248 86 208
+        219 160 3 210 133 190 99 248 41 249 255 0 210 122 167 17 92
+        141 118 127 137 253 159 1 207 30 18 86 196 51 186 156 182
+        87 212 211 13 50 12 216 64 27 31 186 76 140 246 162 217 225
+        136 120 123 80 41 224 115 206 106 40 232 98 43 123 241 111
+        55 242 128 113 147 235 86 7 70 235 76 246 230 31 197 68 140
+        195 200 164 237 96 62 135 214 163 182 90 28 218 158 99 130
+        221 164 59 178 0 198 15 235 239 83 110 151 232 9 102 141 45
+        238 237 102 138 39 28 156 252 191 98 41 210 160 39 68 255 0
+        165 250 138 212 58 193 170 73 178 233 134 228 73 134 1 30
+        245 97 104 186 198 154 206 169 103 118 214 236 71 158 25
+        198 232 228 63 70 244 168 62 133 208 169 21 164 118 179 70
+        211 148 27 99 71 200 199 234 65 53 34 178 233 77 74 194 47
+        232 114 58 143 68 151 133 31 99 89 171 11 157 178 203 176
+        99 185 30 56 210 54 198 74 171 102 50 61 193 247 166 203
+        120 56 63 32 61 188 78 23 244 53 94 105 26 213 214 151 34
+        65 172 88 220 66 190 147 198 165 215 63 92 122 84 202 206
+        234 75 168 188 68 219 34 158 79 151 1 190 191 74 70 19 118
+        187 11 222 67 44 177 177 18 6 220 184 239 75 186 90 250 71
+        102 183 153 124 225 176 64 244 250 211 153 97 142 226 50
+        193 164 82 7 96 188 138 91 106 39 134 247 250 138 202 231
+        141 231 130 71 181 35 84 131 21 240 154 167 49 34 238 13
+        199 24 160 103 45 29 214 214 82 84 247 241 56 81 69 217 110
+        49 40 48 52 89 28 140 19 254 21 246 250 214 73 151 104 141
+        217 125 8 28 212 219 108 77 38 107 71 120 216 109 66 69 16
+        38 82 128 134 28 156 80 86 73 58 66 99 117 124 158 57 70
+        255 0 181 100 201 60 78 89 81 153 49 200 8 114 63 186 130
+        116 48 99 44 138 63 45 178 123 226 132 186 185 120 226 220
+        97 102 63 196 69 97 52 178 170 171 68 178 242 57 204 109
+        255 0 106 85 169 92 92 179 21 69 112 185 231 32 138 22 195
+        24 41 50 63 213 151 154 140 182 87 118 246 208 73 27 225
+        138 101 126 149 203 122 183 93 117 30 165 38 161 167 94 204
+        208 248 19 164 109 30 48 78 61 8 174 179 185 188 189 92 25
+        97 105 87 248 252 157 197 85 223 17 250 3 72 234 125 66 13
+        98 214 217 180 157 71 112 23 37 99 32 78 61 73 24 239 79 39
+        25 157 120 230 177 233 171 1 248 55 105 213 17 233 144 222
+        220 248 50 217 52 132 194 7 204 23 255 0 154 187 244 141 66
+        229 131 52 208 177 193 218 131 28 154 143 104 115 197 97
+        103 13 142 159 96 237 28 40 168 143 225 156 240 63 252 52
+        217 46 47 152 134 48 50 182 253 196 178 145 71 81 68 114 91
+        118 137 97 184 157 190 85 49 159 102 172 252 67 180 110 96
+        88 154 77 109 119 50 219 170 24 228 45 252 71 109 24 101
+        102 64 162 57 11 247 225 73 197 73 79 147 209 37 141 160
+        167 186 40 14 197 220 115 130 7 165 7 113 54 223 48 243 159
+        85 126 194 182 71 11 42 110 109 229 255 0 216 108 127 133
+        105 72 101 150 243 196 145 88 133 236 2 54 15 247 83 59 176
+        85 5 105 241 55 134 93 243 188 118 52 46 171 34 67 3 185
+        145 93 199 101 3 36 83 68 142 84 92 172 100 125 233 38 189
+        36 203 4 135 240 108 231 30 163 138 165 94 128 145 12 135
+        241 90 158 160 99 86 111 12 54 91 105 201 21 39 134 85 183
+        137 98 82 177 198 6 60 79 251 82 189 46 217 152 134 104 12
+        1 142 78 208 114 104 235 213 217 228 142 57 60 188 6 101
+        237 246 166 173 81 154 62 94 77 44 150 225 83 42 23 213 199
+        155 244 21 29 213 174 34 181 133 247 220 69 1 3 45 52 190
+        103 31 65 255 0 106 47 91 215 45 44 81 252 95 21 220 29 171
+        26 33 44 199 219 21 16 190 126 161 214 8 240 109 13 165 190
+        237 202 146 99 113 250 241 154 41 1 161 62 179 175 104 240
+        69 36 239 49 42 23 205 52 173 134 99 238 61 170 187 215 53
+        233 37 34 230 214 241 150 215 186 60 131 195 76 125 9 239
+        86 14 163 209 114 73 40 146 238 54 109 195 45 189 72 254
+        193 138 135 117 47 195 150 190 148 93 78 178 76 35 253 216
+        201 217 143 246 79 21 130 138 135 172 58 169 217 198 39 142
+        64 252 43 3 197 34 211 238 191 16 134 70 238 220 131 232 69
+        75 117 206 133 188 138 228 205 37 140 174 15 206 242 112
+        168 61 197 71 36 129 44 93 193 85 69 221 181 85 152 3 143
+        240 166 143 96 146 189 131 187 237 63 74 196 29 195 53 186
+        102 73 6 236 167 232 192 255 0 133 106 85 227 140 99 239 79
+        45 128 38 30 212 162 251 139 174 120 230 156 64 8 250 15
+        189 1 168 70 11 124 188 147 223 35 20 189 9 35 116 37 90
+        223 5 128 29 243 65 234 18 255 0 67 184 255 0 116 244 90 41
+        16 1 142 195 222 151 106 24 252 61 194 110 27 188 54 227 61
+        179 78 165 162 110 34 139 47 220 55 251 165 160 238 251 175
+        251 85 234 245 73 118 116 190 131 109 63 174 219 83 53 253
+        234 126 181 234 245 80 80 139 143 222 15 189 122 95 221 143
+        189 122 189 88 198 235 207 234 95 253 163 252 107 86 155
+        251 179 246 175 87 169 31 209 144 77 191 121 255 0 217 173
+        49 127 90 95 246 133 122 189 74 198 143 99 214 236 104 22
+        253 243 125 235 213 234 148 69 126 198 211 251 197 175 79
+        251 179 94 175 80 8 60 191 187 95 181 100 191 184 74 245
+        122 153 244 62 46 204 26 180 183 239 79 218 189 94 166 47
+        30 205 144 126 248 81 147 250 215 171 213 136 100 236 244
+        63 45 125 184 253 239 255 0 109 122 189 80 143 177 51 91
+        252 181 157 167 205 94 175 85 95 208 154 161 175 147 126
+        234 111 246 63 235 94 175 83 46 204 129 173 191 131 237 91
+        117 15 221 138 245 122 156 192 58 215 249 246 111 247 149
+        242 127 221 39 251 85 234 245 17 88 116 223 212 135 218 148
+        220 254 224 87 171 212 16 77 109 253 105 105 76 159 214 222
+        189 94 162 140 205 87 255 0 50 255 0 179 88 71 242 10 245
+        122 156 64 133 253 217 161 174 254 85 255 0 106 189 94 165
+        125 139 35 47 253 58 105 99 253 68 255 0 186 175 87 168 174
+        133 63 255 217 13 10 45 45 45 45 45 45 87 101 98 75 105 116
+        70 111 114 109 66 111 117 110 100 97 114 121 74 57 98 119
+        65 87 115 51 121 110 112 113 115 72 53 75 13 10 67 111 110
+        116 101 110 116 45 68 105 115 112 111 115 105 116 105 111
+        110 58 32 102 111 114 109 45 100 97 116 97 59 32 110 97 109
+        101 61 34 102 105 108 101 50 34 59 32 102 105 108 101 110
+        97 109 101 61 34 116 101 115 116 46 116 120 116 34 13 10 67
+        111 110 116 101 110 116 45 84 121 112 101 58 32 116 101 120
+        116 47 112 108 97 105 110 13 10 13 10 116 101 115 116 10 13
+        10 45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
+        111 117 110 100 97 114 121 74 57 98 119 65 87 115 51 121
+        110 112 113 115 72 53 75 13 10 67 111 110 116 101 110 116
+        45 68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
+        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
+        108 101 51 34 59 32 102 105 108 101 110 97 109 101 61 34 34
+        13 10 13 10 13 10 45 45 45 45 45 45 87 101 98 75 105 116 70
+        111 114 109 66 111 117 110 100 97 114 121 74 57 98 119 65
+        87 115 51 121 110 112 113 115 72 53 75 45 45 13 10
+    } ;
 
-[ { "a" "a" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "aa" f f "b" f f "c" f f "d" f f } ] [
-    [
-        "aazzbzzczzdzz" <string-reader> "z" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-
-
-[ { "a" f "b" f "c" f "d" f } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "zz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [
-    [
-        "azzbzzczzdzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 1 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
-
-[ { "az" "zb" "zz" "cz" "zd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 2 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: dog-test-empty-bytes-firefox ( -- bytes )
+    B{
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 49 49 51 55 53 50 50 53 48 51 49
+        52 52 49 50 56 50 51 50 55 49 54 53 51 49 55 50 57 13 10 67
+        111 110 116 101 110 116 45 68 105 115 112 111 115 105 116
+        105 111 110 58 32 102 111 114 109 45 100 97 116 97 59 32
+        110 97 109 101 61 34 102 105 108 101 49 34 59 32 102 105
+        108 101 110 97 109 101 61 34 100 111 103 46 106 112 103 34
+        13 10 67 111 110 116 101 110 116 45 84 121 112 101 58 32
+        105 109 97 103 101 47 106 112 101 103 13 10 13 10 255 216
+        255 224 0 16 74 70 73 70 0 1 1 0 0 1 0 1 0 0 255 219 0 67 0
+        5 3 4 4 4 3 5 4 4 4 5 5 5 6 7 12 8 7 7 7 7 15 11 11 9 12 17
+        15 18 18 17 15 17 17 19 22 28 23 19 20 26 21 17 17 24 33 24
+        26 29 29 31 31 31 19 23 34 36 34 30 36 28 30 31 30 255 219
+        0 67 1 5 5 5 7 6 7 14 8 8 14 30 20 17 20 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
+        30 30 30 30 255 192 0 17 8 1 49 1 64 3 1 34 0 2 17 1 3 17 1
+        255 196 0 29 0 0 2 2 3 1 1 1 0 0 0 0 0 0 0 0 0 4 5 6 7 2 3
+        8 0 1 9 255 196 0 74 16 0 2 1 3 3 2 4 4 3 4 5 10 5 3 5 1 1
+        2 3 0 4 17 5 18 33 6 49 19 34 65 81 7 50 97 113 20 35 129
+        21 51 66 82 36 52 145 161 177 8 53 83 98 114 115 147 178
+        193 209 22 37 67 116 241 99 130 240 23 68 84 100 146 225
+        255 196 0 25 1 0 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 2 3 0 4 5
+        255 196 0 39 17 0 2 2 2 2 3 0 2 1 5 1 0 0 0 0 0 0 1 2 17 3
+        33 18 49 34 50 65 19 81 4 5 20 35 66 97 82 255 218 0 12 3 1
+        0 2 17 3 17 0 63 0 228 200 149 136 219 131 200 207 233 68
+        196 145 112 60 21 45 234 91 181 57 177 178 138 75 56 95 111
+        152 196 51 250 209 11 167 198 14 118 138 22 138 153 104 150
+        118 82 46 217 45 161 98 79 242 102 157 38 151 98 174 64 211
+        237 72 247 49 46 104 11 8 140 111 229 247 166 194 70 137 12
+        146 112 61 235 57 36 172 31 82 7 154 199 78 244 176 178 255
+        0 132 41 100 195 76 15 183 240 118 60 31 244 85 237 126 241
+        237 237 157 213 176 113 197 66 158 254 234 82 74 49 45 187
+        144 42 49 155 158 217 108 152 99 21 68 214 88 116 217 83 17
+        218 218 171 250 109 138 180 254 6 221 83 205 109 1 199 115
+        225 10 141 90 106 23 106 187 95 59 73 239 237 77 44 111 89
+        79 136 24 186 250 131 235 86 199 166 71 143 20 52 181 211
+        237 24 143 232 150 236 61 140 66 155 65 167 233 251 64 252
+        5 158 127 221 45 3 99 42 220 42 186 240 79 247 83 139 38 86
+        92 21 57 20 76 246 140 78 155 98 88 31 217 246 125 191 209
+        45 108 253 159 97 255 0 240 44 255 0 225 45 22 216 200 199
+        181 99 88 74 98 77 99 78 178 69 111 14 194 213 23 28 226 48
+        15 246 212 30 242 21 252 105 8 145 170 103 178 213 137 172
+        121 162 127 181 87 151 141 182 247 31 235 210 180 216 209
+        28 88 217 219 120 99 250 52 100 255 0 172 155 168 248 108
+        109 11 103 240 208 127 194 173 118 82 71 225 47 148 246 163
+        11 169 30 74 81 140 102 182 178 35 203 97 104 62 162 46 104
+        41 45 109 119 127 86 131 254 21 48 144 225 9 198 104 105
+        198 24 118 53 76 77 81 141 73 105 109 143 234 176 127 193
+        21 146 89 219 110 63 209 97 255 0 131 69 65 183 110 15 39
+        218 182 144 160 159 41 6 169 102 5 22 54 138 114 109 45 216
+        123 24 184 53 177 45 44 137 231 79 179 237 254 138 179 118
+        101 112 167 159 181 102 131 140 212 35 236 99 95 224 172
+        119 143 252 190 207 254 21 18 186 125 129 92 254 2 207 254
+        16 172 15 148 230 182 71 46 225 198 106 178 78 204 40 213
+        237 109 83 33 45 224 237 223 195 199 247 214 189 30 222 222
+        69 45 37 165 187 156 227 12 161 177 245 230 143 214 212 8
+        75 123 138 15 69 96 7 220 214 159 169 135 31 129 177 192
+        198 159 102 120 255 0 68 181 240 216 217 12 15 217 214 156
+        246 252 165 230 137 139 205 235 128 7 204 123 80 183 154
+        148 118 202 66 225 156 118 62 148 169 174 38 91 55 193 167
+        233 191 60 214 22 96 14 249 137 107 84 199 69 137 246 174
+        157 100 255 0 65 18 210 43 237 82 105 148 188 108 64 254 31
+        102 164 243 223 204 146 249 155 39 233 73 38 50 84 137 156
+        112 233 19 200 4 118 54 201 238 22 33 68 54 153 166 52 96
+        173 149 163 15 115 16 205 66 244 189 77 141 226 40 115 143
+        90 155 91 73 192 116 245 29 141 77 233 140 177 169 46 64
+        109 167 88 45 203 31 217 246 92 127 244 171 19 97 99 226 16
+        218 125 152 227 63 186 20 100 204 56 247 245 175 66 84 145
+        191 147 235 246 174 140 125 18 180 125 183 211 108 72 7 246
+        125 158 63 221 45 109 151 77 177 219 254 111 179 255 0 132
+        180 68 76 163 133 206 51 197 103 43 0 184 166 158 144 72
+        133 244 54 113 220 5 91 120 50 59 254 77 7 120 109 188 48
+        22 8 1 207 242 98 152 106 170 191 137 45 239 218 149 93 41
+        97 129 239 73 97 143 96 19 172 103 204 161 23 232 181 164
+        71 152 93 143 173 110 117 101 67 90 142 239 195 55 165 97
+        229 251 37 122 124 138 182 48 118 253 210 81 66 116 250 82
+        123 2 205 103 108 55 30 99 31 221 218 140 134 63 56 221 200
+        169 147 26 90 229 159 56 20 109 242 171 89 16 217 251 80
+        214 190 80 49 197 110 212 63 168 147 234 107 74 62 44 166
+        36 156 209 17 234 235 140 193 26 170 182 230 227 21 40 248
+        113 208 240 234 214 169 53 194 224 63 166 57 168 167 85 55
+        136 34 5 87 126 124 170 123 26 233 15 129 214 42 221 59 108
+        123 112 51 27 14 223 90 142 61 68 233 206 227 249 58 35 7
+        224 252 57 252 133 141 91 25 82 71 24 255 0 189 44 212 254
+        21 222 99 16 171 120 139 234 160 97 171 165 99 81 143 5 145
+        74 142 199 29 171 239 225 99 121 138 149 80 127 133 241 205
+        22 229 96 121 19 84 145 199 250 231 77 106 61 62 210 25 35
+        114 189 212 1 198 43 237 133 210 72 71 24 56 228 125 107
+        167 186 179 163 236 245 93 61 149 35 76 148 42 43 154 186
+        195 167 175 58 123 85 149 9 37 67 103 63 74 117 39 123 37
+        151 26 110 226 20 14 64 53 246 132 211 174 22 234 21 216
+        217 111 83 69 22 80 72 197 89 245 103 61 238 128 117 60 155
+        121 15 174 218 174 239 8 23 141 158 251 170 192 213 36 219
+        11 175 169 28 85 123 169 237 93 64 240 57 52 99 32 142 45
+        89 191 15 229 231 154 46 201 155 60 214 141 48 43 69 141
+        163 24 162 109 227 61 199 21 57 118 96 244 57 92 227 52 43
+        198 219 143 126 244 68 18 3 88 202 172 141 134 108 147 205
+        8 107 64 62 65 223 145 131 239 91 25 188 199 39 38 181 163
+        99 191 122 250 112 199 118 59 213 83 160 114 54 59 46 211
+        239 89 39 203 90 93 89 88 115 197 110 64 74 113 83 138 169
+        5 59 62 183 35 214 189 16 193 197 124 109 202 123 154 251
+        19 13 199 35 38 170 242 69 62 194 105 214 255 0 171 138 85
+        166 169 82 204 164 237 60 103 235 77 181 129 226 66 184 98
+        163 220 82 155 73 24 202 45 34 81 201 239 75 44 138 141 7
+        114 72 110 146 203 36 73 12 42 207 150 193 197 73 52 191
+        135 215 186 168 241 220 180 113 177 206 49 200 90 153 124
+        40 248 122 110 151 241 183 65 66 12 48 207 191 189 94 54
+        186 61 165 156 94 28 123 10 149 10 78 59 138 231 109 252 58
+        163 8 163 159 236 254 19 73 53 176 86 80 176 175 171 1 197
+        107 185 248 77 101 105 103 51 204 187 36 199 24 25 39 255 0
+        249 93 18 176 195 18 157 177 168 30 212 191 85 132 201 109
+        39 134 138 204 227 110 8 160 175 232 210 227 196 226 14 170
+        210 27 66 215 60 46 54 110 5 72 31 227 82 141 57 214 72 145
+        137 198 64 237 70 127 148 13 146 219 107 208 145 150 5 240
+        91 211 245 165 58 75 237 130 48 72 36 47 117 237 71 39 113
+        4 23 248 216 202 224 96 100 114 107 24 148 183 126 62 213
+        182 101 57 231 145 89 70 6 7 2 174 221 35 133 71 102 248 84
+        40 245 172 110 57 38 182 175 3 140 86 19 1 142 194 145 182
+        199 34 250 129 197 226 100 241 154 211 52 121 77 194 182
+        234 67 117 238 223 236 162 150 17 248 81 218 138 116 52 72
+        228 225 183 246 21 241 148 126 30 79 76 46 234 62 234 16 27
+        181 7 34 55 135 55 63 250 116 232 210 118 168 117 167 172
+        127 132 183 220 224 15 13 127 187 189 16 10 135 194 144 69
+        43 176 144 155 88 23 212 71 70 32 110 251 129 165 170 25 99
+        99 139 78 127 182 179 213 220 199 167 141 190 86 35 191 189
+        42 241 228 132 174 50 65 246 162 53 9 89 172 227 221 158
+        212 178 151 139 54 61 100 68 118 241 86 227 89 182 132 121
+        247 72 1 2 186 187 225 157 184 131 70 182 143 28 162 128
+        203 234 167 235 92 181 211 246 87 23 221 92 145 198 173 133
+        144 121 192 249 107 170 250 103 242 236 35 241 147 194 157
+        84 6 99 252 85 36 169 34 249 98 229 34 100 89 89 139 43 6
+        97 192 35 211 233 95 94 86 17 2 199 56 238 105 119 226 188
+        171 223 183 39 222 190 27 172 16 95 113 79 95 173 16 199 30
+        134 246 242 11 133 60 242 59 212 75 226 103 77 91 235 58
+        101 204 138 159 154 145 147 145 235 78 97 152 171 248 145
+        200 10 31 65 222 138 155 100 200 21 178 222 167 29 171 5 87
+        211 144 110 214 109 31 80 240 36 111 32 39 57 244 57 237 77
+        224 152 92 69 226 174 49 142 126 149 105 124 86 232 27 125
+        70 22 187 178 132 9 2 229 177 247 53 76 66 38 209 181 65
+        109 48 111 8 156 18 123 81 229 20 170 201 101 196 253 163
+        208 94 161 14 251 105 27 217 106 189 213 20 11 226 125 51
+        138 177 181 70 205 153 104 249 87 28 85 117 117 253 117 247
+        251 241 84 87 240 231 26 233 108 192 5 3 131 77 145 78 243
+        74 180 213 193 7 138 115 18 229 137 172 227 33 27 48 183 64
+        24 26 202 126 13 108 140 169 242 142 9 236 79 106 26 92 150
+        228 250 209 140 93 140 124 254 48 107 34 195 39 154 215 255
+        0 231 122 247 191 253 234 188 65 196 223 27 151 24 144 101
+        253 40 152 179 130 49 233 90 109 85 29 124 217 163 226 218
+        19 28 98 163 123 176 165 64 46 219 13 122 22 223 39 28 147
+        216 86 219 133 4 19 90 1 240 161 50 28 131 252 52 91 131
+        219 55 144 62 189 56 91 68 133 88 110 245 30 213 37 248 49
+        210 178 106 58 188 51 73 144 138 119 19 233 140 208 189 61
+        210 211 245 12 232 193 79 204 57 32 226 186 51 161 250 90
+        195 65 211 161 138 8 255 0 51 104 46 125 106 115 146 78 145
+        124 17 113 143 146 37 26 85 188 122 109 132 113 68 184 96
+        49 159 165 125 185 185 85 59 90 64 119 124 198 180 205 43 5
+        43 156 31 79 181 10 178 36 44 26 70 222 205 223 30 148 165
+        210 177 139 150 149 10 227 98 142 192 250 214 155 147 253
+        28 199 177 88 122 238 244 250 208 171 52 155 134 88 98 133
+        150 237 164 36 46 112 15 53 129 56 190 145 65 255 0 148 77
+        158 235 69 153 118 182 199 218 54 118 239 154 175 116 73 72
+        181 129 135 204 203 218 174 31 142 22 18 234 26 36 203 2 72
+        21 60 229 64 253 225 207 106 165 244 67 38 194 37 36 178
+        240 51 90 91 175 248 104 234 13 18 169 228 221 230 127 46
+        43 5 151 196 228 214 55 127 186 221 238 43 85 187 100 227
+        158 213 94 71 20 180 232 103 23 43 197 125 145 84 168 201
+        230 176 135 182 43 100 156 40 165 9 22 212 144 45 249 247
+        163 161 254 174 40 93 79 157 67 62 153 166 22 234 166 1 197
+        96 53 98 235 149 12 167 222 147 234 3 242 102 81 220 71 82
+        41 99 12 59 129 74 117 91 114 45 167 117 31 250 103 251 169
+        148 140 129 45 55 44 17 99 253 29 23 12 204 28 6 3 20 20 19
+        127 71 139 159 253 42 223 28 129 136 7 156 154 103 208 255
+        0 153 177 205 170 120 204 3 12 12 240 69 111 213 199 134
+        145 66 163 36 143 90 246 154 141 148 231 143 74 203 89 138
+        67 123 11 6 57 199 21 63 134 139 243 68 211 224 110 159 102
+        218 140 243 189 188 178 60 152 249 192 192 171 213 173 128
+        140 176 141 15 25 193 244 168 39 193 43 63 15 79 19 76 7
+        140 199 206 184 171 30 250 50 146 43 42 228 48 193 168 219
+        163 177 55 200 71 226 254 97 228 140 28 99 210 183 69 117
+        30 226 31 105 30 222 148 46 161 152 75 141 229 148 156 226
+        149 60 140 70 248 137 80 189 241 75 143 34 186 101 158 54
+        201 25 102 241 55 70 35 3 216 118 162 108 39 87 144 66 242
+        108 61 243 239 244 168 180 119 82 49 253 233 136 123 10 206
+        207 82 89 36 88 174 150 38 195 121 37 76 247 250 213 123 36
+        224 214 201 204 169 20 145 60 61 148 240 72 245 170 127 227
+        23 70 172 150 134 226 214 223 107 103 141 130 173 155 70 86
+        183 66 28 179 3 250 26 58 242 194 43 232 66 92 66 187 79
+        189 115 201 108 56 230 163 105 156 115 105 60 208 196 214
+        23 80 148 145 71 5 135 122 132 235 145 201 29 249 42 188 22
+        245 174 164 248 151 240 207 198 70 212 45 21 81 145 142 204
+        10 160 186 163 71 154 222 77 183 49 8 157 84 246 254 35 239
+        93 112 206 180 145 203 60 93 201 116 37 211 39 10 0 126 41
+        220 119 81 1 144 213 22 120 174 35 92 237 226 135 146 250
+        234 33 235 143 65 87 228 217 13 50 87 226 199 254 144 126
+        149 245 166 141 200 243 10 133 46 162 232 115 146 72 172
+        206 175 41 238 191 223 67 147 9 51 12 132 227 114 214 82
+        120 106 56 113 80 209 170 72 88 5 76 31 189 20 215 178 152
+        212 149 201 197 50 102 37 118 211 195 242 150 227 222 140
+        18 71 129 181 137 168 84 119 151 1 73 197 49 180 191 153
+        148 110 200 199 106 231 250 104 246 74 29 148 174 230 227
+        29 177 89 232 58 77 246 183 172 195 20 112 177 141 125 135
+        6 153 244 151 75 234 157 65 36 113 136 241 9 0 230 186 15
+        162 250 19 79 208 225 79 42 25 145 130 183 31 74 76 146 138
+        71 84 49 211 183 209 143 68 244 245 174 149 167 6 252 56 86
+        28 246 169 45 207 130 182 134 66 222 30 61 187 214 251 192
+        182 235 26 15 40 39 210 144 107 247 22 176 249 46 37 36 124
+        193 127 155 233 83 91 118 86 172 214 151 14 236 220 228 103
+        130 222 213 147 204 138 164 48 86 39 185 168 228 218 149
+        196 206 56 17 91 129 133 81 243 17 88 53 227 180 137 28 114
+        56 92 122 247 170 27 241 177 225 187 24 231 251 171 43 85
+        241 50 170 14 15 36 154 87 109 34 151 27 134 121 167 54 108
+        225 129 12 118 251 82 185 168 151 112 226 129 250 130 194
+        222 77 30 118 120 247 237 140 250 122 215 48 107 54 169 103
+        169 201 224 163 129 188 240 195 138 235 187 203 101 109 50
+        82 205 130 227 143 181 115 71 197 11 55 183 214 228 88 219
+        17 239 224 1 244 162 157 171 57 102 252 68 107 48 54 234 27
+        24 175 68 15 114 49 158 213 166 218 19 37 160 207 38 140
+        137 120 10 220 145 86 198 173 108 227 123 9 130 182 203 218
+        181 195 216 240 59 214 215 70 49 131 73 244 196 91 80 99
+        248 197 62 230 152 193 145 111 145 75 245 24 207 226 147
+        159 90 109 103 31 244 97 158 115 84 140 28 140 40 184 185
+        117 148 100 12 118 173 183 172 143 165 92 48 193 34 39 175
+        186 149 168 14 24 142 49 64 220 201 183 78 157 87 129 225
+        61 43 84 232 196 94 55 155 195 207 134 216 61 168 155 89
+        101 241 16 108 61 232 168 236 220 219 161 11 198 208 223
+        219 91 173 172 157 100 86 32 119 166 109 80 30 201 95 79
+        166 228 30 245 150 187 129 127 18 255 0 101 110 209 23 195
+        43 246 175 107 136 5 253 171 30 119 29 181 54 44 125 209
+        127 252 28 119 147 73 72 230 142 40 215 60 31 122 156 223
+        199 182 38 200 192 3 32 212 119 225 21 138 174 131 12 155
+        67 115 220 84 183 91 141 148 97 89 64 199 32 251 84 228 244
+        119 67 216 175 53 163 38 215 30 25 199 112 213 29 69 63 48
+        152 73 159 65 233 83 13 65 48 37 1 124 167 249 170 55 61
+        169 40 20 109 200 254 90 129 218 4 247 78 190 70 24 83 220
+        214 80 238 154 69 16 176 14 14 87 234 104 11 230 104 238 90
+        118 5 84 252 202 125 190 148 126 152 158 21 202 220 69 135
+        4 103 13 217 215 233 250 215 70 55 226 38 88 187 39 154 13
+        208 252 34 163 33 141 193 243 231 212 251 211 251 121 149
+        85 1 97 130 112 191 90 135 90 206 197 188 64 27 45 201 207
+        127 214 134 215 181 195 98 143 189 138 237 77 203 207 99 70
+        147 236 131 99 174 169 234 43 123 77 62 84 37 70 88 247 53
+        203 223 20 122 138 214 234 127 203 100 102 12 71 7 177 230
+        180 252 80 248 131 123 168 93 92 217 90 92 48 143 126 11 3
+        85 179 199 52 132 72 237 36 140 199 144 125 105 163 26 232
+        132 230 210 164 48 75 217 26 50 178 31 175 216 86 192 177
+        179 120 114 70 67 241 199 223 181 123 78 176 141 158 25 60
+        57 29 36 94 123 112 125 170 77 160 116 237 205 192 152 92
+        70 3 69 180 142 14 72 30 149 94 150 201 70 42 93 246 70 127
+        3 111 32 5 156 28 246 30 245 190 13 46 213 184 24 7 252 106
+        204 181 232 39 188 134 25 214 2 158 110 1 167 211 252 45
+        149 128 217 22 112 6 10 158 230 167 249 25 79 192 83 113 90
+        218 43 149 217 141 188 156 214 187 150 139 38 69 97 207 165
+        90 154 223 195 91 168 237 85 150 18 178 103 7 158 226 163
+        250 159 68 74 152 183 104 138 133 245 230 154 51 108 73 97
+        165 178 2 110 35 93 185 140 228 246 250 214 22 218 145 75
+        144 79 49 169 237 237 76 239 180 139 136 30 225 167 183 116
+        136 113 19 250 19 244 164 87 118 130 221 66 140 239 113 150
+        255 0 84 123 26 210 236 17 199 79 146 58 87 225 47 85 90 20
+        133 99 120 217 252 48 184 7 154 188 44 181 72 110 33 115 28
+        138 189 178 107 243 247 73 212 245 13 34 238 43 139 91 150
+        86 86 224 103 130 43 161 190 21 117 252 218 133 187 199 52
+        195 196 199 42 79 57 169 101 130 173 150 89 37 47 133 243
+        123 62 27 184 205 66 250 153 228 158 87 72 219 242 128 203
+        31 230 250 83 11 125 67 241 86 98 67 184 239 92 140 119 20
+        179 85 146 97 108 214 246 225 124 118 236 237 217 7 169 53
+        139 136 77 210 199 8 240 215 106 142 5 122 9 94 225 177 34
+        149 251 208 119 94 29 164 113 164 108 89 229 206 11 127 16
+        254 111 181 21 167 69 35 196 145 178 183 3 230 247 165 148
+        171 163 166 41 164 130 109 86 72 238 147 99 239 32 246 21
+        50 208 67 51 13 202 70 225 138 143 217 91 1 54 246 198 79
+        106 149 105 49 31 46 210 1 250 210 91 125 141 149 166 135
+        114 167 244 87 221 194 162 96 31 173 115 103 199 23 118 190
+        241 36 82 160 55 148 159 90 234 47 194 238 179 39 25 59 121
+        246 174 109 255 0 40 116 120 110 193 194 99 119 97 84 199
+        217 231 101 232 129 88 15 19 77 12 127 74 223 28 124 80 182
+        50 40 176 133 70 70 70 236 125 40 181 124 40 198 106 216
+        211 226 206 89 109 155 34 93 166 136 112 118 10 12 51 23 28
+        26 222 242 16 170 190 227 251 40 168 180 18 63 170 115 121
+        30 61 233 149 159 238 69 44 213 124 179 41 200 224 209 54
+        210 55 130 49 197 27 163 25 220 166 238 105 102 167 24 91 9
+        200 239 225 63 20 222 94 35 207 189 5 169 47 244 9 255 0
+        221 61 43 70 54 233 208 175 236 235 101 33 79 228 35 103
+        244 175 52 113 171 249 177 244 197 37 178 189 151 240 22
+        235 26 231 108 64 22 250 14 212 76 115 74 236 190 76 156
+        214 148 120 148 135 25 116 137 30 154 114 195 142 115 199
+        181 103 212 2 69 22 211 42 134 41 38 15 181 97 165 135 104
+        187 109 230 137 213 70 52 183 247 83 145 247 160 73 170 154
+        103 65 124 33 150 245 186 106 18 99 120 198 121 199 106 156
+        223 50 181 177 103 80 95 24 21 0 248 17 121 29 215 79 197
+        27 206 216 7 154 178 245 45 63 242 188 72 206 83 28 87 61
+        118 206 200 63 34 5 170 47 149 155 113 35 212 123 82 11 169
+        21 163 11 24 218 71 114 106 73 171 90 72 204 237 27 21 199
+        124 122 212 102 246 53 149 138 188 133 0 61 197 37 89 217
+        29 136 53 75 171 111 21 13 192 196 108 112 91 218 137 211
+        97 109 58 34 151 18 135 183 97 186 25 129 206 207 245 126
+        212 171 82 145 33 117 180 155 5 91 129 159 74 81 38 165 119
+        166 23 181 185 13 36 64 111 140 154 120 107 68 242 77 217
+        59 186 215 99 183 178 109 201 135 81 232 121 199 215 235 84
+        183 196 238 182 55 119 18 90 219 202 225 135 145 142 107
+        221 79 213 32 192 235 24 33 241 140 3 233 239 85 212 183 17
+        202 254 44 222 116 39 42 87 230 253 106 177 77 156 83 157
+        61 31 45 237 237 239 1 102 27 100 118 207 29 137 246 21 186
+        210 206 226 234 117 88 99 32 227 102 0 229 79 210 134 131
+        114 220 179 91 169 147 235 31 106 184 62 29 116 188 215 205
+        14 160 145 168 115 141 216 236 79 184 250 85 23 138 217 40
+        183 116 197 93 13 210 179 94 74 18 230 213 114 14 72 92 240
+        106 230 233 14 149 201 182 205 143 49 182 210 72 249 254
+        245 48 233 30 132 176 210 209 47 24 174 233 57 97 252 167
+        218 167 186 85 149 188 100 34 145 133 57 28 122 212 102 220
+        186 58 97 20 182 200 190 129 210 227 194 72 103 183 201 140
+        229 192 28 17 78 83 165 195 162 4 143 96 7 111 126 245 58
+        210 108 148 90 143 40 231 191 214 137 154 200 237 77 168 54
+        171 110 34 137 185 113 123 101 115 115 210 176 184 101 150
+        223 113 81 198 106 35 212 61 46 204 146 44 118 104 3 38 204
+        227 176 247 251 213 241 45 180 101 119 0 9 35 251 41 14 173
+        104 170 73 101 10 153 224 208 119 240 50 148 89 202 157 87
+        210 48 77 60 202 214 110 145 193 229 140 1 199 222 169 174
+        161 208 175 22 242 86 75 117 218 95 31 252 215 114 106 218
+        69 181 227 52 71 111 57 46 113 223 138 169 250 227 225 231
+        131 110 90 216 198 94 224 22 231 209 126 149 162 223 45 154
+        81 168 156 164 246 105 35 152 164 140 41 67 203 122 15 160
+        172 244 205 66 77 47 82 51 89 54 17 78 55 19 203 125 233
+        247 94 105 223 178 174 22 205 16 237 44 124 64 125 90 162
+        182 234 136 155 102 138 70 62 137 31 173 94 124 90 57 84
+        156 54 116 39 195 190 179 134 247 78 137 124 92 52 99 12 24
+        250 84 190 125 74 222 228 22 13 148 35 12 7 241 125 15 210
+        185 131 65 214 164 211 239 247 12 162 231 205 138 181 180
+        30 166 140 66 173 183 114 133 221 180 251 251 212 163 217
+        104 57 61 217 45 187 183 48 52 154 150 161 34 137 37 242 67
+        26 246 81 232 61 233 182 153 49 100 85 229 112 63 90 138 45
+        212 147 203 251 79 82 37 80 183 229 102 164 26 9 252 67 120
+        146 72 85 91 145 72 227 114 59 160 237 18 88 219 116 161
+        128 194 250 98 164 218 66 175 145 152 176 31 74 141 233 144
+        188 234 35 221 177 148 246 247 169 118 137 110 210 97 23
+        142 49 73 246 131 54 146 29 92 206 230 219 109 190 115 183
+        140 251 87 51 255 0 148 20 183 13 170 120 78 170 124 221
+        249 174 164 185 130 27 123 23 50 76 82 69 143 129 239 92
+        167 241 178 239 241 93 84 144 43 29 170 196 55 214 169 141
+        83 103 14 94 136 60 113 50 75 18 174 79 229 246 52 94 226 2
+        231 223 154 250 84 199 50 150 228 142 7 218 177 118 12 221
+        171 162 18 75 71 56 79 139 25 101 81 243 99 244 172 165 198
+        194 27 185 239 143 74 24 174 210 24 112 43 207 32 216 41
+        219 179 8 181 86 62 48 237 222 143 178 93 208 45 3 170 168
+        241 215 143 90 105 166 46 97 24 246 169 72 198 115 174 16
+        41 251 208 58 145 99 167 93 28 124 176 57 31 217 76 167 70
+        35 147 64 234 8 223 179 47 121 255 0 246 207 255 0 45 82 49
+        209 133 58 116 91 236 237 155 215 195 163 214 53 35 105 60
+        208 186 71 245 59 111 247 99 251 232 167 39 120 199 189 115
+        61 187 58 49 244 62 211 27 106 40 244 11 138 206 245 131 90
+        52 110 112 15 124 250 80 182 59 150 60 230 183 93 131 52 5
+        27 128 123 98 175 195 198 206 121 123 23 111 194 141 25 19
+        165 163 146 25 150 25 163 228 146 123 213 139 166 235 6 72
+        132 55 16 182 244 227 196 61 136 170 231 225 154 76 186 12
+        22 208 179 49 99 134 250 138 156 221 168 180 182 82 216 81
+        234 125 123 87 36 175 164 117 198 187 96 58 228 214 203 59
+        186 202 20 145 242 147 193 53 1 215 181 21 183 159 204 200
+        184 60 224 240 43 87 94 245 125 134 157 20 166 73 17 216
+        118 25 230 168 174 178 235 171 237 81 90 222 215 114 199
+        158 72 239 250 86 132 91 208 207 34 142 209 51 235 190 160
+        181 86 120 81 64 43 192 57 245 168 68 189 85 123 61 177 130
+        95 57 67 149 63 78 212 133 26 107 169 12 183 147 177 200
+        245 61 205 1 113 118 200 204 145 224 15 173 118 67 29 171
+        100 178 229 182 25 125 127 150 37 188 197 251 168 238 15
+        189 39 185 59 88 239 96 227 233 90 204 153 36 243 156 250
+        214 80 71 44 242 42 170 239 102 56 81 158 230 153 164 142
+        87 119 100 211 225 206 159 38 163 172 70 24 180 11 24 192
+        157 144 149 39 254 181 215 159 13 186 114 107 91 40 63 18
+        33 155 114 143 204 72 246 156 125 126 149 76 255 0 147 198
+        143 171 90 193 29 212 150 211 92 187 159 201 137 149 118
+        238 29 192 231 57 31 95 210 186 179 67 253 204 19 79 111 28
+        23 17 128 94 51 243 21 255 0 10 231 148 172 183 14 42 205
+        194 198 51 182 56 212 246 239 76 244 141 60 52 109 25 57
+        246 62 245 140 23 182 18 93 21 158 101 66 237 144 163 184
+        167 169 60 62 42 219 197 177 155 211 111 183 189 78 154 232
+        101 145 208 77 140 91 97 53 181 215 56 86 224 19 201 175
+        182 255 0 153 207 99 244 237 88 207 34 169 11 131 222 155
+        95 72 74 219 179 99 70 54 96 118 28 10 87 127 110 100 144
+        112 118 47 115 77 147 204 156 80 119 141 180 129 42 159 15
+        233 220 208 119 240 104 57 39 178 37 117 96 85 213 147 200
+        51 198 125 105 102 187 166 69 54 157 34 149 46 249 193 30
+        255 0 74 152 93 203 101 248 35 47 136 164 33 198 65 165 111
+        61 188 182 243 165 187 70 230 70 249 143 96 43 36 238 217
+        105 100 109 81 202 255 0 26 122 94 231 240 119 19 36 177 69
+        30 60 177 32 36 177 255 0 189 115 30 160 38 130 83 13 194
+        52 108 59 6 24 56 175 208 63 136 208 223 92 105 207 21 134
+        158 207 19 103 243 21 87 43 199 98 73 239 92 75 241 71 69
+        212 236 122 138 225 174 109 229 104 249 35 198 24 32 125 72
+        227 251 234 139 100 114 69 209 22 180 152 162 121 78 1 245
+        167 218 70 173 115 107 34 186 254 98 142 224 122 138 138 6
+        100 227 248 79 106 221 5 228 177 159 47 98 49 85 171 22 46
+        145 97 69 213 51 92 95 197 248 179 182 5 249 99 61 254 245
+        105 116 222 187 111 113 98 30 50 170 84 236 7 61 207 181
+        115 221 153 241 206 226 88 47 185 244 52 108 26 166 163 165
+        220 175 225 238 11 170 182 229 0 240 77 35 196 213 179 170
+        57 18 143 103 91 244 253 212 110 23 116 170 167 102 50 125
+        13 77 116 75 168 109 109 131 33 103 25 229 147 214 185 131
+        161 190 34 36 211 8 175 36 104 229 7 140 227 7 251 234 246
+        233 77 90 222 254 213 26 9 55 2 61 235 145 220 101 208 202
+        74 107 178 77 121 113 115 170 188 145 70 36 181 135 30 99
+        47 241 253 171 159 62 46 90 90 218 245 34 77 104 193 54 183
+        0 213 253 169 91 200 150 203 113 19 96 168 36 227 218 185
+        235 226 187 51 106 194 86 112 70 227 192 239 84 199 53 100
+        178 105 82 35 18 57 99 90 7 239 43 4 155 33 91 156 123 86
+        107 203 110 174 142 36 101 166 19 130 0 200 199 21 237 170
+        121 39 154 248 155 177 230 32 214 71 129 156 142 105 210
+        179 8 245 140 248 163 138 109 163 200 162 223 130 51 138 85
+        173 224 74 87 190 61 69 29 163 254 235 244 161 40 152 57
+        183 51 103 6 131 213 8 93 58 247 60 127 71 127 249 104 238
+        62 180 22 177 183 246 101 239 127 234 239 255 0 45 20 233
+        24 85 167 73 26 216 65 158 254 18 86 70 100 50 129 159 90
+        89 104 199 240 86 236 199 63 150 63 186 178 133 100 146 225
+        112 199 147 197 69 37 101 99 145 116 137 133 143 154 42 223
+        50 31 8 149 228 138 209 167 127 87 0 247 94 9 162 157 136
+        78 14 51 222 171 242 136 228 246 39 127 8 122 155 193 211
+        165 220 219 222 54 192 218 113 254 52 71 92 124 78 134 206
+        23 182 242 187 28 252 196 228 113 244 170 88 223 220 219
+        207 44 80 206 241 239 239 180 227 38 144 234 211 205 121 49
+        73 228 101 63 206 79 45 244 169 180 145 73 78 162 107 234
+        29 90 235 92 212 101 113 39 229 150 254 34 104 102 133 173
+        146 56 230 104 163 6 61 202 249 206 107 11 155 118 183 143
+        115 52 123 72 227 117 42 184 144 147 183 57 35 142 15 24
+        167 142 136 115 114 14 212 175 140 155 18 48 170 23 212 122
+        208 18 51 72 219 155 143 181 124 141 89 188 217 237 82 45
+        15 165 239 239 228 64 35 220 172 50 60 164 211 60 180 168
+        122 182 34 182 181 150 105 22 52 83 150 56 21 119 124 40
+        232 61 22 11 120 117 14 162 91 71 193 223 137 156 141 163
+        244 168 207 76 244 169 183 63 136 212 18 225 18 57 54 168
+        100 219 185 135 63 225 91 58 183 90 125 107 82 255 0 195 61
+        62 206 225 188 133 223 130 120 244 164 82 82 209 69 162 234
+        185 248 149 211 250 36 150 134 27 173 53 90 60 43 62 205
+        196 168 237 185 135 124 122 30 226 143 31 29 52 104 209 202
+        95 254 32 5 27 100 36 236 45 159 148 10 175 236 62 14 116
+        119 78 233 49 106 29 125 173 188 6 78 209 228 140 254 148
+        143 173 126 25 244 255 0 254 31 184 234 111 135 186 191 237
+        75 11 33 253 58 212 252 240 131 193 111 211 138 203 18 248
+        105 41 203 127 11 55 77 248 167 13 230 169 52 150 247 62 32
+        50 141 165 57 219 192 206 71 176 171 175 165 122 166 5 180
+        105 218 238 57 174 14 11 190 120 198 63 135 233 92 19 209
+        178 53 191 80 219 134 145 158 37 96 36 8 112 28 122 30 61
+        49 87 123 245 75 105 182 99 207 52 183 69 118 195 26 0 16
+        169 237 74 213 104 10 171 71 82 105 125 92 178 27 168 173
+        231 133 252 12 41 37 143 45 235 68 75 172 79 115 181 162 5
+        128 229 177 233 84 103 195 200 167 142 199 241 23 49 151
+        121 21 93 163 36 242 199 230 63 165 90 218 115 72 203 28
+        109 148 86 95 48 30 130 163 46 131 68 134 62 164 146 22 88
+        78 21 152 231 46 120 197 44 126 179 134 226 226 72 124 104
+        153 146 79 13 129 39 0 251 253 170 55 212 64 44 102 54 86
+        40 36 33 28 158 7 21 76 245 62 169 115 211 218 200 159 30
+        37 165 208 49 206 224 240 62 181 88 250 152 177 62 34 245
+        140 58 102 239 2 121 12 14 222 120 80 249 147 237 244 168
+        54 141 241 163 78 211 141 197 165 197 196 110 210 203 184
+        16 199 40 158 223 78 113 222 160 191 17 53 127 196 104 134
+        75 123 167 145 74 17 20 217 230 63 175 255 0 62 245 82 116
+        190 137 169 117 70 175 107 165 233 240 120 183 183 79 225
+        199 158 199 156 150 111 160 28 213 97 20 214 197 201 168
+        218 58 99 87 248 221 161 73 107 36 48 234 16 164 172 70 232
+        230 77 202 62 162 133 213 239 186 63 173 172 13 173 252 186
+        108 175 26 9 160 13 46 213 115 245 3 147 81 85 248 123 240
+        135 79 184 58 54 177 212 210 207 171 96 36 146 110 10 187
+        253 64 250 103 181 70 126 35 124 48 190 232 99 6 191 161
+        221 181 213 145 243 70 249 7 2 179 138 55 41 69 121 116 68
+        62 34 244 106 232 154 139 73 100 209 61 179 246 17 146 66
+        253 179 80 146 152 39 131 199 28 213 195 105 171 105 157 87
+        161 143 26 59 165 188 183 127 13 178 23 185 254 44 14 194
+        162 250 143 68 106 158 61 204 107 110 234 144 30 119 14 228
+        250 214 186 216 120 166 66 226 186 146 33 181 64 42 79 57
+        166 150 183 81 221 67 28 108 18 34 131 27 135 115 75 245 13
+        58 230 209 218 57 151 105 30 148 26 50 169 243 12 143 106
+        111 201 100 165 221 14 110 45 100 30 29 202 108 93 231 201
+        176 249 179 245 169 239 195 46 190 155 65 116 134 233 140
+        202 14 56 39 138 173 172 165 241 167 102 114 65 246 205 29
+        45 139 162 248 204 228 123 82 154 13 217 214 154 111 94 193
+        127 103 35 13 219 89 59 103 214 170 30 176 184 55 250 195
+        158 200 28 241 237 81 14 158 212 46 196 42 137 52 136 163
+        140 3 222 158 137 55 121 155 204 199 185 62 181 62 153 119
+        177 106 33 86 39 146 15 247 81 80 227 28 214 137 102 84 57
+        35 143 81 91 33 60 96 250 242 42 184 246 182 77 236 45 72
+        53 242 65 229 28 154 249 12 110 20 229 189 107 50 141 142
+        244 244 97 14 171 216 100 246 245 166 26 88 99 0 35 218 130
+        215 35 41 149 62 180 126 145 34 139 101 76 115 75 35 4 237
+        124 253 43 70 167 206 153 122 63 254 179 255 0 203 71 73
+        185 87 191 122 7 80 255 0 54 94 255 0 237 223 254 90 41 42
+        48 158 198 216 61 132 13 234 34 76 10 223 4 91 101 25 226
+        129 180 188 95 192 192 168 74 159 13 123 253 40 136 174 55
+        56 243 115 92 231 71 24 168 162 77 103 194 133 29 143 173
+        23 183 3 142 104 29 53 183 69 159 173 28 161 137 32 48 31
+        122 183 250 156 242 236 132 107 158 77 85 199 161 245 165
+        154 157 228 75 20 143 224 147 38 208 160 254 180 95 83 57
+        138 255 0 123 28 143 97 222 163 23 119 6 86 113 187 3 28 3
+        64 73 118 105 188 158 75 137 188 71 96 196 142 62 149 164
+        43 30 194 155 233 90 68 247 146 69 24 134 76 56 200 101 82
+        71 247 84 150 223 225 254 169 117 125 13 172 54 206 217 30
+        128 228 208 177 150 50 61 211 246 17 93 221 197 19 50 151
+        102 24 78 228 254 149 210 29 55 105 99 164 244 220 104 153
+        154 237 211 1 35 143 5 190 134 190 116 95 193 91 125 52 67
+        53 238 212 144 12 22 9 206 126 149 105 216 232 54 58 126
+        158 27 240 202 229 60 161 207 115 250 84 178 100 101 225
+        138 145 205 127 16 35 235 141 54 194 107 169 173 82 194 202
+        102 43 28 64 121 177 238 126 181 183 252 152 180 184 110
+        186 206 59 139 153 55 120 114 255 0 23 124 138 184 254 36
+        90 166 177 166 141 46 104 35 142 4 39 108 140 60 196 227
+        176 199 115 84 102 142 215 157 3 174 165 245 152 155 98 49
+        145 210 65 182 66 185 239 131 86 197 41 73 81 57 175 22 75
+        126 54 92 222 106 189 105 168 45 206 80 193 62 200 131 127
+        20 127 74 19 225 245 222 151 210 147 38 181 113 169 69 121
+        103 125 101 56 212 44 99 102 221 6 60 168 178 103 131 158
+        249 20 247 171 250 255 0 225 55 87 218 197 168 106 38 238
+        29 67 24 153 33 139 7 31 169 239 80 253 42 199 77 234 9 221
+        244 173 34 120 116 93 223 60 242 238 146 225 135 191 176
+        197 36 63 140 227 147 155 122 59 223 245 28 95 218 44 42 62
+        68 123 167 116 185 33 117 214 20 71 109 12 210 51 36 95 197
+        180 158 0 171 51 165 244 73 181 27 215 191 191 183 154 71
+        150 61 177 2 56 219 239 254 213 35 135 77 93 99 94 75 88 99
+        72 173 161 199 135 10 231 9 138 187 122 35 69 184 136 199
+        113 225 112 23 204 91 181 105 61 158 122 116 182 109 183
+        177 142 215 72 137 99 152 44 139 202 169 238 135 220 211
+        173 10 247 84 145 37 105 49 49 72 240 127 183 230 20 195
+        195 180 216 86 107 115 34 158 225 69 108 183 146 21 220 177
+        126 90 40 200 92 115 82 158 217 76 73 209 23 188 188 186
+        187 184 17 77 43 73 110 173 231 66 57 205 36 235 93 26 222
+        248 180 239 3 92 196 188 182 206 202 49 86 11 61 188 190
+        105 20 200 254 158 80 48 43 69 253 168 184 183 219 28 107
+        27 24 246 133 127 95 236 162 131 61 28 197 173 216 222 88
+        217 13 44 226 43 73 31 242 89 255 0 139 239 65 124 52 190
+        183 232 190 169 212 34 186 137 37 188 186 211 165 252 20
+        241 182 10 183 7 106 159 114 1 171 31 226 39 74 188 150 165
+        68 82 126 72 47 156 241 159 165 66 44 180 219 125 107 79 75
+        123 168 137 187 181 36 199 112 14 10 48 237 131 86 134 153
+        9 78 169 175 217 28 191 211 109 173 111 109 205 190 165 6
+        167 45 196 98 226 89 34 13 152 157 143 40 229 191 136 122
+        213 219 240 252 182 169 240 123 92 211 245 15 204 134 221
+        191 163 153 62 94 59 129 85 78 147 168 244 85 173 233 139
+        172 44 181 29 51 80 138 76 59 194 229 163 155 253 110 121
+        201 246 169 111 88 252 86 233 143 252 53 7 76 244 23 143 35
+        72 140 37 121 34 218 50 125 205 8 97 148 95 43 61 95 231
+        255 0 59 22 124 80 140 35 180 82 80 254 51 75 234 219 152
+        244 185 25 31 199 17 162 17 228 111 191 210 174 222 139 139
+        169 109 103 71 234 59 16 208 73 134 91 132 28 99 218 162
+        191 15 58 89 110 181 4 213 181 39 113 32 199 134 93 114 142
+        255 0 82 43 162 180 147 22 161 107 2 222 219 198 147 162
+        132 64 7 148 175 189 35 200 250 103 18 132 111 179 158 126
+        54 232 182 47 178 234 216 143 12 182 230 34 169 75 216 226
+        86 62 11 7 25 238 43 184 58 167 161 44 181 120 36 73 6 204
+        140 99 195 4 19 238 42 138 248 143 240 98 250 192 126 51 78
+        18 73 30 114 219 87 3 251 40 197 162 83 195 78 202 44 103
+        52 211 78 187 145 54 164 135 122 127 47 168 167 119 125 31
+        117 14 158 39 146 60 72 6 74 169 228 212 106 230 9 109 91
+        44 172 185 28 110 20 233 139 199 137 59 211 30 223 194 6 21
+        216 9 228 123 154 117 19 21 183 101 35 181 68 58 114 224 52
+        41 184 147 232 64 247 169 58 179 120 108 164 130 77 35 236
+        22 8 208 254 98 209 16 202 21 112 8 197 15 63 136 172 6 112
+        125 43 234 35 110 238 0 255 0 173 87 23 65 24 66 236 121
+        193 197 109 144 238 21 170 15 42 121 151 28 214 213 59 184
+        170 24 79 174 144 84 145 216 246 173 250 79 238 135 218 133
+        214 206 213 17 144 115 69 105 35 49 45 99 12 223 228 160
+        245 15 243 101 239 254 217 255 0 229 163 101 24 10 191 74
+        11 81 227 77 189 255 0 219 191 252 181 140 66 237 225 152
+        136 216 103 105 143 138 42 222 57 150 117 57 39 154 107 103
+        110 162 194 219 10 63 171 171 126 167 189 98 177 159 20 10
+        230 67 56 162 65 166 16 176 15 122 57 202 178 141 172 115
+        64 88 198 124 49 205 27 28 101 92 179 114 41 211 177 27 43
+        190 181 38 61 66 76 115 159 127 74 142 91 196 102 157 87
+        146 88 212 151 174 163 111 198 6 254 126 212 171 167 182
+        166 169 24 144 2 50 57 62 156 208 151 236 120 165 106 206
+        132 248 59 209 94 38 135 22 165 116 100 87 219 133 80 70 49
+        138 180 58 43 73 68 189 154 226 52 220 241 182 23 35 56 160
+        58 34 72 173 250 58 47 54 209 225 129 24 247 207 173 79 186
+        31 77 16 218 248 219 67 25 6 226 42 13 203 224 242 236 123
+        167 216 226 13 203 26 128 188 231 57 255 0 26 95 212 86 203
+        14 38 0 224 17 188 125 42 75 20 6 20 41 26 240 252 40 164
+        186 234 187 174 24 60 133 78 89 87 218 149 187 209 148 221
+        236 138 245 22 157 60 140 183 218 74 1 34 249 247 204 160
+        162 241 142 213 79 245 47 72 111 89 117 61 99 84 182 187
+        158 103 33 174 166 206 10 255 0 42 133 245 251 213 175 213
+        218 164 50 217 172 77 44 214 192 54 8 65 153 36 250 40 165
+        235 164 216 95 233 145 223 73 17 140 91 201 143 195 177 220
+        227 244 236 198 173 6 250 55 37 118 206 124 181 232 213 212
+        181 136 196 118 238 246 80 74 54 160 1 90 97 239 159 229
+        171 3 81 179 134 222 91 125 63 77 88 108 247 70 21 97 132
+        238 43 245 53 45 120 119 180 159 135 218 145 202 124 24 230
+        10 1 96 59 138 144 116 239 76 219 104 202 250 174 165 4 101
+        194 238 201 94 91 218 157 201 213 11 26 91 162 47 209 221
+        26 52 117 23 55 18 44 146 183 32 241 146 126 181 97 105 233
+        20 118 239 243 120 107 243 2 121 52 161 18 107 251 179 117
+        35 164 17 70 249 66 107 125 213 247 138 230 59 119 1 148
+        224 149 236 106 118 51 105 187 99 27 235 207 20 237 133 85
+        51 237 90 163 140 144 27 36 55 175 214 176 176 141 3 171 57
+        220 128 242 222 212 213 32 181 101 44 179 99 53 59 41 141
+        241 20 200 230 41 119 134 56 245 197 31 105 121 29 194 42
+        177 193 3 134 254 42 198 107 120 2 16 178 100 251 210 153
+        213 161 184 13 20 228 145 243 173 50 86 9 53 123 50 234 11
+        11 107 132 41 134 60 99 35 4 255 0 125 85 157 71 210 82 232
+        87 15 123 4 237 225 49 203 32 28 15 92 241 86 153 120 245
+        40 4 33 140 12 220 54 239 152 214 173 37 225 148 75 165 223
+        70 178 197 38 80 59 12 213 185 19 139 75 225 77 117 119 76
+        218 117 23 78 199 47 225 99 146 248 121 146 242 54 243 3
+        252 172 191 245 164 29 51 210 246 205 122 209 95 27 104 110
+        162 249 76 132 248 83 143 117 43 87 61 247 76 54 135 118
+        243 89 248 81 68 91 43 159 95 113 205 124 211 116 235 59
+        199 54 23 81 195 110 249 202 133 64 54 122 231 39 248 104
+        114 98 73 236 91 209 125 35 169 105 98 107 75 29 66 7 178
+        150 60 155 57 0 59 121 244 39 154 176 161 130 56 45 161 131
+        240 242 36 164 237 44 221 179 244 168 206 172 145 216 106
+        169 111 43 77 19 68 121 184 135 229 199 250 223 79 168 169
+        93 165 218 234 150 209 172 106 222 64 48 87 215 30 166 167
+        40 219 177 137 5 164 77 225 36 102 48 236 7 36 210 254 160
+        178 221 27 70 208 171 41 249 151 210 159 105 140 205 10 22
+        12 209 109 192 217 232 126 191 90 251 119 110 165 6 236 183
+        213 187 209 72 45 183 217 69 183 75 195 125 121 61 155 100
+        5 30 184 205 115 207 198 174 155 151 68 213 222 32 25 161
+        83 228 98 7 34 186 207 88 181 139 79 234 23 149 155 247 220
+        10 163 255 0 202 41 80 99 115 120 135 178 3 252 67 6 155 28
+        147 208 117 84 202 79 164 121 159 185 198 123 26 153 3 129
+        233 81 14 155 253 250 152 252 188 224 129 233 82 233 50 23
+        235 76 227 178 79 197 31 83 243 62 113 147 239 69 69 10 17
+        207 56 237 66 70 234 20 224 115 68 71 56 0 125 120 167 197
+        209 141 160 49 250 250 86 74 25 125 43 234 28 14 56 205 101
+        147 239 84 48 155 89 82 249 46 54 159 165 109 209 219 49
+        125 171 29 96 150 206 121 226 190 232 192 180 71 21 140 53
+        145 153 136 192 29 168 109 70 54 253 151 120 205 192 54 207
+        255 0 45 18 119 46 57 244 172 117 94 116 59 175 253 179 255
+        0 202 107 24 142 89 51 27 24 6 15 238 146 183 163 13 224
+        100 103 53 170 197 15 224 160 237 251 164 175 174 140 178
+        175 110 245 199 99 146 109 59 247 127 173 22 85 73 60 208
+        90 110 68 32 159 122 34 114 206 190 203 233 142 245 117 29
+        89 39 221 16 158 179 54 177 220 6 150 54 101 29 212 54 9
+        253 107 111 65 52 119 55 208 199 14 159 167 164 123 191 120
+        209 111 147 191 189 1 214 76 222 33 221 130 113 71 252 41
+        88 255 0 104 199 36 165 130 171 100 227 214 150 79 84 58
+        126 71 78 217 170 67 162 91 71 31 38 76 42 17 235 86 191 71
+        218 226 40 183 157 227 104 3 30 245 85 116 252 107 47 224
+        147 147 26 121 176 106 212 209 200 68 130 221 153 131 103
+        118 229 237 138 136 242 236 147 52 74 210 101 92 7 94 113
+        81 206 163 180 146 65 45 212 115 0 66 224 212 170 13 172 85
+        149 148 48 60 230 163 157 92 118 146 241 130 177 200 118 96
+        251 227 63 244 167 125 0 170 250 146 107 143 26 41 174 154
+        105 32 81 183 100 67 37 142 104 141 62 226 225 44 37 156
+        192 167 127 149 93 184 194 251 154 34 85 150 107 205 145
+        176 9 27 121 178 56 175 107 55 45 34 236 114 145 219 47 4
+        142 9 164 10 179 239 79 89 193 97 27 94 77 34 162 47 152 51
+        30 13 9 170 235 147 234 243 24 80 18 177 156 130 61 69 71
+        239 239 159 88 188 88 85 21 45 226 60 5 39 154 51 80 158
+        223 65 182 73 37 184 54 225 70 230 4 14 70 59 81 76 106 190
+        198 23 55 145 91 233 127 141 105 132 48 198 48 238 199 3
+        255 0 154 174 58 155 227 6 147 167 135 139 69 183 123 233
+        84 238 241 230 249 11 85 101 241 47 174 53 30 162 190 154
+        40 100 123 125 56 54 216 237 225 111 46 51 220 253 106 53
+        162 195 249 223 155 143 15 235 70 43 147 7 137 100 15 139
+        93 115 122 210 203 111 115 4 1 223 248 98 193 3 233 91 224
+        235 142 190 159 44 117 201 23 112 254 17 66 244 246 143 9
+        132 58 170 159 165 53 93 29 113 226 5 35 43 144 0 167 81
+        127 161 185 68 15 255 0 212 47 136 86 174 118 234 178 76 23
+        130 28 113 138 249 167 124 105 234 91 59 198 143 87 180 181
+        188 182 99 229 35 190 62 148 116 154 76 126 31 238 219 44
+        57 200 168 119 85 233 118 246 170 74 40 12 79 4 246 20 90
+        111 224 27 139 46 222 152 235 237 19 169 151 109 140 198
+        218 240 156 61 180 237 134 79 246 126 181 34 212 21 229 41
+        26 161 241 147 204 8 244 250 215 29 239 158 206 100 158 41
+        36 142 88 206 229 120 216 130 167 220 123 213 223 240 171
+        175 165 212 172 19 76 214 36 205 194 174 216 238 9 229 135
+        177 164 118 129 73 244 93 58 63 80 195 169 35 105 23 135
+        108 177 46 6 238 198 129 182 183 146 199 89 146 65 27 74
+        210 38 207 15 196 194 129 244 164 122 189 171 181 132 55 80
+        183 134 20 238 18 47 175 222 138 210 117 111 218 67 240 247
+        18 5 184 78 3 10 91 12 83 110 168 207 85 150 225 110 90 222
+        68 144 6 95 202 42 60 195 234 79 173 72 186 125 111 38 252
+        53 180 146 166 118 124 222 189 251 26 213 115 190 234 201 0
+        88 214 88 142 85 241 233 68 116 235 184 34 119 145 222 69
+        109 187 113 253 244 108 220 75 31 72 181 120 160 48 25 4
+        128 12 144 43 116 176 199 248 15 13 99 98 8 230 182 105 222
+        91 96 164 129 43 97 183 30 216 199 106 209 172 188 98 216
+        198 172 195 234 180 91 36 221 58 43 158 186 142 72 46 32
+        154 67 149 13 159 189 85 31 25 237 148 233 226 85 240 156
+        21 220 168 235 184 30 61 69 91 221 94 127 21 104 95 4 140
+        121 126 149 89 245 117 172 87 90 116 126 59 200 27 105 92
+        142 64 21 37 26 118 91 134 172 230 221 62 226 221 53 16 143
+        103 28 110 78 73 133 246 47 255 0 230 164 55 238 134 37 218
+        70 61 57 165 29 89 165 92 104 218 195 188 136 230 34 124
+        178 122 99 222 178 134 224 188 74 172 114 64 239 86 82 100
+        166 188 67 34 108 46 115 69 71 38 229 238 41 100 47 199 122
+        54 221 129 166 140 184 137 45 58 24 219 252 167 62 245 183
+        156 103 210 180 68 234 171 94 150 96 20 14 106 139 34 97 0
+        213 121 25 29 141 124 210 37 111 8 166 59 26 245 243 6 77
+        163 248 123 159 122 195 70 238 212 121 196 195 144 196 247
+        21 163 84 35 246 77 208 245 17 57 63 109 180 65 27 87 60 80
+        154 145 255 0 203 111 127 246 207 254 24 173 206 38 21 233
+        188 216 219 159 254 146 127 133 110 4 9 121 25 161 108 37
+        85 177 183 95 85 140 110 250 226 136 143 243 36 7 208 26
+        228 41 30 199 214 25 240 78 71 173 109 150 64 16 143 95 65
+        239 88 90 16 109 248 227 28 86 139 146 119 231 60 142 213
+        107 124 73 201 121 16 206 172 95 26 80 23 191 175 210 166
+        191 9 186 121 141 170 220 180 51 57 39 129 129 239 222 144
+        217 105 82 234 218 199 131 179 11 184 110 53 209 157 23 211
+        214 182 122 44 81 201 48 241 182 0 61 49 74 24 251 14 122
+        66 214 229 94 48 208 133 80 63 139 189 88 90 72 96 192 54
+        56 236 105 7 78 88 164 31 52 129 163 94 88 231 204 79 181
+        74 32 134 75 123 116 196 68 156 118 110 226 145 143 46 198
+        179 58 65 18 179 74 219 207 112 59 84 115 170 46 217 180
+        249 95 121 44 62 81 237 245 251 209 183 119 81 180 108 184
+        238 42 25 212 90 162 174 228 102 93 157 155 119 96 41 152
+        42 207 186 29 184 107 71 154 87 35 185 99 238 106 35 214 90
+        132 78 5 157 187 22 99 232 41 157 222 169 44 26 83 52 101
+        76 44 48 54 118 53 26 208 109 228 190 214 33 145 162 12 12
+        152 25 246 164 47 12 111 76 155 124 53 233 149 16 45 197
+        218 110 64 114 115 235 84 239 199 221 101 78 177 123 102
+        140 26 56 188 160 102 186 123 67 179 75 123 51 101 8 13 193
+        12 127 147 235 92 107 241 198 27 139 126 176 212 98 152 146
+        230 124 159 246 105 148 28 132 134 68 242 52 200 12 48 44
+        118 198 237 149 195 183 37 15 202 62 213 165 53 63 1 131 60
+        39 195 251 84 155 168 46 180 217 180 109 62 218 212 51 92
+        54 12 161 7 205 247 165 87 82 89 54 159 36 87 22 142 140 62
+        94 59 85 34 168 156 161 110 209 97 124 56 215 45 245 8 28
+        170 12 227 145 237 86 5 215 225 226 75 113 12 108 254 77
+        217 110 56 170 35 225 13 243 91 235 38 53 243 161 111 238
+        171 123 169 245 84 91 139 104 17 137 65 24 17 253 15 181
+        116 66 105 160 113 67 109 70 91 88 173 214 118 0 239 5 72
+        81 218 169 78 186 234 56 127 27 45 154 167 136 55 144 49
+        222 173 110 160 212 29 58 101 228 42 5 202 198 66 12 122
+        123 215 62 233 243 164 250 255 0 141 116 60 92 49 242 142
+        237 247 161 55 72 220 80 93 188 222 50 8 230 132 164 141
+        199 110 5 49 209 255 0 242 221 97 24 23 216 28 40 223 199
+        127 181 107 189 186 73 119 50 219 202 189 176 224 114 121
+        166 125 93 62 159 113 248 25 172 29 213 196 65 164 200 238
+        213 12 177 114 141 153 73 69 209 212 95 8 26 223 168 186 54
+        104 166 219 35 68 72 81 246 21 27 234 77 54 125 23 88 18
+        236 216 132 242 69 51 255 0 37 139 27 166 208 175 174 74
+        150 141 66 149 95 114 123 212 179 226 94 151 227 217 181
+        196 42 36 98 114 19 249 126 149 25 174 40 188 50 46 64 61
+        45 117 107 170 89 51 69 38 14 57 7 189 109 179 111 194 245
+        10 13 196 46 60 195 211 25 168 15 76 222 92 88 234 70 5 5
+        73 60 113 145 82 150 213 51 126 143 112 34 19 99 128 135
+        119 30 249 255 0 165 104 116 52 210 79 69 167 109 119 185
+        17 22 66 87 119 13 235 138 35 83 11 140 198 229 199 166 106
+        45 162 220 120 138 36 207 25 230 164 81 75 226 40 88 227
+        223 143 74 214 115 53 228 70 181 136 157 225 117 141 64 227
+        133 53 93 235 150 179 52 130 23 132 62 14 0 95 191 173 90
+        250 196 56 152 49 219 150 249 75 118 6 161 215 246 48 139
+        215 146 105 24 130 48 71 240 211 36 55 39 209 207 127 20 33
+        179 180 212 101 79 6 102 89 24 46 201 62 82 113 220 84 6 88
+        22 44 52 44 206 159 94 226 174 175 140 58 47 137 104 38 179
+        101 148 71 150 81 184 6 83 244 205 83 54 30 42 72 232 246
+        243 3 159 48 200 110 126 244 64 246 104 220 241 131 186 137
+        182 184 64 57 110 107 102 161 110 172 9 141 65 30 254 212
+        166 104 218 35 156 253 42 148 128 210 100 129 46 99 63 197
+        95 39 148 99 200 115 72 34 149 193 201 99 138 221 248 229
+        67 207 106 87 20 128 208 222 233 129 143 30 222 190 245 142
+        151 235 247 165 175 125 226 2 84 226 143 210 100 5 194 255
+        0 53 40 7 133 191 44 80 90 144 206 153 122 114 127 171 61
+        109 150 224 46 87 219 138 26 250 101 109 34 233 189 225 112
+        126 213 168 70 221 137 52 247 111 194 91 140 28 136 249 166
+        118 114 121 192 160 116 224 166 24 71 111 203 163 173 194
+        248 234 5 98 204 146 89 170 152 115 187 239 66 223 99 5 148
+        225 63 157 62 106 105 99 25 48 42 199 183 39 190 104 203
+        189 29 230 179 1 21 83 112 249 143 111 238 172 37 48 14 133
+        210 188 109 107 241 144 164 50 46 209 151 99 130 13 116 78
+        131 56 158 218 20 150 81 189 80 13 158 131 235 85 223 195
+        94 156 59 143 226 99 12 217 225 135 21 108 90 233 166 36 79
+        10 30 0 239 88 172 152 218 198 23 133 149 225 96 185 238
+        126 148 254 207 12 187 34 137 143 243 63 165 35 182 146 88
+        80 35 67 128 79 239 15 240 253 41 148 55 50 71 3 198 155
+        223 63 59 227 185 250 86 20 246 175 9 49 238 137 75 194 7
+        14 59 26 171 122 185 101 146 252 170 221 70 138 79 57 171
+        19 90 190 184 150 223 207 136 198 60 160 85 91 173 91 79
+        121 123 35 126 42 20 85 57 229 143 253 169 39 236 52 59 21
+        95 71 52 120 85 189 141 19 24 193 61 254 181 38 232 109 62
+        56 84 95 120 139 52 177 12 70 23 208 251 210 8 45 33 102 62
+        35 69 113 183 143 43 28 138 150 244 28 129 53 1 12 177 109
+        133 56 69 30 223 90 89 71 145 87 58 90 44 222 153 135 108
+        45 112 24 137 64 59 200 35 39 138 160 63 202 143 164 236
+        110 35 77 90 16 177 220 71 31 157 207 118 63 203 255 0 95
+        210 186 59 76 240 101 45 113 224 67 10 200 219 34 218 152
+        57 168 199 95 116 226 234 154 109 212 19 66 158 32 207 206
+        14 8 193 237 93 81 141 66 145 199 109 202 217 193 218 38
+        143 125 172 92 206 182 82 120 115 194 3 167 250 199 216 81
+        186 229 182 179 114 195 76 184 142 52 153 64 252 208 57 63
+        83 79 238 108 238 58 51 172 102 142 72 93 32 119 36 100 119
+        25 197 72 174 109 109 245 43 132 213 172 128 119 83 202 159
+        81 83 166 116 173 171 43 142 148 209 167 210 53 87 186 109
+        225 20 130 8 29 254 212 255 0 168 117 88 99 189 18 151 121
+        75 184 112 15 163 10 115 169 205 104 214 160 109 219 47 168
+        3 24 168 70 191 34 35 161 50 198 74 190 79 218 171 23 76 95
+        199 68 203 87 214 37 213 236 26 53 97 28 146 199 220 255 0
+        102 42 186 135 166 111 237 101 123 191 50 170 19 133 35 150
+        251 84 183 68 104 4 177 177 98 112 6 125 170 84 82 27 248
+        197 189 188 97 156 253 56 169 202 77 176 113 118 65 83 78
+        215 58 130 206 36 216 150 214 208 121 188 131 131 250 210
+        254 157 210 219 80 215 226 210 252 97 8 241 48 197 189 106
+        194 214 117 11 77 19 76 125 54 215 30 57 82 9 28 3 79 255 0
+        201 219 162 228 212 181 51 171 222 70 35 241 27 10 204 14
+        59 131 237 70 9 216 217 101 20 182 116 135 194 61 10 223 71
+        233 107 107 59 21 100 11 15 159 61 137 250 208 157 71 12 97
+        154 215 143 1 137 222 171 83 13 26 218 43 88 139 75 108 35
+        139 110 197 57 225 143 189 38 234 185 161 181 211 101 183
+        48 140 177 224 142 226 182 98 56 211 178 137 234 75 3 103
+        126 235 13 210 69 179 144 73 173 130 222 67 20 99 241 145
+        191 102 220 13 27 168 199 28 215 18 77 53 184 93 195 130 79
+        106 16 88 52 155 213 111 32 12 167 182 227 255 0 106 132
+        186 59 155 209 97 116 84 108 85 3 72 36 56 192 34 167 80 70
+        200 128 172 81 179 175 24 61 234 176 232 167 154 223 242
+        154 101 45 191 131 159 165 88 208 95 93 44 106 165 81 128
+        31 50 250 211 199 212 228 105 169 108 211 171 31 16 177 142
+        51 27 145 202 159 74 142 94 195 25 140 200 192 22 94 114 87
+        52 250 250 105 35 117 104 83 45 234 27 185 165 119 214 183
+        19 184 62 25 85 110 227 183 52 76 85 255 0 17 132 154 166
+        147 37 186 248 46 20 21 7 110 222 125 170 129 155 79 252 60
+        230 39 32 182 79 145 107 171 122 135 68 142 75 86 221 25 92
+        100 146 59 26 162 186 143 167 38 135 88 220 138 165 119 28
+        30 107 24 133 203 14 207 44 159 150 79 240 175 99 75 110 45
+        85 216 243 83 62 164 210 229 135 108 166 18 138 125 248 34
+        163 110 129 92 228 86 17 232 71 37 152 0 226 130 158 215
+        239 82 48 136 202 124 190 180 37 197 190 92 129 142 244 105
+        152 143 205 19 33 242 127 109 63 233 213 252 149 242 146
+        217 228 214 155 139 85 10 78 40 189 15 8 59 113 154 120 166
+        96 249 147 50 29 220 26 211 168 68 19 72 186 62 190 11 147
+        246 162 174 15 230 134 247 21 167 84 255 0 50 221 55 24 107
+        119 24 162 97 14 159 36 102 218 32 205 180 248 116 198 213
+        226 87 83 188 147 154 81 107 167 220 53 140 18 7 35 242 249
+        163 44 237 37 105 17 119 28 131 147 82 28 156 233 82 143 18
+        49 232 69 79 180 187 75 121 32 92 220 73 28 184 249 68 69
+        133 65 186 106 197 231 158 36 49 201 38 61 87 210 174 190
+        145 211 94 68 137 95 195 66 171 140 177 231 245 172 97 191
+        72 233 106 109 6 103 93 195 186 142 230 167 58 110 155 149
+        2 36 4 1 146 204 199 138 15 167 44 108 128 241 124 25 230
+        127 226 240 71 203 82 107 123 49 34 172 113 248 241 71 156
+        226 65 131 88 87 42 6 22 110 1 241 219 196 92 121 84 129
+        138 211 5 149 227 238 88 149 84 19 252 93 170 65 111 103
+        146 84 149 104 151 251 65 172 166 82 241 42 66 205 41 31
+        194 220 17 253 148 44 28 209 92 245 109 181 212 113 110 220
+        74 129 192 30 181 84 206 151 127 141 151 198 194 3 192 4
+        213 229 213 154 108 146 218 14 114 49 230 95 229 174 127
+        235 72 166 211 53 41 87 12 242 147 223 39 129 83 156 188
+        139 225 142 218 26 233 208 201 11 157 171 16 82 114 78 78
+        106 95 211 141 17 148 180 69 153 211 137 31 248 84 253 106
+        187 210 229 27 98 154 234 102 10 87 29 253 106 99 211 247
+        50 71 229 137 138 237 243 73 143 226 31 90 220 138 100 73
+        45 23 31 79 177 184 177 104 84 141 225 195 120 141 198 71
+        208 83 253 66 55 75 114 242 175 137 43 240 0 25 207 21 16
+        233 137 18 107 104 217 110 11 55 0 15 166 123 84 230 250
+        120 225 136 200 204 200 137 128 8 25 197 118 65 218 60 188
+        146 119 163 156 190 49 244 36 186 173 171 92 181 143 225
+        228 44 85 153 187 143 94 42 128 158 223 90 233 105 158 56
+        219 198 133 143 215 143 181 117 247 196 9 154 123 217 165
+        105 34 104 200 206 194 249 195 127 241 84 31 89 91 238 184
+        157 99 133 30 82 55 40 29 143 214 169 197 23 199 41 112 162
+        186 185 214 103 186 102 123 219 95 57 239 33 24 3 251 42 61
+        172 120 51 36 69 109 119 3 47 206 61 78 15 21 33 184 142
+        230 221 222 9 70 84 15 54 125 169 116 176 205 24 93 141 132
+        241 6 6 59 26 159 17 249 72 198 214 241 98 108 27 117 4 224
+        149 92 211 111 252 65 168 64 98 75 43 87 17 129 229 44 56
+        199 233 205 3 107 110 99 99 52 152 50 150 56 99 237 154 123
+        211 176 77 38 160 37 101 223 31 177 237 70 43 246 110 82 10
+        232 190 141 212 53 205 71 241 87 143 28 140 88 121 125 43
+        171 254 26 232 50 233 22 137 111 248 16 144 42 133 223 142
+        9 170 163 225 212 126 10 143 13 109 192 115 128 31 230 253
+        42 249 232 235 223 11 77 134 25 36 73 90 110 236 15 57 166
+        215 194 25 174 84 55 189 178 97 21 188 74 235 225 15 54 210
+        121 53 5 235 9 86 234 105 118 131 187 119 150 33 243 84 243
+        168 21 134 153 148 145 35 216 255 0 49 238 56 170 163 172
+        110 246 221 148 183 185 203 147 193 90 134 99 163 9 14 213
+        90 57 49 224 176 111 230 87 226 144 79 4 139 52 147 43 196
+        140 253 129 124 12 209 122 205 212 6 227 198 110 1 242 103
+        63 197 239 81 141 94 238 226 25 194 40 87 70 244 127 81 244
+        174 103 45 29 138 28 145 48 233 15 198 27 192 146 18 27 119
+        163 2 63 76 85 189 164 89 221 73 26 42 185 200 28 131 85
+        191 195 29 42 75 141 146 194 172 24 159 144 255 0 15 30 149
+        113 233 150 55 16 170 135 252 206 60 210 123 85 99 234 114
+        229 146 230 1 29 155 9 135 226 87 9 252 254 162 190 157 54
+        73 150 76 206 179 156 121 119 112 64 253 42 68 34 23 10 4
+        109 226 159 76 208 151 54 110 238 87 196 43 32 237 232 7
+        222 137 62 104 132 107 26 118 99 219 226 136 152 14 121 205
+        86 125 99 167 175 237 5 105 110 23 96 62 102 65 87 101 229
+        188 101 30 59 139 121 159 159 51 70 50 13 67 181 253 46 209
+        204 177 194 198 53 217 156 74 7 6 176 201 217 68 117 172 48
+        8 222 72 228 50 38 223 33 116 108 230 160 19 129 180 62 59
+        174 113 87 71 94 233 47 38 158 234 139 184 43 97 86 169 187
+        184 158 34 241 200 48 85 138 129 236 43 2 74 221 128 250
+        103 222 176 101 39 229 25 53 159 210 179 135 230 170 115 85
+        64 52 201 22 80 150 24 56 161 172 78 217 8 0 119 166 23 142
+        190 27 113 233 75 237 10 155 130 2 253 105 224 237 24 105
+        58 110 10 223 74 18 255 0 63 178 110 193 244 129 218 143
+        149 149 99 11 142 72 160 117 31 243 85 217 61 204 78 15 218
+        131 236 193 186 90 198 116 139 76 50 159 232 201 254 21 240
+        8 214 109 220 18 57 24 165 154 124 231 246 109 170 238 218
+        22 221 20 215 212 185 118 155 195 29 189 234 35 147 62 151
+        185 63 180 227 85 109 196 243 145 232 125 170 240 233 87
+        154 98 130 117 42 224 113 159 90 231 254 159 141 77 220 110
+        210 109 243 14 213 208 95 13 174 45 209 81 90 100 44 23 203
+        187 146 127 178 177 139 91 167 68 45 106 163 233 147 24 238
+        194 164 246 194 223 193 93 177 201 193 236 190 159 122 65
+        161 25 226 95 204 138 16 51 198 79 27 105 254 159 226 186
+        121 152 39 60 39 253 105 146 178 13 219 8 84 102 112 4 112
+        237 246 207 52 108 80 71 23 155 240 209 243 245 175 145 32
+        81 150 82 62 181 181 229 80 128 114 126 212 234 128 38 234
+        59 17 121 1 113 181 118 131 149 240 176 107 157 254 36 105
+        145 172 225 132 94 57 82 119 47 168 174 150 190 241 164 6
+        72 31 195 35 212 142 106 176 235 237 5 174 124 86 101 12
+        216 221 187 24 57 164 156 20 138 96 157 62 69 19 13 184 134
+        214 71 243 120 132 102 52 147 248 105 222 141 61 221 194
+        172 215 18 131 50 12 125 90 134 154 19 103 168 120 18 237
+        96 217 0 125 104 103 241 173 101 252 106 134 27 79 111 74
+        229 105 166 119 57 114 90 45 126 140 184 86 180 102 55 40 8
+        237 205 78 191 31 60 86 95 135 107 229 220 190 111 47 36
+        241 242 213 27 163 234 202 176 41 241 140 81 191 112 123
+        211 185 186 180 219 217 198 209 221 168 144 143 56 99 206
+        43 167 30 95 140 228 201 141 223 67 62 185 190 0 22 88 89
+        78 194 89 166 24 85 62 245 68 234 173 20 200 146 120 151 15
+        39 140 216 192 249 177 223 21 100 234 93 81 167 222 233 242
+        121 135 138 27 206 9 24 97 75 172 109 244 123 201 222 118
+        186 72 146 21 59 6 6 11 55 106 235 82 137 57 41 69 21 69
+        244 107 60 211 93 169 222 178 249 75 55 4 26 2 230 55 93
+        145 140 130 91 129 142 245 120 75 240 222 29 147 220 75 118
+        30 222 100 81 28 157 134 226 70 72 166 215 191 0 76 154 124
+        23 81 107 2 210 70 149 7 157 187 131 233 218 133 196 73 100
+        226 172 231 200 35 12 21 130 144 9 218 51 234 105 173 147
+        53 180 47 106 237 55 154 81 38 213 29 143 181 92 250 183
+        193 155 93 2 226 207 241 55 27 217 230 97 184 158 15 181 0
+        157 15 107 160 194 127 107 93 71 0 157 155 135 97 207 177
+        173 113 30 18 114 86 36 232 155 166 181 212 229 142 20 15
+        143 149 27 248 143 181 95 61 33 125 178 213 99 141 94 2 163
+        115 73 32 242 131 237 84 149 189 254 147 167 202 177 171
+        167 138 174 4 135 0 227 235 82 24 186 206 56 238 36 138 210
+        113 176 227 37 143 31 165 36 164 146 26 172 183 53 139 233
+        37 145 47 13 228 65 72 33 147 61 170 172 234 89 213 239 76
+        97 195 43 49 243 10 217 127 212 139 61 152 48 202 93 149
+        124 192 17 222 162 154 181 244 173 190 4 254 177 41 201 39
+        176 251 87 62 73 166 138 98 139 176 77 70 226 105 110 227
+        128 248 50 89 41 255 0 238 31 106 9 108 115 118 169 36 98
+        88 216 249 95 209 13 31 102 134 210 220 137 35 60 142 239
+        220 83 222 137 209 164 212 174 195 188 108 235 158 0 251
+        215 53 72 232 121 20 116 139 19 225 174 154 190 12 107 17
+        119 219 130 199 244 255 0 10 182 236 213 161 183 40 171 147
+        237 81 142 150 210 174 172 237 217 18 40 227 82 0 5 187 212
+        174 22 216 118 158 113 234 59 26 234 132 93 108 243 231 92
+        172 209 53 180 127 188 240 78 87 156 30 213 161 217 164 25
+        154 48 24 118 49 242 113 76 193 89 99 56 237 67 205 20 120
+        199 202 125 13 55 16 8 111 196 76 140 161 37 39 25 203 14
+        213 1 234 117 1 164 101 229 74 96 55 189 88 23 183 19 70
+        204 138 137 142 217 62 181 21 215 72 134 54 150 70 183 84
+        245 221 158 63 186 183 18 176 119 162 142 235 107 139 179
+        101 112 48 74 131 149 250 213 55 169 21 153 101 109 195 118
+        226 49 87 143 197 11 59 89 172 228 240 238 163 86 11 193 86
+        242 213 7 168 41 183 153 227 13 189 119 119 20 133 31 26 4
+        138 53 225 183 114 56 162 35 249 141 99 16 93 166 190 134
+        10 199 218 177 51 11 207 221 183 218 128 179 230 224 227
+        154 97 117 242 31 181 45 179 202 206 87 215 189 82 14 145
+        135 197 65 136 103 142 40 13 74 48 116 219 220 28 255 0 70
+        122 48 73 249 67 52 22 160 196 88 93 242 60 240 56 20 89
+        132 246 173 33 176 131 211 242 147 181 25 98 164 202 55 122
+        241 90 172 99 38 202 223 63 232 146 141 137 10 48 53 33 195
+        237 36 17 76 55 59 140 28 241 86 191 194 221 82 71 187 85
+        134 86 137 241 229 144 138 169 145 73 66 203 220 28 154 150
+        252 57 214 154 199 83 71 134 72 163 97 235 39 106 198 58
+        223 67 121 30 205 68 246 178 34 103 201 57 60 49 250 84 166
+        202 250 59 114 171 42 153 28 140 2 7 97 80 110 157 214 5
+        238 147 18 27 150 57 60 113 156 126 149 55 208 161 152 66
+        38 143 136 200 198 120 57 63 173 89 164 186 57 199 169 35
+        72 23 119 0 142 213 189 35 81 233 199 181 13 8 118 33 179
+        192 224 209 101 148 32 227 154 6 62 50 174 119 99 129 233
+        74 122 130 205 110 173 152 236 11 246 29 233 163 72 161 114
+        71 21 131 48 145 10 178 239 83 233 237 65 179 45 20 167 88
+        244 52 211 91 27 203 104 80 178 18 119 122 231 218 171 11
+        187 123 200 110 31 78 189 93 162 67 243 123 87 79 107 176
+        53 157 147 186 43 75 17 238 139 232 125 234 136 248 146 177
+        73 114 100 84 96 155 185 13 195 126 181 25 70 203 225 156
+        147 164 35 210 116 152 166 184 16 52 171 42 149 202 236 247
+        170 207 226 54 139 175 105 90 204 242 61 196 190 11 28 198
+        83 149 219 237 83 222 151 214 197 133 218 194 100 240 225
+        249 67 96 114 61 170 196 212 52 152 117 189 17 90 56 209
+        212 12 238 35 56 21 60 77 73 157 83 132 226 185 72 228 251
+        45 112 139 146 26 86 59 20 134 4 156 22 162 52 205 98 226
+        222 203 242 166 62 57 186 18 54 227 193 3 211 237 83 78 185
+        248 112 99 190 184 149 45 13 188 32 231 116 125 152 213 121
+        169 104 183 182 101 130 238 0 252 153 238 5 116 62 206 120
+        228 82 123 39 58 151 88 245 117 197 134 159 165 75 124 86
+        218 24 205 202 70 184 218 7 177 53 60 215 254 43 117 237
+        199 75 232 182 247 182 18 89 199 225 44 214 243 173 187 21
+        184 10 123 130 51 199 189 115 249 107 184 36 221 151 221
+        141 188 156 241 237 82 109 7 226 31 89 104 177 71 109 109
+        172 94 4 130 217 160 129 50 8 138 54 238 160 17 218 154 133
+        88 87 254 139 31 226 175 196 126 181 234 43 13 48 94 88 61
+        132 70 63 26 222 88 247 33 125 191 196 51 233 144 106 29
+        212 157 103 212 58 189 165 140 186 165 244 83 35 32 88 176
+        131 32 47 114 126 181 19 213 186 147 168 117 153 33 159 81
+        212 174 238 154 217 12 80 120 178 110 240 211 249 71 211
+        147 66 44 55 19 90 71 181 75 159 155 25 236 115 90 135 73
+        46 221 140 238 53 67 251 78 238 95 20 178 77 146 50 121 205
+        104 210 245 75 139 217 34 181 134 232 137 3 16 192 3 154 47
+        67 232 251 173 64 201 227 187 71 35 225 148 14 248 207 106
+        185 62 27 244 16 178 195 61 132 105 48 148 18 242 96 22 95
+        214 132 163 171 4 230 170 162 7 208 29 47 125 30 141 53 238
+        172 242 178 203 251 188 30 64 199 253 232 177 103 28 123
+        100 241 137 149 120 84 110 199 239 83 126 177 191 182 208
+        237 37 183 143 116 44 56 85 36 55 24 244 170 238 202 83 123
+        118 94 66 67 19 148 106 228 116 203 168 73 18 94 153 233
+        253 83 95 144 76 202 76 46 112 163 31 227 87 31 73 116 153
+        210 204 49 204 170 14 1 194 210 111 135 23 11 20 34 8 35
+        145 159 56 201 3 21 104 90 90 27 93 175 36 126 35 176 206
+        242 79 31 74 233 199 7 86 206 60 143 97 118 241 133 77 187
+        118 129 233 239 91 90 53 199 28 125 171 21 155 60 50 225
+        171 238 252 119 170 217 42 53 58 136 187 51 42 250 129 65
+        234 23 94 12 69 100 143 35 221 123 138 60 149 151 229 20 27
+        169 71 219 252 62 223 90 1 35 215 115 43 40 113 32 251 55
+        124 84 47 171 100 186 49 179 184 154 201 65 231 124 91 149
+        170 85 173 98 202 233 252 103 42 224 121 152 199 145 223
+        251 170 186 248 147 214 183 90 125 177 91 107 171 105 7 250
+        223 246 53 138 68 162 190 47 107 186 95 138 214 49 248 190
+        48 28 73 25 198 223 211 181 87 209 0 214 161 139 51 100 247
+        110 244 87 94 106 67 88 234 55 186 240 194 31 92 113 154 14
+        73 213 85 87 233 82 4 244 244 124 133 130 190 211 235 68 52
+        89 229 73 52 2 183 155 121 163 109 174 50 160 131 233 88 17
+        102 171 131 149 35 233 75 163 27 110 179 76 238 20 96 210
+        213 254 179 85 198 149 14 54 149 179 26 231 142 61 41 102
+        163 41 252 21 194 142 194 39 166 50 168 48 131 244 165 151
+        202 63 5 63 251 167 162 251 17 183 102 122 48 63 179 160
+        224 254 233 43 126 71 137 143 90 203 72 79 252 174 220 129
+        222 36 197 18 45 198 75 17 81 101 227 217 227 251 146 61 77
+        15 111 122 246 87 65 149 118 227 187 30 213 235 171 133 141
+        128 57 237 90 226 219 121 34 110 71 40 7 56 28 154 186 143
+        40 137 47 99 167 126 4 117 157 174 161 167 172 63 153 44
+        136 120 24 171 231 78 212 65 81 225 218 249 118 231 115 28
+        0 107 144 190 28 89 173 188 130 77 54 89 34 32 231 105 56
+        39 237 138 178 180 238 161 234 84 87 102 17 76 136 48 6 9
+        199 215 154 14 60 65 197 51 163 45 102 103 1 100 216 170
+        121 5 78 69 99 169 220 54 192 163 201 236 199 214 170 77 11
+        171 245 39 17 71 112 168 23 28 248 35 183 223 62 181 53 209
+        175 226 185 45 33 153 131 255 0 44 188 98 164 251 19 36 117
+        72 147 192 159 42 72 164 38 120 62 244 112 27 80 5 35 111
+        160 165 118 19 120 142 1 96 223 202 1 230 152 44 168 80 110
+        202 243 142 105 211 64 173 30 154 21 153 25 100 25 82 48 69
+        84 255 0 18 122 82 19 35 155 101 32 179 100 10 183 3 46 56
+        96 104 109 66 202 27 200 240 200 140 222 153 173 40 218 27
+        28 169 232 228 91 238 152 186 91 147 43 63 135 20 71 60 142
+        255 0 74 125 211 93 69 117 98 88 93 200 22 221 92 4 207 160
+        171 91 173 250 76 108 150 72 227 80 51 187 143 106 165 250
+        146 41 68 141 111 29 187 8 213 253 185 205 113 188 124 37
+        103 124 36 178 42 147 44 121 46 108 53 205 177 220 69 249
+        108 155 65 247 250 212 119 170 190 23 217 155 104 37 134
+        225 10 63 203 143 240 164 218 37 252 214 58 188 112 204 228
+        64 202 48 79 189 89 90 93 253 188 177 237 89 214 103 253
+        214 210 123 15 113 245 170 71 43 229 103 52 177 46 52 138
+        27 93 248 99 116 151 210 44 86 251 160 69 196 44 163 211
+        220 84 30 247 64 107 107 182 140 171 56 31 46 7 173 118 133
+        237 180 90 149 144 93 194 54 141 118 57 42 57 250 138 137
+        106 125 33 167 197 120 100 88 86 104 216 96 101 107 174 50
+        199 37 105 28 235 179 155 116 14 140 186 212 193 240 55 51
+        49 206 208 188 226 167 125 55 240 195 54 203 45 210 186 72
+        143 198 70 55 15 122 186 52 46 153 179 177 138 55 182 217
+        20 217 228 99 140 83 173 90 104 225 84 141 97 141 86 49 134
+        36 96 181 53 165 234 138 37 201 144 171 110 135 210 116 79
+        10 226 121 20 205 225 229 4 124 130 107 238 173 212 150 246
+        54 203 105 24 72 156 55 151 216 241 254 53 171 169 181 136
+        109 237 36 219 112 30 68 114 145 166 114 77 87 147 73 121
+        168 91 139 182 87 46 210 121 71 176 174 73 101 116 209 214
+        176 213 51 45 96 106 26 245 227 195 122 216 99 204 45 232 5
+        54 233 30 147 152 202 177 205 147 199 3 20 227 163 244 134
+        213 30 40 228 140 164 138 70 25 187 26 185 250 111 167 99
+        183 132 60 209 70 37 3 154 92 80 79 108 76 217 56 233 25
+        116 63 79 219 217 233 161 221 79 138 125 79 165 74 23 229
+        25 227 28 115 88 194 137 12 33 19 140 119 175 179 58 38 55
+        56 31 90 233 163 142 105 182 99 58 163 46 230 96 160 118
+        165 215 146 52 67 197 102 150 48 222 168 51 69 207 44 126
+        25 60 176 250 14 212 174 246 96 84 171 178 178 5 200 32 240
+        69 103 163 40 114 26 137 15 135 230 81 199 203 187 179 80
+        83 95 73 202 136 33 56 255 0 91 154 134 235 29 68 108 99 48
+        219 9 166 0 124 199 24 63 110 106 11 172 117 110 189 53 203
+        197 225 196 233 140 169 112 114 181 135 88 210 44 46 168
+        215 33 143 79 157 228 73 85 84 16 222 249 250 87 37 124 96
+        235 11 91 205 78 75 11 75 153 21 131 19 137 70 56 171 39 86
+        212 53 237 70 57 32 188 185 82 161 14 28 13 187 87 254 188
+        213 69 213 58 29 188 241 201 42 67 113 123 118 92 225 136 0
+        99 251 107 112 79 232 106 136 45 172 37 228 105 14 112 123
+        31 122 33 161 221 231 60 55 108 125 40 217 99 104 81 97 112
+        145 183 177 239 65 22 96 73 244 237 74 218 163 27 60 53 9
+        206 43 43 104 195 112 57 172 21 183 33 251 215 212 98 157
+        142 13 32 12 175 65 7 145 74 155 137 197 57 148 111 83 187
+        154 73 38 127 24 71 165 60 69 147 25 187 226 49 142 120 165
+        247 103 117 189 217 247 183 113 250 209 172 165 163 31 106
+        22 244 40 211 231 199 205 225 62 105 133 25 233 30 109 42
+        213 113 140 198 159 225 154 57 216 44 44 48 59 119 160 52
+        103 85 211 44 148 142 76 8 127 93 180 85 196 171 225 242 42
+        71 74 116 70 181 2 242 94 14 113 199 97 247 169 87 65 219
+        36 215 177 195 40 220 8 228 47 113 253 180 141 109 252 107
+        213 37 60 184 239 237 83 174 143 211 149 39 87 0 110 35 200
+        195 131 138 180 102 170 137 190 236 187 58 103 166 236 35
+        48 52 114 32 24 221 133 249 170 91 107 165 194 210 5 148 4
+        24 192 56 168 247 77 204 176 89 68 222 55 138 83 229 76 14
+        126 149 52 209 238 55 145 226 76 129 217 126 87 3 129 90 82
+        85 70 74 194 44 116 24 227 153 78 119 103 182 208 48 71 214
+        155 92 104 236 214 174 17 76 111 252 203 220 211 109 38 72
+        100 140 6 240 164 218 118 249 123 230 152 203 11 109 9 28
+        140 152 244 32 100 84 69 110 136 158 149 251 66 218 111 194
+        218 184 47 158 78 114 5 72 45 159 86 128 156 172 114 40 93
+        204 199 57 253 41 93 196 81 199 127 137 15 131 38 120 34
+        155 219 106 64 58 195 28 121 80 57 111 115 72 60 23 137 178
+        29 74 89 38 86 154 45 171 252 195 176 251 209 173 121 8 5
+        150 64 9 249 72 245 173 55 48 174 4 182 234 178 49 30 104
+        207 111 191 222 180 189 188 19 219 238 145 124 39 95 238
+        166 78 76 87 75 160 203 219 113 121 98 20 190 254 57 35 214
+        161 183 93 11 13 220 146 220 54 84 224 236 80 7 38 165 58
+        35 53 189 185 93 199 104 244 166 73 134 1 135 108 230 179
+        175 160 230 215 69 41 170 244 5 221 179 37 204 176 248 171
+        17 59 84 14 231 235 81 248 244 109 67 78 159 196 11 34 144
+        251 184 245 174 141 101 220 140 49 201 239 154 73 168 104
+        208 238 105 240 173 207 153 113 72 240 193 236 172 103 162
+        162 147 168 46 237 252 56 132 78 217 143 156 131 205 101
+        107 212 23 37 89 165 134 70 77 222 78 15 53 53 189 211 108
+        154 225 166 107 120 194 42 144 191 65 65 219 221 104 214 54
+        107 248 235 88 252 36 82 219 206 125 234 111 148 53 101 249
+        127 194 40 122 138 227 204 86 41 3 231 142 15 106 211 125
+        123 169 234 176 162 109 146 54 3 146 163 189 74 236 166 211
+        53 75 176 109 97 70 129 135 151 138 145 105 90 109 177 111
+        195 248 9 145 242 253 41 146 151 105 153 78 190 21 78 149
+        210 55 151 72 200 33 98 31 141 199 146 15 189 75 116 79 135
+        114 8 209 111 35 196 123 118 140 119 31 90 179 52 205 54 27
+        24 246 140 125 168 227 207 113 84 73 62 200 203 249 18 122
+        100 95 167 186 102 29 46 97 225 64 133 23 213 187 231 222
+        164 83 203 28 108 25 164 31 111 122 251 43 108 224 71 147
+        239 154 80 109 218 109 77 228 152 17 30 121 25 239 77 72
+        156 83 126 193 247 23 107 26 144 60 205 232 40 24 111 174
+        166 111 14 8 145 142 78 75 103 138 222 87 50 5 130 208 2 59
+        190 79 21 153 11 103 110 207 18 6 62 173 236 105 28 218 10
+        236 85 123 38 178 45 252 88 165 81 144 67 32 30 148 134 222
+        198 235 80 184 114 210 22 10 249 108 30 62 195 233 79 46 46
+        86 123 98 100 102 137 7 30 94 228 214 26 28 69 220 52 56 95
+        109 180 109 181 108 51 175 245 23 221 104 208 203 25 13 31
+        229 129 194 251 210 27 221 6 56 84 182 239 46 120 12 163 2
+        172 115 20 110 160 110 19 183 169 110 21 62 216 168 230 179
+        52 101 156 43 64 138 157 234 170 104 69 127 74 251 80 209
+        225 184 180 144 51 194 168 14 15 166 106 191 234 221 39 75
+        179 211 165 184 146 21 154 112 126 84 98 23 245 171 39 87
+        185 202 186 49 71 82 114 25 71 106 174 122 230 37 156 40 50
+        77 55 180 64 0 15 246 86 228 53 20 87 81 74 130 251 153 35
+        67 39 101 143 36 99 238 104 9 50 234 54 142 213 35 235 13
+        19 195 45 36 96 65 27 252 170 57 231 245 168 229 186 201 20
+        4 73 195 103 24 247 20 128 122 116 122 47 148 253 235 9 178
+        172 72 247 172 226 32 3 159 122 215 63 53 128 213 133 195
+        34 136 200 60 253 233 61 209 254 151 156 12 102 155 69 26
+        176 198 222 244 166 249 130 92 5 250 211 196 70 168 105 11
+        47 131 230 224 80 87 255 0 212 238 63 221 191 248 86 208
+        219 160 3 210 133 190 99 248 41 249 255 0 210 122 167 17 92
+        141 118 127 137 253 159 1 207 30 18 86 196 51 186 156 182
+        87 212 211 13 50 12 216 64 27 31 186 76 140 246 162 217 225
+        136 120 123 80 41 224 115 206 106 40 232 98 43 123 241 111
+        55 242 128 113 147 235 86 7 70 235 76 246 230 31 197 68 140
+        195 200 164 237 96 62 135 214 163 182 90 28 218 158 99 130
+        221 164 59 178 0 198 15 235 239 83 110 151 232 9 102 141 45
+        238 237 102 138 39 28 156 252 191 98 41 210 160 39 68 255 0
+        165 250 138 212 58 193 170 73 178 233 134 228 73 134 1 30
+        245 97 104 186 198 154 206 169 103 118 214 236 71 158 25
+        198 232 228 63 70 244 168 62 133 208 169 21 164 118 179 70
+        211 148 27 99 71 200 199 234 65 53 34 178 233 77 74 194 47
+        232 114 58 143 68 151 133 31 99 89 171 11 157 178 203 176
+        99 185 30 56 210 54 198 74 171 102 50 61 193 247 166 203
+        120 56 63 32 61 188 78 23 244 53 94 105 26 213 214 151 34
+        65 172 88 220 66 190 147 198 165 215 63 92 122 84 202 206
+        234 75 168 188 68 219 34 158 79 151 1 190 191 74 70 19 118
+        187 11 222 67 44 177 177 18 6 220 184 239 75 186 90 250 71
+        102 183 153 124 225 176 64 244 250 211 153 97 142 226 50
+        193 164 82 7 96 188 138 91 106 39 134 247 250 138 202 231
+        141 231 130 71 181 35 84 131 21 240 154 167 49 34 238 13
+        199 24 160 103 45 29 214 214 82 84 247 241 56 81 69 217 110
+        49 40 48 52 89 28 140 19 254 21 246 250 214 73 151 104 141
+        217 125 8 28 212 219 108 77 38 107 71 120 216 109 66 69 16
+        38 82 128 134 28 156 80 86 73 58 66 99 117 124 158 57 70
+        255 0 181 100 201 60 78 89 81 153 49 200 8 114 63 186 130
+        116 48 99 44 138 63 45 178 123 226 132 186 185 120 226 220
+        97 102 63 196 69 97 52 178 170 171 68 178 242 57 204 109
+        255 0 106 85 169 92 92 179 21 69 112 185 231 32 138 22 195
+        24 41 50 63 213 151 154 140 182 87 118 246 208 73 27 225
+        138 101 126 149 203 122 183 93 117 30 165 38 161 167 94 204
+        208 248 19 164 109 30 48 78 61 8 174 179 185 188 189 92 25
+        97 105 87 248 252 157 197 85 223 17 250 3 72 234 125 66 13
+        98 214 217 180 157 71 112 23 37 99 32 78 61 73 24 239 79 39
+        25 157 120 230 177 233 171 1 248 55 105 213 17 233 144 222
+        220 248 50 217 52 132 194 7 204 23 255 0 154 187 244 141 66
+        229 131 52 208 177 193 218 131 28 154 143 104 115 197 97
+        103 13 142 159 96 237 28 40 168 143 225 156 240 63 252 52
+        217 46 47 152 134 48 50 182 253 196 178 145 71 81 68 114 91
+        118 137 97 184 157 190 85 49 159 102 172 252 67 180 110 96
+        88 154 77 109 119 50 219 170 24 228 45 252 71 109 24 101
+        102 64 162 57 11 247 225 73 197 73 79 147 209 37 141 160
+        167 186 40 14 197 220 115 130 7 165 7 113 54 223 48 243 159
+        85 126 194 182 71 11 42 110 109 229 255 0 216 108 127 133
+        105 72 101 150 243 196 145 88 133 236 2 54 15 247 83 59 176
+        85 5 105 241 55 134 93 243 188 118 52 46 171 34 67 3 185
+        145 93 199 101 3 36 83 68 142 84 92 172 100 125 233 38 189
+        36 203 4 135 240 108 231 30 163 138 165 94 128 145 12 135
+        241 90 158 160 99 86 111 12 54 91 105 201 21 39 134 85 183
+        137 98 82 177 198 6 60 79 251 82 189 46 217 152 134 104 12
+        1 142 78 208 114 104 235 213 217 228 142 57 60 188 6 101
+        237 246 166 173 81 154 62 94 77 44 150 225 83 42 23 213 199
+        155 244 21 29 213 174 34 181 133 247 220 69 1 3 45 52 190
+        103 31 65 255 0 106 47 91 215 45 44 81 252 95 21 220 29 171
+        26 33 44 199 219 21 16 190 126 161 214 8 240 109 13 165 190
+        237 202 146 99 113 250 241 154 41 1 161 62 179 175 104 240
+        69 36 239 49 42 23 205 52 173 134 99 238 61 170 187 215 53
+        233 37 34 230 214 241 150 215 186 60 131 195 76 125 9 239
+        86 14 163 209 114 73 40 146 238 54 109 195 45 189 72 254
+        193 138 135 117 47 195 150 190 148 93 78 178 76 35 253 216
+        201 217 143 246 79 21 130 138 135 172 58 169 217 198 39 142
+        64 252 43 3 197 34 211 238 191 16 134 70 238 220 131 232 69
+        75 117 206 133 188 138 228 205 37 140 174 15 206 242 112
+        168 61 197 71 36 129 44 93 193 85 69 221 181 85 152 3 143
+        240 166 143 96 146 189 131 187 237 63 74 196 29 195 53 186
+        102 73 6 236 167 232 192 255 0 133 106 85 227 140 99 239 79
+        45 128 38 30 212 162 251 139 174 120 230 156 64 8 250 15
+        189 1 168 70 11 124 188 147 223 35 20 189 9 35 116 37 90
+        223 5 128 29 243 65 234 18 255 0 67 184 255 0 116 244 90 41
+        16 1 142 195 222 151 106 24 252 61 194 110 27 188 54 227 61
+        179 78 165 162 110 34 139 47 220 55 251 165 160 238 251 175
+        251 85 234 245 73 118 116 190 131 109 63 174 219 83 53 253
+        234 126 181 234 245 80 80 139 143 222 15 189 122 95 221 143
+        189 122 189 88 198 235 207 234 95 253 163 252 107 86 155
+        251 179 246 175 87 169 31 209 144 77 191 121 255 0 217 173
+        49 127 90 95 246 133 122 189 74 198 143 99 214 236 104 22
+        253 243 125 235 213 234 148 69 126 198 211 251 197 175 79
+        251 179 94 175 80 8 60 191 187 95 181 100 191 184 74 245
+        122 153 244 62 46 204 26 180 183 239 79 218 189 94 166 47
+        30 205 144 126 248 81 147 250 215 171 213 136 100 236 244
+        63 45 125 184 253 239 255 0 109 122 189 80 143 177 51 91
+        252 181 157 167 205 94 175 85 95 208 154 161 175 147 126
+        234 111 246 63 235 94 175 83 46 204 129 173 191 131 237 91
+        117 15 221 138 245 122 156 192 58 215 249 246 111 247 149
+        242 127 221 39 251 85 234 245 17 88 116 223 212 135 218 148
+        220 254 224 87 171 212 16 77 109 253 105 105 76 159 214 222
+        189 94 162 140 205 87 255 0 50 255 0 179 88 71 242 10 245
+        122 156 64 133 253 217 161 174 254 85 255 0 106 189 94 165
+        125 139 35 47 253 58 105 99 253 68 255 0 186 175 87 168 174
+        133 63 255 217 13 10 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 49 49 51 55
+        53 50 50 53 48 51 49 52 52 49 50 56 50 51 50 55 49 54 53 51
+        49 55 50 57 13 10 67 111 110 116 101 110 116 45 68 105 115
+        112 111 115 105 116 105 111 110 58 32 102 111 114 109 45
+        100 97 116 97 59 32 110 97 109 101 61 34 102 105 108 101 50
+        34 59 32 102 105 108 101 110 97 109 101 61 34 116 101 115
+        116 46 116 120 116 34 13 10 67 111 110 116 101 110 116 45
+        84 121 112 101 58 32 116 101 120 116 47 112 108 97 105 110
+        13 10 13 10 116 101 115 116 10 13 10 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 49 49 51 55 53 50 50 53 48 51 49 52 52 49 50 56 50 51
+        50 55 49 54 53 51 49 55 50 57 13 10 67 111 110 116 101 110
+        116 45 68 105 115 112 111 115 105 116 105 111 110 58 32 102
+        111 114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102
+        105 108 101 51 34 59 32 102 105 108 101 110 97 109 101 61
+        34 34 13 10 67 111 110 116 101 110 116 45 84 121 112 101 58
+        32 97 112 112 108 105 99 97 116 105 111 110 47 111 99 116
+        101 116 45 115 116 114 101 97 109 13 10 13 10 13 10 45 45
+        45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45
+        45 45 45 45 45 45 45 49 49 51 55 53 50 50 53 48 51 49 52 52
+        49 50 56 50 51 50 55 49 54 53 51 49 55 50 57 45 45 13 10
+    } ;
 
-[ { "a" "zzb" "zzc" "zzd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 3 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file ( bytes -- seq )
+    binary <byte-reader> parse-multipart ;
 
-[ { "az" "zbzz" "czzd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 4 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file1 ( bytes -- ? )
+    test-file
+    first [ filename>> "dog.jpg" = ] [ name>> "file1" = ]
+    [ path>> md5 checksum-file B{ 172 192 179 2 18 210 155 156 115 186 169 30 147 51 91 82 } = ] tri and and ;
 
-[ { "azz" "bzzcz" "zd" f } ] [
-    [
-        "azzbzzczzdzzz" <string-reader> "zzz" <multipart-stream> 5 >>n
-        [ , ] [ ] multipart-loop-all
-    ] { } make
-] unit-test
+: test-file2 ( bytes -- ? )
+    test-file
+    second [ filename>> "test.txt" = ] [ name>> "file2" = ]
+    [ path>> ascii file-contents "test\n" = ] tri and and ;
 
+: test-file3 ( bytes -- ? )
+    test-file
+    third [ filename>> "" = ]
+    [ name>> "file3" = ]
+    [ path>> file-info size>> 0 = ] tri and and ;
 
-: dog-upload ( -- string )
-    B{
-        45 45 45 45 45 45 87 101 98 75 105 116 70 111 114 109 66
-        111 117 110 100 97 114 121 115 105 103 113 43 53 113 87 116
-        54 79 114 122 56 76 79 13 10 67 111 110 116 101 110 116 45
-        68 105 115 112 111 115 105 116 105 111 110 58 32 102 111
-        114 109 45 100 97 116 97 59 32 110 97 109 101 61 34 102 105
-        108 101 34 59 32 102 105 108 101 110 97 109 101 61 34 100
-        111 103 46 106 112 103 34 13 10 67 111 110 116 101 110 116
-        45 84 121 112 101 58 32 105 109 97 103 101 47 106 112 101
-        103 13 10 13 10 253 253 253 253 0 16 74 70 73 70 0 1 1 0 0
-        1 0 1 0 0 253 253 0 67 0 5 3 4 4 4 3 5 4 4 4 5 5 5 6 7 12 8
-        7 7 7 7 15 11 11 9 12 17 15 18 18 17 15 17 17 19 22 28 23
-        19 20 26 21 17 17 24 33 24 26 29 29 31 31 31 19 23 34 36 34
-        30 36 28 30 31 30 253 253 0 67 1 5 5 5 7 6 7 14 8 8 14 30
-        20 17 20 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
-        30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
-        30 30 30 30 30 30 30 30 30 30 30 30 30 253 253 0 17 8 1 49
-        1 64 3 1 34 0 2 17 1 3 17 1 253 253 0 29 0 0 2 2 3 1 1 1 0
-        0 0 0 0 0 0 0 0 4 5 6 7 2 3 8 0 1 9 253 253 0 74 16 0 2 1 3
-        3 2 4 4 3 4 5 10 5 3 5 1 1 2 3 0 4 17 5 18 33 6 49 19 34 65
-        81 7 50 97 113 20 35 253 21 51 66 82 36 52 253 253 253 8 53
-        83 98 114 115 253 253 253 253 22 37 67 116 253 99 253 253
-        23 68 84 100 253 253 253 253 0 25 1 0 3 1 1 1 0 0 0 0 0 0 0
-        0 0 0 0 1 2 3 0 4 5 253 253 0 39 17 0 2 2 2 2 3 0 2 1 5 1 0
-        0 0 0 0 0 1 2 17 3 33 18 49 34 50 65 19 81 4 5 20 35 66 97
-        82 253 253 0 12 3 1 0 2 17 3 17 0 63 0 253 253 253 253 253
-        253 253 253 253 68 253 253 112 60 21 45 253 91 253 57 253
-        253 253 75 56 95 111 253 253 51 253 253 11 253 253 14 118
-        253 22 253 253 104 253 118 82 46 253 45 253 98 79 253 102
-        253 38 253 98 253 64 253 253 72 253 49 46 104 11 8 253 111
-        253 253 253 253 70 253 12 253 112 61 253 57 36 253 31 82 7
-        253 253 78 253 253 253 253 0 253 41 100 253 76 15 253 253
-        118 60 31 253 85 253 126 253 253 253 253 253 253 113 253 66
-        253 253 253 82 74 49 45 253 253 42 49 253 253 253 108 253
-        99 21 68 253 88 116 253 83 17 253 253 253 253 109 253 253
-        253 6 253 83 253 109 1 253 115 253 10 253 90 106 23 106 253
-        95 59 73 253 253 77 44 111 89 79 253 24 253 253 253 253 86
-        253 253 71 253 20 52 253 253 253 24 253 253 253 253 61 253
-        66 253 65 253 253 253 64 253 5 253 127 253 45 3 99 42 253
-        42 253 253 79 253 83 253 38 86 92 21 57 20 76 253 253 78
-        253 98 88 31 253 253 125 253 253 45 108 253 253 97 253 0
-        253 44 253 0 253 45 22 253 253 253 253 99 88 74 98 77 99 78
-        253 69 111 14 253 253 23 28 253 48 15 253 253 30 253 21 253
-        105 8 253 253 103 253 253 253 253 121 253 127 253 87 253
-        253 253 253 31 253 253 253 253 253 28 88 253 253 120 99 253
-        52 100 253 0 253 253 253 253 108 109 11 103 253 253 127 253
-        253 118 82 71 253 47 253 253 253 11 253 30 74 81 253 102
-        253 253 35 253 97 104 62 253 46 104 41 45 109 119 127 86
-        253 253 21 48 253 253 9 253 104 105 253 24 118 53 76 77 81
-        253 73 105 109 253 253 253 127 253 21 253 89 253 110 63 253
-        97 253 0 253 69 65 253 110 15 39 253 253 253 253 253 41 6
-        253 102 5 22 54 253 114 109 45 253 123 24 253 53 253 45 44
-        253 253 79 253 253 253 253 253 118 101 112 253 253 253 102
-        253 253 253 35 253 99 95 253 253 119 253 253 253 253 253 21
-        18 253 125 253 92 253 2 253 253 16 253 15 253 253 253 71 46
-        253 253 106 253 78 253 40 253 253 109 83 33 45 253 253 253
-        253 253 253 253 253 30 253 253 69 45 37 253 253 253 253 12
-        253 253 253 253 253 253 253 8 75 123 253 15 69 96 7 253 253
-        253 253 253 31 253 253 253 253 253 102 120 253 0 68 253 253
-        253 253 12 15 253 253 253 253 253 253 253 253 253 253 253
-        253 7 253 123 80 253 253 253 118 253 66 253 253 118 62 253
-        253 253 38 91 55 253 253 253 253 60 253 22 96 14 253 253
-        107 84 253 69 253 253 253 253 100 253 0 65 18 253 43 253 82
-        105 253 253 108 64 253 31 102 253 253 253 253 253 253 253
-        39 253 73 38 50 84 253 253 112 253 19 253 4 118 54 253 253
-        22 33 68 54 253 253 52 96 253 253 253 15 115 16 253 66 253
-        253 77 253 253 40 115 253 90 253 91 73 253 116 253 29 253
-        77 253 253 253 253 46 64 109 253 88 45 253 31 253 253 92
-        127 253 253 19 97 99 253 16 253 125 253 253 63 253 20 100
-        253 56 253 253 253 66 84 253 253 253 253 253 253 253 125 18
-        253 125 253 253 108 72 7 253 125 253 63 253 45 109 253 77
-        253 253 253 111 253 253 0 253 253 68 76 253 253 253 51 253
-        103 43 0 253 253 253 253 72 253 253 54 113 253 5 91 120 50
-        59 253 77 7 120 109 253 48 22 8 1 253 253 98 253 106 253
-        253 253 45 253 253 253 93 41 97 253 253 73 97 253 96 19 253
-        103 253 253 23 253 253 253 71 253 93 253 253 110 117 101 67
-        90 253 253 253 55 253 97 253 253 37 122 124 253 253 48 118
-        253 253 81 66 116 253 82 123 2 253 103 108 55 30 99 31 253
-        253 253 253 63 56 253 253 253 253 26 90 253 253 56 20 109
-        253 253 89 16 253 253 80 253 253 80 49 253 110 253 63 253
-        253 253 107 74 62 44 253 36 253 253 17 253 253 253 253 26
-        253 253 253 253 21 40 253 113 253 253 253 253 253 53 253
-        253 63 253 57 253 253 85 55 253 34 5 87 126 124 253 123 26
-        253 15 253 253 42 253 59 108 123 112 51 27 14 253 90 253 61
-        68 253 253 253 253 58 35 7 253 253 57 253 253 253 91 25 82
-        71 24 253 0 253 44 253 253 21 253 99 16 253 120 253 253 253
-        97 253 253 99 81 253 5 253 74 253 253 29 253 253 253 99 121
-        253 253 80 127 253 253 253 22 253 96 121 19 84 253 253 253
-        253 77 106 61 62 253 25 35 114 253 253 1 253 43 253 253 253
-        72 71 24 56 253 125 107 253 253 253 253 253 253 93 61 253
-        35 76 253 42 43 253 253 253 253 253 58 123 85 253 9 37 67
-        103 63 74 117 39 123 37 253 26 110 253 20 14 64 53 253 253
-        253 253 22 253 21 253 253 111 83 69 22 80 72 253 89 253 103
-        61 253 253 117 60 253 121 15 253 253 253 253 8 23 253 253
-        253 253 253 253 36 253 11 253 253 28 85 123 253 253 93 64
-        253 57 52 99 32 253 45 89 253 15 253 253 253 46 253 253 60
-        253 253 48 43 69 253 253 24 253 109 253 61 253 21 57 118 96
-        253 57 92 253 52 43 253 253 253 126 253 68 18 3 88 253 253
-        253 253 108 253 253 8 107 64 62 65 253 253 253 253 91 25
-        253 253 39 38 253 253 99 253 122 253 112 253 118 59 253 83
-        253 114 54 59 46 253 253 89 39 253 90 93 89 88 115 253 110
-        64 74 113 83 253 253 5 59 62 253 35 253 253 16 253 253 124
-        109 253 123 253 253 19 13 253 35 38 253 253 69 62 253 105
-        253 253 0 253 253 85 253 253 82 253 253 253 60 103 253 77
-        253 253 253 66 253 98 253 253 82 253 73 24 253 45 34 81 253
-        253 75 44 253 253 7 114 72 110 253 253 36 73 12 42 253 253
-        253 253 73 52 253 253 253 253 253 253 253 253 113 253 253
-        49 253 90 253 124 40 253 122 110 253 253 253 65 66 12 48
-        253 253 253 94 54 253 61 253 253 94 28 123 10 253 10 78 59
-        253 253 109 253 58 253 8 253 253 253 253 19 73 53 253 86 80
-        253 253 253 1 253 107 253 253 77 101 105 103 51 253 253 36
-        253 24 25 39 253 0 253 93 18 253 253 18 253 253 253 30 253
-        253 85 253 253 109 39 253 253 253 253 110 8 253 253 253 253
-        253 253 253 14 253 253 27 66 253 60 46 54 110 5 72 31 253
-        82 253 57 253 72 253 253 253 64 253 70 127 253 13 253 253
-        107 253 253 253 5 253 91 253 253 253 58 75 253 253 48 72 36
-        47 117 253 71 39 113 4 23 253 253 253 253 96 100 114 107 24
-        253 253 126 62 253 253 101 57 253 253 89 70 6 7 2 253 253
-        35 253 71 102 253 84 40 253 253 110 57 38 253 253 3 253 86
-        19 1 253 253 253 253 253 34 253 253 253 253 100 253 253 253
-        52 121 77 253 253 253 67 117 253 253 253 253 253 17 253 81
-        253 253 116 52 72 253 253 253 253 21 253 253 126 30 79 76
-        46 253 62 253 16 27 253 7 34 55 253 55 63 253 116 253 253
-        118 253 117 253 253 127 253 253 253 253 15 13 127 253 253
-        16 10 253 253 253 69 43 253 253 253 88 23 253 71 70 32 110
-        253 253 253 253 25 99 99 253 78 127 253 253 253 253 253 253
-        253 253 86 35 253 253 42 253 253 253 253 50 65 253 253 53 9
-        89 253 253 253 253 253 253 253 253 54 61 100 68 118 253 86
-        253 89 253 253 121 253 72 1 2 253 253 253 253 253 253 70
-        253 253 28 253 253 253 253 253 253 92 253 253 253 87 23 253
-        92 253 253 253 253 253 121 253 253 107 253 253 103 253 253
-        35 253 253 253 253 84 6 99 253 85 36 253 34 253 98 253 34
-        100 89 89 253 43 6 97 253 35 253 253 95 94 86 17 2 253 56
-        253 105 119 253 253 253 253 253 39 253 253 27 253 16 95 113
-        79 95 253 16 253 30 253 253 253 11 253 60 253 59 253 75 253
-        103 77 91 253 58 101 253 253 253 253 253 253 253 253 78 97
-        253 253 253 253 253 10 31 65 253 253 253 100 253 21 253 253
-        253 29 253 5 87 253 253 110 253 109 31 80 253 36 111 32 39
-        57 253 57 253 77 253 253 92 69 253 253 49 253 126 253 105
-        124 86 253 27 125 70 22 253 253 253 9 2 253 253 253 53 76
-        66 38 253 253 65 109 48 111 8 253 18 123 81 253 20 253 253
-        101 253 253 253 253 94 253 14 253 105 27 253 106 253 253 20
-        11 253 125 51 253 253 253 70 253 253 104 253 87 28 85 117
-        117 253 117 253 253 253 84 87 253 253 26 253 108 253 5 3
-        253 77 253 78 253 74 253 253 253 7 253 115 18 253 253 253
-        253 33 27 48 253 64 24 26 253 126 13 108 253 253 253 253 9
-        253 79 106 26 92 253 253 253 253 253 93 253 124 253 48 107
-        34 253 39 253 253 253 0 253 122 253 253 253 253 253 65 253
-        253 27 253 24 253 101 253 40 253 253 253 49 253 90 109 85
-        29 124 253 253 253 253 19 28 98 253 123 253 253 64 46 253
-        13 122 22 253 39 28 253 253 86 253 253 4 19 90 1 253 253 50
-        28 253 253 52 91 253 253 55 253 62 253 56 91 68 253 88 110
-        253 30 253 37 253 49 253 253 106 58 253 51 73 253 253 119
-        19 253 253 253 253 61 253 253 253 12 253 253 79 253 57 32
-        253 253 51 253 253 90 253 65 253 253 253 8 253 0 51 104 46
-        125 106 115 253 78 253 124 17 113 253 253 37 26 85 253 122
-        109 253 113 68 253 96 49 253 253 125 253 253 85 59 90 64
-        119 124 253 253 253 43 5 43 253 31 79 253 10 253 36 44 26
-        70 253 253 253 30 253 253 253 253 253 253 253 10 253 98 253
-        253 253 253 253 253 253 28 253 253 88 122 253 253 253 253
-        253 52 253 253 88 98 253 253 253 253 36 46 112 15 53 253 56
-        253 253 65 253 0 253 77 253 253 69 253 118 253 253 253 54
-        118 253 253 253 116 73 72 253 253 253 253 253 253 253 31
-        253 22 18 253 26 36 253 2 72 21 60 253 64 253 253 253 106
-        253 253 67 38 253 37 36 253 253 51 90 91 253 253 104 253 13
-        18 253 253 253 253 127 46 43 5 253 253 253 253 55 127 253
-        253 253 43 85 253 100 253 253 253 94 71 20 253 253 103 23
-        43 253 125 253 84 253 253 253 253 253 253 43 100 253 40 253
-        9 22 253 253 45 253 253 253 253 253 253 40 93 79 253 67 62
-        253 253 22 253 253 1 253 96 53 98 253 253 12 253 253 253
-        253 3 253 102 81 253 71 82 41 99 12 59 253 74 117 91 114 45
-        253 117 31 253 103 253 253 253 253 253 45 55 44 17 99 253
-        29 23 12 253 28 6 3 20 20 19 127 71 253 253 253 42 253 28
-        253 253 7 253 253 103 253 253 0 253 253 253 253 120 253 3
-        12 12 253 69 111 253 253 253 253 66 253 36 253 90 253 253
-        253 253 253 253 74 253 89 253 67 123 11 6 57 253 21 63 253
-        253 253 68 253 253 110 253 102 253 253 253 253 253 253 60
-        253 253 253 253 253 253 253 253 253 253 253 15 25 253 253
-        253 39 253 43 63 15 79 19 76 7 253 253 253 253 253 30 253
-        50 253 43 42 253 48 253 253 253 253 253 55 253 71 253 253
-        97 253 253 28 99 253 253 69 117 30 253 31 105 30 253 253 46
-        253 253 75 253 253 253 253 253 253 60 253 70 253 253 80 253
-        253 75 253 34 253 101 253 54 253 25 102 253 55 70 35 3 253
-        118 253 108 39 87 253 66 253 108 61 253 253 253 253 253 119
-        82 49 253 253 253 123 10 253 253 82 89 36 88 253 253 38 253
-        121 37 76 253 253 253 123 36 253 253 253 253 253 20 253 60
-        61 253 253 72 253 253 127 253 23 70 253 253 253 253 253 253
-        107 103 253 253 253 253 70 86 253 66 28 253 3 253 26 58 253
-        253 43 253 66 92 66 253 79 253 115 253 108 56 253 253 105
-        253 115 105 60 253 253 253 23 80 253 253 71 5 253 122 253
-        253 253 253 29 253 42 253 22 253 253 253 253 253 253 253
-        253 70 253 45 21 81 253 253 253 10 253 253 253 71 253 253
-        77 253 49 8 253 84 253 253 35 253 93 112 253 253 253 253 60
-        93 253 116 37 253 39 10 0 126 41 253 119 81 1 253 253 22
-        120 253 35 92 253 253 253 253 253 253 33 253 253 65 87 253
-        253 13 50 87 253 253 253 253 126 253 253 253 253 253 253 10
-        253 46 253 253 115 253 72 253 253 253 41 253 253 253 67 253
-        9 51 12 253 253 114 253 82 120 106 56 113 80 253 253 72 88
-        5 76 31 253 20 253 253 253 253 253 253 253 50 102 37 118
-        253 253 253 253 253 253 253 18 71 253 253 253 253 84 119
-        253 1 73 253 49 253 253 253 253 110 253 253 106 253 253 104
-        253 74 29 253 253 253 253 29 253 89 253 58 77 253 253 253
-        253 20 112 253 253 125 253 6 253 253 253 75 253 253 65 36
-        113 253 253 9 0 253 253 15 253 253 19 79 253 253 79 42 25
-        253 253 253 31 74 76 253 253 71 84 49 253 253 253 253 68
-        253 253 253 253 253 6 253 56 86 28 253 253 45 253 253 253
-        253 66 253 30 61 253 253 253 253 253 253 26 15 40 39 253
-        253 107 253 22 253 253 46 37 36 124 253 127 253 253 83 91
-        118 86 253 253 253 14 253 253 253 103 253 253 253 253 253
-        253 253 48 86 39 253 253 253 253 253 253 253 56 17 91 253
-        253 81 253 17 88 53 253 253 253 28 114 56 92 122 253 253 27
-        253 253 253 253 24 253 253 253 43 85 253 50 253 14 15 36
-        253 87 109 34 253 27 253 121 253 54 108 253 253 12 118 253
-        82 253 253 253 112 253 253 253 253 253 253 77 30 118 120
-        253 253 253 253 122 253 48 107 54 253 103 253 253 253 253
-        253 253 253 253 253 253 253 253 101 109 50 82 253 253 253
-        253 253 115 71 253 11 55 253 253 253 88 253 17 253 253 1
-        253 253 253 253 57 102 253 68 107 48 54 253 27 24 253 68 15
-        114 49 253 253 253 253 19 37 253 253 38 253 253 120 10 253
-        253 86 253 253 108 253 123 9 253 253 253 253 253 253 253
-        253 59 253 253 70 49 253 73 253 253 91 80 99 253 253 62 253
-        253 253 253 111 253 75 253 24 253 253 253 253 90 109 103 31
-        253 97 253 115 84 253 28 253 40 253 253 117 253 100 12 118
-        253 253 253 253 253 92 48 253 34 39 253 253 253 253 14 24
-        253 49 64 253 253 253 78 253 87 253 253 61 43 84 253 253 94
-        55 253 253 253 253 253 61 253 253 89 101 253 16 108 61 253
-        253 253 253 253 253 11 253 253 253 253 91 253 253 253 100
-        86 32 119 253 109 80 30 253 95 79 253 253 30 253 253 253
-        253 127 18 253 0 101 110 253 23 253 43 253 253 107 253 5
-        253 253 30 119 29 253 54 44 125 253 127 253 28 119 253 73
-        72 253 253 40 253 60 31 122 253 253 253 253 38 253 253 3 32
-        253 119 253 21 253 253 253 12 253 67 115 253 84 253 91 253
-        253 97 89 64 253 32 253 84 253 253 119 67 253 253 53 253 38
-        253 30 25 253 112 253 29 69 63 48 253 73 253 65 253 83 13
-        65 48 37 1 124 253 253 253 55 61 253 40 20 109 253 253 90
-        253 253 4 253 78 253 70 24 83 253 253 80 253 253 69 16 253
-        14 14 87 253 104 11 253 104 253 90 118 5 84 253 253 125 253
-        253 126 253 253 21 253 253 69 253 4 103 13 253 253 253 253
-        253 70 55 253 38 88 253 39 253 13 253 253 34 253 33 253 253
-        253 253 253 253 253 253 121 253 85 1 97 253 112 253 90 253
-        90 253 253 253 64 27 45 253 253 127 253 253 253 253 253 98
-        253 253 253 253 77 253 253 99 70 253 253 253 99 253 253 253
-        43 123 77 62 84 37 70 88 253 53 253 253 20 122 253 253 253
-        127 253 100 102 12 71 7 253 253 253 253 80 253 253 123 253
-        93 92 253 90 92 48 253 126 11 3 85 253 253 52 253 72 253 36
-        253 253 253 125 105 253 26 253 253 253 253 253 48 75 253 26
-        50 253 31 253 253 86 253 253 253 120 114 70 67 253 253 253
-        253 123 78 253 253 253 25 60 57 29 36 94 123 112 125 253 77
-        253 116 253 253 253 253 92 70 3 69 253 253 14 72 30 253 94
-        253 253 70 42 93 253 70 127 3 111 32 5 253 28 253 30 253
-        253 13 46 253 253 24 7 253 106 253 253 253 39 253 253 25
-        253 2 253 110 1 253 253 253 45 253 253 253 22 112 6 10 253
-        253 253 253 25 79 253 83 113 90 253 43 253 253 253 253 253
-        253 253 253 253 38 69 97 253 253 90 253 253 253 91 253 253
-        85 253 18 253 103 7 253 253 253 253 253 68 74 253 253 104
-        253 253 253 253 253 51 108 73 97 253 253 2 110 35 93 253
-        253 253 253 253 253 22 253 253 75 253 79 49 253 253 253 76
-        253 253 253 253 30 253 253 253 116 253 113 19 253 19 253
-        253 87 118 253 253 66 253 253 113 253 253 0 84 123 26 253
-        253 17 253 79 253 58 87 253 47 85 90 20 253 99 120 253 253
-        48 253 7 253 253 44 253 72 110 33 115 28 253 253 253 107
-        253 253 73 253 253 13 34 253 43 253 91 253 86 86 253 103
-        253 43 253 253 21 117 253 253 253 253 253 52 253 253 253 42
-        79 57 253 101 253 253 253 89 37 47 253 253 123 62 27 253
-        253 66 253 253 253 253 87 72 253 253 253 253 31 253 253 83
-        11 125 67 253 86 98 67 253 253 92 253 119 20 253 85 253 97
-        108 253 253 253 124 118 253 253 253 7 253 53 253 253 77 253
-        253 8 253 253 106 253 5 122 9 94 253 253 34 253 253 253 119
-        94 29 253 113 253 108 89 253 253 11 127 16 253 111 253 21
-        253 69 35 253 253 253 253 3 253 253 253 253 253 253 253 41
-        253 253 109 86 72 253 253 99 253 32 253 21 50 253 67 51 13
-        253 70 253 253 253 253 91 1 54 253 253 79 106 253 105 49 31
-        46 253 1 253 253 91 125 253 253 253 253 114 253 253 87 253
-        253 253 96 31 253 115 103 253 23 118 253 253 36 82 253 55
-        253 253 90 253 47 253 253 253 39 25 59 121 253 253 109 253
-        0 40 116 120 110 253 253 99 119 97 84 253 253 253 101 253
-        253 88 15 19 77 12 127 74 253 28 124 80 253 50 40 253 253
-        70 70 70 253 125 40 253 124 40 253 106 253 253 253 253 89
-        109 253 34 93 253 253 112 118 10 12 51 23 28 26 253 253 16
-        253 253 253 253 40 253 253 18 63 253 115 121 30 61 253 253
-        253 253 69 44 253 124 253 41 253 253 253 54 253 55 253 49
-        253 27 253 25 253 253 253 105 102 253 24 91 9 253 253 253
-        63 20 253 94 35 253 253 5 253 47 253 9 253 0 253 61 43 70
-        54 253 253 253 253 253 101 33 79 253 35 103 253 253 52 113
-        253 253 253 253 253 37 253 253 253 253 22 253 26 253 108 64
-        22 253 14 253 76 115 74 253 253 76 253 253 253 120 253 253
-        25 116 253 30 253 114 253 253 115 253 253 103 253 2 69 22
-        253 42 253 41 38 15 253 97 253 253 104 253 109 253 253 253
-        70 52 253 253 83 253 253 253 73 253 253 103 65 124 33 253
-        253 253 106 18 99 120 253 121 253 106 253 253 50 253 253
-        103 80 95 24 21 0 253 17 121 29 253 79 253 27 253 253 7 253
-        253 253 45 63 253 253 72 253 83 28 87 61 118 253 253 63 34
-        5 253 47 253 253 113 35 253 123 82 11 253 21 253 11 24 253
-        71 114 106 73 253 90 72 253 253 27 21 253 124 122 253 102
-        253 53 253 253 253 253 0 61 253 37 89 253 29 253 53 75 253
-        111 21 13 253 253 108 112 91 253 253 253 97 109 58 34 253
-        18 253 253 97 253 25 253 253 253 253 126 253 253 82 253 33
-        117 253 253 5 91 253 253 74 81 38 253 119 253 23 253 253 13
-        36 64 111 253 253 120 107 68 253 77 253 59 253 253 99 253
-        253 109 253 253 81 253 121 253 253 253 84 253 253 253 253
-        55 119 18 90 253 253 253 253 253 253 107 253 79 253 32 253
-        253 24 33 253 253 3 253 253 85 253 253 17 253 253 44 253
-        116 39 42 87 253 253 106 253 77 253 83 253 61 31 45 253 253
-        253 1 102 27 100 118 253 29 253 253 21 253 253 253 253 253
-        117 88 99 32 253 102 0 253 79 253 253 253 114 253 253 91
-        253 253 253 31 106 253 62 29 116 253 253 253 14 253 253 253
-        115 253 253 253 79 253 253 85 23 253 253 40 253 116 253 93
-        13 253 253 94 74 18 253 253 114 14 72 92 253 106 253 253 14
-        253 253 253 253 253 49 253 253 72 253 253 253 48 253 30 253
-        253 253 253 47 24 253 253 57 97 253 253 253 253 253 85 253
-        253 100 34 253 253 57 28 122 253 102 253 253 58 97 20 253
-        253 253 253 253 253 253 72 103 253 253 253 253 253 28 17 78
-        83 253 253 253 4 253 96 7 111 126 253 58 253 108 253 90 253
-        40 253 253 253 253 253 253 253 77 253 54 253 110 34 253 253
-        113 123 101 115 115 253 253 253 101 253 253 113 81 253 106
-        35 253 61 46 253 253 44 118 104 3 38 253 253 253 253 253
-        253 253 45 253 101 119 0 9 35 253 41 14 253 104 253 73 101
-        10 253 253 253 119 253 50 253 89 253 253 87 253 48 77 60
-        253 253 110 253 253 253 253 1 253 253 253 253 253 253 253
-        22 253 86 75 117 253 95 31 253 253 114 106 253 69 253 253
-        52 71 111 57 46 113 253 253 253 253 253 253 253 253 110 90
-        253 253 94 253 22 253 253 126 253 253 253 45 253 81 253 253
-        253 253 105 35 253 253 253 41 67 253 122 15 253 253 253 253
-        66 77 47 82 51 89 54 17 78 55 19 253 125 253 253 94 105 253
-        253 253 22 253 16 253 44 124 64 125 90 253 253 253 253 253
-        102 253 70 62 253 31 253 94 124 90 57 84 253 54 116 39 253
-        253 253 253 253 78 253 124 92 52 99 12 24 253 84 253 125 74
-        253 253 22 13 253 35 12 7 253 125 15 253 253 253 65 253 253
-        253 253 253 12 253 253 253 253 253 253 30 253 253 66 253
-        253 114 253 253 253 253 253 253 253 253 104 57 61 253 45
-        253 253 48 52 253 253 253 34 253 37 253 67 26 253 81 253 61
-        253 253 253 49 100 85 253 112 63 90 253 45 253 253 253 253
-        79 82 37 80 253 253 102 253 26 9 253 67 120 253 72 85 91
-        253 72 253 114 59 253 253 18 88 253 116 253 253 253 253 98
-        253 253 66 253 253 253 253 31 74 253 253 253 253 253 35 253
-        253 253 253 253 253 118 253 110 253 97 23 253 49 73 253 253
-        54 253 29 92 253 253 253 109 253 115 253 253 253 87 51 253
-        0 253 20 253 13 253 120 78 253 124 253 253 253 253 253 253
-        27 123 23 50 76 82 69 253 253 253 92 253 253 253 253 253 93
-        84 253 43 29 253 253 55 253 253 253 83 103 14 94 253 60 113
-        50 75 18 253 79 253 253 52 94 253 2 253 253 253 253 84 253
-        50 253 253 253 7 253 253 118 12 253 253 253 18 75 71 56 79
-        253 25 101 81 253 99 253 253 253 253 253 27 253 253 253 74
-        24 253 253 24 112 43 253 32 253 41 253 253 8 253 86 62 48
-        253 253 253 253 93 253 45 3 253 253 253 253 253 90 105 253
-        46 97 24 253 253 72 253 115 253 16 41 253 253 58 253 99 253
-        93 28 124 253 57 31 253 76 253 70 35 253 64 253 8 253 253
-        47 121 253 0 253 253 253 0 45 82 49 253 253 58 116 91 253
-        253 253 253 253 253 253 53 35 105 60 253 253 71 253 59 111
-        253 99 253 253 253 39 120 253 253 115 61 253 58 49 253 62
-        253 27 106 40 253 11 253 253 253 253 90 52 110 112 15 124
-        253 80 253 59 253 60 253 253 93 253 52 5 27 253 123 98 253
-        253 253 253 121 123 23 111 253 253 25 19 253 253 253 25 253
-        25 253 253 253 123 253 253 253 253 6 72 253 55 16 253 253
-        253 253 61 253 253 253 253 253 76 253 12 22 253 253 49 99
-        253 253 253 253 253 253 253 253 82 253 81 253 125 123 87 36
-        253 253 117 253 253 96 58 253 253 253 59 253 253 20 253 253
-        253 253 53 1 253 253 21 253 253 253 253 253 60 253 253 43
-        87 94 253 125 253 253 20 253 73 17 253 118 25 253 253 253
-        253 253 253 253 81 90 253 253 114 253 253 72 253 253 86 253
-        91 253 253 34 253 253 51 253 253 253 253 86 120 81 64 43
-        253 57 253 253 68 253 85 123 61 253 253 95 57 67 253 63 78
-        253 253 26 107 253 12 253 253 253 253 253 61 253 1 113 118
-        253 253 253 253 15 253 118 67 29 253 100 253 253 253 25 125
-        127 253 37 253 253 253 253 253 15 253 39 253 59 88 253 96
-        253 253 90 253 253 36 253 253 253 253 80 71 44 253 42 253
-        253 102 56 81 253 253 253 253 253 87 119 100 253 253 253
-        253 38 253 253 70 24 253 11 24 253 253 253 253 39 253 253
-        253 253 13 253 114 107 91 40 63 18 33 253 114 253 253 72
-        253 253 125 126 253 76 253 0 253 253 253 253 90 253 29 253
-        253 253 92 253 253 253 253 253 118 253 29 253 253 57 31 95
-        253 253 253 67 253 253 19 79 111 28 23 17 253 94 51 253 21
-        253 0 10 253 253 253 253 14 42 253 253 253 51 253 56 253
-        253 253 76 253 253 60 52 109 25 57 253 62 253 253 23 253 18
-        93 21 253 101 66 253 253 253 253 253 253 60 62 42 253 253
-        253 253 253 111 253 253 78 253 253 101 253 253 77 253 91 97
-        53 253 253 56 86 253 19 253 253 253 253 0 253 253 99 253
-        253 88 253 34 253 11 253 253 253 95 72 74 253 253 99 70 54
-        96 118 28 10 87 127 110 100 253 112 118 47 115 77 253 253
-        253 80 119 253 253 253 42 253 15 253 253 253 119 253 104 57
-        39 253 37 117 96 85 253 253 253 51 253 125 105 102 253 253
-        69 54 253 34 253 46 253 253 30 253 0 74 253 93 253 101 253
-        35 47 253 253 33 253 65 253 111 61 253 253 253 253 253 70
-        253 70 253 253 96 43 36 253 253 105 100 109 81 253 253 0 26
-        122 94 253 253 119 19 36 253 69 30 60 253 32 36 253 253 0
-        253 115 30 253 38 253 83 13 253 52 108 59 6 24 56 253 253
-        63 253 253 253 92 105 253 21 253 253 253 19 103 253 21 87
-        43 253 98 73 253 92 75 253 71 69 253 253 122 253 253 253
-        109 253 104 253 35 253 24 32 125 72 253 253 253 253 100 114
-        69 253 22 253 253 253 121 78 1 253 253 253 70 253 115 107
-        34 253 253 98 253 253 122 253 253 6 100 253 253 79 106 253
-        5 253 253 253 47 98 49 85 253 22 46 253 97 69 253 51 92 95
-        253 253 253 253 5 253 99 61 253 253 105 116 253 253 111 113
-        98 30 50 253 84 253 7 61 253 253 115 253 253 253 253 253 88
-        47 253 253 52 108 26 253 253 253 253 253 253 253 11 253 253
-        253 0 253 77 35 253 253 253 253 57 18 253 103 91 253 253
-        253 110 23 116 253 253 102 50 125 13 77 116 75 253 109 109
-        253 33 103 25 253 253 253 253 253 253 253 34 36 253 8 253
-        36 104 253 7 253 253 7 253 253 253 253 77 90 253 253 253 26
-        9 55 2 61 253 253 253 101 253 253 74 107 253 77 121 113 115
-        253 253 253 70 36 253 253 30 99 47 253 253 253 253 62 46 90
-        90 253 253 34 77 104 253 54 253 0 253 253 253 91 253 253
-        253 113 19 96 253 36 253 253 253 253 253 253 51 106 253 86
-        112 70 253 253 253 84 253 53 100 253 105 82 35 18 57 99 90
-        7 253 43 4 253 33 91 253 123 86 107 253 110 253 253 36 101
-        253 19 253 0 253 253 21 253 253 121 39 253 253 253 253 253
-        32 253 71 253 253 253 105 253 253 8 253 253 253 253 253 109
-        253 253 253 253 253 51 253 85 253 253 74 87 253 61 69 29
-        253 253 253 253 253 40 253 57 253 51 103 6 253 253 8 93 58
-        253 60 127 71 127 253 104 253 62 253 22 253 253 253 101 253
-        127 253 253 253 0 45 20 253 24 85 253 73 26 253 65 253 253
-        18 86 70 100 50 253 253 90 89 104 253 253 86 253 253 63 253
-        63 253 253 253 100 253 253 112 253 253 253 69 37 101 99 253
-        116 253 253 253 253 42 253 50 31 8 253 253 253 253 253 127
-        87 0 253 94 9 253 253 253 78 14 51 253 253 253 253 253 253
-        39 127 8 122 253 253 253 253 253 253 253 54 253 253 113 253
-        52 71 92 124 78 253 253 23 253 253 253 28 253 253 253 113
-        253 253 88 253 253 253 253 44 80 253 253 253 253 253 253 38
-        253 253 253 253 121 49 73 253 101 63 253 79 45 253 253 253
-        253 73 78 253 107 253 29 90 253 92 253 101 113 39 253 253
-        253 34 104 102 253 253 253 56 253 104 253 6 61 253 253 253
-        107 11 253 118 253 253 115 52 123 72 253 117 42 253 253 253
-        253 57 35 253 15 24 253 253 253 115 114 14 253 253 253 253
-        18 48 253 23 253 122 253 18 51 72 253 253 253 253 124 253
-        89 253 253 253 82 45 15 253 253 253 253 64 35 253 253 50 60
-        253 253 60 253 253 122 253 34 253 253 253 105 22 52 83 253
-        56 21 119 124 40 253 61 22 11 120 117 14 253 91 71 253 253
-        253 253 253 253 253 253 253 76 253 253 253 63 253 253 18
-        253 18 57 54 253 100 253 253 253 63 253 91 58 253 90 125
-        107 82 253 0 253 61 62 253 253 253 253 253 253 120 253 253
-        82 82 253 69 253 253 253 253 253 253 253 36 253 253 27 253
-        53 90 60 43 62 253 253 253 253 253 253 124 122 30 253 253
-        31 29 52 104 253 253 95 253 32 5 27 100 36 253 45 253 253
-        10 253 253 62 14 116 119 78 253 49 106 29 125 253 253 6 78
-        253 253 253 253 253 253 253 126 25 253 253 0 253 31 253 253
-        111 253 253 253 253 75 11 33 253 58 253 253 253 253 253 111
-        253 253 253 18 253 105 41 253 127 11 55 77 253 253 13 253
-        253 52 253 253 62 32 50 253 253 57 253 253 253 71 253 253
-        253 253 122 253 5 253 105 253 253 57 253 14 11 253 120 253
-        63 253 253 92 19 253 253 53 253 80 253 253 253 253 37 96 36
-        8 112 28 122 30 61 49 87 123 253 75 105 253 99 253 52 253
-        69 118 253 26 0 16 253 253 74 253 104 10 253 71 82 105 125
-        92 253 27 253 253 253 253 253 12 41 37 253 45 253 68 75 253
-        79 115 253 253 5 253 253 253 253 84 103 253 253 253 253 253
-        253 23 49 253 121 21 93 253 36 253 253 253 63 253 90 253
-        115 72 253 28 109 253 86 95 48 30 253 253 46 253 68 253 62
-        253 253 22 88 78 21 253 253 46 120 253 44 126 253 253 253
-        253 72 124 104 253 253 79 13 253 39 0 253 253 253 55 253 64
-        44 102 54 86 40 36 33 28 253 7 21 76 253 62 253 115 253 253
-        253 253 30 37 253 253 49 253 253 253 62 253 88 253 253 253
-        62 34 253 253 58 102 253 2 121 12 14 253 120 80 253 253 253
-        253 253 54 253 253 253 78 253 253 253 253 253 253 110 253
-        253 253 16 253 40 253 253 78 113 253 253 253 17 53 127 253
-        104 253 75 123 253 253 74 17 20 253 253 63 253 253 0 62 253
-        82 116 253 253 253 117 70 253 107 253 253 253 120 253 253
-        79 253 253 253 253 253 253 111 253 28 253 97 20 253 253 253
-        253 253 58 99 87 253 253 253 73 107 36 48 253 16 253 253 70
-        253 253 77 253 62 253 253 253 253 253 63 253 253 13 253 253
-        253 108 253 26 9 253 13 46 253 115 253 3 253 81 85 253 123
-        253 253 79 253 58 54 253 253 253 253 253 96 36 253 110 10
-        253 253 64 253 103 253 70 126 35 124 48 253 253 99 6 253
-        253 253 253 253 253 253 70 253 7 2 253 253 55 41 69 121 116
-        68 62 34 253 106 253 253 253 73 100 253 61 253 253 17 253
-        66 253 253 80 253 253 39 253 253 28 253 253 105 253 105 253
-        87 253 253 26 59 253 253 253 127 13 253 23 253 253 44 14
-        253 253 253 253 68 106 253 61 253 107 110 253 253 30 119 14
-        253 253 253 253 253 120 253 66 253 253 253 33 253 64 42 79
-        57 253 253 253 81 253 67 28 108 18 34 253 27 253 115 75 253
-        13 58 253 253 253 57 253 105 30 253 26 50 253 253 12 253
-        106 111 253 100 253 253 14 110 45 100 30 29 253 108 93 253
-        253 253 253 253 253 253 253 253 46 253 253 65 116 253 253
-        253 253 14 56 39 253 253 253 253 253 253 102 114 65 253 253
-        29 45 253 253 253 253 253 123 82 253 13 253 253 253 111 94
-        253 127 103 35 13 253 89 59 103 253 253 30 253 253 55 253
-        253 253 253 28 253 253 81 14 253 253 46 253 42 253 52 253
-        253 253 3 253 253 253 55 121 253 253 253 253 62 253 62 253
-        119 253 106 33 86 39 253 15 253 81 80 253 28 253 253 102 84
-        57 35 253 81 91 33 60 96 253 253 42 253 253 253 77 253 45
-        72 53 253 65 253 28 253 253 12 110 20 253 253 107 50 253
-        253 253 253 97 14 253 253 100 253 253 253 26 88 99 0 35 253
-        253 253 35 41 253 62 253 126 253 34 253 101 76 115 75 35 4
-        253 124 253 43 70 253 253 253 122 63 253 253 253 0 253 71
-        73 253 87 253 122 7 80 253 0 54 94 253 0 253 253 253 90 41
-        42 48 253 253 253 61 253 13 253 34 76 10 253 4 91 101 25
-        253 253 253 253 95 253 253 253 74 253 13 123 253 40 253 253
-        55 56 253 115 92 253 71 24 253 253 77 103 253 253 29 253
-        253 23 253 3 253 104 29 53 253 69 253 253 28 253 253 32 48
-        31 122 253 253 253 253 253 253 107 253 77 85 253 253 253
-        253 253 253 253 75 20 253 253 253 38 253 253 253 253 95 83
-        57 253 253 0 123 28 253 97 253 253 23 119 6 86 113 253 3 28
-        3 64 73 118 105 253 253 75 253 253 71 96 253 253 62 253 253
-        43 30 253 253 253 90 68 253 253 69 24 253 76 56 253 101 82
-        71 253 84 253 253 253 253 253 117 125 13 253 54 253 253 30
-        253 253 253 253 253 50 61 253 253 17 93 253 253 19 50 253
-        102 24 78 253 253 253 253 29 55 105 99 253 253 253 104 253
-        253 253 253 1 35 253 5 253 253 253 116 95 253 91 125 52 67
-        53 253 253 253 12 22 9 253 126 253 105 253 253 54 58 126
-        253 27 253 253 253 60 253 253 115 253 84 253 100 101 253
-        253 253 253 127 16 35 253 253 54 253 107 253 253 82 253 253
-        102 43 28 64 121 253 253 126 253 253 253 253 253 253 110
-        253 253 59 253 253 55 120 114 253 0 23 124 253 253 253 36
-        90 253 253 253 253 46 104 35 253 4 39 108 253 60 253 253
-        253 253 115 84 102 253 253 253 3 253 253 253 253 253 98 49
-        253 253 65 253 66 253 253 253 86 253 41 73 81 57 253 22 75
-        126 54 92 253 106 253 105 253 45 253 80 253 62 253 253 127
-        20 127 74 19 253 253 253 253 253 253 38 253 113 253 69 121
-        103 125 101 56 253 44 99 102 253 6 60 253 253 103 253 253
-        253 20 253 253 253 253 0 253 55 87 253 253 253 106 38 253
-        29 67 24 253 33 253 7 31 253 253 80 253 42 253 77 253 9 253
-        253 253 34 120 116 93 253 60 253 253 253 253 253 253 253
-        253 36 63 253 253 253 253 122 59 253 253 28 95 253 44 42 62
-        68 123 253 116 253 33 117 253 20 71 109 12 253 51 36 95 253
-        253 253 0 253 51 253 253 73 253 27 253 253 253 253 253 71
-        253 61 253 2 56 253 253 253 253 35 253 77 93 99 94 75 88 99
-        72 253 253 253 253 10 253 9 253 253 122 35 69 253 253 253
-        113 253 112 23 253 91 253 105 61 253 122 116 253 109 253
-        253 253 253 72 253 99 253 44 253 253 253 253 253 253 253
-        253 10 253 84 253 37 105 49 49 72 253 127 253 253 20 253
-        253 253 253 86 107 115 34 253 253 69 108 253 253 21 253 253
-        126 90 40 253 92 115 82 253 253 76 73 253 23 253 253 253
-        253 253 17 77 43 73 110 253 253 66 57 253 36 253 93 26 253
-        253 253 253 3 92 253 253 253 253 253 49 86 11 61 253 253
-        105 20 253 253 253 80 48 43 69 253 253 253 253 253 28 107
-        27 24 253 253 127 95 253 253 253 61 28 253 253 253 253 88
-        253 13 44 253 43 73 31 253 89 253 0 253 253 65 124 52 253
-        253 253 253 253 253 34 253 253 37 253 253 253 253 253 20
-        253 253 10 253 7 106 253 114 1 253 31 253 39 74 253 253 253
-        68 82 126 72 47 253 253 253 253 66 44 253 253 125 107 79 75
-        123 253 253 253 253 36 253 112 14 10 48 253 253 86 253 253
-        9 78 253 253 253 28 253 253 109 253 111 109 253 253 253 6
-        253 45 253 98 253 89 34 13 253 253 253 40 253 253 253 122
-        253 253 253 253 253 253 253 123 92 253 253 15 253 253 253
-        253 253 253 62 94 59 253 85 78 253 253 253 85 253 253 253
-        253 44 253 29 51 80 253 76 59 253 253 253 253 253 110 121
-        253 253 253 111 88 253 86 253 253 253 53 7 76 253 23 253 35
-        72 253 37 121 34 253 50 125 253 8 97 253 95 43 61 95 253
-        253 0 59 22 124 80 253 35 253 82 80 253 51 75 253 253 253
-        253 253 25 31 253 17 253 17 253 111 253 253 253 253 253 253
-        253 109 103 71 253 59 16 253 73 253 91 253 28 99 253 253
-        253 15 58 89 110 253 4 253 253 39 113 32 253 253 93 114 253
-        253 0 82 43 253 253 253 22 253 107 2 253 253 253 253 253
-        253 64 7 253 253 253 35 253 253 103 18 253 111 253 253 126
-        54 253 253 47 253 253 253 253 12 253 253 34 253 75 253 253
-        86 62 11 7 25 253 43 253 58 253 253 44 253 120 36 73 6 253
-        253 99 253 4 19 253 42 253 253 253 253 98 253 253 126 51 78
-        18 73 30 114 253 87 3 253 40 253 253 83 253 78 253 44 103
-        52 253 78 253 253 54 253 253 122 127 47 253 253 119 125 31
-        117 14 253 39 253 60 72 6 74 253 253 253 106 253 9 109 91
-        44 253 253 28 110 20 253 253 253 253 59 253 30 253 253 6 21
-        253 9 253 123 253 117 19 21 253 101 35 253 68 58 114 253 52
-        41 253 253 253 64 253 253 58 253 120 108 253 253 77 35 253
-        22 8 253 253 98 253 16 253 21 112 8 253 15 63 253 253 6 112
-        125 43 253 35 110 253 0 253 0 253 87 23 65 24 66 253 121
-        253 253 109 253 253 21 253 15 42 121 253 28 253 253 59 253
-        253 24 79 253 253 84 253 253 253 253 253 79 253 253 253 253
-        253 253 253 17 253 115 69 105 35 49 45 99 12 253 253 253
-        253 15 253 101 253 253 253 253 0 253 253 101 24 10 253 74
-        11 81 253 77 253 253 0 253 253 253 253 253 66 253 253 253
-        253 253 103 105 253 253 42 253 57 253 117 57 39 253 107 103
-        110 253 253 253 10 63 253 253 126 253 253 98 253 253 20 10
-        253 67 56 253 65 253 16 253 15 122 57 253 253 253 253 115
-        64 88 253 124 49 253 27 28 101 92 253 114 41 253 253 27 43
-        253 253 38 61 66 76 115 253 127 74 253 91 253 102 253 87
-        253 88 253 253 253 253 111 253 6 253 126 253 253 253 253
-        253 253 24 253 2 50 57 62 253 253 253 253 120 253 106 253
-        253 253 59 253 94 38 253 22 253 116 100 87 253 253 80 70 49
-        253 253 58 43 73 68 253 253 253 52 253 253 253 23 35 56 253
-        58 34 72 253 253 58 47 54 253 253 253 24 253 253 253 79 253
-        31 77 16 253 253 253 67 25 6 253 42 13 253 253 253 253 123
-        253 253 253 13 253 26 253 253 253 57 253 0 26 95 253 86 253
-        14 38 0 253 17 253 125 42 75 20 6 20 41 26 253 253 40 253
-        253 253 253 253 24 60 253 78 89 87 253 253 253 253 253 253
-        253 253 253 22 253 60 253 253 253 74 1 34 253 253 253 253
-        253 253 253 253 79 253 47 72 111 89 117 61 99 84 253 253
-        253 103 33 253 253 253 10 253 0 42 253 253 253 253 253 253
-        253 253 50 253 253 77 44 253 253 54 8 65 253 36 253 40 253
-        253 253 253 95 253 253 253 73 17 253 91 253 253 253 253 253
-        253 253 253 253 253 6 253 55 37 118 253 124 253 253 253 253
-        253 253 253 118 253 253 80 74 54 253 1 90 97 253 253 253
-        253 3 81 253 253 253 91 125 63 77 88 108 253 70 21 97 253
-        253 43 253 53 45 120 119 253 253 253 253 253 253 124 24 253
-        10 1 96 59 253 253 116 253 76 253 104 253 253 253 253 4 101
-        253 253 253 94 91 253 253 253 253 11 26 91 253 47 253 253
-        26 52 117 23 55 18 44 253 253 32 253 253 126 253 97 105 253
-        20 118 253 253 120 107 253 2 121 52 253 18 107 253 253 117
-        35 253 17 70 253 66 107 125 253 253 253 253 59 119 1 253
-        253 253 253 106 118 51 105 253 99 27 253 253 20 253 253 85
-        51 253 90 253 253 253 27 36 55 253 253 253 253 253 3 253 57
-        253 253 253 253 253 253 32 253 101 44 253 99 53 59 41 253
-        253 20 253 253 41 119 253 56 253 253 31 105 121 29 253 42
-        253 253 3 253 253 42 253 107 120 2 16 253 100 253 253 253
-        253 253 253 13 20 253 253 253 253 50 86 9 53 123 50 253 11
-        11 107 253 41 253 60 99 35 4 253 0 125 85 253 71 253 82 253
-        87 15 123 4 253 253 49 253 32 28 15 92 253 86 253 120 253
-        40 4 33 253 12 253 54 253 253 253 253 37 253 253 75 253 253
-        70 253 253 38 80 59 12 253 253 19 253 75 253 77 117 119 76
-        253 117 23 78 253 47 253 99 253 253 121 253 253 54 253 3
-        253 253 253 253 253 29 51 253 253 253 122 253 95 27 104 110
-        253 253 76 253 253 83 253 117 43 87 61 253 76 54 253 118
-        253 89 253 81 68 91 43 253 95 113 253 124 253 116 253 59
-        253 54 23 81 253 110 253 253 253 64 54 122 253 39 253 104
-        114 98 73 253 91 253 125 35 253 105 98 107 75 29 66 7 253
-        253 60 253 57 0 59 121 253 39 253 253 253 253 56 45 253 253
-        253 253 36 253 253 44 253 253 253 253 253 253 253 253 106
-        253 111 43 77 19 68 121 253 253 253 253 253 253 79 253 253
-        93 253 253 253 253 253 253 106 253 64 48 87 253 30 253 253
-        40 253 253 253 5 253 77 253 36 102 48 253 7 36 253 253 253
-        253 253 27 70 253 253 41 253 253 253 253 105 253 253 10 22
-        12 253 109 253 253 253 126 253 90 253 119 110 253 6 253 253
-        253 253 253 72 45 253 253 69 253 75 253 125 121 61 253 100
-        5 30 253 253 115 253 253 253 253 253 68 253 253 32 25 253
-        83 253 98 7 34 253 253 88 253 253 79 253 23 253 253 253 253
-        10 253 253 0 253 41 80 99 115 120 253 253 3 253 67 6 253 28
-        253 253 117 84 253 79 253 121 253 253 253 123 26 253 3 253
-        253 81 14 253 253 253 253 253 253 253 253 253 82 253 50 23
-        253 76 253 253 79 253 31 83 253 62 113 253 253 69 69 10 17
-        253 56 253 66 70 253 20 253 115 68 71 56 0 125 120 253 253
-        253 253 253 49 253 253 86 74 25 125 43 253 28 14 56 253 101
-        253 253 84 48 253 89 82 253 46 54 253 253 109 253 253 49
-        125 253 29 96 253 253 121 253 253 253 253 253 71 21 253 53
-        253 253 253 253 29 253 109 70 54 253 253 120 253 253 54 253
-        253 0 45 18 119 46 57 253 253 117 94 116 59 253 253 253 253
-        0 253 107 24 253 89 51 27 24 6 15 253 253 253 253 13 253
-        100 103 53 253 253 15 253 253 253 253 253 253 253 253 253
-        253 110 253 253 99 253 109 59 253 127 253 22 85 73 60 253
-        90 110 68 32 253 122 34 114 253 253 253 253 253 253 117 29
-        89 39 253 16 253 253 54 253 253 6 253 54 101 29 253 54 9
-        253 107 111 65 52 119 55 253 253 14 253 253 253 123 253 120
-        253 111 253 253 253 1 253 76 253 33 253 253 113 71 253 41
-        88 253 0 104 253 36 253 253 253 100 253 253 253 79 84 58
-        126 71 78 253 253 67 253 91 71 31 38 76 42 17 253 86 253 71
-        253 253 40 253 253 253 104 3 30 253 85 116 253 107 47 253
-        253 253 26 121 253 106 253 253 253 68 253 253 253 253 103
-        118 253 253 253 253 253 253 253 52 74 253 101 92 7 94 113
-        81 253 253 253 253 65 45 253 115 0 66 253 253 253 13 253 85
-        253 253 48 60 253 253 253 92 118 253 253 253 253 253 118 96
-        253 253 63 253 253 125 0 253 253 253 107 253 26 41 253 253
-        105 32 81 253 100 67 37 253 104 253 62 253 253 44 37 253
-        253 253 127 253 93 253 253 253 253 34 85 253 107 253 253
-        253 9 27 121 253 56 253 107 55 45 34 253 114 253 253 47 4
-        253 9 253 10 253 253 79 89 253 97 27 94 77 34 253 47 253 51
-        30 13 9 253 253 253 253 253 24 80 18 253 253 253 61 69 71
-        253 253 253 88 253 88 85 21 45 253 60 5 39 253 51 80 253
-        253 65 253 73 37 253 54 253 70 253 4 14 70 59 81 76 106 253
-        253 23 55 253 91 253 127 253 105 253 48 253 48 253 253 3
-        253 0 253 253 58 253 253 6 253 253 253 253 69 253 123 253
-        84 253 253 253 253 11 85 101 253 47 253 53 30 253 253 253
-        40 100 123 125 56 54 253 253 253 111 46 51 253 253 106 53
-        253 253 253 253 253 253 15 253 70 43 253 7 253 100 15 253
-        93 115 122 253 253 111 115 4 1 253 253 98 253 3 253 91 253
-        253 253 253 253 44 117 253 23 112 253 17 66 253 253 253 9
-        253 58 253 253 253 53 93 29 113 253 5 35 43 253 0 253 81
-        127 253 253 68 15 253 0 253 47 253 86 253 118 253 253 76 23
-        253 28 113 253 253 253 124 105 253 91 59 253 253 87 253 253
-        253 253 99 253 35 253 62 253 116 253 76 126 31 253 253 44
-        57 253 253 119 85 253 118 253 253 74 40 12 79 4 253 20 90
-        111 253 27 253 46 253 253 253 253 19 253 253 109 253 253
-        253 253 253 61 253 253 253 79 253 126 253 34 253 21 253 41
-        26 253 253 253 253 8 253 253 253 29 253 253 253 100 253 41
-        36 253 88 253 253 120 253 253 253 253 123 253 253 253 253
-        253 253 253 253 19 76 253 36 253 253 253 253 253 9 253 253
-        253 253 118 253 73 253 93 58 63 80 253 253 35 105 23 253
-        108 253 46 6 253 253 253 253 253 253 253 89 253 65 27 74
-        253 38 253 15 253 253 253 253 253 122 253 253 253 253 55 80
-        253 253 20 253 18 47 253 253 253 253 117 111 253 67 253 253
-        18 5 253 78 3 10 91 12 83 110 253 253 85 253 253 110 90 253
-        68 253 6 95 253 42 60 253 253 79 253 72 253 125 111 38 253
-        53 253 253 253 118 124 253 253 253 26 253 115 253 253 253 0
-        88 253 88 253 85 253 253 68 116 253 253 34 119 253 253 69
-        109 253 113 253 253 108 253 75 31 72 253 120 253 48 25 4
-        253 12 253 43 116 253 253 253 15 13 99 98 8 253 253 105 253
-        91 96 253 253 43 97 253 30 253 253 106 253 253 253 98 253
-        253 253 253 253 253 91 36 253 58 43 253 253 253 72 46 32
-        253 67 253 13 253 253 85 31 25 253 253 253 253 85 253 253
-        21 253 253 253 253 30 61 69 91 253 94 127 21 104 95 4 253
-        121 126 253 89 253 117 253 87 90 116 126 59 253 27 105 92
-        253 64 21 37 26 118 91 253 253 253 253 62 253 253 53 16 253
-        103 28 110 78 73 253 253 47 253 0 253 253 55 253 253 37 253
-        70 61 57 253 29 89 253 92 104 253 253 253 253 253 34 124
-        253 122 99 253 253 253 253 253 74 253 114 64 253 86 82 100
-        253 253 67 34 108 46 115 69 71 38 253 253 41 100 47 253 122
-        54 253 253 253 253 253 253 45 58 24 253 253 253 62 253 253
-        253 103 253 253 68 253 253 94 253 96 20 14 106 253 34 97 0
-        253 121 25 29 253 124 253 37 111 8 253 59 26 253 253 6 77
-        253 253 123 253 122 253 70 253 253 121 253 253 253 253 253
-        21 253 84 35 253 77 253 253 17 57 63 109 253 65 27 87 60 80
-        253 253 253 0 253 111 127 253 253 253 24 253 253 38 21 253
-        253 253 253 253 253 253 127 253 110 4 9 121 25 253 108 37
-        85 253 253 95 85 253 110 253 253 253 253 253 36 7 253 26
-        253 41 30 253 253 25 253 78 71 253 109 253 64 16 253 95 65
-        253 88 90 16 109 253 253 28 86 253 253 119 253 60 253 253
-        107 124 73 253 121 16 253 253 95 26 80 23 253 253 253 253
-        253 9 253 121 253 253 253 253 51 57 39 253 253 253 253 253
-        253 105 82 253 253 253 253 253 11 253 110 53 253 253 23 253
-        253 253 122 44 81 253 48 253 253 0 61 49 74 24 253 14 122
-        66 253 253 94 48 253 253 80 63 253 253 88 90 72 96 253 54
-        56 253 105 7 78 88 253 31 52 253 253 94 88 253 253 79 253
-        74 32 253 75 123 116 253 68 253 118 110 253 253 253 46 253
-        253 58 65 18 253 74 253 253 112 59 84 115 253 46 253 253
-        253 95 121 44 62 81 253 253 253 253 253 119 81 253 108 253
-        253 42 25 253 90 253 253 253 102 93 253 253 119 96 41 253
-        42 253 253 29 253 107 71 253 87 35 253 99 253 106 35 253 90
-        253 78 5 253 253 22 99 253 41 253 253 253 44 26 83 52 101
-        76 44 48 54 118 53 26 253 109 253 253 253 33 253 253 12 12
-        253 25 253 253 47 12 111 76 253 124 53 253 253 16 45 253
-        253 110 64 114 115 253 84 253 253 253 101 78 253 123 102
-        253 26 56 253 253 102 253 123 67 253 75 123 51 101 8 13 253
-        12 127 253 253 92 107 253 253 27 253 126 253 253 98 253 253
-        253 124 253 253 105 253 28 253 253 68 253 52 253 12 48 44
-        118 253 253 253 253 253 37 15 253 62 253 253 53 63 1 253 60
-        39 253 253 84 253 253 46 253 253 253 109 62 253 253 51 92
-        54 12 253 7 253 253 253 87 82 89 54 253 36 87 22 253 253 62
-        94 59 85 34 253 253 253 110 253 97 124 56 253 45 253 8 28
-        253 12 253 253 253 86 5 253 253 253 75 113 12 108 253 77
-        253 110 56 253 35 253 13 253 91 253 38 53 253 253 111 253
-        253 123 253 253 84 91 253 104 17 253 65 24 17 253 15 253
-        116 66 105 253 113 67 109 70 91 88 253 253 118 0 253 5 72
-        81 253 253 78 253 253 56 127 27 45 253 253 253 55 253 49
-        253 253 110 253 253 29 58 101 253 42 5 253 253 66 12 122
-        123 253 62 253 253 253 253 253 0 253 116 60 92 49 253 253
-        253 253 253 55 72 253 80 93 253 253 50 8 253 253 253 253
-        253 110 5 49 253 253 0 253 253 97 24 23 253 28 40 253 253
-        127 253 107 253 253 73 119 50 253 253 253 253 253 114 121
-        253 125 93 62 253 113 253 25 253 29 253 253 65 253 253 253
-        253 12 253 114 253 253 73 69 253 253 95 8 26 253 253 253 54
-        104 253 253 35 68 72 81 253 21 27 253 77 54 125 23 88 18
-        253 253 253 253 69 51 253 0 37 253 27 253 253 253 253 74
-        253 253 66 253 95 114 123 253 253 253 94 253 253 253 253
-        253 42 36 98 114 19 253 126 253 25 253 40 253 50 46 64 61
-        45 117 107 253 89 51 69 38 14 57 7 253 109 253 111 253 253
-        10 13 253 46 60 253 253 25 253 15 76 253 92 88 253 70 5 5
-        73 60 113 253 82 253 253 51 126 253 112 34 19 99 253 253
-        119 30 253 253 0 253 104 116 52 253 79 69 253 109 119 253
-        17 22 66 87 119 13 253 253 35 83 11 253 253 253 253 253 106
-        45 253 253 120 253 36 253 25 253 253 81 75 253 40 88 253
-        253 253 74 253 115 53 253 70 253 253 253 253 117 253 64 253
-        253 53 93 253 253 253 52 253 23 253 62 14 0 95 253 253 90
-        253 253 56 253 49 253 253 253 75 118 6 253 253 253 48 253
-        253 253 105 24 253 48 71 253 253 36 55 39 253 253 127 20 33
-        253 253 253 101 79 6 102 89 24 46 253 62 82 113 253 84 6 88
-        22 44 52 44 253 253 94 253 253 253 253 58 47 253 104 38 253
-        101 253 71 253 81 253 6 83 253 253 83 54 30 42 72 253 253
-        253 3 253 48 253 110 126 253 64 253 104 253 253 253 253 253
-        253 253 64 57 110 107 102 253 110 253 9 253 65 30 253 253
-        253 104 253 35 253 253 42 253 253 253 100 253 46 99 63 253
-        95 39 253 99 253 115 72 34 253 253 253 99 253 253 253 253
-        67 253 106 87 20 253 253 253 253 253 253 30 253 253 253 253
-        253 253 253 253 253 125 253 2 84 253 253 253 100 5 253 253
-        0 53 40 7 253 253 44 80 90 253 253 253 122 114 127 253 61
-        109 253 253 46 87 253 253 26 253 101 109 34 253 253 253 112
-        126 253 253 70 253 253 52 253 111 253 91 253 28 253 253 253
-        118 114 121 253 253 116 253 253 24 71 111 253 253 253 253
-        253 253 5 98 253 253 89 253 253 115 253 253 66 253 99 5 253
-        253 63 253 62 106 105 99 25 48 42 253 253 39 253 104 253
-        253 29 253 253 1 21 83 112 253 253 111 253 253 37 48 14 253
-        253 253 109 107 253 253 253 50 46 253 253 99 253 13 116 78
-        253 56 253 253 20 253 81 253 80 13 253 253 253 85 253 253
-        94 253 59 253 253 99 12 253 253 253 21 108 90 253 253 36 79
-        10 30 0 253 88 253 253 253 253 23 253 253 253 96 253 253
-        126 253 253 253 12 253 34 253 253 253 63 253 35 253 253 88
-        80 35 67 253 79 253 15 253 253 41 253 55 50 71 3 253 253
-        253 63 59 253 253 253 86 20 253 253 9 49 253 253 75 253 7
-        14 59 26 253 122 253 101 253 253 253 253 70 253 79 57 253
-        19 90 253 253 253 253 253 253 253 60 253 85 91 253 91 79
-        121 123 35 126 42 20 85 57 253 253 253 253 39 253 52 59 21
-        95 71 52 120 85 253 253 19 24 253 61 253 253 38 253 109 62
-        56 84 95 120 253 52 253 12 70 23 253 253 253 8 45 33 102 62
-        35 69 113 253 253 43 28 253 253 253 28 253 53 1 12 253 109
-        253 56 69 30 253 90 89 71 253 87 58 90 44 253 253 253 108
-        45 112 24 253 64 59 253 35 39 253 253 63 253 253 253 253
-        110 35 77 90 16 253 253 71 31 253 253 118 63 253 253 0 95
-        253 253 59 76 253 101 45 113 253 67 10 253 253 34 253 253
-        57 253 253 95 116 253 253 253 109 253 19 66 253 32 253 253
-        14 8 253 253 93 81 253 66 253 253 109 253 253 253 253 38
-        253 125 253 92 253 253 82 120 115 253 3 253 253 253 253 81
-        253 253 253 253 114 253 76 253 253 52 253 64 253 253 57 63
-        83 79 253 108 253 58 51 253 102 253 72 93 32 119 36 100 119
-        25 253 72 253 109 109 253 43 253 253 253 253 119 83 253 253
-        81 83 253 116 253 253 43 253 253 253 253 253 53 87 253 109
-        253 20 253 8 29 253 253 253 0 253 117 88 99 253 18 253 121
-        75 253 112 15 253 10 115 253 253 104 253 253 109 253 47 253
-        3 24 253 70 253 34 35 253 50 253 74 253 79 253 253 23 76 95
-        253 68 253 87 253 37 253 253 26 53 97 28 253 253 253 253 0
-        102 42 253 253 253 111 253 101 123 253 50 253 19 253 35 253
-        253 84 253 68 104 4 253 253 98 112 6 125 253 84 82 27 253
-        253 253 253 97 253 253 56 253 253 77 253 113 118 65 83 78
-        253 58 253 253 36 253 253 253 253 121 253 253 253 253 253
-        253 253 253 253 80 253 253 253 253 97 8 253 48 253 253 106
-        253 253 117 11 77 19 76 125 54 253 30 57 82 9 28 3 79 253 0
-        253 253 253 253 253 253 51 253 253 70 35 253 27 10 253 14
-        59 253 253 70 9 253 253 101 20 253 116 253 253 61 10 253 71
-        253 107 107 59 21 100 11 15 253 61 253 253 253 253 71 12 97
-        253 253 253 1 253 253 253 83 13 26 253 43 88 253 75 108 35
-        253 110 253 57 253 253 253 38 253 253 253 253 253 101 253
-        48 253 253 253 253 253 253 98 56 253 253 253 253 75 3 103
-        126 253 13 253 69 253 253 73 253 253 253 67 20 99 253 253
-        253 102 253 13 27 253 253 28 253 18 77 53 253 93 253 253 79
-        106 16 88 52 253 253 111 32 12 253 253 253 253 0 106 253
-        253 59 253 253 97 116 84 108 85 3 72 36 56 253 34 253 80 70
-        253 253 253 81 253 253 24 61 253 253 253 253 253 253 253
-        253 101 45 253 253 253 253 88 253 95 93 44 106 253 81 253
-        31 50 253 253 253 253 253 105 253 108 253 253 31 16 253 253
-        51 27 253 253 253 74 253 94 253 25 253 253 253 22 94 114 87
-        52 253 253 105 35 117 104 83 45 253 27 253 253 119 253 253
-        19 253 62 25 85 110 253 253 52 76 85 253 0 17 253 253 253
-        253 37 253 253 46 20 21 7 110 253 125 253 253 253 79 253 60
-        253 39 32 253 79 253 107 253 122 253 68 253 75 86 253 25 92
-        100 253 59 26 253 253 253 253 38 253 88 253 253 253 119 28
-        30 107 24 253 253 14 253 44 253 253 79 253 253 99 75 110 45
-        85 253 253 83 62 253 253 253 253 108 253 18 253 125 253 34
-        253 110 253 92 253 86 17 253 71 37 253 0 253 253 253 253
-        253 82 48 253 253 124 253 253 37 253 253 92 253 253 253 105
-        253 253 253 19 33 253 127 109 63 253 253 253 253 253 253
-        253 253 253 253 253 85 10 78 40 253 15 8 59 113 253 120 253
-        96 253 253 50 29 253 26 253 253 68 19 72 253 62 253 11 253
-        253 253 253 15 253 253 253 21 253 84 253 0 50 253 55 24 107
-        119 24 253 97 14 253 36 102 253 32 253 253 253 116 253 253
-        253 87 83 253 253 253 81 107 253 253 53 253 18 7 35 253 253
-        253 44 253 37 105 17 119 28 253 253 82 28 253 253 82 253 18
-        49 253 69 79 253 253 75 121 32 92 253 73 28 253 253 68 69
-        253 65 253 106 253 253 253 36 49 253 38 61 87 253 253 253
-        253 253 94 68 253 95 253 66 253 253 253 253 253 253 97 253
-        72 253 106 109 6 103 93 253 253 253 253 253 58 110 253 253
-        2 36 4 1 253 253 253 253 15 253 44 108 253 253 124 25 253
-        127 253 253 71 253 82 107 123 49 34 253 113 253 253 71 253
-        253 65 253 88 87 42 6 22 110 1 253 253 253 92 121 84 253
-        253 253 5 253 253 253 88 253 84 19 253 93 253 65 111 103
-        253 84 253 104 253 253 65 253 253 82 253 42 66 253 41 31
-        253 253 17 253 253 44 28 253 92 253 109 253 253 113 110 253
-        74 253 253 30 253 84 253 253 127 253 253 253 253 3 253 4
-        253 253 253 253 108 253 253 14 114 49 253 95 253 253 127
-        253 72 253 253 53 41 87 12 253 253 253 39 253 83 253 253
-        253 253 253 253 26 253 253 253 11 253 253 16 82 114 78 78
-        106 95 253 253 17 253 253 69 253 253 253 31 253 84 253 106
-        253 253 253 27 98 253 253 102 10 87 29 253 106 99 253 253
-        50 71 253 253 253 253 253 73 253 253 31 90 253 253 100 73
-        45 23 31 79 253 253 253 104 84 253 253 253 120 253 253 71
-        253 83 253 66 55 75 114 253 253 253 43 253 0 25 253 21 16
-        253 253 18 107 104 253 110 11 55 0 15 253 123 84 253 253
-        120 253 253 253 253 253 253 253 8 25 253 118 65 253 60 253
-        253 119 253 253 253 49 253 36 253 253 253 92 253 253 253
-        253 44 85 253 253 253 94 42 253 253 253 90 253 105 253 56
-        253 253 253 253 253 253 253 117 253 253 9 253 123 253 253
-        105 34 104 253 253 253 253 253 127 253 84 31 89 91 253 253
-        253 99 253 30 82 55 40 29 253 253 253 253 23 253 41 112 253
-        253 253 253 103 253 102 123 253 95 57 253 33 24 3 253 42 61
-        253 120 51 36 69 109 119 3 47 253 61 78 15 21 33 253 253
-        253 253 253 9 70 84 15 54 125 253 116 253 253 24 93 253 253
-        253 6 6 59 26 253 17 253 72 253 253 253 98 108 27 117 4 253
-        253 92 253 111 253 65 253 64 98 75 43 87 17 253 253 44 56
-        253 253 253 3 107 110 99 99 52 253 50 253 56 99 253 253 123
-        253 253 77 38 253 37 101 253 31 253 253 70 43 253 110 82 10
-        253 253 253 253 53 253 71 253 87 253 28 253 88 121 125 43
-        253 253 26 253 50 253 22 253 111 253 16 253 42 253 253 253
-        9 253 253 253 253 126 10 253 13 109 253 115 253 31 253 253
-        42 253 253 253 253 11 77 253 25 36 73 90 110 253 15 57 253
-        253 253 25 253 84 55 253 253 97 21 253 74 253 253 15 54 253
-        121 53 5 253 9 86 253 105 118 253 253 119 253 33 253 84 253
-        253 21 253 253 253 253 35 253 253 0 49 253 56 253 253 253
-        110 253 253 253 253 253 253 253 253 90 253 99 253 9 14 253
-        90 57 49 253 253 111 253 87 253 253 79 4 253 52 253 43 253
-        253 253 253 124 12 253 122 253 253 6 253 253 110 1 253 103
-        63 253 253 81 253 94 253 253 25 253 40 87 70 253 127 81 253
-        253 103 45 29 253 28 253 48 253 15 253 27 253 253 18 27 119
-        253 2 63 76 85 253 253 89 253 73 26 42 253 253 28 253 85
-        253 253 29 42 75 253 253 253 253 24 253 253 253 0 15 30 253
-        113 253 253 55 16 253 253 253 253 60 253 123 85 99 253 114
-        253 253 253 1 29 253 9 253 253 87 9 253 253 253 253 253 54
-        73 253 76 253 253 253 121 119 112 64 253 42 68 34 23 10 4
-        109 253 253 76 253 253 54 110 253 87 253 43 32 253 253 7
-        253 253 62 104 253 107 26 118 99 253 253 253 253 14 121 253
-        86 125 99 253 253 253 5 105 110 23 96 62 102 65 87 101 253
-        253 101 30 59 253 121 253 253 51 70 50 13 67 253 253 46 253
-        253 253 253 253 53 253 253 74 7 6 253 253 253 68 117 253 48
-        8 253 72 253 50 38 253 33 116 108 253 253 19 253 253 62 59
-        253 113 87 71 94 253 47 38 253 253 253 253 43 97 86 253 253
-        253 253 34 253 253 48 85 253 253 253 43 2 74 253 253 253
-        103 253 253 101 39 253 25 53 253 253 253 253 253 253 115 85
-        64 52 253 22 80 253 24 56 253 253 78 253 8 0 119 253 23 253
-        253 27 113 253 75 253 10 253 253 2 253 105 253 253 24 105
-        58 110 10 253 74 18 253 0 63 253 110 253 253 253 253 253
-        253 253 99 11 253 72 253 117 31 253 85 253 61 253 78 15 253
-        253 253 253 253 90 253 116 253 76 50 253 253 253 253 21 253
-        8 253 109 253 18 57 24 253 253 124 253 253 109 253 253 253
-        22 253 20 253 253 253 118 253 253 29 253 253 35 253 62 253
-        253 63 253 253 85 109 253 253 253 253 125 253 253 253 87
-        253 98 253 117 42 253 113 253 90 253 253 253 253 77 253 110
-        253 109 253 14 253 253 95 13 253 45 253 81 90 100 44 23 253
-        253 253 127 253 253 253 91 253 68 45 106 253 253 253 24 253
-        253 253 253 253 253 253 93 253 253 253 253 253 253 122 65
-        253 25 253 95 253 253 16 51 253 79 27 105 253 253 253 253
-        121 253 39 60 39 253 105 253 253 13 253 8 84 102 112 4 112
-        253 253 253 52 108 80 71 23 253 253 253 253 253 253 253 32
-        81 253 82 62 253 253 253 80 253 114 126 253 253 253 38 253
-        59 17 121 1 113 253 118 253 253 253 253 107 253 253 36 105
-        253 253 253 253 94 57 82 119 47 253 253 253 253 253 253 6
-        72 31 253 35 253 253 106 253 253 253 5 253 124 86 101 12
-        253 253 253 24 57 253 253 20 253 96 253 62 69 19 13 253 253
-        253 71 253 120 253 102 52 253 253 105 253 253 61 253 253
-        253 253 18 253 50 12 125 90 253 253 19 103 253 120 18 253
-        96 253 0 125 104 103 253 253 101 253 106 253 27 79 111 74
-        253 105 253 119 57 114 90 45 126 253 253 86 253 102 55 40 8
-        253 253 78 253 31 60 86 95 253 107 253 253 253 111 47 36
-        253 253 253 27 253 253 253 253 41 253 253 81 253 112 123
-        253 253 253 253 253 253 253 253 253 253 253 253 56 99 253
-        43 253 30 95 253 253 253 253 253 67 62 253 253 0 22 88 89
-        78 253 89 253 24 85 62 253 68 253 253 20 253 253 120 253 15
-        39 253 253 253 253 253 253 21 100 253 93 81 253 253 253 253
-        121 253 253 27 253 9 24 97 75 253 109 253 123 253 253 118
-        253 72 253 21 59 6 6 11 55 106 253 82 253 57 41 69 21 69
-        253 107 60 253 93 253 253 253 253 75 55 4 26 2 253 55 93
-        253 253 253 91 253 253 253 120 75 253 253 29 253 253 75 118
-        30 253 100 81 28 253 253 253 70 72 253 253 253 0 76 253 124
-        23 81 107 2 253 70 253 7 253 253 253 253 253 253 253 73 100
-        253 253 253 253 35 12 21 253 253 9 253 51 253 105 253 253
-        53 253 47 106 253 55 253 81 38 253 29 253 253 92 253 253
-        253 253 93 2 253 253 253 55 27 253 253 97 253 253 15 253 0
-        253 15 107 253 253 127 107 93 71 0 253 253 253 97 253 253
-        253 113 30 18 114 86 36 253 253 253 253 253 253 253 20 15
-        253 253 27 253 253 253 95 61 33 125 253 253 99 253 94 2 253
-        115 73 32 253 253 253 84 253 253 253 253 253 253 253 253
-        253 253 253 4 253 0 253 253 82 24 253 253 56 253 36 253 253
-        113 253 253 37 253 31 253 36 253 253 26 253 253 53 253 253
-        37 253 47 13 253 65 72 33 253 61 253 253 253 89 253 253 76
-        97 253 43 49 253 10 253 127 253 253 61 253 48 253 93 253
-        124 253 17 253 253 253 253 253 253 253 4 253 253 41 253 39
-        253 253 87 62 73 253 253 98 253 253 77 70 253 105 110 253
-        253 253 50 89 41 253 0 253 31 106 9 108 115 118 253 36 98
-        88 253 253 95 253 13 31 102 253 253 253 253 35 60 253 253
-        253 83 253 253 253 253 253 253 253 253 108 253 253 0 253
-        253 53 72 253 121 20 116 253 19 253 253 253 253 12 107 17
-        119 253 253 253 253 253 0 10 253 253 253 253 253 40 253 253
-        253 81 253 253 253 253 253 253 253 18 40 253 82 0 5 253 253
-        253 22 253 118 253 113 253 59 26 253 253 93 108 253 253 92
-        253 253 53 253 127 253 253 78 87 253 30 253 253 253 253 25
-        253 48 24 118 49 253 113 76 253 89 99 56 253 67 253 20 120
-        253 253 125 13 55 16 8 111 253 76 253 253 37 39 25 253 14
-        253 1 253 117 1 253 101 253 74 96 55 253 88 23 253 19 70
-        253 253 253 253 253 62 253 21 253 72 253 54 253 70 253 84
-        253 253 253 63 253 253 18 253 119 253 253 253 107 253 253
-        101 112 48 74 253 253 253 253 55 253 21 253 101 109 253 118
-        253 49 87 253 253 11 59 89 253 253 253 253 253 86 11 253 86
-        253 253 7 253 41 253 253 253 13 253 119 119 20 253 31 26 4
-        253 53 253 253 114 56 253 35 253 253 99 16 93 253 253 253
-        10 253 253 253 51 11 253 253 253 253 253 253 253 253 253
-        253 97 117 253 31 253 45 253 253 253 87 253 253 82 14 253
-        253 253 65 253 103 253 40 13 74 48 116 253 253 28 253 0 70
-        122 48 73 253 67 52 22 253 253 88 93 253 60 253 56 20 89
-        253 253 253 33 253 253 253 253 253 253 25 98 253 253 55 122
-        253 90 253 99 38 253 253 63 253 253 253 253 10 48 53 33 253
-        253 36 17 76 55 59 253 28 253 86 253 253 253 82 71 253 85
-        253 86 253 253 253 253 253 253 253 73 66 253 253 28 253 253
-        253 57 253 253 253 83 71 253 72 253 97 253 39 106 253 58
-        253 67 121 30 253 68 253 253 34 103 253 57 60 49 253 84 253
-        253 253 59 114 253 42 253 28 253 2 7 97 80 110 253 253 5
-        253 253 18 27 253 57 60 113 253 126 253 55 253 253 253 66
-        38 253 253 253 253 120 57 63 253 89 253 253 57 253 253 35
-        72 23 119 0 253 253 253 35 81 253 253 253 13 8 118 33 253
-        253 253 253 101 253 32 253 253 6 62 50 253 119 99 253 253
-        74 122 253 253 110 253 253 253 11 253 29 253 253 72 253 114
-        71 21 253 48 253 10 253 253 83 253 253 65 253 45 20 253 88
-        253 52 253 91 27 253 104 80 253 18 119 122 253 253 253 11
-        253 123 253 110 31 78 253 93 253 67 253 123 87 79 107 253
-        53 253 253 253 43 75 17 253 253 253 125 253 253 253 253 253
-        73 114 100 84 96 253 253 13 253 126 253 25 70 253 253 253
-        253 253 35 253 116 253 253 253 16 52 253 42 253 253 253 253
-        253 253 253 54 253 253 105 90 253 253 61 253 253 11 28 253
-        83 253 253 253 83 253 253 253 253 253 253 253 100 253 253
-        253 67 96 114 61 253 253 253 52 253 117 253 17 90 56 253
-        253 12 253 35 56 21 60 77 73 253 83 253 253 253 72 253 253
-        45 112 253 253 26 86 59 20 253 4 253 22 253 52 253 98 253
-        253 253 253 253 62 57 253 18 54 253 253 3 253 253 83 78 253
-        253 112 99 253 253 253 45 13 253 32 253 116 125 253 253 121
-        253 104 253 253 101 253 253 0 253 253 253 5 116 62 253 120
-        253 82 123 39 58 253 88 253 117 253 253 253 253 75 124 86
-        253 24 253 253 70 253 253 7 253 53 60 253 253 43 117 253
-        253 75 253 253 253 253 18 89 253 253 44 253 253 253 253 21
-        253 10 123 253 51 253 253 115 253 107 253 36 253 253 253
-        253 253 253 253 253 82 109 7 253 31 89 104 253 71 109 109
-        253 94 4 253 253 253 253 50 8 253 54 253 253 17 253 253 253
-        88 87 253 253 31 253 253 253 126 253 253 43 13 48 94 88 61
-        253 70 63 26 253 88 253 33 125 253 253 51 253 253 106 29
-        253 253 103 253 58 253 253 253 253 253 253 83 35 32 88 253
-        253 32 47 114 126 253 19 253 253 253 253 117 253 33 253 81
-        253 253 253 253 253 12 80 120 253 110 253 253 253 71 253
-        253 66 44 55 19 90 71 253 75 253 253 25 253 115 90 253 73
-        46 253 253 253 53 67 253 78 253 95 20 253 77 253 50 121 253
-        104 253 253 75 253 253 34 253 253 253 253 3 16 253 3 253 47
-        67 253 253 253 64 253 253 253 71 35 253 253 14 253 253 106
-        253 62 27 253 16 253 253 61 253 105 48 253 18 253 96 22 95
-        253 253 253 253 4 253 253 253 7 253 29 47 125 30 253 53 253
-        253 253 253 253 253 253 30 64 253 253 253 253 103 28 123
-        100 253 253 253 120 84 110 253 253 83 126 253 253 253 253
-        253 37 253 253 116 44 56 85 36 55 24 253 253 253 253 83 123
-        118 94 66 67 19 253 106 253 116 253 253 73 18 94 253 253
-        253 83 95 253 76 253 76 46 112 253 31 253 87 31 73 116 253
-        253 253 49 253 253 14 1 253 253 111 253 23 11 20 34 8 35
-        253 253 56 253 3 21 104 90 90 27 93 253 36 126 35 253 253
-        253 79 31 74 253 253 7 86 253 60 253 97 118 253 253 77 253
-        118 253 253 253 91 90 53 253 28 125 253 21 253 60 50 253
-        253 253 253 119 253 253 42 53 58 253 253 51 42 253 253 65
-        253 23 94 12 69 100 253 35 253 123 253 60 253 253 253 20 27
-        253 71 253 253 62 253 90 1 35 253 115 43 40 113 32 253 55
-        124 84 47 253 100 253 49 253 253 253 253 65 253 124 91 253
-        253 85 253 98 253 253 253 103 42 253 121 253 253 253 253
-        253 253 253 253 253 253 253 90 125 253 91 107 253 105 7 253
-        253 253 53 253 68 253 253 47 107 253 95 253 253 49 253 253
-        48 28 73 25 253 253 253 253 87 253 0 253 253 253 51 100 253
-        110 253 87 94 106 67 88 253 55 253 253 253 31 92 113 253 14
-        73 253 85 87 253 82 4 253 253 124 253 253 253 253 253 68 52
-        89 253 73 52 2 253 253 121 253 109 253 50 253 253 253 88 17
-        102 253 253 253 35 253 75 253 27 110 253 76 253 20 96 253
-        253 253 253 85 253 253 14 54 253 253 26 253 253 61 41 102
-        253 41 253 21 253 253 253 39 253 50 253 48 253 253 253 253
-        253 63 5 63 253 253 253 253 17 253 102 122 48 63 253 253
-        253 253 253 43 126 71 253 253 90 253 72 79 253 253 253 253
-        253 36 253 18 45 253 75 17 81 101 253 253 253 253 253 61 77
-        15 111 122 253 87 65 253 118 253 253 30 253 253 253 253 253
-        253 57 253 90 253 253 121 34 110 71 40 7 56 28 253 253 253
-        40 253 47 99 253 126 4 117 253 253 253 253 253 63 253 44
-        253 120 24 253 253 78 253 65 81 253 253 253 118 253 115 28
-        0 107 253 253 28 89 253 253 253 77 54 89 34 32 253 105 56
-        39 253 253 253 253 253 253 253 84 87 102 17 76 253 48 6 9
-        253 253 253 14 60 65 253 51 253 45 102 103 1 100 253 253
-        121 5 78 69 99 253 253 54 253 253 253 253 253 253 253 77 11
-        253 253 39 17 71 112 253 23 28 253 35 253 253 62 253 53 253
-        253 253 253 45 33 253 253 253 0 44 253 98 253 253 19 36 117
-        72 253 253 253 42 72 253 38 120 62 253 112 27 80 5 35 111
-        253 253 118 19 120 253 1 96 253 253 1 253 253 44 253 80 110
-        253 253 253 105 253 64 253 30 253 21 253 25 100 25 82 48 69
-        84 253 0 18 122 82 19 35 253 101 32 253 100 10 253 3 46 56
-        96 104 109 66 253 27 253 253 253 253 253 253 253 40 253 27
-        28 253 253 253 91 253 253 253 91 253 43 63 253 20 71 60 253
-        253 0 74 125 253 93 69 117 98 88 93 253 22 253 92 4 253 253
-        253 91 253 253 76 108 253 72 253 80 51 253 253 106 253 253
-        253 41 68 253 111 29 253 8 253 253 253 253 113 253 124 37
-        103 124 36 253 42 253 44 121 46 108 53 253 253 253 69 253
-        108 253 65 253 253 253 119 253 253 23 253 253 104 37 253
-        253 10 63 253 253 253 253 253 37 253 253 58 253 112 253 253
-        64 253 48 79 253 89 90 93 253 253 253 253 89 253 103 253
-        253 253 123 15 113 253 253 71 43 253 103 52 253 46 52 253
-        27 93 253 99 116 253 253 44 86 253 253 69 253 44 253 253
-        253 84 30 253 64 107 107 253 253 253 56 31 46 7 253 118 253
-        253 253 90 253 253 93 253 54 253 118 57 42 57 253 253 253
-        106 125 33 253 253 120 100 88 86 104 253 96 101 107 253 50
-        253 37 105 28 253 253 253 116 14 253 253 253 253 253 55 51
-        49 253 253 253 253 253 125 55 253 253 54 253 45 253 253 72
-        253 253 70 55 15 122 253 52 46 253 253 253 253 55 253 253
-        20 253 253 99 253 83 253 90 104 253 84 253 97 253 86 49 253
-        36 96 253 53 253 253 253 37 253 253 253 110 253 253 116 79
-        10 253 121 20 253 253 253 4 124 253 107 253 253 253 253 253
-        54 253 105 24 72 253 55 253 253 253 253 53 253 253 253 253
-        109 253 36 253 112 30 68 114 253 253 114 77 87 253 73 121
-        253 91 253 253 87 46 253 121 71 253 253 73 101 116 253 253
-        253 253 51 45 96 106 26 253 253 253 122 253 99 253 45 253 5
-        54 253 30 253 253 253 253 253 253 253 3 20 253 253 253 253
-        253 30 40 253 253 253 253 70 25 253 26 253 253 111 253 99
-        253 253 60 253 70 37 3 253 92 80 79 108 76 253 56 253 25
-        116 63 79 253 253 253 253 253 79 253 125 79 253 74 23 253
-        25 253 28 115 88 253 253 12 33 19 253 119 253 253 58 38 55
-        56 31 90 253 253 253 105 253 99 58 253 46 253 96 253 118
-        253 253 253 52 67 253 102 253 48 253 253 51 69 253 44 126
-        25 60 253 253 14 253 253 253 96 84 253 253 253 5 253 32 253
-        69 103 253 40 114 26 253 15 253 253 81 253 253 253 253 80
-        83 95 73 253 253 33 56 253 0 91 253 253 253 29 68 108 99 48
-        253 9 253 0 124 253 24 63 110 106 11 253 117 110 253 53 253
-        253 253 253 253 253 253 112 114 253 253 88 253 44 46 253
-        253 33 253 79 253 253 73 85 84 16 253 253 253 87 37 124 96
-        253 11 91 253 78 75 11 75 253 21 253 19 253 70 56 253 39 86
-        253 53 253 70 57 32 253 253 82 253 14 28 13 253 87 253 253
-        253 69 253 58 29 253 253 253 42 67 113 123 118 92 253 253 0
-        99 253 107 112 79 253 106 253 45 253 37 253 105 14 112 123
-        31 122 33 253 253 253 60 55 108 125 40 253 99 104 81 97 112
-        253 253 253 253 65 22 96 73 253 253 74 253 253 27 60 53 9
-        253 43 43 104 253 112 57 253 21 253 33 253 253 253 98 253
-        253 13 32 12 253 65 7 253 74 253 253 253 57 253 111 83 253
-        253 73 38 127 24 71 253 60 69 253 25 253 253 49 253 120 253
-        253 103 117 253 253 253 253 113 253 253 253 253 253 31 106
-        22 253 40 253 253 253 253 253 62 105 253 25 253 30 109 42
-        253 113 253 253 253 253 253 57 253 44 44 48 59 119 253 52
-        103 85 253 44 253 253 76 8 127 93 253 85 253 253 253 253 42
-        71 74 116 70 253 2 253 94 14 113 253 97 253 253 87 65 253
-        36 253 253 253 40 253 8 253 47 113 253 253 253 109 253 107
-        253 37 60 253 253 253 83 253 253 253 253 39 87 0 110 35 253
-        253 253 253 253 102 253 253 253 253 253 58 103 253 253 35
-        48 52 114 32 24 253 253 253 253 91 107 253 253 253 5 253 4
-        24 253 56 253 253 77 253 253 89 68 253 55 253 83 253 76 14
-        126 253 52 253 253 55 253 253 76 253 253 126 87 3 253 90 82
-        85 70 74 253 44 116 24 253 253 78 119 103 253 253 48 71 253
-        253 92 104 253 253 253 17 76 111 253 253 253 253 109 38 72
-        100 253 6 253 253 253 118 253 123 253 253 253 11 109 9 28
-        253 253 253 32 100 84 69 110 253 253 253 253 66 253 111 253
-        253 253 47 253 78 114 5 72 45 253 86 253 253 253 114 40 93
-        253 253 57 253 41 93 253 81 253 127 253 15 253 38 120 34
-        253 253 106 64 58 253 28 121 80 57 111 115 72 60 23 253 253
-        29 74 89 38 86 253 45 253 253 253 253 253 253 253 121 8 5
-        253 64 9 253 72 253 253 55 48 253 4 253 253 253 49 30 104
-        253 111 253 253 253 253 253 19 253 253 253 124 39 95 253
-        253 78 76 87 75 253 253 253 113 121 98 20 253 253 57 35 253
-        253 253 93 11 13 253 253 253 54 84 253 253 80 7 38 253 58
-        35 53 253 253 93 253 104 253 253 73 253 1 253 108 253 253
-        253 253 253 253 69 41 253 253 5 253 253 37 253 253 253 253
-        17 59 84 14 253 253 81 253 253 109 67 78 253 253 11 34 253
-        253 253 253 253 253 101 253 253 49 253 253 253 73 253 104
-        253 253 105 253 253 253 253 113 72 253 253 253 253 103 253
-        253 253 253 46 253 253 56 253 78 253 253 253 253 253 101
-        107 253 23 37 89 253 253 70 77 253 78 15 53 53 253 253 108
-        253 253 253 107 120 253 42 253 253 65 65 253 253 104 253 54
-        107 253 253 88 253 36 82 253 253 125 253 111 253 53 101 253
-        127 253 40 122 253 253 253 86 41 3 253 253 15 106 253 125
-        123 253 253 253 253 109 253 54 3 253 253 253 74 253 253 253
-        53 75 253 109 97 70 253 253 253 253 253 105 90 109 253 111
-        253 253 9 253 253 253 41 253 253 105 253 78 253 21 78 253
-        253 55 253 72 253 33 98 31 253 253 253 15 253 75 116 79 253
-        114 8 253 111 35 253 123 118 253 119 31 90 253 52 253 54 27
-        24 253 253 125 253 253 253 113 84 73 62 253 253 253 18 122
-        100 95 253 253 102 29 46 97 253 64 253 23 253 253 253 253
-        253 83 253 28 108 25 253 31 111 122 253 43 108 253 71 253
-        253 253 80 109 253 109 77 253 253 17 30 121 25 253 77 72
-        253 83 126 253 253 23 107 26 253 60 253 253 40 24 111 253
-        253 111 14 8 253 253 78 75 103 253 253 87 50 5 253 253 2 59
-        253 79 21 253 11 103 110 253 18 6 62 253 253 105 28 253 10
-        253 85 123 38 253 45 253 88 253 81 253 67 32 30 253 253 253
-        253 253 80 253 114 253 22 10 253 108 30 62 253 253 79 46 46
-        86 123 98 100 102 253 7 30 94 253 253 26 28 69 253 52 56 95
-        109 253 109 253 108 51 253 253 23 253 104 253 253 25 13 31
-        253 253 253 253 253 27 253 6 56 84 253 253 46 120 12 253 2
-        253 115 20 110 253 110 19 253 253 110 21 62 253 253 253 253
-        52 101 253 43 64 253 253 253 253 104 69 127 74 253 80 253
-        253 253 253 253 51 253 253 14 15 253 106 253 253 253 39 75
-        253 253 253 253 253 21 253 112 126 84 98 23 253 253 39 87
-        253 253 253 49 71 82 114 25 71 106 253 122 253 37 253 40 50
-        77 55 253 64 0 15 253 86 253 53 20 87 81 74 253 253 253 35
-        67 39 101 253 36 99 253 104 9 50 253 54 253 253 35 253 13
-        19 253 45 36 96 65 27 253 253 57 253 253 253 253 253 253 20
-        4 73 253 103 24 253 20 253 122 116 122 47 253 253 253 9 253
-        253 72 253 253 253 32 3 253 122 253 63 53 253 253 253 253
-        34 253 253 60 253 253 61 253 253 253 253 12 102 253 69 26
-        253 253 253 253 253 253 253 92 5 253 253 253 70 253 105 11
-        47 253 253 253 80 87 253 0 253 253 63 253 253 253 86 253
-        253 253 3 253 253 253 99 253 41 253 253 0 253 122 253 17 92
-        253 118 127 253 253 253 1 253 30 18 86 253 51 253 253 253
-        87 253 253 13 50 12 253 64 27 31 253 76 253 253 253 253 253
-        253 120 123 80 41 253 115 253 106 40 253 98 43 123 253 111
-        55 253 253 113 253 253 86 7 70 253 76 253 253 31 253 68 253
-        253 253 253 253 96 62 253 253 253 253 90 28 253 253 99 253
-        253 253 59 253 0 253 15 253 253 83 110 253 253 9 102 253 45
-        253 253 102 253 39 28 253 253 253 98 41 253 253 39 68 253 0
-        253 253 253 253 58 253 253 73 253 253 253 253 73 253 1 30
-        253 97 104 253 253 253 253 253 103 118 253 253 71 253 25
-        253 253 253 63 70 253 253 62 253 253 253 21 253 118 253 70
-        253 253 27 99 71 253 253 253 65 53 34 253 253 77 74 253 47
-        253 114 58 253 68 253 253 31 99 89 253 11 253 253 253 253
-        99 253 30 56 253 54 253 74 253 102 50 61 253 253 253 253
-        120 56 63 32 61 253 78 23 253 53 94 105 26 253 253 253 34
-        65 253 88 253 66 253 253 253 253 253 63 92 122 84 253 253
-        253 75 253 253 68 253 34 253 79 253 1 253 253 74 70 19 118
-        253 11 253 67 44 253 253 18 6 253 253 253 75 253 90 253 71
-        102 253 253 124 253 253 64 253 253 253 253 97 253 253 50
-        253 253 82 7 96 253 253 91 106 39 253 253 253 253 253 253
-        253 253 253 71 253 35 84 253 21 253 253 253 49 34 253 13
-        253 24 253 103 45 29 253 253 82 84 253 253 56 81 69 253 110
-        49 40 48 52 89 28 253 19 253 21 253 253 253 73 253 104 253
-        253 125 8 28 253 253 108 77 38 107 71 120 253 109 66 69 16
-        38 82 253 253 28 253 80 86 73 58 66 99 117 124 253 57 70
-        253 0 253 100 253 60 78 89 81 253 49 253 8 114 63 253 253
-        116 48 99 44 253 63 45 253 123 253 253 253 253 120 253 253
-        97 102 63 253 69 97 52 253 253 253 68 253 253 57 253 109
-        253 0 106 85 253 92 92 253 21 69 112 253 253 32 253 22 253
-        24 41 50 63 253 253 253 253 253 87 118 253 253 73 27 253
-        253 101 126 253 253 122 253 93 117 30 253 38 253 253 94 253
-        253 253 19 253 109 30 48 78 61 8 253 253 253 253 253 92 25
-        97 105 87 253 253 253 253 85 253 17 253 3 72 253 125 66 13
-        98 253 253 253 253 71 112 23 37 99 32 78 61 73 24 253 79 39
-        25 253 120 253 253 253 253 1 253 55 105 253 17 253 253 253
-        253 253 50 253 52 253 253 7 253 23 253 0 253 253 253 253 66
-        253 253 52 253 253 253 253 253 28 253 253 104 115 253 97
-        103 13 253 253 96 253 28 40 253 253 253 253 253 63 253 52
-        253 46 47 253 253 48 50 253 253 253 253 253 71 81 68 114 91
-        118 253 97 253 253 253 85 49 253 102 253 253 67 253 110 96
-        88 253 77 109 119 50 253 253 24 253 45 253 71 109 24 101
-        102 64 253 57 11 253 253 73 253 73 79 253 253 37 253 253
-        253 253 40 14 253 253 115 253 7 253 7 113 54 253 48 253 253
-        85 126 253 253 71 11 42 110 109 253 253 0 253 108 127 253
-        105 72 101 253 253 253 253 88 253 253 2 54 15 253 83 59 253
-        85 5 105 253 55 253 93 253 253 118 52 46 253 34 67 3 253
-        253 93 253 101 3 36 83 68 253 84 92 253 100 125 253 38 253
-        36 253 4 253 253 108 253 30 253 253 253 94 253 253 12 253
-        253 90 253 253 99 86 111 12 54 91 105 253 21 39 253 85 253
-        253 98 82 253 253 6 60 79 253 82 253 46 253 253 253 104 12
-        1 253 78 253 114 104 253 253 253 253 253 57 60 253 6 101
-        253 253 253 253 81 253 62 94 77 44 253 253 83 42 23 253 253
-        253 253 21 29 253 253 34 253 253 253 253 69 1 3 45 52 253
-        103 31 65 253 0 106 47 91 253 45 44 81 253 95 21 253 29 253
-        26 33 44 253 253 21 16 253 126 253 253 8 253 109 13 253 253
-        253 253 253 99 113 253 253 253 41 1 253 62 253 253 104 253
-        69 36 253 49 42 23 253 52 253 253 99 253 61 253 253 253 53
-        253 37 34 253 253 253 253 253 253 60 253 253 76 125 9 253
-        86 14 253 253 114 73 40 253 253 54 109 253 45 253 72 253
-        253 253 253 117 47 253 253 253 253 93 78 253 76 35 253 253
-        253 253 253 253 79 21 253 253 253 253 58 253 253 253 39 253
-        64 253 43 3 253 34 253 253 253 16 253 70 253 253 253 253 69
-        75 117 253 253 253 253 253 253 37 253 253 15 253 253 112
-        253 61 253 71 36 253 44 93 253 85 69 253 253 85 253 3 253
-        253 253 253 96 253 253 253 253 253 63 74 253 29 253 53 253
-        102 73 6 253 253 253 253 253 0 253 106 85 253 253 99 253 79
-        45 253 38 30 253 253 253 253 253 120 253 253 64 8 253 15
-        253 1 253 70 11 124 253 253 253 35 20 253 9 35 116 37 90
-        253 5 253 29 253 65 253 18 253 0 67 253 253 0 116 253 90 41
-        16 1 253 253 253 253 106 24 253 61 253 110 27 253 54 253 61
-        253 78 253 253 110 34 253 47 253 55 253 253 253 253 253 253
-        253 85 253 253 73 118 116 253 253 109 63 253 253 83 53 253
-        253 126 253 253 253 80 80 253 253 253 15 253 122 95 253 253
-        253 122 253 88 253 253 253 253 95 253 253 253 107 86 253
-        253 253 253 253 87 253 31 253 253 77 253 121 253 0 253 253
-        49 127 90 95 253 253 122 253 74 253 253 99 253 253 104 22
-        253 253 125 253 253 253 253 69 126 253 253 253 253 253 79
-        253 253 94 253 80 8 60 253 253 95 253 100 253 253 74 253
-        122 253 253 62 46 253 26 253 253 253 79 253 253 94 253 47
-        30 253 253 126 253 81 253 253 253 253 253 253 100 253 253
-        63 45 125 253 253 253 253 0 109 122 253 80 253 253 51 91
-        253 253 253 253 253 94 253 85 95 253 253 253 253 253 126
-        253 111 253 63 253 94 253 83 46 253 253 253 253 253 253 91
-        117 15 253 253 253 122 253 253 58 253 253 253 111 253 253
-        253 127 253 39 253 85 253 253 17 88 116 253 253 253 253 253
-        253 253 253 87 253 253 16 77 109 253 105 105 76 253 253 253
-        253 94 253 253 253 87 253 0 50 253 0 253 88 71 253 10 253
-        122 253 64 253 253 253 253 253 253 85 253 0 106 253 94 253
-        125 253 35 47 253 58 105 99 253 68 253 0 253 253 87 253 253
-        253 63 253 253 13 10 45 45 45 45 45 45 87 101 98 75 105 116
-        70 111 114 109 66 111 117 110 100 97 114 121 115 105 103
-        113 43 53 113 87 116 54 79 114 122 56 76 79 45 45 13 10
-    } >string ;
+[ t ] [ dog-test-empty-bytes-firefox test-file1 ] unit-test
+[ t ] [ dog-test-empty-bytes-firefox test-file2 ] unit-test
+[ t ] [ dog-test-empty-bytes-firefox test-file3 ] unit-test
 
+[ t ] [ dog-test-empty-bytes-safari test-file1 ] unit-test
+[ t ] [ dog-test-empty-bytes-safari test-file2 ] unit-test
+[ t ] [ dog-test-empty-bytes-safari test-file3 ] unit-test
index 4c7b95699e6eb9e22a8b1e3abd621f41cce4b2ed..3e44f163ed1a635c0b5f89c6cb9c772b6544e3d4 100644 (file)
@@ -1,7 +1,9 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators io kernel locals math multiline
-sequences splitting prettyprint ;
+sequences splitting prettyprint namespaces http.parsers
+ascii assocs unicode.case io.files.unique io.files io.encodings.binary
+byte-arrays io.encodings make fry ;
 IN: mime.multipart
 
 TUPLE: multipart-stream stream n leftover separator ;
@@ -27,37 +29,77 @@ TUPLE: multipart-stream stream n leftover separator ;
 : multipart-split ( bytes separator -- before after seq=? )
     2dup sequence= [ 2drop f f t ] [ split1 f ] if ;
 
-:: multipart-step-found ( bytes stream quot -- ? )
-    bytes [
-        quot unless-empty
-    ] [
-        stream (>>leftover)
-        quot unless-empty
-    ] if-empty f quot call f ;
+:: multipart-step-found ( bytes stream quot: ( bytes -- ) -- ? )
+    bytes [ quot unless-empty ]
+    [ stream (>>leftover) quot unless-empty ] if-empty f ; inline
 
-:: multipart-step-not-found ( stream end-stream? separator quot -- ? )
-    end-stream? [
+:: multipart-step-not-found ( bytes stream end-stream? separator quot: ( bytes -- ) -- ? )
+    bytes end-stream? [
         quot unless-empty f
     ] [
         separator length 1- ?cut* stream (>>leftover)
         quot unless-empty t
-    ] if ;
+    ] if ; inline
 
 :: multipart-step ( stream bytes end-stream? separator quot: ( bytes -- ) -- ? end-stream? )
     #! return t to loop again
     bytes separator multipart-split
-    [ 2drop f quot call f ]
+    [ 2drop f ]
     [
         [ stream quot multipart-step-found ]
         [ stream end-stream? separator quot multipart-step-not-found ] if*
-    ] if stream leftover>> end-stream? not or ;
+    ] if stream leftover>> end-stream? not or >boolean ;
 
-PRIVATE>
 
-:: multipart-step-loop ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ? )
+:: multipart-step-loop ( stream quot1: ( bytes -- ) -- ? )
     stream dup [ read-n ] [ separator>> ] bi quot1 multipart-step
-    swap [ drop stream quot1 quot2 multipart-step-loop ] quot2 if ;
+    swap [ drop stream quot1 multipart-step-loop ] when ; inline recursive
+
+SYMBOL: header
+SYMBOL: parsed-header
+SYMBOL: magic-separator
+
+: trim-blanks ( str -- str' ) [ blank? ] trim ;
+
+: trim-quotes ( str -- str' )
+    [ [ CHAR: " = ] [ CHAR: ' = ] bi or ] trim ;
+
+: parse-content-disposition ( str -- content-disposition hash )
+    ";" split [ first ] [ rest-slice ] bi [ "=" split ] map
+    [ [ trim-blanks ] [ trim-quotes ] bi* ] H{ } assoc-map-as ;
+
+: parse-multipart-header ( string -- headers )
+    "\r\n" split harvest
+    [ parse-header-line first2 ] H{ } map>assoc ;
 
-: multipart-loop-all ( stream quot1: ( bytes -- ) quot2: ( -- ) -- )
-    3dup multipart-step-loop
-    [ multipart-loop-all ] [ 3drop ] if ;
+ERROR: expected-file ;
+
+TUPLE: uploaded-file path filename name ;
+
+: (parse-multipart) ( stream -- ? )
+    "\r\n\r\n" >>separator
+    header off
+    dup [ header [ prepend ] change ] multipart-step-loop drop
+    header get dup magic-separator get [ length ] bi@ < [
+        2drop f
+    ] [
+        parse-multipart-header
+        parsed-header set
+        "\r\n" magic-separator get append >>separator
+        "factor-upload" "httpd" make-unique-file tuck
+        binary [ [ write ] multipart-step-loop ] with-file-writer swap
+        "content-disposition" parsed-header get at parse-content-disposition
+        nip [ "filename" swap at ] [ "name" swap at ] bi
+        uploaded-file boa ,
+    ] if ;
+
+PRIVATE>
+
+: parse-multipart ( stream -- array )
+    [
+        "\r\n" <multipart-stream>
+        magic-separator off
+        dup [ magic-separator [ prepend ] change ]
+            multipart-step-loop drop
+        '[ [ _ (parse-multipart) ] loop ] { } make
+    ] with-scope ;
index caf6f39d5c95ba274abf6717edd5b3e1a6a07c22..90d6b594ffdfb62276545bea0ff8ef1fe8267230 100644 (file)
@@ -18,7 +18,7 @@ TUPLE: history < model back forward ;
 \r
 : go-back/forward ( history to from -- )\r
     [ 2drop ]\r
-    [ >r dupd (add-history) r> pop swap set-model ] if-empty ;\r
+    [ [ dupd (add-history) ] dip pop swap set-model ] if-empty ;\r
 \r
 : go-back ( history -- )\r
     dup [ forward>> ] [ back>> ] bi go-back/forward ;\r
index 45519f70219d6fa697c18db825cd60b111924cf6..5da564b9d08fed793d59b8761504c7c3cbd1985e 100644 (file)
@@ -91,7 +91,7 @@ M: model update-model drop ;
     ] if ;
 
 : ((change-model)) ( model quot -- newvalue model )
-    over >r >r value>> r> call r> ; inline
+    over [ [ value>> ] dip call ] dip ; inline
 
 : change-model ( model quot -- )
     ((change-model)) set-model ; inline
index 8e230a2d0c1a22874236e65d0ab5a19500f22ae4..53d99ab1620bc6251444493eb65bef055a20ce49 100644 (file)
@@ -6,7 +6,7 @@ IN: models.range
 \r
 TUPLE: range < compose ;\r
 \r
-: <range> ( value min max page -- range )\r
+: <range> ( value page min max -- range )\r
     4array [ <model> ] map range new-compose ;\r
 \r
 : range-model ( range -- model ) dependencies>> first ;\r
index ecbe9e668f14f852fcc83a1ea63279924058e21f..64d4b1a041ef0aebf1fc4fdc5e16579845690665 100644 (file)
@@ -28,7 +28,7 @@ PRIVATE>
 : (parse-multiline-string) ( start-index end-text -- end-index )
     lexer get line-text>> [
         2dup start
-        [ rot dupd >r >r swap subseq % r> r> length + ] [
+        [ rot dupd [ swap subseq % ] 2dip length + ] [
             rot tail % "\n" % 0
             lexer get next-line swap (parse-multiline-string)
         ] if*
diff --git a/basis/nibble-arrays/nibble-arrays-tests.factor b/basis/nibble-arrays/nibble-arrays-tests.factor
new file mode 100644 (file)
index 0000000..2a0eef7
--- /dev/null
@@ -0,0 +1,6 @@
+USING: nibble-arrays tools.test sequences kernel math ;
+IN: nibble-arrays.tests
+
+[ t ] [ 16 dup >nibble-array sequence= ] unit-test
+[ N{ 4 2 1 3 } ] [ N{ 3 1 2 4 } reverse ] unit-test
+[ N{ 1 4 9 0 9 4 } ] [ N{ 1 2 3 4 5 6 } [ sq ] map ] unit-test
diff --git a/basis/nibble-arrays/nibble-arrays.factor b/basis/nibble-arrays/nibble-arrays.factor
new file mode 100644 (file)
index 0000000..c753d0f
--- /dev/null
@@ -0,0 +1,71 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math kernel sequences sequences.private byte-arrays
+alien.c-types prettyprint.backend parser accessors ;
+IN: nibble-arrays
+
+TUPLE: nibble-array
+{ length array-capacity read-only }
+{ underlying byte-array read-only } ;
+
+<PRIVATE
+
+: nibble BIN: 1111 ; inline
+
+: nibbles>bytes 1 + 2/ ; inline
+
+: byte/nibble ( n -- shift n' )
+    [ 1 bitand 2 shift ] [ -1 shift ] bi ; inline
+
+: get-nibble ( n byte -- nibble )
+    swap neg shift nibble bitand ; inline
+
+: set-nibble ( value n byte -- byte' )
+    nibble pick shift bitnot bitand -rot shift bitor ; inline
+
+: nibble@ ( n nibble-array -- shift n' byte-array )
+    [ >fixnum byte/nibble ] [ underlying>> ] bi* ; inline
+
+PRIVATE>
+
+: <nibble-array> ( n -- nibble-array )
+    dup nibbles>bytes <byte-array> nibble-array boa ; inline
+
+M: nibble-array length length>> ;
+
+M: nibble-array nth-unsafe
+    nibble@ nth-unsafe get-nibble ;
+
+M: nibble-array set-nth-unsafe
+    nibble@ [ nth-unsafe set-nibble ] 2keep set-nth-unsafe ;
+
+M: nibble-array clone
+    [ length>> ] [ underlying>> clone ] bi nibble-array boa ;
+
+: >nibble-array ( seq -- nibble-array )
+    T{ nibble-array } clone-like ; inline
+
+M: nibble-array like
+    drop dup nibble-array? [ >nibble-array ] unless ;
+
+M: nibble-array new-sequence drop <nibble-array> ;
+
+M: nibble-array equal?
+    over nibble-array? [ sequence= ] [ 2drop f ] if ;
+
+M: nibble-array resize
+    [ drop ] [
+        [ nibbles>bytes ] [ underlying>> ] bi*
+        resize-byte-array
+    ] 2bi
+    nibble-array boa ;
+
+M: nibble-array byte-length length nibbles>bytes ;
+
+: N{ \ } [ >nibble-array ] parse-literal ; parsing
+
+INSTANCE: nibble-array sequence
+
+M: nibble-array pprint-delims drop \ N{ \ } ;
+M: nibble-array >pprint-sequence ;
+M: nibble-array pprint* pprint-object ;
index fd547c8b5a3d3f9ae377b3efdd987423d2a4905d..ea37829d0ee13537cbf78a8993b602a4cfe2546e 100644 (file)
@@ -1,6 +1,6 @@
-USING: alien alien.syntax combinators kernel parser sequences
-system words namespaces hashtables init math arrays assocs
-continuations lexer ;
+USING: alien alien.syntax alien.parser combinators
+kernel parser sequences system words namespaces hashtables init
+math arrays assocs continuations lexer fry locals ;
 IN: opengl.gl.extensions
 
 ERROR: unknown-gl-platform ;
@@ -30,12 +30,23 @@ reset-gl-function-number-counter
 : gl-function-pointer ( names n -- funptr )
     gl-function-context 2array dup +gl-function-pointers+ get-global at
     [ 2nip ] [
-        >r [ gl-function-address ] map [ ] find nip
-        dup [ "OpenGL function not available" throw ] unless
-        dup r>
+        [
+            [ gl-function-address ] map [ ] find nip
+            dup [ "OpenGL function not available" throw ] unless
+            dup
+        ] dip
         +gl-function-pointers+ get-global set-at
     ] if* ;
 
+: indirect-quot ( function-ptr-quot return types abi -- quot )
+    '[ @  _ _ _ alien-indirect ] ;
+
+:: define-indirect ( abi return function-ptr-quot function-name parameters -- )
+    function-name create-in dup reset-generic
+    function-ptr-quot return
+    parameters return parse-arglist [ abi indirect-quot ] dip
+    define-declared ;
+
 : GL-FUNCTION:
     gl-function-calling-convention
     scan
index ecb4c4a08ccaef179c298ec184189a0a2e31d91d..10f9c57a838129b54e34012f34b452a35f6b36fb 100644 (file)
@@ -6,7 +6,8 @@ USING: alien alien.c-types continuations kernel libc math macros
 namespaces math.vectors math.constants math.functions
 math.parser opengl.gl opengl.glu combinators arrays sequences
 splitting words byte-arrays assocs colors accessors
-generalizations locals memoize ;
+generalizations locals specialized-arrays.float
+specialized-arrays.uint ;
 IN: opengl
 
 : color>raw ( object -- r g b a )
@@ -42,47 +43,51 @@ IN: opengl
     [ glDisableClientState ] each ; inline
 
 MACRO: all-enabled ( seq quot -- )
-    >r words>values r> [ (all-enabled) ] 2curry ;
+    [ words>values ] dip [ (all-enabled) ] 2curry ;
 
 MACRO: all-enabled-client-state ( seq quot -- )
-    >r words>values r> [ (all-enabled-client-state) ] 2curry ;
+    [ words>values ] dip [ (all-enabled-client-state) ] 2curry ;
 
 : do-matrix ( mode quot -- )
     swap [ glMatrixMode glPushMatrix call ] keep
     glMatrixMode glPopMatrix ; inline
 
 : gl-material ( face pname params -- )
-    >c-float-array glMaterialfv ;
+    float-array{ } like underlying>> glMaterialfv ;
 
 : gl-vertex-pointer ( seq -- )
-    [ 2 GL_FLOAT 0 ] dip glVertexPointer ; inline
+    [ 2 GL_FLOAT 0 ] dip underlying>> glVertexPointer ; inline
 
 : gl-color-pointer ( seq -- )
-    [ 4 GL_FLOAT 0 ] dip glColorPointer ; inline
+    [ 4 GL_FLOAT 0 ] dip underlying>> glColorPointer ; inline
 
 : gl-texture-coord-pointer ( seq -- )
-    [ 2 GL_FLOAT 0 ] dip glTexCoordPointer ; inline
+    [ 2 GL_FLOAT 0 ] dip underlying>> glTexCoordPointer ; inline
 
 : line-vertices ( a b -- )
-    [ first2 [ 0.5 + ] bi@ ] bi@ 4 narray
-    >c-float-array gl-vertex-pointer ;
+    [ first2 [ 0.5 + ] bi@ ] bi@ 4 float-array{ } nsequence
+    gl-vertex-pointer ;
 
 : gl-line ( a b -- )
     line-vertices GL_LINES 0 2 glDrawArrays ;
 
 : (rect-vertices) ( dim -- vertices )
+    #! We use GL_LINE_STRIP with a duplicated first vertex
+    #! instead of GL_LINE_LOOP to work around a bug in Apple's
+    #! X3100 driver.
     {
         [ drop 0.5 0.5 ]
         [ first 0.3 - 0.5 ]
         [ [ first 0.3 - ] [ second 0.3 - ] bi ]
         [ second 0.3 - 0.5 swap ]
-    } cleave 8 narray >c-float-array ;
+        [ drop 0.5 0.5 ]
+    } cleave 10 float-array{ } nsequence ;
 
 : rect-vertices ( dim -- )
     (rect-vertices) gl-vertex-pointer ;
 
 : (gl-rect) ( -- )
-    GL_LINE_LOOP 0 4 glDrawArrays ;
+    GL_LINE_STRIP 0 5 glDrawArrays ;
 
 : gl-rect ( dim -- )
     rect-vertices (gl-rect) ;
@@ -93,7 +98,7 @@ MACRO: all-enabled-client-state ( seq quot -- )
         [ first 0 ]
         [ first2 ]
         [ second 0 swap ]
-    } cleave 8 narray >c-float-array ;
+    } cleave 8 float-array{ } nsequence ;
 
 : fill-rect-vertices ( dim -- )
     (fill-rect-vertices) gl-vertex-pointer ;
@@ -119,11 +124,20 @@ MACRO: all-enabled-client-state ( seq quot -- )
 : circle-points ( loc dim steps -- points )
     circle-steps unit-circle adjust-points scale-points ;
 
+: close-path ( points -- points' )
+    dup first suffix ;
+
 : circle-vertices ( loc dim steps -- vertices )
-    circle-points concat >c-float-array ;
+    #! We use GL_LINE_STRIP with a duplicated first vertex
+    #! instead of GL_LINE_LOOP to work around a bug in Apple's
+    #! X3100 driver.
+    circle-points close-path concat >float-array ;
+
+: fill-circle-vertices ( loc dim steps -- vertices )
+    circle-points concat >float-array ;
 
 : (gen-gl-object) ( quot -- id )
-    >r 1 0 <uint> r> keep *uint ; inline
+    [ 1 0 <uint> ] dip keep *uint ; inline
 
 : gen-texture ( -- id )
     [ glGenTextures ] (gen-gl-object) ;
@@ -132,7 +146,7 @@ MACRO: all-enabled-client-state ( seq quot -- )
     [ glGenBuffers ] (gen-gl-object) ;
 
 : (delete-gl-object) ( id quot -- )
-    >r 1 swap <uint> r> call ; inline
+    [ 1 swap <uint> ] dip call ; inline
 
 : delete-texture ( id -- )
     [ glDeleteTextures ] (delete-gl-object) ;
@@ -151,7 +165,7 @@ MACRO: all-enabled-client-state ( seq quot -- )
 
 : <gl-buffer> ( target data hint -- id )
     pick gen-gl-buffer [ [
-        >r dup byte-length swap r> glBufferData
+        [ dup byte-length swap ] dip glBufferData
     ] with-gl-buffer ] keep ;
 
 : buffer-offset ( int -- alien )
@@ -161,7 +175,7 @@ MACRO: all-enabled-client-state ( seq quot -- )
     glActiveTexture swap glBindTexture gl-error ;
 
 : (set-draw-buffers) ( buffers -- )
-    dup length swap >c-uint-array glDrawBuffers ;
+    [ length ] [ >uint-array underlying>> ] bi glDrawBuffers ;
 
 MACRO: set-draw-buffers ( buffers -- )
     words>values [ (set-draw-buffers) ] curry ;
@@ -185,9 +199,11 @@ TUPLE: sprite loc dim dim2 dlist texture ;
     gen-texture [
         GL_TEXTURE_BIT [
             GL_TEXTURE_2D swap glBindTexture
-            >r >r GL_TEXTURE_2D 0 GL_RGBA r>
-            sprite-size2 0 GL_LUMINANCE_ALPHA
-            GL_UNSIGNED_BYTE r> glTexImage2D
+            [
+                [ GL_TEXTURE_2D 0 GL_RGBA ] dip
+                sprite-size2 0 GL_LUMINANCE_ALPHA
+                GL_UNSIGNED_BYTE
+            ] dip glTexImage2D
         ] do-attribs
     ] keep ;
     
@@ -204,11 +220,8 @@ TUPLE: sprite loc dim dim2 dlist texture ;
 
 : gl-translate ( point -- ) first2 0.0 glTranslated ;
 
-MEMO: (rect-texture-coords) ( -- seq )
-    { 0 0 1 0 1 1 0 1 } >c-float-array ;
-
 : rect-texture-coords ( -- )
-    (rect-texture-coords) gl-texture-coord-pointer ;
+    float-array{ 0 0 1 0 1 1 0 1 } gl-texture-coord-pointer ;
 
 : draw-sprite ( sprite -- )
     GL_TEXTURE_COORD_ARRAY [
@@ -239,7 +252,7 @@ MEMO: (rect-texture-coords) ( -- seq )
     [ nip [ free-sprite ] when* ] assoc-each ;
 
 : with-translation ( loc quot -- )
-    GL_MODELVIEW [ >r gl-translate r> call ] do-matrix ; inline
+    GL_MODELVIEW [ [ gl-translate ] dip call ] do-matrix ; inline
 
 : fix-coordinates ( point1 point2 -- x1 y2 x2 y2 )
     [ first2 [ >fixnum ] bi@ ] bi@ ;
index f1dc21f99376e47d628cc0d30ecef0731400826d..30501a61056979e1b3938acf6f4a094e4e62c170 100644 (file)
@@ -234,13 +234,13 @@ FUNCTION: void SSL_CTX_set_tmp_rsa_callback ( SSL_CTX* ctx, void* rsa ) ;
 FUNCTION: void* BIO_f_ssl (  ) ;
 
 : SSL_CTX_set_tmp_rsa ( ctx rsa -- n )
-    >r SSL_CTRL_SET_TMP_RSA 0 r> SSL_CTX_ctrl ;
+    [ SSL_CTRL_SET_TMP_RSA 0 ] dip SSL_CTX_ctrl ;
 
 : SSL_CTX_set_tmp_dh ( ctx dh -- n )
-    >r SSL_CTRL_SET_TMP_DH 0 r> SSL_CTX_ctrl ;
+    [ SSL_CTRL_SET_TMP_DH 0 ] dip SSL_CTX_ctrl ;
 
 : SSL_CTX_set_session_cache_mode ( ctx mode -- n )
-    >r SSL_CTRL_SET_SESS_CACHE_MODE r> f SSL_CTX_ctrl ;
+    [ SSL_CTRL_SET_SESS_CACHE_MODE ] dip f SSL_CTX_ctrl ;
 
 : SSL_SESS_CACHE_OFF                      HEX: 0000 ; inline
 : SSL_SESS_CACHE_CLIENT                   HEX: 0001 ; inline
index af1b4aec047c6db6a2f7e28d48df9bc8d6f9dabd..7434ca6a7a21873c4bd13ee01736edb2108ce0a2 100644 (file)
@@ -24,7 +24,7 @@ M: just-parser (compile) ( parser -- quot )
 : 1token ( ch -- parser ) 1string token ;
 
 : (list-of) ( items separator repeat1? -- parser )
-  >r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
+  [ over 2seq ] dip [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
   [ unclip 1vector swap first append ] action ;
 
 : list-of ( items separator -- parser )
@@ -60,11 +60,11 @@ PRIVATE>
   [ flatten-vectors ] action ;
 
 : from-m-to-n ( parser m n -- parser' )
-  >r [ exactly-n ] 2keep r> swap - at-most-n 2seq
+  [ [ exactly-n ] 2keep ] dip swap - at-most-n 2seq
   [ flatten-vectors ] action ;
 
 : pack ( begin body end -- parser )
-  >r >r hide r> r> hide 3seq [ first ] action ;
+  [ hide ] 2dip hide 3seq [ first ] action ;
 
 : surrounded-by ( parser begin end -- parser' )
   [ token ] bi@ swapd pack ;
index 2dabf1edf789221520b6fd53422384699ab6b6a0..8a62365f533ef68e1c2183a278a2af0e8a802853 100644 (file)
@@ -4,8 +4,7 @@ USING: kernel sequences strings fry namespaces make math assocs
 debugger io vectors arrays math.parser math.order
 vectors combinators classes sets unicode.categories
 compiler.units parser words quotations effects memoize accessors
-locals effects splitting combinators.short-circuit
-combinators.short-circuit.smart generalizations ;
+locals effects splitting combinators.short-circuit generalizations ;
 IN: peg
 
 USE: prettyprint
@@ -146,8 +145,8 @@ TUPLE: peg-head rule-id involved-set eval-set ;
   pos set dup involved-set>> clone >>eval-set drop ;
 
 : (grow-lr) ( h p r: ( -- result ) m -- )
-  >r >r [ setup-growth ] 2keep r> r>
-  >r dup eval-rule r> swap
+  [ [ setup-growth ] 2keep ] 2dip
+  [ dup eval-rule ] dip swap
   dup pick stop-growth? [
     5 ndrop
   ] [
@@ -156,8 +155,8 @@ TUPLE: peg-head rule-id involved-set eval-set ;
   ] if ; inline recursive
  
 : grow-lr ( h p r m -- ast )
-  >r >r [ heads set-at ] 2keep r> r>
-  pick over >r >r (grow-lr) r> r>
+  [ [ heads set-at ] 2keep ] 2dip
+  pick over [ (grow-lr) ] 2dip
   swap heads delete-at
   dup pos>> pos set ans>>
   ; inline
@@ -278,7 +277,8 @@ GENERIC: (compile) ( peg -- quot )
 : parser-body ( parser -- quot )
   #! Return the body of the word that is the compiled version
   #! of the parser.
-  gensym 2dup swap peg>> (compile) 0 1 <effect> define-declared swap dupd id>> "peg-id" set-word-prop
+  gensym 2dup swap peg>> (compile) (( -- result )) define-declared
+  swap dupd id>> "peg-id" set-word-prop
   [ execute-parser ] curry ;
 
 : preset-parser-word ( parser -- parser word )
@@ -306,7 +306,7 @@ SYMBOL: delayed
   #! Work through all delayed parsers and recompile their
   #! words to have the correct bodies.
   delayed get [
-    call compile-parser 1quotation 0 1 <effect> define-declared
+    call compile-parser 1quotation (( -- result )) define-declared
   ] assoc-each ;
 
 : compile ( parser -- word )
@@ -352,7 +352,7 @@ TUPLE: token-parser symbol ;
   [ ?head-slice ] keep swap [
     <parse-result> f f add-error
   ] [
-    >r drop pos get "token '" r> append "'" append 1vector add-error f
+    [ drop pos get "token '" ] dip append "'" append 1vector add-error f
   ] if ;
 
 M: token-parser (compile) ( peg -- quot )
@@ -421,7 +421,7 @@ M: seq-parser (compile) ( peg -- quot )
     [
       parsers>> unclip compile-parser 1quotation [ parse-seq-element ] curry ,
       [ compile-parser 1quotation [ merge-errors ] compose [ parse-seq-element ] curry , ] each 
-    ] { } make , \ && , 
+    ] { } make , \ 1&& , 
   ] [ ] make ;
 
 TUPLE: choice-parser parsers ;
@@ -431,7 +431,7 @@ M: choice-parser (compile) ( peg -- quot )
     [
       parsers>> [ compile-parser ] map 
       unclip 1quotation , [ 1quotation [ merge-errors ] compose , ] each
-    ] { } make , \ || ,
+    ] { } make , \ 0|| ,
   ] [ ] make ;
 
 TUPLE: repeat0-parser p1 ;
index bda772317310078748abad7f7efd18b4802edef1..0428235c2a104aba50bc71807201bdfb7c33c057 100644 (file)
@@ -8,6 +8,6 @@ ARTICLE: "present" "Converting objects to human-readable strings"
 HELP: present
 { $values { "object" object } { "string" string } }
 { $contract "Outputs a human-readable string from an object." }
-{ $notes "New methods can be defined by user code. Most often, this is done so that the object can be used with various words in the " { $vocab-link "html.components" } " or " { $link "urls" } " vocabularies." } ;
+{ $notes "New methods can be defined by user code. Most often, this is done so that the object can be used with various words in the " { $vocab-link "html.components" } " or " { $vocab-link "urls" } " vocabularies." } ;
 
 ABOUT: "present"
index f1fd749666db5903e2b0e7f17dda1efc209d08ca..7a5b16a3c2d999329438b585525adfa715e0ff09 100644 (file)
@@ -21,9 +21,6 @@ M: effect pprint* effect>string "(" swap ")" 3append text ;
 : ?end-group ( word -- )
     ?effect-height 0 < [ end-group ] when ;
 
-\ >r hard "break-before" set-word-prop
-\ r> hard "break-after" set-word-prop
-
 ! Atoms
 : word-style ( word -- style )
     dup "word-style" word-prop >hashtable [
@@ -93,7 +90,7 @@ M: f pprint* drop \ f pprint-word ;
     ] H{ } make-assoc ;
 
 : unparse-string ( str prefix suffix -- str )
-    [ >r % do-string-limit [ unparse-ch ] each r> % ] "" make ;
+    [ [ % do-string-limit [ unparse-ch ] each ] dip % ] "" make ;
 
 : pprint-string ( obj str prefix suffix -- )
     unparse-string swap string-style styled-text ;
@@ -156,13 +153,13 @@ M: tuple pprint*
 : do-length-limit ( seq -- trimmed n/f )
     length-limit get dup [
         over length over [-]
-        dup zero? [ 2drop f ] [ >r head r> ] if
+        dup zero? [ 2drop f ] [ [ head ] dip ] if
     ] when ;
 
 : pprint-elements ( seq -- )
-    do-length-limit >r
-    [ pprint* ] each
-    r> [ "~" swap number>string " more~" 3append text ] when* ;
+    do-length-limit
+    [ [ pprint* ] each ] dip
+    [ "~" swap number>string " more~" 3append text ] when* ;
 
 GENERIC: pprint-delims ( obj -- start end )
 
@@ -206,10 +203,12 @@ M: tuple pprint-narrow? drop t ;
 : pprint-object ( obj -- )
     [
         <flow
-        dup pprint-delims >r pprint-word
-        dup pprint-narrow? <inset
-        >pprint-sequence pprint-elements
-        block> r> pprint-word block>
+        dup pprint-delims [
+            pprint-word
+            dup pprint-narrow? <inset
+            >pprint-sequence pprint-elements
+            block>
+        ] dip pprint-word block>
     ] check-recursion ;
 
 M: object pprint* pprint-object ;
index 96698fc18f5778969912aa2d1ce7f307b307bd38..648c7079677ac0dbbd45972ef30e893ce0ceac55 100644 (file)
@@ -135,20 +135,6 @@ M: object method-layout ;
     [ \ method-layout see-methods ] with-string-writer "\n" split
 ] unit-test
 
-: retain-stack-test
-    {
-        "USING: io kernel sequences words ;"
-        "IN: prettyprint.tests"
-        ": retain-stack-layout ( x -- )"
-        "    dup stream-readln stream-readln"
-        "    >r [ define ] map r>"
-        "    define ;"
-    } ;
-
-[ t ] [
-    "retain-stack-layout" retain-stack-test check-see
-] unit-test
-
 : soft-break-test
     {
         "USING: kernel math sequences strings ;"
@@ -164,19 +150,6 @@ M: object method-layout ;
     "soft-break-layout" soft-break-test check-see
 ] unit-test
 
-: another-retain-layout-test
-    {
-        "USING: kernel sequences ;"
-        "IN: prettyprint.tests"
-        ": another-retain-layout ( seq1 seq2 quot -- newseq )"
-        "    -rot 2dup dupd min-length [ each drop roll ] map"
-        "    >r 3drop r> ; inline"
-    } ;
-
-[ t ] [
-    "another-retain-layout" another-retain-layout-test check-see
-] unit-test
-
 DEFER: parse-error-file
 
 : another-soft-break-test
@@ -219,8 +192,7 @@ DEFER: parse-error-file
         "USING: kernel sequences ;"
         "IN: prettyprint.tests"
         ": final-soft-break-layout ( class dim -- view )"
-        "    >r \"alloc\" send 0 0 r>"
-        "    first2 <NSRect>"
+        "    [ \"alloc\" send 0 0 ] dip first2 <NSRect>"
         "    <PixelFormat> \"initWithFrame:pixelFormat:\" send"
         "    dup 1 \"setPostsBoundsChangedNotifications:\" send"
         "    dup 1 \"setPostsFrameChangedNotifications:\" send ;"
index 6dd7175db8c220436893a72c27f613d0e5ea6088..7c4de1e973764081efc51b1f15cb6d23e88085f8 100644 (file)
@@ -129,7 +129,7 @@ SYMBOL: ->
 : remove-breakpoints ( quot pos -- quot' )
     over quotation? [
         1+ cut [ (remove-breakpoints) ] bi@
-        [ -> ] swap 3append
+        [ -> ] glue 
     ] [
         drop
     ] if ;
@@ -370,9 +370,12 @@ M: word see
 : (see-methods) ( generic -- seq )
     "methods" word-prop values natural-sort ;
 
-: see-methods ( word -- )
+: methods ( word -- seq )
     [
         dup class? [ dup (see-implementors) % ] when
         dup generic? [ dup (see-methods) % ] when
         drop
-    ] { } make prune see-all ;
+    ] { } make prune ;
+
+: see-methods ( word -- )
+    methods see-all ;
index a629ca6fff2ff40efef57bd5ee56564a043e9269..102d005f39e498682386f5d31a20db27b605b12c 100644 (file)
@@ -42,7 +42,7 @@ TUPLE: pprinter last-newline line-count indent ;
 
 : text-fits? ( len -- ? )
     margin get dup zero?
-    [ 2drop t ] [ >r pprinter get indent>> + r> <= ] if ;
+    [ 2drop t ] [ [ pprinter get indent>> + ] dip <= ] if ;
 
 ! break only if position margin 2 / >
 SYMBOL: soft
@@ -189,7 +189,7 @@ M: block short-section ( block -- )
 : empty-block? ( block -- ? ) sections>> empty? ;
 
 : if-nonempty ( block quot -- )
-    >r dup empty-block? [ drop ] r> if ; inline
+    [ dup empty-block? [ drop ] ] dip if ; inline
 
 : (<block) ( block -- ) pprinter-stack get push ;
 
index 067d221d2fc571e5703d4d88549a3b639d286287..828d811b468cf80959d1155d64da2272376414fc 100644 (file)
@@ -4,14 +4,21 @@ IN: qualified
 HELP: QUALIFIED:
 { $syntax "QUALIFIED: vocab" }
 { $description "Similar to " { $link POSTPONE: USE: } " but loads vocabulary with prefix." }
-{ $examples { $code
-    "QUALIFIED: math\n1 2 math:+ ! ==> 3" } } ;
+{ $examples { $example
+    "USING: prettyprint qualified ;"
+    "QUALIFIED: math"
+    "1 2 math:+ ." "3"
+} } ;
 
 HELP: QUALIFIED-WITH:
 { $syntax "QUALIFIED-WITH: vocab word-prefix" }
 { $description "Works like " { $link POSTPONE: QUALIFIED: } " but uses " { $snippet "word-prefix" } " as prefix." }
 { $examples { $code
-    "QUALIFIED-WITH: math m\n1 2 m:+ ! ==> 3" } } ;
+    "USING: prettyprint qualified ;"
+    "QUALIFIED-WITH: math m"
+    "1 2 m:+ ."
+    "3"
+} } ;
 
 HELP: FROM:
 { $syntax "FROM: vocab => words ... ;" }
@@ -28,9 +35,12 @@ HELP: EXCLUDE:
 HELP: RENAME:
 { $syntax "RENAME: word vocab => newname " }
 { $description "Imports " { $snippet "word" } " from " { $snippet "vocab" } ", but renamed to " { $snippet "newname" } "." }
-{ $examples { $code
+{ $examples { $example
+    "USING: prettyprint qualified ;"
     "RENAME: + math => -"
-    "2 3 - ! => 5" } } ;
+    "2 3 - ."
+    "5"
+} } ;
 
 ARTICLE: "qualified" "Qualified word lookup"
 "The " { $vocab-link "qualified" } " vocabulary provides a handful of parsing words which give more control over word lookup than is offered by " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } "."
index c31d338fac84672c5a5467666790b3b183a4987e..67b0fa23e78f8d99d1bb241fc13b8bdb27abb99e 100644 (file)
@@ -2,49 +2,49 @@
 ! See http://factorcode.org/license.txt for BSD license.
 ! mersenne twister based on 
 ! http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
-USING: arrays kernel math namespaces sequences system init
-accessors math.ranges random circular math.bitwise
-combinators ;
+USING: kernel math namespaces sequences sequences.private system
+init accessors math.ranges random math.bitwise combinators
+specialized-arrays.uint fry ;
 IN: random.mersenne-twister
 
 <PRIVATE
 
-TUPLE: mersenne-twister seq i ;
+TUPLE: mersenne-twister { seq uint-array } { i fixnum } ;
 
-: mt-n 624 ; inline
-: mt-m 397 ; inline
-: mt-a HEX: 9908b0df ; inline
+: n 624 ; inline
+: m 397 ; inline
+: a uint-array{ 0 HEX: 9908b0df } ; inline
 
-: calculate-y ( n seq -- y )
-    [ nth 31 mask-bit ]
-    [ [ 1+ ] [ nth ] bi* 31 bits ] 2bi bitor ; inline
+: y ( n seq -- y )
+    [ nth-unsafe 31 mask-bit ]
+    [ [ 1+ ] [ nth-unsafe ] bi* 31 bits ] 2bi bitor ; inline
 
-: (mt-generate) ( n seq -- next-mt )
+: mt[k] ( offset n seq -- )
     [
-        calculate-y
-        [ 2/ ] [ odd? mt-a 0 ? ] bi bitxor
-    ] [
-        [ mt-m + ] [ nth ] bi*
-    ] 2bi bitxor ;
+        [ [ + ] dip nth-unsafe ]
+        [ y [ 2/ ] [ 1 bitand a nth ] bi bitxor ] 2bi
+        bitxor
+    ] 2keep set-nth-unsafe ; inline
 
 : mt-generate ( mt -- )
     [
-        mt-n swap seq>> [
-            [ (mt-generate) ] [ set-nth ] 2bi
-        ] curry each
-    ] [ 0 >>i drop ] bi ;
+        seq>>
+        [ [ n m - ] dip '[ [ m ] dip _ mt[k] ] each ]
+        [ [ m 1- ] dip '[ [ m n - ] [ n m - + ] bi* _ mt[k] ] each ]
+        bi
+    ] [ 0 >>i drop ] bi ; inline
 
 : init-mt-formula ( i seq -- f(seq[i]) )
-    dupd nth dup -30 shift bitxor 1812433253 * + 1+ 32 bits ;
+    dupd nth dup -30 shift bitxor 1812433253 * + 1+ 32 bits ; inline
 
 : init-mt-rest ( seq -- )
-    mt-n 1- swap [
-        [ init-mt-formula ] [ >r 1+ r> set-nth ] 2bi
-    ] curry each ;
+    n 1- swap '[
+        _ [ init-mt-formula ] [ [ 1+ ] dip set-nth ] 2bi
+    ] each ; inline
 
 : init-mt-seq ( seed -- seq )
-    32 bits mt-n 0 <array> <circular>
-    [ set-first ] [ init-mt-rest ] [ ] tri ;
+    32 bits n <uint-array>
+    [ set-first ] [ init-mt-rest ] [ ] tri ; inline
 
 : mt-temper ( y -- yt )
     dup -11 shift bitxor
@@ -53,7 +53,7 @@ TUPLE: mersenne-twister seq i ;
     dup -18 shift bitxor ; inline
 
 : next-index  ( mt -- i )
-    dup i>> dup mt-n < [ nip ] [ drop mt-generate 0 ] if ;
+    dup i>> dup n < [ nip ] [ drop mt-generate 0 ] if ; inline
 
 PRIVATE>
 
@@ -66,7 +66,7 @@ M: mersenne-twister seed-random ( mt seed -- )
 
 M: mersenne-twister random-32* ( mt -- r )
     [ next-index ]
-    [ seq>> nth mt-temper ]
+    [ seq>> nth-unsafe mt-temper ]
     [ [ 1+ ] change-i drop ] tri ;
 
 USE: init
index 75a010b70529d791ed87314fed128f7672bda2fb..5eff0579c8202dcf95cd0c890c9a0ca3b4e2b622 100644 (file)
@@ -1,16 +1,17 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors hashtables kernel math state-tables vectors ;
+USING: accessors hashtables kernel math vectors ;
 IN: regexp.backend
 
 TUPLE: regexp
     raw
-    { stack vector }
-    parse-tree
     { options hashtable }
+    stack
+    parse-tree
     nfa-table
     dfa-table
     minimized-table
+    matchers
     { nfa-traversal-flags hashtable }
     { dfa-traversal-flags hashtable }
     { state integer }
index 7b729b2e5088b3e9f01f32d0692a99f59c1dd947..eec0d309b15e93ac526c7d3a90ba9f1cffbca5ad 100644 (file)
@@ -1,12 +1,26 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel math math.order symbols regexp.parser
+USING: accessors kernel math math.order symbols 
 words regexp.utils unicode.categories combinators.short-circuit ;
 IN: regexp.classes
 
+SINGLETONS: any-char any-char-no-nl
+letter-class LETTER-class Letter-class digit-class
+alpha-class non-newline-blank-class
+ascii-class punctuation-class java-printable-class blank-class
+control-character-class hex-digit-class java-blank-class c-identifier-class
+unmatchable-class terminator-class word-boundary-class ;
+
+SINGLETONS: beginning-of-input beginning-of-line
+end-of-input end-of-line ;
+
+MIXIN: node
+TUPLE: character-class-range from to ; INSTANCE: character-class-range node
+
 GENERIC: class-member? ( obj class -- ? )
 
-M: word class-member? ( obj class -- ? ) 2drop f ;
+M: t class-member? ( obj class -- ? ) 2drop f ;
+
 M: integer class-member? ( obj class -- ? ) 2drop f ;
 
 M: character-class-range class-member? ( obj class -- ? )
@@ -17,7 +31,7 @@ M: any-char class-member? ( obj class -- ? )
 
 M: any-char-no-nl class-member? ( obj class -- ? )
     drop CHAR: \n = not ;
-    
+
 M: letter-class class-member? ( obj class -- ? )
     drop letter? ;
             
@@ -60,3 +74,18 @@ M: java-blank-class class-member? ( obj class -- ? )
 
 M: unmatchable-class class-member? ( obj class -- ? )
     2drop f ;
+
+M: terminator-class class-member? ( obj class -- ? )
+    drop {
+        [ CHAR: \r = ]
+        [ CHAR: \n = ]
+        [ CHAR: \u000085 = ]
+        [ CHAR: \u002028 = ]
+        [ CHAR: \u002029 = ]
+    } 1|| ;
+
+M: beginning-of-line class-member? ( obj class -- ? )
+    2drop f ;
+
+M: end-of-line class-member? ( obj class -- ? )
+    2drop f ;
index ef985258fd2cc66706d4a39402ebedc9a1c09c3f..0abd1c2edc5dc243c27c6634c686df9518495e7e 100644 (file)
@@ -43,7 +43,8 @@ IN: regexp.dfa
         dupd pop dup pick find-transitions rot
         [
             [ [ find-closure ] 2keep nip dupd add-todo-state ] 3keep
-            >r swapd transition make-transition r> dfa-table>> add-transition 
+            [ swapd transition make-transition ] dip
+            dfa-table>> add-transition 
         ] curry with each
         new-transitions
     ] if-empty ;
index 72d0fe970bdcb3abe5e4def0311de81319b847b1..76206529487107df89bc84bd75d26c8fc480cd3e 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs grouping kernel regexp.backend
-locals math namespaces regexp.parser sequences state-tables fry
-quotations math.order math.ranges vectors unicode.categories
-regexp.utils regexp.transition-tables words sets ;
+locals math namespaces regexp.parser sequences fry quotations
+math.order math.ranges vectors unicode.categories regexp.utils
+regexp.transition-tables words sets regexp.classes unicode.case ;
 IN: regexp.nfa
 
 SYMBOL: negation-mode
@@ -18,6 +18,17 @@ SINGLETON: lookbehind-on INSTANCE: lookbehind-on traversal-flag
 SINGLETON: lookbehind-off INSTANCE: lookbehind-off traversal-flag
 SINGLETON: capture-group-on INSTANCE: capture-group-on traversal-flag
 SINGLETON: capture-group-off INSTANCE: capture-group-off traversal-flag
+SINGLETON: front-anchor INSTANCE: front-anchor traversal-flag
+SINGLETON: back-anchor INSTANCE: back-anchor traversal-flag
+SINGLETON: word-boundary INSTANCE: word-boundary traversal-flag
+
+: options ( -- obj ) current-regexp get options>> ;
+
+: option? ( obj -- ? ) options key? ;
+
+: option-on ( obj -- ) options conjoin ;
+
+: option-off ( obj -- ) options delete-at ;
 
 : next-state ( regexp -- state )
     [ state>> ] [ [ 1+ ] change-state drop ] bi ;
@@ -100,6 +111,7 @@ M: kleene-star nfa-node ( node -- )
 
 M: concatenation nfa-node ( node -- )
     seq>>
+    reversed-regexp option? [ <reversed> ] when
     [ [ nfa-node ] each ]
     [ length 1- [ concatenate-nodes ] times ] bi ;
 
@@ -109,16 +121,59 @@ M: alternation nfa-node ( node -- )
     [ length 1- [ alternate-nodes ] times ] bi ;
 
 M: constant nfa-node ( node -- )
-    char>> literal-transition add-simple-entry ;
+    case-insensitive option? [
+        dup char>> [ ch>lower ] [ ch>upper ] bi
+        2dup = [
+            2drop
+            char>> literal-transition add-simple-entry
+        ] [
+            [ literal-transition add-simple-entry ] bi@
+            alternate-nodes drop
+        ] if
+    ] [
+        char>> literal-transition add-simple-entry
+    ] if ;
 
 M: epsilon nfa-node ( node -- )
     drop eps literal-transition add-simple-entry ;
 
-M: word nfa-node ( node -- )
+M: word nfa-node ( node -- ) class-transition add-simple-entry ;
+
+M: any-char nfa-node ( node -- )
+    [ dotall option? ] dip any-char-no-nl ?
     class-transition add-simple-entry ;
 
+! M: beginning-of-text nfa-node ( node -- ) ;
+
+M: beginning-of-line nfa-node ( node -- ) class-transition add-simple-entry ;
+
+M: end-of-line nfa-node ( node -- ) class-transition add-simple-entry ;
+
+: choose-letter-class ( node -- node' )
+    case-insensitive option? Letter-class rot ? ;
+
+M: letter-class nfa-node ( node -- )
+    choose-letter-class class-transition add-simple-entry ;
+
+M: LETTER-class nfa-node ( node -- )
+    choose-letter-class class-transition add-simple-entry ;
+
 M: character-class-range nfa-node ( node -- )
-    class-transition add-simple-entry ;
+    case-insensitive option? [
+        dup [ from>> ] [ to>> ] bi
+        2dup [ Letter? ] bi@ and [
+            rot drop
+            [ [ ch>lower ] bi@ character-class-range boa ]
+            [ [ ch>upper ] bi@ character-class-range boa ] 2bi 
+            [ class-transition add-simple-entry ] bi@
+            alternate-nodes
+        ] [
+            2drop
+            class-transition add-simple-entry
+        ] if
+    ] [
+        class-transition add-simple-entry
+    ] if ;
 
 M: capture-group nfa-node ( node -- )
     eps literal-transition add-simple-entry
@@ -135,8 +190,6 @@ M: non-capture-group nfa-node ( node -- )
 M: reluctant-kleene-star nfa-node ( node -- )
     term>> <kleene-star> nfa-node ;
 
-!
-
 M: negation nfa-node ( node -- )
     negation-mode inc
     term>> nfa-node 
@@ -158,6 +211,10 @@ M: lookbehind nfa-node ( node -- )
     lookbehind-off add-traversal-flag
     2 [ concatenate-nodes ] times ;
 
+M: option nfa-node ( node -- )
+    [ option>> ] [ on?>> ] bi [ option-on ] [ option-off ] if
+    eps literal-transition add-simple-entry ;
+
 : construct-nfa ( regexp -- )
     [
         reset-regexp
index 0f25b2e3bf701fa3785f7e677825d3e8011b9ca5..fe4d2f1d1a877d141c679519b22a8eb4e58df88e 100644 (file)
@@ -19,8 +19,8 @@ IN: regexp.parser
 [ ] [ "(?:a)" test-regexp ] unit-test
 [ ] [ "(?i:a)" test-regexp ] unit-test
 [ ] [ "(?-i:a)" test-regexp ] unit-test
-[ "(?z:a)" test-regexp ] [ bad-option? ] must-fail-with
-[ "(?-z:a)" test-regexp ] [ bad-option? ] must-fail-with
+[ "(?z:a)" test-regexp ] [ unknown-regexp-option? ] must-fail-with
+[ "(?-z:a)" test-regexp ] [ unknown-regexp-option? ] must-fail-with
 
 [ ] [ "(?=a)" test-regexp ] unit-test
 
index 7f1d92a1ab91baace3f7dcb967c245d3898f544a..4d8f3ddfbc7e29c96a7e20880a9b7d63b88a566d 100644 (file)
@@ -4,12 +4,11 @@ USING: accessors arrays assocs combinators io io.streams.string
 kernel math math.parser namespaces qualified sets
 quotations sequences splitting symbols vectors math.order
 unicode.categories strings regexp.backend regexp.utils
-unicode.case words ;
+unicode.case words locals regexp.classes ;
 IN: regexp.parser
 
 FROM: math.ranges => [a,b] ;
 
-MIXIN: node
 TUPLE: concatenation seq ; INSTANCE: concatenation node
 TUPLE: alternation seq ; INSTANCE: alternation node
 TUPLE: kleene-star term ; INSTANCE: kleene-star node
@@ -40,35 +39,31 @@ INSTANCE: independent-group parentheses-group
 TUPLE: comment-group term ; INSTANCE: comment-group node
 INSTANCE: comment-group parentheses-group
 
-TUPLE: character-class-range from to ; INSTANCE: character-class-range node
 SINGLETON: epsilon INSTANCE: epsilon node
-SINGLETON: any-char INSTANCE: any-char node
-SINGLETON: any-char-no-nl INSTANCE: any-char-no-nl node
-SINGLETON: front-anchor INSTANCE: front-anchor node
-SINGLETON: back-anchor INSTANCE: back-anchor node
-
-TUPLE: option-on option ; INSTANCE: option-on node
-TUPLE: option-off option ; INSTANCE: option-off node
-SINGLETONS: unix-lines dotall multiline comments case-insensitive unicode-case reversed-regexp ;
-
-SINGLETONS: letter-class LETTER-class Letter-class digit-class
-alpha-class non-newline-blank-class
-ascii-class punctuation-class java-printable-class blank-class
-control-character-class hex-digit-class java-blank-class c-identifier-class
-unmatchable-class ;
-
-SINGLETONS: beginning-of-group end-of-group
-beginning-of-character-class end-of-character-class
+
+TUPLE: option option on? ; INSTANCE: option node
+
+SINGLETONS: unix-lines dotall multiline comments case-insensitive
+unicode-case reversed-regexp ;
+
+SINGLETONS: beginning-of-character-class end-of-character-class
 left-parenthesis pipe caret dash ;
 
-: get-option ( option -- ? ) current-regexp get options>> at ;
-: get-unix-lines ( -- ? ) unix-lines get-option ;
-: get-dotall ( -- ? ) dotall get-option ;
-: get-multiline ( -- ? ) multiline get-option ;
-: get-comments ( -- ? ) comments get-option ;
-: get-case-insensitive ( -- ? ) case-insensitive get-option ;
-: get-unicode-case ( -- ? ) unicode-case get-option ;
-: get-reversed-regexp ( -- ? ) reversed-regexp get-option ;
+: push1 ( obj -- ) input-stream get stream>> push ;
+: peek1 ( -- obj ) input-stream get stream>> [ f ] [ peek ] if-empty ;
+: pop3 ( seq -- obj1 obj2 obj3 ) [ pop ] [ pop ] [ pop ] tri spin ;
+: drop1 ( -- ) read1 drop ;
+
+: stack ( -- obj ) current-regexp get stack>> ;
+: change-whole-stack ( quot -- )
+    current-regexp get
+    [ stack>> swap call ] keep (>>stack) ; inline
+: push-stack ( obj -- ) stack push ;
+: pop-stack ( -- obj ) stack pop ;
+: cut-out ( vector n -- vector' vector ) cut rest ;
+ERROR: cut-stack-error ;
+: cut-stack ( obj vector -- vector' vector )
+    tuck last-index [ cut-stack-error ] unless* cut-out swap ;
 
 : <possessive-kleene-star> ( obj -- kleene ) possessive-kleene-star boa ;
 : <reluctant-kleene-star> ( obj -- kleene ) reluctant-kleene-star boa ;
@@ -77,18 +72,11 @@ left-parenthesis pipe caret dash ;
 
 : <negation> ( obj -- negation ) negation boa ;
 : <concatenation> ( seq -- concatenation )
-    >vector get-reversed-regexp [ reverse ] when
-    [ epsilon ] [ concatenation boa ] if-empty ;
+    >vector [ epsilon ] [ concatenation boa ] if-empty ;
 : <alternation> ( seq -- alternation ) >vector alternation boa ;
 : <capture-group> ( obj -- capture-group ) capture-group boa ;
 : <kleene-star> ( obj -- kleene-star ) kleene-star boa ;
-: <constant> ( obj -- constant )
-    dup Letter? get-case-insensitive and [
-        [ ch>lower constant boa ]
-        [ ch>upper constant boa ] bi 2array <alternation>
-    ] [
-        constant boa
-    ] if ;
+: <constant> ( obj -- constant ) constant boa ;
 
 : first|concatenation ( seq -- first/concatenation )
     dup length 1 = [ first ] [ <concatenation> ] if ;
@@ -97,21 +85,14 @@ left-parenthesis pipe caret dash ;
     dup length 1 = [ first ] [ <alternation> ] if ;
 
 : <character-class-range> ( from to -- obj )
-    2dup [ Letter? ] bi@ or get-case-insensitive and [
-        [ [ ch>lower ] bi@ character-class-range boa ]
-        [ [ ch>upper ] bi@ character-class-range boa ] 2bi
-        2array [ [ from>> ] [ to>> ] bi < ] filter
-        [ unmatchable-class ] [ first|alternation ] if-empty
-    ] [
-        2dup <
-        [ character-class-range boa ] [ 2drop unmatchable-class ] if
-    ] if ;
+    2dup <
+    [ character-class-range boa ] [ 2drop unmatchable-class ] if ;
 
 ERROR: unmatched-parentheses ;
 
-ERROR: bad-option ch ;
+ERROR: unknown-regexp-option option ;
 
-: option ( ch -- singleton )
+: ch>option ( ch -- singleton )
     {
         { CHAR: i [ case-insensitive ] }
         { CHAR: d [ unix-lines ] }
@@ -121,13 +102,21 @@ ERROR: bad-option ch ;
         { CHAR: s [ dotall ] }
         { CHAR: u [ unicode-case ] }
         { CHAR: x [ comments ] }
-        [ bad-option ]
+        [ unknown-regexp-option ]
+    } case ;
+
+: option>ch ( option -- string )
+    {
+        { case-insensitive [ CHAR: i ] }
+        { multiline [ CHAR: m ] }
+        { reversed-regexp [ CHAR: r ] }
+        { dotall [ CHAR: s ] }
+        [ unknown-regexp-option ]
     } case ;
 
-: option-on ( option -- ) current-regexp get options>> conjoin ;
-: option-off ( option -- ) current-regexp get options>> delete-at ;
+: toggle-option ( ch ? -- ) 
+    [ ch>option ] dip option boa push-stack ;
 
-: toggle-option ( ch ? -- ) [ option ] dip [ option-on ] [ option-off ] if ;
 : (parse-options) ( string ? -- ) [ toggle-option ] curry each ;
 
 : parse-options ( string -- )
@@ -173,7 +162,7 @@ DEFER: (parse-regexp)
     [ drop1 (parse-special-group) ]
     [ capture-group f nested-parse-regexp ] if ;
 
-: handle-dot ( -- ) get-dotall any-char any-char-no-nl ? push-stack ;
+: handle-dot ( -- ) any-char push-stack ;
 : handle-pipe ( -- ) pipe push-stack ;
 : (handle-star) ( obj -- kleene-star )
     peek1 {
@@ -225,31 +214,14 @@ ERROR: invalid-range a b ;
 
 : handle-left-brace ( -- )
     parse-repetition
-    >r 2dup [ [ 0 < [ invalid-range ] when ] when* ] bi@ r>
+    [ 2dup [ [ 0 < [ invalid-range ] when ] when* ] bi@ ] dip
     [
         2dup and [ from-m-to-n ]
         [ [ nip at-most-n ] [ at-least-n ] if* ] if
     ] [ drop 0 max exactly-n ] if ;
 
-SINGLETON: beginning-of-input
-SINGLETON: end-of-input
-
-: newlines ( -- obj1 obj2 obj3 )
-    CHAR: \r <constant>
-    CHAR: \n <constant>
-    2dup 2array <concatenation> ;
-
-: beginning-of-line ( -- obj )
-    beginning-of-input newlines 4array <alternation> lookbehind boa ;
-
-: end-of-line ( -- obj )
-    end-of-input newlines 4array <alternation> lookahead boa ;
-
-: handle-front-anchor ( -- )
-    get-multiline beginning-of-line beginning-of-input ? push-stack ;
-
-: handle-back-anchor ( -- )
-    get-multiline end-of-line end-of-input ? push-stack ;
+: handle-front-anchor ( -- ) beginning-of-line push-stack ;
+: handle-back-anchor ( -- ) end-of-line push-stack ;
 
 ERROR: bad-character-class obj ;
 ERROR: expected-posix-class ;
@@ -258,8 +230,8 @@ ERROR: expected-posix-class ;
     read1 CHAR: { = [ expected-posix-class ] unless
     "}" read-until [ bad-character-class ] unless
     {
-        { "Lower" [ get-case-insensitive Letter-class letter-class ? ] }
-        { "Upper" [ get-case-insensitive Letter-class LETTER-class ? ] }
+        { "Lower" [ letter-class ] }
+        { "Upper" [ LETTER-class ] }
         { "Alpha" [ Letter-class ] }
         { "ASCII" [ ascii-class ] }
         { "Digit" [ digit-class ] }
@@ -281,13 +253,26 @@ ERROR: expected-posix-class ;
 : parse-control-character ( -- n ) read1 ;
 
 ERROR: bad-escaped-literals seq ;
-: parse-escaped-literals ( -- obj )
-    "\\E" read-until [ bad-escaped-literals ] unless
+
+: parse-til-E ( -- obj )
+    "\\E" read-until [ bad-escaped-literals ] unless ;
+    
+:: (parse-escaped-literals) ( quot: ( obj -- obj' ) -- obj )
+    parse-til-E
     drop1
     [ epsilon ] [
-        [ <constant> ] V{ } map-as
+        [ quot call <constant> ] V{ } map-as
         first|concatenation
-    ] if-empty ;
+    ] if-empty ; inline
+
+: parse-escaped-literals ( -- obj )
+    [ ] (parse-escaped-literals) ;
+
+: lower-case-literals ( -- obj )
+    [ ch>lower ] (parse-escaped-literals) ;
+
+: upper-case-literals ( -- obj )
+    [ ch>upper ] (parse-escaped-literals) ;
 
 : parse-escaped ( -- obj )
     read1
@@ -299,12 +284,12 @@ ERROR: bad-escaped-literals seq ;
         { CHAR: a [ HEX: 7 <constant> ] }
         { CHAR: e [ HEX: 1b <constant> ] }
 
-        { CHAR: d [ digit-class ] }
-        { CHAR: D [ digit-class <negation> ] }
-        { CHAR: s [ java-blank-class ] }
-        { CHAR: S [ java-blank-class <negation> ] }
         { CHAR: w [ c-identifier-class ] }
         { CHAR: W [ c-identifier-class <negation> ] }
+        { CHAR: s [ java-blank-class ] }
+        { CHAR: S [ java-blank-class <negation> ] }
+        { CHAR: d [ digit-class ] }
+        { CHAR: D [ digit-class <negation> ] }
 
         { CHAR: p [ parse-posix-class ] }
         { CHAR: P [ parse-posix-class <negation> ] }
@@ -313,13 +298,19 @@ ERROR: bad-escaped-literals seq ;
         { CHAR: 0 [ parse-octal <constant> ] }
         { CHAR: c [ parse-control-character ] }
 
-        ! { CHAR: b [ handle-word-boundary ] }
-        ! { CHAR: B [ handle-word-boundary <negation> ] }
+        { CHAR: Q [ parse-escaped-literals ] }
+
+        ! { CHAR: b [ word-boundary-class ] }
+        ! { CHAR: B [ word-boundary-class <negation> ] }
         ! { CHAR: A [ handle-beginning-of-input ] }
+        ! { CHAR: z [ handle-end-of-input ] }
+
+        ! { CHAR: Z [ handle-end-of-input ] } ! plus a final terminator
+
+        ! m//g mode
         ! { CHAR: G [ end of previous match ] }
-        ! { CHAR: Z [ handle-end-of-input ] }
-        ! { CHAR: z [ handle-end-of-input ] } ! except for terminator
 
+        ! Group capture
         ! { CHAR: 1 [ CHAR: 1 <constant> ] }
         ! { CHAR: 2 [ CHAR: 2 <constant> ] }
         ! { CHAR: 3 [ CHAR: 3 <constant> ] }
@@ -330,7 +321,11 @@ ERROR: bad-escaped-literals seq ;
         ! { CHAR: 8 [ CHAR: 8 <constant> ] }
         ! { CHAR: 9 [ CHAR: 9 <constant> ] }
 
-        { CHAR: Q [ parse-escaped-literals ] }
+        ! Perl extensions
+        ! can't do \l and \u because \u is already a 4-hex
+        { CHAR: L [ lower-case-literals ] }
+        { CHAR: U [ upper-case-literals ] }
+
         [ <constant> ]
     } case ;
 
@@ -372,20 +367,22 @@ DEFER: handle-left-bracket
     } case
     [ (parse-character-class) ] when ;
 
+: push-constant ( ch -- ) <constant> push-stack ;
+
 : parse-character-class-second ( -- )
     read1 {
-        { CHAR: [ [ CHAR: [ <constant> push-stack ] }
-        { CHAR: ] [ CHAR: ] <constant> push-stack ] }
-        { CHAR: - [ CHAR: - <constant> push-stack ] }
+        { CHAR: [ [ CHAR: [ push-constant ] }
+        { CHAR: ] [ CHAR: ] push-constant ] }
+        { CHAR: - [ CHAR: - push-constant ] }
         [ push1 ]
     } case ;
 
 : parse-character-class-first ( -- )
     read1 {
         { CHAR: ^ [ caret push-stack parse-character-class-second ] }
-        { CHAR: [ [ CHAR: [ <constant> push-stack ] }
-        { CHAR: ] [ CHAR: ] <constant> push-stack ] }
-        { CHAR: - [ CHAR: - <constant> push-stack ] }
+        { CHAR: [ [ CHAR: [ push-constant ] }
+        { CHAR: ] [ CHAR: ] push-constant ] }
+        { CHAR: - [ CHAR: - push-constant ] }
         [ push1 ]
     } case ;
 
@@ -398,7 +395,8 @@ DEFER: handle-left-bracket
     [ first|concatenation ] map first|alternation ;
 
 : handle-right-parenthesis ( -- )
-    stack dup [ parentheses-group "members" word-prop member? ] find-last -rot cut rest
+    stack dup [ parentheses-group "members" word-prop member? ] find-last
+    -rot cut rest
     [ [ push ] keep current-regexp get (>>stack) ]
     [ finish-regexp-parse push-stack ] bi* ;
 
@@ -415,12 +413,9 @@ DEFER: handle-left-bracket
         { CHAR: [ [ handle-left-bracket t ] }
         { CHAR: \ [ handle-escape t ] }
         [
-            dup CHAR: $ = peek1 f = and [
-                drop
-                handle-back-anchor f
-            ] [
-                <constant> push-stack t
-            ] if
+            dup CHAR: $ = peek1 f = and
+            [ drop handle-back-anchor f ]
+            [ push-constant t ] if
         ]
     } case ;
 
@@ -437,7 +432,6 @@ DEFER: handle-left-bracket
                 parse-regexp-beginning (parse-regexp)
             ] with-input-stream
         ] unless-empty
-        current-regexp get
-        stack finish-regexp-parse
-            >>parse-tree drop
+        current-regexp get [ finish-regexp-parse ] change-stack
+        dup stack>> >>parse-tree drop
     ] with-variable ;
index f6a1fe18765adeb9f539a1f67d1d23ddd8b5987a..378ae503ce7257ce331f1b412a1b05121b2c6d1f 100644 (file)
@@ -6,9 +6,3 @@ IN: regexp
 HELP: <regexp>
 { $values { "string" string } { "regexp" regexp } }
 { $description "Compiles a regular expression into a DFA and returns this object.  Regular expressions only have to be compiled once and can then be used multiple times to match input strings." } ;
-
-HELP: <iregexp>
-{ $values { "string" string } { "regexp" regexp } }
-{ $description "Compiles a case-insensitive regular expression into a DFA and returns this object.  Otherwise, exactly the same as " { $link <regexp> } } ;
-
-{ <regexp> <iregexp> } related-words
index 777d0985e4c34e50ae570d9dc7ea829e2717bf58..74f06ed65be1ef7daa9ba96058dbc1db088b033c 100644 (file)
@@ -45,6 +45,7 @@ IN: regexp-tests
 ! Off by default.
 [ f ] [ "\n" "." <regexp> matches? ] unit-test
 [ t ] [ "\n" "(?s)." <regexp> matches? ] unit-test
+[ t ] [ "\n" R/ ./s matches? ] unit-test
 [ f ] [ "\n\n" "(?s).(?-s)." <regexp> matches? ] unit-test
 
 [ f ] [ "" ".+" <regexp> matches? ] unit-test
@@ -210,34 +211,34 @@ IN: regexp-tests
 [ 3 ] [ "aaacb" "a*" <regexp> match-head ] unit-test
 [ 2 ] [ "aaacb" "aa?" <regexp> match-head ] unit-test
 
-[ t ] [ "aaa" "AAA" <iregexp> matches? ] unit-test
-[ f ] [ "aax" "AAA" <iregexp> matches? ] unit-test
-[ t ] [ "aaa" "A*" <iregexp> matches? ] unit-test
-[ f ] [ "aaba" "A*" <iregexp> matches? ] unit-test
-[ t ] [ "b" "[AB]" <iregexp> matches? ] unit-test
-[ f ] [ "c" "[AB]" <iregexp> matches? ] unit-test
-[ t ] [ "c" "[A-Z]" <iregexp> matches? ] unit-test
-[ f ] [ "3" "[A-Z]" <iregexp> matches? ] unit-test
+[ t ] [ "aaa" R/ AAA/i matches? ] unit-test
+[ f ] [ "aax" R/ AAA/i matches? ] unit-test
+[ t ] [ "aaa" R/ A*/i matches? ] unit-test
+[ f ] [ "aaba" R/ A*/i matches? ] unit-test
+[ t ] [ "b" R/ [AB]/i matches? ] unit-test
+[ f ] [ "c" R/ [AB]/i matches? ] unit-test
+[ t ] [ "c" R/ [A-Z]/i matches? ] unit-test
+[ f ] [ "3" R/ [A-Z]/i matches? ] unit-test
 
 [ t ] [ "a" "(?i)a" <regexp> matches? ] unit-test
 [ t ] [ "a" "(?i)a" <regexp> matches? ] unit-test
 [ t ] [ "A" "(?i)a" <regexp> matches? ] unit-test
 [ t ] [ "A" "(?i)a" <regexp> matches? ] unit-test
 
-[ t ] [ "a" "(?-i)a" <iregexp> matches? ] unit-test
-[ t ] [ "a" "(?-i)a" <iregexp> matches? ] unit-test
-[ f ] [ "A" "(?-i)a" <iregexp> matches? ] unit-test
-[ f ] [ "A" "(?-i)a" <iregexp> matches? ] unit-test
+[ t ] [ "a" R/ (?-i)a/i matches? ] unit-test
+[ t ] [ "a" R/ (?-i)a/i matches? ] unit-test
+[ f ] [ "A" R/ (?-i)a/i matches? ] unit-test
+[ f ] [ "A" R/ (?-i)a/i matches? ] unit-test
 
 [ f ] [ "A" "[a-z]" <regexp> matches? ] unit-test
-[ t ] [ "A" "[a-z]" <iregexp> matches? ] unit-test
+[ t ] [ "A" R/ [a-z]/i matches? ] unit-test
 
 [ f ] [ "A" "\\p{Lower}" <regexp> matches? ] unit-test
-[ t ] [ "A" "\\p{Lower}" <iregexp> matches? ] unit-test
+[ t ] [ "A" R/ \p{Lower}/i matches? ] unit-test
 
-[ t ] [ "abc" <reversed> "abc" <rregexp> matches? ] unit-test
-[ t ] [ "abc" <reversed> "a[bB][cC]" <rregexp> matches? ] unit-test
-[ t ] [ "adcbe" "a(?r)(bcd)(?-r)e" <rregexp> matches? ] unit-test
+[ t ] [ "abc" <reversed> R/ abc/r matches? ] unit-test
+[ t ] [ "abc" <reversed> R/ a[bB][cC]/r matches? ] unit-test
+[ t ] [ "adcbe" R/ a(?r)(bcd)(?-r)e/ matches? ] unit-test
 
 [ t ] [ "s@f" "[a-z.-]@[a-z]" <regexp> matches? ] unit-test
 [ f ] [ "a" "[a-z.-]@[a-z]" <regexp> matches? ] unit-test
@@ -253,7 +254,7 @@ IN: regexp-tests
 
 [ ] [ "(\\$[\\p{XDigit}]|[\\p{Digit}])" <regexp> drop ] unit-test
 
-! Comment
+! Comment inside a regular expression
 [ t ] [ "ac" "a(?#boo)c" <regexp> matches? ] unit-test
 
 [ ] [ "USING: regexp kernel ; R' -{3}[+]{1,6}(?:!!)?\\s' drop" eval ] unit-test
@@ -270,9 +271,9 @@ IN: regexp-tests
 
 [ "b" ] [ "aaaaaaaaaaaaaaaaaaaaaaab" "((a*)*b)*b" <regexp> first-match >string ] unit-test
 
-[ t ] [ "a:b" ".+:?" <regexp> matches? ] unit-test
+[ t ] [ "a:b" ".+:?" <regexp> matches? ] unit-test
 
-[ 1 ] [ "hello" ".+?" <regexp> match length ] unit-test
+[ 1 ] [ "hello" ".+?" <regexp> match length ] unit-test
 
 [ { "1" "2" "3" "4" } ]
 [ "1ABC2DEF3GHI4" R/ [A-Z]+/ re-split [ >string ] map ] unit-test
@@ -283,32 +284,95 @@ IN: regexp-tests
 [ { "ABC" "DEF" "GHI" } ]
 [ "1ABC2DEF3GHI4" R/ [A-Z]+/ all-matches [ >string ] map ] unit-test
 
+[ 3 ]
+[ "1ABC2DEF3GHI4" R/ [A-Z]+/ count-matches ] unit-test
+
+[ 0 ]
+[ "123" R/ [A-Z]+/ count-matches ] unit-test
+
 [ "1.2.3.4" ]
 [ "1ABC2DEF3GHI4JK" R/ [A-Z]+/ "." re-replace ] unit-test
 
 [ f ] [ "ab" "a(?!b)" <regexp> first-match ] unit-test
+[ "a" ] [ "ac" "a(?!b)" <regexp> first-match >string ] unit-test
+! [ t ] [ "fxxbar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
+[ f ] [ "foobar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
 [ "a" ] [ "ab" "a(?=b)(?=b)" <regexp> first-match >string ] unit-test
 [ "a" ] [ "ba" "a(?<=b)(?<=b)" <regexp> first-match >string ] unit-test
 [ "a" ] [ "cab" "a(?=b)(?<=c)" <regexp> first-match >string ] unit-test
 
+[ 3 ] [ "foobar" "foo(?=bar)" <regexp> match-head ] unit-test
+[ f ] [ "foobxr" "foo(?=bar)" <regexp> match-head ] unit-test
+
+! Bug in parsing word
+[ t ] [ "a" R' a' matches?  ] unit-test
+
+! Convert to lowercase until E
+[ f ] [ "AA" R/ \LAA\E/ matches? ] unit-test
+[ t ] [ "aa" R/ \LAA\E/ matches? ] unit-test
+
+! Convert to uppercase until E
+[ t ] [ "AA" R/ \Uaa\E/ matches? ] unit-test
+[ f ] [ "aa" R/ \Uaa\E/ matches? ] unit-test
+
 ! [ "{Lower}" <regexp> ] [ invalid-range? ] must-fail-with
 
-! [ 1 ] [ "aaacb" "a+?" <regexp> match-head ] unit-test
-! [ 1 ] [ "aaacb" "aa??" <regexp> match-head ] unit-test
-! [ f ] [ "aaaab" "a++ab" <regexp> matches? ] unit-test
-! [ t ] [ "aaacb" "a++cb" <regexp> matches? ] unit-test
-! [ 3 ] [ "aacb" "aa?c" <regexp> match-head ] unit-test
-! [ 3 ] [ "aacb" "aa??c" <regexp> match-head ] unit-test
+! [ t ] [ "a" R/ ^a/ matches? ] unit-test
+! [ f ] [ "\na" R/ ^a/ matches? ] unit-test
+! [ f ] [ "\r\na" R/ ^a/ matches? ] unit-test
+! [ f ] [ "\ra" R/ ^a/ matches? ] unit-test
 
-! [ t ] [ "fxxbar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
-! [ f ] [ "foobar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
+! [ t ] [ "a" R/ a$/ matches? ] unit-test
+! [ f ] [ "a\n" R/ a$/ matches? ] unit-test
+! [ f ] [ "a\r" R/ a$/ matches? ] unit-test
+! [ f ] [ "a\r\n" R/ a$/ matches? ] unit-test
 
-[ 3 ] [ "foobar" "foo(?=bar)" <regexp> match-head ] unit-test
-[ f ] [ "foobxr" "foo(?=bar)" <regexp> match-head ] unit-test
+! [ t ] [ "a" R/ a$|b$/ matches? ] unit-test
+! [ t ] [ "b" R/ a$|b$/ matches? ] unit-test
+! [ t ] [ "ab" R/ a$|b$/ matches? ] unit-test
+! [ t ] [ "ba" R/ ba$|b$/ matches? ] unit-test
+
+! [ t ] [ "a" R/ \Aa/ matches? ] unit-test
+! [ f ] [ "\na" R/ \Aaa/ matches? ] unit-test
+! [ f ] [ "\r\na" R/ \Aa/ matches? ] unit-test
+! [ f ] [ "\ra" R/ \Aa/ matches? ] unit-test
+
+! [ t ] [ "a" R/ \Aa/m matches? ] unit-test
+! [ f ] [ "\na" R/ \Aaa/m matches? ] unit-test
+! [ f ] [ "\r\na" R/ \Aa/m matches? ] unit-test
+! [ f ] [ "\ra" R/ \Aa/m matches? ] unit-test
+
+! [ t ] [ "\r\n\n\n\nam" R/ ^am/m matches? ] unit-test
+
+! [ t ] [ "a" R/ \Aa\z/m matches? ] unit-test
+! [ f ] [ "a\n" R/ \Aa\z/m matches? ] unit-test
+
+! [ t ] [ "a\r\n" R/ \Aa\Z/m matches? ] unit-test
+! [ t ] [ "a\n" R/ \Aa\Z/m matches? ] unit-test
+
+! [ t ] [ "a" R/ \Aa\Z/m matches? ] unit-test
+! [ f ] [ "\na" R/ \Aaa\Z/m matches? ] unit-test
+! [ f ] [ "\r\na" R/ \Aa\Z/m matches? ] unit-test
+! [ f ] [ "\ra" R/ \Aa\Z/m matches? ] unit-test
+
+! [ t ] [ "a" R/ ^a/m matches? ] unit-test
+! [ t ] [ "\na" R/ ^a/m matches? ] unit-test
+! [ t ] [ "\r\na" R/ ^a/m matches? ] unit-test
+! [ t ] [ "\ra" R/ ^a/m matches? ] unit-test
+
+! [ t ] [ "a" "a$" R/ a$/m matches? ] unit-test
+! [ t ] [ "a\n" "a$" R/ a$/m matches? ] unit-test
+! [ t ] [ "a\r" "a$" R/ a$/m matches? ] unit-test
+! [ t ] [ "a\r\n" "a$" R/ a$/m matches? ] unit-test
 
 ! [ f ] [ "foobxr" "foo\\z" <regexp> match-head ] unit-test
 ! [ 3 ] [ "foo" "foo\\z" <regexp> match-head ] unit-test
 
+! [ t ] [ "foo" "\\bfoo\\b" <regexp> matches? ] unit-test
+! [ t ] [ "afoob" "\\Bfoo\\B" <regexp> matches? ] unit-test
+! [ t ] [ "afoob" "\\bfoo\\b" <regexp> matches? ] unit-test
+! [ f ] [ "foo" "\\Bfoo\\B" <regexp> matches? ] unit-test
+
 ! [ 3 ] [ "foo bar" "foo\\b" <regexp> match-head ] unit-test
 ! [ f ] [ "fooxbar" "foo\\b" <regexp> matches? ] unit-test
 ! [ t ] [ "foo" "foo\\b" <regexp> matches? ] unit-test
@@ -323,39 +387,29 @@ IN: regexp-tests
 ! [ t ] [ "fooxbar" "foo\\Bxbar" <regexp> matches? ] unit-test
 ! [ f ] [ "foo" "foo\\Bbar" <regexp> matches? ] unit-test
 
+! [ 1 ] [ "aaacb" "a+?" <regexp> match-head ] unit-test
+! [ 1 ] [ "aaacb" "aa??" <regexp> match-head ] unit-test
+! [ f ] [ "aaaab" "a++ab" <regexp> matches? ] unit-test
+! [ t ] [ "aaacb" "a++cb" <regexp> matches? ] unit-test
+! [ 3 ] [ "aacb" "aa?c" <regexp> match-head ] unit-test
+! [ 3 ] [ "aacb" "aa??c" <regexp> match-head ] unit-test
 
-! Bug in parsing word
-! [ t ] [ "a" R' a' matches?  ] unit-test
-
-! clear "a(?=b*)" <regexp> "ab" over match
-! clear "a(?=b*c)" <regexp> "abbbbbc" over match
-! clear "a(?=b*)" <regexp> "ab" over match
-
-! clear "^a" <regexp> "a" over match
-! clear "^a" <regexp> "\na" over match
-! clear "^a" <regexp> "\r\na" over match
-! clear "^a" <regexp> "\ra" over match
-
-! clear "a$" <regexp> "a" over match
-! clear "a$" <regexp> "a\n" over match
-! clear "a$" <regexp> "a\r" over match
-! clear "a$" <regexp> "a\r\n" over match
-
-! "(az)(?<=b)" <regexp> "baz" over first-match
-! "a(?<=b*)" <regexp> "cbaz" over first-match
-! "a(?<=b)" <regexp> "baz" over first-match
-
-! "a(?<!b)" <regexp> "baz" over first-match
-! "a(?<!b)" <regexp> "caz" over first-match
+! "ab" "a(?=b*)" <regexp> match
+! "abbbbbc" "a(?=b*c)" <regexp> match
+! "ab" "a(?=b*)" <regexp> match
 
-! "a(?=bcdefg)bcd" <regexp> "abcdefg" over first-match
-! "a(?#bcdefg)bcd" <regexp> "abcdefg" over first-match
-! "a(?:bcdefg)" <regexp> "abcdefg" over first-match
+! "baz" "(az)(?<=b)" <regexp> first-match
+! "cbaz" "a(?<=b*)" <regexp> first-match
+! "baz" "a(?<=b)" <regexp> first-match
 
-[ "a" ] [ "ac" "a(?!b)" <regexp> first-match >string ] unit-test
+! "baz" "a(?<!b)" <regexp> first-match
+! "caz" "a(?<!b)" <regexp> first-match
 
-! "a(?<=b)" <regexp> "caba" over first-match
+! "abcdefg" "a(?=bcdefg)bcd" <regexp> first-match
+! "abcdefg" "a(?#bcdefg)bcd" <regexp> first-match
+! "abcdefg" "a(?:bcdefg)" <regexp> first-match
 
+! "caba" "a(?<=b)" <regexp> first-match
 
 ! capture group 1: "aaaa"  2: ""
 ! "aaaa" "(a*)(a*)" <regexp> match*
index 66bc39415bc0a9ec4af8e820d087250283fe8168..b41e4d271e8f22d4074356240da8551231b0a0eb 100644 (file)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators kernel math sequences
+USING: accessors combinators kernel math sequences strings
 sets assocs prettyprint.backend make lexer namespaces parser
 arrays fry regexp.backend regexp.utils regexp.parser regexp.nfa
-regexp.dfa regexp.traversal regexp.transition-tables splitting ;
+regexp.dfa regexp.traversal regexp.transition-tables splitting
+sorting ;
 IN: regexp
 
 : default-regexp ( string -- regexp )
@@ -15,6 +16,7 @@ IN: regexp
         H{ } clone >>nfa-traversal-flags
         H{ } clone >>dfa-traversal-flags
         H{ } clone >>options
+        H{ } clone >>matchers
         reset-regexp ;
 
 : construct-regexp ( regexp -- regexp' )
@@ -73,30 +75,49 @@ IN: regexp
     [ dup ] swap '[ _ next-match ] [ ] produce nip harvest ;
 
 : count-matches ( string regexp -- n )
-    all-matches length 1- ;
+    all-matches length ;
 
-: initial-option ( regexp option -- regexp' )
-    over options>> conjoin ;
+<PRIVATE
 
-: <regexp> ( string -- regexp )
-    default-regexp construct-regexp ;
+: find-regexp-syntax ( string -- prefix suffix )
+    {
+        { "R/ "  "/"  }
+        { "R! "  "!"  }
+        { "R\" " "\"" }
+        { "R# "  "#"  }
+        { "R' "  "'"  }
+        { "R( "  ")"  }
+        { "R@ "  "@"  }
+        { "R[ "  "]"  }
+        { "R` "  "`"  }
+        { "R{ "  "}"  }
+        { "R| "  "|"  }
+    } swap [ subseq? not nip ] curry assoc-find drop ;
 
-: <iregexp> ( string -- regexp )
-    default-regexp
-    case-insensitive initial-option
-    construct-regexp ;
+: string>options ( string -- options )
+    [ ch>option dup ] H{ } map>assoc ;
+
+: options>string ( options -- string )
+    keys [ option>ch ] map natural-sort >string ;
 
-: <rregexp> ( string -- regexp )
-    default-regexp
-    reversed-regexp initial-option
+PRIVATE>
+
+: <optioned-regexp> ( string option-string -- regexp )
+    [ default-regexp ] [ string>options ] bi* >>options
     construct-regexp ;
 
+: <regexp> ( string -- regexp ) "" <optioned-regexp> ;
+
+<PRIVATE
+
 : parsing-regexp ( accum end -- accum )
     lexer get dup skip-blank
     [ [ index-from dup 1+ swap ] 2keep swapd subseq swap ] change-lexer-column
     lexer get dup still-parsing-line?
     [ (parse-token) ] [ drop f ] if
-    "i" = [ <iregexp> ] [ <regexp> ] if parsed ;
+    <optioned-regexp> parsed ;
+
+PRIVATE>
 
 : R! CHAR: ! parsing-regexp ; parsing
 : R" CHAR: " parsing-regexp ; parsing
@@ -110,29 +131,10 @@ IN: regexp
 : R{ CHAR: } parsing-regexp ; parsing
 : R| CHAR: | parsing-regexp ; parsing
 
-: find-regexp-syntax ( string -- prefix suffix )
-    {
-        { "R/ "  "/"  }
-        { "R! "  "!"  }
-        { "R\" " "\"" }
-        { "R# "  "#"  }
-        { "R' "  "'"  }
-        { "R( "  ")"  }
-        { "R@ "  "@"  }
-        { "R[ "  "]"  }
-        { "R` "  "`"  }
-        { "R{ "  "}"  }
-        { "R| "  "|"  }
-    } swap [ subseq? not nip ] curry assoc-find drop ;
-
-: option? ( option regexp -- ? )
-    options>> key? ;
-
 M: regexp pprint*
     [
         [
-            dup raw>>
-            dup find-regexp-syntax swap % swap % %
-            case-insensitive swap option? [ "i" % ] when
+            [ raw>> dup find-regexp-syntax swap % swap % % ]
+            [ options>> options>string % ] bi
         ] "" make
     ] keep present-text ;
index 1c9a3e3001ca359c848c1b985eb8a4de6834a7f3..5375d813e1bc719f3f9993674b5d93b7d3616db6 100644 (file)
@@ -20,8 +20,10 @@ TUPLE: default ;
 
 : <literal-transition> ( from to obj -- transition )
     literal-transition make-transition ;
+
 : <class-transition> ( from to obj -- transition )
     class-transition make-transition ;
+
 : <default-transition> ( from to -- transition )
     t default-transition make-transition ;
 
@@ -40,7 +42,7 @@ TUPLE: transition-table transitions start-state final-states ;
     2dup [ to>> ] dip maybe-initialize-key
     [ [ to>> ] [ obj>> ] [ from>> ] tri ] dip
     2dup at* [ 2nip insert-at ]
-    [ drop >r >r H{ } clone [ insert-at ] keep r> r> set-at ] if ;
+    [ drop [ H{ } clone [ insert-at ] keep ] 2dip set-at ] if ;
 
 : add-transition ( transition transition-table -- )
     transitions>> set-transition ;
index 86d315ee2fa5df58802d89ef2c1b850e0ab41696..d8c25eda18ffcea56cc2a0a759c7d48f20fb3747 100644 (file)
@@ -17,6 +17,7 @@ TUPLE: dfa-traverser
     capture-group-index
     last-state current-state
     text
+    match-failed?
     start-index current-index
     matches ;
 
@@ -37,14 +38,20 @@ TUPLE: dfa-traverser
         H{ } clone >>captured-groups ;
 
 : final-state? ( dfa-traverser -- ? )
-    [ current-state>> ] [ dfa-table>> final-states>> ] bi
-    key? ;
+    [ current-state>> ]
+    [ dfa-table>> final-states>> ] bi key? ;
+
+: beginning-of-text? ( dfa-traverser -- ? )
+    current-index>> 0 <= ; inline
+
+: end-of-text? ( dfa-traverser -- ? )
+    [ current-index>> ] [ text>> length ] bi >= ; inline
 
 : text-finished? ( dfa-traverser -- ? )
     {
         [ current-state>> empty? ]
-        [ [ current-index>> ] [ text>> length ] bi >= ]
-        ! [ current-index>> 0 < ]
+        [ end-of-text? ]
+        [ match-failed?>> ]
     } 1|| ;
 
 : save-final-state ( dfa-straverser -- )
@@ -55,8 +62,50 @@ TUPLE: dfa-traverser
         dup save-final-state
     ] when text-finished? ;
 
+: previous-text-character ( dfa-traverser -- ch )
+    [ text>> ] [ current-index>> 1- ] bi nth ;
+
+: current-text-character ( dfa-traverser -- ch )
+    [ text>> ] [ current-index>> ] bi nth ;
+
+: next-text-character ( dfa-traverser -- ch )
+    [ text>> ] [ current-index>> 1+ ] bi nth ;
+
 GENERIC: flag-action ( dfa-traverser flag -- )
 
+
+M: beginning-of-input flag-action ( dfa-traverser flag -- )
+    drop
+    dup beginning-of-text? [ t >>match-failed? ] unless drop ;
+
+M: end-of-input flag-action ( dfa-traverser flag -- )
+    drop
+    dup end-of-text? [ t >>match-failed? ] unless drop ;
+
+
+M: beginning-of-line flag-action ( dfa-traverser flag -- )
+    drop
+    dup {
+        [ beginning-of-text? ]
+        [ previous-text-character terminator-class class-member? ]
+    } 1|| [ t >>match-failed? ] unless drop ;
+
+M: end-of-line flag-action ( dfa-traverser flag -- )
+    drop
+    dup {
+        [ end-of-text? ]
+        [ next-text-character terminator-class class-member? ]
+    } 1|| [ t >>match-failed? ] unless drop ;
+
+
+M: word-boundary flag-action ( dfa-traverser flag -- )
+    drop
+    dup {
+        [ end-of-text? ]
+        [ current-text-character terminator-class class-member? ]
+    } 1|| [ t >>match-failed? ] unless drop ;
+
+
 M: lookahead-on flag-action ( dfa-traverser flag -- )
     drop
     lookahead-counters>> 0 swap push ;
@@ -110,11 +159,7 @@ M: capture-group-off flag-action ( dfa-traverser flag -- )
         [ [ 1+ ] change-current-index ]
         [ [ 1- ] change-current-index ] if
         dup current-state>> >>last-state
-    ] dip
-    first >>current-state ;
-
-: match-failed ( dfa-traverser -- dfa-traverser )
-    V{ } clone >>matches ;
+    ] [ first ] bi* >>current-state ;
 
 : match-literal ( transition from-state table -- to-state/f )
     transitions>> at at ;
@@ -131,11 +176,9 @@ M: capture-group-off flag-action ( dfa-traverser flag -- )
     { [ match-literal ] [ match-class ] [ match-default ] } 3|| ;
 
 : setup-match ( match -- obj state dfa-table )
-    {
-        [ current-index>> ] [ text>> ]
-        [ current-state>> ] [ dfa-table>> ]
-    } cleave
-    [ nth ] 2dip ;
+    [ [ current-index>> ] [ text>> ] bi nth ]
+    [ current-state>> ]
+    [ dfa-table>> ] tri ;
 
 : do-match ( dfa-traverser -- dfa-traverser )
     dup process-flags
index 5116dd2b7e40d8e60fb039279810e7a54f93dc46..af1b2fa1fb0eb25dd1bbec644f07a48680853f60 100644 (file)
@@ -26,23 +26,6 @@ IN: regexp.utils
 : ?insert-at ( value key hash/f -- hash )
     [ H{ } clone ] unless* [ insert-at ] keep ;
 
-: last-state ( regexp -- range ) stack>> peek first2 [a,b] ;
-: push1 ( obj -- ) input-stream get stream>> push ;
-: peek1 ( -- obj ) input-stream get stream>> [ f ] [ peek ] if-empty ;
-: pop3 ( seq -- obj1 obj2 obj3 ) [ pop ] [ pop ] [ pop ] tri spin ;
-: drop1 ( -- ) read1 drop ;
-
-: stack ( -- obj ) current-regexp get stack>> ;
-: change-whole-stack ( quot -- )
-    current-regexp get
-    [ stack>> swap call ] keep (>>stack) ; inline
-: push-stack ( obj -- ) stack push ;
-: pop-stack ( -- obj ) stack pop ;
-: cut-out ( vector n -- vector' vector ) cut rest ;
-ERROR: cut-stack-error ;
-: cut-stack ( obj vector -- vector' vector )
-    tuck last-index [ cut-stack-error ] unless* cut-out swap ;
-
 ERROR: bad-octal number ;
 ERROR: bad-hex number ;
 : check-octal ( octal -- octal ) dup 255 > [ bad-octal ] when ;
index 3dc560f46d9201b7300a5b3c24636bae6dcf54bd..f067e6ecdda39183a5b06b0af8a54a8306a6981a 100644 (file)
@@ -1,30 +1,49 @@
-USING: help.syntax help.markup ;
+USING: help.syntax help.markup kernel sequences ;
 IN: sequences.deep
 
 HELP: deep-each
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- ) " } }
-{ $description "Execute a quotation on each nested element of an object and its children, in preorder." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- )" } } }
+{ $description "Execute a quotation on each nested element of an object and its children, in preorder." }
+{ $see-also each } ;
 
 HELP: deep-map
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- newelt )" } { "newobj" "the mapped object" } }
-{ $description "Execute a quotation on each nested element of an object and its children, in preorder. That is, the result of the execution of the quotation on the outer is used to map the inner elements." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- newelt )" } } { "newobj" "the mapped object" } }
+{ $description "Execute a quotation on each nested element of an object and its children, in preorder. That is, the result of the execution of the quotation on the outer is used to map the inner elements." }
+{ $see-also map }  ;
 
 HELP: deep-filter
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- ? )" } { "seq" "a sequence" } }
-{ $description "Creates a sequence of sub-nodes in the object which satisfy the given quotation, in preorder. This includes the object itself, if it passes the quotation." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- ? )" } } { "seq" "a sequence" } }
+{ $description "Creates a sequence of sub-nodes in the object which satisfy the given quotation, in preorder. This includes the object itself, if it passes the quotation." }
+{ $see-also filter }  ;
 
 HELP: deep-find
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- ? )" } { "elt" "an element" } }
-{ $description "Gets the first sub-node of the object, in preorder, which satisfies the quotation. If nothing satisifies it, it returns " { $link f } "." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- ? )" } } { "elt" "an element" } }
+{ $description "Gets the first sub-node of the object, in preorder, which satisfies the quotation. If nothing satisifies it, it returns " { $link f } "." }
+{ $see-also find }  ;
 
 HELP: deep-contains?
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- ? )" } { "?" "a boolean" } }
-{ $description "Tests whether the given object or any subnode satisfies the given quotation." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- ? )" } } { "?" "a boolean" } }
+{ $description "Tests whether the given object or any subnode satisfies the given quotation." }
+{ $see-also contains? } ;
 
 HELP: flatten
-{ $values { "obj" "an object" } { "seq" "a sequence" } }
+{ $values { "obj" object } { "seq" "a sequence" } }
 { $description "Creates a sequence of all of the leaf nodes (non-sequence nodes, but including strings and numbers) in the object." } ;
 
 HELP: deep-change-each
-{ $values { "obj" "an object" } { "quot" "a quotation ( elt -- newelt )" } }
-{ $description "Modifies each sub-node of an object in place, in preorder." } ;
+{ $values { "obj" object } { "quot" { $quotation "( elt -- newelt )" } } }
+{ $description "Modifies each sub-node of an object in place, in preorder." }
+{ $see-also change-each } ;
+
+ARTICLE: "sequences.deep" "Deep sequence combinators"
+"The combinators in the " { $vocab-link "sequences.deep" } " vocabulary are variants of standard sequence combinators which traverse nested subsequences."
+{ $subsection deep-each }
+{ $subsection deep-map }
+{ $subsection deep-filter }
+{ $subsection deep-find }
+{ $subsection deep-contains? }
+{ $subsection deep-change-each }
+"A utility word to collapse nested subsequences:"
+{ $subsection flatten } ;
+
+ABOUT: "sequences.deep"
index a88634aa8af20010c3705fcbdb3fdbb936c919a2..522b5ecdf95a5f60472ba3773b327d4f8a0ee98d 100644 (file)
@@ -4,11 +4,11 @@ IN: sequences.deep.tests
 
 [ [ "hello" 3 4 swap ] ] [ [ { "hello" V{ 3 4 } } swap ] flatten ] unit-test
 
-[ "foo" t ] [ { { "foo" } "bar" } [ string? ] deep-find-from ] unit-test
+[ "foo" t ] [ { { "foo" } "bar" } [ string? ] (deep-find) ] unit-test
 
-[ f f ] [ { { "foo" } "bar" } [ number? ] deep-find-from ] unit-test
+[ f f ] [ { { "foo" } "bar" } [ number? ] (deep-find) ] unit-test
 
-[ { { "foo" } "bar" } t ] [ { { "foo" } "bar" } [ array? ] deep-find-from ] unit-test
+[ { { "foo" } "bar" } t ] [ { { "foo" } "bar" } [ array? ] (deep-find) ] unit-test
 
 : change-something ( seq -- newseq )
     dup array? [ "hi" suffix ] [ "hello" append ] if ;
index 2e50fa5411a7262999c6f554c4523586cdbdcfbe..db572681a16c72f56d9721fbf3dc06aa5bf7a4c3 100644 (file)
@@ -21,28 +21,27 @@ M: object branch? drop f ;
     [ [ deep-map ] curry map ] [ drop ] if ; inline recursive
 
 : deep-filter ( obj quot: ( elt -- ? ) -- seq )
-    over >r
-    pusher >r deep-each r>
-    r> dup branch? [ like ] [ drop ] if ; inline recursive
+    over [ pusher [ deep-each ] dip ] dip
+    dup branch? [ like ] [ drop ] if ; inline recursive
 
-: deep-find-from ( obj quot: ( elt -- ? ) -- elt ? )
+: (deep-find) ( obj quot: ( elt -- ? ) -- elt ? )
     [ call ] 2keep rot [ drop t ] [
         over branch? [
-            f -rot [ >r nip r> deep-find-from ] curry find drop >boolean
+            f -rot [ [ nip ] dip (deep-find) ] curry find drop >boolean
         ] [ 2drop f f ] if  
     ] if ; inline recursive
 
-: deep-find ( obj quot -- elt ) deep-find-from drop ; inline
+: deep-find ( obj quot -- elt ) (deep-find) drop ; inline
 
-: deep-contains? ( obj quot -- ? ) deep-find-from nip ; inline
+: deep-contains? ( obj quot -- ? ) (deep-find) nip ; inline
 
 : deep-all? ( obj quot -- ? )
     [ not ] compose deep-contains? not ; inline
 
 : deep-change-each ( obj quot: ( elt -- elt' ) -- )
-    over branch? [ [
-        [ call ] keep over >r deep-change-each r>
-    ] curry change-each ] [ 2drop ] if ; inline recursive
+    over branch? [
+        [ [ call ] keep over [ deep-change-each ] dip ] curry change-each
+    ] [ 2drop ] if ; inline recursive
 
 : flatten ( obj -- seq )
     [ branch? not ] deep-filter ;
index b22bf2683c78031486ff306cbe58165b6b21b08d..a0a441ab50c63e4ff1e09818997e586c1dd1dfa0 100644 (file)
@@ -3,20 +3,18 @@ IN: sequences.next
 
 <PRIVATE
 
-: iterate-seq >r dup length swap r> ; inline
+: iterate-seq [ dup length swap ] dip ; inline
 
 : (map-next) ( i seq quot -- )
     ! this uses O(n) more bounds checks than is really necessary
-    >r [ >r 1+ r> ?nth ] 2keep nth-unsafe r> call ; inline
+    [ [ [ 1+ ] dip ?nth ] 2keep nth-unsafe ] dip call ; inline
 
 PRIVATE>
 
-: each-next ( seq quot -- )
-    ! quot: next-elt elt --
+: each-next ( seq quot: ( next-elt elt -- ) -- )
     iterate-seq [ (map-next) ] 2curry each-integer ; inline
 
-: map-next ( seq quot -- newseq )
-    ! quot: next-elt elt -- newelt
-    over dup length swap new-sequence >r
-    iterate-seq [ (map-next) ] 2curry
-    r> [ collect ] keep ; inline
+: map-next ( seq quot: ( next-elt elt -- newelt ) -- newseq )
+    over dup length swap new-sequence [
+        iterate-seq [ (map-next) ] 2curry
+    ] dip [ collect ] keep ; inline
index 4ed534151b0de86cb429ac1a9290bb89c4f26276..99c6d0e255f7afa586f2cae27d67d0d8853ec7b0 100644 (file)
@@ -1,10 +1,10 @@
 ! Copyright (C) 2006 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
 ! 
-USING: tools.test kernel serialize serialize.private io
-io.streams.byte-array math alien arrays byte-arrays bit-arrays
-float-arrays sequences math prettyprint parser classes
-math.constants io.encodings.binary random assocs ;
+USING: tools.test kernel serialize io io.streams.byte-array math
+alien arrays byte-arrays bit-arrays specialized-arrays.double
+sequences math prettyprint parser classes math.constants
+io.encodings.binary random assocs serialize.private ;
 IN: serialize.tests
 
 : test-serialize-cell
@@ -48,7 +48,7 @@ C: <serialize-test> serialize-test
         T{ serialize-test f "a" 2 }
         B{ 50 13 55 64 1 }
         ?{ t f t f f t f }
-        F{ 1.0 3.0 4.0 1.0 2.35 0.33 }
+        double-array{ 1.0 3.0 4.0 1.0 2.35 0.33 }
         << 1 [ 2 ] curry parsed >>
         { { "a" "bc" } { "de" "fg" } }
         H{ { "a" "bc" } { "de" "fg" } }
index b5168b903ce4fe1909ad7101d85f04c80d9489f9..f190544e198aef7a4998bb8b7ecc0aaca28e9754 100644 (file)
@@ -2,3 +2,4 @@ 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
index 9a0dfe0e88d6b91d7d97a854f047fb2824dbd03c..b195e4abf903bd261d199d61741af8a4577cc9b7 100644 (file)
@@ -4,7 +4,7 @@ USING: kernel generalizations ;
 
 IN: shuffle
 
-: 2swap ( x y z t -- z t x y ) rot >r rot r> ; inline
+: 2swap ( x y z t -- z t x y ) 2 2 mnswap ; inline
 
 : nipd ( a b c -- b c ) rot drop ; inline
 
index a6a8bb2ccaa28ced9355e514ce1dbf6c35ce9543..7de22e9af9a3ccbd8ded2a29099c0bc30d3a2d46 100644 (file)
@@ -1,13 +1,14 @@
 ! Copyright (C) 2007 Elie CHAFTARI
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel prettyprint io io.timeouts
-sequences namespaces io.sockets continuations calendar
-io.encodings.ascii io.streams.duplex destructors ;
+USING: combinators kernel prettyprint io io.timeouts sequences
+namespaces io.sockets io.sockets.secure continuations calendar
+io.encodings.ascii io.streams.duplex destructors locals
+concurrency.promises threads accessors smtp.private
+io.unix.sockets.secure.debug ;
 IN: smtp.server
 
 ! Mock SMTP server for testing purposes.
 
-! Usage: 4321 mock-smtp-server
 ! $ telnet 127.0.0.1 4321
 ! Trying 127.0.0.1...
 ! Connected to localhost.
@@ -34,41 +35,52 @@ IN: smtp.server
 SYMBOL: data-mode
 
 : process ( -- )
-    readln {
-        { [ [ dup "HELO" head? ] keep "EHLO" head? or ] [ 
-            "220 and..?\r\n" write flush t
-          ] }
-        { [ dup "QUIT" = ] [ 
-            "bye\r\n" write flush f
-          ] }
-        { [ dup "MAIL FROM:" head? ] [ 
-            "220 OK\r\n" write flush t
-          ] }
-        { [ dup "RCPT TO:" head? ] [ 
-            "220 OK\r\n" write flush t
-          ] }
-        { [ dup "DATA" = ] [
-            data-mode on 
-            "354 Enter message, ending with \".\" on a line by itself\r\n"
-            write flush t
-          ] }
-        { [ dup "." = data-mode get and ] [
-            data-mode off
-            "220 OK\r\n" write flush t
-          ] }
+    read-crlf {
+        {
+            [ dup [ "HELO" head? ] [ "EHLO" head? ] bi or ]
+            [ "220 and..?\r\n" write flush t ]
+        }
+        {
+            [ dup "STARTTLS" = ]
+            [
+                "220 2.0.0 Ready to start TLS\r\n" write flush
+                accept-secure-handshake t
+            ]
+        }
+        { [ dup "QUIT" = ] [ "220 bye\r\n" write flush f ] }
+        { [ dup "MAIL FROM:" head? ] [ "220 OK\r\n" write flush t ] }
+        { [ dup "RCPT TO:" head? ] [ "220 OK\r\n" write flush t ] }
+        {
+            [ dup "DATA" = ]
+            [
+                data-mode on 
+                "354 Enter message, ending with \".\" on a line by itself\r\n"
+                write flush t
+            ]
+        }
+        {
+            [ dup "." = data-mode get and ]
+            [
+                data-mode off
+                "220 OK\r\n" write flush t
+            ]
+        }
         { [ data-mode get ] [ dup global [ print ] bind t ] }
-        [ 
-            "500 ERROR\r\n" write flush t
-        ]
+        [ "500 ERROR\r\n" write flush t ]
     } cond nip [ process ] when ;
 
-: mock-smtp-server ( port -- )
-    "Starting SMTP server on port " write dup . flush
-    "127.0.0.1" swap <inet4> ascii <server> [
-        accept drop [
-            1 minutes timeouts
-            "220 hello\r\n" write flush
-            process
-            global [ flush ] bind
-        ] with-stream
-    ] with-disposal ;
+:: mock-smtp-server ( promise -- )
+    #! Store the port we are running on in the promise.
+    [
+        [
+            "127.0.0.1" 0 <inet4> ascii <server> [
+            dup addr>> port>> promise fulfill
+                accept drop [
+                    1 minutes timeouts
+                    "220 hello\r\n" write flush
+                    process
+                    global [ flush ] bind
+                ] with-stream
+            ] with-disposal
+        ] with-test-context
+    ] in-thread ;
index c1c2d1c1f8f151a9884c2ec5e673097966c00e51..83b9287043fbf9882aba604f173037af74b9254c 100644 (file)
@@ -5,20 +5,52 @@ io.sockets strings calendar ;
 IN: smtp
 
 HELP: smtp-domain
-{ $description "The name of the machine that is sending the email.  This variable will be filled in by the " { $link host-name } " word if not set by the user." } ;
+{ $var-description "The name of the machine that is sending the email.  This variable will be filled in by the " { $link host-name } " word if not set by the user." } ;
 
 HELP: smtp-server
-{ $description "Holds an " { $link inet } " object with the address of an SMTP server." } ;
+{ $var-description "Holds an " { $link inet } " object with the address of an SMTP server." } ;
+
+HELP: smtp-tls?
+{ $var-description "If set to true, secure socket communication will be established after connecting to the SMTP server. The server must support the " { $snippet "STARTTLS" } " command. Off by default." } ;
 
 HELP: smtp-read-timeout
-{ $description "Holds an " { $link duration } " object that specifies how long to wait for a response from the SMTP server." } ;
+{ $var-description "Holds a " { $link duration } " object that specifies how long to wait for a response from the SMTP server." } ;
+
+HELP: smtp-auth
+{ $var-description "Holds either " { $link no-auth } " or an instance of " { $link plain-auth } ", specifying how to authenticate with the SMTP server. Set to " { $link no-auth } " by default." } ;
+
+HELP: no-auth
+{ $class-description "If the " { $link smtp-auth } " variable is set to this value, no authentication will be performed." } ;
+
+HELP: plain-auth
+{ $class-description "If the " { $link smtp-auth } " variable is set to this value, plain authentication will be performed, with the username and password stored in the " { $slot "username" } " and " { $slot "password" } " slots of the tuple sent to the server as plain-text." } ;
 
-HELP: esmtp?
-{ $description "Set true by default, determines whether the SMTP client is using the Extended SMTP protocol." } ;
+HELP: <plain-auth> ( username password -- plain-auth )
+{ $values { "username" string } { "password" string } { "plain-auth" plain-auth } }
+{ $description "Creates a new " { $link plain-auth } " instance." } ;
 
 HELP: with-smtp-connection
 { $values { "quot" quotation } }
-{ $description "Connects to an SMTP server stored in " { $link smtp-server } " and calls the quotation." } ;
+{ $description "Connects to an SMTP server stored in " { $link smtp-server } " and calls the quotation." }
+{ $notes "This word is used to implement " { $link send-email } " and there is probably no reason to call it directly." } ;
+
+HELP: email
+{ $class-description "An e-mail. E-mails have the following slots:"
+    { $table
+        { { $slot "from" } "The sender of the e-mail. An e-mail address." }
+        { { $slot "to" } "The recipients of the e-mail. A sequence of e-mail addresses." }
+        { { $slot "cc" } "Carbon-copy. A sequence of e-mail addresses." }
+        { { $slot "bcc" } "Blind carbon-copy. A sequence of e-mail addresses." }
+        { { $slot "subject" } " The subject of the e-mail. A string." }
+        { { $slot "body" } " The body of the e-mail. A string." }
+    }
+"The " { $slot "from" } " and " { $slot "to" } " slots are required; the rest are optional."
+$nl
+"An e-mail address is a string in one of the following two formats:"
+{ $list
+    { $snippet "joe@groff.com" }
+    { $snippet "Joe Groff <joe@groff.com>" }
+} } ;
 
 HELP: <email>
 { $values { "email" email } }
@@ -26,9 +58,9 @@ HELP: <email>
 
 HELP: send-email
 { $values { "email" email } }
-{ $description "Sends an " { $link email } " object to an STMP server stored in the " { $link smtp-server } " variable.  The required slots are " { $slot "from" } " and " { $slot "to" } "." }
+{ $description "Sends an e-mail." }
 { $examples
-    { $unchecked-example "USING: accessors smtp ;"
+    { $code "USING: accessors smtp ;"
     "<email>"
     "    \"groucho@marx.bros\" >>from"
     "    { \"chico@marx.bros\" \"harpo@marx.bros\" } >>to"
@@ -42,10 +74,21 @@ HELP: send-email
 } ;
 
 ARTICLE: "smtp" "SMTP client library"
-"Configuring SMTP:"
+"The " { $vocab-link "smtp" } " vocabulary sends e-mail via an SMTP server."
+$nl
+"This library is configured by a set of dynamically-scoped variables:"
 { $subsection smtp-server }
+{ $subsection smtp-tls? }
 { $subsection smtp-read-timeout }
 { $subsection smtp-domain }
-{ $subsection esmtp? }
+{ $subsection smtp-auth }
+"The latter is set to an instance of one of the following:"
+{ $subsection no-auth }
+{ $subsection plain-auth }
+"Constructing an e-mail:"
+{ $subsection email }
+{ $subsection <email> }
 "Sending an email:"
 { $subsection send-email } ;
+
+ABOUT: "smtp"
index f8b321fdac465218ad4ae1d4f3d585fbfe83c984..e3638bd96918fcb527f4448bf0270e6542cc7504 100644 (file)
@@ -1,8 +1,11 @@
-USING: smtp tools.test io.streams.string io.sockets threads
-smtp.server kernel sequences namespaces logging accessors
-assocs sorting smtp.private ;
+USING: smtp tools.test io.streams.string io.sockets
+io.sockets.secure threads smtp.server kernel sequences
+namespaces logging accessors assocs sorting smtp.private
+concurrency.promises system ;
 IN: smtp.tests
 
+\ send-email must-infer
+
 { 0 0 } [ [ ] with-smtp-connection ] must-infer-as
 
 [ "hello\nworld" validate-address ] must-fail
@@ -16,15 +19,22 @@ IN: smtp.tests
     "hello\nworld" [ send-body ] with-string-writer
 ] unit-test
 
-[ "500 syntax error" check-response ] must-fail
+[ { "500 syntax error" } <response> check-response ]
+[ smtp-error? ] must-fail-with
 
-[ ] [ "220 success" check-response ] unit-test
+[ ] [ { "220 success" } <response> check-response ] unit-test
 
-[ "220 success" ] [
+[ T{ response f 220 { "220 success" } } ] [
     "220 success" [ receive-response ] with-string-reader
 ] unit-test
 
-[ "220 the end" ] [
+[
+    T{ response f 220 {
+        "220-a multiline response"
+        "250-another line"
+        "220 the end"
+    } }
+] [
     "220-a multiline response\r\n250-another line\r\n220 the end"
     [ receive-response ] with-string-reader
 ] unit-test
@@ -63,13 +73,15 @@ IN: smtp.tests
     [ from>> extract-email ] tri
 ] unit-test
 
-[ ] [ [ 4321 mock-smtp-server ] "SMTP server" spawn drop ] unit-test
+<promise> "p" set
 
-[ ] [ yield ] unit-test
+[ ] [ "p" get mock-smtp-server ] unit-test
 
 [ ] [
-    [
-        "localhost" 4321 <inet> smtp-server set
+    <secure-config> f >>verify [
+        "localhost" "p" get ?promise <inet> smtp-server set
+        no-auth smtp-auth set
+        os unix? [ smtp-tls? on ] when
 
         <email>
             "Hi guys\nBye guys" >>body
@@ -80,7 +92,5 @@ IN: smtp.tests
             } >>to
             "Doug <erg@factorcode.org>" >>from
         send-email
-    ] with-scope
+    ] with-secure-context
 ] unit-test
-
-[ ] [ yield ] unit-test
index 9dc03dfac2a8ae7314a121a3612672f1e79873e8..7f14945633b82f2b2201959ede17856d2086b209 100644 (file)
@@ -1,16 +1,31 @@
 ! Copyright (C) 2007, 2008 Elie CHAFTARI, Dirk Vleugels,
 ! Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays namespaces make io io.timeouts kernel logging
-io.sockets sequences combinators splitting assocs strings
-math.parser random system calendar io.encodings.ascii summary
-calendar.format accessors sets hashtables ;
+USING: arrays namespaces make io io.encodings.string
+io.encodings.utf8 io.timeouts io.sockets io.sockets.secure
+io.encodings.ascii kernel logging sequences combinators
+splitting assocs strings math.order math.parser random system
+calendar summary calendar.format accessors sets hashtables
+base64 debugger classes prettyprint ;
 IN: smtp
 
 SYMBOL: smtp-domain
-SYMBOL: smtp-server     "localhost" 25 <inet> smtp-server set-global
-SYMBOL: smtp-read-timeout    1 minutes smtp-read-timeout set-global
-SYMBOL: esmtp?           t esmtp? set-global
+
+SYMBOL: smtp-server
+"localhost" 25 <inet> smtp-server set-global
+
+SYMBOL: smtp-tls?
+
+SYMBOL: smtp-read-timeout
+1 minutes smtp-read-timeout set-global
+
+SINGLETON: no-auth
+
+TUPLE: plain-auth username password ;
+C: <plain-auth> plain-auth
+
+SYMBOL: smtp-auth
+no-auth smtp-auth set-global
 
 LOG: log-smtp-connection NOTICE ( addrspec -- )
 
@@ -31,15 +46,23 @@ TUPLE: email
     { subject string }
     { body string } ;
 
-: <email> ( -- email ) email new ;
+: <email> ( -- email ) email new ; inline
 
 <PRIVATE
+
 : crlf ( -- ) "\r\n" write ;
 
+: read-crlf ( -- bytes )
+    "\r" read-until
+    [ CHAR: \r assert= read1 CHAR: \n assert= ] when* ;
+
 : command ( string -- ) write crlf flush ;
 
-: helo ( -- )
-    esmtp? get "EHLO " "HELO " ? host-name append command ;
+\ command DEBUG add-input-logging
+
+: helo ( -- ) "EHLO " host-name append command ;
+
+: start-tls ( -- ) "STARTTLS" command ;
 
 ERROR: bad-email-address email ;
 
@@ -60,8 +83,7 @@ ERROR: bad-email-address email ;
 ERROR: message-contains-dot message ;
 
 M: message-contains-dot summary ( obj -- string )
-    drop
-    "Message cannot contain . on a line by itself" ;
+    drop "Message cannot contain . on a line by itself" ;
 
 : validate-message ( msg -- msg' )
     "." over member?
@@ -78,7 +100,30 @@ M: message-contains-dot summary ( obj -- string )
 
 LOG: smtp-response DEBUG
 
-ERROR: smtp-error message ;
+: multiline? ( response -- boolean )
+    3 swap ?nth CHAR: - = ;
+
+: (receive-response) ( -- )
+    read-crlf
+    [ , ]
+    [ smtp-response ]
+    [ multiline? [ (receive-response) ] when ]
+    tri ;
+
+TUPLE: response code messages ;
+
+: <response> ( lines -- response )
+    [ first 3 head string>number ] keep response boa ;
+
+: receive-response ( -- response )
+    [ (receive-response) ] { } make <response> ;
+
+ERROR: smtp-error response ;
+
+M: smtp-error error.
+    "SMTP error (" write dup class pprint ")" print
+    response>> messages>> [ print ] each ;
+
 ERROR: smtp-server-busy < smtp-error ;
 ERROR: smtp-syntax-error < smtp-error ;
 ERROR: smtp-command-not-implemented < smtp-error ;
@@ -90,42 +135,35 @@ ERROR: smtp-bad-mailbox-name < smtp-error ;
 ERROR: smtp-transaction-failed < smtp-error ;
 
 : check-response ( response -- )
-    dup smtp-response
-    {
-        { [ dup "bye" head? ] [ drop ] }
-        { [ dup "220" head? ] [ drop ] }
-        { [ dup "235" swap subseq? ] [ drop ] }
-        { [ dup "250" head? ] [ drop ] }
-        { [ dup "221" head? ] [ drop ] }
-        { [ dup "354" head? ] [ drop ] }
-        { [ dup "4" head? ] [ smtp-server-busy ] }
-        { [ dup "500" head? ] [ smtp-syntax-error ] }
-        { [ dup "501" head? ] [ smtp-command-not-implemented ] }
-        { [ dup "50" head? ] [ smtp-syntax-error ] }
-        { [ dup "53" head? ] [ smtp-bad-authentication ] }
-        { [ dup "550" head? ] [ smtp-mailbox-unavailable ] }
-        { [ dup "551" head? ] [ smtp-user-not-local ] }
-        { [ dup "552" head? ] [ smtp-exceeded-storage-allocation ] }
-        { [ dup "553" head? ] [ smtp-bad-mailbox-name ] }
-        { [ dup "554" head? ] [ smtp-transaction-failed ] }
-        [ smtp-error ]
+    dup code>> {
+        { [ dup { 220 235 250 221 354 } member? ] [ 2drop ] }
+        { [ dup 400 499 between? ] [ drop smtp-server-busy ] }
+        { [ dup 500 = ] [ drop smtp-syntax-error ] }
+        { [ dup 501 = ] [ drop smtp-command-not-implemented ] }
+        { [ dup 500 509 between? ] [ drop smtp-syntax-error ] }
+        { [ dup 530 539 between? ] [ drop smtp-bad-authentication ] }
+        { [ dup 550 = ] [ drop smtp-mailbox-unavailable ] }
+        { [ dup 551 = ] [ drop smtp-user-not-local ] }
+        { [ dup 552 = ] [ drop smtp-exceeded-storage-allocation ] }
+        { [ dup 553 = ] [ drop smtp-bad-mailbox-name ] }
+        { [ dup 554 = ] [ drop smtp-transaction-failed ] }
+        [ drop smtp-error ]
     } cond ;
 
-: multiline? ( response -- boolean )
-    3 swap ?nth CHAR: - = ;
+: get-ok ( -- ) receive-response check-response ;
 
-: process-multiline ( multiline -- response )
-    >r readln r> 2dup " " append head? [
-        drop dup smtp-response
-    ] [
-        swap check-response process-multiline
-    ] if ;
+GENERIC: send-auth ( auth -- )
 
-: receive-response ( -- response )
-    readln
-    dup multiline? [ 3 head process-multiline ] when ;
+M: no-auth send-auth drop ;
 
-: get-ok ( -- ) receive-response check-response ;
+: plain-auth-string ( username password -- string )
+    [ "\0" prepend ] bi@ append utf8 encode >base64 ;
+
+M: plain-auth send-auth
+    [ username>> ] [ password>> ] bi plain-auth-string
+    "AUTH PLAIN " prepend command get-ok ;
+
+: auth ( -- ) smtp-auth get send-auth ;
 
 ERROR: invalid-header-string string ;
 
@@ -169,7 +207,10 @@ ERROR: invalid-header-string string ;
 
 : (send-email) ( headers email -- )
     [
+        get-ok
         helo get-ok
+        smtp-tls? get [ start-tls get-ok send-secure-handshake ] when
+        auth
         dup from>> extract-email mail-from get-ok
         dup to>> [ extract-email rcpt-to get-ok ] each
         dup cc>> [ extract-email rcpt-to get-ok ] each
@@ -180,6 +221,7 @@ ERROR: invalid-header-string string ;
         body>> send-body get-ok
         quit get-ok
     ] with-smtp-connection ;
+
 PRIVATE>
 
 : send-email ( email -- )
diff --git a/basis/specialized-arrays/alien/alien.factor b/basis/specialized-arrays/alien/alien.factor
new file mode 100644 (file)
index 0000000..465d166
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.alien
+
+<< "void*" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/authors.txt b/basis/specialized-arrays/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/specialized-arrays/bool/bool.factor b/basis/specialized-arrays/bool/bool.factor
new file mode 100644 (file)
index 0000000..759ee91
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.bool
+
+<< "bool" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/char/char.factor b/basis/specialized-arrays/char/char.factor
new file mode 100644 (file)
index 0000000..cdf78ee
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.char
+
+<< "char" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/alien/alien.factor b/basis/specialized-arrays/direct/alien/alien.factor
new file mode 100644 (file)
index 0000000..3949c40
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.alien specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.alien
+
+<< "void*" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/bool/bool.factor b/basis/specialized-arrays/direct/bool/bool.factor
new file mode 100644 (file)
index 0000000..689fcc3
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.bool specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.bool
+
+<< "bool" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/char/char.factor b/basis/specialized-arrays/direct/char/char.factor
new file mode 100644 (file)
index 0000000..cca3a62
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.char specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.char
+
+<< "char" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/direct-docs.factor b/basis/specialized-arrays/direct/direct-docs.factor
new file mode 100644 (file)
index 0000000..e2638c4
--- /dev/null
@@ -0,0 +1,33 @@
+USING: help.markup help.syntax byte-arrays alien ;
+IN: specialized-arrays.direct
+
+ARTICLE: "specialized-arrays.direct" "Direct-mapped specialized arrays"
+"The " { $vocab-link "specialized-arrays.direct" } " vocabulary implements fixed-length sequence types for storing machine values in unmanaged C memory."
+$nl
+"For each primitive C type " { $snippet "T" } ", a set of words are defined:"
+{ $table
+    { { $snippet "direct-T-array" } { "The class of direct arrays with elements of type " { $snippet "T" } } }
+    { { $snippet "<direct-T-array>" } { "Constructor for arrays with elements of type " { $snippet "T" } "; stack effect " { $snippet "( alien len -- array )" } } }
+}
+"Each direct array has a " { $slot "underlying" } " slot holding an " { $link simple-alien } " pointer to the raw data. This data can be passed to C functions."
+$nl
+"The primitive C types for which direct arrays exist:"
+{ $list
+    { $snippet "char" }
+    { $snippet "uchar" }
+    { $snippet "short" }
+    { $snippet "ushort" }
+    { $snippet "int" }
+    { $snippet "uint" }
+    { $snippet "long" }
+    { $snippet "ulong" }
+    { $snippet "longlong" }
+    { $snippet "ulonglong" }
+    { $snippet "float" }
+    { $snippet "double" }
+    { $snippet "void*" }
+    { $snippet "bool" }
+}
+"Direct arrays are generated with a functor in the " { $vocab-link "specialized-arrays.direct.functor" } " vocabulary." ;
+
+ABOUT: "specialized-arrays.direct"
diff --git a/basis/specialized-arrays/direct/direct-tests.factor b/basis/specialized-arrays/direct/direct-tests.factor
new file mode 100644 (file)
index 0000000..2a48b5d
--- /dev/null
@@ -0,0 +1,7 @@
+IN: specialized-arrays.direct.tests
+USING: specialized-arrays.direct.ushort tools.test
+specialized-arrays.ushort alien.syntax sequences ;
+
+[ ushort-array{ 0 0 0 } ] [
+    3 ALIEN: 123 100 <direct-ushort-array> new-sequence
+] unit-test
diff --git a/basis/specialized-arrays/direct/direct.factor b/basis/specialized-arrays/direct/direct.factor
new file mode 100644 (file)
index 0000000..7c15c66
--- /dev/null
@@ -0,0 +1,3 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: specialized-arrays.direct
diff --git a/basis/specialized-arrays/direct/double/double.factor b/basis/specialized-arrays/direct/double/double.factor
new file mode 100644 (file)
index 0000000..c3089b3
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.double specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.double
+
+<< "double" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/float/float.factor b/basis/specialized-arrays/direct/float/float.factor
new file mode 100644 (file)
index 0000000..94caa95
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.float specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.float
+
+<< "float" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/functor/functor.factor b/basis/specialized-arrays/direct/functor/functor.factor
new file mode 100755 (executable)
index 0000000..14fb739
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: functors sequences sequences.private kernel words classes
+math alien alien.c-types byte-arrays accessors
+specialized-arrays ;
+IN: specialized-arrays.direct.functor
+
+FUNCTOR: define-direct-array ( T -- )
+
+A'      IS ${T}-array
+>A'     IS >${T}-array
+<A'>    IS <${A'}>
+
+A       DEFINES direct-${T}-array
+<A>     DEFINES <${A}>
+
+NTH     [ T dup c-getter array-accessor ]
+SET-NTH [ T dup c-setter array-accessor ]
+
+WHERE
+
+TUPLE: A
+{ underlying c-ptr read-only }
+{ length fixnum read-only } ;
+
+: <A> ( alien len -- direct-array ) A boa ; inline
+M: A length length>> ;
+M: A nth-unsafe underlying>> NTH call ;
+M: A set-nth-unsafe underlying>> SET-NTH call ;
+M: A like drop dup A instance? [ >A' execute ] unless ;
+M: A new-sequence drop <A'> execute ;
+
+INSTANCE: A sequence
+
+;FUNCTOR
diff --git a/basis/specialized-arrays/direct/int/int.factor b/basis/specialized-arrays/direct/int/int.factor
new file mode 100644 (file)
index 0000000..c204e27
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.int specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.int
+
+<< "int" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/long/long.factor b/basis/specialized-arrays/direct/long/long.factor
new file mode 100644 (file)
index 0000000..33c52bb
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.long specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.long
+
+<< "long" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/longlong/longlong.factor b/basis/specialized-arrays/direct/longlong/longlong.factor
new file mode 100644 (file)
index 0000000..f132000
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.longlong specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.longlong
+
+<< "longlong" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/short/short.factor b/basis/specialized-arrays/direct/short/short.factor
new file mode 100644 (file)
index 0000000..f837beb
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.short specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.short
+
+<< "short" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/uchar/uchar.factor b/basis/specialized-arrays/direct/uchar/uchar.factor
new file mode 100644 (file)
index 0000000..3440979
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.uchar specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.uchar
+
+<< "uchar" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/uint/uint.factor b/basis/specialized-arrays/direct/uint/uint.factor
new file mode 100644 (file)
index 0000000..22f7ba3
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.uint specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.uint
+
+<< "uint" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/ulong/ulong.factor b/basis/specialized-arrays/direct/ulong/ulong.factor
new file mode 100644 (file)
index 0000000..8a568ab
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.ulong specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.ulong
+
+<< "ulong" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/ulonglong/ulonglong.factor b/basis/specialized-arrays/direct/ulonglong/ulonglong.factor
new file mode 100644 (file)
index 0000000..10fa178
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.ulonglong specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.ulonglong
+
+<< "ulonglong" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/direct/ushort/ushort.factor b/basis/specialized-arrays/direct/ushort/ushort.factor
new file mode 100644 (file)
index 0000000..6bd34c7
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-arrays.ushort specialized-arrays.direct.functor ;
+IN: specialized-arrays.direct.ushort
+
+<< "ushort" define-direct-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/double/double.factor b/basis/specialized-arrays/double/double.factor
new file mode 100644 (file)
index 0000000..0501458
--- /dev/null
@@ -0,0 +1,70 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.double
+
+<< "double" define-array >>
+
+! Specializer hints. These should really be generalized, and placed
+! somewhere else
+USING: hints math.vectors arrays kernel math accessors sequences ;
+
+HINTS: <double-array> { 2 } { 3 } ;
+
+HINTS: vneg { array } { double-array } ;
+HINTS: v*n { array object } { double-array float } ;
+HINTS: n*v { array object } { float double-array } ;
+HINTS: v/n { array object } { double-array float } ;
+HINTS: n/v { object array } { float double-array } ;
+HINTS: v+ { array array } { double-array double-array } ;
+HINTS: v- { array array } { double-array double-array } ;
+HINTS: v* { array array } { double-array double-array } ;
+HINTS: v/ { array array } { double-array double-array } ;
+HINTS: vmax { array array } { double-array double-array } ;
+HINTS: vmin { array array } { double-array double-array } ;
+HINTS: v. { array array } { double-array double-array } ;
+HINTS: norm-sq { array } { double-array } ;
+HINTS: norm { array } { double-array } ;
+HINTS: normalize { array } { double-array } ;
+HINTS: distance { array array } { double-array double-array } ;
+
+! Type functions
+USING: words classes.algebra compiler.tree.propagation.info
+math.intervals ;
+
+{ v+ v- v* v/ vmax vmin } [
+    [
+        [ class>> double-array class<= ] both?
+        double-array object ? <class-info>
+    ] "outputs" set-word-prop
+] each
+
+{ n*v n/v } [
+    [
+        nip class>> double-array class<= double-array object ? <class-info>
+    ] "outputs" set-word-prop
+] each
+
+{ v*n v/n } [
+    [
+        drop class>> double-array class<= double-array object ? <class-info>
+    ] "outputs" set-word-prop
+] each
+
+{ vneg normalize } [
+    [
+        class>> double-array class<= double-array object ? <class-info>
+    ] "outputs" set-word-prop
+] each
+
+\ norm-sq [
+    class>> double-array class<= [ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
+] "outputs" set-word-prop
+
+\ v. [
+    [ class>> double-array class<= ] both?
+    float object ? <class-info>
+] "outputs" set-word-prop
+
+\ distance [
+    [ class>> double-array class<= ] both?
+    [ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
+] "outputs" set-word-prop
diff --git a/basis/specialized-arrays/float/float.factor b/basis/specialized-arrays/float/float.factor
new file mode 100644 (file)
index 0000000..5d9da66
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.float
+
+<< "float" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/functor/functor.factor b/basis/specialized-arrays/functor/functor.factor
new file mode 100644 (file)
index 0000000..52977dc
--- /dev/null
@@ -0,0 +1,71 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: functors sequences sequences.private prettyprint.backend
+kernel words classes math parser alien.c-types byte-arrays
+accessors summary ;
+IN: specialized-arrays.functor
+
+ERROR: bad-byte-array-length byte-array type ;
+
+M: bad-byte-array-length summary
+    drop "Byte array length doesn't divide type width" ;
+
+FUNCTOR: define-array ( T -- )
+
+A            DEFINES ${T}-array
+<A>          DEFINES <${A}>
+>A           DEFINES >${A}
+byte-array>A DEFINES byte-array>${A}
+A{           DEFINES ${A}{
+
+NTH          [ T dup c-getter array-accessor ]
+SET-NTH      [ T dup c-setter array-accessor ]
+
+WHERE
+
+TUPLE: A
+{ length array-capacity read-only }
+{ underlying byte-array read-only } ;
+
+: <A> ( n -- specialized-array ) dup T <c-array> A boa ; inline
+
+: byte-array>A ( byte-array -- specialized-array )
+    dup length T heap-size /mod 0 = [ drop T bad-byte-array-length ] unless
+    swap A boa ; inline
+
+M: A clone [ length>> ] [ underlying>> clone ] bi A boa ;
+
+M: A length length>> ;
+
+M: A nth-unsafe underlying>> NTH call ;
+
+M: A set-nth-unsafe underlying>> SET-NTH call ;
+
+: >A ( seq -- specialized-array ) A new clone-like ; inline
+
+M: A like drop dup A instance? [ >A execute ] unless ;
+
+M: A new-sequence drop <A> execute ;
+
+M: A equal? over A instance? [ sequence= ] [ 2drop f ] if ;
+
+M: A resize
+    [ drop ] [
+        [ T heap-size * ] [ underlying>> ] bi*
+        resize-byte-array
+    ] 2bi
+    A boa ;
+
+M: A byte-length underlying>> length ;
+
+M: A pprint-delims drop A{ \ } ;
+
+M: A >pprint-sequence ;
+
+M: A pprint* pprint-object ;
+
+: A{ \ } [ >A execute ] parse-literal ; parsing
+
+INSTANCE: A sequence
+
+;FUNCTOR
diff --git a/basis/specialized-arrays/int/int.factor b/basis/specialized-arrays/int/int.factor
new file mode 100644 (file)
index 0000000..37f4b59
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.int
+
+<< "int" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/long/long.factor b/basis/specialized-arrays/long/long.factor
new file mode 100644 (file)
index 0000000..2cba642
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.long
+
+<< "long" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/longlong/longlong.factor b/basis/specialized-arrays/longlong/longlong.factor
new file mode 100644 (file)
index 0000000..195dd78
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.longlong
+
+<< "longlong" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/short/short.factor b/basis/specialized-arrays/short/short.factor
new file mode 100644 (file)
index 0000000..3891462
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.short
+
+<< "short" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/specialized-arrays-docs.factor b/basis/specialized-arrays/specialized-arrays-docs.factor
new file mode 100644 (file)
index 0000000..1c1b3db
--- /dev/null
@@ -0,0 +1,40 @@
+USING: help.markup help.syntax byte-arrays ;
+IN: specialized-arrays
+
+ARTICLE: "specialized-arrays" "Specialized arrays"
+"The " { $vocab-link "specialized-arrays" } " vocabulary implements fixed-length sequence types for storing machine values in a space-efficient manner without boxing."
+$nl
+"For each primitive C type " { $snippet "T" } ", a set of words are defined in the vocabulary named " { $snippet "specialized-arrays.T" } ":"
+{ $table
+    { { $snippet "T-array" } { "The class of arrays with elements of type " { $snippet "T" } } }
+    { { $snippet "<T-array>" } { "Constructor for arrays with elements of type " { $snippet "T" } "; stack effect " { $snippet "( len -- array )" } } }
+    { { $snippet ">T-array" } { "Converts a sequence into a specialized array of type " { $snippet "T" } "; stack effect " { $snippet "( seq -- array )" } } }
+    { { $snippet "byte-array>T-array" } { "Converts a byte array into a specialized array by interpreting the bytes in as machine-specific values. Code which uses this word is unportable" } }
+    { { $snippet "T-array{" } { "Literal syntax, consists of a series of values terminated by " { $snippet "}" } } }
+}
+"Each specialized array has a " { $slot "underlying" } " slot holding a " { $link byte-array } " with the raw data. This data can be passed to C functions."
+$nl
+"The primitive C types for which specialized arrays exist:"
+{ $list
+    { $snippet "char" }
+    { $snippet "uchar" }
+    { $snippet "short" }
+    { $snippet "ushort" }
+    { $snippet "int" }
+    { $snippet "uint" }
+    { $snippet "long" }
+    { $snippet "ulong" }
+    { $snippet "longlong" }
+    { $snippet "ulonglong" }
+    { $snippet "float" }
+    { $snippet "double" }
+    { $snippet "void*" }
+    { $snippet "bool" }
+}
+"Note that " { $vocab-link "specialized-arrays.bool" } " behaves like a C " { $snippet "bool[]" } " array, and each element takes up 8 bits of space. For a more space-efficient boolean array, see " { $link "bit-arrays" } "."
+$nl
+"Specialized arrays are generated with a functor in the " { $vocab-link "specialized-arrays.functor" } " vocabulary."
+$nl
+"The " { $vocab-link "specialized-vectors" } " vocabulary provides resizable versions of the above." ;
+
+ABOUT: "specialized-arrays"
diff --git a/basis/specialized-arrays/specialized-arrays-tests.factor b/basis/specialized-arrays/specialized-arrays-tests.factor
new file mode 100644 (file)
index 0000000..1ca0411
--- /dev/null
@@ -0,0 +1,18 @@
+IN: specialized-arrays.tests
+USING: tools.test specialized-arrays sequences
+specialized-arrays.int specialized-arrays.bool
+specialized-arrays.ushort alien.c-types accessors kernel ;
+
+[ t ] [ { 1 2 3 } >int-array int-array? ] unit-test
+
+[ t ] [ int-array{ 1 2 3 } int-array? ] unit-test
+
+[ 2 ] [ int-array{ 1 2 3 } second ] unit-test
+
+[ t ] [ { t f t } >bool-array underlying>> { 1 0 1 } >int-array underlying>> = ] unit-test
+
+[ ushort-array{ 1234 } ] [
+    little-endian? B{ 210 4 } B{ 4 210 } ? byte-array>ushort-array
+] unit-test
+
+[ B{ 210 4 1 } byte-array>ushort-array ] must-fail
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
new file mode 100644 (file)
index 0000000..631d28d
--- /dev/null
@@ -0,0 +1,3 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: specialized-arrays
diff --git a/basis/specialized-arrays/summary.txt b/basis/specialized-arrays/summary.txt
new file mode 100644 (file)
index 0000000..6191766
--- /dev/null
@@ -0,0 +1 @@
+Arrays of unboxed primitive C types
diff --git a/basis/specialized-arrays/tags.txt b/basis/specialized-arrays/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/basis/specialized-arrays/uchar/uchar.factor b/basis/specialized-arrays/uchar/uchar.factor
new file mode 100644 (file)
index 0000000..c6ed4f3
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.uchar
+
+<< "uchar" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/uint/uint.factor b/basis/specialized-arrays/uint/uint.factor
new file mode 100644 (file)
index 0000000..1534a3d
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.uint
+
+<< "uint" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/ulong/ulong.factor b/basis/specialized-arrays/ulong/ulong.factor
new file mode 100644 (file)
index 0000000..27dc129
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.ulong
+
+<< "ulong" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/ulonglong/ulonglong.factor b/basis/specialized-arrays/ulonglong/ulonglong.factor
new file mode 100644 (file)
index 0000000..cbb2b3c
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.ulonglong
+
+<< "ulonglong" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-arrays/ushort/ushort.factor b/basis/specialized-arrays/ushort/ushort.factor
new file mode 100644 (file)
index 0000000..e0989aa
--- /dev/null
@@ -0,0 +1,4 @@
+USE: specialized-arrays.functor
+IN: specialized-arrays.ushort
+
+<< "ushort" define-array >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/alien/alien.factor b/basis/specialized-vectors/alien/alien.factor
new file mode 100644 (file)
index 0000000..2b9855f
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.alien ;
+IN: specialized-vectors.alien
+
+<< "void*" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/authors.txt b/basis/specialized-vectors/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/specialized-vectors/bool/bool.factor b/basis/specialized-vectors/bool/bool.factor
new file mode 100644 (file)
index 0000000..75d452a
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.bool ;
+IN: specialized-vectors.bool
+
+<< "bool" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/char/char.factor b/basis/specialized-vectors/char/char.factor
new file mode 100644 (file)
index 0000000..c34167c
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.char ;
+IN: specialized-vectors.char
+
+<< "char" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/double/double.factor b/basis/specialized-vectors/double/double.factor
new file mode 100644 (file)
index 0000000..5e77162
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.double ;
+IN: specialized-vectors.double
+
+<< "double" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/float/float.factor b/basis/specialized-vectors/float/float.factor
new file mode 100644 (file)
index 0000000..010b448
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.float ;
+IN: specialized-vectors.float
+
+<< "float" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/functor/functor.factor b/basis/specialized-vectors/functor/functor.factor
new file mode 100644 (file)
index 0000000..0628f8b
--- /dev/null
@@ -0,0 +1,46 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: functors sequences sequences.private growable
+prettyprint.backend kernel words classes math parser ;
+IN: specialized-vectors.functor
+
+FUNCTOR: define-vector ( T -- )
+
+A   IS      ${T}-array
+<A> IS      <${A}>
+
+V   DEFINES ${T}-vector
+<V> DEFINES <${V}>
+>V  DEFINES >${V}
+V{  DEFINES ${V}{
+
+WHERE
+
+TUPLE: V { underlying A } { length array-capacity } ;
+
+: <V> <A> execute 0 V boa ; inline
+
+M: V like
+    drop dup V instance? [
+        dup A instance? [ dup length V boa ] [ >V execute ] if
+    ] unless ;
+
+M: V new-sequence drop [ <A> execute ] [ >fixnum ] bi V boa ;
+
+M: A new-resizable drop <V> execute ;
+
+M: V equal? over V instance? [ sequence= ] [ 2drop f ] if ;
+
+: >V V new clone-like ; inline
+
+M: V pprint-delims drop V{ \ } ;
+
+M: V >pprint-sequence ;
+
+M: V pprint* pprint-object ;
+
+: V{ \ } [ >V execute ] parse-literal ; parsing
+
+INSTANCE: V growable
+
+;FUNCTOR
diff --git a/basis/specialized-vectors/int/int.factor b/basis/specialized-vectors/int/int.factor
new file mode 100644 (file)
index 0000000..d77e6fd
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.int ;
+IN: specialized-vectors.int
+
+<< "int" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/long/long.factor b/basis/specialized-vectors/long/long.factor
new file mode 100644 (file)
index 0000000..a026054
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.long ;
+IN: specialized-vectors.long
+
+<< "long" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/longlong/longlong.factor b/basis/specialized-vectors/longlong/longlong.factor
new file mode 100644 (file)
index 0000000..e272ea0
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.longlong ;
+IN: specialized-vectors.longlong
+
+<< "longlong" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/short/short.factor b/basis/specialized-vectors/short/short.factor
new file mode 100644 (file)
index 0000000..26ffad4
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.short ;
+IN: specialized-vectors.short
+
+<< "short" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/specialized-vectors-docs.factor b/basis/specialized-vectors/specialized-vectors-docs.factor
new file mode 100644 (file)
index 0000000..5c0a15c
--- /dev/null
@@ -0,0 +1,35 @@
+USING: help.markup help.syntax byte-vectors ;
+IN: specialized-vectors
+
+ARTICLE: "specialized-vectors" "Specialized vectors"
+"The " { $vocab-link "specialized-vectors" } " vocabulary implements resizable sequence types for storing machine values in a space-efficient manner without boxing."
+$nl
+"For each primitive C type " { $snippet "T" } ", a set of words are defined:"
+{ $table
+    { { $snippet "T-vector" } { "The class of vectors with elements of type " { $snippet "T" } } }
+    { { $snippet "<T-vector>" } { "Constructor for vectors with elements of type " { $snippet "T" } "; stack effect " { $snippet "( len -- vector )" } } }
+    { { $snippet ">T-vector" } { "Converts a sequence into a specialized vector of type " { $snippet "T" } "; stack effect " { $snippet "( seq -- vector )" } } }
+    { { $snippet "T-vector{" } { "Literal syntax, consists of a series of values terminated by " { $snippet "}" } } }
+}
+"The primitive C types for which specialized vectors exist:"
+{ $list
+    { $snippet "char" }
+    { $snippet "uchar" }
+    { $snippet "short" }
+    { $snippet "ushort" }
+    { $snippet "int" }
+    { $snippet "uint" }
+    { $snippet "long" }
+    { $snippet "ulong" }
+    { $snippet "longlong" }
+    { $snippet "ulonglong" }
+    { $snippet "float" }
+    { $snippet "double" }
+    { $snippet "void*" }
+    { $snippet "bool" }
+}
+"Specialized vectors are generated with a functor in the " { $vocab-link "specialized-vectors.functor" } " vocabulary."
+$nl
+"The " { $vocab-link "specialized-arrays" } " vocabulary provides fixed-length versions of the above." ;
+
+ABOUT: "specialized-vectors"
diff --git a/basis/specialized-vectors/specialized-vectors-tests.factor b/basis/specialized-vectors/specialized-vectors-tests.factor
new file mode 100644 (file)
index 0000000..df077ce
--- /dev/null
@@ -0,0 +1,5 @@
+IN: specialized-vectors.tests
+USING: specialized-vectors.double tools.test kernel sequences ;
+
+[ 3 ] [ double-vector{ 1 2 } 3 over push length ] unit-test
+
diff --git a/basis/specialized-vectors/specialized-vectors.factor b/basis/specialized-vectors/specialized-vectors.factor
new file mode 100644 (file)
index 0000000..5df602c
--- /dev/null
@@ -0,0 +1,3 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: specialized-vectors
diff --git a/basis/specialized-vectors/summary.txt b/basis/specialized-vectors/summary.txt
new file mode 100644 (file)
index 0000000..9df7115
--- /dev/null
@@ -0,0 +1 @@
+Vectors of unboxed primitive C types
diff --git a/basis/specialized-vectors/tags.txt b/basis/specialized-vectors/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/basis/specialized-vectors/uchar/uchar.factor b/basis/specialized-vectors/uchar/uchar.factor
new file mode 100644 (file)
index 0000000..76cbd15
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.uchar ;
+IN: specialized-vectors.uchar
+
+<< "uchar" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/uint/uint.factor b/basis/specialized-vectors/uint/uint.factor
new file mode 100644 (file)
index 0000000..9580087
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.uint ;
+IN: specialized-vectors.uint
+
+<< "uint" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/ulong/ulong.factor b/basis/specialized-vectors/ulong/ulong.factor
new file mode 100644 (file)
index 0000000..486a9dd
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.ulong ;
+IN: specialized-vectors.ulong
+
+<< "ulong" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/ulonglong/ulonglong.factor b/basis/specialized-vectors/ulonglong/ulonglong.factor
new file mode 100644 (file)
index 0000000..c06ccec
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.ulonglong ;
+IN: specialized-vectors.ulonglong
+
+<< "ulonglong" define-vector >>
\ No newline at end of file
diff --git a/basis/specialized-vectors/ushort/ushort.factor b/basis/specialized-vectors/ushort/ushort.factor
new file mode 100644 (file)
index 0000000..6968607
--- /dev/null
@@ -0,0 +1,4 @@
+USING: specialized-vectors.functor specialized-arrays.ushort ;
+IN: specialized-vectors.ushort
+
+<< "ushort" define-vector >>
\ No newline at end of file
index 3bbba0fcb83d6e0da703fc3d5b4761f81c613fec..48cd10a7ee82243fd140efe8e35dc5efcbbcca30 100644 (file)
@@ -3,20 +3,21 @@ stack-checker.state sequences ;
 IN: stack-checker.backend.tests
 
 [ ] [
-    V{ } clone meta-d set
-    V{ } clone meta-r set
+    V{ } clone \ meta-d set
+    V{ } clone \ meta-r set
+    V{ } clone \ literals set
     0 d-in set
 ] unit-test
 
 [ 0 ] [ 0 ensure-d length ] unit-test
 
 [ 2 ] [ 2 ensure-d length ] unit-test
-[ 2 ] [ meta-d get length ] unit-test
+[ 2 ] [ meta-d length ] unit-test
 
 [ 3 ] [ 3 ensure-d length ] unit-test
-[ 3 ] [ meta-d get length ] unit-test
+[ 3 ] [ meta-d length ] unit-test
 
 [ 1 ] [ 1 ensure-d length ] unit-test
-[ 3 ] [ meta-d get length ] unit-test
+[ 3 ] [ meta-d length ] unit-test
 
 [ ] [ 1 consume-d drop ] unit-test
index 94e59950f74f20d5778171175716e93b9b582aca..7f8c920b199878fd95a06fbf200aa4065b9ea2b3 100644 (file)
@@ -4,15 +4,15 @@ USING: fry arrays generic io io.streams.string kernel math
 namespaces parser prettyprint sequences strings vectors words
 quotations effects classes continuations debugger assocs
 combinators compiler.errors accessors math.order definitions
-sets generic.standard.engines.tuple stack-checker.state
+sets generic.standard.engines.tuple hints stack-checker.state
 stack-checker.visitor stack-checker.errors
 stack-checker.values stack-checker.recursive-state ;
 IN: stack-checker.backend
 
-: push-d ( obj -- ) meta-d get push ;
+: push-d ( obj -- ) meta-d push ;
 
 : pop-d  ( -- obj )
-    meta-d get [
+    meta-d [
         <value> dup 1array #introduce, d-in inc
     ] [ pop ] if-empty ;
 
@@ -22,46 +22,52 @@ IN: stack-checker.backend
     [ <value> ] replicate ;
 
 : ensure-d ( n -- values )
-    meta-d get 2dup length > [
+    meta-d 2dup length > [
         2dup
         [ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
-        [ length d-in +@ ] [ #introduce, ] [ meta-d get push-all ] tri
-        meta-d get push-all
+        [ length d-in +@ ] [ #introduce, ] [ meta-d push-all ] tri
+        meta-d push-all
     ] when swap tail* ;
 
 : shorten-by ( n seq -- )
     [ length swap - ] keep shorten ; inline
 
 : consume-d ( n -- seq )
-    [ ensure-d ] [ meta-d get shorten-by ] bi ;
+    [ ensure-d ] [ meta-d shorten-by ] bi ;
 
-: output-d ( values -- ) meta-d get push-all ;
+: output-d ( values -- ) meta-d push-all ;
 
 : produce-d ( n -- values )
-    make-values dup meta-d get push-all ;
+    make-values dup meta-d push-all ;
 
-: push-r ( obj -- ) meta-r get push ;
+: push-r ( obj -- ) meta-r push ;
 
-: pop-r  ( -- obj )
-    meta-r get dup empty?
+: pop-r ( -- obj )
+    meta-r dup empty?
     [ too-many-r> inference-error ] [ pop ] if ;
 
 : consume-r ( n -- seq )
-    meta-r get 2dup length >
+    meta-r 2dup length >
     [ too-many-r> inference-error ] when
     [ swap tail* ] [ shorten-by ] 2bi ;
 
-: output-r ( seq -- ) meta-r get push-all ;
+: output-r ( seq -- ) meta-r push-all ;
+
+: push-literal ( obj -- )
+    literals get push ;
 
 : pop-literal ( -- rstate obj )
-    pop-d
-    [ 1array #drop, ]
-    [ literal [ recursion>> ] [ value>> ] bi ] bi ;
+    literals get [
+        pop-d
+        [ 1array #drop, ]
+        [ literal [ recursion>> ] [ value>> ] bi ] bi
+    ] [ pop recursive-state get swap ] if-empty ;
 
-GENERIC: apply-object ( obj -- )
+: literals-available? ( n -- literals ? )
+    literals get 2dup length <=
+    [ [ swap tail* ] [ shorten-by ] 2bi t ] [ 2drop f f ] if ;
 
-: push-literal ( obj -- )
-    dup <literal> make-known [ nip push-d ] [ #push, ] 2bi ;
+GENERIC: apply-object ( obj -- )
 
 M: wrapper apply-object
     wrapped>>
@@ -72,10 +78,17 @@ M: wrapper apply-object
 M: object apply-object push-literal ;
 
 : terminate ( -- )
-    terminated? on meta-d get clone meta-r get clone #terminate, ;
+    terminated? on meta-d clone meta-r clone #terminate, ;
+
+: check->r ( -- )
+    meta-r empty? [ \ too-many->r inference-error ] unless ;
 
 : infer-quot-here ( quot -- )
-    [ apply-object terminated? get not ] all? drop ;
+    meta-r [
+        V{ } clone \ meta-r set
+        [ apply-object terminated? get not ] all?
+        [ commit-literals check->r ] [ literals get delete-all ] if
+    ] dip \ meta-r set ;
 
 : infer-quot ( quot rstate -- )
     recursive-state get [
@@ -103,10 +116,10 @@ M: object apply-object push-literal ;
     ] if ;
 
 : infer->r ( n -- )
-    consume-d dup copy-values [ #>r, ] [ nip output-r ] 2bi ;
+    consume-d dup copy-values [ nip output-r ] [ #>r, ] 2bi ;
 
 : infer-r> ( n -- )
-    consume-r dup copy-values [ #r>, ] [ nip output-d ] 2bi ;
+    consume-r dup copy-values [ nip output-d ] [ #r>, ] 2bi ;
 
 : undo-infer ( -- )
     recorded get [ f "inferred-effect" set-word-prop ] each ;
@@ -125,22 +138,17 @@ M: object apply-object push-literal ;
     ] 2bi ; inline
 
 : infer-word-def ( word -- )
-    [ def>> ] [ add-recursive-state ] bi infer-quot ;
-
-: check->r ( -- )
-    meta-r get empty? terminated? get or
-    [ \ too-many->r inference-error ] unless ;
+    [ specialized-def ] [ add-recursive-state ] bi infer-quot ;
 
 : end-infer ( -- )
-    check->r
-    meta-d get clone #return, ;
+    meta-d clone #return, ;
 
 : effect-required? ( word -- ? )
     {
         { [ dup inline? ] [ drop f ] }
         { [ dup deferred? ] [ drop f ] }
         { [ dup crossref? not ] [ drop f ] }
-        [ def>> [ [ word? ] [ primitive? not ] bi and ] contains? ]
+        [ def>> [ word? ] contains? ]
     } cond ;
 
 : ?missing-effect ( word -- )
index 7b461d0028bbde2f9653fec50eb32c27e380bd34..e4c11960de90acd5dcdf8aa4d6fb1ccc80b20a73 100644 (file)
@@ -57,9 +57,9 @@ SYMBOL: quotations
     branch-variable ;
 
 : datastack-phi ( seq -- phi-in phi-out )
-    [ d-in branch-variable ] [ meta-d active-variable ] bi
+    [ d-in branch-variable ] [ meta-d active-variable ] bi
     unify-branches
-    [ d-in set ] [ ] [ dup >vector meta-d set ] tri* ;
+    [ d-in set ] [ ] [ dup >vector meta-d set ] tri* ;
 
 : terminated-phi ( seq -- terminated )
     terminated? branch-variable ;
@@ -74,17 +74,25 @@ SYMBOL: quotations
     tri ;
 
 : copy-inference ( -- )
-    meta-d [ clone ] change
-    V{ } clone meta-r set
+    meta-d [ clone ] change
+    literals [ clone ] change
     d-in [ ] change ;
 
-: infer-branch ( literal -- namespace )
+GENERIC: infer-branch ( literal -- namespace )
+
+M: literal infer-branch
     [
         copy-inference
         nest-visitor
         [ value>> quotation set ] [ infer-literal-quot ] bi
-        check->r
-    ] H{ } make-assoc ; inline
+    ] H{ } make-assoc ;
+
+M: callable infer-branch
+    [
+        copy-inference
+        nest-visitor
+        [ quotation set ] [ infer-quot-here ] bi
+    ] H{ } make-assoc ;
 
 : infer-branches ( branches -- input children data )
     [ pop-d ] dip
@@ -96,16 +104,19 @@ SYMBOL: quotations
     [ first2 #if, ] dip compute-phi-function ;
 
 : infer-if ( -- )
-    2 consume-d
-    dup [ known [ curried? ] [ composed? ] bi or ] contains? [
-        output-d
-        [ rot [ drop call ] [ nip call ] if ]
-        infer-quot-here
+    2 literals-available? [
+        (infer-if)
     ] [
-        [ #drop, ] [ [ literal ] map (infer-if) ] bi
+        drop 2 consume-d
+        dup [ known [ curried? ] [ composed? ] bi or ] contains? [
+            output-d
+            [ rot [ drop call ] [ nip call ] if ]
+            infer-quot-here
+        ] [
+            [ #drop, ] [ [ literal ] map (infer-if) ] bi
+        ] if
     ] if ;
 
 : infer-dispatch ( -- )
-    pop-literal nip [ <literal> ] map
-    infer-branches
+    pop-literal nip infer-branches
     [ #dispatch, ] dip compute-phi-function ;
index f4d7c80e1313005f915ca0512a6fa24f3fe6da90..d4a074031dc319a92f996dd2c0e83977d2c87f36 100644 (file)
@@ -115,7 +115,6 @@ ARTICLE: "inference-errors" "Inference warnings and errors"
 { $subsection inconsistent-recursive-call-error }
 "Retain stack usage errors:"
 { $subsection too-many->r }
-{ $subsection too-many-r> }
-"See " { $link "shuffle-words" } " for retain stack usage conventions. This error can only occur if your code calls " { $link >r } " and " { $link r> } " directly. The " { $link dip } " combinator is safer to use because there is no way to leave the retain stack in an unbalanced state." ;
+{ $subsection too-many-r> } ;
 
 ABOUT: "inference-errors"
index 31ae0a6789f9393b3a271aee1d0886142aefff5e..5b6b3c089379446056f197d84137f6776f22d492 100644 (file)
@@ -13,7 +13,7 @@ M: inference-error compiler-error-type type>> ;
 M: inference-error error-help error>> error-help ;
 
 : (inference-error) ( ... class type -- * )
-    >r boa r>
+    [ boa ] dip
     recursive-state get word>>
     \ inference-error boa throw ; inline
 
index b6a988652b8415a648b5e27f3d4ae02f7dae7277..23283fb6e309064e8bd185f67ffa803befb846d3 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry namespaces assocs kernel sequences words accessors
 definitions math math.order effects classes arrays combinators
-vectors arrays
+vectors arrays hints
 stack-checker.state
 stack-checker.errors
 stack-checker.values
@@ -17,7 +17,7 @@ IN: stack-checker.inlining
 ! having to handle recursive inline words.
 
 : infer-inline-word-def ( word label -- )
-    [ drop def>> ] [ add-inline-word ] 2bi infer-quot ;
+    [ drop specialized-def ] [ add-inline-word ] 2bi infer-quot ;
 
 TUPLE: inline-recursive < identity-tuple
 id
@@ -51,14 +51,14 @@ SYMBOL: enter-out
 : prepare-stack ( word -- )
     required-stack-effect in>>
     [ length ensure-d drop ] [
-        meta-d get clone enter-in set
-        meta-d get swap make-copies enter-out set
+        meta-d clone enter-in set
+        meta-d swap make-copies enter-out set
     ] bi ;
 
 : emit-enter-recursive ( label -- )
     enter-out get >>enter-out
     enter-in get enter-out get #enter-recursive,
-    enter-out get >vector meta-d set ;
+    enter-out get >vector meta-d set ;
 
 : entry-stack-height ( label -- stack )
     enter-out>> length ;
@@ -77,7 +77,7 @@ SYMBOL: enter-out
 
 : end-recursive-word ( word label -- )
     [ check-return ]
-    [ meta-d get dup copy-values dup meta-d set #return-recursive, ]
+    [ meta-d dup copy-values dup \ meta-d set #return-recursive, ]
     bi ;
 
 : recursive-word-inputs ( label -- n )
@@ -95,10 +95,8 @@ SYMBOL: enter-out
         [ nip ]
         2tri
 
-        check->r
-
         dup recursive-word-inputs
-        meta-d get
+        meta-d
         stack-visitor get
         terminated? get
     ] with-scope ;
@@ -116,7 +114,7 @@ SYMBOL: enter-out
     swap word>> required-stack-effect in>> length tail* ;
 
 : call-site-stack ( label -- stack )
-    meta-d get trim-stack ;
+    meta-d trim-stack ;
 
 : trimmed-enter-out ( label -- stack )
     dup enter-out>> trim-stack ;
@@ -131,7 +129,7 @@ SYMBOL: enter-out
 
 : adjust-stack-effect ( effect -- effect' )
     [ in>> ] [ out>> ] bi
-    meta-d get length pick length [-]
+    meta-d length pick length [-]
     object <repetition> '[ _ prepend ] bi@
     <effect> ;
 
@@ -142,6 +140,7 @@ SYMBOL: enter-out
     ] [ drop undeclared-recursion-error inference-error ] if ;
 
 : inline-word ( word -- )
+    commit-literals
     [ inlined-dependency depends-on ]
     [
         dup inline-recursive-label [
index 986bbe4c7239981817141c31b6c988ab556f5fbc..28634f2d44e8fd0c9986d0dac2a605930ae61ba7 100644 (file)
@@ -63,7 +63,9 @@ IN: stack-checker.known-words
 
 GENERIC: infer-call* ( value known -- )
 
-: infer-call ( value -- ) dup known infer-call* ;
+: (infer-call) ( value -- ) dup known infer-call* ;
+
+: infer-call ( -- ) pop-d (infer-call) ;
 
 M: literal infer-call*
     [ 1array #drop, ] [ infer-literal-quot ] bi* ;
@@ -73,7 +75,7 @@ M: curried infer-call*
     [ uncurry ] infer-quot-here
     [ quot>> known pop-d [ set-known ] keep ]
     [ obj>> known pop-d [ set-known ] keep ] bi
-    push-d infer-call ;
+    push-d (infer-call) ;
 
 M: composed infer-call*
     swap push-d
@@ -81,20 +83,38 @@ M: composed infer-call*
     [ quot2>> known pop-d [ set-known ] keep ]
     [ quot1>> known pop-d [ set-known ] keep ] bi
     push-d push-d
-    1 infer->r pop-d infer-call
-    terminated? get [ 1 infer-r> pop-d infer-call ] unless ;
+    1 infer->r infer-call
+    terminated? get [ 1 infer-r> infer-call ] unless ;
 
 M: object infer-call*
     \ literal-expected inference-warning ;
 
 : infer-slip ( -- )
-    1 infer->r pop-d infer-call 1 infer-r> ;
+    1 infer->r infer-call 1 infer-r> ;
 
 : infer-2slip ( -- )
-    2 infer->r pop-d infer-call 2 infer-r> ;
+    2 infer->r infer-call 2 infer-r> ;
 
 : infer-3slip ( -- )
-    3 infer->r pop-d infer-call 3 infer-r> ;
+    3 infer->r infer-call 3 infer-r> ;
+
+: infer-dip ( -- )
+    literals get
+    [ \ dip def>> infer-quot-here ]
+    [ pop 1 infer->r infer-quot-here 1 infer-r>  ]
+    if-empty ;
+
+: infer-2dip ( -- )
+    literals get
+    [ \ 2dip def>> infer-quot-here ]
+    [ pop 2 infer->r infer-quot-here 2 infer-r>  ]
+    if-empty ;
+
+: infer-3dip ( -- )
+    literals get
+    [ \ 3dip def>> infer-quot-here ]
+    [ pop 3 infer->r infer-quot-here 3 infer-r>  ]
+    if-empty ;
 
 : infer-curry ( -- )
     2 consume-d
@@ -134,11 +154,11 @@ M: object infer-call*
 
 : infer-load-locals ( -- )
     pop-literal nip
-    consume-d dup reverse copy-values dup output-r
-    [ [ f f ] dip ] [ reverse swap zip ] 2bi #shuffle, ;
+    consume-d dup copy-values dup output-r
+    [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
 
 : infer-get-local ( -- )
-    [let* | n [ pop-literal nip ]
+    [let* | n [ pop-literal nip 1 swap - ]
             in-r [ n consume-r ]
             out-d [ in-r first copy-value 1array ]
             out-r [ in-r copy-values ] |
@@ -157,11 +177,14 @@ M: object infer-call*
         { \ >r [ 1 infer->r ] }
         { \ r> [ 1 infer-r> ] }
         { \ declare [ infer-declare ] }
-        { \ call [ pop-d infer-call ] }
-        { \ (call) [ pop-d infer-call ] }
+        { \ call [ infer-call ] }
+        { \ (call) [ infer-call ] }
         { \ slip [ infer-slip ] }
         { \ 2slip [ infer-2slip ] }
         { \ 3slip [ infer-3slip ] }
+        { \ dip [ infer-dip ] }
+        { \ 2dip [ infer-2dip ] }
+        { \ 3dip [ infer-3dip ] }
         { \ curry [ infer-curry ] }
         { \ compose [ infer-compose ] }
         { \ execute [ infer-execute ] }
@@ -186,11 +209,14 @@ M: object infer-call*
 : infer-local-writer ( word -- )
     (( value -- )) apply-word/effect ;
 
+: infer-local-word ( word -- )
+    "local-word-def" word-prop infer-quot-here ;
+
 {
-    >r r> declare call (call) slip 2slip 3slip curry compose
-    execute (execute) if dispatch <tuple-boa> (throw)
-    load-locals get-local drop-locals do-primitive alien-invoke
-    alien-indirect alien-callback
+    >r r> declare call (call) slip 2slip 3slip dip 2dip 3dip
+    curry compose execute (execute) if dispatch <tuple-boa>
+    (throw) load-locals get-local drop-locals do-primitive
+    alien-invoke alien-indirect alien-callback
 } [ t "special" set-word-prop ] each
 
 { call execute dispatch load-locals get-local drop-locals }
@@ -209,6 +235,7 @@ M: object infer-call*
         { [ dup local? ] [ infer-local-reader ] }
         { [ dup local-reader? ] [ infer-local-reader ] }
         { [ dup local-writer? ] [ infer-local-writer ] }
+        { [ dup local-word? ] [ infer-local-word ] }
         { [ dup recursive-word? ] [ call-recursive-word ] }
         [ dup infer-word apply-word/effect ]
     } cond ;
@@ -277,6 +304,8 @@ M: object infer-call*
 \ <complex> { real real } { complex } define-primitive
 \ <complex> make-foldable
 
+\ both-fixnums? { object object } { object } define-primitive
+
 \ fixnum+ { fixnum fixnum } { integer } define-primitive
 \ fixnum+ make-foldable
 
@@ -530,7 +559,8 @@ M: object infer-call*
 \ string-nth { fixnum string } { fixnum } define-primitive
 \ string-nth make-flushable
 
-\ set-string-nth { fixnum fixnum string } { } define-primitive
+\ set-string-nth-slow { fixnum fixnum string } { } define-primitive
+\ set-string-nth-fast { fixnum fixnum string } { } define-primitive
 
 \ resize-array { integer array } { array } define-primitive
 \ resize-array make-flushable
@@ -614,3 +644,9 @@ M: object infer-call*
 \ modify-code-heap { array object } { } define-primitive
 
 \ unimplemented { } { } define-primitive
+
+\ gc-reset { } { } define-primitive
+
+\ gc-stats { } { array } define-primitive
+
+\ jit-compile { quotation } { } define-primitive
index 2706ec60ef490782c7da033dfb5f1bac5e27e665..130147f798f0316b825a084d348d0383bfe574d6 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs arrays namespaces sequences kernel definitions
 math effects accessors words fry classes.algebra
-compiler.units ;
+compiler.units stack-checker.values stack-checker.visitor ;
 IN: stack-checker.state
 
 ! Did the current control-flow path throw an error?
@@ -11,23 +11,40 @@ SYMBOL: terminated?
 ! Number of inputs current word expects from the stack
 SYMBOL: d-in
 
+DEFER: commit-literals
+
 ! Compile-time data stack
-SYMBOL: meta-d
+: meta-d ( -- stack ) commit-literals \ meta-d get ;
 
 ! Compile-time retain stack
-SYMBOL: meta-r
+: meta-r ( -- stack ) \ meta-r get ;
+
+! Uncommitted literals. This is a form of local dead-code
+! elimination; the goal is to reduce the number of IR nodes
+! which get constructed. Technically it is redundant since
+! we do global DCE later, but it speeds up compile time.
+SYMBOL: literals
+
+: (push-literal) ( obj -- )
+    dup <literal> make-known
+    [ nip \ meta-d get push ] [ #push, ] 2bi ;
+
+: commit-literals ( -- )
+    literals get [
+        [ [ (push-literal) ] each ] [ delete-all ] bi
+    ] unless-empty ;
 
-: current-stack-height ( -- n ) meta-d get length d-in get - ;
+: current-stack-height ( -- n ) meta-d length d-in get - ;
 
 : current-effect ( -- effect )
     d-in get
-    meta-d get length <effect>
+    meta-d length <effect>
     terminated? get >>terminated? ;
 
 : init-inference ( -- )
     terminated? off
-    V{ } clone meta-d set
-    V{ } clone meta-r set
+    V{ } clone meta-d set
+    V{ } clone literals set
     0 d-in set ;
 
 ! Words that the current quotation depends on
index 6e11eb1189aeee0cd50bfb95874e17587e5b9c2d..299dc1b5515b473289219960107bea44f8edff6d 100644 (file)
@@ -19,11 +19,8 @@ IN: stack-checker.transforms
     rot with-datastack first2
     dup [
         [
-            [ drop ] [
-                [ length meta-d get '[ _ pop* ] times ]
-                [ #drop, ]
-                bi
-            ] bi*
+            [ drop ]
+            [ [ length meta-d shorten-by ] [ #drop, ] bi ] bi*
         ] 2dip
         swap infer-quot
     ] [
@@ -94,7 +91,10 @@ IN: stack-checker.transforms
         [ "method-class" word-prop ]
         [ "method-generic" word-prop ] bi
         [ inlined-dependency depends-on ] bi@
-    ] [ next-method-quot ] bi
+    ] [
+        [ next-method-quot ]
+        [ '[ _ no-next-method ] ] bi or
+    ] bi
 ] 1 define-transform
 
 ! Constructors
diff --git a/basis/state-tables/authors.txt b/basis/state-tables/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/state-tables/state-tables-tests.factor b/basis/state-tables/state-tables-tests.factor
deleted file mode 100644 (file)
index b86c4f5..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-USING: kernel state-tables tools.test ;
-IN: state-tables.tests
-
-: test-table
-    <table>
-    "a" "c" "z" <entry> over set-entry
-    "a" "o" "y" <entry> over set-entry
-    "a" "l" "x" <entry> over set-entry
-    "b" "o" "y" <entry> over set-entry
-    "b" "l" "x" <entry> over set-entry
-    "b" "s" "u" <entry> over set-entry ;
-
-[
-    T{
-        table
-        f
-        H{ 
-            { "a" H{ { "l" "x" } { "c" "z" } { "o" "y" } } }
-            { "b" H{ { "l" "x" } { "s" "u" } { "o" "y" } } }
-        }
-        H{ { "l" t } { "s" t } { "c" t } { "o" t } }
-        f
-        H{ }
-    }
-] [ test-table ] unit-test
-
-[ "x" t ] [ "a" "l" test-table get-entry ] unit-test
-[ "har" t ] [
-    "a" "z" "har" <entry> test-table [ set-entry ] keep
-    >r "a" "z" r> get-entry
-] unit-test
-
-: vector-test-table
-    <vector-table>
-    "a" "c" "z" <entry> over add-entry
-    "a" "c" "r" <entry> over add-entry
-    "a" "o" "y" <entry> over add-entry
-    "a" "l" "x" <entry> over add-entry
-    "b" "o" "y" <entry> over add-entry
-    "b" "l" "x" <entry> over add-entry
-    "b" "s" "u" <entry> over add-entry ;
-
-[
-T{ vector-table f
-    H{ 
-        { "a"
-            H{ { "l" "x" } { "c" V{ "z" "r" } } { "o" "y" } } }
-        { "b"
-            H{ { "l" "x" } { "s" "u" } { "o" "y" } } }
-    }
-    H{ { "l" t } { "s" t } { "c" t } { "o" t } }
-    f
-    H{ }
-}
-] [ vector-test-table ] unit-test
-
diff --git a/basis/state-tables/state-tables.factor b/basis/state-tables/state-tables.factor
deleted file mode 100644 (file)
index ecb258c..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces make sequences vectors assocs accessors ;
-IN: state-tables
-
-TUPLE: table rows columns start-state final-states ;
-TUPLE: entry row-key column-key value ;
-
-GENERIC: add-entry ( entry table -- )
-
-: make-table ( class -- obj )
-    new
-        H{ } clone >>rows
-        H{ } clone >>columns
-        H{ } clone >>final-states ;
-
-: <table> ( -- obj )
-    table make-table ;
-
-C: <entry> entry
-
-: (add-row) ( row-key table -- row )
-    2dup rows>> at* [
-        2nip
-    ] [
-        drop H{ } clone [ -rot rows>> set-at ] keep
-    ] if ;
-
-: add-row ( row-key table -- )
-    (add-row) drop ;
-
-: add-column ( column-key table -- )
-    t -rot columns>> set-at ;
-
-: set-row ( row row-key table -- )
-    rows>> set-at ;
-
-: lookup-row ( row-key table -- row/f ? )
-    rows>> at* ;
-
-: row-exists? ( row-key table -- ? )
-    lookup-row nip ;
-
-: lookup-column ( column-key table -- column/f ? )
-    columns>> at* ;
-
-: column-exists? ( column-key table -- ? )
-    lookup-column nip ;
-
-ERROR: no-row key ;
-ERROR: no-column key ;
-
-: get-row ( row-key table -- row )
-    dupd lookup-row [
-        nip
-    ] [
-        drop no-row
-    ] if ;
-
-: get-column ( column-key table -- column )
-    dupd lookup-column [
-        nip
-    ] [
-        drop no-column
-    ] if ;
-
-: get-entry ( row-key column-key table -- obj ? )
-    swapd lookup-row [
-        at*
-    ] [
-        2drop f f
-    ] if ;
-
-: (set-entry) ( entry table -- value column-key row )
-    [ >r column-key>> r> add-column ] 2keep
-    dupd >r row-key>> r> (add-row)
-    >r [ value>> ] keep column-key>> r> ;
-
-: set-entry ( entry table -- )
-    (set-entry) set-at ;
-
-: delete-entry ( entry table -- )
-    >r [ column-key>> ] [ row-key>> ] bi r>
-    lookup-row [ delete-at ] [ 2drop ] if ;
-
-: swap-rows ( row-key1 row-key2 table -- )
-    [ tuck get-row >r get-row r> ] 3keep
-    >r >r rot r> r> [ set-row ] keep set-row ;
-
-: member?* ( obj obj -- bool )
-    2dup = [ 2drop t ] [ member? ] if ;
-
-: find-by-column ( column-key data table -- seq )
-    swapd 2dup lookup-column 2drop 
-    [
-        rows>> [
-            pick swap at* [ 
-                >r pick r> member?* [ , ] [ drop ] if
-            ] [ 
-                2drop
-            ] if 
-        ] assoc-each
-    ] { } make 2nip ;
-
-
-TUPLE: vector-table < table ;
-: <vector-table> ( -- obj )
-    vector-table make-table ;
-
-: add-hash-vector ( value key hash -- )
-    2dup at* [
-        dup vector? [
-            2nip push
-        ] [
-            V{ } clone [ push ] keep
-            -rot >r >r [ push ] keep r> r> set-at
-        ] if
-    ] [
-        drop set-at
-    ] if ;
-M: vector-table add-entry ( entry table -- )
-    (set-entry) add-hash-vector ;
diff --git a/basis/struct-arrays/authors.txt b/basis/struct-arrays/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/struct-arrays/struct-arrays-docs.factor b/basis/struct-arrays/struct-arrays-docs.factor
new file mode 100644 (file)
index 0000000..0a627f7
--- /dev/null
@@ -0,0 +1,23 @@
+IN: struct-arrays
+USING: help.markup help.syntax alien strings math ;
+
+HELP: struct-array
+{ $class-description "The class of C struct and union arrays."
+$nl
+"The " { $slot "underlying" } " slot holds a " { $link c-ptr } " with the raw data. This pointer can be passed to C functions." } ;
+
+HELP: <struct-array>
+{ $values { "length" integer } { "c-type" string } { "struct-array" struct-array } }
+{ $description "Creates a new array for holding values of the specified C type." } ;
+
+HELP: <direct-struct-array>
+{ $values { "alien" c-ptr } { "length" integer } { "c-type" string } { "struct-array" struct-array } }
+{ $description "Creates a new array for holding values of the specified C type, backed by the memory at " { $snippet "alien" } "." } ;
+
+ARTICLE: "struct-arrays" "C struct and union arrays"
+"The " { $vocab-link "struct-arrays" } " vocabulary implements arrays specialized for holding C struct and union values."
+{ $subsection struct-array }
+{ $subsection <struct-array> }
+{ $subsection <direct-struct-array> } ;
+
+ABOUT: "struct-arrays"
diff --git a/basis/struct-arrays/struct-arrays-tests.factor b/basis/struct-arrays/struct-arrays-tests.factor
new file mode 100755 (executable)
index 0000000..d2bf583
--- /dev/null
@@ -0,0 +1,29 @@
+IN: struct-arrays.tests
+USING: struct-arrays tools.test kernel math sequences
+alien.syntax alien.c-types destructors libc accessors ;
+
+C-STRUCT: test-struct
+{ "int" "x" }
+{ "int" "y" } ;
+
+: make-point ( x y -- struct )
+    "test-struct" <c-object>
+    [ set-test-struct-y ] keep
+    [ set-test-struct-x ] keep ;
+
+[ 5/4 ] [
+    2 "test-struct" <struct-array>
+    1 2 make-point over set-first
+    3 4 make-point over set-second
+    0 [ [ test-struct-x ] [ test-struct-y ] bi / + ] reduce
+] unit-test
+
+[ 5/4 ] [
+    [
+        2 "test-struct" malloc-struct-array
+        dup underlying>> &free drop
+        1 2 make-point over set-first
+        3 4 make-point over set-second
+        0 [ [ test-struct-x ] [ test-struct-y ] bi / + ] reduce
+    ] with-destructors
+] unit-test
diff --git a/basis/struct-arrays/struct-arrays.factor b/basis/struct-arrays/struct-arrays.factor
new file mode 100755 (executable)
index 0000000..33a469d
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.c-types byte-arrays kernel libc
+math sequences sequences.private ;
+IN: struct-arrays
+
+TUPLE: struct-array
+{ underlying c-ptr read-only }
+{ length array-capacity read-only }
+{ element-size array-capacity read-only } ;
+
+M: struct-array length length>> ;
+
+M: struct-array nth-unsafe
+    [ element-size>> * ] [ underlying>> ] bi <displaced-alien> ;
+
+M: struct-array set-nth-unsafe
+    [ nth-unsafe swap ] [ element-size>> ] bi memcpy ;
+
+M: struct-array new-sequence
+    element-size>> [ * <byte-array> ] 2keep struct-array boa ; inline
+
+: <struct-array> ( length c-type -- struct-array )
+    heap-size [ * <byte-array> ] 2keep struct-array boa ; inline
+
+ERROR: bad-byte-array-length byte-array ;
+
+: byte-array>struct-array ( byte-array c-type -- struct-array )
+    heap-size [
+        [ dup length ] dip /mod 0 =
+        [ drop bad-byte-array-length ] unless
+    ] keep struct-array boa ; inline
+
+: <direct-struct-array> ( alien length c-type -- struct-array )
+    struct-array boa ; inline
+
+: malloc-struct-array ( length c-type -- struct-array )
+    heap-size [ calloc ] 2keep <direct-struct-array> ;
+
+INSTANCE: struct-array sequence
diff --git a/basis/struct-arrays/summary.txt b/basis/struct-arrays/summary.txt
new file mode 100644 (file)
index 0000000..0458b5a
--- /dev/null
@@ -0,0 +1 @@
+Arrays of C structs and unions
diff --git a/basis/struct-arrays/tags.txt b/basis/struct-arrays/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index aca09b939c4e374d89d3cb02f711c968906ae5d8..a6eaff44926f7c3c4e9ce4dd4354c2ebfe1ed45c 100644 (file)
@@ -81,7 +81,7 @@ TUPLE: entry title url description date ;
         [
             { "content" "summary" } any-tag-named
             dup children>> [ string? not ] contains?
-            [ children>> [ write-chunk ] with-string-writer ]
+            [ children>> [ write-xml-chunk ] with-string-writer ]
             [ children>string ] if >>description
         ]
         [
index cc2216545d4001e8beb2238f2b3a48d62c637adc..a1d7e50594ae5fae4b7f4b7f77dc8f8332f3b838 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax kernel kernel.private io
 threads.private continuations init quotations strings
-assocs heaps boxes namespaces deques ;
+assocs heaps boxes namespaces deques dlists ;
 IN: threads
 
 ARTICLE: "threads-start/stop" "Starting and stopping threads"
@@ -82,7 +82,7 @@ $nl
 { $notes "In most cases, user code should call " { $link spawn } " instead, however for control over the error handler quotation, threads can be created with " { $link <thread> } " then passed to " { $link (spawn) } "." } ;
 
 HELP: run-queue
-{ $values { "queue" deque } }
+{ $values { "dlist" dlist } }
 { $var-description "Global variable holding the queue of runnable threads. Calls to " { $link yield } " switch to the thread which has been in the queue for the longest period of time."
 $nl
 "By convention, threads are queued with " { $link push-front } 
@@ -97,6 +97,7 @@ HELP: resume-with
 { $description "Adds a thread to the end of the run queue together with an object to pass to the thread. The thread must have previously been suspended by a call to " { $link suspend } "; the object is returned from the " { $link suspend } " call." } ;
 
 HELP: sleep-queue
+{ $values { "heap" min-heap } }
 { $var-description "A " { $link min-heap } " storing the queue of sleeping threads." } ;
 
 HELP: sleep-time
index 5dca7be6336e86bb321f2217eb62a077009b90d9..305ef0cca3b8f34c7d336a62f6c64bd3f1390e7f 100644 (file)
@@ -4,7 +4,7 @@
 USING: arrays hashtables heaps kernel kernel.private math
 namespaces sequences vectors continuations continuations.private
 dlists assocs system combinators init boxes accessors
-math.order deques strings quotations ;
+math.order deques strings quotations fry ;
 IN: threads
 
 SYMBOL: initial-thread
@@ -36,7 +36,7 @@ sleep-entry ;
 : tchange ( key quot -- )
     tnamespace swap change-at ; inline
 
-: threads 64 getenv ;
+: threads ( -- assoc ) 64 getenv ;
 
 : thread ( id -- thread ) threads at ;
 
@@ -73,9 +73,9 @@ PRIVATE>
 : <thread> ( quot name -- thread )
     \ thread new-thread ;
 
-: run-queue 65 getenv ;
+: run-queue ( -- dlist ) 65 getenv ;
 
-: sleep-queue 66 getenv ;
+: sleep-queue ( -- heap ) 66 getenv ;
 
 : resume ( thread -- )
     f >>state
@@ -89,7 +89,7 @@ PRIVATE>
     f >>state
     check-registered 2array run-queue push-front ;
 
-: sleep-time ( -- ms/f )
+: sleep-time ( -- us/f )
     {
         { [ run-queue deque-empty? not ] [ 0 ] }
         { [ sleep-queue heap-empty? ] [ f ] }
@@ -101,7 +101,7 @@ DEFER: stop
 <PRIVATE
 
 : schedule-sleep ( thread dt -- )
-    >r check-registered dup r> sleep-queue heap-push*
+    [ check-registered dup ] dip sleep-queue heap-push*
     >>sleep-entry drop ;
 
 : expire-sleep? ( heap -- ? )
@@ -164,10 +164,8 @@ PRIVATE>
 
 : suspend ( quot state -- obj )
     [
-        >r
-        >r self swap call
-        r> self (>>state)
-        r> self continuation>> >box
+        [ [ self swap call ] dip self (>>state) ] dip
+        self continuation>> >box
         next
     ] callcc1 2nip ; inline
 
@@ -176,7 +174,7 @@ PRIVATE>
 GENERIC: sleep-until ( time/f -- )
 
 M: integer sleep-until
-    [ schedule-sleep ] curry "sleep" suspend drop ;
+    '[ _ schedule-sleep ] "sleep" suspend drop ;
 
 M: f sleep-until
     drop [ drop ] "interrupt" suspend drop ;
@@ -200,11 +198,11 @@ M: real sleep
     <thread> [ (spawn) ] keep ;
 
 : spawn-server ( quot name -- thread )
-    >r [ loop ] curry r> spawn ;
+    [ '[ _ loop ] ] dip spawn ;
 
 : in-thread ( quot -- )
-    >r datastack r>
-    [ >r set-datastack r> call ] 2curry
+    [ datastack ] dip
+    '[ _ set-datastack _ call ]
     "Thread" spawn drop ;
 
 GENERIC: error-in-thread ( error thread -- )
index c61b4547a94a0226e6184d10080a08ffdb872433..c88e959b8e9fa1468f0dce1cc22d625c5a5d754a 100644 (file)
@@ -4,9 +4,17 @@ IN: tools.annotations
 
 ARTICLE: "tools.annotations" "Word annotations"
 "The word annotation feature modifies word definitions to add debugging code. You can restore the old definition by calling " { $link reset } " on the word in question."
+$nl
+"Printing messages when a word is called or returns:"
 { $subsection watch }
+{ $subsection watch-vars }
+"Starting the walker when a word is called:"
 { $subsection breakpoint }
 { $subsection breakpoint-if }
+"Timing words:"
+{ $subsection reset-word-timing }
+{ $subsection add-timing }
+{ $subsection word-timing. }
 "All of the above words are implemented using a single combinator which applies a quotation to a word definition to yield a new definition:"
 { $subsection annotate } ;
 
@@ -63,3 +71,13 @@ HELP: word-inputs
      { "seq" sequence } }
 { $description "Makes a sequence of the inputs to a word by counting the number of inputs in the stack effect and saving that many items from the datastack." } ;
 
+HELP: add-timing
+{ $values { "word" word } }
+{ $description "Adds timing code to a word, which records its total running time, including that of words it calls, on every invocation." }
+{ $see-also "timing" "profiling" } ;
+
+HELP: reset-word-timing
+{ $description "Resets the word timing table." } ;
+
+HELP: word-timing.
+{ $description "Prints the word timing table." } ;
index 1e1eccb8b592dbe1d24c74361b394ca67225c86b..1e766e3dec2e279b1a5596308529d260264dd343 100644 (file)
@@ -1,4 +1,4 @@
-USING: tools.test tools.annotations math parser eval
+USING: tools.test tools.annotations tools.time math parser eval
 io.streams.string kernel ;
 IN: tools.annotations.tests
 
index c836bfc2b6610f3e73bb31dbacf3a5f1f2e2a78b..ecf3ba0a76563dea2f1a784cb4054003edfecd5a 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel words parser io summary quotations
-sequences prettyprint continuations effects definitions
-compiler.units namespaces assocs tools.walker generic
-inspector fry ;
+USING: accessors kernel math sorting words parser io summary
+quotations sequences prettyprint continuations effects
+definitions compiler.units namespaces assocs tools.walker
+tools.time generic inspector fry ;
 IN: tools.annotations
 
 GENERIC: reset ( word -- )
@@ -20,18 +20,20 @@ M: word reset
         f "unannotated-def" set-word-prop
     ] [ drop ] if ;
 
+ERROR: cannot-annotate-twice word ;
+
 : annotate ( word quot -- )
     over "unannotated-def" word-prop [
-        "Cannot annotate a word twice" throw
+        over cannot-annotate-twice
     ] when
     [
         over dup def>> "unannotated-def" set-word-prop
-        >r dup def>> r> call define
+        [ dup def>> ] dip call define
     ] with-compilation-unit ; inline
 
 : word-inputs ( word -- seq )
     stack-effect [
-        >r datastack r> in>> length tail*
+        [ datastack ] dip in>> length tail*
     ] [
         datastack
     ] if* ;
@@ -41,34 +43,38 @@ M: word reset
     word-inputs stack.
     "\\--" print flush ;
 
-: leaving ( str -- )
-    "/-- Leaving: " write dup .
+: word-outputs ( word -- seq )
     stack-effect [
-        >r datastack r> out>> length tail* stack.
+        [ datastack ] dip out>> length tail*
     ] [
-        .s
-    ] if* "\\--" print flush ;
+        datastack
+    ] if* ;
+
+: leaving ( str -- )
+    "/-- Leaving: " write dup .
+    word-outputs stack.
+     "\\--" print flush ;
 
-: (watch) ( word def -- def ) over '[ _ entering @ _ leaving ] ;
+: (watch) ( word def -- def )
+    over '[ _ entering @ _ leaving ] ;
 
 : watch ( word -- )
     dup [ (watch) ] annotate ;
 
-: (watch-vars) ( quot word vars -- newquot )
-    rot
+: (watch-vars) ( word vars quot -- newquot )
    '[
-        "--- Entering: "       write _ .
+        "--- Entering: " write _ .
         "--- Variable values:" print _ [ dup get ] H{ } map>assoc describe
         @
     ] ;
 
 : watch-vars ( word vars -- )
-    dupd [ (watch-vars) ] 2curry annotate ;
+    dupd '[ [ _ _ ] dip (watch-vars) ] annotate ;
 
 GENERIC# annotate-methods 1 ( word quot -- )
 
 M: generic annotate-methods
-    >r "methods" word-prop values r> [ annotate ] curry each ;
+    [ "methods" word-prop values ] dip [ annotate ] curry each ;
 
 M: word annotate-methods
     annotate ;
@@ -77,4 +83,22 @@ M: word annotate-methods
     [ add-breakpoint ] annotate-methods ;
 
 : breakpoint-if ( word quot -- )
-    [ [ [ break ] when ] rot 3append ] curry annotate-methods ;
+    '[ [ _ [ [ break ] when ] ] dip 3append ] annotate-methods ;
+
+SYMBOL: word-timing
+
+word-timing global [ H{ } clone or ] change-at
+
+: reset-word-timing ( -- )
+    word-timing get clear-assoc ;
+
+: (add-timing) ( def word -- def' )
+    '[ _ benchmark _ word-timing get at+ ] ;
+
+: add-timing ( word -- )
+    dup '[ _ (add-timing) ] annotate ;
+
+: word-timing. ( -- )
+    word-timing get
+    >alist [ 1000000 /f ] assoc-map sort-values
+    simple-table. ;
index 2306ff53a8cd51eb25d61ffc9e3792c54264d448..084b97970d63e00ffc260fda7c6f69b13f55adcf 100644 (file)
@@ -33,8 +33,8 @@ IN: tools.completion
     {
         { [ over zero? ] [ 2drop 10 ] }
         { [ 2dup length 1- number= ] [ 2drop 4 ] }
-        { [ 2dup >r 1- r> nth Letter? not ] [ 2drop 10 ] }
-        { [ 2dup >r 1+ r> nth Letter? not ] [ 2drop 4 ] }
+        { [ 2dup [ 1- ] dip nth Letter? not ] [ 2drop 10 ] }
+        { [ 2dup [ 1+ ] dip nth Letter? not ] [ 2drop 4 ] }
         [ 2drop 1 ]
     } cond ;
 
@@ -67,7 +67,7 @@ IN: tools.completion
     over empty? [
         nip [ first ] map
     ] [
-        >r >lower r> [ completion ] with map
+        [ >lower ] dip [ completion ] with map
         rank-completions
     ] if ;
 
index c78e0a32ba94d0d7b5fb94af9e911886ec8c7650..84bfab682be2dc4457fa4db93123d45442b1a24b 100644 (file)
@@ -76,7 +76,7 @@ SYMBOL: deploy-image
     parse-fresh [ first assoc-union ] unless-empty ;
 
 : set-deploy-config ( assoc vocab -- )
-    >r unparse-use string-lines r>
+    [ unparse-use string-lines ] dip
     dup deploy-config-path set-vocab-file-contents ;
 
 : set-deploy-flag ( value key vocab -- )
index e0ac391fdfdfff862bd45e1bf5b6ed714e5c8951..9cc48972fab1754385aba254462982adc31793e9 100644 (file)
@@ -7,42 +7,29 @@ urls math.parser ;
 : shake-and-bake ( vocab -- )\r
     [ "test.image" temp-file delete-file ] ignore-errors\r
     "resource:" [\r
-        >r vm\r
-        "test.image" temp-file\r
-        r> dup deploy-config make-deploy-image\r
+        [ vm "test.image" temp-file ] dip\r
+        dup deploy-config make-deploy-image\r
     ] with-directory ;\r
 \r
 : small-enough? ( n -- ? )\r
-    >r "test.image" temp-file file-info size>> r> cell 4 / * <= ;\r
+    [ "test.image" temp-file file-info size>> ] [ cell 4 / * ] bi* <= ;\r
 \r
-[ ] [ "hello-world" shake-and-bake ] unit-test\r
+[ t ] [ "hello-world" shake-and-bake 500000 small-enough? ] unit-test\r
 \r
-[ t ] [ 500000 small-enough? ] unit-test\r
+[ t ] [ "sudoku" shake-and-bake 800000 small-enough? ] unit-test\r
 \r
-[ ] [ "sudoku" shake-and-bake ] unit-test\r
-\r
-[ t ] [ 800000 small-enough? ] unit-test\r
-\r
-[ ] [ "hello-ui" shake-and-bake ] unit-test\r
-\r
-[ t ] [ 1300000 small-enough? ] unit-test\r
+[ t ] [ "hello-ui" shake-and-bake 1300000 small-enough? ] unit-test\r
 \r
 [ "staging.math-compiler-threads-ui-strip.image" ] [\r
     "hello-ui" deploy-config\r
     [ bootstrap-profile staging-image-name file-name ] bind\r
 ] unit-test\r
 \r
-[ ] [ "maze" shake-and-bake ] unit-test\r
-\r
-[ t ] [ 1200000 small-enough? ] unit-test\r
-\r
-[ ] [ "tetris" shake-and-bake ] unit-test\r
+[ t ] [ "maze" shake-and-bake 1200000 small-enough? ] unit-test\r
 \r
-[ t ] [ 1500000 small-enough? ] unit-test\r
+[ t ] [ "tetris" shake-and-bake 1500000 small-enough? ] unit-test\r
 \r
-[ ] [ "bunny" shake-and-bake ] unit-test\r
-\r
-[ t ] [ 2500000 small-enough? ] unit-test\r
+[ t ] [ "bunny" shake-and-bake 2500000 small-enough? ] unit-test\r
 \r
 : run-temp-image ( -- )\r
     vm\r
@@ -111,3 +98,8 @@ M: quit-responder call-responder*
     "tools.deploy.test.7" shake-and-bake\r
     run-temp-image\r
 ] unit-test\r
+\r
+[ ] [\r
+    "tools.deploy.test.8" shake-and-bake\r
+    run-temp-image\r
+] unit-test\r
index 9cc5a66f7017fff29db7f51c0d7d4fb1b5de363c..15fd2a37d792588c06adda429643746d291f7481 100755 (executable)
@@ -23,10 +23,8 @@ IN: tools.deploy.shaker
 
 : strip-init-hooks ( -- )
     "Stripping startup hooks" show
-    "cpu.x86" init-hooks get delete-at
-    "command-line" init-hooks get delete-at
-    "libc" init-hooks get delete-at
-    "system" init-hooks get delete-at
+    { "cpu.x86" "command-line" "libc" "system" "environment" }
+    [ init-hooks get delete-at ] each
     deploy-threads? get [
         "threads" init-hooks get delete-at
     ] unless
@@ -111,6 +109,7 @@ IN: tools.deploy.shaker
                 "default-method"
                 "default-output-classes"
                 "derived-from"
+                "ebnf-parser"
                 "engines"
                 "forgotten"
                 "identities"
@@ -271,8 +270,8 @@ IN: tools.deploy.shaker
             } %
 
             { } { "math.partial-dispatch" } strip-vocab-globals %
-            
-            "peg-cache" "peg" lookup ,
+
+            { } { "peg" } strip-vocab-globals %
         ] when
 
         strip-prettyprint? [
@@ -321,24 +320,34 @@ IN: tools.deploy.shaker
         ] with-compilation-unit
     ] unless ;
 
-: compress ( pred string -- )
+: compress ( pred post-process string -- )
     "Compressing " prepend show
-    instances
-    dup H{ } clone [ [ ] cache ] curry map
+    [ instances dup H{ } clone [ [ ] cache ] curry map ] dip call
     become ; inline
 
 : compress-byte-arrays ( -- )
-    [ byte-array? ] "byte arrays" compress ;
+    [ byte-array? ] [ ] "byte arrays" compress ;
+
+: remain-compiled ( old new -- old new )
+    #! Quotations which were formerly compiled must remain
+    #! compiled.
+    2dup [
+        2dup [ compiled>> ] [ compiled>> not ] bi* and
+        [ nip jit-compile ] [ 2drop ] if
+    ] 2each ;
 
 : compress-quotations ( -- )
-    [ quotation? ] "quotations" compress ;
+    [ quotation? ] [ remain-compiled ] "quotations" compress ;
 
 : compress-strings ( -- )
-    [ string? ] "strings" compress ;
+    [ string? ] [ ] "strings" compress ;
+
+: compress-wrappers ( -- )
+    [ wrapper? ] [ ] "wrappers" compress ;
 
 : finish-deploy ( final-image -- )
     "Finishing up" show
-    >r { } set-datastack r>
+    [ { } set-datastack ] dip
     { } set-retainstack
     V{ } set-namestack
     V{ } set-catchstack
@@ -379,12 +388,13 @@ SYMBOL: deploy-vocab
     strip-c-io
     f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore
     deploy-vocab get vocab-main set-boot-quot*
-    stripped-word-props >r
+    stripped-word-props
     stripped-globals strip-globals
-    r> strip-words
+    strip-words
     compress-byte-arrays
     compress-quotations
-    compress-strings ;
+    compress-strings
+    compress-wrappers ;
 
 : (deploy) ( final-image vocab config -- )
     #! Does the actual work of a deployment in the slave
diff --git a/basis/tools/deploy/test/8/8.factor b/basis/tools/deploy/test/8/8.factor
new file mode 100644 (file)
index 0000000..c495928
--- /dev/null
@@ -0,0 +1,11 @@
+USING: kernel ;
+IN: tools.deploy.test.8
+
+: literal-merge-test-1 ( -- x ) H{ { "lil" "wayne" } } ;
+: literal-merge-test-2 ( -- x ) H{ { "lil" "wayne" } } ;
+
+: literal-merge-test ( -- )
+    literal-merge-test-1
+    literal-merge-test-2 eq? t assert= ;
+
+MAIN: literal-merge-test
diff --git a/basis/tools/deploy/test/8/deploy.factor b/basis/tools/deploy/test/8/deploy.factor
new file mode 100644 (file)
index 0000000..3bea1ed
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-name "tools.deploy.test.8" }
+    { deploy-c-types? f }
+    { deploy-word-props? f }
+    { deploy-ui? f }
+    { deploy-reflection 1 }
+    { deploy-compiler? f }
+    { deploy-unicode? f }
+    { deploy-io 1 }
+    { deploy-word-defs? f }
+    { deploy-threads? f }
+    { "stop-after-last-window?" t }
+    { deploy-math? f }
+}
diff --git a/basis/tools/files/authors.txt b/basis/tools/files/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/tools/files/files-docs.factor b/basis/tools/files/files-docs.factor
new file mode 100644 (file)
index 0000000..c5c5b44
--- /dev/null
@@ -0,0 +1,17 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string strings ;
+IN: tools.files
+
+HELP: directory.
+{ $values
+     { "path" "a pathname string" }
+}
+{ $description "Prints information about all files in a directory to the output stream in a cross-platform way similar to the Unix " { $snippet "ls" } " command." } ;
+
+ARTICLE: "tools.files" "Files tools"
+"The " { $vocab-link "tools.files" } " vocabulary implements directory files and file-systems listing in a cross-platform way." $nl
+"Listing a directory:"
+{ $subsection directory. } ;
+
+ABOUT: "tools.files"
diff --git a/basis/tools/files/files-tests.factor b/basis/tools/files/files-tests.factor
new file mode 100644 (file)
index 0000000..6aa68d8
--- /dev/null
@@ -0,0 +1,8 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test tools.files strings kernel ;
+IN: tools.files.tests
+
+\ directory. must-infer
+
+[ ] [ "" directory. ] unit-test
diff --git a/basis/tools/files/files.factor b/basis/tools/files/files.factor
new file mode 100755 (executable)
index 0000000..58c24ef
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays combinators io io.files kernel
+math.parser sequences system vocabs.loader calendar ;
+IN: tools.files
+
+<PRIVATE
+
+: ls-time ( timestamp -- string )
+    [ hour>> ] [ minute>> ] bi
+    [ number>string 2 CHAR: 0 pad-left ] bi@ ":" swap 3append ;
+
+: ls-timestamp ( timestamp -- string )
+    [ month>> month-abbreviation ]
+    [ day>> number>string 2 CHAR: \s pad-left ]
+    [
+        dup year>> dup now year>> =
+        [ drop ls-time ] [ nip number>string ] if
+        5 CHAR: \s pad-left
+    ] tri 3array " " join ;
+
+: read>string ( ? -- string ) "r" "-" ? ; inline
+
+: write>string ( ? -- string ) "w" "-" ? ; inline
+
+: execute>string ( ? -- string ) "x" "-" ? ; inline
+
+HOOK: (directory.) os ( path -- lines )
+
+PRIVATE>
+
+: directory. ( path -- )
+    [ (directory.) ] with-directory-files [ print ] each ;
+
+{
+    { [ os unix? ] [ "tools.files.unix" ] }
+    { [ os windows? ] [ "tools.files.windows" ] }
+} cond require
diff --git a/basis/tools/files/tags.txt b/basis/tools/files/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/files/unix/authors.txt b/basis/tools/files/unix/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/tools/files/unix/tags.txt b/basis/tools/files/unix/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/files/unix/unix.factor b/basis/tools/files/unix/unix.factor
new file mode 100755 (executable)
index 0000000..184f371
--- /dev/null
@@ -0,0 +1,60 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators kernel system unicode.case
+io.unix.files tools.files generalizations strings
+arrays sequences io.files math.parser unix.groups unix.users
+tools.files.private unix.stat math ;
+IN: tools.files.unix
+
+<PRIVATE
+
+: unix-execute>string ( str bools -- str' )
+    swap {
+        { { t t } [ >lower ] }
+        { { t f } [ >upper ] }
+        { { f t } [ drop "x" ] }
+        [ 2drop "-" ]
+    } case ;
+
+: permissions-string ( permissions -- str )
+    {
+        [ type>> file-type>ch 1string ]
+        [ user-read? read>string ]
+        [ user-write? write>string ]
+        [ [ uid? ] [ user-execute? ] bi 2array "s" unix-execute>string ]
+        [ group-read? read>string ]
+        [ group-write? write>string ]
+        [ [ gid? ] [ group-execute? ] bi 2array "s" unix-execute>string ]
+        [ other-read? read>string ]
+        [ other-write? write>string ]
+        [ [ sticky? ] [ other-execute? ] bi 2array "t" unix-execute>string ]
+    } cleave 10 narray concat ;
+
+: mode>symbol ( mode -- ch )
+    S_IFMT bitand
+    {
+        { [ dup S_IFDIR = ] [ drop "/" ] }
+        { [ dup S_IFIFO = ] [ drop "|" ] }
+        { [ dup any-execute? ] [ drop "*" ] }
+        { [ dup S_IFLNK = ] [ drop "@" ] }
+        { [ dup S_IFWHT = ] [ drop "%" ] }
+        { [ dup S_IFSOCK = ] [ drop "=" ] }
+        { [ t ] [ drop "" ] }
+    } cond ;
+
+M: unix (directory.) ( path -- lines )
+    [ [
+        [
+            dup file-info
+            {
+                [ permissions-string ]
+                [ nlink>> number>string 3 CHAR: \s pad-left ]
+                ! [ uid>> ]
+                ! [ gid>> ]
+                [ size>> number>string 15 CHAR: \s pad-left ]
+                [ modified>> ls-timestamp ]
+            } cleave 4 narray swap suffix " " join
+        ] map
+    ] with-group-cache ] with-user-cache ;
+
+PRIVATE>
diff --git a/basis/tools/files/windows/authors.txt b/basis/tools/files/windows/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/tools/files/windows/tags.txt b/basis/tools/files/windows/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/files/windows/windows.factor b/basis/tools/files/windows/windows.factor
new file mode 100755 (executable)
index 0000000..76e6ea5
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors calendar.format combinators io.files
+kernel math.parser sequences splitting system tools.files
+generalizations tools.files.private ;
+IN: tools.files.windows
+
+<PRIVATE
+
+: directory-or-size ( file-info -- str )
+    dup directory? [
+        drop "<DIR>" 20 CHAR: \s pad-right
+    ] [
+        size>> number>string 20 CHAR: \s pad-left
+    ] if ;
+
+M: windows (directory.) ( entries -- lines )
+    [
+        dup file-info {
+            [ modified>> timestamp>ymdhms ]
+            [ directory-or-size ]
+        } cleave 2 narray swap suffix " " join
+    ] map ;
+
+PRIVATE>
index 9579fb7f81d74ac2b072854fa73e8bdc9a7e56d9..612195d9977f523114e861a086ce46bb187fcdef 100644 (file)
@@ -1,14 +1,15 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel sequences strings ;
+USING: help.markup help.syntax kernel sequences byte-arrays
+strings ;
 IN: tools.hexdump
 
 HELP: hexdump.
-{ $values { "seq" sequence } }
+{ $values { "byte-array" byte-array } }
 { $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time and writes it to standard out." } ;
 
 HELP: hexdump
-{ $values { "seq" sequence } { "str" string } }
+{ $values { "byte-array" byte-array } { "str" string } }
 { $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time.  Lines are separated by a newline character." }
 { $see-also hexdump. } ;
 
index 7202e4402c6cd106d3fb6ece0469ea889670ef0f..1a8ed35510d8ac0236a3fcb77829d795f771c696 100644 (file)
@@ -1,10 +1,10 @@
-USING: tools.hexdump kernel sequences tools.test ;
+USING: tools.hexdump kernel sequences tools.test byte-arrays ;
 IN: tools.hexdump.tests
 
-[ t ] [ "" hexdump "Length: 0, 0h\n" = ] unit-test
-[ t ] [ "abcdefghijklmnopqrstuvwxyz" hexdump "Length: 26, 1ah\n00000000h: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop\n00000010h: 71 72 73 74 75 76 77 78 79 7a                   qrstuvwxyz\n" = ] unit-test
+[ t ] [ B{ } hexdump "Length: 0, 0h\n" = ] unit-test
+[ t ] [ "abcdefghijklmnopqrstuvwxyz" >byte-array hexdump "Length: 26, 1ah\n00000000h: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop\n00000010h: 71 72 73 74 75 76 77 78 79 7a                   qrstuvwxyz\n" = ] unit-test
 
-[ t ] [ 256 [ ] map hexdump "Length: 256, 100h\n00000000h: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n00000010h: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n00000020h: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f  !\"#$%&'()*+,-./\n00000030h: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n00000040h: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n00000050h: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n00000060h: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n00000070h: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n00000080h: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................\n00000090h: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................\n000000a0h: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................\n000000b0h: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................\n000000c0h: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................\n000000d0h: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................\n000000e0h: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................\n000000f0h: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................\n" = ] unit-test
+[ t ] [ 256 [ ] B{ } map-as hexdump "Length: 256, 100h\n00000000h: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n00000010h: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n00000020h: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f  !\"#$%&'()*+,-./\n00000030h: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n00000040h: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n00000050h: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n00000060h: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n00000070h: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n00000080h: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................\n00000090h: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................\n000000a0h: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................\n000000b0h: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................\n000000c0h: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................\n000000d0h: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................\n000000e0h: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................\n000000f0h: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................\n" = ] unit-test
 
 
 [
index c8b9f4accc158a28dfe4a21323594724d1987670..d16d6b259515f550e96b145a51bd78fddac6f869 100644 (file)
@@ -1,7 +1,7 @@
 ! 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 ;
+namespaces sequences splitting grouping strings ascii byte-arrays ;
 IN: tools.hexdump
 
 <PRIVATE
@@ -28,9 +28,11 @@ IN: tools.hexdump
 
 PRIVATE>
 
-: hexdump. ( seq -- )
+GENERIC: hexdump. ( byte-array -- )
+
+M: byte-array hexdump.
     [ length write-header ]
     [ 16 <sliced-groups> [ write-hex-line ] each-index ] bi ;
 
-: hexdump ( seq -- str )
+: hexdump ( byte-array -- str )
     [ hexdump. ] with-string-writer ;
index d860bd7f84fd090351c1572b4a75b8922717245d..e63da3512a42249e591973f6c0d42a45ad802b54 100644 (file)
@@ -1 +1 @@
-Prints formatted hex dump of an arbitrary sequence
+Prints the formatted hex dump of a byte-array
index f61694da786753ac13da6b22cc7bd13cb381bc70..8c35ae25a84e506eae48ace6e116d0340b99a290 100644 (file)
@@ -3,14 +3,14 @@
 USING: kernel sequences vectors arrays generic assocs io math
 namespaces parser prettyprint strings io.styles vectors words
 system sorting splitting grouping math.parser classes memory
-combinators ;
+combinators fry ;
 IN: tools.memory
 
 <PRIVATE
 
 : write-size ( n -- )
     number>string
-    dup length 4 > [ 3 cut* "," swap 3append ] when
+    dup length 4 > [ 3 cut* "," glue ] when
     " KB" append write-cell ;
 
 : write-total/used/free ( free total str -- )
@@ -51,9 +51,10 @@ IN: tools.memory
         [ "Largest free block:" write-labelled-size ]
     } spread ;
 
-: heap-stat-step ( counts sizes obj -- )
-    [ dup size swap class rot at+ ] keep
-    1 swap class rot at+ ;
+: heap-stat-step ( obj counts sizes -- )
+    [ over ] dip
+    [ [ [ drop 1 ] [ class ] bi ] dip at+ ]
+    [ [ [ size ] [ class ] bi ] dip at+ ] 2bi* ;
 
 PRIVATE>
 
@@ -71,7 +72,7 @@ PRIVATE>
 
 : heap-stats ( -- counts sizes )
     H{ } clone H{ } clone
-    [ >r 2dup r> heap-stat-step ] each-object ;
+    2dup '[ _ _ heap-stat-step ] each-object ;
 
 : heap-stats. ( -- )
     heap-stats dup keys natural-sort standard-table-style [
index b7f7ae97a691716b8121e9bd7509f603397bd5c3..f21e8498ebeca28f09fb65d28866646acd98f2ce 100644 (file)
@@ -34,7 +34,7 @@ M: method-body (profile.)
 
 : counter. ( obj n -- )
     [
-        >r [ (profile.) ] with-cell r>
+        [ [ (profile.) ] with-cell ] dip
         [ number>string write ] with-cell
     ] with-row ;
 
index 281180126695f6abf69bfb0d639fb87666c7c6ee..d8822f51dc1eb4064d346282b3086e1edec3fda1 100644 (file)
@@ -17,23 +17,17 @@ ERROR: no-vocab vocab ;
 
 <PRIVATE
 
-: root? ( string -- ? ) vocab-roots get member?  ;
+: root? ( string -- ? ) vocab-roots get member? ;
 
-: length-changes? ( seq quot -- ? )
-    dupd call [ length ] bi@ = not ; inline
+: contains-dot? ( string -- ? ) ".." swap subseq? ;
 
-: check-vocab-name ( string -- string )
-    dup [ [ CHAR: . = ] trim ] length-changes?
-    [ vocab-name-contains-dot ] when
-
-    ".." over subseq? [ vocab-name-contains-dot ] when
+: contains-separator? ( string -- ? ) [ path-separator? ] contains? ;
 
-    dup [ path-separator? ] contains?
-    [ vocab-name-contains-separator ] when ;
+: check-vocab-name ( string -- string )
+    dup contains-dot? [ vocab-name-contains-dot ] when
+    dup contains-separator? [ vocab-name-contains-separator ] when ;
 
 : check-root ( string -- string )
-    check-vocab-name
-    dup "resource:" head? [ "resource:" prepend ] unless
     dup root? [ not-a-vocab-root ] unless ;
 
 : directory-exists ( path -- )
index f19ffb83a48fef4a78bbc454ead25de32be69b8c..3cabff457f270a2258cfb302289859bb867a59cc 100644 (file)
@@ -86,7 +86,7 @@ HELP: test-all
 { $description "Runs unit tests for all loaded vocabularies." } ;
 
 HELP: run-all-tests
-{ $values { "prefix" "a vocabulary name" } { "failures" "an association list of unit test failures" } }
+{ $values { "failures" "an association list of unit test failures" } }
 { $description "Runs unit tests for all loaded vocabularies and outputs unit test failures as documented in " { $link "tools.test.failure" } "." } ;
 
 HELP: test-failures.
diff --git a/basis/tools/test/test-tests.factor b/basis/tools/test/test-tests.factor
new file mode 100644 (file)
index 0000000..4733356
--- /dev/null
@@ -0,0 +1,4 @@
+IN: tools.test.tests
+USING: tools.test ;
+
+\ test-all must-infer
index 73b261bf13cb5de80c26dc7112ad4d2d2a53c752..704a7f1bd5430d828ff504b1228f48ad382bf259 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors namespaces arrays prettyprint sequences kernel
 vectors quotations words parser assocs combinators continuations
 debugger io io.styles io.files vocabs vocabs.loader source-files
-compiler.units summary stack-checker effects tools.vocabs ;
+compiler.units summary stack-checker effects tools.vocabs fry ;
 IN: tools.test
 
 SYMBOL: failures
@@ -26,24 +26,22 @@ SYMBOL: this-test
     ] if ;
 
 : unit-test ( output input -- )
-    [ 2array ] 2keep [
-        { } swap with-datastack swap >array assert=
-    ] 2curry (unit-test) ;
+    [ 2array ] 2keep '[
+        _ { } _ with-datastack swap >array assert=
+    ] (unit-test) ;
 
 : short-effect ( effect -- pair )
     [ in>> length ] [ out>> length ] bi 2array ;
 
 : must-infer-as ( effect quot -- )
-    >r 1quotation r> [ infer short-effect ] curry unit-test ;
+    [ 1quotation ] dip '[ _ infer short-effect ] unit-test ;
 
 : must-infer ( word/quot -- )
     dup word? [ 1quotation ] when
-    [ infer drop ] curry [ ] swap unit-test ;
+    '[ _ infer drop ] [ ] swap unit-test ;
 
 : must-fail-with ( quot pred -- )
-    >r [ f ] compose r>
-    [ recover ] 2curry
-    [ t ] swap unit-test ;
+    [ '[ @ f ] ] dip '[ _ _ recover ] [ t ] swap unit-test ;
 
 : must-fail ( quot -- )
     [ drop t ] must-fail-with ;
@@ -90,7 +88,7 @@ SYMBOL: this-test
 : test ( prefix -- )
     run-tests test-failures. ;
 
-: run-all-tests ( prefix -- failures )
+: run-all-tests ( -- failures )
     "" run-tests ;
 
 : test-all ( -- )
index 1672017fc4161cd71261057837998f34db7bfb36..58fc531623995fe5cbf0b4f555172c7baaf85741 100644 (file)
@@ -5,7 +5,7 @@ namespaces system sequences splitting grouping assocs strings ;
 IN: tools.time
 
 : benchmark ( quot -- runtime )
-    micros >r call micros r> - ; inline
+    micros [ call micros ] dip - ; inline
 
 : time. ( data -- )
     unclip
@@ -37,4 +37,4 @@ IN: tools.time
     ] bi* ;
 
 : time ( quot -- )
-    gc-reset micros >r call gc-stats micros r> - prefix time. ; inline
+    gc-reset micros [ call gc-stats micros ] dip - prefix time. ; inline
index 6c5fb596e89ca0f38c06e8c26de015961deed4cb..508b4a34938703fe4af0e0e6ffbefee0e3cd2575 100644 (file)
@@ -11,3 +11,7 @@ ARTICLE: "vocab-index" "Vocabulary index"
 { $subsection "vocab-tags" }
 { $subsection "vocab-authors" }
 { $describe-vocab "" } ;
+
+HELP: words.
+{ $values { "vocab" "a vocabulary name" } }
+{ $description "Printings a listing of all the words in a vocabulary, categorized by type." } ;
index cfc541d9bc45912f1d9c0e0be13da3805d8a59bd..4cd5653ab460dbb98c784695ae9e18a1c4c39e06 100644 (file)
@@ -250,9 +250,9 @@ C: <vocab-author> vocab-author
 
 : keyed-vocabs ( str quot -- seq )
     all-vocabs [
-        swap >r
-        [ >r 2dup r> swap call member? ] filter
-        r> swap
+        swap [
+            [ [ 2dup ] dip swap call member? ] filter
+        ] dip swap
     ] assoc-map 2nip ; inline
 
 : tagged ( tag -- assoc )
index ed2e486ecccc86282d20b4d8ed3f5f73bb102f14..416eec91d2b164df9555f10bdba54745e868a1e1 100644 (file)
@@ -54,7 +54,6 @@ TR: convert-separators "/\\" ".." ;
     [ monitor-thread ] "Vocabulary monitor" spawn drop ;\r
 \r
 [\r
-    "-no-monitors" cli-args member? [\r
-        start-monitor-thread\r
-    ] unless\r
+    "-no-monitors" (command-line) member?\r
+    [ start-monitor-thread ] unless\r
 ] "tools.vocabs.monitor" add-init-hook\r
index d926b670786abc526be01ea0d427e0ec86b14a41..ab2d089d94914f4412cd2f0143fff78b83cf7c45 100644 (file)
@@ -203,7 +203,7 @@ M: vocab summary
 M: vocab-link summary vocab-summary ;\r
 \r
 : set-vocab-summary ( string vocab -- )\r
-    >r 1array r>\r
+    [ 1array ] dip\r
     dup vocab-summary-path\r
     set-vocab-file-contents ;\r
 \r
@@ -238,7 +238,7 @@ M: vocab-link summary vocab-summary ;
         vocab-dir append-path dup exists?\r
         [ subdirs ] [ drop { } ] if\r
     ] keep [\r
-        swap [ "." swap 3append ] with map\r
+        swap [ "." glue ] with map\r
     ] unless-empty ;\r
 \r
 : vocabs-in-dir ( root name -- )\r
index e002af8f6da9f72ba07af47f4ea419c89927bef9..f8026765830160e95a7d10b151bac86c2d4e6da2 100644 (file)
@@ -17,7 +17,11 @@ IN: tools.walker.tests
 ] unit-test
 
 [ { "Yo" 2 } ] [
-    [ 2 >r "Yo" r> ] test-walker
+    [ 2 [ "Yo" ] dip ] test-walker
+] unit-test
+
+[ { "Yo" 2 3 } ] [
+    [ 2 [ "Yo" ] dip 3 ] test-walker
 ] unit-test
 
 [ { 2 } ] [
index 1d26567952e34a30e6a3cc660edeea52efc23094..953291cc59d75ebc8871b0aca519a83298bcf80d 100644 (file)
@@ -64,6 +64,12 @@ M: object add-breakpoint ;
 
 : (step-into-quot) ( quot -- ) add-breakpoint call ;
 
+: (step-into-dip) ( quot -- ) add-breakpoint dip ;
+
+: (step-into-2dip) ( quot -- ) add-breakpoint 2dip ;
+
+: (step-into-3dip) ( quot -- ) add-breakpoint 3dip ;
+
 : (step-into-if) ( true false ? -- ) ? (step-into-quot) ;
 
 : (step-into-dispatch) ( array n -- ) nth (step-into-quot) ;
@@ -103,25 +109,25 @@ SYMBOL: +stopped+
 : change-frame ( continuation quot -- continuation' )
     #! Applies quot to innermost call frame of the
     #! continuation.
-    >r clone r> [
-        >r clone r>
+    [ clone ] dip [
+        [ clone ] dip
         [
-            >r
-            [ innermost-frame-scan 1+ ]
-            [ innermost-frame-quot ] bi
-            r> call
+            [
+                [ innermost-frame-scan 1+ ]
+                [ innermost-frame-quot ] bi
+            ] dip call
         ]
         [ drop set-innermost-frame-quot ]
         [ drop ]
         2tri
     ] curry change-call ; inline
 
-: step-msg ( continuation -- continuation' )
+: step-msg ( continuation -- continuation' ) USE: io
     [
-        2dup nth \ break = [
-            nip
-        ] [
-            swap 1+ cut [ break ] swap 3append
+        2dup length = [ nip [ break ] append ] [
+            2dup nth \ break = [ nip ] [
+                swap 1+ cut [ break ] glue 
+            ] if
         ] if
     ] change-frame ;
 
@@ -130,6 +136,9 @@ SYMBOL: +stopped+
 
 {
     { call [ (step-into-quot) ] }
+    { dip [ (step-into-dip) ] }
+    { 2dip [ (step-into-2dip) ] }
+    { 3dip [ (step-into-3dip) ] }
     { (throw) [ drop (step-into-quot) ] }
     { execute [ (step-into-execute) ] }
     { if [ (step-into-if) ] }
@@ -152,13 +161,16 @@ SYMBOL: +stopped+
 : step-into-msg ( continuation -- continuation' )
     [
         swap cut [
-            swap % unclip {
-                { [ dup \ break eq? ] [ , ] }
-                { [ dup quotation? ] [ add-breakpoint , \ break , ] }
-                { [ dup array? ] [ add-breakpoint , \ break , ] }
-                { [ dup word? ] [ literalize , \ (step-into-execute) , ] }
-                [ , \ break , ]
-            } cond %
+            swap %
+            [ \ break , ] [
+                unclip {
+                    { [ dup \ break eq? ] [ , ] }
+                    { [ dup quotation? ] [ add-breakpoint , \ break , ] }
+                    { [ dup array? ] [ add-breakpoint , \ break , ] }
+                    { [ dup word? ] [ literalize , \ (step-into-execute) , ] }
+                    [ , \ break , ]
+                } cond %
+            ] if-empty
         ] [ ] make
     ] change-frame ;
 
index 30d0efb28ba0c06e8140222649f6ba839bc772be..66d8df7d449a939e60b2ba2744154344df8cd1f9 100644 (file)
@@ -1,13 +1,25 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: byte-arrays strings sequences sequences.private
-fry kernel words parser lexer assocs math.order ;
+fry kernel words parser lexer assocs math math.order summary ;
 IN: tr
 
+ERROR: bad-tr ;
+
+M: bad-tr summary
+    drop "TR: can only be used with ASCII characters" ;
+
 <PRIVATE
 
+: ascii? ( ch -- ? ) 0 127 between? ; inline
+
+: tr-nth ( n mapping -- ch ) nth-unsafe 127 bitand ; inline
+
+: check-tr ( from to -- )
+    [ [ ascii? ] all? ] both? [ bad-tr ] unless ;
+
 : compute-tr ( quot from to -- mapping )
-    zip [ 256 ] 2dip '[ [ @ _ at ] keep or ] B{ } map-as ; inline
+    zip [ 128 ] 2dip '[ [ @ _ at ] keep or ] B{ } map-as ; inline
 
 : tr-hints ( word -- )
     { { byte-array } { string } } "specializer" set-word-prop ;
@@ -16,13 +28,13 @@ IN: tr
     create-in dup tr-hints ;
 
 : tr-quot ( mapping -- quot )
-    '[ [ dup 0 255 between? [ _ nth-unsafe ] when ] map ] ;
+    '[ [ dup ascii? [ _ tr-nth ] when ] map ] ;
 
 : define-tr ( word mapping -- )
     tr-quot (( seq -- translated )) define-declared ;
 
 : fast-tr-quot ( mapping -- quot )
-    '[ [ _ nth-unsafe ] change-each ] ;
+    '[ [ _ tr-nth ] change-each ] ;
 
 : define-fast-tr ( word mapping -- )
     fast-tr-quot (( seq -- )) define-declared ;
@@ -32,6 +44,7 @@ PRIVATE>
 : TR:
     scan parse-definition
     unclip-last [ unclip-last ] dip compute-tr
+    [ check-tr ]
     [ [ create-tr ] dip define-tr ]
-    [ [ "-fast" append create-tr ] dip define-fast-tr ] 2bi ;
+    [ [ "-fast" append create-tr ] dip define-fast-tr ] 2tri ;
     parsing
index e1b591dfb90abaccbac1e68dd44191227ddd8e8e..42c3f6ddef79a0ce77639b42cf8a69d0ba1915d5 100644 (file)
@@ -33,7 +33,7 @@ SYMBOL: selection
 
 : gadget-copy ( gadget clipboard -- )
     over gadget-selection?
-        [ >r [ gadget-selection ] keep r> copy-clipboard ]
+        [ [ [ gadget-selection ] keep ] dip copy-clipboard ]
         [ 2drop ]
     if ;
 
index 9ff3a59f71bbd8c75847f65cfad4db67682b1eae..42063fbf7326b21adede23677ff24484b886ebb6 100644 (file)
@@ -1,11 +1,11 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors math arrays cocoa cocoa.application
+USING: accessors math arrays assocs cocoa cocoa.application
 command-line kernel memory namespaces cocoa.messages
 cocoa.runtime cocoa.subclassing cocoa.pasteboard cocoa.types
 cocoa.windows cocoa.classes cocoa.application sequences system
 ui ui.backend ui.clipboards ui.gadgets ui.gadgets.worlds
-ui.cocoa.views core-foundation threads math.geometry.rect ;
+ui.cocoa.views core-foundation threads math.geometry.rect fry ;
 IN: ui.cocoa
 
 TUPLE: handle view window ;
@@ -15,7 +15,7 @@ C: <handle> handle
 SINGLETON: cocoa-ui-backend
 
 M: cocoa-ui-backend do-events ( -- )
-    [ NSApp [ do-event ] curry loop ui-wait ] with-autorelease-pool ;
+    [ NSApp '[ _ do-event ] loop ui-wait ] with-autorelease-pool ;
 
 TUPLE: pasteboard handle ;
 
@@ -33,16 +33,13 @@ M: pasteboard set-clipboard-contents
     <clipboard> selection set-global ;
 
 : world>NSRect ( world -- NSRect )
-    dup window-loc>> first2 rot rect-dim first2 <NSRect> ;
+    [ window-loc>> ] [ dim>> ] bi [ first2 ] bi@ <NSRect> ;
 
 : gadget-window ( world -- )
-    [
-        dup <FactorView>
-        dup rot world>NSRect <ViewWindow>
-        dup install-window-delegate
-        over -> release
-        <handle>
-    ] keep (>>handle) ;
+    dup <FactorView>
+    2dup swap world>NSRect <ViewWindow>
+    [ [ -> release ] [ install-window-delegate ] bi* ] [ <handle> ] 2bi
+    >>handle drop ;
 
 M: cocoa-ui-backend set-title ( string world -- )
     handle>> window>> swap <NSString> -> setTitle: ;
@@ -99,16 +96,29 @@ M: cocoa-ui-backend flush-gl-context ( handle -- )
 M: cocoa-ui-backend beep ( -- )
     NSBeep ;
 
+CLASS: {
+    { +superclass+ "NSObject" }
+    { +name+ "FactorApplicationDelegate" }
+}
+
+{ "applicationDidFinishLaunching:" "void" { "id" "SEL" "id" }
+    [ 3drop event-loop ]
+} ;
+
+: install-app-delegate ( -- )
+    NSApp FactorApplicationDelegate install-delegate ;
+
 SYMBOL: cocoa-init-hook
 
+cocoa-init-hook global [ [ install-app-delegate ] or ] change-at
+
 M: cocoa-ui-backend ui
     "UI" assert.app [
         [
             init-clipboard
-            cocoa-init-hook get [ call ] when*
+            cocoa-init-hook get call
             start-ui
-            finish-launching
-            event-loop
+            NSApp -> run
         ] ui-running
     ] with-cocoa ;
 
index 876e9e5df19e74e0aeccf031e21cfb3fb0d5f8dc..ccaae0c1ab39629f498dc63ab166b82e9aeb79e9 100644 (file)
@@ -20,12 +20,12 @@ IN: ui.cocoa.tools
 
 ! Handle Open events from the Finder
 CLASS: {
-    { +superclass+ "NSObject" }
-    { +name+ "FactorApplicationDelegate" }
+    { +superclass+ "FactorApplicationDelegate" }
+    { +name+ "FactorWorkspaceApplicationDelegate" }
 }
 
 { "application:openFiles:" "void" { "id" "SEL" "id" "id" }
-    [ >r 3drop r> finder-run-files ]
+    [ [ 3drop ] dip finder-run-files ]
 }
 
 { "newFactorWorkspace:" "id" { "id" "SEL" "id" }
@@ -49,7 +49,7 @@ CLASS: {
 } ;
 
 : install-app-delegate ( -- )
-    NSApp FactorApplicationDelegate install-delegate ;
+    NSApp FactorWorkspaceApplicationDelegate install-delegate ;
 
 ! Service support; evaluate Factor code from other apps
 :: do-service ( pboard error quot -- )
diff --git a/basis/ui/cocoa/views/views-tests.factor b/basis/ui/cocoa/views/views-tests.factor
new file mode 100644 (file)
index 0000000..fc64534
--- /dev/null
@@ -0,0 +1,15 @@
+IN: ui.cocoa.views.tests
+USING: ui.cocoa.views tools.test kernel math.geometry.rect
+namespaces ;
+
+[ t ] [
+    T{ rect
+        { loc { 0 0 } }
+        { dim { 1000 1000 } }
+    } "world" set
+
+    T{ rect
+        { loc { 1.5 2.25 } }
+        { dim { 13.0 14.0 } }
+    } dup "world" get rect>NSRect "world" get NSRect>rect =
+] unit-test
index 82a31ad0d9ec354231371ffb7bbfe94e3e389a34..128fdceeb4f02065020c39f4f88741effc056470 100644 (file)
@@ -8,7 +8,7 @@ core-foundation threads combinators math.geometry.rect ;
 IN: ui.cocoa.views
 
 : send-mouse-moved ( view event -- )
-    over >r mouse-location r> window move-hand fire-motion ;
+    [ mouse-location ] [ drop window ] 2bi move-hand fire-motion ;
 
 : button ( event -- n )
     #! Cocoa -> Factor UI button mapping
@@ -77,46 +77,48 @@ IN: ui.cocoa.views
     dup event-modifiers swap button ;
 
 : send-button-down$ ( view event -- )
-    [ mouse-event>gesture <button-down> ]
-    [ mouse-location rot window send-button-down ] 2bi ;
+    [ nip mouse-event>gesture <button-down> ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-button-down ;
 
 : send-button-up$ ( view event -- )
-    [ mouse-event>gesture <button-up> ] 2keep
-    mouse-location rot window send-button-up ;
+    [ nip mouse-event>gesture <button-up> ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-button-up ;
 
 : send-wheel$ ( view event -- )
-    over >r
-    dup -> deltaX sgn neg over -> deltaY sgn neg 2array -rot
-    mouse-location
-    r> window send-wheel ;
+    [ nip [ -> deltaX ] [ -> deltaY ] bi [ sgn neg ] bi@ 2array ]
+    [ mouse-location ]
+    [ drop window ]
+    2tri send-wheel ;
 
 : send-action$ ( view event gesture -- junk )
-    >r drop window r> send-action f ;
+    [ drop window ] dip send-action f ;
 
 : add-resize-observer ( observer object -- )
-    >r "updateFactorGadgetSize:"
-    "NSViewFrameDidChangeNotification" <NSString>
-    r> add-observer ;
+    [
+        "updateFactorGadgetSize:"
+        "NSViewFrameDidChangeNotification" <NSString>
+    ] dip add-observer ;
 
 : string-or-nil? ( NSString -- ? )
     [ CF>string NSStringPboardType = ] [ t ] if* ;
 
 : valid-service? ( gadget send-type return-type -- ? )
-    over string-or-nil? over string-or-nil? and [
-        drop [ gadget-selection? ] [ drop t ] if
-    ] [
-        3drop f
-    ] if ;
+    over string-or-nil? over string-or-nil? and
+    [ drop [ gadget-selection? ] [ drop t ] if ] [ 3drop f ] if ;
 
 : NSRect>rect ( NSRect world -- rect )
-    >r dup NSRect-x over NSRect-y r>
-    rect-dim second swap - 2array
-    over NSRect-w rot NSRect-h 2array
-    <rect> ;
+    [ [ [ NSRect-x ] [ NSRect-y ] bi ] [ dim>> second ] bi* swap - 2array ]
+    [ drop [ NSRect-w ] [ NSRect-h ] bi 2array ]
+    2bi <rect> ;
 
 : rect>NSRect ( rect world -- NSRect )
-    over rect-loc first2 rot rect-dim second swap -
-    rot rect-dim first2 <NSRect> ;
+    [ [ rect-loc first2 ] [ dim>> second ] bi* swap - ]
+    [ drop rect-dim first2 ]
+    2bi <NSRect> ;
 
 CLASS: {
     { +superclass+ "NSOpenGLView" }
@@ -256,7 +258,7 @@ CLASS: {
 { "validRequestorForSendType:returnType:" "id" { "id" "SEL" "id" "id" }
     [
         ! We return either self or nil
-        >r >r over window-focus r> r>
+        [ over window-focus ] 2dip
         valid-service? [ drop ] [ 2drop f ] if
     ]
 }
@@ -278,7 +280,7 @@ CLASS: {
 { "readSelectionFromPasteboard:" "char" { "id" "SEL" "id" }
     [
         pasteboard-string dup [
-            >r drop window-focus r> swap user-input 1
+            [ drop window-focus ] dip swap user-input 1
         ] [
             3drop 0
         ] if
@@ -341,7 +343,7 @@ CLASS: {
 
 { "initWithFrame:pixelFormat:" "id" { "id" "SEL" "NSRect" "id" }
     [
-        rot drop
+        [ drop ] 2dip
         SUPER-> initWithFrame:pixelFormat:
         dup dup add-resize-observer
     ]
@@ -350,9 +352,10 @@ CLASS: {
 { "dealloc" "void" { "id" "SEL" }
     [
         drop
-        dup unregister-window
-        dup remove-observer
-        SUPER-> dealloc
+        [ unregister-window ]
+        [ remove-observer ]
+        [ SUPER-> dealloc ]
+        tri
     ]
 } ;
 
index b45e2e400427139c8462e1aeeca4365c883ca61e..5f8c3381b7bd2634844e6f30f4409924f45f30b0 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions kernel sequences strings
 math assocs words generic namespaces make assocs quotations
-splitting ui.gestures unicode.case unicode.categories tr ;
+splitting ui.gestures unicode.case unicode.categories tr fry ;
 IN: ui.commands
 
 SYMBOL: +nullary+
@@ -37,7 +37,7 @@ GENERIC: command-word ( command -- word )
         [
             commands>>
             [ drop ] assoc-filter
-            [ [ invoke-command ] curry swap set ] assoc-each
+            [ '[ _ invoke-command ] swap set ] assoc-each
         ] each
     ] H{ } make-assoc ;
 
index d2dfe56ed4423f32d99ade596f55f5b8d0e3f6bf..b0d152fc880fa557663f711a2d7f134a7b60f852 100644 (file)
@@ -4,8 +4,7 @@ USING: alien alien.accessors alien.c-types arrays io kernel libc
 math math.vectors namespaces opengl opengl.gl prettyprint assocs
 sequences io.files io.styles continuations freetype
 ui.gadgets.worlds ui.render ui.backend byte-arrays accessors
-locals ;
-
+locals specialized-arrays.direct.uchar ;
 IN: ui.freetype
 
 TUPLE: freetype-renderer ;
@@ -97,21 +96,22 @@ SYMBOL: dpi
     dup handle>> init-descent
     dup [ ascent>> ] [ descent>> ] bi - ft-ceil >>height ; inline
 
-: set-char-size ( handle size -- )
-    0 swap 6 shift dpi get-global dup FT_Set_Char_Size freetype-error ;
+: set-char-size ( open-font size -- open-font )
+    [ dup handle>> 0 ] dip
+    6 shift dpi get-global dup FT_Set_Char_Size freetype-error ;
 
-: <font> ( handle -- font )
+: <font> ( font -- open-font )
     font new
         H{ } clone >>widths
         over first2 open-face >>handle
-        dup handle>> rot third set-char-size
+        swap third set-char-size
         init-font ;
 
 M: freetype-renderer open-font ( font -- open-font )
     freetype drop open-fonts get [ <font> ] cache ;
 
 : load-glyph ( font char -- glyph )
-    >r handle>> dup r> 0 FT_Load_Char
+    [ handle>> dup ] dip 0 FT_Load_Char
     freetype-error face-glyph ;
 
 : char-width ( open-font char -- w )
@@ -120,7 +120,7 @@ M: freetype-renderer open-font ( font -- open-font )
     ] cache nip ;
 
 M: freetype-renderer string-width ( open-font string -- w )
-    0 -rot [ char-width + ] with each ;
+    [ 0 ] 2dip [ char-width + ] with each ;
 
 M: freetype-renderer string-height ( open-font string -- h )
     drop height>> ;
@@ -134,8 +134,8 @@ M: freetype-renderer string-height ( open-font string -- h )
     FT_RENDER_MODE_NORMAL FT_Render_Glyph freetype-error ;
 
 :: copy-pixel ( i j bitmap texture -- i j )
-    255 j texture set-char-nth
-    i bitmap char-nth j 1 + texture set-char-nth
+    255 j texture set-nth
+    i bitmap nth j 1 + texture set-nth
     i 1 + j 2 + ; inline
 
 :: (copy-row) ( i j bitmap texture end -- )
@@ -154,19 +154,23 @@ M: freetype-renderer string-height ( open-font string -- h )
             rows [ glyph glyph-bitmap-rows ]
             width [ glyph glyph-bitmap-width ]
             width2 [ width next-power-of-2 2 * ] |
-        0 0
-        rows [ bitmap texture width width2 copy-row ] times
-        2drop
+        bitmap [
+            [let | bitmap' [ bitmap rows width * <direct-uchar-array> ] |
+                0 0
+                rows [ bitmap' texture width width2 copy-row ] times
+                2drop
+            ]
+        ] when
     ] ;
 
 : bitmap>texture ( glyph sprite -- id )
-    tuck sprite-size2 * 2 * [
-        [ copy-bitmap ] keep gray-texture
-    ] with-malloc ;
+    tuck sprite-size2 * 2 * <byte-array>
+    [ copy-bitmap ] keep gray-texture ;
 
 : glyph-texture-loc ( glyph font -- loc )
-    over glyph-hori-bearing-x ft-floor -rot
-    ascent>> swap glyph-hori-bearing-y - ft-floor 2array ;
+    [ drop glyph-hori-bearing-x ft-floor ]
+    [ ascent>> swap glyph-hori-bearing-y - ft-floor ]
+    2bi 2array ;
 
 : glyph-texture-size ( glyph -- dim )
     [ glyph-bitmap-width next-power-of-2 ]
@@ -174,7 +178,7 @@ M: freetype-renderer string-height ( open-font string -- h )
     bi 2array ;
 
 : <char-sprite> ( open-font char -- sprite )
-    over >r render-glyph dup r> glyph-texture-loc
+    over [ render-glyph dup ] dip glyph-texture-loc
     over glyph-size pick glyph-texture-size <sprite>
     [ bitmap>texture ] keep [ init-sprite ] keep ;
 
@@ -206,7 +210,7 @@ M: freetype-renderer string-height ( open-font string -- h )
     fonts>> [ open-font H{ } clone 2array ] cache first2 ;
 
 M: freetype-renderer draw-string ( font string loc -- )
-    >r >r world get font-sprites r> r> (draw-string) ;
+    [ world get font-sprites ] 2dip (draw-string) ;
 
 : run-char-widths ( open-font string -- widths )
     char-widths [ scan-sums ] [ 2 v/n ] bi v+ ;
index da0ff35728ce1df6986d2966c524037fc933b677..4ef90d87b98f518c4f3d642151e96862f8fbc87d 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel sequences models ui.gadgets math.geometry.rect ;
+USING: accessors kernel sequences models ui.gadgets
+math.geometry.rect fry ;
 IN: ui.gadgets.books
 
 TUPLE: book < gadget ;
@@ -25,6 +26,6 @@ M: book model-changed ( model book -- )
 M: book pref-dim* ( book -- dim ) children>> pref-dims max-dim ;
 
 M: book layout* ( book -- )
-    [ children>> ] [ dim>> ] bi [ >>dim drop ] curry each ;
+    [ children>> ] [ dim>> ] bi '[ _ >>dim drop ] each ;
 
 M: book focusable-child* ( book -- child/t ) current-page ;
index 4a428404c1bb65e1fe5893ac16ee578dd275778c..086ef2ca81939dbf8434e6a7064e8d1c262fb471 100644 (file)
@@ -71,3 +71,5 @@ ARTICLE: "ui.gadgets.buttons" "Button gadgets"
 { $subsection button-paint }
 "Button constructors take " { $emphasis "label specifiers" } " as input. A label specifier is either a string, an array of strings, a gadget or " { $link f } "."
 { $see-also <command-button> "ui-commands" } ;
+
+ABOUT: "ui.gadgets.buttons"
index 88d957f8ccd688cfda00d69ba16c5e27158281e6..75469671ef14ed47afb7358a84768e3cfc9b0037 100644 (file)
@@ -2,11 +2,11 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel math models namespaces sequences
 strings quotations assocs combinators classes colors
-classes.tuple locals alien.c-types fry opengl opengl.gl
-math.vectors ui.commands ui.gadgets ui.gadgets.borders
-ui.gadgets.labels ui.gadgets.theme ui.gadgets.tracks
-ui.gadgets.packs ui.gadgets.worlds ui.gestures ui.render
-math.geometry.rect ;
+classes.tuple opengl opengl.gl math.vectors ui.commands ui.gadgets
+ui.gadgets.borders ui.gadgets.labels ui.gadgets.theme
+ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures
+ui.render math.geometry.rect locals alien.c-types
+specialized-arrays.float fry ;
 IN: ui.gadgets.buttons
 
 TUPLE: button < border pressed? selected? quot ;
@@ -119,7 +119,7 @@ TUPLE: checkmark-paint < caching-pen color last-vertices ;
     } cleave 4array ;
 
 : checkmark-vertices ( dim -- vertices )
-    checkmark-points concat >c-float-array ;
+    checkmark-points concat >float-array ;
 
 PRIVATE>
 
@@ -177,7 +177,7 @@ PRIVATE>
 
 M: radio-paint recompute-pen
     swap dim>>
-    [ { 4 4 } swap { 9 9 } v- circle-steps circle-vertices >>interior-vertices ]
+    [ { 4 4 } swap { 9 9 } v- circle-steps fill-circle-vertices >>interior-vertices ]
     [ { 1 1 } swap { 3 3 } v- circle-steps circle-vertices >>boundary-vertices ] bi
     drop ;
 
@@ -194,7 +194,7 @@ M: radio-paint draw-interior
 
 M: radio-paint draw-boundary
     [ (radio-paint) ] [ boundary-vertices>> gl-vertex-pointer ] bi
-    GL_LINE_LOOP 0 circle-steps glDrawArrays ;
+    GL_LINE_STRIP 0 circle-steps 1+ glDrawArrays ;
 
 :: radio-knob-theme ( gadget -- gadget )
     [let | radio-paint [ black <radio-paint> ] |
index 4ff7519a8506ef17bcf1da28583da8ce99d864a0..0028b9b165cd9676016e951fa577bdf9c13e183d 100644 (file)
@@ -12,8 +12,7 @@ TUPLE: canvas < gadget dlist ;
 
 : delete-canvas-dlist ( canvas -- )
     [ find-gl-context ]
-    [ dlist>> [ delete-dlist ] when* ]
-    [ f >>dlist drop ] tri ;
+    [ [ [ delete-dlist ] when* f ] change-dlist drop ] bi ;
 
 : make-canvas-dlist ( canvas quot -- dlist )
     [ drop ] [ GL_COMPILE swap make-dlist ] 2bi
index 0cf60ff5e8848a9715d9af72bb765daf69363a09..d749b8905c02ede603fb5eb5f6c5d0ddd47e6614 100644 (file)
@@ -20,22 +20,12 @@ HELP: <editor>
 { $values { "editor" "a new " { $link editor } } }
 { $description "Creates a new " { $link editor } " with an empty document." } ;
 
-! 'editor-caret' is now an old accessor, but it's documented as a word here. Maybe move this description somewhere else.
-
-! HELP: editor-caret ( editor -- caret )
-! { $values { "editor" editor } { "caret" model } }
-! { $description "Outputs a " { $link model } " holding the current caret location." } ;
-
 { editor-caret* editor-mark* } related-words
 
 HELP: editor-caret*
 { $values { "editor" editor } { "loc" "a pair of integers" } }
 { $description "Outputs the current caret location as a line/column number pair." } ;
 
-! HELP: editor-mark ( editor -- mark )
-! { $values { "editor" editor } { "mark" model } }
-! { $description "Outputs a " { $link model } " holding the current mark location." } ;
-
 HELP: editor-mark*
 { $values { "editor" editor } { "loc" "a pair of integers" } }
 { $description "Outputs the current mark location as a line/column number pair." } ;
old mode 100644 (file)
new mode 100755 (executable)
index 856795e..72d5900
@@ -1,12 +1,13 @@
 ! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays documents io kernel math models
-namespaces make opengl opengl.gl sequences strings io.styles
-math.vectors sorting colors combinators assocs math.order fry
-calendar alarms ui.clipboards ui.commands ui.gadgets
-ui.gadgets.borders ui.gadgets.buttons ui.gadgets.labels
-ui.gadgets.scrollers ui.gadgets.theme ui.gadgets.wrappers
-ui.render ui.gestures math.geometry.rect ;
+USING: accessors arrays documents kernel math models
+namespaces locals fry make opengl opengl.gl sequences strings
+io.styles math.vectors sorting colors combinators assocs
+math.order fry calendar alarms ui.clipboards ui.commands
+ui.gadgets ui.gadgets.borders ui.gadgets.buttons
+ui.gadgets.labels ui.gadgets.scrollers ui.gadgets.theme
+ui.gadgets.menus ui.gadgets.wrappers ui.render ui.gestures
+math.geometry.rect ;
 IN: ui.gadgets.editors
 
 TUPLE: editor < gadget
@@ -52,19 +53,21 @@ SYMBOL: blink-interval
 
 750 milliseconds blink-interval set-global
 
-: start-blinking ( editor -- )
-    t >>blink
-    dup '[ _ blink-caret ] blink-interval get every >>blink-alarm drop ;
-
 : stop-blinking ( editor -- )
     [ [ cancel-alarm ] when* f ] change-blink-alarm drop ;
 
+: start-blinking ( editor -- )
+    [ stop-blinking ] [
+        t >>blink
+        dup '[ _ blink-caret ] blink-interval get every
+        >>blink-alarm drop
+    ] bi ;
+
 : restart-blinking ( editor -- )
     dup focused?>> [
-        [ stop-blinking ]
         [ start-blinking ]
         [ relayout-1 ]
-        tri
+        bi
     ] [ drop ] if ;
 
 M: editor graft*
@@ -104,14 +107,20 @@ M: editor ungraft*
     editor-font* "" string-height ;
 
 : y>line ( y editor -- line# )
-    [ line-height / >fixnum ] keep model>> validate-line ;
-
-: point>loc ( point editor -- loc )
-    [
-        [ first2 ] dip tuck y>line dup ,
-        [ dup editor-font* ] dip
-        rot editor-line x>offset ,
-    ] { } make ;
+    line-height / >fixnum ;
+
+:: point>loc ( point editor -- loc )
+    point second editor y>line {
+        { [ dup 0 < ] [ drop { 0 0 } ] }
+        { [ dup editor model>> last-line# > ] [ drop editor model>> doc-end ] }
+        [| n |
+            n
+            point first
+            editor editor-font*
+            n editor editor-line
+            x>offset 2array
+        ]
+    } cond ;
 
 : clicked-loc ( editor -- loc )
     [ hand-rel ] keep point>loc ;
@@ -129,11 +138,8 @@ M: editor ungraft*
     f >>focused?
     relayout-1 ;
 
-: (offset>x) ( font col# str -- x )
-    swap head-slice string-width ;
-
 : offset>x ( col# line# editor -- x )
-    [ editor-line ] keep editor-font* -rot (offset>x) ;
+    [ editor-line ] keep editor-font* spin head-slice string-width ;
 
 : loc>x ( loc editor -- x ) [ first2 swap ] dip offset>x ;
 
@@ -141,8 +147,8 @@ M: editor ungraft*
     line-height * ;
 
 : caret-loc ( editor -- loc )
-    [ editor-caret* ] keep 2dup loc>x
-    rot first rot line>y 2array ;
+    [ editor-caret* ] keep
+    [ loc>x ] [ [ first ] dip line>y ] 2bi 2array ;
 
 : caret-dim ( editor -- dim )
     line-height 0 swap 2array ;
@@ -175,12 +181,16 @@ M: editor ungraft*
     [ font>> ] dip { 0 0 } draw-string ;
 
 : first-visible-line ( editor -- n )
-    clip get rect-loc second origin get second -
-    swap y>line ;
+    [
+        [ clip get rect-loc second origin get second - ] dip
+        y>line
+    ] keep model>> validate-line ;
 
 : last-visible-line ( editor -- n )
-    clip get rect-extent nip second origin get second -
-    swap y>line 1+ ;
+    [
+        [ clip get rect-extent nip second origin get second - ] dip
+        y>line
+    ] keep model>> validate-line 1+ ;
 
 : with-editor ( editor quot -- )
     [
@@ -193,9 +203,8 @@ M: editor ungraft*
     ] with-scope ; inline
 
 : visible-lines ( editor -- seq )
-    \ first-visible-line get
-    \ last-visible-line get
-    rot control-value <slice> ;
+    [ \ first-visible-line get \ last-visible-line get ] dip
+    control-value <slice> ;
 
 : with-editor-translation ( n quot -- )
     [ line-translation origin get v+ ] dip with-translation ;
@@ -209,7 +218,7 @@ M: editor ungraft*
     ] with-editor-translation ;
 
 : selection-start/end ( editor -- start end )
-    dup editor-mark* swap editor-caret* sort-pair ;
+    [ editor-mark* ] [ editor-caret* ] bi sort-pair ;
 
 : (draw-selection) ( x1 x2 -- )
     over -
@@ -218,19 +227,19 @@ M: editor ungraft*
     swap [ gl-fill-rect ] with-translation ;
 
 : draw-selected-line ( start end n -- )
-    [ start/end-on-line ] keep tuck
-    [ editor get offset>x ] 2dip
-    editor get offset>x
+    [ start/end-on-line ] keep
+    tuck [ editor get offset>x ] 2bi@
     (draw-selection) ;
 
 : draw-selection ( -- )
     editor get selection-color>> gl-color
     editor get selection-start/end
     over first [
-        2dup [
-            [ 2dup ] dip draw-selected-line
+        2dup '[
+            [ _ _ ] dip
+            draw-selected-line
             1 translate-lines
-        ] each-line 2drop
+        ] each-line
     ] with-editor-translation ;
 
 M: editor draw-gadget*
@@ -313,9 +322,9 @@ M: editor gadget-text* editor-string % ;
 : editor-cut ( editor clipboard -- )
     dupd gadget-copy remove-selection ;
 
-: delete/backspace ( elt editor quot -- )
+: delete/backspace ( editor quot -- )
     over gadget-selection? [
-        drop nip remove-selection
+        drop remove-selection
     ] [
         [ [ [ editor-caret* ] [ model>> ] bi ] dip call ]
         [ drop model>> ]
@@ -323,19 +332,19 @@ M: editor gadget-text* editor-string % ;
     ] if ; inline
 
 : editor-delete ( editor elt -- )
-    swap [ over [ rot next-elt ] dip swap ] delete/backspace ;
+    '[ dupd _ next-elt ] delete/backspace ;
 
 : editor-backspace ( editor elt -- )
-    swap [ over [ rot prev-elt ] dip ] delete/backspace ;
+    '[ over [ _ prev-elt ] dip ] delete/backspace ;
 
 : editor-select-prev ( editor elt -- )
-    swap [ rot prev-elt ] change-caret ;
+    '[ _ prev-elt ] change-caret ;
 
 : editor-prev ( editor elt -- )
     dupd editor-select-prev mark>caret ;
 
 : editor-select-next ( editor elt -- )
-    swap [ rot next-elt ] change-caret ;
+    '[ _ next-elt ] change-caret ;
 
 : editor-next ( editor elt -- )
     dupd editor-select-next mark>caret ;
@@ -504,6 +513,13 @@ editor "selection" f {
     { T{ key-down f { S+ C+ } "END" } select-end-of-document }
 } define-command-map
 
+: editor-menu ( editor -- )
+    { cut com-copy paste } show-commands-menu ;
+
+editor "misc" f {
+    { T{ button-down f f 3 } editor-menu }
+} define-command-map
+
 ! Multi-line editors
 TUPLE: multiline-editor < editor ;
 
index e38e97c76ccb83bd8d152a4cd67a4d6a2a41712b..27d511e10ac0829c4cf8b5f6444a639f2c6891fe 100644 (file)
@@ -1,4 +1,17 @@
+USING: accessors kernel namespaces tools.test ui.gadgets
+ui.gadgets.frames ui.gadgets.grids ui.gadgets.labels ;
 IN: ui.gadgets.frames.tests
-USING: ui.gadgets.frames ui.gadgets tools.test ;
 
 [ ] [ <frame> layout ] unit-test
+
+[ t ] [
+    <frame>
+        "Hello world" <label> @top grid-add
+        "Hello world" <label> @center grid-add
+        dup pref-dim "dim1" set
+        { 1000 1000 } >>dim
+        dup layout*
+        dup pref-dim "dim2" set
+        drop
+    "dim1" get "dim2" get =
+] unit-test
index b5c373689623436c7ac6e28cae770d156ae35f4f..ae4c7d929a5d3658839ce6ad4f28a8ab83dde066 100644 (file)
@@ -1,15 +1,17 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays generic kernel math namespaces sequences words
-splitting grouping math.vectors ui.gadgets.grids ui.gadgets
-math.geometry.rect ;
+USING: accessors arrays generic kernel math namespaces sequences
+words splitting grouping math.vectors ui.gadgets.grids
+ui.gadgets math.geometry.rect ;
 IN: ui.gadgets.frames
 
-! A frame arranges gadgets in a 3x3 grid, where the center
-! gadgets gets left-over space.
-TUPLE: frame < grid ;
+TUPLE: glue < gadget ;
+
+M: glue pref-dim* drop { 0 0 } ;
+
+: <glue> ( -- glue ) glue new-gadget ;
 
-: <frame-grid> ( -- grid ) 9 [ <gadget> ] replicate 3 group ;
+: <frame-grid> ( -- grid ) 9 [ <glue> ] replicate 3 group ;
 
 : @center 1 1 ; inline
 : @left 0 1 ; inline
@@ -22,13 +24,15 @@ TUPLE: frame < grid ;
 : @bottom-left 0 2 ; inline
 : @bottom-right 2 2 ; inline
 
+TUPLE: frame < grid ;
+
 : new-frame ( class -- frame )
     <frame-grid> swap new-grid ; inline
 
 : <frame> ( -- frame )
     frame new-frame ;
 
-: (fill-center) ( n vec -- )
+: (fill-center) ( dim vec -- )
     [ [ first ] [ third ] bi v+ [v-] ] keep set-second ;
 
 : fill-center ( dim horiz vert -- )
@@ -36,4 +40,4 @@ TUPLE: frame < grid ;
 
 M: frame layout*
     dup compute-grid
-    [ [ rect-dim ] 2dip fill-center ] [ grid-layout ] 3bi ;
+    [ [ dim>> ] 2dip fill-center ] [ grid-layout ] 3bi ;
index 7d33ec21fdadd8e5da4b74fd009d7a7ac880cf08..baf025d11625f90d267d9ef8dacd857d584b4b04 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors arrays hashtables kernel models math namespaces
 make sequences quotations math.vectors combinators sorting
 binary-search vectors dlists deques models threads
-concurrency.flags math.order math.geometry.rect ;
+concurrency.flags math.order math.geometry.rect fry ;
 IN: ui.gadgets
 
 SYMBOL: ui-notify-flag
@@ -56,9 +56,7 @@ M: gadget model-changed 2drop ;
     2dup eq? [
         2drop { 0 0 }
     ] [
-        over rect-loc >r
-        >r parent>> r> relative-loc
-        r> v+
+        over rect-loc [ [ parent>> ] dip relative-loc ] dip v+
     ] if ;
 
 GENERIC: user-input* ( str gadget -- ? )
@@ -73,7 +71,7 @@ M: gadget children-on nip children>> ;
     [ swap loc>> v- ] dip v. 0 <=> ;
 
 : (fast-children-on) ( dim axis children -- i )
-    -rot [ ((fast-children-on)) ] 2curry search drop ;
+    -rot '[ _ _ ((fast-children-on)) ] search drop ;
 
 : fast-children-on ( rect axis children -- from to )
     [ [ rect-loc ] 2dip (fast-children-on) 0 or ]
@@ -88,17 +86,14 @@ M: gadget children-on nip children>> ;
 
 : pick-up ( point gadget -- child/f )
     2dup (pick-up) dup
-    [ nip [ rect-loc v- ] keep pick-up ] [ rot 2drop ] if ;
+    [ nip [ rect-loc v- ] keep pick-up ] [ drop nip ] if ;
 
 : max-dim ( dims -- dim ) { 0 0 } [ vmax ] reduce ;
 
 : dim-sum ( seq -- dim ) { 0 0 } [ v+ ] reduce ;
 
-: orient ( gadget seq1 seq2 -- seq )
-    >r >r orientation>> r> r> [ pick set-axis ] 2map nip ;
-
 : each-child ( gadget quot -- )
-    >r children>> r> each ; inline
+    [ children>> ] dip each ; inline
 
 ! Selection protocol
 GENERIC: gadget-selection? ( gadget -- ? )
@@ -310,18 +305,18 @@ SYMBOL: in-layout?
     [ parent>> ] follow ;
 
 : each-parent ( gadget quot -- ? )
-    >r parents r> all? ; inline
+    [ parents ] dip all? ; inline
 
 : find-parent ( gadget quot -- parent )
-    >r parents r> find nip ; inline
+    [ parents ] dip find nip ; inline
 
 : screen-loc ( gadget -- loc )
     parents { 0 0 } [ rect-loc v+ ] reduce ;
 
 : (screen-rect) ( gadget -- loc ext )
     dup parent>> [
-        >r rect-extent r> (screen-rect)
-        >r tuck v+ r> vmin >r v+ r>
+        [ rect-extent ] dip (screen-rect)
+        [ tuck v+ ] dip vmin [ v+ ] dip
     ] [
         rect-extent
     ] if* ;
index feca8f7c63273cf0b9a42502c8b5b3cc603f729d..8d79c9e07c9877af633c8cb8949dba507719c8c0 100755 (executable)
@@ -1,7 +1,8 @@
-! Copyright (C) 2006, 2007 Slava Pestov.
+! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors math namespaces opengl opengl.gl sequences
-math.vectors ui.gadgets ui.gadgets.grids ui.render math.geometry.rect ;
+USING: kernel accessors math namespaces opengl opengl.gl
+sequences math.vectors ui.gadgets ui.gadgets.grids ui.render
+math.geometry.rect fry ;
 IN: ui.gadgets.grid-lines
 
 TUPLE: grid-lines color ;
@@ -19,8 +20,8 @@ SYMBOL: grid-dim
 
 : draw-grid-lines ( gaps orientation -- )
     [ grid get swap grid-positions grid get rect-dim suffix ] dip
-    [ [ v- ] curry map ] keep
-    [ swap grid-line-from/to gl-line ] curry each ;
+    [ '[ _ v- ] map ] keep
+    '[ _ swap grid-line-from/to gl-line ] each ;
 
 M: grid-lines draw-boundary
     color>> gl-color [
index 3e91e0ceb6614d11a13fef42d9a64d7598e52860..eab8833120b21d23a552719742dea195456d8362 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel math namespaces make sequences words io
 io.streams.string math.vectors ui.gadgets columns accessors
-math.geometry.rect locals ;
+math.geometry.rect locals fry ;
 IN: ui.gadgets.grids
 
 TUPLE: grid < gadget
@@ -18,14 +18,14 @@ grid
 : <grid> ( children -- grid )
     grid new-grid ;
 
-: grid-child ( grid i j -- gadget ) rot grid>> nth nth ;
+:: grid-child ( grid i j -- gadget ) i j grid grid>> nth nth ;
 
 :: grid-add ( grid child i j -- grid )
     grid i j grid-child unparent
     grid child add-gadget
     child i j grid grid>> nth set-nth ;
 
-: grid-remove ( grid i j -- grid ) <gadget> -rot grid-add ;
+: grid-remove ( grid i j -- grid ) [ <gadget> ] 2dip grid-add ;
 
 : pref-dim-grid ( grid -- dims )
     grid>> [ [ pref-dim ] map ] map ;
@@ -48,21 +48,18 @@ grid
     dupd add-gaps dim-sum v+ ;
 
 M: grid pref-dim*
-    dup gap>> swap compute-grid >r over r>
-    gap-sum >r gap-sum r> (pair-up) ;
+    dup gap>> swap compute-grid [ over ] dip
+    [ gap-sum ] 2bi@ (pair-up) ;
 
 : do-grid ( dims grid quot -- )
-    -rot grid>>
-    [ [ pick call ] 2each ] 2each
-    drop ; inline
+    [ grid>> ] dip '[ _ 2each ] 2each ; inline
 
 : grid-positions ( grid dims -- locs )
-    >r gap>> dup r> add-gaps swap [ v+ ] accumulate nip ;
+    [ gap>> dup ] dip add-gaps swap [ v+ ] accumulate nip ;
 
 : position-grid ( grid horiz vert -- )
-    pick >r
-    >r over r> grid-positions >r grid-positions r>
-    pair-up r> [ (>>loc) ] do-grid ;
+    pick [ [ over ] dip [ grid-positions ] 2bi@ pair-up ] dip
+    [ (>>loc) ] do-grid ;
 
 : resize-grid ( grid horiz vert -- )
     pick fill?>> [
index 79a485b7115fcca50f9327baaea65d36af50d721..108c5ae461d1b3a25c38647383f02f96eb5fa4ed 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2006, 2007 Slava Pestov.
+! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays ui.gadgets.buttons ui.gadgets.borders
 ui.gadgets.labels ui.gadgets.panes ui.gadgets.scrollers
@@ -19,10 +19,10 @@ TUPLE: labelled-gadget < track content ;
 M: labelled-gadget focusable-child* content>> ;
 
 : <labelled-scroller> ( gadget title -- gadget )
-    >r <scroller> r> <labelled-gadget> ;
+    [ <scroller> ] dip <labelled-gadget> ;
 
 : <labelled-pane> ( model quot scrolls? title -- gadget )
-    >r >r <pane-control> r> >>scrolls? r>
+    [ [ <pane-control> ] dip >>scrolls? ] dip
     <labelled-scroller> ;
 
 : <close-box> ( quot -- button/f )
@@ -48,9 +48,10 @@ TUPLE: closable-gadget < frame content ;
     [ closable-gadget? ] find-parent ;
 
 : <closable-gadget> ( gadget title quot -- gadget )
-    closable-gadget new-frame
-        -rot <title-bar> @top grid-add
-        swap >>content
-        dup content>> @center grid-add ;
+    [
+        [ closable-gadget new-frame ] dip
+        [ >>content ] [ @center grid-add ] bi
+    ] 2dip
+    <title-bar> @top grid-add ;
     
 M: closable-gadget focusable-child* content>> ;
index 6e56b48c8b33b36c3bc4dc5a222d6fea0416705f..5706f4763937f566ab00997524c1cc50fdde3ef8 100644 (file)
@@ -13,7 +13,7 @@ TUPLE: label < gadget text font color ;
 
 : set-label-string ( string label -- )
     CHAR: \n pick memq? [
-        >r string-lines r> (>>text)
+        [ string-lines ] dip (>>text)
     ] [
         (>>text)
     ] if ; inline
index ec46638c918d77642c2eb7f155cde53f100e6196..0113e1959d41eb9b60da94196e5e41618064a7be 100644 (file)
@@ -33,7 +33,7 @@ TUPLE: list < pack index presenter color hook ;
     hook>> [ [ list? ] find-parent ] prepend ;
 
 : <list-presentation> ( hook elt presenter -- gadget )
-    keep >r >label text-theme r>
+    keep [ >label text-theme ] dip
     <presentation>
     swap >>hook ; inline
 
@@ -42,7 +42,7 @@ TUPLE: list < pack index presenter color hook ;
     [ presenter>> ]
     [ control-value ]
     tri [
-        >r 2dup r> swap <list-presentation>
+        [ 2dup ] dip swap <list-presentation>
     ] map 2nip ;
 
 M: list model-changed
@@ -113,8 +113,8 @@ M: list focusable-child* drop t ;
     select-gadget ;
 
 : list-page ( list vec -- )
-    >r dup selected-rect rect-bounds 2 v/n v+
-    over visible-dim r> v* v+ swap select-at ;
+    [ dup selected-rect rect-bounds 2 v/n v+ over visible-dim ] dip
+    v* v+ swap select-at ;
 
 : list-page-up ( list -- ) { 0 -1 } list-page ;
 
index 303eb0a13ea60b77dbdad49fc1bb86e4adfa9b5a..d7297217ed930cd56441d3d404da9195a6fa32c2 100644 (file)
@@ -3,9 +3,22 @@ kernel ;
 IN: ui.gadgets.menus
 
 HELP: <commands-menu>
-{ $values { "hook" { $quotation "( button -- )" } } { "target" object } { "commands" "a sequence of commands" } { "gadget" "a new " { $link gadget } } }
+{ $values { "target" object } { "commands" "a sequence of commands" } { "hook" { $quotation "( button -- )" } }  { "menu" "a new " { $link gadget } } }
 { $description "Creates a popup menu of commands which are to be invoked on " { $snippet "target" } ". The " { $snippet "hook" } " quotation is run before a command is invoked." } ;
 
 HELP: show-menu
-{ $values { "gadget" gadget } { "owner" gadget } }
-{ $description "Displays a popup menu in the " { $link world } " containing " { $snippet "owner" } " at the current mouse location." } ;
+{ $values { "owner" gadget } { "menu" gadget } }
+{ $description "Displays a popup menu in the " { $link world } " containing " { $snippet "owner" } " at the current mouse location. The popup menu can be any gadget." } ;
+
+HELP: show-commands-menu
+{ $values { "target" gadget } { "commands" "a sequence of commands" } }
+{ $description "Displays a popup menu with the given commands. The commands act on the target gadget. This is just a convenience word that combines " { $link <commands-menu> } " with " { $link show-menu } "." }
+{ $notes "Useful for right-click context menus." } ;
+
+ARTICLE: "ui.gadgets.menus" "Popup menus"
+"The " { $vocab-link "ui.gadgets.menus" } " vocabulary implements popup menus."
+{ $subsection <commands-menu> }
+{ $subsection show-menu }
+{ $subsection show-commands-menu } ;
+
+ABOUT: "ui.gadgets.menus"
index 7dd57e526a4a6cb45c678f18808db467d89a7caf..2aef0b8417ce14c7d6259c452dd59f493cda5be0 100644 (file)
@@ -1,20 +1,20 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays ui.commands ui.gadgets ui.gadgets.buttons
-ui.gadgets.worlds ui.gestures generic hashtables kernel math
-models namespaces opengl sequences math.vectors
-ui.gadgets.theme ui.gadgets.packs ui.gadgets.borders colors
-math.geometry.rect ;
+USING: locals accessors arrays ui.commands ui.gadgets
+ui.gadgets.buttons ui.gadgets.worlds ui.gestures generic
+hashtables kernel math models namespaces opengl sequences
+math.vectors ui.gadgets.theme ui.gadgets.packs
+ui.gadgets.borders colors math.geometry.rect ;
 IN: ui.gadgets.menus
 
 : menu-loc ( world menu -- loc )
-    >r rect-dim r> pref-dim [v-] hand-loc get-global vmin ;
+    [ rect-dim ] [ pref-dim ] bi* [v-] hand-loc get-global vmin ;
 
 TUPLE: menu-glass < gadget ;
 
-: <menu-glass> ( menu world -- glass )
+: <menu-glass> ( world menu -- glass )
+    tuck menu-loc >>loc
     menu-glass new-gadget
-    >r over menu-loc >>loc r>
     swap add-gadget ;
 
 M: menu-glass layout* gadget-child prefer ;
@@ -22,31 +22,35 @@ M: menu-glass layout* gadget-child prefer ;
 : hide-glass ( world -- )
     [ [ unparent ] when* f ] change-glass drop ;
 
-: show-glass ( gadget world -- )
-    dup hide-glass
-    swap [ hand-clicked set-global ] [ >>glass ] bi
-    dup glass>> add-gadget drop ;
+: show-glass ( world gadget -- )
+    [ [ hide-glass ] [ hand-clicked set-global ] bi* ]
+    [ add-gadget drop ]
+    [ >>glass drop ]
+    2tri ;
 
-: show-menu ( gadget owner -- )
-    find-world [ <menu-glass> ] keep show-glass ;
+: show-menu ( owner menu -- )
+    [ find-world dup ] dip <menu-glass> show-glass ;
 
 \ menu-glass H{
     { T{ button-down } [ find-world [ hide-glass ] when* ] }
     { T{ drag } [ update-clicked drop ] }
 } set-gestures
 
-: <menu-item> ( hook target command -- button )
-    dup command-name -rot command-button-quot
-    swapd
-    [ hand-clicked get find-world hide-glass ]
-    3append <roll-button> ;
+:: <menu-item> ( target hook command -- button )
+    command command-name [
+        hook call
+        target command command-button-quot call
+        hand-clicked get find-world hide-glass
+    ] <roll-button> ;
 
 : menu-theme ( gadget -- gadget )
     light-gray solid-interior
     faint-boundary ;
 
-: <commands-menu> ( hook target commands -- gadget )
-    <filled-pile>
-        -roll
-        [ <menu-item> add-gadget ] with with each
+: <commands-menu> ( target hook commands -- menu )
+    [ <filled-pile> ] 3dip
+    [ <menu-item> add-gadget ] with with each
     5 <border> menu-theme ;
+
+: show-commands-menu ( target commands -- )
+    [ dup [ ] ] dip <commands-menu> show-menu ;
index 065267d7be825553cb8e8804b19e6d375a38dc9e..8b52a2ad2fbee5fb31be319c5d41c8dfb8f7880a 100644 (file)
@@ -1,6 +1,7 @@
 IN: ui.gadgets.packs.tests
 USING: ui.gadgets.packs ui.gadgets.labels ui.gadgets ui.render
-kernel namespaces tools.test math.parser sequences math.geometry.rect ;
+kernel namespaces tools.test math.parser sequences math.geometry.rect
+accessors ;
 
 [ t ] [
     { 0 0 } { 100 100 } <rect> clip set
@@ -11,3 +12,10 @@ kernel namespaces tools.test math.parser sequences math.geometry.rect ;
 
     visible-children [ label? ] all?
 ] unit-test
+
+[ { { 10 30 } } ] [
+    { { 10 20 } }
+    { { 100 30 } }
+    <gadget> { 0 1 } >>orientation
+    orient
+] unit-test
index 32a60374ebcc8d271167c1f728b9431ad735d0f7..86dc6ea354f92d384004377abb41fc4d42c5fbb1 100644 (file)
@@ -1,28 +1,30 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: sequences ui.gadgets kernel math math.functions
-math.vectors namespaces math.order accessors math.geometry.rect ;
+math.vectors math.order math.geometry.rect namespaces accessors
+fry ;
 IN: ui.gadgets.packs
 
 TUPLE: pack < gadget
-    { align initial: 0 }
-    { fill  initial: 0 }
-    { gap   initial: { 0 0 } } ;
+{ align initial: 0 } { fill initial: 0 } { gap initial: { 0 0 } } ;
 
 : packed-dim-2 ( gadget sizes -- list )
-    [ over rect-dim over v- rot fill>> v*n v+ ] with map ;
+    swap [ dim>> ] [ fill>> ] bi '[ _ over v- _ v*n v+ ] map ;
+
+: orient ( seq1 seq2 gadget -- seq )
+    orientation>> '[ _ set-axis ] 2map ;
 
 : packed-dims ( gadget sizes -- seq )
-    2dup packed-dim-2 swap orient ;
+    [ packed-dim-2 ] [ nip ] [ drop ] 2tri orient ;
 
 : gap-locs ( gap sizes -- seq )
     { 0 0 } [ v+ over v+ ] accumulate 2nip ;
 
 : aligned-locs ( gadget sizes -- seq )
-    [ >r dup align>> swap rect-dim r> v- n*v ] with map ;
+    [ [ [ align>> ] [ dim>> ] bi ] dip v- n*v ] with map ;
 
 : packed-locs ( gadget sizes -- seq )
-    over gap>> over gap-locs >r dupd aligned-locs r> orient ;
+    [ aligned-locs ] [ [ gap>> ] dip gap-locs ] [ drop ] 2tri orient ;
 
 : round-dims ( seq -- newseq )
     { 0 0 } swap
@@ -31,8 +33,9 @@ TUPLE: pack < gadget
 
 : pack-layout ( pack sizes -- )
     round-dims over children>>
-    >r dupd packed-dims r> 2dup [ (>>dim) ] 2each
-    >r packed-locs r> [ (>>loc) ] 2each ;
+    [ dupd packed-dims ] dip
+    [ [ (>>dim) ] 2each ]
+    [ [ packed-locs ] dip [ (>>loc) ] 2each ] 2bi ;
 
 : <pack> ( orientation -- pack )
     pack new-gadget
@@ -44,12 +47,14 @@ TUPLE: pack < gadget
 
 : <shelf> ( -- pack ) { 1 0 } <pack> ;
 
-: gap-dims ( gap sizes -- seeq )
-    [ dim-sum ] keep length 1 [-] rot n*v v+ ;
+: gap-dims ( sizes gadget -- seeq )
+    [ [ dim-sum ] [ length 1 [-] ] bi ] [ gap>> ] bi* n*v v+ ;
 
 : pack-pref-dim ( gadget sizes -- dim )
-    over gap>> over gap-dims >r max-dim r>
-    rot orientation>> set-axis ;
+    [ nip max-dim ]
+    [ swap gap-dims ]
+    [ drop orientation>> ]
+    2tri set-axis ;
 
 M: pack pref-dim*
     dup children>> pref-dims pack-pref-dim ;
index c612cbef0ad815f40d5697c0d83c1613af1abcc9..79a47380b6ccaf0e611f4802a434677523c61cf7 100644 (file)
@@ -3,13 +3,13 @@
 USING: arrays ui.gadgets ui.gadgets.borders ui.gadgets.buttons
 ui.gadgets.labels ui.gadgets.scrollers ui.gadgets.paragraphs
 ui.gadgets.incremental ui.gadgets.packs ui.gadgets.theme
-ui.clipboards ui.gestures ui.traverse ui.render hashtables io
-kernel namespaces sequences io.styles strings quotations math
-opengl combinators math.vectors sorting splitting
-io.streams.nested assocs ui.gadgets.presentations
+ui.gadgets.menus ui.clipboards ui.gestures ui.traverse ui.render
+hashtables io kernel namespaces sequences io.styles strings
+quotations math opengl combinators math.vectors sorting
+splitting io.streams.nested assocs ui.gadgets.presentations
 ui.gadgets.slots ui.gadgets.grids ui.gadgets.grid-lines
 classes.tuple models continuations destructors accessors
-math.geometry.rect ;
+math.geometry.rect fry ;
 IN: ui.gadgets.panes
 
 TUPLE: pane < pack
@@ -59,7 +59,7 @@ M: pane gadget-selection ( pane -- string/f )
 GENERIC: draw-selection ( loc obj -- )
 
 : if-fits ( rect quot -- )
-    >r clip get over intersects? r> [ drop ] if ; inline
+    [ clip get over intersects? ] dip [ drop ] if ; inline
 
 M: gadget draw-selection ( loc gadget -- )
     swap offset-rect [
@@ -135,8 +135,8 @@ M: style-stream write-gadget
 
 : with-pane ( pane quot -- )
     over scroll>top
-    over pane-clear >r <pane-stream> r>
-    over >r with-output-stream* r> ?nl ; inline
+    over pane-clear [ <pane-stream> ] dip
+    over [ with-output-stream* ] dip ?nl ; inline
 
 : make-pane ( quot -- gadget )
     <pane> [ swap with-pane ] keep smash-pane ; inline
@@ -154,7 +154,7 @@ M: pane-control model-changed ( model pane-control -- )
         swap >>model ;
 
 : do-pane-stream ( pane-stream quot -- )
-    >r pane>> r> keep scroll-pane ; inline
+    [ pane>> ] dip keep scroll-pane ; inline
 
 M: pane-stream stream-nl
     [ pane-nl drop ] do-pane-stream ;
@@ -178,7 +178,7 @@ M: pane-stream make-span-stream
 ! Character styles
 
 : apply-style ( style gadget key quot -- style gadget )
-    >r pick at r> when* ; inline
+    [ pick at ] dip when* ; inline
 
 : apply-foreground-style ( style gadget -- style gadget )
     foreground [ >>color ] apply-style ;
@@ -228,7 +228,7 @@ M: pane-stream make-span-stream
     border-width [ <border> ] apply-style ;
 
 : apply-printer-style ( style gadget -- style gadget )
-    presented-printer [ [ make-pane ] curry >>printer ] apply-style ;
+    presented-printer [ '[ _ make-pane ] >>printer ] apply-style ;
 
 : style-pane ( style pane -- pane )
     apply-border-width-style
@@ -284,10 +284,10 @@ M: pane-stream make-cell-stream
     pane-cell-stream new-nested-pane-stream ;
 
 M: pane-stream stream-write-table
-    >r
-    swap [ [ pane>> smash-pane ] map ] map
-    styled-grid
-    r> print-gadget ;
+    [
+        swap [ [ pane>> smash-pane ] map ] map
+        styled-grid
+    ] dip print-gadget ;
 
 ! Stream utilities
 M: pack dispose drop ;
@@ -309,7 +309,7 @@ M: paragraph stream-write
     drop ;
 
 : gadget-write1 ( char gadget -- )
-    >r 1string r> stream-write ;
+    [ 1string ] dip stream-write ;
 
 M: pack stream-write1 gadget-write1 ;
 
@@ -398,6 +398,8 @@ M: f sloppy-pick-up*
     dup request-focus
     com-copy-selection ;
 
+: pane-menu ( pane -- ) { com-copy } show-commands-menu ;
+
 pane H{
     { T{ button-down } [ begin-selection ] }
     { T{ button-down f { S+ } 1 } [ select-to-caret ] }
@@ -405,4 +407,5 @@ pane H{
     { T{ button-up } [ end-selection ] }
     { T{ drag } [ extend-selection ] }
     { T{ copy-action } [ com-copy ] }
+    { T{ button-down f f 3 } [ pane-menu ] }
 } set-gestures
index 216f21af27bbf4981aec5a4ba9ec57f7602e1aca..6e26a2989f0c7342ac0e6f268e6ce209d517d7bb 100644 (file)
@@ -1,7 +1,8 @@
-! Copyright (C) 2005, 2007 Slava Pestov
+! Copyright (C) 2005, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays ui.gadgets ui.gadgets.labels ui.render kernel math
-namespaces sequences math.order math.geometry.rect ;
+USING: accessors arrays ui.gadgets ui.gadgets.labels ui.render
+kernel math namespaces sequences math.order math.geometry.rect
+locals ;
 IN: ui.gadgets.paragraphs
 
 ! A word break gadget
@@ -46,12 +47,19 @@ SYMBOL: margin
     dup line-height [ max ] change
     y get + max-y [ max ] change ;
 
-: wrap-step ( quot child -- )
-    dup pref-dim [
-        over word-break-gadget? [
-            dup first overrun? [ wrap-line ] when
-        ] unless drop wrap-pos rot call
-    ] keep first2 advance-y advance-x ; inline
+:: wrap-step ( quot child -- )
+    child pref-dim
+    [
+        child
+        [
+            word-break-gadget?
+            [ drop ] [ first overrun? [ wrap-line ] when ] if
+        ]
+        [ wrap-pos quot call ] bi
+    ]
+    [ first advance-x ]
+    [ second advance-y ]
+    tri ; inline
 
 : wrap-dim ( -- dim ) max-x get max-y get 2array ;
 
index c5f078e82ea828ade283606b9857e119dd5a2a62..33ef3bbe3afbbc007feef35d98557987fdfe5a27 100644 (file)
@@ -12,7 +12,7 @@ TUPLE: presentation < button object hook ;
 
 : invoke-presentation ( presentation command -- )
     over dup hook>> call
-    >r object>> r> invoke-command ;
+    [ object>> ] dip invoke-command ;
 
 : invoke-primary ( presentation -- )
     dup object>> primary-operation
@@ -36,12 +36,13 @@ M: presentation ungraft*
     call-next-method ;
 
 : <operations-menu> ( presentation -- menu )
-    dup dup hook>> curry
-    swap object>>
-    dup object-operations <commands-menu> ;
+    [ object>> ]
+    [ dup hook>> curry ]
+    [ object>> object-operations ]
+    tri <commands-menu> ;
 
 : operations-menu ( presentation -- )
-    dup <operations-menu> swap show-menu ;
+    dup <operations-menu> show-menu ;
 
 presentation H{
     { T{ button-down f f 3 } [ operations-menu ] }
index f42d65f738f7be6c9a15083c85d359af121e19eb..1c2055156ea346020159fb51e1d0ea1ab21aa0f5 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors arrays ui.gestures ui.gadgets ui.gadgets.buttons
 ui.gadgets.frames ui.gadgets.grids math.order
 ui.gadgets.theme ui.render kernel math namespaces sequences
 vectors models models.range math.vectors math.functions
-quotations colors math.geometry.rect ;
+quotations colors math.geometry.rect fry ;
 IN: ui.gadgets.sliders
 
 TUPLE: elevator < gadget direction ;
@@ -26,17 +26,19 @@ TUPLE: slider < frame elevator thumb saved line ;
 : slider-max*  ( gadget -- n ) model>> range-max-value*    ;
 
 : thumb-dim ( slider -- h )
-    dup slider-page over slider-max 1 max / 1 min
-    over elevator-length * min-thumb-dim max
-    over elevator>> rect-dim
-    rot orientation>> v. min ;
+    [
+        [ [ slider-page ] [ slider-max 1 max ] bi / 1 min ]
+        [ elevator-length ] bi * min-thumb-dim max
+    ]
+    [ [ elevator>> dim>> ] [ orientation>> ] bi v. ] bi min ;
 
 : slider-scale ( slider -- n )
     #! A scaling factor such that if x is a slider co-ordinate,
     #! x*n is the screen position of the thumb, and conversely
     #! for x/n. The '1 max' calls avoid division by zero.
-    dup elevator-length over thumb-dim - 1 max
-    swap slider-max* 1 max / ;
+    [ [ elevator-length ] [ thumb-dim ] bi - 1 max ]
+    [ slider-max* 1 max ]
+    bi / ;
 
 : slider>screen ( m scale -- n ) slider-scale * ;
 : screen>slider ( m scale -- n ) slider-scale / ;
@@ -104,13 +106,14 @@ elevator H{
 
 : layout-thumb-loc ( slider -- )
     dup thumb-loc (layout-thumb)
-    >r [ floor ] map r> (>>loc) ;
+    [ [ floor ] map ] dip (>>loc) ;
 
 : layout-thumb-dim ( slider -- )
-    dup dup thumb-dim (layout-thumb) >r
-    >r dup rect-dim r>
-    rot orientation>> set-axis [ ceiling ] map
-    r> (>>dim) ;
+    dup dup thumb-dim (layout-thumb)
+    [
+        [ [ rect-dim ] dip ] [ drop orientation>> ] 2bi set-axis
+        [ ceiling ] map
+    ] dip (>>dim) ;
 
 : layout-thumb ( slider -- )
     dup layout-thumb-loc layout-thumb-dim ;
@@ -121,13 +124,13 @@ M: elevator layout*
 : slide-by-line ( amount slider -- ) [ line>> * ] keep slide-by ;
 
 : <slide-button> ( vector polygon amount -- button )
-    >r gray swap <polygon-gadget> r>
-    [ swap find-slider slide-by-line ] curry <repeat-button>
+    [ gray swap <polygon-gadget> ] dip
+    '[ _ swap find-slider slide-by-line ] <repeat-button>
     swap >>orientation ;
 
 : elevator, ( gadget orientation -- gadget )
     tuck <elevator> >>elevator
-    swap <thumb>    >>thumb
+    swap <thumb> >>thumb
     dup elevator>> over thumb>> add-gadget
     @center grid-add ;
 
index 431804f4cabce8b8d5800919903f1e60107de6e0..32abcd5466b50077e632b5bc3136564ede92e66e 100644 (file)
@@ -16,4 +16,4 @@ IN: ui.gadgets.status-bar
     open-world-window ;
 
 : show-summary ( object gadget -- )
-    >r [ summary ] [ "" ] if* r> show-status ;
+    [ [ summary ] [ "" ] if* ] dip show-status ;
index 9dd152885e2ba09d308962dda108f6d3b8ff851c..35781fa5685606d99137c1cf8acc2aa19f7d38da 100644 (file)
@@ -53,3 +53,20 @@ HELP: draw-world
 { $values { "world" world } }
 { $description "Redraws a world." }
 { $notes "This word should only be called by the UI backend. To force a gadget to redraw from user code, call " { $link relayout-1 } "." } ;
+
+HELP: find-gl-context
+{ $values { "gadget" gadget } }
+{ $description "Makes the OpenGL context of the gadget's containing native window the current OpenGL context." }
+{ $notes "This word should be called from " { $link graft* } " and " { $link ungraft* } " methods which need to allocate and deallocate OpenGL resources, such as textures, display lists, and so on." } ;
+
+ARTICLE: "ui-paint-custom" "Implementing custom drawing logic"
+"The UI uses OpenGL to render gadgets. Custom rendering logic can be plugged in with the " { $link "ui-pen-protocol" } ", or by implementing a generic word:"
+{ $subsection draw-gadget* }
+"Custom drawing code has access to the full OpenGL API in the " { $vocab-link "opengl" } " vocabulary."
+$nl
+"Gadgets which need to allocate and deallocate OpenGL resources such as textures, display lists, and so on, should perform the allocation in the " { $link graft* } " method, and the deallocation in the " { $link ungraft* } " method. Since those words are not necessarily called with the gadget's OpenGL context active, a utility word can be used to find and make the correct OpenGL context current:"
+{ $subsection find-gl-context }
+"OpenGL state must not be altered as a result of drawing a gadget, so any flags which were enabled should be disabled, and vice versa."
+{ $subsection "ui-paint-coord" }
+{ $subsection "gl-utilities" }
+{ $subsection "text-rendering" } ;
index 904a2a5bac29f259b687b735a25f80e4f4fc17d1..68a2a18210109adf47d1094c106f63a0188d4650 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs continuations kernel math models
-namespaces opengl sequences io combinators math.vectors
+namespaces opengl sequences io combinators fry math.vectors
 ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks
 debugger math.geometry.rect ;
 IN: ui.gadgets.worlds
@@ -52,7 +52,7 @@ M: world request-focus-on ( child gadget -- )
 M: world layout*
     dup call-next-method
     dup glass>> [
-        >r dup rect-dim r> (>>dim)
+        [ dup rect-dim ] dip (>>dim)
     ] when* drop ;
 
 M: world focusable-child* gadget-child ;
@@ -67,9 +67,7 @@ M: world children-on nip children>> ;
 : draw-world? ( world -- ? )
     #! We don't draw deactivated worlds, or those with 0 size.
     #! On Windows, the latter case results in GL errors.
-    dup active?>>
-    over handle>>
-    rot rect-dim [ 0 > ] all? and and ;
+    [ active?>> ] [ handle>> ] [ dim>> [ 0 > ] all? ] tri and and ;
 
 TUPLE: world-error error world ;
 
@@ -127,5 +125,4 @@ M: world handle-gesture ( gesture gadget -- ? )
     ] [ 2drop f ] if ;
 
 : close-global ( world global -- )
-    dup get-global find-world rot eq?
-    [ f swap set-global ] [ drop ] if ;
+    [ get-global find-world eq? ] keep '[ f _ set-global ] when ;
index 1e472e921f0591ca9d8d8ada303af57a7f52f318..602d3fd4255a25d7c032f24e3384b221d8106e07 100644 (file)
@@ -191,6 +191,43 @@ HELP: gesture>string
     { $example "USING: io ui.gestures ;" "T{ key-down f { C+ } \"x\" } gesture>string print" "C+x" }
 } ;
 
+HELP: left-action
+{ $class-description "Gesture sent when the user performs a multi-touch three-finger swipe left." } ;
+
+HELP: right-action
+{ $class-description "Gesture sent when the user performs a multi-touch three-finger swipe right." } ;
+
+HELP: up-action
+{ $class-description "Gesture sent when the user performs a multi-touch three-finger swipe up." } ;
+
+HELP: down-action
+{ $class-description "Gesture sent when the user performs a multi-touch three-finger swipe down." } ;
+
+HELP: zoom-in-action
+{ $class-description "Gesture sent when the user performs a multi-touch two-finger pinch in." } ;
+
+HELP: zoom-out-action
+{ $class-description "Gesture sent when the user performs a multi-touch two-finger pinch out." } ;
+
+ARTICLE: "gesture-differences" "Gesture handling differences between platforms"
+"On Mac OS X, the modifier keys map as follows:"
+{ $table
+    { { $link S+ } "Shift" }
+    { { $link A+ } "Command (Apple)" }
+    { { $link C+ } "Control" }
+    { { $link M+ } "Option" }
+}
+"On Windows and X11:"
+{ $table
+    { { $link S+ } "Shift" }
+    { { $link A+ } "Alt" }
+    { { $link C+ } "Control" }
+    { { $link M+ } "Windows key" }
+}
+"On Windows, " { $link key-up } " gestures are not reported for all keyboard events."
+$nl
+{ $link "multitouch-gestures" } " are only supported on Mac OS X." ;
+
 ARTICLE: "ui-gestures" "UI gestures"
 "User actions such as keyboard input and mouse button clicks deliver " { $emphasis "gestures" } " to gadgets. If the direct receiver of the gesture does not handle it, the gesture is passed on to the receiver's parent, and this way it travels up the gadget hierarchy. Gestures which are not handled at some point are ignored."
 $nl
@@ -207,6 +244,9 @@ $nl
 { $subsection "ui-user-input" }
 "Mouse input:"
 { $subsection "mouse-gestures" }
+{ $subsection "multitouch-gestures" }
+"Guidelines for cross-platform applications:"
+{ $subsection "gesture-differences" }
 "Abstractions built on top of gestures:"
 { $subsection "ui-commands" }
 { $subsection "ui-operations" } ;
@@ -301,6 +341,18 @@ $nl
 "Global variable set when a mouse scroll wheel gesture is sent:"
 { $subsection scroll-direction } ;
 
+ARTICLE: "multitouch-gestures" "Multi-touch gestures"
+"Multi-touch gestures are only supported on Mac OS X with newer MacBook and MacBook Pro models."
+$nl
+"Three-finger swipe:"
+{ $subsection left-action }
+{ $subsection right-action }
+{ $subsection up-action }
+{ $subsection down-action }
+"Two-finger pinch:"
+{ $subsection zoom-in-action }
+{ $subsection zoom-out-action } ;
+
 ARTICLE: "action-gestures" "Action gestures"
 "Action gestures exist to keep keyboard shortcuts for common clipboard operations consistent."
 { $subsection cut-action }
index ffb9795ef8584105ed313faa7de55ac8988df0f0..5faaa93292ed4a4a5b5e294fa23b4610509e0ee6 100644 (file)
@@ -205,7 +205,7 @@ SYMBOL: drag-timer
     dup hand-last-button get = ;
 
 : multi-click-position? ( -- ? )
-    hand-loc get hand-click-loc get v- norm-sq 100 <= ;
+    hand-loc get hand-click-loc get distance 10 <= ;
 
 : multi-click? ( button -- ? )
     {
index 8e83f69edbb18ba5304259480cd1ad81fb79f746..bcfca946dd0ceb3cc3c2ad17d5037456107dcb35 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions kernel ui.commands
 ui.gestures sequences strings math words generic namespaces make
-hashtables help.markup quotations assocs ;
+hashtables help.markup quotations assocs fry ;
 IN: ui.operations
 
 SYMBOL: +keyboard+
@@ -38,7 +38,7 @@ SYMBOL: operations
     operations get [ predicate>> call ] with filter ;
 
 : find-operation ( obj quot -- command )
-    >r object-operations r> find-last nip ; inline
+    [ object-operations ] dip find-last nip ; inline
 
 : primary-operation ( obj -- operation )
     [ command>> +primary+ word-prop ] find-operation ;
@@ -63,7 +63,7 @@ SYMBOL: operations
         t >>listener? ;
 
 : modify-operations ( operations hook translator -- operations )
-    rot [ modify-operation ] with with map ;
+    '[ [ _ _ ] dip modify-operation ] map ;
 
 : operations>commands ( object hook translator -- pairs )
     [ object-operations ] 2dip modify-operations
index 294ee1c63dd43cae801bc19239ae5970bde4d41c..7f88a904ecdeb3aeacec49e0b1850ad6ba14a95e 100644 (file)
@@ -1,5 +1,6 @@
 USING: ui.gadgets ui.gestures help.markup help.syntax
-kernel classes strings opengl.gl models math.geometry.rect ;
+kernel classes strings opengl opengl.gl models
+math.geometry.rect ;
 IN: ui.render
 
 HELP: gadget
@@ -128,21 +129,11 @@ $nl
 { $subsection draw-string }
 { $subsection draw-text } ;
 
-ARTICLE: "ui-paint-custom" "Implementing custom drawing logic"
-"The UI uses OpenGL to render gadgets. Custom rendering logic can be plugged in with the " { $link "ui-pen-protocol" } ", or by implementing a generic word:"
-{ $subsection draw-gadget* }
-"Custom drawing code has access to the full OpenGL API in the " { $vocab-link "opengl" } " vocabulary."
-$nl
+ARTICLE: "ui-paint-coord" "The UI co-ordinate system"
 "The UI uses a co-ordinate system where the y axis is oriented down. The OpenGL " { $link GL_MODELVIEW } " matrix is not saved or restored when rendering a gadget. Instead, the origin of the gadget relative to the OpenGL context is stored in a variable:"
 { $subsection origin }
-"Custom drawing implementations can translate co-ordinates manually, or save and restore the " { $link GL_MODELVIEW } " matrix."
-$nl
-"OpenGL state must not be altered as a result of drawing a gadget, so any flags which were enabled should be disabled, and vice versa."
-$nl
-"Gadgets must not draw outside of their bounding box, however clipping is not enforced by default, for performance reasons. This can be changed by setting the " { $snippet "clipped?" } " slot to " { $link t } " in the gadget's constructor."
+"Custom drawing implementations can translate co-ordinates manually, or save and restore the " { $link GL_MODELVIEW } " matrix using a word such as " { $link with-translation } "."
 $nl
-"Saving the " { $link GL_MODELVIEW } " matrix and enabling/disabling flags can be done in a clean way using the combinators documented in the following section."
-{ $subsection "gl-utilities" }
-{ $subsection "text-rendering" } ;
+"Gadgets must not draw outside of their bounding box, however clipping is not enforced by default, for performance reasons. This can be changed by setting the " { $slot "clipped?" } " slot to " { $link t } " in the gadget's constructor." ;
 
 ABOUT: "ui-paint-custom"
index 1e4c9c34f1c0b2f7fe1e60ef98abff27519c552b..5cbac9798a054f096eb736b12d0eaa9619b9c38b 100755 (executable)
@@ -3,7 +3,7 @@
 USING: accessors alien alien.c-types arrays hashtables io kernel
 math namespaces opengl opengl.gl opengl.glu sequences strings
 io.styles vectors combinators math.vectors ui.gadgets colors
-math.order math.geometry.rect locals ;
+math.order math.geometry.rect locals specialized-arrays.float ;
 IN: ui.render
 
 SYMBOL: clip
@@ -12,7 +12,7 @@ SYMBOL: viewport-translation
 
 : flip-rect ( rect -- loc dim )
     rect-bounds [
-        >r { 1 -1 } v* r> { 0 -1 } v* v+
+        [ { 1 -1 } v* ] dip { 0 -1 } v* v+
         viewport-translation get v+
     ] keep ;
 
@@ -79,9 +79,7 @@ DEFER: draw-gadget
     >absolute clip [ rect-intersect ] change ;
 
 : with-clipping ( gadget quot -- )
-    clip get >r
-    over change-clip do-clip call
-    r> clip set do-clip ; inline
+    clip get [ over change-clip do-clip call ] dip clip set do-clip ; inline
 
 : draw-gadget ( gadget -- )
     {
@@ -140,10 +138,11 @@ TUPLE: gradient < caching-pen colors last-vertices last-colors ;
     direction dim v* dim over v- swap
     colors length dup 1- v/n [ v*n ] with map
     [ dup rot v+ 2array ] with map
-    concat concat >c-float-array ;
+    concat concat >float-array ;
 
 : gradient-colors ( colors -- seq )
-    [ color>raw 4array dup 2array ] map concat concat >c-float-array ;
+    [ color>raw 4array dup 2array ] map concat concat
+    >float-array ;
 
 M: gradient recompute-pen ( gadget gradient -- )
     tuck
@@ -168,24 +167,29 @@ M: gradient draw-interior
     } cleave ;
 
 ! Polygon pen
-TUPLE: polygon color vertex-array count ;
+TUPLE: polygon color
+interior-vertices
+interior-count
+boundary-vertices
+boundary-count ;
 
 : <polygon> ( color points -- polygon )
-    [ concat >c-float-array ] [ length ] bi polygon boa ;
+    dup close-path [ [ concat >float-array ] [ length ] bi ] bi@
+    polygon boa ;
 
-: draw-polygon ( polygon mode -- )
-    swap
+M: polygon draw-boundary
+    nip
     [ color>> gl-color ]
-    [ vertex-array>> gl-vertex-pointer ]
-    [ 0 swap count>> glDrawArrays ]
+    [ boundary-vertices>> gl-vertex-pointer ]
+    [ [ GL_LINE_STRIP 0 ] dip boundary-count>> glDrawArrays ]
     tri ;
 
-M: polygon draw-boundary
-    GL_LINE_LOOP draw-polygon drop ;
-
 M: polygon draw-interior
-    dup count>> 2 > GL_POLYGON GL_LINES ?
-    draw-polygon drop ;
+    nip
+    [ color>> gl-color ]
+    [ interior-vertices>> gl-vertex-pointer ]
+    [ [ GL_POLYGON 0 ] dip interior-count>> glDrawArrays ]
+    tri ;
 
 : arrow-up    { { 3 0 } { 6 6 } { 0 6 } } ;
 : arrow-right { { 0 0 } { 6 3 } { 0 6 } } ;
@@ -195,7 +199,7 @@ M: polygon draw-interior
 
 : <polygon-gadget> ( color points -- gadget )
     dup max-dim
-    >r <polygon> <gadget> r> >>dim
+    [ <polygon> <gadget> ] dip >>dim
     swap >>interior ;
 
 ! Font rendering
@@ -224,7 +228,7 @@ HOOK: free-fonts font-renderer ( world -- )
     dup string? [
         string-width
     ] [
-        0 -rot [ string-width max ] with each
+        [ 0 ] 2dip [ string-width max ] with each
     ] if ;
 
 : text-dim ( open-font text -- dim )
@@ -237,7 +241,7 @@ HOOK: free-fonts font-renderer ( world -- )
         [
             [
                 2dup { 0 0 } draw-string
-                >r open-font r> string-height
+                [ open-font ] dip string-height
                 0.0 swap 0.0 glTranslated
             ] with each
         ] with-translation
index 641763c0b13babcd404d0c474f4b6a2c8362e12d..cfe7baf0ae9b404a756d1f0df5107092a751bb8d 100644 (file)
@@ -1,35 +1,43 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays ui ui.commands ui.gestures ui.gadgets
-       ui.gadgets.worlds ui.gadgets.packs ui.gadgets.buttons
-       ui.gadgets.labels ui.gadgets.panes ui.gadgets.presentations
-       ui.gadgets.viewports ui.gadgets.lists ui.gadgets.tracks
-       ui.gadgets.scrollers ui.gadgets.panes hashtables io kernel math
-       models namespaces sequences sequences words continuations
-       debugger prettyprint ui.tools.traceback help editors ;
-
+USING: accessors arrays hashtables io kernel math models
+namespaces sequences sequences words continuations debugger
+prettyprint help editors ui ui.commands ui.gestures ui.gadgets
+ui.gadgets.worlds ui.gadgets.packs ui.gadgets.buttons
+ui.gadgets.labels ui.gadgets.panes ui.gadgets.presentations
+ui.gadgets.viewports ui.gadgets.lists ui.gadgets.tracks
+ui.gadgets.scrollers ui.gadgets.panes ui.tools.traceback ;
 IN: ui.tools.debugger
 
-: <restart-list> ( restarts restart-hook -- gadget )
-    [ name>> ] rot <model> <list> ;
+TUPLE: debugger < track error restarts restart-hook restart-list continuation ;
+
+<PRIVATE
+
+: <restart-list> ( debugger -- gadget )
+    [ restart-hook>> ] [ restarts>> ] bi
+    [ name>> ] swap <model> <list> ; inline
 
-TUPLE: debugger < track restarts ;
+: <error-pane> ( error -- pane )
+    <pane> [ [ print-error ] with-pane ] keep ; inline
 
-: <debugger-display> ( restart-list error -- gadget )
+: <debugger-display> ( debugger -- gadget )
     <filled-pile>
-        <pane>
-            swapd tuck [ print-error ] with-pane
-        add-gadget
+        over error>> <error-pane> add-gadget
+        swap restart-list>> add-gadget ; inline
 
-        swap add-gadget ;
+PRIVATE>
 
 : <debugger> ( error restarts restart-hook -- gadget )
     { 0 1 } debugger new-track
         add-toolbar
-        -rot <restart-list> >>restarts
-        dup restarts>> rot <debugger-display> <scroller> 1 track-add ;
+        swap >>restart-hook
+        swap >>restarts
+        swap >>error
+        error-continuation get >>continuation
+        dup <restart-list> >>restart-list
+        dup <debugger-display> <scroller> 1 track-add ;
 
-M: debugger focusable-child* restarts>> ;
+M: debugger focusable-child* restart-list>> ;
 
 : debugger-window ( error -- )
     #! No restarts for the debugger window
@@ -55,16 +63,20 @@ debugger "gestures" f {
     { T{ button-down } request-focus }
 } define-command-map
 
-: com-traceback ( -- ) error-continuation get traceback-window ;
+: com-traceback ( debugger -- ) continuation>> traceback-window ;
+
+\ com-traceback H{ } define-command
+
+: com-help ( debugger -- ) error>> (:help) ;
 
-\ com-traceback H{ { +nullary+ t } } define-command
+\ com-help H{ { +listener+ t } } define-command
 
-\ :help H{ { +nullary+ t } { +listener+ t } } define-command
+: com-edit ( debugger -- ) error>> (:edit) ;
 
-\ :edit H{ { +nullary+ t } { +listener+ t } } define-command
+\ com-edit H{ { +listener+ t } } define-command
 
 debugger "toolbar" f {
     { T{ key-down f f "s" } com-traceback }
-    { T{ key-down f f "h" } :help }
-    { T{ key-down f f "e" } :edit }
+    { T{ key-down f f "h" } com-help }
+    { T{ key-down f f "e" } com-edit }
 } define-command-map
index f310f727808432a937ad14c7ac1d5aaeb253c995..127269b325ce8be2b73de65b1aae810d81d3bba0 100644 (file)
@@ -1,12 +1,11 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: ui.gadgets colors kernel ui.render namespaces
-       models models.mapping sequences ui.gadgets.buttons
-       ui.gadgets.packs ui.gadgets.labels tools.deploy.config
-       namespaces ui.gadgets.editors ui.gadgets.borders ui.gestures
-       ui.commands assocs ui.gadgets.tracks ui ui.tools.listener
-       tools.deploy vocabs ui.tools.workspace system accessors ;
-
+USING: ui.gadgets colors kernel ui.render namespaces models
+models.mapping sequences ui.gadgets.buttons ui.gadgets.packs
+ui.gadgets.labels tools.deploy.config namespaces
+ui.gadgets.editors ui.gadgets.borders ui.gestures ui.commands
+assocs ui.gadgets.tracks ui ui.tools.listener tools.deploy
+vocabs ui.tools.workspace system accessors fry ;
 IN: ui.tools.deploy
 
 TUPLE: deploy-gadget < pack vocab settings ;
@@ -83,7 +82,7 @@ TUPLE: deploy-gadget < pack vocab settings ;
 
 : com-deploy ( gadget -- )
     dup com-save
-    dup find-deploy-vocab [ deploy ] curry call-listener
+    dup find-deploy-vocab '[ _ deploy ] call-listener
     close-window ;
 
 : com-help ( -- )
@@ -118,5 +117,7 @@ deploy-gadget "toolbar" f {
     dup com-revert ;
     
 : deploy-tool ( vocab -- )
-    vocab-name dup <deploy-gadget> 10 <border>
-    "Deploying \"" rot "\"" 3append open-window ;
+    vocab-name
+    [ <deploy-gadget> 10 <border> ]
+    [ "Deploying \"" swap "\"" 3append ] bi
+    open-window ;
index 5739a469ea7b7554ad734f9ca59965f803449b20..51425b124d0afffb64ddc73cc9dfad41c15206f2 100644 (file)
@@ -7,7 +7,7 @@ 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
 definitions calendar concurrency.flags concurrency.mailboxes
-ui.tools.workspace accessors sets destructors ;
+ui.tools.workspace accessors sets destructors fry ;
 IN: ui.tools.interactor
 
 ! If waiting is t, we're waiting for user input, and invoking
@@ -81,14 +81,15 @@ M: interactor model-changed
 : interactor-continue ( obj interactor -- )
     mailbox>> mailbox-put ;
 
-: clear-input ( interactor -- ) model>> clear-doc ;
+: clear-input ( interactor -- )
+    #! The with-datastack is a kludge to make it infer. Stupid.
+    model>> 1array [ clear-doc ] with-datastack drop ;
 
 : interactor-finish ( interactor -- )
-    #! The spawn is a kludge to make it infer. Stupid.
     [ editor-string ] keep
     [ interactor-input. ] 2keep
     [ add-interactor-history ] keep
-    [ clear-input ] curry "Clearing input" spawn drop ;
+    clear-input ;
 
 : interactor-eof ( interactor -- )
     dup interactor-busy? [
@@ -126,7 +127,7 @@ M: interactor stream-read
     swap dup zero? [
         2drop ""
     ] [
-        >r interactor-read dup [ "\n" join ] when r> short head
+        [ interactor-read dup [ "\n" join ] when ] dip short head
     ] if ;
 
 M: interactor stream-read-partial
index 1fe2d8eb24b574bf2bd991e86934acb2f13a8f2b..7ffbfd273881d115057d298af4b91160d283269e 100644 (file)
@@ -6,9 +6,9 @@ listener debugger threads boxes concurrency.flags math arrays
 generic accessors combinators assocs fry ui.commands ui.gadgets
 ui.gadgets.editors ui.gadgets.labelled ui.gadgets.panes
 ui.gadgets.buttons ui.gadgets.scrollers ui.gadgets.packs
-ui.gadgets.tracks ui.gadgets.borders ui.gestures ui.operations
-ui.tools.browser ui.tools.interactor ui.tools.inspector
-ui.tools.workspace ;
+ui.gadgets.tracks ui.gadgets.borders ui.gadgets.frames
+ui.gadgets.grids ui.gestures ui.operations ui.tools.browser
+ui.tools.interactor ui.tools.inspector ui.tools.workspace ;
 IN: ui.tools.listener
 
 TUPLE: listener-gadget < track input output ;
@@ -28,7 +28,7 @@ M: listener-gadget focusable-child*
     input>> ;
 
 M: listener-gadget call-tool* ( input listener -- )
-    >r string>> r> input>> set-editor-string ;
+    [ string>> ] dip input>> set-editor-string ;
 
 M: listener-gadget tool-scroller
     output>> find-scroller ;
@@ -95,13 +95,13 @@ M: engine-word word-completion-string
 : use-if-necessary ( word seq -- )
     over vocabulary>> over and [
         2dup [ assoc-stack ] keep = [ 2drop ] [
-            >r vocabulary>> vocab-words r> push
+            [ vocabulary>> vocab-words ] dip push
         ] if
     ] [ 2drop ] if ;
 
 : insert-word ( word -- )
     get-workspace listener>> input>>
-    [ >r word-completion-string r> user-input* drop ]
+    [ [ word-completion-string ] dip user-input* drop ]
     [ interactor-use use-if-necessary ]
     2bi ;
 
@@ -153,9 +153,9 @@ M: engine-word word-completion-string
     dup <listener-input> >>input ;
 
 : <listener-scroller> ( listener -- scroller )
-    <filled-pile>
-        over output>> add-gadget
-        swap input>> add-gadget
+    <frame>
+        over output>> @top grid-add
+        swap input>> @center grid-add
     <scroller> ;
 
 : <listener-gadget> ( -- gadget )
index 05d1ccdb82a97435e367cea00d8b75d0f12bb337..7280efe8850a2b3389b5ec391cbca2f55b5687ef 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: ui.tools.workspace kernel quotations tools.profiler
 ui.commands ui.gadgets ui.gadgets.panes ui.gadgets.scrollers
-ui.gadgets.tracks ui.gestures ui.gadgets.buttons accessors ;
+ui.gadgets.tracks ui.gestures ui.gadgets.buttons accessors fry ;
 IN: ui.tools.profiler
 
 TUPLE: profiler-gadget < track pane ;
@@ -14,7 +14,7 @@ TUPLE: profiler-gadget < track pane ;
         dup pane>> <scroller> 1 track-add ;
 
 : with-profiler-pane ( gadget quot -- )
-    >r pane>> r> with-pane ;
+    [ pane>> ] dip with-pane ;
 
 : com-full-profile ( gadget -- )
     [ profile. ] with-profiler-pane ;
@@ -39,10 +39,10 @@ profiler-gadget "toolbar" f {
 GENERIC: profiler-presentation ( obj -- quot )
 
 M: usage-profile profiler-presentation
-    word>> [ usage-profile. ] curry ;
+    word>> '[ _ usage-profile. ] ;
 
 M: vocab-profile profiler-presentation
-    vocab>> [ vocab-profile. ] curry ;
+    vocab>> '[ _ vocab-profile. ] ;
 
 M: f profiler-presentation
     drop [ vocabs-profile. ] ;
index c8c7c6c2191035bbe63834553cf87ad25968fb57..39a644230808654d58ff111e24c5cc3bf14ff04b 100644 (file)
@@ -19,7 +19,7 @@ IN: ui.tools.search.tests
     ] with-grafted-gadget ;
 
 : test-live-search ( gadget quot -- ? )
-    >r update-live-search dup assert-non-empty r> all? ;
+    [ update-live-search dup assert-non-empty ] dip all? ;
 
 [ t ] [
     "swp" all-words f <definition-search>
index 6368737460a9c1056c5a8ca25bb595811e715754..8e1cc8d8f06b592e829a4428ec28dd525ab14bbc 100644 (file)
@@ -76,17 +76,6 @@ $nl
 
 ;
 
-ARTICLE: "ui-tool-tutorial" "UI tool tutorial"
-"The following is an example of a typical session with the UI which should give you a taste of its power:"
-{ $list
-    { "You decide to refactor some code, and move a few words from a source file you have already loaded, into a new source file." }
-    { "You press " { $operation edit } " in the listener, which displays a gadget where you can type part of a loaded file's name, and then press " { $snippet "RET" } " when the correct completion is highlighted. This opens the file in your editor." } 
-    { "You refactor your words, move them to a new source file, and load the new file using " { $link run-file } "." }
-    { "Interactively testing the new code reveals a problem with one particular code snippet, so you enter it in the listener's input area, and press " { $operation walk } " to invoke the single stepper." }
-    { "Single stepping through the code makes the problem obvious, so you right-click on a presentation of the broken word in the stepper, and choose " { $strong "Edit" } " from the menu." }
-    { "After fixing the problem in the source editor, you right click on the word in the stepper and invoke " { $strong "Reload" } " from the menu." }
-} ;
-
 ARTICLE: "ui-completion-words" "Word completion popup"
 "Clicking a word in the word completion popup displays the word definition in the " { $link "ui-browser" } ". Pressing " { $snippet "RET" } " with a word selected inserts the word name in the listener, along with a " { $link POSTPONE: USE: } " declaration (if necessary)."
 { $operations \ $operations } ;
@@ -110,18 +99,16 @@ $nl
 { $subsection "ui-completion-sources" } ;
 
 ARTICLE: "ui-workspace-keys" "UI keyboard shortcuts"
+"See " { $link "gesture-differences" } " to find out how your platform's modifier keys map to modifiers in the Factor UI."
 { $command-map workspace "tool-switching" }
 { $command-map workspace "scrolling" }
 { $command-map workspace "workflow" }
-{ $command-map workspace "multi-touch" }
-{ $heading "Implementation" }
-"Workspaces are instances of " { $link workspace } "." ;
+{ $command-map workspace "multi-touch" } ;
 
 ARTICLE: "ui-tools" "UI developer tools"
 "The Factor development environment can seem rather different from what you are used to, because it is very simple and powerful.."
 $nl
 "To take full advantage of the UI, you should be using a supported text editor. See " { $link "editor" } "."
-{ $subsection "ui-tool-tutorial" }
 { $subsection "ui-workspace-keys" }
 { $subsection "ui-presentations" }
 { $subsection "ui-completion" }
index 3310a3e0a56a9c919d4e9f3058e88636de825326..9927f9e5ae9353683012f132d177cab5d3105b38 100644 (file)
@@ -9,7 +9,7 @@ ui.gadgets.books ui.gadgets.buttons ui.gadgets.labelled
 ui.gadgets.scrollers ui.gadgets.tracks ui.gadgets.worlds
 ui.gadgets.presentations ui.gestures words vocabs.loader
 tools.test tools.vocabs ui.gadgets.buttons ui.gadgets.status-bar
-mirrors ;
+mirrors fry ;
 IN: ui.tools
 
 : <workspace-tabs> ( workspace -- tabs )
@@ -93,7 +93,7 @@ workspace "workflow" f {
 ] workspace-window-hook set-global
 
 : inspect-continuation ( traceback -- )
-    control-value [ inspect ] curry call-listener ;
+    control-value '[ _ inspect ] call-listener ;
 
 traceback-gadget "toolbar" f {
     { T{ key-down f f "v" } variables }
index 45f15b1ffc9f80b6423c4af355a8f101ff2d54ef..90f1e601c7fa740b43beb58ab28a58844f1904e7 100644 (file)
@@ -53,4 +53,4 @@ M: traceback-gadget pref-dim* drop { 550 600 } ;
     "Dynamic variables" open-status-window ;
 
 : traceback-window ( continuation -- )
-    <model> <traceback-gadget> "Traceback" open-window ;
+    <model> <traceback-gadget> "Traceback" open-status-window ;
index 9c825d49202a9ddef1c0fe7e70aa0f7ccf7d700c..e6643698c7c26415782855b9f35c2c103318a1d6 100644 (file)
@@ -5,7 +5,7 @@ ui.tools.listener ui.tools.traceback ui.gadgets.buttons
 ui.gadgets.status-bar ui.gadgets.tracks ui.commands ui.gadgets
 models models.filter ui.tools.workspace ui.gestures
 ui.gadgets.labels ui threads namespaces make tools.walker assocs
-combinators ;
+combinators fry ;
 IN: ui.tools.walker
 
 TUPLE: walker-gadget < track
@@ -53,7 +53,7 @@ M: walker-gadget focusable-child*
     ] "" make ;
 
 : <thread-status> ( model thread -- gadget )
-    [ walker-state-string ] curry <filter> <label-control> ;
+    '[ _ walker-state-string ] <filter> <label-control> ;
 
 : <walker-gadget> ( status continuation thread -- gadget )
     { 0 1 } walker-gadget new-track
@@ -89,7 +89,7 @@ walker-gadget "toolbar" f {
     } cond ;
 
 : find-walker-window ( thread -- world/f )
-    [ swap walker-for-thread? ] curry find-window ;
+    '[ _ swap walker-for-thread? ] find-window ;
 
 : walker-window ( status continuation thread -- )
     [ <walker-gadget> ] [ name>> ] bi open-status-window ;
index 6536cb8c7d9ff874b9ae6d672e11e5fc6de1d0b3..3b689eee398530281afd36f88a42a7347c413a42 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: classes continuations help help.topics kernel models
-sequences assocs arrays namespaces accessors math.vectors ui
+sequences assocs arrays namespaces accessors math.vectors fry ui
 ui.backend ui.tools.debugger ui.gadgets ui.gadgets.books
 ui.gadgets.buttons ui.gadgets.labelled ui.gadgets.panes
 ui.gadgets.scrollers ui.gadgets.tracks ui.gadgets.worlds
@@ -33,7 +33,7 @@ M: gadget tool-scroller drop f ;
     set-model ;
 
 : get-workspace* ( quot -- workspace )
-    [ >r dup workspace? r> [ drop f ] if ] curry find-window
+    '[ dup workspace? _ [ drop f ] if ] find-window
     [ dup raise-window gadget-child ]
     [ workspace-window* ] if* ; inline
 
index eadd110fe7e8ac3c5efab0965262bfbbc5cb231e..7a012aa3e001891530b7022b5ad4263443533c9f 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors namespaces make sequences kernel math arrays io
 ui.gadgets generic combinators ;
@@ -7,7 +7,7 @@ IN: ui.traverse
 TUPLE: node value children ;
 
 : traverse-step ( path gadget -- path' gadget' )
-    >r unclip r> children>> ?nth ;
+    [ unclip ] dip children>> ?nth ;
 
 : make-node ( quot -- ) { } make node boa , ; inline
 
@@ -43,7 +43,7 @@ TUPLE: node value children ;
     traverse-step traverse-from-path ;
 
 : (traverse-middle) ( frompath topath gadget -- )
-    >r >r first 1+ r> first r> children>> <slice> % ;
+    [ first 1+ ] [ first ] [ children>> ] tri* <slice> % ;
 
 : traverse-post ( topath gadget -- )
     traverse-step traverse-to-path ;
@@ -59,15 +59,15 @@ TUPLE: node value children ;
 DEFER: (gadget-subtree)
 
 : traverse-child ( frompath topath gadget -- )
-    dup -roll [
-        >r >r rest-slice r> r> traverse-step (gadget-subtree)
-    make-node ;
+    [ 2nip ] 3keep
+    [ [ rest-slice ] 2dip traverse-step (gadget-subtree) ]
+    make-node ;
 
 : (gadget-subtree) ( frompath topath gadget -- )
     {
         { [ dup not ] [ 3drop ] }
         { [ pick empty? pick empty? and ] [ 2nip , ] }
-        { [ pick empty? ] [ rot drop traverse-to-path ] }
+        { [ pick empty? ] [ traverse-to-path drop ] }
         { [ over empty? ] [ nip traverse-from-path ] }
         { [ pick first pick first = ] [ traverse-child ] }
         [ traverse-middle ]
index 978bd2405527487efa4d4e93b8fb28c7acc8c3c2..738d259cad5c0a3c15843887fab27eb3de9e7e2a 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax strings quotations debugger
 io.styles namespaces ui.backend ui.gadgets ui.gadgets.worlds
-ui.gadgets.tracks ui.gadgets.packs ui.gadgets.grids math.geometry.rect ;
+ui.gadgets.tracks ui.gadgets.packs ui.gadgets.grids math.geometry.rect colors ;
 IN: ui
 
 HELP: windows
@@ -47,18 +47,19 @@ HELP: (open-window)
 { $description "Opens a native window containing the given world. This grafts the world by calling " { $link graft } ". Each world can only be displayed in one top-level window at a time." }
 { $notes "This word should not be called directly by user code. Instead, use " { $link open-window } "." } ;
 
+HELP: raise-window
+{ $values { "gadget" gadget } }
+{ $description "Makes the native window containing the given gadget the front-most window." } ;
+
+HELP: with-ui
+{ $values { "quot" quotation } }
+{ $description "Calls the quotation, starting the UI first if necessary." }
+{ $notes "This combinator should be used in the " { $link POSTPONE: MAIN: } " word of a vocabulary, in order for the vocabulary to work when run from the UI listener (" { $snippet "\"my-app\" run" } " and the command line (" { $snippet "./factor -run=my-app" } ")." }
+{ $examples "The " { $vocab-link "hello-ui" } " vocabulary implements a simple UI application which uses this combinator." } ;
+
 ARTICLE: "ui-glossary" "UI glossary"
 { $table
-    { "color specifier"
-        { "an array of four elements, all numbers between 0 and 1:"
-            { $list
-                "red"
-                "green"
-                "blue"
-                "alpha - 0 is completely transparent, 1 is completely opaque"
-            }
-        }
-    }
+    { "color" { "an instance of " { $link color } } }
     { "dimension" "a pair of integers denoting pixel size on screen" }
     { "font specifier"
         { "an array of three elements:"
@@ -94,6 +95,7 @@ ARTICLE: "gadgets" "Pre-made UI gadgets"
 { $subsection "ui.gadgets.sliders" }
 { $subsection "ui.gadgets.scrollers" }
 { $subsection "gadgets-editors" }
+{ $subsection "ui.gadgets.menus" }
 { $subsection "ui.gadgets.panes" }
 { $subsection "ui.gadgets.presentations" }
 { $subsection "ui.gadgets.lists" } ;
@@ -129,9 +131,7 @@ ARTICLE: "ui-backend" "Developing UI backends"
 "UI backends may implement the " { $link "clipboard-protocol" } "." ;
 
 ARTICLE: "ui-backend-init" "UI initialization and the event loop"
-"An UI backend is required to define a word to start the UI:"
-{ $subsection ui }
-"This word should contain backend initialization, together with some boilerplate:"
+"An UI backend is required to define a method on the " { $link ui } " word. This word should contain backend initialization, together with some boilerplate:"
 { $code
     "IN: shells"
     ""
@@ -163,10 +163,6 @@ ARTICLE: "ui-backend-windows" "UI backend window management"
 "If the user clicks the window's close box, you must call the following word:"
 { $subsection close-window } ;
 
-HELP: raise-window
-{ $values { "gadget" gadget } }
-{ $description "Makes the native window containing the given gadget the front-most window." } ;
-
 ARTICLE: "ui-layouts" "Gadget hierarchy and layouts"
 "A layout gadget is a gadget whose sole purpose is to contain other gadgets. Layout gadgets position and resize children according to a certain policy, taking the preferred size of the children into account. Gadget hierarchies are constructed by building up nested layouts."
 { $subsection "ui-layout-basics" }
@@ -240,7 +236,23 @@ $nl
 { $subsection "clipboard-protocol" }
 { $see-also "ui-layout-impl" } ;
 
+ARTICLE: "starting-ui" "Starting the UI"
+"The UI starts automatically where possible:"
+{ $list
+    { "On Windows, the UI starts when the Factor executable is run." }
+    { "On X11, the UI starts if the " { $snippet "DISPLAY" } " environment variable is set." }
+    { "On Mac OS X, the UI starts if the " { $snippet "Factor.app" } " application bundle is run." }
+}
+"In all cases, passing the " { $snippet "-run=listener" } " command line switch starts the terminal listener instead. The UI can be started from the terminal listener using a word:"
+{ $subsection ui }
+"To run the terminal listener and the UI simultaneously, start the UI in a new thread:"
+{ $code "USING: threads ui ;" "[ ui ] in-thread" }
+"The main word of a vocabulary implementing a UI application should use a combinator to ensure that the application works when run from the command line as well as in the UI listener:"
+{ $subsection with-ui } ;
+
 ARTICLE: "ui" "UI framework"
+"The " { $vocab-link "ui" } " vocabulary hierarchy implements the Factor UI framework. The implementation relies on a small amount of platform-specific code to open windows and receive keyboard and mouse events; UI gadgets are rendered using OpenGL."
+{ $subsection "starting-ui" }
 { $subsection "ui-glossary" }
 { $subsection "building-ui" }
 { $subsection "new-gadgets" }
index 512930d06d8495cb3005dbebbb7d540485857f37..1481287e9599351dd14c4216de13a171a08d0eea 100755 (executable)
@@ -9,7 +9,7 @@ windows.user32 windows.opengl32 windows.messages windows.types
 windows.nt windows threads libc combinators
 combinators.short-circuit continuations command-line shuffle
 opengl ui.render ascii math.bitwise locals symbols accessors
-math.geometry.rect math.order ascii ;
+math.geometry.rect math.order ascii calendar ;
 IN: ui.windows
 
 SINGLETON: windows-ui-backend
@@ -284,20 +284,18 @@ SYMBOL: nc-buttons
     message>button nc-buttons get
     swap [ push ] [ delete ] if ;
 
-: >lo-hi ( WORD -- array ) [ lo-word ] keep hi-word 2array ;
-: mouse-wheel ( lParam -- array ) >lo-hi [ sgn neg ] map ;
+: >lo-hi ( WORD -- array ) [ lo-word ] [ hi-word ] bi 2array ;
 
-: mouse-absolute>relative ( lparam handle -- array )
-    >r >lo-hi r>
-    "RECT" <c-object> [ GetWindowRect win32-error=0/f ] keep
-    get-RECT-top-left 2array v- ;
+: mouse-wheel ( wParam -- array ) >lo-hi [ sgn neg ] map ;
 
 : mouse-event>gesture ( uMsg -- button )
     key-modifiers swap message>button
     [ <button-down> ] [ <button-up> ] if ;
 
-: prepare-mouse ( hWnd uMsg wParam lParam -- button coordinate world )
-    nip >r mouse-event>gesture r> >lo-hi rot window ;
+:: prepare-mouse ( hWnd uMsg wParam lParam -- button coordinate world )
+    uMsg mouse-event>gesture
+    lParam >lo-hi
+    hWnd window ;
 
 : set-capture ( hwnd -- )
     mouse-captured get [
@@ -312,10 +310,10 @@ SYMBOL: nc-buttons
     mouse-captured off ;
 
 : handle-wm-buttondown ( hWnd uMsg wParam lParam -- )
-    >r >r
-    over set-capture
-    dup message>button drop nc-buttons get delete
-    r> r> prepare-mouse send-button-down ;
+    [
+        over set-capture
+        dup message>button drop nc-buttons get delete
+    ] 2dip prepare-mouse send-button-down ;
 
 : handle-wm-buttonup ( hWnd uMsg wParam lParam -- )
     mouse-captured get [ release-capture ] when
@@ -337,9 +335,8 @@ SYMBOL: nc-buttons
     TrackMouseEvent drop
     >lo-hi swap window move-hand fire-motion ;
 
-: handle-wm-mousewheel ( hWnd uMsg wParam lParam -- )
-    >r nip r>
-    pick mouse-absolute>relative >r mouse-wheel r> rot window send-wheel ;
+:: handle-wm-mousewheel ( hWnd uMsg wParam lParam -- )
+    wParam mouse-wheel hand-loc get hWnd window send-wheel ;
 
 : handle-wm-cancelmode ( hWnd uMsg wParam lParam -- )
     #! message sent if windows needs application to stop dragging
@@ -434,7 +431,7 @@ M: windows-ui-backend do-events
     style 0 ex-style AdjustWindowRectEx win32-error=0/f ;
 
 : make-RECT ( world -- RECT )
-    dup window-loc>> dup rot rect-dim v+
+    [ window-loc>> dup ] [ rect-dim ] bi v+
     "RECT" <c-object>
     over first over set-RECT-right
     swap second over set-RECT-bottom
@@ -456,10 +453,11 @@ M: windows-ui-backend do-events
 
 : create-window ( rect -- hwnd )
     make-adjusted-RECT
-    >r class-name-ptr get-global f r>
-    >r >r >r ex-style r> r>
+    [ class-name-ptr get-global f ] dip
+    [
+        [ ex-style ] 2dip
         { WS_CLIPSIBLINGS WS_CLIPCHILDREN style } flags
-    r> get-RECT-dimensions
+    ] dip get-RECT-dimensions
     f f f GetModuleHandle f CreateWindowEx dup win32-error=0/f ;
 
 : show-window ( hWnd -- )
@@ -472,7 +470,7 @@ M: windows-ui-backend do-events
     "MSG" malloc-object msg-obj set-global
     "Factor-window" utf16n malloc-string class-name-ptr set-global
     register-wndclassex drop
-    GetDoubleClickTime double-click-timeout set-global ;
+    GetDoubleClickTime milliseconds double-click-timeout set-global ;
 
 : cleanup-win32-ui ( -- )
     class-name-ptr get-global [ dup f UnregisterClass drop free ] when*
@@ -515,7 +513,7 @@ M: windows-ui-backend raise-window* ( world -- )
 M: windows-ui-backend set-title ( string world -- )
     handle>>
     dup title>> [ free ] when*
-    >r utf16n malloc-string r>
+    [ utf16n malloc-string ] dip
     2dup (>>title)
     hWnd>> WM_SETTEXT 0 roll alien-address SendMessage drop ;
 
old mode 100644 (file)
new mode 100755 (executable)
index de57c2d..b65236d
@@ -79,7 +79,7 @@ M: world configure-event
 : key-down-event>gesture ( event world -- string gesture )
     dupd
     handle>> xic>> lookup-string
-    >r swap event-modifiers r> key-code <key-down> ;
+    [ swap event-modifiers ] dip key-code <key-down> ;
 
 M: world key-down-event
     [ key-down-event>gesture ] keep
@@ -92,18 +92,20 @@ M: world key-down-event
     dup event-modifiers swap 0 XLookupKeysym key-code <key-up> ;
 
 M: world key-up-event
-    >r key-up-event>gesture r> world-focus propagate-gesture ;
+    [ key-up-event>gesture ] dip world-focus propagate-gesture ;
 
 : mouse-event>gesture ( event -- modifiers button loc )
-    dup event-modifiers over XButtonEvent-button
-    rot mouse-event-loc ;
+    [ event-modifiers ]
+    [ XButtonEvent-button ]
+    [ mouse-event-loc ]
+    tri ;
 
 M: world button-down-event
-    >r mouse-event>gesture >r <button-down> r> r>
+    [ mouse-event>gesture [ <button-down> ] dip ] dip
     send-button-down ;
 
 M: world button-up-event
-    >r mouse-event>gesture >r <button-up> r> r>
+    [ mouse-event>gesture [ <button-up> ] dip ] dip
     send-button-up ;
 
 : mouse-event>scroll-direction ( event -- pair )
@@ -115,7 +117,7 @@ M: world button-up-event
     } at ;
 
 M: world wheel-event
-    >r dup mouse-event>scroll-direction swap mouse-event-loc r>
+    [ [ mouse-event>scroll-direction ] [ mouse-event-loc ] bi ] dip
     send-wheel ;
 
 M: world enter-event motion-event ;
@@ -123,7 +125,7 @@ M: world enter-event motion-event ;
 M: world leave-event 2drop forget-rollover ;
 
 M: world motion-event
-    >r dup XMotionEvent-x swap XMotionEvent-y 2array r>
+    [ [ XMotionEvent-x ] [ XMotionEvent-y ] bi 2array ] dip
     move-hand fire-motion ;
 
 M: world focus-in-event
@@ -144,10 +146,10 @@ M: world selection-notify-event
 
 : clipboard-for-atom ( atom -- clipboard )
     {
-        { [ dup XA_PRIMARY = ] [ drop selection get ] }
-        { [ dup XA_CLIPBOARD = ] [ drop clipboard get ] }
+        { XA_PRIMARY [ selection get ] }
+        { XA_CLIPBOARD [ clipboard get ] }
         [ drop <clipboard> ]
-    } cond ;
+    } case ;
 
 : encode-clipboard ( string type -- bytes )
     XSelectionRequestEvent-target
@@ -158,7 +160,7 @@ M: world selection-notify-event
     [ XSelectionRequestEvent-requestor ] keep
     [ XSelectionRequestEvent-property ] keep
     [ XSelectionRequestEvent-target ] keep
-    >r 8 PropModeReplace r>
+    [ 8 PropModeReplace ] dip
     [
         XSelectionRequestEvent-selection
         clipboard-for-atom contents>>
@@ -208,8 +210,7 @@ M: x-clipboard copy-clipboard
     (>>contents) ;
 
 M: x-clipboard paste-clipboard
-    >r find-world handle>> window>>
-    r> atom>> convert-selection ;
+    [ find-world handle>> window>> ] dip atom>> convert-selection ;
 
 : init-clipboard ( -- )
     XA_PRIMARY <x-clipboard> selection set-global
@@ -219,14 +220,13 @@ M: x-clipboard paste-clipboard
     dup [ 127 <= ] all? [ XStoreName drop ] [ 3drop ] if ;
 
 : set-title-new ( dpy window string -- )
-    >r
-    XA_NET_WM_NAME XA_UTF8_STRING 8 PropModeReplace
-    r> utf8 encode dup length XChangeProperty drop ;
+    [ XA_NET_WM_NAME XA_UTF8_STRING 8 PropModeReplace ] dip
+    utf8 encode dup length XChangeProperty drop ;
 
 M: x11-ui-backend set-title ( string world -- )
-    handle>> window>> swap dpy get -rot
-    3dup set-title-old set-title-new ;
-    
+    handle>> window>> swap
+    [ dpy get ] 2dip [ set-title-old ] [ set-title-new ] 3bi ;
+
 M: x11-ui-backend set-fullscreen* ( ? world -- )
     handle>> window>> "XClientMessageEvent" <c-object>
     tuck set-XClientMessageEvent-window
@@ -237,8 +237,7 @@ M: x11-ui-backend set-fullscreen* ( ? world -- )
     "_NET_WM_STATE" x-atom over set-XClientMessageEvent-message_type
     32 over set-XClientMessageEvent-format
     "_NET_WM_STATE_FULLSCREEN" x-atom over set-XClientMessageEvent-data1
-    >r dpy get root get 0 SubstructureNotifyMask r> XSendEvent drop ;
-
+    [ dpy get root get 0 SubstructureNotifyMask ] dip XSendEvent drop ;
 
 M: x11-ui-backend (open-window) ( world -- )
     dup gadget-window
index 0f2e12119de141fe8eb9b0d4b06cd729ad8013af..58c7a5d10e6eabe9ebe11ecbeab54e6380ed3322 100644 (file)
@@ -72,7 +72,7 @@ VALUE: grapheme-table
     grapheme-table nth nth not ;
 
 : chars ( i str n -- str[i] str[i+n] )
-    swap >r dupd + r> [ ?nth ] curry bi@ ;
+    swap [ dupd + ] dip [ ?nth ] curry bi@ ;
 
 : find-index ( seq quot -- i ) find drop ; inline
 : find-last-index ( seq quot -- i ) find-last drop ; inline
index 3def7b5f4812212f4067267c500beea7c6d1dfcd..932f72960a1aa847bf14d401d6495880aeaffedf 100644 (file)
@@ -5,7 +5,7 @@ unicode.normalize math unicode.categories combinators
 assocs strings splitting kernel accessors ;
 IN: unicode.case
 
-: at-default ( key assoc -- value/key ) over >r at r> or ;
+: at-default ( key assoc -- value/key ) [ at ] [ drop ] 2bi or ;
 
 : ch>lower ( ch -- lower ) simple-lower at-default ;
 : ch>upper ( ch -- upper ) simple-upper at-default ;
index 7f445b8513c9b91496114099fdd403ea81602bda..90b280ee09f5697968059c069c0bc27fb619a71c 100644 (file)
@@ -124,7 +124,7 @@ PRIVATE>
     [ zero? ] tri@ and and ;\r
 \r
 : filter-ignorable ( weights -- weights' )\r
-    >r f r> [\r
+    f swap [\r
         tuck primary>> zero? and\r
         [ swap ignorable?>> or ]\r
         [ swap completely-ignorable? or not ] 2bi\r
index 31d0be799f194bb6ea1dd7947ac0b66bd6653f70..80cf40fbf1f3d38db7bde2df75b6ae49ae2c011d 100644 (file)
@@ -49,7 +49,7 @@ VALUE: properties
 : (process-data) ( index data -- newdata )
     filter-comments
     [ [ nth ] keep first swap ] with { } map>assoc
-    [ >r hex> r> ] assoc-map ;
+    [ [ hex> ] dip ] assoc-map ;
 
 : process-data ( index data -- hash )
     (process-data) [ hex> ] assoc-map [ nip ] assoc-filter >hashtable ;
index 8d6f6e888a69b9d806048e9c6fe92e83fc426646..35bdda67f051accd3369dfd0bcc4e32192d48cec 100644 (file)
@@ -27,14 +27,17 @@ IN: unicode.normalize
 
 : hangul>jamo ( hangul -- jamo-string )
     hangul-base - final-count /mod final-base +
-    >r medial-count /mod medial-base +
-    >r initial-base + r> r>
+    [
+        medial-count /mod medial-base +
+        [ initial-base + ] dip
+    ] dip
     dup final-base = [ drop 2array ] [ 3array ] if ;
 
 : jamo>hangul ( initial medial final -- hangul )
-    >r >r initial-base - medial-count *
-    r> medial-base - + final-count *
-    r> final-base - + hangul-base + ;
+    [
+        [ initial-base - medial-count * ] dip
+        medial-base - + final-count *
+    ] dip final-base - + hangul-base + ;
 
 ! Normalization -- Decomposition 
 
@@ -45,7 +48,7 @@ IN: unicode.normalize
 : reorder-next ( string i -- new-i done? )
     over [ non-starter? ] find-from drop [
         reorder-slice
-        >r dup [ combining-class ] insertion-sort to>> r>
+        [ dup [ combining-class ] insertion-sort to>> ] dip
     ] [ length t ] if* ;
 
 : reorder-loop ( string start -- )
diff --git a/basis/unix/getfsstat/freebsd/authors.txt b/basis/unix/getfsstat/freebsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/getfsstat/freebsd/freebsd.factor b/basis/unix/getfsstat/freebsd/freebsd.factor
new file mode 100644 (file)
index 0000000..1d9cab5
--- /dev/null
@@ -0,0 +1,11 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.getfsstat.freebsd
+
+: MNT_WAIT        1       ; inline ! synchronously wait for I/O to complete
+: MNT_NOWAIT      2       ; inline ! start all I/O, but do not wait for it 
+: MNT_LAZY        3       ; inline ! push data not written by filesystem syncer 
+: MNT_SUSPEND     4       ; inline ! Suspend file system after sync 
+
+FUNCTION: int getfsstat ( statfs* buf, int bufsize, int flags ) ;
diff --git a/basis/unix/getfsstat/freebsd/tags.txt b/basis/unix/getfsstat/freebsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/getfsstat/macosx/authors.txt b/basis/unix/getfsstat/macosx/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/getfsstat/macosx/macosx.factor b/basis/unix/getfsstat/macosx/macosx.factor
new file mode 100644 (file)
index 0000000..fe39f85
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.getfsstat.macosx
+
+: MNT_WAIT    1   ; inline ! synchronously wait for I/O to complete
+: MNT_NOWAIT  2   ; inline ! start all I/O, but do not wait for it
+
+FUNCTION: int getfsstat64 ( statfs* buf, int bufsize, int flags ) ;
diff --git a/basis/unix/getfsstat/macosx/tags.txt b/basis/unix/getfsstat/macosx/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/getfsstat/netbsd/authors.txt b/basis/unix/getfsstat/netbsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/getfsstat/netbsd/netbsd.factor b/basis/unix/getfsstat/netbsd/netbsd.factor
new file mode 100644 (file)
index 0000000..1c8941a
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.getfsstat.netbsd
+
+: MNT_WAIT        1       ; inline ! synchronously wait for I/O to complete
+: MNT_NOWAIT      2       ; inline ! start all I/O, but do not wait for it 
+: MNT_LAZY        3       ; inline ! push data not written by filesystem syncer 
+
+FUNCTION: int getvfsstat ( statfs* buf, int bufsize, int flags ) ;
diff --git a/basis/unix/getfsstat/netbsd/tags.txt b/basis/unix/getfsstat/netbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/getfsstat/openbsd/authors.txt b/basis/unix/getfsstat/openbsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/getfsstat/openbsd/openbsd.factor b/basis/unix/getfsstat/openbsd/openbsd.factor
new file mode 100644 (file)
index 0000000..8bf692b
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.getfsstat.openbsd
+
+: MNT_WAIT        1       ; ! synchronously wait for I/O to complete
+: MNT_NOWAIT      2       ; ! start all I/O, but do not wait for it
+: MNT_LAZY        3       ; ! push data not written by filesystem syncer
+
+FUNCTION: int getfsstat ( statfs* buf, int bufsize, int flags ) ;
diff --git a/basis/unix/getfsstat/openbsd/tags.txt b/basis/unix/getfsstat/openbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index 030f0977e23ba510512015e5025239b7ad6a6926..175425f948f7298c34eec524a4ad7fa603300bd4 100644 (file)
@@ -33,7 +33,7 @@ FUNCTION: int execve ( char* path, char** argv, char** envp ) ;
     [ first ] [ ] bi exec-with-path ;
 
 : exec-args-with-env  ( seq seq -- int )
-    >r [ first ] [ ] bi r> exec-with-env ;
+    [ [ first ] [ ] bi ] dip exec-with-env ;
 
 : with-fork ( child parent -- )
     [ [ fork-process dup zero? ] dip [ drop ] prepose ] dip
diff --git a/basis/unix/statfs/authors.txt b/basis/unix/statfs/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
index b6179a4ad717c92fb93126f24859011b011197e8..038178f6f8351f018017f4dc2db51a34874dffe1 100644 (file)
@@ -1,53 +1,34 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax kernel unix math accessors
-combinators system io.backend alien.c-types unix.statfs 
-io.files ;
+USING: alien.syntax ;
 IN: unix.statfs.freebsd
 
-: ST_RDONLY       1 ; inline
-: ST_NOSUID       2 ; inline
+: MFSNAMELEN      16            ; inline ! length of type name including null */
+: MNAMELEN        88            ; inline ! size of on/from name bufs
+: STATFS_VERSION  HEX: 20030518 ; inline ! current version number 
 
-C-STRUCT: statvfs               
-    { "fsblkcnt_t" "f_bavail" }
-    { "fsblkcnt_t" "f_bfree" }
-    { "fsblkcnt_t" "f_blocks" }
-    { "fsfilcnt_t" "f_favail" }
-    { "fsfilcnt_t" "f_ffree" }
-    { "fsfilcnt_t" "f_files" }
-    { "ulong" "f_bsize" }
-    { "ulong" "f_flag" }
-    { "ulong" "f_frsize" }
-    { "ulong" "f_fsid" }
-    { "ulong" "f_namemax" } ;
+C-STRUCT: statfs
+    { "uint32_t" "f_version" }
+    { "uint32_t" "f_type" }
+    { "uint64_t" "f_flags" }
+    { "uint64_t" "f_bsize" }
+    { "uint64_t" "f_iosize" }
+    { "uint64_t" "f_blocks" }
+    { "uint64_t" "f_bfree" }
+    { "int64_t"  "f_bavail" }
+    { "uint64_t" "f_files" }
+    { "int64_t"  "f_ffree" }
+    { "uint64_t" "f_syncwrites" }
+    { "uint64_t" "f_asyncwrites" }
+    { "uint64_t" "f_syncreads" }
+    { "uint64_t" "f_asyncreads" }
+    { { "uint64_t" 10 } "f_spare" }
+    { "uint32_t" "f_namemax" }
+    { "uid_t"    "f_owner" }
+    { "fsid_t"   "f_fsid" }
+    { { "char" 80 } "f_charspare" }
+    { { "char" MFSNAMELEN } "f_fstypename" }
+    { { "char" MNAMELEN } "f_mntfromname" }
+    { { "char" MNAMELEN } "f_mntonname" } ;
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
-
-TUPLE: freebsd-file-system-info < file-system-info
-bavail bfree blocks favail ffree files
-bsize flag frsize fsid namemax ;
-
-M: freebsd >file-system-info ( struct -- statfs )
-    [ \ freebsd-file-system-info new ] dip
-    {
-        [
-            [ statvfs-f_bsize ]
-            [ statvfs-f_bavail ] bi * >>free-space
-        ]
-        [ statvfs-f_bavail >>bavail ]
-        [ statvfs-f_bfree >>bfree ]
-        [ statvfs-f_blocks >>blocks ]
-        [ statvfs-f_favail >>favail ]
-        [ statvfs-f_ffree >>ffree ]
-        [ statvfs-f_files >>files ]
-        [ statvfs-f_bsize >>bsize ]
-        [ statvfs-f_flag >>flag ]
-        [ statvfs-f_frsize >>frsize ]
-        [ statvfs-f_fsid >>fsid ]
-        [ statvfs-f_namemax >>namemax ]
-    } cleave ;
-
-M: freebsd file-system-info ( path -- byte-array )
-    normalize-path
-    "statvfs" <c-object> tuck statvfs io-error
-    >file-system-info ;
+FUNCTION: int statfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statfs/linux/32/32.factor b/basis/unix/statfs/linux/32/32.factor
deleted file mode 100644 (file)
index fb8c6b5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types combinators kernel unix.stat
-math accessors system unix io.backend layouts vocabs.loader
-alien.syntax unix.statfs io.files ;
-IN: unix.statfs.linux
-
-C-STRUCT: statfs
-    { "long"    "f_type" }
-    { "long"    "f_bsize" }
-    { "long"    "f_blocks" }
-    { "long"    "f_bfree" }
-    { "long"    "f_bavail" }
-    { "long"    "f_files" }
-    { "long"    "f_ffree" }
-    { "fsid_t"  "f_fsid" }
-    { "long"    "f_namelen" } ;
-
-FUNCTION: int statfs ( char* path, statfs* buf ) ;
-
-TUPLE: linux32-file-system-info < file-system-info
-bsize blocks bfree bavail files ffree fsid namelen
-frsize spare ;
-
-M: linux >file-system-info ( struct -- statfs )
-    [ \ linux32-file-system-info new ] dip
-    {
-        [
-            [ statfs-f_bsize ]
-            [ statfs-f_bavail ] bi * >>free-space
-        ]
-        [ statfs-f_type >>type ]
-        [ statfs-f_bsize >>bsize ]
-        [ statfs-f_blocks >>blocks ]
-        [ statfs-f_bfree >>bfree ]
-        [ statfs-f_bavail >>bavail ]
-        [ statfs-f_files >>files ]
-        [ statfs-f_ffree >>ffree ]
-        [ statfs-f_fsid >>fsid ]
-        [ statfs-f_namelen >>namelen ]
-    } cleave ;
-
-M: linux file-system-info ( path -- byte-array )
-    normalize-path
-    "statfs" <c-object> tuck statfs io-error
-    >file-system-info ;
diff --git a/basis/unix/statfs/linux/32/authors.txt b/basis/unix/statfs/linux/32/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/unix/statfs/linux/32/tags.txt b/basis/unix/statfs/linux/32/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/linux/64/64.factor b/basis/unix/statfs/linux/64/64.factor
deleted file mode 100644 (file)
index e9cd557..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types combinators kernel unix.stat
-math accessors system unix io.backend layouts vocabs.loader
-alien.syntax unix.statfs io.files ;
-IN: unix.statfs.linux
-
-C-STRUCT: statfs64
-    { "__SWORD_TYPE" "f_type" }
-    { "__SWORD_TYPE" "f_bsize" }
-    { "__fsblkcnt64_t" "f_blocks" }
-    { "__fsblkcnt64_t" "f_bfree" }
-    { "__fsblkcnt64_t" "f_bavail" }
-    { "__fsfilcnt64_t" "f_files" }
-    { "__fsfilcnt64_t" "f_ffree" }
-    { "__fsid_t" "f_fsid" }
-    { "__SWORD_TYPE" "f_namelen" }
-    { "__SWORD_TYPE" "f_frsize" }
-    { { "__SWORD_TYPE" 5 } "f_spare" } ;
-
-FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
-
-TUPLE: linux64-file-system-info < file-system-info
-bsize blocks bfree bavail files ffree fsid namelen
-frsize spare ;
-
-M: linux >file-system-info ( struct -- statfs )
-    [ \ linux64-file-system-info new ] dip
-    {
-        [
-            [ statfs64-f_bsize ]
-            [ statfs64-f_bavail ] bi * >>free-space
-        ]
-        [ statfs64-f_type >>type ]
-        [ statfs64-f_bsize >>bsize ]
-        [ statfs64-f_blocks >>blocks ]
-        [ statfs64-f_bfree >>bfree ]
-        [ statfs64-f_bavail >>bavail ]
-        [ statfs64-f_files >>files ]
-        [ statfs64-f_ffree >>ffree ]
-        [ statfs64-f_fsid >>fsid ]
-        [ statfs64-f_namelen >>namelen ]
-        [ statfs64-f_frsize >>frsize ]
-        [ statfs64-f_spare >>spare ]
-    } cleave ;
-
-M: linux file-system-info ( path -- byte-array )
-    normalize-path
-    "statfs64" <c-object> tuck statfs64 io-error
-    >file-system-info ;
diff --git a/basis/unix/statfs/linux/64/authors.txt b/basis/unix/statfs/linux/64/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/unix/statfs/linux/64/tags.txt b/basis/unix/statfs/linux/64/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
index 43d5a99cd157d6ff5bd3c4edc8f852b110860e95..6550ee572e023926968ec997fff99b28e434ec39 100644 (file)
@@ -1,43 +1,19 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types combinators kernel unix.stat
-math accessors system unix io.backend layouts vocabs.loader
-sequences csv io.streams.string io.encodings.utf8 namespaces
-unix.statfs io.files ;
+USING: alien.syntax ;
 IN: unix.statfs.linux
 
-cell-bits {
-    { 32 [ "unix.statfs.linux.32" require ] }
-    { 64 [ "unix.statfs.linux.64" require ] }
-} case
+C-STRUCT: statfs64
+    { "__SWORD_TYPE" "f_type" }
+    { "__SWORD_TYPE" "f_bsize" }
+    { "__fsblkcnt64_t" "f_blocks" }
+    { "__fsblkcnt64_t" "f_bfree" }
+    { "__fsblkcnt64_t" "f_bavail" }
+    { "__fsfilcnt64_t" "f_files" }
+    { "__fsfilcnt64_t" "f_ffree" }
+    { "__fsid_t" "f_fsid" }
+    { "__SWORD_TYPE" "f_namelen" }
+    { "__SWORD_TYPE" "f_frsize" }
+    { { "__SWORD_TYPE" 5 } "f_spare" } ;
 
-TUPLE: mtab-entry file-system-name mount-point type options
-frequency pass-number ;
-
-: mtab-csv>mtab-entry ( csv -- mtab-entry )
-    [ mtab-entry new ] dip
-    {
-        [ first >>file-system-name ]
-        [ second >>mount-point ]
-        [ third >>type ]
-        [ fourth <string-reader> csv first >>options ]
-        [ 4 swap nth >>frequency ]
-        [ 5 swap nth >>pass-number ]
-    } cleave ;
-
-: parse-mtab ( -- array )
-    [
-        "/etc/mtab" utf8 <file-reader>
-        CHAR: \s delimiter set csv
-    ] with-scope
-    [ mtab-csv>mtab-entry ] map ;
-
-M: linux file-systems
-    parse-mtab [
-        [ mount-point>> file-system-info ] keep
-        {
-            [ file-system-name>> >>device-name ]
-            [ mount-point>> >>mount-point ]
-            [ type>> >>type ]
-        } cleave
-    ] map ;
+FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
index 7c30c4b9d417994812a8741536dad4e9312bf80d..210e9fbe12ede628e582c7fb3265d5a4c805d705 100644 (file)
@@ -2,8 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types io.encodings.utf8 io.encodings.string
 kernel sequences unix.stat accessors unix combinators math
-grouping system unix.statfs io.files io.backend alien.strings
-math.bitwise alien.syntax ;
+grouping system alien.strings math.bitwise alien.syntax ;
 IN: unix.statfs.macosx
 
 : MNT_RDONLY  HEX: 00000001 ; inline
@@ -116,50 +115,3 @@ C-STRUCT: statfs64
 
 FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
 FUNCTION: int getmntinfo64 ( statfs64** mntbufp, int flags ) ;
-
-
-TUPLE: macosx-file-system-info < file-system-info
-block-size io-size blocks blocks-free blocks-available files
-files-free file-system-id owner type-id flags filesystem-subtype ;
-
-M: macosx file-systems ( -- array )
-    f <void*> dup 0 getmntinfo64 dup io-error
-    [ *void* ] dip
-    "statfs64" heap-size [ * memory>byte-array ] keep group
-    [ >file-system-info ] map ;
-
-M: macosx >file-system-info ( byte-array -- file-system-info )
-    [ \ macosx-file-system-info new ] dip
-    {
-        [
-            [ statfs64-f_bavail ] [ statfs64-f_bsize ] bi *
-            >>free-space
-        ]
-        [ statfs64-f_mntonname utf8 alien>string >>mount-point ]
-        [ statfs64-f_bsize >>block-size ]
-
-        [ statfs64-f_iosize >>io-size ]
-        [ statfs64-f_blocks >>blocks ]
-        [ statfs64-f_bfree >>blocks-free ]
-        [ statfs64-f_bavail >>blocks-available ]
-        [ statfs64-f_files >>files ]
-        [ statfs64-f_ffree >>files-free ]
-        [ statfs64-f_fsid >>file-system-id ]
-        [ statfs64-f_owner >>owner ]
-        [ statfs64-f_type >>type-id ]
-        [ statfs64-f_flags >>flags ]
-        [ statfs64-f_fssubtype >>filesystem-subtype ]
-        [
-            statfs64-f_fstypename utf8 alien>string
-            >>type
-        ]
-        [
-            statfs64-f_mntfromname
-            utf8 alien>string >>device-name
-        ]
-    } cleave ;
-
-M: macosx file-system-info ( path -- file-system-info )
-    normalize-path
-    "statfs64" <c-object> tuck statfs64 io-error
-    >file-system-info ;
diff --git a/basis/unix/statfs/netbsd/authors.txt b/basis/unix/statfs/netbsd/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/unix/statfs/netbsd/netbsd.factor b/basis/unix/statfs/netbsd/netbsd.factor
deleted file mode 100644 (file)
index 56c632e..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax kernel unix.stat math unix
-combinators system io.backend accessors alien.c-types
-io.encodings.utf8 alien.strings unix.types unix.statfs io.files ;
-IN: unix.statfs.netbsd
-
-: _VFS_NAMELEN    32   ; inline
-: _VFS_MNAMELEN   1024 ; inline
-
-C-STRUCT: statvfs
-    { "ulong"   "f_flag" }   
-    { "ulong"   "f_bsize" }
-    { "ulong"   "f_frsize" }  
-    { "ulong"   "f_iosize" }  
-    { "fsblkcnt_t" "f_blocks" }       
-    { "fsblkcnt_t" "f_bfree" } 
-    { "fsblkcnt_t" "f_bavail" }       
-    { "fsblkcnt_t" "f_bresvd" }       
-    { "fsfilcnt_t" "f_files" }
-    { "fsfilcnt_t" "f_ffree" }
-    { "fsfilcnt_t" "f_favail" }       
-    { "fsfilcnt_t" "f_fresvd" }       
-    { "uint64_t"   "f_syncreads" }    
-    { "uint64_t"   "f_syncwrites" }   
-    { "uint64_t"   "f_asyncreads" }   
-    { "uint64_t"   "f_asyncwrites" }  
-    { "fsid_t"    "f_fsidx" }
-    { "ulong"   "f_fsid" }
-    { "ulong"   "f_namemax" }      
-    { "uid_t"   "f_owner" }
-    { { "uint32_t" 4 } "f_spare" }     
-    { { "char" _VFS_NAMELEN } "f_fstypename" }
-    { { "char" _VFS_NAMELEN } "f_mntonname" }
-    { { "char" _VFS_NAMELEN } "f_mntfromname" } ;
-
-FUNCTION: int statvfs ( char* path, statvfs *buf ) ;
-
-TUPLE: netbsd-file-system-info < file-system-info
-flag bsize frsize io-size
-blocks blocks-free blocks-available blocks-reserved
-files ffree sync-reads sync-writes async-reads async-writes
-fsidx fsid namemax owner spare fstype mnotonname mntfromname
-file-system-type-name mount-from ;
-
-M: netbsd >file-system-info ( byte-array -- netbsd-file-system-info )
-    [ \ netbsd-file-system-info new ] dip
-    {
-        [
-            [ statvfs-f_bsize ]
-            [ statvfs-f_bavail ] bi * >>free-space
-        ]
-        [ statvfs-f_flag >>flag ]
-        [ statvfs-f_bsize >>bsize ]
-        [ statvfs-f_frsize >>frsize ]
-        [ statvfs-f_iosize >>io-size ]
-        [ statvfs-f_blocks >>blocks ]
-        [ statvfs-f_bfree >>blocks-free ]
-        [ statvfs-f_favail >>blocks-available ]
-        [ statvfs-f_fresvd >>blocks-reserved ]
-        [ statvfs-f_files >>files ]
-        [ statvfs-f_ffree >>ffree ]
-        [ statvfs-f_syncreads >>sync-reads ]
-        [ statvfs-f_syncwrites >>sync-writes ]
-        [ statvfs-f_asyncreads >>async-reads ]
-        [ statvfs-f_asyncwrites >>async-writes ]
-        [ statvfs-f_fsidx >>fsidx ]
-        [ statvfs-f_namemax >>namemax ]
-        [ statvfs-f_owner >>owner ]
-        [ statvfs-f_spare >>spare ]
-        [ statvfs-f_fstypename utf8 alien>string >>file-system-type-name ]
-        [ statvfs-f_mntonname utf8 alien>string >>mount-point ]
-        [ statvfs-f_mntfromname utf8 alien>string >>mount-from ]
-    } cleave ;
-
-M: netbsd file-system-info
-    normalize-path "statvfs" <c-object> tuck statvfs io-error 
-    >file-system-info ;
diff --git a/basis/unix/statfs/netbsd/tags.txt b/basis/unix/statfs/netbsd/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/openbsd/32/32.factor b/basis/unix/statfs/openbsd/32/32.factor
deleted file mode 100644 (file)
index aa1e842..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax kernel unix ; 
-IN: unix.statfs.openbsd.32
-
-: MFSNAMELEN 16 ; inline
-: MNAMELEN 90 ; inline
-
-C-STRUCT: statfs
-    { "u_int32_t"  "f_flags" }
-    { "int32_t"    "f_bsize" }
-    { "u_int32_t"  "f_iosize" }
-    { "u_int32_t"  "f_blocks" }
-    { "u_int32_t"  "f_bfree" }
-    { "int32_t"    "f_bavail" }
-    { "u_int32_t"  "f_files" }
-    { "u_int32_t"  "f_ffree" }
-    { "fsid_t"     "f_fsid" }
-    { "uid_t"      "f_owner" }
-    { "u_int32_t"  "f_syncwrites" }
-    { "u_int32_t"  "f_asyncwrites" }
-    { "u_int32_t"  "f_ctime" }
-    { { "u_int32_t" 3 }  "f_spare" }
-    { { "char" MFSNAMELEN } "f_fstypename" }
-    { { "char" MNAMELEN }   "f_mntonname" }  
-    { { "char" MNAMELEN }   "f_mntfromname" } ;
diff --git a/basis/unix/statfs/openbsd/32/authors.txt b/basis/unix/statfs/openbsd/32/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/unix/statfs/openbsd/32/tags.txt b/basis/unix/statfs/openbsd/32/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/openbsd/64/64.factor b/basis/unix/statfs/openbsd/64/64.factor
deleted file mode 100644 (file)
index fd40fba..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax unix ;
-IN: unix.statfs.openbsd.64
-
-: MFSNAMELEN 16 ; inline
-: MNAMELEN 90 ; inline
-
-C-STRUCT: statfss
-    { "u_int32_t"      "f_flags" }
-    { "u_int32_t"      "f_bsize" }
-    { "u_int32_t"      "f_iosize" }
-    { "u_int64_t"      "f_blocks" }
-    { "u_int64_t"      "f_bfree" }
-    { "int64_t"        "f_bavail" }
-    { "u_int64_t"      "f_files" }
-    { "u_int64_t"      "f_ffree" }
-    { "int64_t"        "f_favail" }
-    { "u_int64_t"      "f_syncwrites" }
-    { "u_int64_t"      "f_syncreads" }
-    { "u_int64_t"      "f_asyncwrites" }
-    { "u_int64_t"      "f_asyncreads" }
-    { "fsid_t"         "f_fsid" }
-    { "u_int32_t"      "f_namemax" }
-    { "uid_t"          "f_owner" }
-    { "u_int32_t"      "f_ctime" }
-    { { "u_int32_t" 3 } " f_spare" }
-    { { "char" MFSNAMELEN } "f_fstypename" }
-    { { "char" MNAMELEN } "f_mntonname" }
-    { { "char" MNAMELEN } "f_mntfromname" }
-    { { "char" 512 } "mount_info" } ;
-    ! { "mount_info" "mount_info" } ;                                        
diff --git a/basis/unix/statfs/openbsd/64/authors.txt b/basis/unix/statfs/openbsd/64/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/unix/statfs/openbsd/64/tags.txt b/basis/unix/statfs/openbsd/64/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/openbsd/authors.txt b/basis/unix/statfs/openbsd/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
index fa86ef2bc25fa7176eda20c17688e5c294c749d0..378e335c115e265760775a941cc740ce676de4bc 100644 (file)
@@ -1,53 +1,33 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax accessors combinators kernel
-unix.types math system io.backend alien.c-types unix
-unix.statfs io.files ;
+USING: alien.syntax ;
 IN: unix.statfs.openbsd
 
-C-STRUCT: statvfs
-    { "ulong" "f_bsize" }
-    { "ulong" "f_frsize" }
-    { "fsblkcnt_t" "f_blocks" }
-    { "fsblkcnt_t" "f_bfree" }
-    { "fsblkcnt_t" "f_bavail" }
-    { "fsfilcnt_t" "f_files" }
-    { "fsfilcnt_t" "f_ffree" }
-    { "fsfilcnt_t" "f_favail" }
-    { "ulong" "f_fsid" }
-    { "ulong" "f_flag" }
-    { "ulong" "f_namemax" } ;
+: MFSNAMELEN 16 ; inline
+: MNAMELEN 90 ; inline
 
-: ST_RDONLY       1 ; inline
-: ST_NOSUID       2 ; inline
+C-STRUCT: statfs
+    { "u_int32_t"       "f_flags" }
+    { "u_int32_t"       "f_bsize" }
+    { "u_int32_t"       "f_iosize" }
+    { "u_int64_t"       "f_blocks" }
+    { "u_int64_t"       "f_bfree" }
+    { "int64_t"         "f_bavail" }
+    { "u_int64_t"       "f_files" }
+    { "u_int64_t"       "f_ffree" }
+    { "int64_t"         "f_favail" }
+    { "u_int64_t"       "f_syncwrites" }
+    { "u_int64_t"       "f_syncreads" }
+    { "u_int64_t"       "f_asyncwrites" }
+    { "u_int64_t"       "f_asyncreads" }
+    { "fsid_t"          "f_fsid" }
+    { "u_int32_t"       "f_namemax" }
+    { "uid_t"           "f_owner" }
+    { "u_int32_t"       "f_ctime" }
+    { { "u_int32_t" 3 } "f_spare" }
+    { { "char" MFSNAMELEN } "f_fstypename" }
+    { { "char" MNAMELEN } "f_mntonname" }
+    { { "char" MNAMELEN } "f_mntfromname" }
+    { { "char" 160 } "mount_info" } ;
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
-
-TUPLE: openbsd-file-system-info < file-system-info
-bsize frsize blocks bfree bavail files ffree favail
-fsid flag namemax ;
-
-M: openbsd >file-system-info ( struct -- statfs )
-    [ \ openbsd-file-system-info new ] dip
-    {
-        [
-            [ statvfs-f_bsize ]
-            [ statvfs-f_bavail ] bi * >>free-space
-        ]
-        [ statvfs-f_bsize >>bsize ]
-        [ statvfs-f_frsize >>frsize ]
-        [ statvfs-f_blocks >>blocks ]
-        [ statvfs-f_bfree >>bfree ]
-        [ statvfs-f_bavail >>bavail ]
-        [ statvfs-f_files >>files ]
-        [ statvfs-f_ffree >>ffree ]
-        [ statvfs-f_favail >>favail ]
-        [ statvfs-f_fsid >>fsid ]
-        [ statvfs-f_flag >>flag ]
-        [ statvfs-f_namemax >>namemax ]
-    } cleave ;
-
-M: openbsd file-system-info ( path -- byte-array )
-    normalize-path
-    "statvfs" <c-object> tuck statvfs io-error
-    >file-system-info ;
+FUNCTION: int statfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statfs/statfs-tests.factor b/basis/unix/statfs/statfs-tests.factor
deleted file mode 100644 (file)
index 39bc77f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test unix.statfs ;
-IN: unix.statfs.tests
diff --git a/basis/unix/statfs/statfs.factor b/basis/unix/statfs/statfs.factor
deleted file mode 100644 (file)
index 0397507..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: sequences system vocabs.loader combinators accessors
-kernel math.order sorting ;
-IN: unix.statfs
-
-HOOK: >file-system-info os ( struct -- statfs )
-
-os {
-    { linux   [ "unix.statfs.linux"   require ] }
-    { macosx  [ "unix.statfs.macosx"  require ] }
-    { freebsd [ "unix.statfs.freebsd" require ] }
-    { netbsd  [ "unix.statfs.netbsd"  require ] }
-    { openbsd [ "unix.statfs.openbsd" require ] }
-} case
diff --git a/basis/unix/statfs/tags.txt b/basis/unix/statfs/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/authors.txt b/basis/unix/statvfs/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/freebsd/authors.txt b/basis/unix/statvfs/freebsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/freebsd/freebsd.factor b/basis/unix/statvfs/freebsd/freebsd.factor
new file mode 100644 (file)
index 0000000..7d1a6af
--- /dev/null
@@ -0,0 +1,23 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.statvfs.freebsd
+
+C-STRUCT: statvfs
+    { "fsblkcnt_t"  "f_bavail" }
+    { "fsblkcnt_t"  "f_bfree" }
+    { "fsblkcnt_t"  "f_blocks" }
+    { "fsfilcnt_t"  "f_favail" }
+    { "fsfilcnt_t"  "f_ffree" }
+    { "fsfilcnt_t"  "f_files" }
+    { "ulong"   "f_bsize" }
+    { "ulong"   "f_flag" }
+    { "ulong"   "f_frsize" }
+    { "ulong"   "f_fsid" }
+    { "ulong"   "f_namemax" } ;
+
+! Flags
+: ST_RDONLY   HEX: 1 ; inline ! Read-only file system
+: ST_NOSUID   HEX: 2 ; inline ! Does not honor setuid/setgid
+
+FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/freebsd/tags.txt b/basis/unix/statvfs/freebsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/statvfs/linux/authors.txt b/basis/unix/statvfs/linux/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/linux/linux.factor b/basis/unix/statvfs/linux/linux.factor
new file mode 100644 (file)
index 0000000..3bfbffa
--- /dev/null
@@ -0,0 +1,31 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.statvfs.linux
+
+C-STRUCT: statvfs64
+    { "ulong" "f_bsize" }
+    { "ulong" "f_frsize" }
+    { "__fsblkcnt64_t" "f_blocks" }
+    { "__fsblkcnt64_t" "f_bfree" }
+    { "__fsblkcnt64_t" "f_bavail" }
+    { "__fsfilcnt64_t" "f_files" }
+    { "__fsfilcnt64_t" "f_ffree" }
+    { "__fsfilcnt64_t" "f_favail" }
+    { "ulong" "f_fsid" }
+    { "ulong" "f_flag" }
+    { "ulong" "f_namemax" }
+    { { "int" 6 } "__f_spare" } ;
+
+FUNCTION: int statvfs64 ( char* path, statvfs64* buf ) ;
+
+: ST_RDONLY 1 ; inline        ! Mount read-only.
+: ST_NOSUID 2 ; inline        ! Ignore suid and sgid bits.
+: ST_NODEV 4 ; inline         ! Disallow access to device special files.
+: ST_NOEXEC 8 ; inline        ! Disallow program execution.
+: ST_SYNCHRONOUS 16 ; inline  ! Writes are synced at once.
+: ST_MANDLOCK 64 ; inline     ! Allow mandatory locks on an FS.
+: ST_WRITE 128 ; inline       ! Write on file/directory/symlink.
+: ST_APPEND 256 ; inline      ! Append-only file.
+: ST_IMMUTABLE 512 ; inline   ! Immutable file.
+: ST_NOATIME 1024 ; inline    ! Do not update access times.
diff --git a/basis/unix/statvfs/linux/tags.txt b/basis/unix/statvfs/linux/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/statvfs/macosx/authors.txt b/basis/unix/statvfs/macosx/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/macosx/macosx.factor b/basis/unix/statvfs/macosx/macosx.factor
new file mode 100644 (file)
index 0000000..7078ff9
--- /dev/null
@@ -0,0 +1,23 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.statvfs.macosx
+
+C-STRUCT: statvfs
+    { "ulong"   "f_bsize" }
+    { "ulong"   "f_frsize" }
+    { "fsblkcnt_t"  "f_blocks" }
+    { "fsblkcnt_t"  "f_bfree" }
+    { "fsblkcnt_t"  "f_bavail" }
+    { "fsfilcnt_t"  "f_files" }
+    { "fsfilcnt_t"  "f_ffree" }
+    { "fsfilcnt_t"  "f_favail" }
+    { "ulong"   "f_fsid" }
+    { "ulong"   "f_flag" }
+    { "ulong"   "f_namemax" } ;
+
+! Flags
+: ST_RDONLY   HEX: 1 ; inline ! Read-only file system
+: ST_NOSUID   HEX: 2 ; inline ! Does not honor setuid/setgid
+
+FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/macosx/tags.txt b/basis/unix/statvfs/macosx/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/statvfs/netbsd/authors.txt b/basis/unix/statvfs/netbsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/netbsd/netbsd.factor b/basis/unix/statvfs/netbsd/netbsd.factor
new file mode 100644 (file)
index 0000000..cf575c7
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.statvfs.netbsd
+
+: _VFS_NAMELEN    32   ; inline
+: _VFS_MNAMELEN   1024 ; inline
+
+C-STRUCT: statvfs
+    { "ulong"   "f_flag" }   
+    { "ulong"   "f_bsize" }
+    { "ulong"   "f_frsize" }  
+    { "ulong"   "f_iosize" }  
+    { "fsblkcnt_t" "f_blocks" }       
+    { "fsblkcnt_t" "f_bfree" } 
+    { "fsblkcnt_t" "f_bavail" }       
+    { "fsblkcnt_t" "f_bresvd" }       
+    { "fsfilcnt_t" "f_files" }
+    { "fsfilcnt_t" "f_ffree" }
+    { "fsfilcnt_t" "f_favail" }       
+    { "fsfilcnt_t" "f_fresvd" }       
+    { "uint64_t"   "f_syncreads" }    
+    { "uint64_t"   "f_syncwrites" }   
+    { "uint64_t"   "f_asyncreads" }   
+    { "uint64_t"   "f_asyncwrites" }  
+    { "fsid_t"    "f_fsidx" }
+    { "ulong"   "f_fsid" }
+    { "ulong"   "f_namemax" }      
+    { "uid_t"   "f_owner" }
+    { { "uint32_t" 4 } "f_spare" }     
+    { { "char" _VFS_NAMELEN } "f_fstypename" }
+    { { "char" _VFS_MNAMELEN } "f_mntonname" }
+    { { "char" _VFS_MNAMELEN } "f_mntfromname" } ;
+
+FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/netbsd/tags.txt b/basis/unix/statvfs/netbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/statvfs/openbsd/authors.txt b/basis/unix/statvfs/openbsd/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/unix/statvfs/openbsd/openbsd.factor b/basis/unix/statvfs/openbsd/openbsd.factor
new file mode 100644 (file)
index 0000000..3f9353f
--- /dev/null
@@ -0,0 +1,22 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax ;
+IN: unix.statvfs.openbsd
+
+C-STRUCT: statvfs
+    { "ulong" "f_bsize" }
+    { "ulong" "f_frsize" }
+    { "fsblkcnt_t" "f_blocks" }
+    { "fsblkcnt_t" "f_bfree" }
+    { "fsblkcnt_t" "f_bavail" }
+    { "fsfilcnt_t" "f_files" }
+    { "fsfilcnt_t" "f_ffree" }
+    { "fsfilcnt_t" "f_favail" }
+    { "ulong" "f_fsid" }
+    { "ulong" "f_flag" }
+    { "ulong" "f_namemax" } ;
+
+: ST_RDONLY       1 ; inline
+: ST_NOSUID       2 ; inline
+
+FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/openbsd/tags.txt b/basis/unix/statvfs/openbsd/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/unix/statvfs/statvfs.factor b/basis/unix/statvfs/statvfs.factor
new file mode 100644 (file)
index 0000000..e610140
--- /dev/null
@@ -0,0 +1,12 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators system vocabs.loader ;
+IN: unix.statvfs
+
+os {
+    { linux   [ "unix.statvfs.linux"   require ] }
+    { macosx  [ "unix.statvfs.macosx"  require ] }
+    { freebsd [ "unix.statvfs.freebsd" require ] }
+    { netbsd  [ "unix.statvfs.netbsd"  require ] }
+    { openbsd [ "unix.statvfs.openbsd" require ] }
+} case
diff --git a/basis/unix/statvfs/tags.txt b/basis/unix/statvfs/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index ca8a7a2e60fb9a7a125e7d8035c6e2db8c5f6106..d917425bf9cebb415042811d3e9fcc7d000e5a2b 100644 (file)
@@ -198,10 +198,10 @@ FUNCTION: ssize_t readlink ( char* path, char* buf, size_t bufsize ) ;
 : PATH_MAX 1024 ; inline
 
 : read-symbolic-link ( path -- path )
-    PATH_MAX <byte-array> dup >r
-    PATH_MAX
-    [ readlink ] unix-system-call
-    r> swap head-slice >string ;
+    PATH_MAX <byte-array> dup [
+        PATH_MAX
+        [ readlink ] unix-system-call
+    ] dip swap head-slice >string ;
 
 FUNCTION: ssize_t recv ( int s, void* buf, size_t nbytes, int flags ) ;
 FUNCTION: ssize_t recvfrom ( int s, void* buf, size_t nbytes, int flags, sockaddr-in* from, socklen_t* fromlen ) ;
index 1f3a6bf78a3d744cb6fa029f4014f8d1e1a7c874..e2f780cd1346cdd2c5ed4b10cc46b816103e4f01 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings
-combinators.short-circuit fry kernel layouts sequences ;
+combinators.short-circuit fry kernel layouts sequences
+specialized-arrays.alien accessors ;
 IN: unix.utilities
 
 : more? ( alien -- ? )
@@ -16,4 +17,4 @@ IN: unix.utilities
     [ ] produce nip ;
 
 : strings>alien ( strings encoding -- alien )
-    '[ _ malloc-string ] map f suffix >c-void*-array ;
+    '[ _ malloc-string ] void*-array{ } map-as f suffix underlying>> ;
index fa882609a5c103724b07b8b7ef4dda84ff96fb31..f621384ede3d77c4a9349bd559ae120f1128db44 100644 (file)
@@ -91,6 +91,6 @@ PRIVATE>
     [
         [
             [ url-encode ] dip
-            [ url-encode "=" swap 3append , ] with each
+            [ url-encode "=" glue , ] with each
         ] assoc-each
     ] { } make "&" join ;
index 9649de6402f214a1c2572430152bd0165a9852e8..0e1a907ca76d0da1038738f74435ddbef1f57f37 100644 (file)
@@ -28,9 +28,10 @@ COM-INTERFACE: IDropTarget IUnknown {00000122-0000-0000-C000-000000000046}
     HRESULT Drop ( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) ;\r
 \r
 : com-query-interface ( interface iid -- interface' )\r
-    "void*" heap-size [\r
+    [\r
+        "void*" malloc-object &free\r
         [ IUnknown::QueryInterface ole32-error ] keep *void*\r
-    ] with-malloc ;\r
+    ] with-destructors ;\r
 \r
 : com-add-ref ( interface -- interface )\r
      [ IUnknown::AddRef drop ] keep ; inline\r
old mode 100644 (file)
new mode 100755 (executable)
index c56293b..620b608
@@ -1,7 +1,7 @@
-USING: alien alien.c-types effects kernel windows.ole32
-parser lexer splitting grouping sequences namespaces
-assocs quotations generalizations accessors words macros alien.syntax
-fry arrays ;
+USING: alien alien.c-types alien.accessors effects kernel
+windows.ole32 parser lexer splitting grouping sequences
+namespaces assocs quotations generalizations accessors words
+macros alien.syntax fry arrays layouts math ;
 IN: windows.com.syntax
 
 <PRIVATE
@@ -10,9 +10,9 @@ C-STRUCT: com-interface
     { "void*" "vtbl" } ;
 
 MACRO: com-invoke ( n return parameters -- )
-    dup length -roll
+    [ 2nip length ] 3keep
     '[
-        _ npick com-interface-vtbl _ swap void*-nth _ _
+        _ npick com-interface-vtbl _ cell * alien-cell _ _
         "stdcall" alien-indirect
     ] ;
 
old mode 100644 (file)
new mode 100755 (executable)
index d376ccc..710feee
@@ -1,8 +1,9 @@
-USING: alien alien.c-types windows.com.syntax init
-windows.com.syntax.private windows.com continuations kernel
+USING: alien alien.c-types alien.accessors windows.com.syntax
+init windows.com.syntax.private windows.com continuations kernel
 namespaces windows.ole32 libc vocabs assocs accessors arrays
 sequences quotations combinators math words compiler.units
-destructors fry math.parser generalizations sets ;
+destructors fry math.parser generalizations sets
+specialized-arrays.alien specialized-arrays.direct.alien ;
 IN: windows.com.wrapper
 
 TUPLE: com-wrapper callbacks vtbls disposed ;
@@ -51,23 +52,26 @@ unless
         _ case
         [
             "void*" heap-size * rot <displaced-alien> com-add-ref
-            0 rot set-void*-nth S_OK
-        ] [ nip f 0 rot set-void*-nth E_NOINTERFACE ] if*
+            swap 0 set-alien-cell S_OK
+        ] [ nip f swap 0 set-alien-cell E_NOINTERFACE ] if*
     ] ;
 
 : (make-add-ref) ( interfaces -- quot )
     length "void*" heap-size * '[
-        _ swap <displaced-alien>
-        0 over ulong-nth
-        1+ [ 0 rot set-ulong-nth ] keep
+        _
+        [ alien-unsigned-4 1+ dup ]
+        [ set-alien-unsigned-4 ]
+        2bi
     ] ;
 
 : (make-release) ( interfaces -- quot )
     length "void*" heap-size * '[
-        _ over <displaced-alien>
-        0 over ulong-nth
-        1- [ 0 rot set-ulong-nth ] keep
-        dup zero? [ swap (free-wrapped-object) ] [ nip ] if
+        _
+        [ drop ]
+        [ alien-unsigned-4 1- dup ]
+        [ set-alien-unsigned-4 ]
+        2tri
+        dup 0 = [ swap (free-wrapped-object) ] [ nip ] if
     ] ;
 
 : (make-iunknown-methods) ( interfaces -- quots )
@@ -92,9 +96,6 @@ unless
     [ [ (( -- alien )) define-declared ] pick slip ]
     with-compilation-unit ;
 
-: byte-array>malloc ( byte-array -- alien )
-    [ byte-length malloc ] [ over byte-array>memory ] bi ;
-
 : (callback-word) ( function-name interface-name counter -- word )
     [ "::" rot 3append "-callback-" ] dip number>string 3append
     "windows.com.wrapper.callbacks" create ;
@@ -128,11 +129,10 @@ unless
 : (malloc-wrapped-object) ( wrapper -- wrapped-object )
     vtbls>> length "void*" heap-size *
     [ "ulong" heap-size + malloc ] keep
-    over <displaced-alien>
-    1 0 rot set-ulong-nth ;
+    [ [ 1 ] 2dip set-alien-unsigned-4 ] [ drop ] 2bi ;
 
 : (callbacks>vtbl) ( callbacks -- vtbl )
-    [ execute ] map >c-void*-array byte-array>malloc ;
+    [ execute ] void*-array{ } map-as underlying>> malloc-byte-array ;
 : (callbacks>vtbls) ( callbacks -- vtbls )
     [ (callbacks>vtbl) ] map ;
 
@@ -162,5 +162,5 @@ M: com-wrapper dispose*
 
 : com-wrap ( object wrapper -- wrapped-object )
     [ vtbls>> ] [ (malloc-wrapped-object) ] bi
-    [ [ set-void*-nth ] curry each-index ] keep
+    [ over length <direct-void*-array> 0 swap copy ] keep
     [ +wrapped-objects+ get-global set-at ] keep ;
old mode 100644 (file)
new mode 100755 (executable)
index 182c174..e3bec6d
@@ -1,7 +1,8 @@
 USING: windows.dinput windows.kernel32 windows.ole32 windows.com
 windows.com.syntax alien alien.c-types alien.syntax kernel system namespaces
 combinators sequences symbols fry math accessors macros words quotations
-libc continuations generalizations splitting locals assocs init ;
+libc continuations generalizations splitting locals assocs init
+struct-arrays ;
 IN: windows.dinput.constants
 
 ! Some global variables aren't provided by the DirectInput DLL (they're in the
@@ -52,14 +53,14 @@ SYMBOLS:
     } cleave
     "DIOBJECTDATAFORMAT" <c-object> (DIOBJECTDATAFORMAT) ;
 
-: malloc-DIOBJECTDATAFORMAT-array ( struct array -- alien )
-    [ nip length "DIOBJECTDATAFORMAT" malloc-array dup ]
-    [
-        -rot [| args i alien struct |
+:: malloc-DIOBJECTDATAFORMAT-array ( struct array -- alien )
+    [let | alien [ array length "DIOBJECTDATAFORMAT" malloc-struct-array ] |
+        array [| args i |
             struct args <DIOBJECTDATAFORMAT>
-            i alien set-DIOBJECTDATAFORMAT-nth
-        ] 2curry each-index
-    ] 2bi ;
+            i alien set-nth
+        ] each-index
+        alien underlying>>
+    ] ;
 
 : (DIDATAFORMAT) ( dwSize dwObjSize dwFlags dwDataSize dwNumObjs rgodf alien -- alien )
     [ {
index 96301dbbe4b96c88dbec2e6680491dcb44853fbe..7d6f0ab5f2673b5fa5b5d4a54ccd96f18f524128 100644 (file)
@@ -315,10 +315,10 @@ C-STRUCT: MEMORY_BASIC_INFORMATION
   { "DWORD" "type" } ;
 
 C-STRUCT: GUID
-    { "ulong" "Data1" }
-    { "ushort" "Data2" }
-    { "ushort" "Data3" }
-    { { "uchar" 8 } "Data4" } ;
+    { "ULONG" "Data1" }
+    { "WORD"  "Data2" }
+    { "WORD"  "Data3" }
+    { { "UCHAR" 8 } "Data4" } ;
 
 
 : SE_CREATE_TOKEN_NAME "SeCreateTokenPrivilege" ;
old mode 100644 (file)
new mode 100755 (executable)
index 6256211..6d4e60a
@@ -1,7 +1,7 @@
 USING: alien alien.syntax alien.c-types alien.strings math
 kernel sequences windows windows.types debugger io accessors
 math.order namespaces make math.parser windows.kernel32
-combinators ;
+combinators locals specialized-arrays.direct.uchar ;
 IN: windows.ole32
 
 LIBRARY: ole32
@@ -134,49 +134,57 @@ M: ole32-error error.
 : GUID-STRING-LENGTH
     "{01234567-89ab-cdef-0123-456789abcdef}" length ; inline
 
-: (guid-section>guid) ( guid string start end quot -- )
-    [ roll subseq hex> swap ] dip call ; inline
-: (guid-byte>guid) ( guid string start end byte -- )
-    [ roll subseq hex> ] dip
-    rot GUID-Data4 set-uchar-nth ; inline
+:: (guid-section>guid) ( string guid start end quot -- )
+    start end string subseq hex> guid quot call ; inline
 
-: string>guid ( string -- guid )
-    "GUID" <c-object> [ {
-        [  1  9 [ set-GUID-Data1 ] (guid-section>guid) ]
-
-        [ 10 14 [ set-GUID-Data2 ] (guid-section>guid) ]
-
-        [ 15 19 [ set-GUID-Data3 ] (guid-section>guid) ]
+:: (guid-byte>guid) ( string guid start end byte -- )
+    start end string subseq hex> byte guid set-nth ; inline
 
-        [ 20 22 0 (guid-byte>guid) ]
-        [ 22 24 1 (guid-byte>guid) ]
-
-        [ 25 27 2 (guid-byte>guid) ]
-        [ 27 29 3 (guid-byte>guid) ]
-        [ 29 31 4 (guid-byte>guid) ]
-        [ 31 33 5 (guid-byte>guid) ]
-        [ 33 35 6 (guid-byte>guid) ]
-        [ 35 37 7 (guid-byte>guid) ]
-    } 2cleave ] keep ;
+: string>guid ( string -- guid )
+    "GUID" <c-object> [
+        {
+            [  1  9 [ set-GUID-Data1 ] (guid-section>guid) ]
+            [ 10 14 [ set-GUID-Data2 ] (guid-section>guid) ]
+            [ 15 19 [ set-GUID-Data3 ] (guid-section>guid) ]
+            [ ]
+        } 2cleave
+
+        GUID-Data4 8 <direct-uchar-array> {
+            [ 20 22 0 (guid-byte>guid) ]
+            [ 22 24 1 (guid-byte>guid) ]
+
+            [ 25 27 2 (guid-byte>guid) ]
+            [ 27 29 3 (guid-byte>guid) ]
+            [ 29 31 4 (guid-byte>guid) ]
+            [ 31 33 5 (guid-byte>guid) ]
+            [ 33 35 6 (guid-byte>guid) ]
+            [ 35 37 7 (guid-byte>guid) ]
+        } 2cleave
+    ] keep ;
 
 : (guid-section%) ( guid quot len -- )
     [ call >hex ] dip CHAR: 0 pad-left % ; inline
+
 : (guid-byte%) ( guid byte -- )
-    swap GUID-Data4 uchar-nth >hex 2
-    CHAR: 0 pad-left % ; inline
+    swap nth >hex 2 CHAR: 0 pad-left % ; inline
 
 : guid>string ( guid -- string )
-    [ "{" % {
-        [ [ GUID-Data1 ] 8 (guid-section%) "-" % ]
-        [ [ GUID-Data2 ] 4 (guid-section%) "-" % ]
-        [ [ GUID-Data3 ] 4 (guid-section%) "-" % ]
-        [ 0 (guid-byte%) ]
-        [ 1 (guid-byte%) "-" % ]
-        [ 2 (guid-byte%) ]
-        [ 3 (guid-byte%) ]
-        [ 4 (guid-byte%) ]
-        [ 5 (guid-byte%) ]
-        [ 6 (guid-byte%) ]
-        [ 7 (guid-byte%) "}" % ]
-    } cleave ] "" make ;
+    [
+        "{" % {
+            [ [ GUID-Data1 ] 8 (guid-section%) "-" % ]
+            [ [ GUID-Data2 ] 4 (guid-section%) "-" % ]
+            [ [ GUID-Data3 ] 4 (guid-section%) "-" % ]
+            [ ]
+        } cleave
+        GUID-Data4 8 <direct-uchar-array> {
+            [ 0 (guid-byte%) ]
+            [ 1 (guid-byte%) "-" % ]
+            [ 2 (guid-byte%) ]
+            [ 3 (guid-byte%) ]
+            [ 4 (guid-byte%) ]
+            [ 5 (guid-byte%) ]
+            [ 6 (guid-byte%) ]
+            [ 7 (guid-byte%) "}" % ]
+        } cleave
+    ] "" make ;
 
index 6b1a57a098af32a6fcb79071d4cb73831c5e3213..63ee6627c400237b3cf204f1745445e74883f0ad 100644 (file)
@@ -30,7 +30,7 @@ TYPEDEF: long*               LPLONG
 TYPEDEF: long                LONG_PTR
 TYPEDEF: long*               PLONG_PTR
 
-TYPEDEF: int                 ULONG
+TYPEDEF: uint                ULONG
 TYPEDEF: void*               ULONG_PTR
 TYPEDEF: void*               PULONG_PTR
 
index 1007b47a5b54491d5275ecba4a062b79b8ef146f..1612b7ec11da72a8bd3629b3f294efec77328100 100644 (file)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings alien.syntax arrays
 kernel math namespaces sequences io.encodings.string
-io.encodings.utf8 io.encodings.ascii x11.xlib x11.constants ;
+io.encodings.utf8 io.encodings.ascii x11.xlib x11.constants
+specialized-arrays.int accessors ;
 IN: x11.clipboard
 
 ! This code was based on by McCLIM's Backends/CLX/port.lisp
@@ -50,7 +51,7 @@ TUPLE: x-clipboard atom contents ;
     "TARGETS" x-atom 32 PropModeReplace
     {
         "UTF8_STRING" "STRING" "TARGETS" "TIMESTAMP"
-    } [ x-atom ] map >c-int-array
+    } [ x-atom ] int-array{ } map-as underlying>>
     4 XChangeProperty drop ;
 
 : set-timestamp-prop ( evt -- )
@@ -58,7 +59,7 @@ TUPLE: x-clipboard atom contents ;
     [ XSelectionRequestEvent-requestor ] keep
     [ XSelectionRequestEvent-property ] keep
     >r "TIMESTAMP" x-atom 32 PropModeReplace r>
-    XSelectionRequestEvent-time 1array >c-int-array
+    XSelectionRequestEvent-time <int>
     1 XChangeProperty drop ;
 
 : send-notify ( evt prop -- )
index eefb93772a07235776a7e521bfdf44418768738d..1fab2832421094dc6f0951eb13be9f12aa1a567b 100644 (file)
@@ -2,8 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! based on glx.h from xfree86, and some of glxtokens.h
-USING: alien alien.c-types alien.syntax alien.syntax.private x11.xlib
-namespaces make kernel sequences parser words ;
+USING: alien alien.c-types alien.syntax x11.xlib namespaces make
+kernel sequences parser words specialized-arrays.int accessors ;
 IN: x11.glx
 
 LIBRARY: glx
@@ -93,7 +93,7 @@ FUNCTION: void* glXGetProcAddressARB ( char* procname ) ;
         GLX_DOUBLEBUFFER ,
         GLX_DEPTH_SIZE , 16 ,
         0 ,
-    ] { } make >c-int-array
+    ] int-array{ } make underlying>>
     glXChooseVisual
     [ "Could not get a double-buffered GLX RGBA visual" throw ] unless* ;
 
index 35e1906b2b786069a0a7e04904bcd17cc563ada1..71b0b5f13378a90ea8c55741ed954b598e2aba99 100644 (file)
@@ -1,15 +1,16 @@
-! Copyright (C) 2007 Slava Pestov
+! Copyright (C) 2007, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types arrays byte-arrays hashtables
-io kernel math namespaces sequences strings
-continuations x11.xlib ;
+USING: alien alien.c-types alien.strings arrays byte-arrays
+hashtables io io.encodings.string kernel math namespaces
+sequences strings continuations x11.xlib specialized-arrays.uint
+accessors ;
 IN: x11.xim
 
 SYMBOL: xim
 
 : (init-xim) ( classname medifier -- im )
    XSetLocaleModifiers [ "XSetLocaleModifiers() failed" throw ] unless
-   dpy get f rot dup XOpenIM ;
+   [ dpy get f ] dip dup XOpenIM ;
 
 : init-xim ( classname -- )
    dup "" (init-xim)
@@ -21,14 +22,15 @@ SYMBOL: xim
     xim get-global XCloseIM drop f xim set-global ;
 
 : with-xim ( quot -- )
-    >r "Factor" init-xim r> [ close-xim ] [ ] cleanup ;
+    [ "Factor" init-xim ] dip [ close-xim ] [ ] cleanup ;
 
 : create-xic ( window classname -- xic )
-    >r >r xim get-global
-    XNClientWindow r>
-    XNFocusWindow over
-    XNInputStyle XIMPreeditNothing XIMStatusNothing bitor
-    XNResourceName r>
+    [
+        [ xim get-global XNClientWindow ] dip
+        XNFocusWindow over
+        XNInputStyle XIMPreeditNothing XIMStatusNothing bitor
+        XNResourceName
+    ] dip
     XNResourceClass over 0 XCreateIC
     [ "XCreateIC() failed" throw ] unless* ;
 
@@ -38,17 +40,17 @@ SYMBOL: keybuf
 SYMBOL: keysym
 
 : prepare-lookup ( -- )
-    buf-size "uint" <c-array> keybuf set
+    buf-size <uint-array> keybuf set
     0 <KeySym> keysym set ;
 
 : finish-lookup ( len -- string keysym )
-    keybuf get swap c-uint-array> >string
+    keybuf get swap 2 * head utf16n decode
     keysym get *KeySym ;
 
 : lookup-string ( event xic -- string keysym )
     [
         prepare-lookup
-        swap keybuf get buf-size keysym get 0 <int>
+        swap keybuf get underlying>> buf-size keysym get 0 <int>
         XwcLookupString
         finish-lookup
     ] with-scope ;
index eecf427c9ef6f6bc15ca20843501dd0acea20aae..555eb573fc73c40b8b593e602afff9e916068564 100644 (file)
@@ -13,7 +13,7 @@
 
 USING: kernel arrays alien alien.c-types alien.strings
 alien.syntax math math.bitwise words sequences namespaces
-continuations io.encodings.ascii ;
+continuations io io.encodings.ascii ;
 IN: x11.xlib
 
 LIBRARY: xlib
@@ -1359,8 +1359,8 @@ SYMBOL: scr
 SYMBOL: root
 
 : init-locale ( -- )
-   LC_ALL "" setlocale [ "setlocale() failed" throw ] unless
-   XSupportsLocale [ "XSupportsLocale() failed" throw ] unless ;
+   LC_ALL "" setlocale [ "setlocale() failed" print flush ] unless
+   XSupportsLocale [ "XSupportsLocale() failed" print flush ] unless ;
 
 : flush-dpy ( -- ) dpy get XFlush drop ;
 
@@ -1381,4 +1381,4 @@ SYMBOL: root
 : close-x ( -- ) dpy get XCloseDisplay drop ;
 
 : with-x ( display-string quot -- )
-    >r initialize-x r> [ close-x ] [ ] cleanup ;
+    [ initialize-x ] dip [ close-x ] [ ] cleanup ;
index 0af2ec4700935be8f461fd434da94b6099630db1..bf4e2047a7990df29e275f8082f8e60e405423d3 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences sequences.private assocs arrays
 delegate.protocols delegate vectors accessors multiline
-macros words quotations combinators slots ;
+macros words quotations combinators slots fry ;
 IN: xml.data
 
 TUPLE: name space main url ;
@@ -34,8 +34,25 @@ C: <contained> contained
 TUPLE: comment text ;
 C: <comment> comment
 
-TUPLE: directive text ;
-C: <directive> directive
+TUPLE: directive ;
+
+TUPLE: element-decl < directive name content-spec ;
+C: <element-decl> element-decl
+
+TUPLE: attlist-decl < directive name att-defs ;
+C: <attlist-decl> attlist-decl
+
+TUPLE: entity-decl < directive name def ;
+C: <entity-decl> entity-decl
+
+TUPLE: system-id system-literal ;
+C: <system-id> system-id
+
+TUPLE: public-id pubid-literal system-literal ;
+C: <public-id> public-id
+
+TUPLE: doctype-decl < directive name external-id internal-subset ;
+C: <doctype-decl> doctype-decl
 
 TUPLE: instruction text ;
 C: <instruction> instruction
@@ -47,7 +64,7 @@ TUPLE: attrs alist ;
 C: <attrs> attrs
 
 : attr@ ( key alist -- index {key,value} )
-    >r assure-name r> alist>>
+    [ assure-name ] dip alist>>
     [ first names-match? ] with find ;
 
 M: attrs at*
@@ -56,7 +73,7 @@ M: attrs set-at
     2dup attr@ nip [
         2nip set-second
     ] [
-        >r assure-name swap 2array r>
+        [ assure-name swap 2array ] dip
         [ alist>> ?push ] keep (>>alist)
     ] if* ;
 
@@ -67,7 +84,7 @@ M: attrs >alist alist>> ;
 : >attrs ( assoc -- attrs )
     dup [
         V{ } assoc-clone-like
-        [ >r assure-name r> ] assoc-map
+        [ [ assure-name ] dip ] assoc-map
     ] when <attrs> ;
 M: attrs assoc-like
     drop dup attrs? [ >attrs ] unless ;
@@ -107,9 +124,9 @@ M: tag like
 MACRO: clone-slots ( class -- tuple )
     [
         "slots" word-prop
-        [ name>> reader-word 1quotation [ clone ] compose ] map
-        [ cleave ] curry
-    ] [ [ boa ] curry ] bi compose ;
+        [ name>> reader-word '[ _ execute clone ] ] map
+        '[ _ cleave ]
+    ] [ '[ _ boa ] ] bi compose ;
 
 M: tag clone
     tag clone-slots ;
@@ -129,7 +146,7 @@ CONSULT: name xml body>> ;
 
 <PRIVATE
 : tag>xml ( xml tag -- newxml )
-    >r [ prolog>> ] [ before>> ] [ after>> ] tri r>
+    [ [ prolog>> ] [ before>> ] [ after>> ] tri ] dip
     swap <xml> ;
 
 : seq>xml ( xml seq -- newxml )
index d3eca306858d0420620c1d6d0939afb8930a8e37..03de0f78d1814492947995bf9eff8cdb8884871e 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2006 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces make kernel assocs sequences ;
+USING: namespaces make kernel assocs sequences fry ;
 IN: xml.entities
 
 : entities-out
@@ -19,7 +19,7 @@ IN: xml.entities
 
 : escape-string-by ( str table -- escaped )
     #! Convert <, >, &, ' and " to HTML entities.
-    [ [ dupd at [ % ] [ , ] ?if ] curry each ] "" make ;
+    [ '[ dup _ at [ % ] [ , ] ?if ] each ] "" make ;
 
 : escape-string ( str -- newstr )
     entities-out escape-string-by ;
index ab061530fec23d44157f06cefe736b0d7a1912be..e72e465f0d0179a5c3c342f11903665f6a55b39d 100644 (file)
@@ -1,8 +1,9 @@
-USING: continuations xml xml.errors tools.test kernel arrays xml.data state-parser quotations ;
+USING: continuations xml xml.errors tools.test kernel arrays
+xml.data state-parser quotations fry ;
 IN: xml.errors.tests
 
 : xml-error-test ( expected-error xml-string -- )
-    [ string>xml ] curry swap [ = ] curry must-fail-with ;
+    '[ _ string>xml ] swap '[ _ = ] must-fail-with ;
 
 T{ no-entity f 1 10 "nbsp" } "<x>&nbsp;</x>" xml-error-test
 T{ mismatched f 1 8 T{ name f "" "x" "" } T{ name f "" "y" "" }
@@ -24,5 +25,3 @@ T{ pre/post-content f "x" t } "x<y/>" xml-error-test
 T{ versionless-prolog f 1 8 } "<?xml?><x/>" xml-error-test
 T{ bad-instruction f 1 11 T{ instruction f "xsl" }
 } "<x><?xsl?></x>" xml-error-test
-T{ bad-directive f 1 15 T{ directive f "DOCTYPE" }
-} "<x/><!DOCTYPE>" xml-error-test
index bafa325e895f4ac7f76bf4e256feee5dfc57dd63..0c039d526c5a55e3612294b15d3a656c0e5a195e 100644 (file)
@@ -5,13 +5,13 @@ debugger sequences state-parser accessors summary
 namespaces io.streams.string xml.backend ;
 IN: xml.errors
 
-TUPLE: multitags ;
-C: <multitags> multitags
+ERROR: multitags ;
+
 M: multitags summary ( obj -- str )
     drop "XML document contains multiple main tags" ;
 
-TUPLE: pre/post-content string pre? ;
-C: <pre/post-content> pre/post-content
+ERROR: pre/post-content string pre? ;
+
 M: pre/post-content summary ( obj -- str )
     [
         "The text string:" print
@@ -22,8 +22,10 @@ M: pre/post-content summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: no-entity < parsing-error thing ;
-: <no-entity> ( string -- error )
-    \ no-entity parsing-error swap >>thing ;
+
+: no-entity ( string -- * )
+    \ no-entity parsing-error swap >>thing throw ;
+
 M: no-entity summary ( obj -- str )
     [
         dup call-next-method write
@@ -31,8 +33,10 @@ M: no-entity summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: xml-string-error < parsing-error string ; ! this should not exist
-: <xml-string-error> ( string -- xml-string-error )
-    \ xml-string-error parsing-error swap >>string ;
+
+: xml-string-error ( string -- * )
+    \ xml-string-error parsing-error swap >>string throw ;
+
 M: xml-string-error summary ( obj -- str )
     [
         dup call-next-method write
@@ -40,8 +44,10 @@ M: xml-string-error summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: mismatched < parsing-error open close ;
-: <mismatched> ( open close -- error )
-    \ mismatched parsing-error swap >>close swap >>open ;
+
+: mismatched ( open close -- * )
+    \ mismatched parsing-error swap >>close swap >>open throw ;
+
 M: mismatched summary ( obj -- str )
     [
         dup call-next-method write
@@ -51,9 +57,12 @@ M: mismatched summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: unclosed < parsing-error tags ;
-: <unclosed> ( -- unclosed )
-    unclosed parsing-error
-        xml-stack get rest-slice [ first name>> ] map >>tags ;
+
+: unclosed ( -- * )
+    \ unclosed parsing-error
+        xml-stack get rest-slice [ first name>> ] map >>tags
+    throw ;
+
 M: unclosed summary ( obj -- str )
     [
         dup call-next-method write
@@ -63,8 +72,10 @@ M: unclosed summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: bad-uri < parsing-error string ;
-: <bad-uri> ( string -- bad-uri )
-    \ bad-uri parsing-error swap >>string ;
+
+: bad-uri ( string -- * )
+    \ bad-uri parsing-error swap >>string throw ;
+
 M: bad-uri summary ( obj -- str )
     [
         dup call-next-method write
@@ -72,8 +83,10 @@ M: bad-uri summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: nonexist-ns < parsing-error name ;
-: <nonexist-ns> ( name-string -- nonexist-ns )
-    \ nonexist-ns parsing-error swap >>name ;
+
+: nonexist-ns ( name-string -- * )
+    \ nonexist-ns parsing-error swap >>name throw ;
+
 M: nonexist-ns summary ( obj -- str )
     [
         dup call-next-method write
@@ -81,8 +94,10 @@ M: nonexist-ns summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: unopened < parsing-error ; ! this should give which tag was unopened
-: <unopened> ( -- unopened )
-    \ unopened parsing-error ;
+
+: unopened ( -- * )
+    \ unopened parsing-error throw ;
+
 M: unopened summary ( obj -- str )
     [
         call-next-method write
@@ -90,8 +105,10 @@ M: unopened summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: not-yes/no < parsing-error text ;
-: <not-yes/no> ( text -- not-yes/no )
-    \ not-yes/no parsing-error swap >>text ;
+
+: not-yes/no ( text -- * )
+    \ not-yes/no parsing-error swap >>text throw ;
+
 M: not-yes/no summary ( obj -- str )
     [
         dup call-next-method write
@@ -101,8 +118,10 @@ M: not-yes/no summary ( obj -- str )
 
 ! this should actually print the names
 TUPLE: extra-attrs < parsing-error attrs ;
-: <extra-attrs> ( attrs -- extra-attrs )
-    \ extra-attrs parsing-error swap >>attrs ;
+
+: extra-attrs ( attrs -- * )
+    \ extra-attrs parsing-error swap >>attrs throw ;
+
 M: extra-attrs summary ( obj -- str )
     [
         dup call-next-method write
@@ -111,22 +130,26 @@ M: extra-attrs summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: bad-version < parsing-error num ;
-: <bad-version> ( num -- error )
-    \ bad-version parsing-error swap >>num ;
+
+: bad-version ( num -- * )
+    \ bad-version parsing-error swap >>num throw ;
+
 M: bad-version summary ( obj -- str )
     [
         "XML version must be \"1.0\" or \"1.1\". Version here was " write
         num>> .
     ] with-string-writer ;
 
-TUPLE: notags ;
-C: <notags> notags
+ERROR: notags ;
+
 M: notags summary ( obj -- str )
     drop "XML document lacks a main tag" ;
 
 TUPLE: bad-prolog < parsing-error prolog ;
-: <bad-prolog> ( prolog -- bad-prolog )
-    \ bad-prolog parsing-error swap >>prolog ;
+
+: bad-prolog ( prolog -- * )
+    \ bad-prolog parsing-error swap >>prolog throw ;
+
 M: bad-prolog summary ( obj -- str )
     [
         dup call-next-method write
@@ -135,8 +158,10 @@ M: bad-prolog summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: capitalized-prolog < parsing-error name ;
-: <capitalized-prolog> ( name -- capitalized-prolog )
-    \ capitalized-prolog parsing-error swap >>name ;
+
+: capitalized-prolog ( name -- capitalized-prolog )
+    \ capitalized-prolog parsing-error swap >>name throw ;
+
 M: capitalized-prolog summary ( obj -- str )
     [
         dup call-next-method write
@@ -146,8 +171,10 @@ M: capitalized-prolog summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: versionless-prolog < parsing-error ;
-: <versionless-prolog> ( -- versionless-prolog )
-    \ versionless-prolog parsing-error ;
+
+: versionless-prolog ( -- * )
+    \ versionless-prolog parsing-error throw ;
+
 M: versionless-prolog summary ( obj -- str )
     [
         call-next-method write
@@ -155,23 +182,55 @@ M: versionless-prolog summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: bad-instruction < parsing-error instruction ;
-: <bad-instruction> ( instruction -- bad-instruction )
-    \ bad-instruction parsing-error swap >>instruction ;
+
+: bad-instruction ( instruction -- * )
+    \ bad-instruction parsing-error swap >>instruction throw ;
+
 M: bad-instruction summary ( obj -- str )
     [
         dup call-next-method write
         "Misplaced processor instruction:" print
-        instruction>> write-item nl
+        instruction>> write-xml-chunk nl
     ] with-string-writer ;
 
 TUPLE: bad-directive < parsing-error dir ;
-: <bad-directive> ( directive -- bad-directive )
-    \ bad-directive parsing-error swap >>dir ;
+
+: bad-directive ( directive -- * )
+    \ bad-directive parsing-error swap >>dir throw ;
+
 M: bad-directive summary ( obj -- str )
+    [
+        dup call-next-method write
+        "Unknown directive:" print
+        dir>> write
+    ] with-string-writer ;
+
+TUPLE: bad-doctype-decl < parsing-error ;
+
+: bad-doctype-decl ( -- * )
+    \ bad-doctype-decl parsing-error throw ;
+
+M: bad-doctype-decl summary ( obj -- str )
+    call-next-method "\nBad DOCTYPE" append ;
+
+TUPLE: bad-external-id < parsing-error ;
+
+: bad-external-id ( -- * )
+    \ bad-external-id parsing-error throw ;
+
+M: bad-external-id summary ( obj -- str )
+    call-next-method "\nBad external ID" append ;
+
+TUPLE: misplaced-directive < parsing-error dir ;
+
+: misplaced-directive ( directive -- * )
+    \ misplaced-directive parsing-error swap >>dir throw ;
+
+M: misplaced-directive summary ( obj -- str )
     [
         dup call-next-method write
         "Misplaced directive:" print
-        dir>> write-item nl
+        dir>> write-xml-chunk nl
     ] with-string-writer ;
 
 UNION: xml-parse-error multitags notags extra-attrs nonexist-ns
index 052e5eab7f4727de4cadbb3d788e58dab8f0993c..17f7cab509c9af187b3a6bde2fd290131790f39e 100644 (file)
@@ -1,3 +1,3 @@
 USING: tools.test io.streams.string xml.generator xml.writer accessors ;
 [ "<html><body><a href=\"blah\"/></body></html>" ]
-[ "html" [ "body" [ "a" { { "href" "blah" } } contained*, ] tag, ] make-xml [ body>> write-item ] with-string-writer ] unit-test
+[ "html" [ "body" [ "a" { { "href" "blah" } } contained*, ] tag, ] make-xml [ body>> write-xml-chunk ] with-string-writer ] unit-test
index 24da501265a309d3c97234e68688f516503cb0fc..ac7b14b89e16f3a17ca14d219a132e7b2a9e4494 100644 (file)
@@ -5,12 +5,11 @@ sequences ;
 IN: xml.generator
 
 : comment, ( string -- ) <comment> , ;
-: directive, ( string -- ) <directive> , ;
 : instruction, ( string -- ) <instruction> , ;
 : nl, ( -- ) "\n" , ;
 
 : (tag,) ( name attrs quot -- tag )
-    -rot >r >r V{ } make r> r> rot <tag> ; inline
+    -rot [ V{ } make ] 2dip rot <tag> ; inline
 : tag*, ( name attrs quot -- )
     (tag,) , ; inline
 
index 577ef5718c4eaf906bd4d29ff1e084c31e7d05c8..98facfcac2b80e1def62dc6cc3f35bbead252ff2 100644 (file)
@@ -6,7 +6,7 @@ USING: xml io kernel math sequences strings xml.utilities tools.test math.parser
 PROCESS: calculate ( tag -- n )
 
 : calc-2children ( tag -- n n )
-    children-tags first2 >r calculate r> calculate ;
+    children-tags first2 [ calculate ] dip calculate ;
 
 TAG: number calculate
     children>string string>number ;
diff --git a/basis/xml/tests/funny-dtd.factor b/basis/xml/tests/funny-dtd.factor
new file mode 100644 (file)
index 0000000..1160af6
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: xml.tests
+USING: xml xml.writer io.files io.encodings.utf8 tools.test kernel ;
+
+[ t ] [
+    "resource:basis/xml/tests/funny-dtd.xml" utf8 file-contents string>xml
+    dup xml>string string>xml =
+] unit-test
diff --git a/basis/xml/tests/funny-dtd.xml b/basis/xml/tests/funny-dtd.xml
new file mode 100644 (file)
index 0000000..90f221e
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="yes" ?><!DOCTYPE SHOUTCASTSERVER [<!ELEMENT SHOUTCASTSERVER (CURRENTLISTENERS,PEAKLISTENERS,MAXLISTENERS,REPORTEDLISTENERS,AVERAGETIME,SERVERGENRE,SERVERURL,SERVERTITLE,SONGTITLE,SONGURL,IRC,ICQ,AIM,WEBHITS,STREAMHITS,STREAMSTATUS,BITRATE,CONTENT,VERSION,WEBDATA,LISTENERS,SONGHISTORY)><!ELEMENT CURRENTLISTENERS (#PCDATA)><!ELEMENT PEAKLISTENERS (#PCDATA)><!ELEMENT MAXLISTENERS (#PCDATA)><!ELEMENT REPORTEDLISTENERS (#PCDATA)><!ELEMENT AVERAGETIME (#PCDATA)><!ELEMENT SERVERGENRE (#PCDATA)><!ELEMENT SERVERURL (#PCDATA)><!ELEMENT SERVERTITLE (#PCDATA)><!ELEMENT SONGTITLE (#PCDATA)><!ELEMENT SONGURL (#PCDATA)><!ELEMENT IRC (#PCDATA)><!ELEMENT ICQ (#PCDATA)><!ELEMENT AIM (#PCDATA)><!ELEMENT WEBHITS (#PCDATA)><!ELEMENT STREAMHITS (#PCDATA)><!ELEMENT STREAMSTATUS (#PCDATA)><!ELEMENT BITRATE (#PCDATA)><!ELEMENT CONTENT (#PCDATA)><!ELEMENT VERSION (#PCDATA)><!ELEMENT WEBDATA (INDEX,LISTEN,PALM7,LOGIN,LOGINFAIL,PLAYED,COOKIE,ADMIN,UPDINFO,KICKSRC,KICKDST,UNBANDST,BANDST,VIEWBAN,UNRIPDST,RIPDST,VIEWRIP,VIEWXML,VIEWLOG,INVALID)><!ELEMENT INDEX (#PCDATA)><!ELEMENT LISTEN (#PCDATA)><!ELEMENT PALM7 (#PCDATA)><!ELEMENT LOGIN (#PCDATA)><!ELEMENT LOGINFAIL (#PCDATA)><!ELEMENT PLAYED (#PCDATA)><!ELEMENT COOKIE (#PCDATA)><!ELEMENT ADMIN (#PCDATA)><!ELEMENT UPDINFO (#PCDATA)><!ELEMENT KICKSRC (#PCDATA)><!ELEMENT KICKDST (#PCDATA)><!ELEMENT UNBANDST (#PCDATA)><!ELEMENT BANDST (#PCDATA)><!ELEMENT VIEWBAN (#PCDATA)><!ELEMENT UNRIPDST (#PCDATA)><!ELEMENT RIPDST (#PCDATA)><!ELEMENT VIEWRIP (#PCDATA)><!ELEMENT VIEWXML (#PCDATA)><!ELEMENT VIEWLOG (#PCDATA)><!ELEMENT INVALID (#PCDATA)><!ELEMENT LISTENERS (LISTENER*)><!ELEMENT LISTENER (HOSTNAME,USERAGENT,UNDERRUNS,CONNECTTIME, POINTER, UID)><!ELEMENT HOSTNAME (#PCDATA)><!ELEMENT USERAGENT (#PCDATA)><!ELEMENT UNDERRUNS (#PCDATA)><!ELEMENT CONNECTTIME (#PCDATA)><!ELEMENT POINTER (#PCDATA)><!ELEMENT UID (#PCDATA)><!ELEMENT SONGHISTORY (SONG*)><!ELEMENT SONG (PLAYEDAT, TITLE)><!ELEMENT PLAYEDAT (#PCDATA)><!ELEMENT TITLE (#PCDATA)>]><SHOUTCASTSERVER><CURRENTLISTENERS>0</CURRENTLISTENERS><PEAKLISTENERS>3</PEAKLISTENERS><MAXLISTENERS>500</MAXLISTENERS><REPORTEDLISTENERS>0</REPORTEDLISTENERS><AVERAGETIME>85</AVERAGETIME><SERVERGENRE>various</SERVERGENRE><SERVERURL>http://zomgwtfbbq.info</SERVERURL><SERVERTITLE>[zOMBradio][DJKyleL]</SERVERTITLE><SONGTITLE>Daft Punk - One More Time / Aerodynamic</SONGTITLE><SONGURL></SONGURL><IRC></IRC><ICQ></ICQ><AIM>arkz1372</AIM><WEBHITS>1645</WEBHITS><STREAMHITS>78</STREAMHITS><STREAMSTATUS>0</STREAMSTATUS><BITRATE>96</BITRATE><CONTENT>audio/aacp</CONTENT><VERSION>1.9.8</VERSION><WEBDATA><INDEX>61</INDEX><LISTEN>6</LISTEN><PALM7>0</PALM7><LOGIN>0</LOGIN><LOGINFAIL>30</LOGINFAIL><PLAYED>2</PLAYED><COOKIE>1</COOKIE><ADMIN>11</ADMIN><UPDINFO>1</UPDINFO><KICKSRC>0</KICKSRC><KICKDST>0</KICKDST><UNBANDST>0</UNBANDST><BANDST>0</BANDST><VIEWBAN>3</VIEWBAN><UNRIPDST>0</UNRIPDST><RIPDST>1</RIPDST><VIEWRIP>3</VIEWRIP><VIEWXML>1490</VIEWXML><VIEWLOG>3</VIEWLOG><INVALID>30</INVALID></WEBDATA><LISTENERS></LISTENERS><SONGHISTORY><SONG><PLAYEDAT>1227896017</PLAYEDAT><TITLE>Daft Punk - One More Time / Aerodynamic</TITLE></SONG></SONGHISTORY></SHOUTCASTSERVER>
+
index e95dad661899a15236236d89138d75936c59eb6b..f0af650e4f59ec68013d882c1d31daf48d009be5 100644 (file)
@@ -20,7 +20,7 @@ M: object (r-ref) drop ;
 
 ! Example
 
-: sample-doc
+: sample-doc ( -- string )
     {
         "<html xmlns:f='http://littledan.onigirihouse.com/namespaces/replace'>"
         "<body>"
index 623663ebe1e6eb8b5285b209c4bf603d0a3cf417..01987a98ab6fc0d16bc3d60ce9041ef2f18863cd 100644 (file)
@@ -4,7 +4,7 @@ IN: xml.tests
 USING: kernel xml tools.test io namespaces make sequences
 xml.errors xml.entities parser strings xml.data io.files
 xml.writer xml.utilities state-parser continuations assocs
-sequences.deep accessors ;
+sequences.deep accessors io.streams.string ;
 
 ! This is insufficient
 \ read-xml must-infer
@@ -44,10 +44,20 @@ SYMBOL: xml-file
     "c" get-id children>string
 ] unit-test
 [ "foo" ] [ "<x y='foo'/>" string>xml "y" over
-    at swap "z" >r tuck r> swap set-at
+    at swap "z" [ tuck ] dip swap set-at
     T{ name f "blah" "z" f } swap at ] unit-test
 [ "foo" ] [ "<boo><![CDATA[foo]]></boo>" string>xml children>string ] unit-test
 [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><foo>bar baz</foo>" ]
 [ "<foo>bar</foo>" string>xml [ " baz" append ] map xml>string ] unit-test
 [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<foo>\n  bar\n</foo>" ]
 [ "<foo>         bar            </foo>" string>xml pprint-xml>string ] unit-test
+[ "<!-- B+, B, or B--->" string>xml ] must-fail
+[ ] [ "<?xml version='1.0'?><!-- declarations for <head> & <body> --><foo/>" string>xml drop ] unit-test
+[ T{ element-decl f "br" "EMPTY" } ] [ "<!ELEMENT br EMPTY>" string>xml-chunk second ] unit-test
+[ T{ element-decl f "p" "(#PCDATA|emph)*" } ] [ "<!ELEMENT p (#PCDATA|emph)*>" string>xml-chunk second ] unit-test
+[ T{ element-decl f "%name.para;" "%content.para;" } ] [ "<!ELEMENT %name.para; %content.para;>" string>xml-chunk second ] unit-test
+[ T{ element-decl f "container" "ANY" } ] [ "<!ELEMENT container ANY>" string>xml-chunk second ] unit-test
+[ T{ doctype-decl f "foo" } ] [ "<!DOCTYPE foo>" string>xml-chunk second ] unit-test
+[ T{ doctype-decl f "foo" } ] [ "<!DOCTYPE foo >" string>xml-chunk second ] unit-test
+[ T{ doctype-decl f "foo" T{ system-id f "blah.dtd" } } ] [ "<!DOCTYPE foo SYSTEM 'blah.dtd'>" string>xml-chunk second ] unit-test
+[ T{ doctype-decl f "foo" T{ system-id f "blah.dtd" } } ] [ "<!DOCTYPE foo   SYSTEM \"blah.dtd\"   >" string>xml-chunk second ] unit-test
diff --git a/basis/xml/tests/xmode-dtd.factor b/basis/xml/tests/xmode-dtd.factor
new file mode 100644 (file)
index 0000000..c15d3a4
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: xml io.encodings.utf8 io.files kernel tools.test ;
+IN: xml.tests
+
+[ ] [
+    "resource:basis/xmode/xmode.dtd" utf8 <file-reader>
+    read-xml-chunk drop
+] unit-test
index b7314c5b258f76d1037a87a1e559348f2d3ad193..0c475c108ddb3a0c1a2060a5d90b725303941ee9 100644 (file)
@@ -3,7 +3,7 @@
 USING: xml.errors xml.data xml.utilities xml.char-classes sets
 xml.entities kernel state-parser kernel namespaces make strings
 math math.parser sequences assocs arrays splitting combinators
-unicode.case accessors ;
+unicode.case accessors fry ascii ;
 IN: xml.tokenize
 
 ! XML namespace processing: ns = namespace
@@ -26,7 +26,7 @@ SYMBOL: ns-stack
 
 : add-ns ( name -- )
     dup space>> dup ns-stack get assoc-stack
-    [ nip ] [ <nonexist-ns> throw ] if* >>url drop ;
+    [ nip ] [ nonexist-ns ] if* >>url drop ;
 
 : push-ns ( hash -- )
     ns-stack get push ;
@@ -44,7 +44,7 @@ SYMBOL: ns-stack
 
 : tag-ns ( name attrs-alist -- name attrs )
     dup attrs>ns push-ns
-    >r dup add-ns r> dup [ drop add-ns ] assoc-each <attrs> ;
+    [ dup add-ns ] dip dup [ drop add-ns ] assoc-each <attrs> ;
 
 ! Parsing names
 
@@ -58,7 +58,7 @@ SYMBOL: ns-stack
     get-char name-start? [
         [ dup get-char name-char? not ] take-until nip
     ] [
-        "Malformed name" <xml-string-error> throw
+        "Malformed name" xml-string-error
     ] if ;
 
 : parse-name ( -- name )
@@ -70,9 +70,9 @@ SYMBOL: ns-stack
 : (parse-entity) ( string -- )
     dup entities at [ , ] [ 
         prolog-data get standalone>>
-        [ <no-entity> throw ] [
+        [ no-entity ] [
             dup extra-entities get at
-            [ , ] [ <no-entity> throw ] ?if
+            [ , ] [ no-entity ] ?if
         ] if
     ] ?if ;
 
@@ -95,7 +95,7 @@ SYMBOL: ns-stack
 
 : parse-quot ( ch -- string )
     parse-char get-char
-    [ "XML file ends in a quote" <xml-string-error> throw ] unless ;
+    [ "XML file ends in a quote" xml-string-error ] unless ;
 
 : parse-text ( -- string )
     CHAR: < parse-char ;
@@ -111,7 +111,7 @@ SYMBOL: ns-stack
     get-char dup "'\"" member? [
         next parse-quot
     ] [
-        "Attribute lacks quote" <xml-string-error> throw
+        "Attribute lacks quote" xml-string-error
     ] if ;
 
 : parse-attr ( -- )
@@ -141,8 +141,92 @@ SYMBOL: ns-stack
 : take-cdata ( -- string )
     "[CDATA[" expect-string "]]>" take-string ;
 
+: take-element-decl ( -- element-decl )
+    pass-blank " " take-string pass-blank ">" take-string <element-decl> ;
+
+: take-attlist-decl ( -- doctype-decl )
+    pass-blank " " take-string pass-blank ">" take-string <attlist-decl> ;
+
+: take-until-one-of ( seps -- str sep )
+    '[ get-char _ member? ] take-until get-char ;
+
+: only-blanks ( str -- )
+    [ blank? ] all? [ bad-doctype-decl ] unless ;
+
+: take-system-literal ( -- str )
+    pass-blank get-char next {
+        { CHAR: ' [ "'" take-string ] }
+        { CHAR: " [ "\"" take-string ] }
+    } case ;
+
+: take-system-id ( -- system-id )
+    take-system-literal <system-id>
+    ">" take-string only-blanks ;
+
+: take-public-id ( -- public-id )
+    take-system-literal
+    take-system-literal <public-id>
+    ">" take-string only-blanks ;
+
+DEFER: direct
+
+: (take-internal-subset) ( -- )
+    pass-blank get-char {
+        { CHAR: ] [ next ] }
+        [ drop "<!" expect-string direct , (take-internal-subset) ]
+    } case ;
+
+: take-internal-subset ( -- seq )
+    [ (take-internal-subset) ] { } make ;
+
+: (take-external-id) ( token -- external-id )
+    pass-blank {
+        { "SYSTEM" [ take-system-id ] }
+        { "PUBLIC" [ take-public-id ] }
+        [ bad-external-id ]
+    } case ;
+
+: take-external-id ( -- external-id )
+    " " take-string (take-external-id) ;
+
+: take-doctype-decl ( -- doctype-decl )
+    pass-blank " >" take-until-one-of {
+        { CHAR: \s [
+            pass-blank get-char CHAR: [ = [
+                next take-internal-subset f swap
+                ">" take-string only-blanks
+            ] [
+                " >" take-until-one-of {
+                    { CHAR: \s [ (take-external-id) ] }
+                    { CHAR: > [ only-blanks f ] }
+                } case f
+            ] if
+        ] }
+        { CHAR: > [ f f ] }
+    } case <doctype-decl> ;
+
+: take-entity-def ( -- entity-name entity-def )
+    " " take-string pass-blank get-char {
+        { CHAR: ' [ take-system-literal ] }
+        { CHAR: " [ take-system-literal ] }
+        [ drop take-external-id ]
+    } case ;
+
+: take-entity-decl ( -- entity-decl )
+    pass-blank get-char {
+        { CHAR: % [ next pass-blank take-entity-def ] }
+        [ drop take-entity-def ]
+    } case
+    ">" take-string only-blanks <entity-decl> ;
+
 : take-directive ( -- directive )
-    CHAR: > take-char <directive> next ;
+    " " take-string {
+        { "ELEMENT" [ take-element-decl ] }
+        { "ATTLIST" [ take-attlist-decl ] }
+        { "DOCTYPE" [ take-doctype-decl ] }
+        { "ENTITY" [ take-entity-decl ] }
+        [ bad-directive ]
+    } case ;
 
 : direct ( -- object )
     get-char {
@@ -155,7 +239,7 @@ SYMBOL: ns-stack
     {
         { "yes" [ t ] }
         { "no" [ f ] }
-        [ <not-yes/no> throw ]
+        [ not-yes/no ]
     } case ;
 
 : assure-no-extra ( seq -- )
@@ -164,14 +248,14 @@ SYMBOL: ns-stack
         T{ name f "" "encoding" f }
         T{ name f "" "standalone" f }
     } diff
-    [ <extra-attrs> throw ] unless-empty ; 
+    [ extra-attrs ] unless-empty ; 
 
 : good-version ( version -- version )
-    dup { "1.0" "1.1" } member? [ <bad-version> throw ] unless ;
+    dup { "1.0" "1.1" } member? [ bad-version ] unless ;
 
 : prolog-attrs ( alist -- prolog )
     [ T{ name f "" "version" f } swap at
-      [ good-version ] [ <versionless-prolog> throw ] if* ] keep
+      [ good-version ] [ versionless-prolog ] if* ] keep
     [ T{ name f "" "encoding" f } swap at
       "UTF-8" or ] keep
     T{ name f "" "standalone" f } swap at
@@ -187,7 +271,7 @@ SYMBOL: ns-stack
     (parse-name) dup "xml" =
     [ drop parse-prolog ] [
         dup >lower "xml" =
-        [ <capitalized-prolog> throw ]
+        [ capitalized-prolog ]
         [ "?>" take-string append <instruction> ] if
     ] if ;
 
index 2acb353bb6c7116709f11e56cd96f76aa288d9c4..e104142a76e5586be4ccebddcd23a54952655f2b 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel namespaces sequences words io assocs
 quotations strings parser lexer arrays xml.data xml.writer debugger
-splitting vectors sequences.deep combinators ;
+splitting vectors sequences.deep combinators fry ;
 IN: xml.utilities
 
 ! * System for words specialized on tag names
@@ -16,30 +16,30 @@ M: process-missing error.
 
 : run-process ( tag word -- )
     2dup "xtable" word-prop
-    >r dup main>> r> at* [ 2nip call ] [
+    [ dup main>> ] dip at* [ 2nip call ] [
         drop \ process-missing boa throw
     ] if ;
 
 : PROCESS:
     CREATE
     dup H{ } clone "xtable" set-word-prop
-    dup [ run-process ] curry define ; parsing
+    dup '[ _ run-process ] define ; parsing
 
 : TAG:
     scan scan-word
     parse-definition
     swap "xtable" word-prop
-    rot "/" split [ >r 2dup r> swap set-at ] each 2drop ;
+    rot "/" split [ [ 2dup ] dip swap set-at ] each 2drop ;
     parsing
 
 
 ! * Common utility functions
 
 : build-tag* ( items name -- tag )
-    assure-name swap >r f r> <tag> ;
+    assure-name swap f swap <tag> ;
 
 : build-tag ( item name -- tag )
-    >r 1array r> build-tag* ;
+    [ 1array ] dip build-tag* ;
 
 : standard-prolog ( -- prolog )
     T{ prolog f "1.0" "UTF-8" f } ;
@@ -69,13 +69,13 @@ M: process-missing error.
     dup tag? [ names-match? ] [ 2drop f ] if ;
 
 : tags@ ( tag name -- children name )
-    >r { } like r> assure-name ;
+    [ { } like ] dip assure-name ;
 
 : deep-tag-named ( tag name/string -- matching-tag )
-    assure-name [ swap tag-named? ] curry deep-find ;
+    assure-name '[ _ swap tag-named? ] deep-find ;
 
 : deep-tags-named ( tag name/string -- tags-seq )
-    tags@ [ swap tag-named? ] curry deep-filter ;
+    tags@ '[ _ swap tag-named? ] deep-filter ;
 
 : tag-named ( tag name/string -- matching-tag )
     ! like get-name-tag but only looks at direct children,
@@ -89,22 +89,22 @@ M: process-missing error.
     rot dup tag? [ at = ] [ 3drop f ] if ;
 
 : tag-with-attr ( tag attr-value attr-name -- matching-tag )
-    assure-name [ tag-with-attr? ] 2curry find nip ;
+    assure-name '[ _ _ tag-with-attr? ] find nip ;
 
 : tags-with-attr ( tag attr-value attr-name -- tags-seq )
-    tags@ [ tag-with-attr? ] 2curry filter children>> ;
+    tags@ '[ _ _ tag-with-attr? ] filter children>> ;
 
 : deep-tag-with-attr ( tag attr-value attr-name -- matching-tag )
-    assure-name [ tag-with-attr? ] 2curry deep-find ;
+    assure-name '[ _ _ tag-with-attr? ] deep-find ;
 
 : deep-tags-with-attr ( tag attr-value attr-name -- tags-seq )
-    tags@ [ tag-with-attr? ] 2curry deep-filter ;
+    tags@ '[ _ _ tag-with-attr? ] deep-filter ;
 
 : get-id ( tag id -- elem ) ! elem=tag.getElementById(id)
     "id" deep-tag-with-attr ;
 
 : deep-tags-named-with-attr ( tag tag-name attr-value attr-name -- tags )
-    >r >r deep-tags-named r> r> tags-with-attr ;
+    [ deep-tags-named ] 2dip tags-with-attr ;
 
 : assert-tag ( name name -- )
     names-match? [ "Unexpected XML tag found" throw ] unless ;
@@ -114,4 +114,4 @@ M: process-missing error.
     [ swap V{ } like >>children drop ] if ;
 
 : insert-child ( child tag -- )
-    >r 1vector r> insert-children ;
+    [ 1vector ] dip insert-children ;
index ae6fddacc3a981e97e346ba4e84b4625bd4593a4..12601953f67f67589039d2b3e9324749564b9d0d 100644 (file)
@@ -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 ;\r
+xml.data wrap xml.entities unicode.categories fry ;\r
 IN: xml.writer\r
 \r
 SYMBOL: xml-pprint?\r
@@ -12,7 +12,7 @@ SYMBOL: indenter
 "  " indenter set-global\r
 \r
 : sensitive? ( tag -- ? )\r
-    sensitive-tags get swap [ names-match? ] curry contains? ;\r
+    sensitive-tags get swap '[ _ names-match? ] contains? ;\r
 \r
 : indent-string ( -- string )\r
     xml-pprint? get\r
@@ -52,9 +52,9 @@ SYMBOL: indenter
         "\"" write\r
     ] assoc-each ;\r
 \r
-GENERIC: write-item ( object -- )\r
+GENERIC: write-xml-chunk ( object -- )\r
 \r
-M: string write-item\r
+M: string write-xml-chunk\r
     escape-string dup empty? not xml-pprint? get and\r
     [ nl 80 indent-string indented-break ] when write ;\r
 \r
@@ -65,54 +65,89 @@ M: string write-item
 : write-start-tag ( tag -- )\r
     write-tag ">" write ;\r
 \r
-M: contained-tag write-item\r
+M: contained-tag write-xml-chunk\r
     write-tag "/>" write ;\r
 \r
 : write-children ( tag -- )\r
     indent children>> ?filter-children\r
-    [ write-item ] each unindent ;\r
+    [ write-xml-chunk ] each unindent ;\r
 \r
 : write-end-tag ( tag -- )\r
     ?indent "</" write print-name CHAR: > write1 ;\r
 \r
-M: open-tag write-item\r
-    xml-pprint? get >r\r
-    {\r
-        [ sensitive? not xml-pprint? get and xml-pprint? set ]\r
-        [ write-start-tag ]\r
-        [ write-children ]\r
-        [ write-end-tag ]\r
-    } cleave\r
-    r> xml-pprint? set ;\r
-\r
-M: comment write-item\r
+M: open-tag write-xml-chunk\r
+    xml-pprint? get [\r
+        {\r
+            [ sensitive? not xml-pprint? get and xml-pprint? set ]\r
+            [ write-start-tag ]\r
+            [ write-children ]\r
+            [ write-end-tag ]\r
+        } cleave\r
+    ] dip xml-pprint? set ;\r
+\r
+M: comment write-xml-chunk\r
     "<!--" write text>> write "-->" write ;\r
 \r
-M: directive write-item\r
+M: element-decl write-xml-chunk\r
+    "<!ELEMENT " write\r
+    [ name>> write " " write ]\r
+    [ content-spec>> write ">" write ]\r
+    bi ;\r
+\r
+M: attlist-decl write-xml-chunk\r
+    "<!ATTLIST " write\r
+    [ name>> write " " write ]\r
+    [ att-defs>> write ">" write ]\r
+    bi ;\r
+\r
+M: entity-decl write-xml-chunk\r
+    "<!ENTITY " write\r
+    [ name>> write " " write ]\r
+    [ def>> write-xml-chunk ">" write ]\r
+    bi ;\r
+\r
+M: system-id write-xml-chunk\r
+    "SYSTEM '" write system-literal>> write "'" write ;\r
+\r
+M: public-id write-xml-chunk\r
+    "PUBLIC '" write\r
+    [ pubid-literal>> write "' '" write ]\r
+    [ system-literal>> write "'>" write ] bi ;\r
+\r
+M: doctype-decl write-xml-chunk\r
+    "<!DOCTYPE " write\r
+    [ name>> write " " write ]\r
+    [ external-id>> [ write-xml-chunk " " write ] when* ]\r
+    [\r
+        internal-subset>>\r
+        [ "[" write [ write-xml-chunk ] each "]" write ] when* ">" write\r
+    ] tri ;\r
+\r
+M: directive write-xml-chunk\r
     "<!" write text>> write CHAR: > write1 ;\r
 \r
-M: instruction write-item\r
+M: instruction write-xml-chunk\r
     "<?" write text>> write "?>" write ;\r
 \r
+M: sequence write-xml-chunk\r
+    [ write-xml-chunk ] each ;\r
+\r
 : write-prolog ( xml -- )\r
     "<?xml version=\"" write dup version>> write\r
     "\" encoding=\"" write dup encoding>> write\r
     standalone>> [ "\" standalone=\"yes" write ] when\r
     "\"?>" write ;\r
 \r
-: write-chunk ( seq -- )\r
-    [ write-item ] each ;\r
-\r
 : write-xml ( xml -- )\r
     {\r
         [ prolog>> write-prolog ]\r
-        [ before>> write-chunk ]\r
-        [ body>> write-item ]\r
-        [ after>> write-chunk ]\r
+        [ before>> write-xml-chunk ]\r
+        [ body>> write-xml-chunk ]\r
+        [ after>> write-xml-chunk ]\r
     } cleave ;\r
 \r
-M: xml write-item\r
-    body>> write-item ;\r
+M: xml write-xml-chunk\r
+    body>> write-xml-chunk ;\r
 \r
 : print-xml ( xml -- )\r
     write-xml nl ;\r
index 248a43ed6347fed72fb2d7213ccf78d5cd6e674f..05dd85251dd032602a1e941285746459165c28ad 100644 (file)
@@ -173,10 +173,10 @@ HELP: names-match?
 { $example "USING: prettyprint xml.data ;" "T{ name f \"rpc\" \"methodCall\" f } T{ name f f \"methodCall\" \"http://www.xmlrpc.org/\" } names-match? ." "t" }\r
 { $see-also name } ;\r
 \r
-HELP: xml-chunk\r
+HELP: read-xml-chunk\r
 { $values { "stream" "an input stream" } { "seq" "a sequence of elements" } }\r
 { $description "rather than parse a document, as " { $link read-xml } " does, this word parses and returns a sequence of XML elements (tags, strings, etc), ie a document fragment. This is useful for pieces of XML which may have more than one main tag." }\r
-{ $see-also write-chunk read-xml } ;\r
+{ $see-also write-xml-chunk read-xml } ;\r
 \r
 HELP: get-id\r
 { $values { "tag" "an XML tag or document" } { "id" "a string" } { "elem" "an XML element or f" } }\r
@@ -239,15 +239,10 @@ HELP: pull-event
 { $description "gets the next XML event from the given XML pull parser. Returns f upon exhaustion." }\r
 { $see-also pull-xml <pull-xml> pull-elem } ;\r
 \r
-HELP: write-item\r
+HELP: write-xml-chunk\r
 { $values { "object" "an XML element" } }\r
 { $description "writes an XML element to " { $link output-stream } "." }\r
-{ $see-also write-chunk write-xml } ;\r
-\r
-HELP: write-chunk\r
-{ $values { "seq" "an XML document fragment" } }\r
-{ $description "writes an XML document fragment, ie a sequence of XML elements, to " { $link output-stream } "." }\r
-{ $see-also write-item write-xml } ;\r
+{ $see-also write-xml-chunk write-xml } ;\r
 \r
 HELP: deep-tag-named\r
 { $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "matching-tag" tag } }\r
@@ -352,13 +347,13 @@ ARTICLE: { "xml" "reading" } "Reading XML"
     "The following words are used to read something into an XML document"\r
     { $subsection string>xml }\r
     { $subsection read-xml }\r
-    { $subsection xml-chunk }\r
+    { $subsection read-xml-chunk }\r
+    { $subsection string>xml-chunk }\r
     { $subsection file>xml } ;\r
 \r
 ARTICLE: { "xml" "writing" } "Writing XML"\r
     "These words are used in implementing prettyprint"\r
-    { $subsection write-item }\r
-    { $subsection write-chunk }\r
+    { $subsection write-xml-chunk }\r
     "These words are used to print XML normally"\r
     { $subsection xml>string }\r
     { $subsection write-xml }\r
index 67168bfb4955e4453f88b8e730ccfde8aba58ed0..8afcf7a33b0ed55e0b5c89b6b305efaafbcf27e9 100644 (file)
@@ -24,17 +24,17 @@ M: object process add-child ;
 
 M: prolog process
     xml-stack get V{ { f V{ "" } } } =
-    [ <bad-prolog> throw ] unless drop ;
+    [ bad-prolog ] unless drop ;
 
 M: instruction process
     xml-stack get length 1 =
-    [ <bad-instruction> throw ] unless
+    [ bad-instruction ] unless
     add-child ;
 
 M: directive process
     xml-stack get dup length 1 =
     swap first second [ tag? ] contains? not and
-    [ <bad-directive> throw ] unless
+    [ misplaced-directive ] unless
     add-child ;
 
 M: contained process
@@ -44,13 +44,13 @@ M: contained process
 M: opener process push-xml ;
 
 : check-closer ( name opener -- name opener )
-    dup [ <unopened> throw ] unless
+    dup [ unopened ] unless
     2dup name>> =
-    [ name>> swap <mismatched> throw ] unless ;
+    [ name>> swap mismatched ] unless ;
 
 M: closer process
     name>> pop-xml first2
-    >r check-closer attrs>> r>
+    [ check-closer attrs>> ] dip
     <tag> add-child ;
 
 : init-xml-stack ( -- )
@@ -69,27 +69,25 @@ M: closer process
     swap [ string? ] filter
     [
         dup [ blank? ] all?
-        [ drop ] [ swap <pre/post-content> throw ] if
+        [ drop ] [ swap pre/post-content ] if
     ] each drop ;
 
 : no-pre/post ( pre post -- pre post/* )
     ! this does *not* affect the contents of the stack
-    >r dup t assert-blanks r>
-    dup f assert-blanks ;
+    [ dup t assert-blanks ] [ dup f assert-blanks ] bi* ;
 
 : no-post-tags ( post -- post/* )
     ! this does *not* affect the contents of the stack
-    dup [ tag? ] contains? [ <multitags> throw ] when ; 
+    dup [ tag? ] contains? [ multitags ] when ; 
 
 : assure-tags ( seq -- seq )
     ! this does *not* affect the contents of the stack
-    [ <notags> throw ] unless* ;
+    [ notags ] unless* ;
 
 : make-xml-doc ( prolog seq -- xml-doc )
     dup [ tag? ] find
-    >r assure-tags cut rest
-    no-pre/post no-post-tags
-    r> swap <xml> ;
+    [ assure-tags cut rest no-pre/post no-post-tags ] dip
+    swap <xml> ;
 
 ! * Views of XML
 
@@ -142,24 +140,27 @@ TUPLE: pull-xml scope ;
 : (read-xml) ( -- )
     [ process ] sax-loop ; inline
 
-: (xml-chunk) ( stream -- prolog seq )
+: (read-xml-chunk) ( stream -- prolog seq )
     [
         init-xml (read-xml)
-        done? [ <unclosed> throw ] unless
+        done? [ unclosed ] unless
         xml-stack get first second
         prolog-data get swap
     ] state-parse ;
 
 : read-xml ( stream -- xml )
     #! Produces a tree of XML nodes
-    (xml-chunk) make-xml-doc ;
+    (read-xml-chunk) make-xml-doc ;
 
-: xml-chunk ( stream -- seq )
-    (xml-chunk) nip ;
+: read-xml-chunk ( stream -- seq )
+    (read-xml-chunk) nip ;
 
 : string>xml ( string -- xml )
     <string-reader> read-xml ;
 
+: string>xml-chunk ( string -- xml )
+    <string-reader> read-xml-chunk ;
+
 : file>xml ( filename -- xml )
     ! Autodetect encoding!
     utf8 <file-reader> read-xml ;
index 8f1a6184e84c7658d72bf9e9ea629ae9c82bc004..23e4195158b05dc0d9e90fc647001de05e727ee5 100644 (file)
@@ -1,30 +1,30 @@
 USING: accessors sequences assocs kernel quotations namespaces
-xml.data xml.utilities combinators macros parser lexer words ;
+xml.data xml.utilities combinators macros parser lexer words fry ;
 IN: xmode.utilities
 
-: implies >r not r> or ; inline
+: implies [ not ] dip or ; inline
 
 : child-tags ( tag -- seq ) children>> [ tag? ] filter ;
 
 : map-find ( seq quot -- result elt )
     f -rot
-    [ nip ] swap [ dup ] 3compose find
-    >r [ drop f ] unless r> ; inline
+    '[ nip @ dup ] find
+    [ [ drop f ] unless ] dip ; inline
 
 : tag-init-form ( spec -- quot )
     {
         { [ dup quotation? ] [ [ object get tag get ] prepose ] }
         { [ dup length 2 = ] [
-            first2 [
-                >r >r tag get children>string
-                r> [ execute ] when* object get r> execute
-            ] 2curry
+            first2 '[
+                tag get children>string
+                _ [ execute ] when* object get _ execute
+            ]
         ] }
         { [ dup length 3 = ] [
-            first3 [
-                >r >r tag get at
-                r> [ execute ] when* object get r> execute
-            ] 3curry
+            first3 '[
+                _ tag get at
+                _ [ execute ] when* object get _ execute
+            ]
         ] }
     } cond ;
 
@@ -36,7 +36,7 @@ MACRO: (init-from-tag) ( specs -- )
     [ with-tag-initializer ] curry ;
 
 : init-from-tag ( tag tuple specs -- tuple )
-    over >r (init-from-tag) r> ; inline
+    over [ (init-from-tag) ] dip ; inline
 
 SYMBOL: tag-handlers
 SYMBOL: tag-handler-word
index 74bc57e9db80c80940e44df38831ffffdfac3e8a..4a998a1ebb118d7e15a9bcb4f04681ff640d0471 100644 (file)
@@ -12,11 +12,9 @@ M: array resize resize-array ;
 
 : >array ( seq -- array ) { } clone-like ;
 
-M: object new-sequence drop f <array> ;
+M: object new-sequence drop 0 <array> ;
 
-M: f new-sequence drop dup zero? [ drop f ] [ f <array> ] if ;
-
-M: array like drop dup array? [ >array ] unless ;
+M: f new-sequence drop dup zero? [ drop f ] [ 0 <array> ] if ;
 
 M: array equal?
     over array? [ sequence= ] [ 2drop f ] if ;
index 3deb08ac628f5ca10a9a3fbf855c9606a6b83d6d..969c7249a9205150c01fdacb1b82db9f273411ab 100644 (file)
@@ -1,7 +1,7 @@
 IN: assocs.tests
 USING: kernel math namespaces make tools.test vectors sequences
 sequences.private hashtables io prettyprint assocs
-continuations float-arrays ;
+continuations specialized-arrays.double ;
 
 [ t ] [ H{ } dup assoc-subset? ] unit-test
 [ f ] [ H{ { 1 3 } } H{ } assoc-subset? ] unit-test
@@ -91,7 +91,7 @@ unit-test
 [
     H{ { 1.0 1.0 } { 2.0 2.0 } }
 ] [
-    F{ 1.0 2.0 } [ dup ] H{ } map>assoc
+    double-array{ 1.0 2.0 } [ dup ] H{ } map>assoc
 ] unit-test
 
 [ { 3 } ] [
index 953cc38c5632283fabc023c07dca72513fed58e9..76745cc0151f99055c778d87e5861ddf2f85be4e 100644 (file)
@@ -90,7 +90,7 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     ] if ; inline recursive
 
 : assoc-stack ( key seq -- value )
-    dup length 1- swap (assoc-stack) ;
+    dup length 1- swap (assoc-stack) ; flushable
 
 : assoc-subset? ( assoc1 assoc2 -- ? )
     [ swapd at* [ = ] [ 2drop f ] if ] curry assoc-all? ;
@@ -110,8 +110,8 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
     swap [ swapd set-at ] curry assoc-each ;
 
 : assoc-union ( assoc1 assoc2 -- union )
-    2dup [ assoc-size ] bi@ + pick new-assoc
-    [ rot update ] keep [ swap update ] keep ;
+    [ [ [ assoc-size ] bi@ + ] [ drop ] 2bi new-assoc ] 2keep
+    [ dupd update ] bi@ ;
 
 : assoc-combine ( seq -- union )
     H{ } clone [ dupd update ] reduce ;
index 8f280cb53a37ecc5c648aee0a3ecc2d0e37efab1..f90ba23999994607ae6bcac9ff3f38af23ed512f 100644 (file)
@@ -1,13 +1,13 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien arrays byte-arrays generic hashtables
-hashtables.private io kernel math math.order namespaces make
-parser sequences strings vectors words quotations assocs layouts
-classes classes.builtin classes.tuple classes.tuple.private
-kernel.private vocabs vocabs.loader source-files definitions
-slots classes.union classes.intersection classes.predicate
-compiler.units bootstrap.image.private io.files accessors
-combinators ;
+hashtables.private io kernel math math.private math.order
+namespaces make parser sequences strings vectors words
+quotations assocs layouts classes classes.builtin classes.tuple
+classes.tuple.private kernel.private vocabs vocabs.loader
+source-files definitions slots classes.union
+classes.intersection classes.predicate compiler.units
+bootstrap.image.private io.files accessors combinators ;
 IN: bootstrap.primitives
 
 "Creating primitives and basic runtime structures..." print flush
@@ -109,9 +109,6 @@ bootstrapping? on
 } [ create-vocab drop ] each
 
 ! Builtin classes
-: define-builtin-predicate ( class -- )
-    dup class>type [ builtin-instance? ] curry define-predicate ;
-
 : lookup-type-number ( word -- n )
     global [ target-word ] bind type-number ;
 
@@ -185,9 +182,17 @@ define-union-class
 ! A predicate class used for declarations
 "array-capacity" "sequences.private" create
 "fixnum" "math" lookup
-0 bootstrap-max-array-capacity <fake-bignum> [ between? ] 2curry
+[
+    [ dup 0 fixnum>= ] %
+    bootstrap-max-array-capacity <fake-bignum> [ fixnum<= ] curry ,
+    [ [ drop f ] if ] %
+] [ ] make
 define-predicate-class
 
+"array-capacity" "sequences.private" lookup
+[ >fixnum ] bootstrap-max-array-capacity [ fixnum-bitand ] curry append
+"coercer" set-word-prop
+
 ! Catch-all class for providing a default method.
 "object" "kernel" create
 [ f f { } intersection-class define-class ]
@@ -344,6 +349,7 @@ tuple
 {
     { "(execute)" "words.private" }
     { "(call)" "kernel.private" }
+    { "both-fixnums?" "math.private" }
     { "fixnum+fast" "math.private" }
     { "fixnum-fast" "math.private" }
     { "fixnum*fast" "math.private" }
@@ -494,7 +500,8 @@ tuple
     { "alien-address" "alien" }
     { "set-slot" "slots.private" }
     { "string-nth" "strings.private" }
-    { "set-string-nth" "strings.private" }
+    { "set-string-nth-fast" "strings.private" }
+    { "set-string-nth-slow" "strings.private" }
     { "resize-array" "arrays" }
     { "resize-string" "strings" }
     { "<array>" "arrays" }
@@ -529,6 +536,8 @@ tuple
     { "dll-valid?" "alien" }
     { "unimplemented" "kernel.private" }
     { "gc-reset" "memory" }
+    { "jit-compile" "quotations" }
+    { "load-locals" "locals.backend" }
 }
 [ [ first2 ] dip make-primitive ] each-index
 
index 50ea4b32ba3cf9f106c45eb5b88adbaa7fe3b2c1..f981e758d79e3bd3c76613a74405033c9df3ca8b 100644 (file)
@@ -9,7 +9,6 @@ M: byte-array length length>> ;
 M: byte-array nth-unsafe swap >fixnum alien-unsigned-1 ;
 M: byte-array set-nth-unsafe swap >fixnum set-alien-unsigned-1 ;
 : >byte-array ( seq -- byte-array ) B{ } clone-like ; inline
-M: byte-array like drop dup byte-array? [ >byte-array ] unless ;
 M: byte-array new-sequence drop <byte-array> ;
 
 M: byte-array equal?
index 5d337cb028992afcd0e09d46863437cc8ba4b8b0..6938d02b2f0d79b1c5483a867589110052529889 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: arrays kernel kernel.private math sequences\r
-sequences.private growable byte-arrays ;\r
+sequences.private growable byte-arrays accessors ;\r
 IN: byte-vectors\r
 \r
 TUPLE: byte-vector\r
@@ -26,6 +26,19 @@ M: byte-vector new-sequence
 M: byte-vector equal?\r
     over byte-vector? [ sequence= ] [ 2drop f ] if ;\r
 \r
+M: byte-array like\r
+    #! If we have an byte-array, we're done.\r
+    #! If we have a byte-vector, and it's at full capacity,\r
+    #! we're done. Otherwise, call resize-byte-array, which is a\r
+    #! relatively fast primitive.\r
+    drop dup byte-array? [\r
+        dup byte-vector? [\r
+            [ length ] [ underlying>> ] bi\r
+            2dup length eq?\r
+            [ nip ] [ resize-byte-array ] if\r
+        ] [ >byte-array ] if\r
+    ] unless ;\r
+\r
 M: byte-array new-resizable drop <byte-vector> ;\r
 \r
 INSTANCE: byte-vector growable\r
index ee687c2939abd1e49a7118eca546e4686582995b..0e4a3b56fde4218ae824fa275becf8547b513e39 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors classes classes.algebra words kernel
 kernel.private namespaces sequences math math.private
-combinators assocs ;
+combinators assocs quotations ;
 IN: classes.builtin
 
 SYMBOL: builtins
@@ -10,10 +10,14 @@ SYMBOL: builtins
 PREDICATE: builtin-class < class
     "metaclass" word-prop builtin-class eq? ;
 
-: type>class ( n -- class ) builtins get-global nth ;
-
 : class>type ( class -- n ) "type" word-prop ; foldable
 
+PREDICATE: lo-tag-class < builtin-class class>type 7 <= ;
+
+PREDICATE: hi-tag-class < builtin-class class>type 7 > ;
+
+: type>class ( n -- class ) builtins get-global nth ;
+
 : bootstrap-type>class ( n -- class ) builtins get nth ;
 
 M: hi-tag class hi-tag type>class ;
@@ -22,16 +26,20 @@ M: object class tag type>class ;
 
 M: builtin-class rank-class drop 0 ;
 
-: builtin-instance? ( object n -- ? )
-    #! 7 == tag-mask get
-    #! 3 == hi-tag tag-number
-    dup 7 fixnum<= [ swap tag eq? ] [
-        swap dup tag 3 eq?
-        [ hi-tag eq? ] [ 2drop f ] if
-    ] if ; inline
+GENERIC: define-builtin-predicate ( class -- )
+
+M: lo-tag-class define-builtin-predicate
+    dup class>type [ eq? ] curry [ tag ] prepend define-predicate ;
+
+M: hi-tag-class define-builtin-predicate
+    dup class>type [ eq? ] curry [ hi-tag ] prepend 1quotation
+    [ dup tag 3 eq? ] [ [ drop f ] if ] surround
+    define-predicate ;
+
+M: lo-tag-class instance? [ tag ] [ class>type ] bi* eq? ;
 
-M: builtin-class instance?
-    class>type builtin-instance? ;
+M: hi-tag-class instance?
+    over tag 3 eq? [ [ hi-tag ] [ class>type ] bi* eq? ] [ 2drop f ] if ;
 
 M: builtin-class (flatten-class) dup set ;
 
index 55831fcdb4936e89e85e8f0b9d8a631b73b5e147..fffb172204d7057a9f5f23fdc58b2d8746f72466 100644 (file)
@@ -23,7 +23,7 @@ PREDICATE: intersection-class < class
 M: intersection-class update-class define-intersection-predicate ;
 
 : define-intersection-class ( class participants -- )
-    [ f f rot intersection-class define-class ]
+    [ [ f f ] dip intersection-class define-class ]
     [ drop update-classes ]
     2bi ;
 
index 65726cf6e895f58de464ed2f2f6188ca9218cfff..2470c0087526e0ccf60c9906208a3b3489e66259 100644 (file)
@@ -25,7 +25,7 @@ M: mixin-class rank-class drop 3 ;
         bi
     ] if ;
 
-TUPLE: check-mixin-class mixin ;
+TUPLE: check-mixin-class class ;
 
 : check-mixin-class ( mixin -- mixin )
     dup mixin-class? [
index 4d2c537522051ea604b9b6eeba6f716471ec82c8..3bac6c87b3aa6e429ee07db66c667f4dbcfbee0b 100644 (file)
@@ -90,7 +90,7 @@ ARTICLE: "tuple-constructors" "Tuple constructors"
 { $subsection POSTPONE: C: }
 "By convention, construction logic is encapsulated in a word named after the tuple class surrounded in angle brackets; for example, the constructor word for a " { $snippet "point" } " class might be named " { $snippet "<point>" } "."
 $nl
-"Constructors play a part in enforcing the invariant that slot values must always match slot declarations. The " { $link new } " word fills in the tuple will initial values, and " { $link boa } " ensures that the values on the stack match the corresponding slot declarations. See " { $link "tuple-declarations" } "."
+"Constructors play a part in enforcing the invariant that slot values must always match slot declarations. The " { $link new } " word fills in the tuple with initial values, and " { $link boa } " ensures that the values on the stack match the corresponding slot declarations. See " { $link "tuple-declarations" } "."
 $nl
 "All tuple construction should be done through constructor words, and construction primitives should be encapsulated and never called outside of the vocabulary where the class is defined, because this encourages looser coupling. For example, a constructor word could be changed to use memoization instead of always constructing a new instance, or it could be changed to construt a different class, without breaking callers."
 $nl
@@ -103,11 +103,11 @@ $nl
     "{ alpha integer initial: 1 } ;"
     ""
     "! The following two are equivalent"
-    "C: <rgba> rgba"
+    "C: <rgba> color"
     ": <rgba> color boa ;"
     ""
     "! We can define constructors which call other constructors"
-    ": <rgb> 1 <rgba> ;"
+    ": <rgb> ( r g b -- color ) 1 <rgba> ;"
     ""
     "! The following two are equivalent; note the initial value"
     ": <color> ( -- color ) color new ;"
index b6b277a32f41b6d3897711209be03ce58aa7dbe8..9d748d665d9ae927c1dea776feed91c57efea654 100644 (file)
@@ -90,10 +90,10 @@ ERROR: bad-superclass class ;
         2drop f
     ] if ; inline
 
-: tuple-instance-1? ( object class -- ? )
-    swap dup tuple? [
-        layout-of 7 slot eq?
-    ] [ 2drop f ] if ; inline
+: tuple-predicate-quot/1 ( class -- quot )
+    #! Fast path for tuples with no superclass
+    [ ] curry [ layout-of 7 slot ] [ eq? ] surround 1quotation
+    [ dup tuple? ] [ [ drop f ] if ] surround ;
 
 : tuple-instance? ( object class offset -- ? )
     rot dup tuple? [
@@ -105,13 +105,16 @@ ERROR: bad-superclass class ;
 : layout-class-offset ( echelon -- n )
     2 * 5 + ;
 
+: tuple-predicate-quot ( class echelon -- quot )
+    layout-class-offset [ tuple-instance? ] 2curry ;
+
 : echelon-of ( class -- n )
     tuple-layout third ;
 
 : define-tuple-predicate ( class -- )
     dup dup echelon-of {
-        { 1 [ [ tuple-instance-1? ] curry ] }
-        [ layout-class-offset [ tuple-instance? ] 2curry ]
+        { 1 [ tuple-predicate-quot/1 ] }
+        [ tuple-predicate-quot ]
     } case define-predicate ;
 
 : class-size ( class -- n )
@@ -248,7 +251,9 @@ M: tuple-class update-class
     3bi ;
 
 : tuple-class-unchanged? ( class superclass slots -- ? )
-    rot tuck [ superclass = ] [ "slots" word-prop = ] 2bi* and ;
+    [ over ] dip
+    [ [ superclass ] dip = ]
+    [ [ "slots" word-prop ] dip = ] 2bi* and ;
 
 : valid-superclass? ( class -- ? )
     [ tuple-class? ] [ tuple eq? ] bi or ;
index 3afc0a3c3d1ce853714e12a00a540c3be8a8143e..8d1d9f0d2af040be7d2ada809cdf131fbf4e53ff 100644 (file)
@@ -29,17 +29,9 @@ $nl
 $nl
 "A combinator which can help with implementing methods on " { $link hashcode* } ":"
 { $subsection recursive-hashcode }
-{ $subsection "assertions" }
 { $subsection "combinators-quot" }
 { $see-also "quotations" "dataflow" } ;
 
-ARTICLE: "assertions" "Assertions"
-"Some words to make assertions easier to enforce:"
-{ $subsection assert }
-{ $subsection assert= }
-"Runtime stack depth checking:"
-{ $subsection assert-depth } ;
-
 ABOUT: "combinators"
 
 HELP: cleave
@@ -167,7 +159,3 @@ HELP: dispatch ( n array -- )
 { $values { "n" "a fixnum" } { "array" "an array of quotations" } }
 { $description "Calls the " { $snippet "n" } "th quotation in the array." }
 { $warning "This word is in the " { $vocab-link "kernel.private" } " vocabulary because it is an implementation detail used by the generic word system to accelerate method dispatch. It does not perform type or bounds checks, and user code should not need to call it directly." } ;
-
-HELP: assert-depth
-{ $values { "quot" "a quotation" } }
-{ $description "Runs a quotation. Throws an error if the total number of elements on the stack is not the same before and after the quotation runs." } ;
index 893078fb39d3c71903d6de0328e5dda49da799af..6edec815da18e18c460578e5a983eeca8f6077fd 100644 (file)
@@ -45,7 +45,7 @@ ERROR: no-cond ;
     [ rot \ if 3array append [ ] like ] assoc-each ;
 
 : cond>quot ( assoc -- quot )
-    [ dup callable? [ [ t ] swap 2array ] when ] map
+    [ dup pair? [ [ t ] swap 2array ] unless ] map
     reverse [ no-cond ] swap alist>quot ;
 
 ! case
@@ -134,22 +134,6 @@ ERROR: no-case ;
         [ drop linear-case-quot ]
     } cond ;
 
-! assert-depth
-: trim-datastacks ( seq1 seq2 -- seq1' seq2' )
-    2dup [ length ] bi@ min tuck [ tail ] 2bi@ ;
-
-ERROR: relative-underflow stack ;
-
-ERROR: relative-overflow stack ;
-
-: assert-depth ( quot -- )
-    [ datastack ] dip dip [ datastack ] dip
-    2dup [ length ] compare {
-        { +lt+ [ trim-datastacks nip relative-underflow ] }
-        { +eq+ [ 2drop ] }
-        { +gt+ [ trim-datastacks drop relative-overflow ] }
-    } case ; inline
-
 ! recursive-hashcode
 : recursive-hashcode ( n obj quot -- code )
     pick 0 <= [ 3drop 0 ] [ rot 1- -rot call ] if ; inline
index 7a22306c50279368a336ddc5a1ede247648113a4..363248216281cc009a825933b18bb82576dd9fb9 100644 (file)
@@ -79,9 +79,11 @@ $nl
 { $subsection continue-with }
 "Continuations as control-flow:"
 { $subsection attempt-all }
+{ $subsection retry }
 { $subsection with-return }
 "Reflecting the datastack:"
 { $subsection with-datastack }
+{ $subsection assert-depth }
 "Continuations serve as the building block for a number of higher-level abstractions, such as " { $link "errors" } " and " { $link "threads" } "."
 { $subsection "continuations.private" } ;
 
@@ -215,6 +217,10 @@ HELP: with-datastack
     { $example "USING: continuations math prettyprint ;" "{ 3 7 } [ + ] with-datastack ." "{ 10 }" }
 } ;
 
+HELP: assert-depth
+{ $values { "quot" "a quotation" } }
+{ $description "Runs a quotation. Throws an error if the quotation attempts to take input values from the stack, or leave outputs on the stack." } ;
+
 HELP: <continuation>
 { $description "Constructs a new continuation." }
 { $notes "User code should call " { $link continuation } " instead." } ;
@@ -237,6 +243,20 @@ HELP: attempt-all
     }
 } ;
 
+HELP: retry
+{ $values
+     { "quot" quotation } { "n" null }
+}
+{ $description "Tries the quotation up to " { $snippet "n" } " times until it returns true. Retries the quotation if an exception is thrown or if the quotation returns " { $link f } ". The quotation is expected to have side effects that may fail, such as generating a random name for a new file until successful." }
+{ $examples
+    { $unchecked-example "USING: continuations math prettyprint ;"
+        "[ 5 random 0 = ] retry t"
+        "t"
+    }
+} ;
+
+{ attempt-all retry } related-words
+
 HELP: return
 { $description "Returns early from a quotation by reifying the continuation captured by " { $link with-return } " ; execution is resumed starting immediately after " { $link with-return } "." } ;
 
index af8cda37c69cfb655e98d59b732ec29f63eb1ff7..c7056856b601c70143af297b64977cb689fdf61a 100644 (file)
@@ -114,6 +114,9 @@ SYMBOL: return-continuation
         ] 3 (throw)
     ] callcc1 2nip ;
 
+: assert-depth ( quot -- )
+    { } swap with-datastack { } assert= ; inline
+
 GENERIC: compute-restarts ( error -- seq )
 
 <PRIVATE
@@ -154,6 +157,8 @@ ERROR: attempt-all-error ;
         ] { } make peek swap [ rethrow ] when
     ] if ; inline
 
+: retry ( quot: ( -- ? )  n -- ) swap [ drop ] prepose attempt-all ; inline
+
 TUPLE: condition error restarts continuation ;
 
 C: <condition> condition ( error restarts cc -- condition )
index 0c082477c700df893d7292df9d821a16855f60ac..db6b2461b53653ab228ba98051e27b5ccb4bc338 100644 (file)
@@ -26,7 +26,7 @@ GENERIC: effect>string ( obj -- str )
 M: string effect>string ;
 M: word effect>string name>> ;
 M: integer effect>string number>string ;
-M: pair effect>string first2 [ effect>string ] bi@ ": " swap 3append ;
+M: pair effect>string first2 [ effect>string ] bi@ ": " glue ;
 
 : stack-picture ( seq -- string )
     dup integer? [ "object" <repetition> ] when
index 35029a3fb0976e34dba5bba8424da45bb61135e7..429e27264705dabb9f404f821a2558dc79a84d66 100644 (file)
@@ -165,3 +165,19 @@ HELP: (call-next-method)
 { $values { "method" method-body } }
 { $description "Low-level word implementing " { $link POSTPONE: call-next-method } "." }
 { $notes "In most cases, " { $link POSTPONE: call-next-method } " should be used instead." } ;
+
+HELP: no-next-method
+{ $error-description "Thrown by " { $link POSTPONE: call-next-method } " if the current method is already the least specific method." }
+{ $examples
+    "The following code throws this error:"
+    { $code
+        "GENERIC: error-test ( object -- )"
+        ""
+        "M: number error-test 3 + call-next-method ;"
+        ""
+        "M: integer error-test recip call-next-method ;"
+        ""
+        "123 error-test"
+    }
+    "This results in the method on " { $link integer } " being called, which then calls the method on " { $link number } ". The latter then calls " { $link POSTPONE: call-next-method } ", however there is no method less specific than the method on " { $link number } " and so an error is thrown."
+} ;
index 8d7ed4cb600cf1df616227d441c42281be29b356..4eb39291a05cf04f6d1c1cd294e1add41f244720 100644 (file)
@@ -58,8 +58,10 @@ GENERIC: next-method-quot* ( class generic combination -- quot )
         ] bi next-method-quot*
     ] cache ;
 
+ERROR: no-next-method method ;
+
 : (call-next-method) ( method -- )
-    next-method-quot call ;
+    dup next-method-quot [ call ] [ no-next-method ] ?if ;
 
 TUPLE: check-method class generic ;
 
@@ -75,7 +77,7 @@ TUPLE: check-method class generic ;
     3tri ; inline
 
 : method-word-name ( class word -- string )
-    [ name>> ] bi@ "=>" swap 3append ;
+    [ name>> ] bi@ "=>" glue ;
 
 PREDICATE: method-body < word
     "method-generic" word-prop >boolean ;
index da5d4f9eedd40e0629aff10eef96a08249d89a04..4323f91bc3dfe46659c3b6d8058af21b9c8f065c 100644 (file)
@@ -15,7 +15,7 @@ HELP: no-math-method
 HELP: math-method
 { $values { "word" generic } { "class1" class } { "class2" class } { "quot" quotation } }
 { $description "Generates a definition for " { $snippet "word" } " when the two inputs are instances of " { $snippet "class1" } " and " { $snippet "class2" } ", respectively." }
-{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ [ >float ] dip float=>+ ]" } } ;
+{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip float=>+ ]" } } ;
 
 HELP: math-class
 { $class-description "The class of subtypes of " { $link number } " which are not " { $link null } "." } ;
index 0c7bb2d8e8dbeb122aef81db283adda6fd717245..63043b50b9061d5cf66d5a2511a877028bb48329 100644 (file)
@@ -56,9 +56,11 @@ ERROR: no-math-method left right generic ;
 
 : math-method ( word class1 class2 -- quot )
     2dup and [
-        2dup math-upgrade
-        [ math-class-max over order min-class applicable-method ] dip
-        prepend
+        [
+            2dup 2array , \ declare ,
+            2dup math-upgrade %
+            math-class-max over order min-class applicable-method %
+        ] [ ] make
     ] [
         2drop object-method
     ] if ;
@@ -67,13 +69,9 @@ SYMBOL: picker
 
 : math-vtable ( picker quot -- quot )
     [
-        swap picker set
-        picker get , [ tag 0 eq? ] %
-        num-tags get swap [ bootstrap-type>class ] prepose map
-        unclip ,
-        [
-            picker get , [ tag 1 fixnum-fast ] % , \ dispatch ,
-        ] [ ] make , \ if ,
+        [ , \ tag , ]
+        [ num-tags get swap [ bootstrap-type>class ] prepose map , ] bi*
+        \ dispatch ,
     ] [ ] make ; inline
 
 TUPLE: math-combination ;
@@ -84,13 +82,18 @@ M: math-combination make-default-method
 M: math-combination perform-combination
     drop
     dup
-    \ over [
-        dup math-class? [
-            \ dup [ [ 2dup ] dip math-method ] math-vtable
-        ] [
-            over object-method
-        ] if nip
-    ] math-vtable nip define ;
+    [
+        [ 2dup both-fixnums? ] %
+        dup fixnum bootstrap-word dup math-method ,
+        \ over [
+            dup math-class? [
+                \ dup [ [ 2dup ] dip math-method ] math-vtable
+            ] [
+                over object-method
+            ] if nip
+        ] math-vtable nip ,
+        \ if ,
+    ] [ ] make define ;
 
 PREDICATE: math-generic < generic ( word -- ? )
     "combination" word-prop math-combination? ;
index c6420164d2bc83d084ce354c3d3c729cbd0ec8c3..0852459c34101c26cf1f891af5b9e49a64cd4f16 100644 (file)
@@ -16,7 +16,7 @@ ERROR: not-in-a-method-error ;
 SYMBOL: current-method
 
 : with-method-definition ( method quot -- )
-    [ dup current-method ] dip with-variable ; inline
+    over current-method set call current-method off ; inline
 
 : (M:) ( method def -- )
     CREATE-METHOD [ parse-definition ] with-method-definition ;
index dbdc6e0742b94fe76c4d3bacfa92bcf48de45162..5ed33009c099d37106c9d258ad092f0cad377705 100644 (file)
@@ -3,7 +3,7 @@
 USING: classes.private generic.standard.engines namespaces make
 arrays assocs sequences.private quotations kernel.private
 math slots.private math.private kernel accessors words
-layouts sorting sequences ;
+layouts sorting sequences combinators ;
 IN: generic.standard.engines.tag
 
 TUPLE: lo-tag-dispatch-engine methods ;
@@ -24,15 +24,21 @@ C: <lo-tag-dispatch-engine> lo-tag-dispatch-engine
 
 : sort-tags ( assoc -- alist ) >alist sort-keys reverse ;
 
+: tag-dispatch-test ( tag# -- quot )
+    picker [ tag ] append swap [ eq? ] curry append ;
+
+: tag-dispatch-quot ( alist -- quot )
+    [ default get ] dip
+    [ [ tag-dispatch-test ] dip ] assoc-map
+    alist>quot ;
+
 M: lo-tag-dispatch-engine engine>quot
     methods>> engines>quots*
     [ [ lo-tag-number ] dip ] assoc-map
     [
-        picker % [ tag ] % [
-            sort-tags linear-dispatch-quot
-        ] [
-            num-tags get direct-dispatch-quot
-        ] if-small? %
+        [ sort-tags tag-dispatch-quot ]
+        [ picker % [ tag ] % num-tags get direct-dispatch-quot ]
+        if-small? %
     ] [ ] make ;
 
 TUPLE: hi-tag-dispatch-engine methods ;
index 15913b46bee1bf6d4579011eaf4d289f6fd2eef6..ec2e78c48d17c8bf33f9cd64342ff7e2137f025e 100644 (file)
@@ -33,22 +33,6 @@ HELP: define-simple-generic
 
 { standard-combination hook-combination } related-words
 
-HELP: no-next-method
-{ $error-description "Thrown by " { $link POSTPONE: call-next-method } " if the current method is already the least specific method." }
-{ $examples
-    "The following code throws this error:"
-    { $code
-        "GENERIC: error-test ( object -- )"
-        ""
-        "M: number error-test 3 + call-next-method ;"
-        ""
-        "M: integer error-test recip call-next-method ;"
-        ""
-        "123 error-test"
-    }
-    "This results in the method on " { $link integer } " being called, which then calls the method on " { $link number } ". The latter then calls " { $link POSTPONE: call-next-method } ", however there is no method less specific than the method on " { $link number } " and so an error is thrown."
-} ;
-
 HELP: inconsistent-next-method
 { $error-description "Thrown by " { $link POSTPONE: call-next-method } " if the values on the stack are not compatible with the current method." }
 { $examples
index f6635276b36c26a1b06845330aa5f5c9a1c12783..f5f8f85376794470401b94317cfc5eda4031c71b 100644 (file)
@@ -1,10 +1,10 @@
 IN: generic.standard.tests
 USING: tools.test math math.functions math.constants
-generic.standard strings sequences arrays kernel accessors
-words float-arrays byte-arrays bit-arrays parser namespaces make
-quotations stack-checker vectors growable hashtables sbufs
-prettyprint byte-vectors bit-vectors float-vectors definitions
-generic sets graphs assocs ;
+generic.standard strings sequences arrays kernel accessors words
+specialized-arrays.double byte-arrays bit-arrays parser
+namespaces make quotations stack-checker vectors growable
+hashtables sbufs prettyprint byte-vectors bit-vectors
+specialized-vectors.double definitions generic sets graphs assocs ;
 
 GENERIC: lo-tag-test ( obj -- obj' )
 
@@ -110,14 +110,14 @@ M: circle big-mix-test drop "circle" ;
 [ "integer" ] [ 3 big-mix-test ] unit-test
 [ "float" ] [ 5.0 big-mix-test ] unit-test
 [ "complex" ] [ -1 sqrt big-mix-test ] unit-test
-[ "sequence" ] [ F{ 1.0 2.0 3.0 } big-mix-test ] unit-test
+[ "sequence" ] [ double-array{ 1.0 2.0 3.0 } big-mix-test ] unit-test
 [ "sequence" ] [ B{ 1 2 3 } big-mix-test ] unit-test
 [ "sequence" ] [ ?{ t f t } big-mix-test ] unit-test
 [ "sequence" ] [ SBUF" hello world" big-mix-test ] unit-test
 [ "sequence" ] [ V{ "a" "b" } big-mix-test ] unit-test
 [ "sequence" ] [ BV{ 1 2 } big-mix-test ] unit-test
 [ "sequence" ] [ ?V{ t t f f } big-mix-test ] unit-test
-[ "sequence" ] [ FV{ -0.3 4.6 } big-mix-test ] unit-test
+[ "sequence" ] [ double-vector{ -0.3 4.6 } big-mix-test ] unit-test
 [ "string" ] [ "hello" big-mix-test ] unit-test
 [ "rectangle" ] [ 1 2 <rectangle> big-mix-test ] unit-test
 [ "parallelogram" ] [ 10 4 3 <parallelogram> big-mix-test ] unit-test
@@ -133,13 +133,13 @@ M: string small-lo-tag drop "string" ;
 
 M: array small-lo-tag drop "array" ;
 
-M: float-array small-lo-tag drop "float-array" ;
+M: double-array small-lo-tag drop "double-array" ;
 
 M: byte-array small-lo-tag drop "byte-array" ;
 
 [ "fixnum" ] [ 3 small-lo-tag ] unit-test
 
-[ "float-array" ] [ F{ 1.0 } small-lo-tag ] unit-test
+[ "double-array" ] [ double-array{ 1.0 } small-lo-tag ] unit-test
 
 ! Testing next-method
 TUPLE: person ;
@@ -200,7 +200,7 @@ M: ceo salary
 [ T{ inconsistent-next-method f ceo salary } = ] must-fail-with
 
 [ intern boa salary ]
-[ T{ no-next-method f intern salary } = ] must-fail-with
+[ no-next-method? ] must-fail-with
 
 ! Weird shit
 TUPLE: a ;
index 4f26c40e7807f3518c6796c062b055b6eed73929..300bd44fb4abca12ae175cbba52b5fdfd9a2f9f5 100644 (file)
@@ -79,20 +79,15 @@ ERROR: no-method object generic ;
 
 ERROR: inconsistent-next-method class generic ;
 
-ERROR: no-next-method class generic ;
-
-: single-next-method-quot ( class generic -- quot )
-    [
-        [ drop "predicate" word-prop % ]
+: single-next-method-quot ( class generic -- quot/f )
+    2dup next-method dup [
         [
-            2dup next-method
-            [ 2nip 1quotation ]
-            [ [ no-next-method ] 2curry [ ] like ] if* ,
-        ]
-        [ [ inconsistent-next-method ] 2curry , ]
-        2tri
-        \ if ,
-    ] [ ] make ;
+            pick "predicate" word-prop %
+            1quotation ,
+            [ inconsistent-next-method ] 2curry ,
+            \ if ,
+        ] [ ] make
+    ] [ 3drop f ] if ;
 
 : single-effective-method ( obj word -- method )
     [ [ order [ instance? ] with find-last nip ] keep method ]
@@ -130,7 +125,8 @@ M: standard-combination method-declaration
 
 M: standard-combination next-method-quot*
     [
-        single-next-method-quot picker prepend
+        single-next-method-quot
+        dup [ picker prepend ] when
     ] with-standard ;
 
 M: standard-generic effective-method
@@ -145,9 +141,12 @@ PREDICATE: hook-generic < generic
 
 : with-hook ( combination quot -- quot' )
     0 (dispatch#) [
-        dip var>> [ get ] curry prepend
+        [ hook-combination ] dip with-variable
     ] with-variable ; inline
 
+: prepend-hook-var ( quot -- quot' )
+    hook-combination get var>> [ get ] curry prepend ;
+
 M: hook-combination dispatch# drop 0 ;
 
 M: hook-combination method-declaration 2drop [ ] ;
@@ -159,13 +158,18 @@ M: hook-generic effective-method
     single-effective-method ;
 
 M: hook-combination make-default-method
-    [ error-method ] with-hook ;
+    [ error-method prepend-hook-var ] with-hook ;
 
 M: hook-combination perform-combination
-    [ drop ] [ [ single-combination ] with-hook ] 2bi define ;
+    [ drop ] [
+        [ single-combination prepend-hook-var ] with-hook
+    ] 2bi define ;
 
 M: hook-combination next-method-quot*
-    [ single-next-method-quot ] with-hook ;
+    [
+        single-next-method-quot
+        dup [ prepend-hook-var ] when
+    ] with-hook ;
 
 M: simple-generic definer drop \ GENERIC: f ;
 
index 474cf4c9d60b40b65ed3733ae53e487077a71987..8663f25a7032ba919833130355f5ff6f77486bfc 100644 (file)
@@ -40,7 +40,7 @@ TUPLE: hashtable
     0 >>count 0 >>deleted drop ; inline
 
 : reset-hash ( n hash -- )
-    swap <hash-array> >>array init-hash ;
+    swap <hash-array> >>array init-hash ; inline
 
 : (new-key@) ( key keys i -- keys n empty? )
     3dup swap array-nth dup ((empty)) eq? [
@@ -133,7 +133,7 @@ M: hashtable set-at ( value key hash -- )
 : push-unsafe ( elt seq -- )
     [ length ] keep
     [ underlying>> set-array-nth ]
-    [ [ 1+ ] dip (>>length) ]
+    [ [ 1 fixnum+fast { array-capacity } declare ] dip (>>length) ]
     2bi ; inline
 
 PRIVATE>
index 0c13277106f3f98f5c9473ce666e4620fb14ae33..5456f2251ca61cfe782f10393dd2236fe9cb2fa5 100644 (file)
@@ -8,7 +8,7 @@ SYMBOL: io-backend
 
 SINGLETON: c-io-backend
 
-c-io-backend io-backend set-global
+io-backend global [ c-io-backend or ] change-at
 
 HOOK: init-io io-backend ( -- )
 
@@ -20,7 +20,7 @@ HOOK: (init-stdio) io-backend ( -- stdin stdout stderr )
     [ utf8 <encoder> output-stream set-global ]
     [ utf8 <encoder> error-stream set-global ] tri* ;
 
-HOOK: io-multiplex io-backend ( ms -- )
+HOOK: io-multiplex io-backend ( us -- )
 
 HOOK: normalize-directory io-backend ( str -- newstr )
 
index ba25e7950921ef7cda3e4e08a0332bbf9dcfbadc..b893e7f717cef7fdf6cd2a43cc8504ff5364c173 100644 (file)
@@ -1,21 +1,6 @@
-USING: help.markup help.syntax ;
+USING: help.markup help.syntax io quotations ;
 IN: io.encodings
 
-ABOUT: "io.encodings"
-
-ARTICLE: "io.encodings" "I/O encodings"
-"Bytes can't be understood in isolation as text. They must be interpreted under a certain encoding. Factor provides utilities for dealing with encoded text by declaring that a stream has a particular encoding, and utilities to encode and decode strings."
-{ $subsection "encodings-descriptors" }
-{ $subsection "encodings-constructors" }
-{ $subsection "io.encodings.string" }
-"New types of encodings can be defined:"
-{ $subsection "encodings-protocol" } ;
-
-ARTICLE: "encodings-constructors" "Manually constructing an encoded stream"
-"The following words can be used to construct encoded streams. Note that they are usually not used directly, but rather by the stream constructors themselves. Most stream constructors take an encoding descriptor as a parameter and internally call these constructors."
-{ $subsection <encoder> }
-{ $subsection <decoder> } ;
-
 HELP: <encoder>
 { $values { "stream" "an output stream" }
     { "encoding" "an encoding descriptor" }
@@ -30,8 +15,66 @@ HELP: <decoder>
 { $description "Wraps the given stream in a new stream using the given encoding for all input. The encoding descriptor can either be a class or an instance of something conforming to the " { $link "encodings-protocol" } "." }
 $low-level-note ;
 
+HELP: decode-char
+{ $values { "stream" "an underlying input stream" }
+    { "encoding" "An encoding descriptor tuple" } { "char/f" "a code point or " { $link f } } }
+{ $contract "Reads a single code point from the underlying stream, interpreting it by the encoding. Returns " { $link f } " if the stream is reached." }
+$low-level-note ;
+
+HELP: encode-char
+{ $values { "char" "a character" }
+    { "stream" "an underlying output stream" }
+    { "encoding" "an encoding descriptor" } }
+{ $contract "Writes the code point to the underlying stream in the given encoding." }
+$low-level-note ;
+
+{ encode-char decode-char } related-words
+
+HELP: decode-input
+{ $values
+     { "encoding" "an encoding descriptor" }
+}
+{ $description "Changes the encoding of the current input stream stored in the " { $link input-stream } " variable." } ;
+
+HELP: encode-output
+{ $values
+     { "encoding" "an encoding descriptor" }
+}
+{ $description "Changes the encoding of the current output stream stored in the " { $link output-stream } " variable." } ;
+
+HELP: re-decode
+{ $values
+     { "stream" "a stream" } { "encoding" "an encoding descriptor" }
+     { "newstream" "a new stream" }
+}
+{ $description "Creates a new decoding stream with the supplied encoding descriptor from an existing stream by calling the " { $link <decoder> } " word." } ;
+
+HELP: re-encode
+{ $values
+     { "stream" "a stream" } { "encoding" "an encoding descriptor" }
+     { "newstream" "a new stream" }
+}
+{ $description "Creates a new encoding stream with the supplied encoding descriptor from an existing stream by calling the " { $link <encoder> } " word." } ;
+
+{ re-decode re-encode } related-words
+
+HELP: with-decoded-input
+{ $values
+     { "encoding" "an encoding descriptor" } { "quot" quotation }
+}
+{ $description "Creates a new decoding stream with the given encoding descriptor and calls the quotation with this stream set to the " { $link input-stream } " variable. The original decoder stream is restored after the quotation returns and the stream is kept open for future input operations." } ;
+
+HELP: with-encoded-output
+{ $values
+     { "encoding" "an encoding descriptor" } { "quot" quotation }
+}
+{ $description "Creates a new encoder with the given encoding descriptor and calls the quotation using this encoder. The original encoder object is restored after the quotation returns and the stream is kept open for future output operations." } ;
+
+HELP: replacement-char
+{ $description "A code point that replaces input that could not be decoded. The presence of this character in the decoded data usually signifies an error." } ;
+
 ARTICLE: "encodings-descriptors" "Encoding descriptors"
-"An encoding descriptor is something which can be used for input or output streams to encode or decode files. It must conform to the " { $link "encodings-protocol" } ". Encodings which you can use are defined in the following vocabularies:"
+"An encoding descriptor is something which can be used for input or output streams to encode or decode bytes stored in a certain representation. It must conform to the " { $link "encodings-protocol" } ". Encodings which you can use are defined in the following vocabularies:"
 { $subsection "io.encodings.binary" }
 { $subsection "io.encodings.utf8" }
 { $subsection "io.encodings.utf16" }
@@ -50,17 +93,26 @@ ARTICLE: "encodings-protocol" "Encoding protocol"
 { $subsection encode-char }
 { $see-also "encodings-introduction" } ;
 
-HELP: decode-char
-{ $values { "stream" "an underlying input stream" }
-    { "encoding" "An encoding descriptor tuple" } { "char/f" "a code point or " { $link f } } }
-{ $contract "Reads a single code point from the underlying stream, interpreting it by the encoding." }
-$low-level-note ;
+ARTICLE: "encodings-constructors" "Manually constructing an encoded stream"
+"The following words can be used to construct encoded streams. Note that they are usually not used directly, but rather by the stream constructors themselves. Most stream constructors take an encoding descriptor as a parameter and call these constructors internally."
+{ $subsection <encoder> }
+{ $subsection <decoder> } ;
 
-HELP: encode-char
-{ $values { "char" "a character" }
-    { "stream" "an underlying output stream" }
-    { "encoding" "an encoding descriptor" } }
-{ $contract "Writes the code point in the encoding to the underlying stream given." }
-$low-level-note ;
+ARTICLE: "io.encodings" "I/O encodings"
+"The " { $vocab-link "io.encodings" } " vocabulary provides utilities for encoding and decoding bytes that represent text. Both strings and streams may be encoded."
+{ $subsection "encodings-descriptors" }
+{ $subsection "encodings-constructors" }
+{ $subsection "io.encodings.string" }
+"New types of encodings can be defined:"
+{ $subsection "encodings-protocol" }
+"Setting encodings on the current streams:"
+{ $subsection encode-output }
+{ $subsection decode-input }
+"Setting encodings on streams:"
+{ $subsection re-encode }
+{ $subsection re-decode }
+"Combinators to change the encoding:"
+{ $subsection with-encoded-output }
+{ $subsection with-decoded-input } ;
 
-{ encode-char decode-char } related-words
+ABOUT: "io.encodings"
index 3104fcdb55b1b9aa755fa71a8569e7df7ea20048..4299634642f3b8f3cc06c103cdebb71bef342d2e 100644 (file)
@@ -283,3 +283,6 @@ USE: debugger.threads
     [ "resource:core/bootstrap/stage2.factor" (normalize-path) ]
     unit-test
 ] with-scope
+
+[ t ] [ "/" file-system-info file-system-info? ] unit-test
+[ t ] [ file-systems [ file-system-info? ] all? ] unit-test
index 7c7a2ece313cecfcac346e0bbbfa54a6839fc5bb..77b37180c63aadf79a5f577484f48fd9ad01e368 100644 (file)
@@ -187,7 +187,8 @@ SYMBOL: +unknown+
 
 HOOK: file-systems os ( -- array )
 
-TUPLE: file-system-info device-name mount-point type free-space ;
+TUPLE: file-system-info device-name mount-point type
+available-space free-space used-space total-space ;
 
 HOOK: file-system-info os ( path -- file-system-info )
 
index 43f66657a7d3dc3ad0d61302b26bff5a005d404f..02af963e1a1d13e9b7708026132c840982fca182 100644 (file)
@@ -114,6 +114,9 @@ HELP: input-stream
 HELP: output-stream
 { $var-description "Holds an output stream for various implicit stream operations. Rebound using " { $link with-output-stream } " and " { $link with-output-stream* } "." } ;
 
+HELP: error-stream
+{ $var-description "Holds an error stream." } ;
+
 HELP: readln
 { $values { "str/f" "a string or " { $link f } } }
 { $description "Reads a line of input from " { $link input-stream } ". Outputs " { $link f } " on stream exhaustion." }
@@ -250,6 +253,10 @@ HELP: lines
 { $values { "stream" "an input stream" } { "seq" "a sequence of strings" } }
 { $description "Reads lines of text until the stream is exhausted, collecting them in a sequence of strings." } ;
 
+HELP: each-line
+{ $values { "quot" { $quotation "( str -- )" } } }
+{ $description "Calls the quotatin with successive lines of text, until the current " { $link input-stream } " is exhausted." } ;
+
 HELP: contents
 { $values { "stream" "an input stream" } { "str" string } }
 { $description "Reads the entire contents of a stream into a string." }
@@ -361,6 +368,8 @@ ARTICLE: "stream-utils" "Stream utilities"
 $nl
 "First, a simple composition of " { $link stream-write } " and " { $link stream-nl } ":"
 { $subsection stream-print }
+"Processing lines one by one:"
+{ $subsection each-line }
 "Sluring an entire stream into memory all at once:"
 { $subsection lines }
 { $subsection contents }
index d7d4edf49ff1656c56457069e989dd510155f2eb..c1fd69a16af006791a1e95eb07473ae0987589c2 100644 (file)
@@ -99,6 +99,9 @@ SYMBOL: error-stream
 : lines ( stream -- seq )
     [ [ readln dup ] [ ] [ drop ] produce ] with-input-stream ;
 
+: each-line ( quot -- )
+    [ [ readln dup ] ] dip [ drop ] while ; inline
+
 : contents ( stream -- str )
     [
         [ 65536 read dup ] [ ] [ drop ] produce concat f like
index 6c640bbdeb211b94a585911177eb66694a849d37..a579153353a1032f60d917bbf6276a3450957b3b 100644 (file)
@@ -61,13 +61,13 @@ HELP: fread ( n alien -- str/f )
 { $errors "Throws an error if the input operation failed." } ;
 
 HELP: stdin-handle
-{ $values { "in" "a C FILE* handle" } }
+{ $values { "alien" "a C FILE* handle" } }
 { $description "Outputs the console standard input file handle." } ;
 
 HELP: stdout-handle
-{ $values { "out" "a C FILE* handle" } }
+{ $values { "alien" "a C FILE* handle" } }
 { $description "Outputs the console standard output file handle." } ;
 
 HELP: stderr-handle
-{ $values { "out" "a C FILE* handle" } }
+{ $values { "alien" "a C FILE* handle" } }
 { $description "Outputs the console standard error file handle." } ;
index 47e19d2c40360e1b56f3dfcd62ee6d7940b0daa7..71c9ffd7d9a4e097d147bb2fadc1c35775cf9854 100755 (executable)
@@ -56,9 +56,9 @@ M: c-reader dispose*
 
 M: c-io-backend init-io ;
 
-: stdin-handle 11 getenv ;
-: stdout-handle 12 getenv ;
-: stderr-handle 61 getenv ;
+: stdin-handle ( -- alien ) 11 getenv ;
+: stdout-handle ( -- alien ) 12 getenv ;
+: stderr-handle ( -- alien ) 61 getenv ;
 
 : init-c-stdio ( -- stdin stdout stderr )
     stdin-handle <c-reader>
index 31798c92957908b965d323325616a3a1e7dfd931..01ef8d480da6071fdcd162ac79fbefa561519d94 100644 (file)
@@ -205,18 +205,18 @@ HELP: 3slip
 { $description "Calls a quotation while hiding the top three stack elements." } ;
 
 HELP: keep
-{ $values { "quot" { $quotation "( x -- )" } } { "x" object } }
+{ $values { "quot" { $quotation "( x -- ... )" } } { "x" object } }
 { $description "Call a quotation with a value on the stack, restoring the value when the quotation returns." }
 { $examples
     { $example "USING: arrays kernel prettyprint ;" "2 \"greetings\" [ <array> ] keep 2array ." "{ { \"greetings\" \"greetings\" } \"greetings\" }" }
 } ;
 
 HELP: 2keep
-{ $values { "quot" { $quotation "( x y -- )" } } { "x" object } { "y" object } }
+{ $values { "quot" { $quotation "( x y -- ... )" } } { "x" object } { "y" object } }
 { $description "Call a quotation with two values on the stack, restoring the values when the quotation returns." } ;
 
 HELP: 3keep
-{ $values { "quot" { $quotation "( x y z -- )" } } { "x" object } { "y" object } { "z" object } }
+{ $values { "quot" { $quotation "( x y z -- ... )" } } { "x" object } { "y" object } { "z" object } }
 { $description "Call a quotation with three values on the stack, restoring the values when the quotation returns." } ;
 
 HELP: bi
@@ -371,7 +371,7 @@ HELP: tri*
 } ;
 
 HELP: bi@
-{ $values { "x" object } { "y" object } { "quot" { $quotation "( obj -- )" } } }
+{ $values { "x" object } { "y" object } { "quot" { $quotation "( obj -- ... )" } } }
 { $description "Applies the quotation to " { $snippet "x" } ", then to " { $snippet "y" } "." }
 { $examples
     "The following two lines are equivalent:"
@@ -387,7 +387,7 @@ HELP: bi@
 } ;
 
 HELP: 2bi@
-{ $values { "w" object } { "x" object } { "y" object } { "z" object } { "quot" { $quotation "( obj1 obj2 -- )" } } }
+{ $values { "w" object } { "x" object } { "y" object } { "z" object } { "quot" { $quotation "( obj1 obj2 -- ... )" } } }
 { $description "Applies the quotation to " { $snippet "w" } " and " { $snippet "x" } ", then to " { $snippet "y" } " and " { $snippet "z" } "." }
 { $examples
     "The following two lines are equivalent:"
@@ -403,7 +403,7 @@ HELP: 2bi@
 } ;
 
 HELP: tri@
-{ $values { "x" object } { "y" object } { "z" object } { "quot" { $quotation "( obj -- )" } } }
+{ $values { "x" object } { "y" object } { "z" object } { "quot" { $quotation "( obj -- ... )" } } }
 { $description "Applies the quotation to " { $snippet "x" } ", then to " { $snippet "y" } ", and finally to " { $snippet "z" } "." }
 { $examples
     "The following two lines are equivalent:"
@@ -437,7 +437,7 @@ $nl
 "The " { $snippet "cond" } " value is removed from the stack before the quotation is called." } ;
 
 HELP: if*
-{ $values { "?" "a generalized boolean" } { "true" { $quotation "( cond -- )" } } { "false" quotation } }
+{ $values { "?" "a generalized boolean" } { "true" { $quotation "( cond -- ... )" } } { "false" quotation } }
 { $description "Alternative conditional form that preserves the " { $snippet "cond" } " value if it is true."
 $nl
 "If the condition is true, it is retained on the stack before the " { $snippet "true" } " quotation is called. Otherwise, the condition is removed from the stack and the " { $snippet "false" } " quotation is called."
@@ -446,7 +446,7 @@ $nl
 { $code "X [ Y ] [ Z ] if*" "X dup [ Y ] [ drop Z ] if" } } ;
 
 HELP: when*
-{ $values { "?" "a generalized boolean" } { "true" { $quotation "( cond -- )" } } }
+{ $values { "?" "a generalized boolean" } { "true" { $quotation "( cond -- ... )" } } }
 { $description "Variant of " { $link if* } " with no false quotation."
 $nl
 "The following two lines are equivalent:"
@@ -460,7 +460,7 @@ HELP: unless*
 { $code "X [ Y ] unless*" "X dup [ ] [ drop Y ] if" } } ;
 
 HELP: ?if
-{ $values { "default" object } { "cond" "a generalized boolean" } { "true" { $quotation "( cond -- )" } } { "false" { $quotation "( default -- )" } } }
+{ $values { "default" object } { "cond" "a generalized boolean" } { "true" { $quotation "( cond -- ... )" } } { "false" { $quotation "( default -- ... )" } } }
 { $description "If the condition is " { $link f } ", the " { $snippet "false" } " quotation is called with the " { $snippet "default" } " value on the stack. Otherwise, the " { $snippet "true" } " quotation is called with the condition on the stack." }
 { $notes
 "The following two lines are equivalent:"
@@ -578,18 +578,6 @@ HELP: prepose
 
 { compose prepose } related-words
 
-HELP: 3compose
-{ $values { "quot1" callable } { "quot2" callable } { "quot3" callable } { "compose" compose } }
-{ $description "Quotation composition. Outputs a " { $link callable } " which calls " { $snippet "quot1" } ", " { $snippet "quot2" } " and then " { $snippet "quot3" } "." }
-{ $notes
-    "The following two lines are equivalent:"
-    { $code
-        "3compose call"
-        "3append call"
-    }
-    "However, " { $link 3compose } " runs in constant time, and the compiler is able to compile code which calls composed quotations."
-} ;
-
 HELP: dip
 { $values { "x" object } { "quot" quotation } }
 { $description "Calls " { $snippet "quot" } " with " { $snippet "obj" } " hidden on the retain stack." }
@@ -599,7 +587,7 @@ HELP: dip
 
 HELP: 2dip
 { $values { "x" object } { "y" object } { "quot" quotation } }
-{ $description "Calls " { $snippet "quot" } " with " { $snippet "obj1" } " and " { $snippet "obj2" } " hidden on the retain stack." }
+{ $description "Calls " { $snippet "quot" } " with " { $snippet "x" } " and " { $snippet "y" } " hidden on the retain stack." }
 { $notes "The following are equivalent:"
     { $code "[ [ foo bar ] dip ] dip" }
     { $code "[ foo bar ] 2dip" }
@@ -770,12 +758,10 @@ $nl
 "Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:"
 { $code
     "! First alternative; uses dip"
-    "[ [ 1 + ] dip 1 - dip ] 2 *"
+    "[ [ 1 + ] dip 1 - ] dip 2 *"
     "! Second alternative: uses tri*"
     "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
 }
-
-$nl
 "A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
 { $subsection "spread-shuffle-equivalence" } ;
 
@@ -814,7 +800,6 @@ ARTICLE: "compositional-combinators" "Compositional combinators"
 { $subsection 3curry }
 { $subsection with }
 { $subsection compose }
-{ $subsection 3compose }
 { $subsection prepose }
 "Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } "." ;
 
@@ -902,6 +887,11 @@ $nl
 "An object can be cloned; the clone has distinct identity but equal value:"
 { $subsection clone } ;
 
+ARTICLE: "assertions" "Assertions"
+"Some words to make assertions easier to enforce:"
+{ $subsection assert }
+{ $subsection assert= } ;
+
 ARTICLE: "dataflow" "Data and control flow"
 { $subsection "evaluator" }
 { $subsection "words" }
@@ -917,6 +907,7 @@ ARTICLE: "dataflow" "Data and control flow"
 { $subsection "compositional-combinators" }
 { $subsection "combinators" }
 "Advanced topics:"
+{ $subsection "assertions" }
 { $subsection "implementing-combinators" }
 { $subsection "errors" }
 { $subsection "continuations" } ;
index 6619d331f17ab8ea1e65ff1e48431b8236e703f3..320025b124d9fe91e5298ebf475e4750ae6e86c5 100644 (file)
@@ -1,7 +1,7 @@
 USING: arrays byte-arrays kernel kernel.private math memory
 namespaces sequences tools.test math.private quotations
 continuations prettyprint io.streams.string debugger assocs
-sequences.private ;
+sequences.private accessors ;
 IN: kernel.tests
 
 [ 0 ] [ f size ] unit-test
@@ -124,3 +124,42 @@ IN: kernel.tests
 [ [ sq ] tri@ ] must-infer
 
 [ 4 ] [ 1 { [ 1 ] [ 2 ] } dispatch sq ] unit-test
+
+! Test traceback accuracy
+: last-frame ( -- pair )
+    error-continuation get call>> callstack>array 4 head* 2 tail* ;
+
+[
+    { [ 1 2 [ 3 throw ] call 4 ] 3 }
+] [
+    [ [ 1 2 [ 3 throw ] call 4 ] call ] ignore-errors
+    last-frame
+] unit-test
+
+[
+    { [ 1 2 [ 3 throw ] dip 4 ] 3 }
+] [
+    [ [ 1 2 [ 3 throw ] dip 4 ] call ] ignore-errors
+    last-frame
+] unit-test
+
+[
+    { [ 1 2 3 throw [ ] call 4 ] 3 }
+] [
+    [ [ 1 2 3 throw [ ] call 4 ] call ] ignore-errors
+    last-frame
+] unit-test
+
+[
+    { [ 1 2 3 throw [ ] dip 4 ] 3 }
+] [
+    [ [ 1 2 3 throw [ ] dip 4 ] call ] ignore-errors
+    last-frame
+] unit-test
+
+[
+    { [ 1 2 3 throw [ ] [ ] if 4 ] 3 }
+] [
+    [ [ 1 2 3 throw [ ] [ ] if 4 ] call ] ignore-errors
+    last-frame
+] unit-test
index 1677a2faaac1e1d9cdc84320dd9cc30c209f5a03..564600d322bab63c3dd16fb3f62fdd56db3d6b75 100644 (file)
@@ -52,7 +52,9 @@ DEFER: if
 : ?if ( default cond true false -- )
     pick [ roll 2drop call ] [ 2nip call ] if ; inline
 
-! Slippers
+! Slippers and dippers.
+! Not declared inline because the compiler special-cases them
+
 : slip ( quot x -- x )
     #! 'slip' and 'dip' can be defined in terms of each other
     #! because the JIT special-cases a 'dip' preceeded by
@@ -71,11 +73,11 @@ DEFER: if
     #! a literal quotation.
     [ call ] 3dip ;
 
-: dip ( x quot -- x ) swap slip ; inline
+: dip ( x quot -- x ) swap slip ;
 
-: 2dip ( x y quot -- x y ) -rot 2slip ; inline
+: 2dip ( x y quot -- x y ) -rot 2slip ;
 
-: 3dip ( x y z quot -- x y z ) -roll 3slip ; inline
+: 3dip ( x y z quot -- x y z ) -roll 3slip ;
 
 ! Keepers
 : keep ( x quot -- x ) over slip ; inline
@@ -152,8 +154,11 @@ TUPLE: identity-tuple ;
 
 M: identity-tuple equal? 2drop f ;
 
+USE: math.private
 : = ( obj1 obj2 -- ? )
-    2dup eq? [ 2drop t ] [ equal? ] if ; inline
+    2dup eq? [ 2drop t ] [
+        2dup both-fixnums? [ 2drop f ] [ equal? ] if
+    ] if ; inline
 
 GENERIC: clone ( obj -- cloned )
 
@@ -179,9 +184,6 @@ GENERIC: boa ( ... class -- tuple )
 : prepose ( quot1 quot2 -- compose )
     swap compose ; inline
 
-: 3compose ( quot1 quot2 quot3 -- compose )
-    compose compose ; inline
-
 ! Booleans
 : not ( obj -- ? ) [ f ] [ t ] if ; inline
 
index a1ba16c68accef1d8383728d4c51acf189efb4f0..5549ef79e9d9a555e9bec518a92335cde9151b05 100644 (file)
@@ -6,7 +6,7 @@ ARTICLE: "floats" "Floats"
 "Rational numbers represent " { $emphasis "exact" } " quantities. On the other hand, a floating point number is an " { $emphasis "approximation" } ". While rationals can grow to any required precision, floating point numbers are fixed-width, and manipulating them is usually faster than manipulating ratios or bignums (but slower than manipulating fixnums). Floating point numbers are often used to represent irrational numbers, which have no exact representation as a ratio of two integers."
 $nl
 "Introducing a floating point number in a computation forces the result to be expressed in floating point."
-{ $example "5/4 1/2 + ." "7/4" }
+{ $example "5/4 1/2 + ." "1+3/4" }
 { $example "5/4 0.5 + ." "1.75" }
 "Integers and rationals can be converted to floats:"
 { $subsection >float }
index bd3f951b021ece159dbbc35c621d71764379c022..dbdd5b27fea356a65686a597fca1200f7d05caf3 100644 (file)
@@ -60,3 +60,5 @@ unit-test
 [ 0 ] [ 1/0. >bignum ] unit-test
 
 [ t ] [ 64 [ 2^ 0.5 * ] map [ < ] monotonic? ] unit-test
+
+[ 5 ] [ 10.5 1.9 /i ] unit-test
index 9dcff9eb90397a34324bbf69cc29eb08a5586bc6..2a22dc4330c12ebebe3b6c5cbc040401c6d59d51 100644 (file)
@@ -24,6 +24,7 @@ M: float - float- ;
 M: float * float* ;
 M: float / float/f ;
 M: float /f float/f ;
+M: float /i float/f >integer ;
 M: float mod float-mod ;
 
 M: real abs dup 0 < [ neg ] when ;
index fcb1b65d80c466bd4dc57fd1b1dd83dba39c81e7..910d394c559d951448d897085df2175ca0006250 100644 (file)
@@ -40,11 +40,13 @@ M: fixnum bitnot fixnum-bitnot ;
 
 M: fixnum bit? neg shift 1 bitand 0 > ;
 
-: (fixnum-log2) ( accum n -- accum )
-    dup 1 number= [ drop ] [ [ 1+ ] [ 2/ ] bi* (fixnum-log2) ] if ;
-    inline recursive
+: fixnum-log2 ( x -- n )
+    0 swap [ dup 1 number= not ] [ [ 1+ ] [ 2/ ] bi* ] [ ] while drop ;
 
-M: fixnum (log2) 0 swap (fixnum-log2) ;
+M: fixnum (log2) fixnum-log2 ;
+
+M: integer next-power-of-2
+    dup 2 <= [ drop 2 ] [ 1- log2 1+ 2^ ] if ;
 
 M: bignum >fixnum bignum>fixnum ;
 M: bignum >bignum ;
index aca43add5c4e163013f6313050d9d20262434d6b..3c2b7f67e2eecc618bdf01b3b77e5bc740f83fed 100644 (file)
@@ -166,15 +166,17 @@ HELP: log2
 HELP: 1+
 { $values { "x" number } { "y" number } }
 { $description
-    "Increments a number by 1. The following two lines are equivalent, but the first is more efficient:"
+    "Increments a number by 1. The following two lines are equivalent:"
     { $code "1+" "1 +" }
+    "There is no difference in behavior or efficiency."
 } ;
 
 HELP: 1-
 { $values { "x" number } { "y" number } }
 { $description
-    "Decrements a number by 1. The following two lines are equivalent, but the first is more efficient:"
+    "Decrements a number by 1. The following two lines are equivalent:"
     { $code "1-" "1 -" }
+    "There is no difference in behavior or efficiency."
 } ;
 
 HELP: ?1+
index 5c53d99cff566a31f604fd4ae81bedd58b899e30..8b064725d3710c169a1ba03825cce6b11213323b 100644 (file)
@@ -53,7 +53,7 @@ PRIVATE>
         "log2 expects positive inputs" throw
     ] [
         (log2)
-    ] if ; foldable
+    ] if ; inline
 
 : zero? ( x -- ? ) 0 number= ; inline
 : 1+ ( x -- y ) 1 + ; inline
@@ -103,14 +103,9 @@ M: float fp-infinity? ( float -- ? )
         drop f
     ] if ;
 
-: (next-power-of-2) ( i n -- n )
-    2dup >= [
-        drop
-    ] [
-        [ 1 shift ] dip (next-power-of-2)
-    ] if ;
+GENERIC: next-power-of-2 ( m -- n ) foldable
 
-: next-power-of-2 ( m -- n ) 2 swap (next-power-of-2) ; foldable
+M: real next-power-of-2 1+ >integer next-power-of-2 ;
 
 : power-of-2? ( n -- ? )
     dup 0 <= [ drop f ] [ dup 1- bitand zero? ] if ; foldable
index 8fc6e6dd9e488a3cc4407dd72a822d206996082d..ac6c5e97901f5895ac2d39159e8deb7609140176 100644 (file)
@@ -128,7 +128,7 @@ M: ratio >base
         [
             [ numerator (>base) ]
             [ denominator (>base) ] bi
-            "/" swap 3append
+            "/" glue
         ] bi* append
         negative? get [ CHAR: - prefix ] when
     ] with-radix ;
index 8f49d882ee9826b3fb58b3035c5cbd8787711d03..bfe26823beb30a22655a094b7ab97389971247fe 100644 (file)
@@ -68,14 +68,19 @@ HELP: count-instances
 } } ;
 
 ARTICLE: "images" "Images"
-"The current image can be saved; the image contains a complete dump of all data and code in the current Factor instance:"
+"Factor has the ability to save the entire state of the system into an " { $emphasis "image file" } ". The image contains a complete dump of all data and code in the current Factor instance."
 { $subsection save }
 { $subsection save-image }
 { $subsection save-image-and-exit }
 "To start Factor with a custom image, use the " { $snippet "-i=" { $emphasis "image" } } " command line switch; see " { $link "runtime-cli-args" } "."
 $nl
+"One reason to save a custom image is if you find yourself loading the same libraries in every Factor session; some libraries take a little while to compile, so saving an image with those libraries loaded can save you a lot of time."
+$nl
+"For example, to save an image with the web framework loaded,"
+{ $code "USE: furnace" "save" }
 "New images can be created from scratch:"
 { $subsection "bootstrap.image" }
-{ $see-also "tools.memory" "tools.deploy" } ;
+"The " { $link "tools.deploy" } " tool creates stripped-down images containing just enough code to run a single application."
+{ $see-also "tools.memory" } ;
 
 ABOUT: "images"
index 427c294759bb570d2836f3a3b20672232dd61ec3..36559095cba3902b824c842c39dd31231d4bfb45 100644 (file)
@@ -12,12 +12,12 @@ IN: namespaces
 
 PRIVATE>
 
-: namespace ( -- namespace ) namestack* peek ;
+: namespace ( -- namespace ) namestack* peek ; inline
 : namestack ( -- namestack ) namestack* clone ;
 : set-namestack ( namestack -- ) >vector 0 setenv ;
 : global ( -- g ) 21 getenv { hashtable } declare ; inline
 : init-namespaces ( -- ) global 1array set-namestack ;
-: get ( variable -- value ) namestack* assoc-stack ; flushable
+: get ( variable -- value ) namestack* assoc-stack ; inline
 : set ( value variable -- ) namespace set-at ;
 : on ( variable -- ) t swap set ; inline
 : off ( variable -- ) f swap set ; inline
@@ -28,7 +28,7 @@ PRIVATE>
 : inc ( variable -- ) 1 swap +@ ; inline
 : dec ( variable -- ) -1 swap +@ ; inline
 : bind ( ns quot -- ) swap >n call ndrop ; inline
-: counter ( variable -- n ) global [ dup inc get ] bind ;
+: counter ( variable -- n ) global [ 0 or 1+ dup ] change-at ;
 
 : make-assoc ( quot exemplar -- hash )
     20 swap new-assoc [ >n call ndrop ] keep ; inline
index 1e93a762f2cc8dd3e7cc7ec9db9d4a10eeae4637..cc97b78eb65a1e98bffa4e05825770ca4f727490 100644 (file)
@@ -5,6 +5,8 @@ sorting classes.tuple compiler.units debugger vocabs
 vocabs.loader accessors eval combinators lexer ;
 IN: parser.tests
 
+\ run-file must-infer
+
 [
     [ 1 [ 2 [ 3 ] 4 ] 5 ]
     [ "1\n[\n2\n[\n3\n]\n4\n]\n5" eval ]
@@ -400,7 +402,7 @@ IN: parser.tests
 ] times
 
 [ "resource:core/parser/test/assert-depth.factor" run-file ]
-[ stack>> { 1 2 3 } sequence= ]
+[ got>> { 1 2 3 } sequence= ]
 must-fail-with
 
 2 [
index 42e4e7705540c1b9596bfe7c68ccc1c88072e630..3f3af935b66eace173b3eafe986ac959e8d496c4 100644 (file)
@@ -80,17 +80,17 @@ ERROR: no-word-error name ;
 : <no-word-error> ( name possibilities -- error restarts )
     [ drop \ no-word-error boa ] [ word-restarts ] 2bi ;
 
-SYMBOL: amended-use?
+SYMBOL: amended-use
 
 SYMBOL: auto-use?
 
 : no-word-restarted ( restart-value -- word )
     dup word? [
-        amended-use? on
         dup vocabulary>>
-        [ (use+) ] [
-            "Added ``" swap "'' vocabulary to search path" 3append note.
-        ] bi
+        [ (use+) ]
+        [ amended-use get dup [ push ] [ 2drop ] if ]
+        [ "Added ``" swap "'' vocabulary to search path" 3append note. ]
+        tri
     ] [ create-in ] if ;
 
 : no-word ( name -- newword )
@@ -232,22 +232,16 @@ SYMBOL: interactive-vocabs
 SYMBOL: print-use-hook
 
 print-use-hook global [ [ ] or ] change-at
-
+!
 : parse-fresh ( lines -- quot )
     [
-        amended-use? off
+        V{ } clone amended-use set
         parse-lines
-        amended-use? get [
-            print-use-hook get call
-        ] when
+        amended-use get empty? [ print-use-hook get call ] unless
     ] with-file-vocabs ;
 
 : parsing-file ( file -- )
-    "quiet" get [
-        drop
-    ] [
-        "Loading " write print flush
-    ] if ;
+    "quiet" get [ drop ] [ "Loading " write print flush ] if ;
 
 : filter-moved ( assoc1 assoc2 -- seq )
     swap assoc-diff [
@@ -313,7 +307,7 @@ print-use-hook global [ [ ] or ] change-at
     ] recover ;
 
 : run-file ( file -- )
-    [ dup parse-file call ] assert-depth drop ;
+    [ parse-file call ] curry assert-depth ;
 
 : ?run-file ( path -- )
     dup exists? [ run-file ] [ drop ] if ;
index 5a30654f03677a00c34a14ea3b6d97c9a01a0c62..5590432ef4ca3908facee7aadd6fb31fcb704b26 100644 (file)
@@ -31,16 +31,16 @@ M: sbuf equal?
 M: string new-resizable drop <sbuf> ;
 
 M: string like
+    #! If we have a string, we're done.
+    #! If we have an sbuf, and it's at full capacity, we're done.
+    #! Otherwise, call resize-string, which is a relatively
+    #! fast primitive.
     drop dup string? [
         dup sbuf? [
-            dup length over underlying>> length eq? [
-                underlying>> dup reset-string-hashcode
-            ] [
-                >string
-            ] if
-        ] [
-            >string
-        ] if
+            [ length ] [ underlying>> ] bi
+            2dup length eq?
+            [ nip dup reset-string-hashcode ] [ resize-string ] if
+        ] [ >string ] if
     ] unless ;
 
 INSTANCE: sbuf growable
index cc8daba8c0a812bc9daa947a7507dfc5e8de0ebd..08831579bb4c977fada07f422946c348f54a6970 100644 (file)
@@ -714,6 +714,26 @@ HELP: 3append
     }
 } ;
 
+HELP: surround
+{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "newseq" sequence } }
+{ $description "Outputs a new sequence with " { $snippet "seq1" } " inserted between " { $snippet "seq2" } " and " { $snippet "seq3" } "." }
+{ $examples
+    { $example "USING: sequences prettyprint ;"
+               "\"sssssh\" \"(\" \")\" surround ."
+               "\"(sssssh)\""
+    }
+} ;
+
+HELP: glue
+{ $values { "seq1" sequence } { "seq2" sequence } { "seq3" sequence } { "newseq" sequence } }
+{ $description "Outputs a new sequence with " { $snippet "seq3" } " inserted between " { $snippet "seq1" } " and " { $snippet "seq2" } "." }
+{ $examples
+    { $example "USING: sequences prettyprint ;"
+               "\"a\" \"b\" \",\" glue ."
+               "\"a,b\""
+    }
+} ;
+
 HELP: subseq
 { $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } { "subseq" "a new sequence" } }
 { $description "Outputs a new sequence consisting of all elements starting from and including " { $snippet "from" } ", and up to but not including " { $snippet "to" } "." }
@@ -1348,6 +1368,8 @@ ARTICLE: "sequences-appending" "Appending sequences"
 { $subsection append }
 { $subsection prepend }
 { $subsection 3append }
+{ $subsection surround }
+{ $subsection glue }
 { $subsection concat }
 { $subsection join }
 "A pair of words useful for aligning strings:"
index e27f2410b3a06ddd14f9c5dd7e1cb1ad86111b2c..0d795d453aa44a5b6c6acd2d1838204fb41463e0 100644 (file)
@@ -268,3 +268,6 @@ M: bogus-hashcode hashcode* 2drop 0 >bignum ;
 [ { 1 3 "X" 5 7 } ] [ "X" 2 { 1 3 5 7 } insert-nth ] unit-test
 
 [ V{ 0 2 } ] [ "a" { "a" "b" "a" } indices ] unit-test
+
+[ "a,b" ] [ "a" "b" "," glue ] unit-test
+[ "(abc)" ] [ "abc" "(" ")" surround ] unit-test
index 832de612dd1276a323cbba53f3eeb379f5df9d8a..995a8bba4c29e864d44cb8d185f75fe72068a01a 100644 (file)
@@ -101,14 +101,17 @@ M: integer nth-unsafe drop ;
 
 INSTANCE: integer immutable-sequence
 
+: first-unsafe
+    0 swap nth-unsafe ; inline
+
 : first2-unsafe
-    [ 0 swap nth-unsafe 1 ] [ nth-unsafe ] bi ; inline
+    [ first-unsafe ] [ 1 swap nth-unsafe ] bi ; inline
 
 : first3-unsafe
-    [ first2-unsafe 2 ] [ nth-unsafe ] bi ; inline
+    [ first2-unsafe ] [ 2 swap nth-unsafe ] bi ; inline
 
 : first4-unsafe
-    [ first3-unsafe 3 ] [ nth-unsafe ] bi ; inline
+    [ first3-unsafe ] [ 3 swap nth-unsafe ] bi ; inline
 
 : exchange-unsafe ( m n seq -- )
     [ tuck [ nth-unsafe ] 2bi@ ]
@@ -314,6 +317,10 @@ PRIVATE>
 
 : 3append ( seq1 seq2 seq3 -- newseq ) pick 3append-as ;
 
+: surround ( seq1 seq2 seq3 -- newseq ) swapd 3append ; inline
+
+: glue ( seq1 seq2 seq3 -- newseq ) swap 3append ; inline
+
 : change-nth ( i seq quot -- )
     [ [ nth ] dip call ] 3keep drop set-nth ; inline
 
@@ -774,13 +781,13 @@ PRIVATE>
     tuck [ tail-slice ] 2bi@ ;
 
 : unclip ( seq -- rest first )
-    [ rest ] [ first ] bi ;
+    [ rest ] [ first-unsafe ] bi ;
 
 : unclip-last ( seq -- butlast last )
     [ but-last ] [ peek ] bi ;
 
 : unclip-slice ( seq -- rest-slice first )
-    [ rest-slice ] [ first ] bi ; inline
+    [ rest-slice ] [ first-unsafe ] bi ; inline
 
 : 2unclip-slice ( seq1 seq2 -- rest-slice1 rest-slice2 first1 first2 )
     [ unclip-slice ] bi@ swapd ; inline
@@ -828,12 +835,35 @@ PRIVATE>
 
 : supremum ( seq -- n ) dup first [ max ] reduce ;
 
-: flip ( matrix -- newmatrix )
-    dup empty? [
-        dup [ length ] map infimum
-        swap [ [ nth-unsafe ] with { } map-as ] curry { } map-as
-    ] unless ;
-
 : sigma ( seq quot -- n ) [ + ] compose 0 swap reduce ; inline
 
 : count ( seq quot -- n ) [ 1 0 ? ] compose sigma ; inline
+
+! We hand-optimize flip to such a degree because type hints
+! cannot express that an array is an array of arrays yet, and
+! this word happens to be performance-critical since the compiler
+! itself uses it. Optimizing it like this reduced compile time.
+<PRIVATE
+
+: generic-flip ( matrix -- newmatrix )
+    [ dup first length [ length min ] reduce ] keep
+    [ [ nth-unsafe ] with { } map-as ] curry { } map-as ; inline
+
+USE: arrays
+
+: array-length ( array -- len )
+    { array } declare length>> ;
+
+: array-flip ( matrix -- newmatrix )
+    [ dup first array-length [ array-length min ] reduce ] keep
+    [ [ array-nth ] with { } map-as ] curry { } map-as ;
+
+PRIVATE>
+
+: flip ( matrix -- newmatrix )
+    dup empty? [
+        dup array? [
+            dup [ array? ] all?
+            [ array-flip ] [ generic-flip ] if
+        ] [ generic-flip ] if
+    ] unless ;
index 39628ede98cdfd64edb60f02d3447ac6523e908c..0c3f918fdca03879a8dd65c817b2e94272b0e8a6 100644 (file)
@@ -16,6 +16,10 @@ IN: strings
 : rehash-string ( str -- )
     1 over sequence-hashcode swap set-string-hashcode ; inline
 
+: set-string-nth ( ch n str -- )
+    pick HEX: 7f fixnum<=
+    [ set-string-nth-fast ] [ set-string-nth-slow ] if ; inline
+
 PRIVATE>
 
 M: string equal?
@@ -27,8 +31,9 @@ M: string equal?
     ] if ;
 
 M: string hashcode*
-    nip dup string-hashcode [ ]
-    [ dup rehash-string string-hashcode ] ?if ;
+    nip
+    dup string-hashcode
+    [ ] [ dup rehash-string string-hashcode ] ?if ;
 
 M: string length
     length>> ;
@@ -38,7 +43,7 @@ M: string nth-unsafe
 
 M: string set-nth-unsafe
     dup reset-string-hashcode
-    [ [ >fixnum ] dip >fixnum ] dip set-string-nth ;
+    [ >fixnum ] [ >fixnum ] [ ] tri* set-string-nth ;
 
 M: string clone
     (clone) [ clone ] change-aux ;
index 7d3553faeed48cb26849676d76f80e1b3eb890fa..c951750b342a6cc09f9316bd2840f3ceaa0cc428 100644 (file)
@@ -23,7 +23,7 @@ IN: bootstrap.syntax
     "syntax" lookup t "delimiter" set-word-prop ;
 
 : define-syntax ( name quot -- )
-    [ "syntax" lookup dup ] dip define t "parsing" set-word-prop ;
+    [ "syntax" lookup dup ] dip define make-parsing ;
 
 [
     { "]" "}" ";" ">>" } [ define-delimiter ] each
@@ -93,7 +93,7 @@ IN: bootstrap.syntax
     "foldable" [ word make-foldable ] define-syntax
     "flushable" [ word make-flushable ] define-syntax
     "delimiter" [ word t "delimiter" set-word-prop ] define-syntax
-    "parsing" [ word t "parsing" set-word-prop ] define-syntax
+    "parsing" [ word make-parsing ] define-syntax
 
     "SYMBOL:" [
         CREATE-WORD define-symbol
index 3adf82af7feca35846f78d532720f8013b29d3ba..ab17ce2be9cf571753912637d1cad6e75dd0f3f6 100644 (file)
@@ -12,6 +12,7 @@ ARTICLE: "system" "System interface"
 { $subsection image }
 "Getting the current time:"
 { $subsection micros }
+{ $subsection millis }
 "Exiting the Factor VM:"
 { $subsection exit } ;
 
@@ -70,7 +71,7 @@ HELP: micros ( -- us )
 { $notes "This is a low-level word. The " { $vocab-link "calendar" } " vocabulary provides features for date/time arithmetic and formatting." } ;
 
 HELP: millis ( -- ms )
-{ $values { "us" integer } }
+{ $values { "ms" integer } }
 { $description "Outputs the number of milliseconds ellapsed since midnight January 1, 1970." }
 { $notes "This is a low-level word. The " { $vocab-link "calendar" } " vocabulary provides features for date/time arithmetic and formatting." } ;
 
index dab30f306f2c41eecd967d170671db6cc647d24f..a6bfef71d016a656b1abe56bb483970eb62c3280 100644 (file)
@@ -1,13 +1,14 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math sequences sequences.private growable ;
+USING: arrays kernel math sequences sequences.private growable
+accessors ;
 IN: vectors
 
 TUPLE: vector
 { underlying array }
 { length array-capacity } ;
 
-: <vector> ( n -- vector ) f <array> 0 vector boa ; inline
+: <vector> ( n -- vector ) 0 <array> 0 vector boa ; inline
 
 : >vector ( seq -- vector ) V{ } clone-like ;
 
@@ -22,6 +23,19 @@ M: vector new-sequence
 M: vector equal?
     over vector? [ sequence= ] [ 2drop f ] if ;
 
+M: array like
+    #! If we have an array, we're done.
+    #! If we have a vector, and it's at full capacity, we're done.
+    #! Otherwise, call resize-array, which is a relatively
+    #! fast primitive.
+    drop dup array? [
+        dup vector? [
+            [ length ] [ underlying>> ] bi
+            2dup length eq?
+            [ nip ] [ resize-array ] if
+        ] [ >array ] if
+    ] unless ;
+
 M: sequence new-resizable drop <vector> ;
 
 INSTANCE: vector growable
index 89b8a0728de60454a6977ca58f3be345db700186..ce3b5ea024154940291a1fa8b636ae4731c96ec6 100644 (file)
@@ -2,6 +2,18 @@ USING: vocabs vocabs.loader.private help.markup help.syntax
 words strings io ;
 IN: vocabs.loader
 
+ARTICLE: "add-vocab-roots" "Working with code outside of the Factor source tree"
+"You can work with code outside of the Factor source tree by adding additional directories to the list of vocabulary roots."
+$nl
+"There are three ways of doing this."
+$nl
+"The first way is to use an environment variable. Factor looks at the " { $snippet "FACTOR_ROOTS" } " environment variable for a list of " { $snippet ":" } "-separated paths (on Unix) or a list of " { $snippet ";" } "-separated paths (on Windows)."
+$nl
+"The second way is to create a configuration file. You can list additional vocabulary roots in a file that Factor reads at startup:"
+{ $subsection "factor-roots" }
+"Finally, you can add vocabulary roots dynamically using a word:"
+{ $subsection add-vocab-root } ;
+
 ARTICLE: "vocabs.roots" "Vocabulary roots"
 "The vocabulary loader searches for it in one of the root directories:"
 { $subsection vocab-roots }
@@ -12,12 +24,8 @@ ARTICLE: "vocabs.roots" "Vocabulary roots"
     { { $snippet "extra" } " - additional contributed libraries." }
     { { $snippet "work" } " - a root for vocabularies which are not intended to be contributed back to Factor." }
 }
-"Your own vocabularies should go into " { $snippet "extra" } " or " { $snippet "work" } ", depending on whether or not you intend to contribute them back to the Factor project. If you wish to work on vocabularies outside of the Factor source directory, create a " { $link "factor-boot-rc" } " file like the following:"
-{ $code
-    "USING: namespaces sequences vocabs.loader ;"
-    "\"/home/jane/sources/\" vocab-roots get push"
-}
-"See " { $link "rc-files" } " for details." ;
+"You can store your own vocabularies in the " { $snippet "work" } " directory."
+{ $subsection "add-vocab-roots" } ;
 
 ARTICLE: "vocabs.loader" "Vocabulary loader"
 "The vocabulary loader is defined in the " { $vocab-link "vocabs.loader" } " vocabulary."
@@ -57,6 +65,11 @@ HELP: vocab-main
 HELP: vocab-roots
 { $var-description "A sequence of pathname strings to search for vocabularies." } ;
 
+HELP: add-vocab-root
+{ $values { "root" "a pathname string" } }
+{ $description "Adds a directory pathname to the list of vocabulary roots." }
+{ $see-also "factor-roots" } ;
+
 HELP: find-vocab-root
 { $values { "vocab" "a vocabulary specifier" } { "path/f" "a pathname string" } }
 { $description "Searches for a vocabulary in the vocabulary roots." } ;
index 7b53e98df18526b8ff56dcbfb12f1e5b54f52766..e5bd74a98169b2d28bbe8d50bdf100e377e7a67d 100644 (file)
@@ -154,9 +154,6 @@ forget-junk
 
 [ ] [ [ "vocabs.loader.test.e" forget-vocab ] with-compilation-unit ] unit-test
 
-[ "vocabs.loader.test.e" require ]
-[ relative-overflow? ] must-fail-with
-
 0 "vocabs.loader.test.g" set-global
 
 [
index 49fad2626fb6f212b540fbbf55412ccff33a22b4..6fb0d088118b74fb9c388d1a9f6adcd9bc54bad3 100644 (file)
@@ -3,7 +3,7 @@
 USING: namespaces make sequences io.files kernel assocs words
 vocabs definitions parser continuations io hashtables sorting
 source-files arrays combinators strings system math.parser
-compiler.errors splitting init accessors ;
+compiler.errors splitting init accessors sets ;
 IN: vocabs.loader
 
 SYMBOL: vocab-roots
@@ -15,6 +15,9 @@ V{
     "resource:work"
 } clone vocab-roots set-global
 
+: add-vocab-root ( root -- )
+    vocab-roots get adjoin ;
+
 : vocab-dir ( vocab -- dir )
     vocab-name { { CHAR: . CHAR: / } } substitute ;
 
index 929161c5d6e87f4fdd7d1d357fe0248ea421af58..b36f8be6775c5eac3a0cfdf1e5308f103714bd5a 100644 (file)
@@ -221,7 +221,7 @@ M: word subwords drop f ;
     "( gensym )" f <word> ;
 
 : define-temp ( quot -- word )
-    gensym dup rot define ;
+    [ gensym dup ] dip define ;
 
 : reveal ( word -- )
     dup [ name>> ] [ vocabulary>> ] bi dup vocab-words
@@ -243,6 +243,8 @@ ERROR: bad-create name vocab ;
 
 PREDICATE: parsing-word < word "parsing" word-prop ;
 
+: make-parsing ( word -- ) t "parsing" set-word-prop ;
+
 : delimiter? ( obj -- ? )
     dup word? [ "delimiter" word-prop ] [ drop f ] if ;
 
index bd1ed83baa6859e1b4b3e30e46b822adf1704823..b087d3ae2baf47636c91feeb0af739f31ba59bb5 100644 (file)
@@ -189,11 +189,11 @@ M: string >ber ( str -- byte-array )
     >byte-array append ;
 
 : >ber-application-string ( n str -- byte-array )
-    >r HEX: 40 + set-tag r> >ber ;
+    [ HEX: 40 + set-tag ] dip >ber ;
 
 GENERIC: >ber-contextspecific ( n obj -- byte-array )
 M: string >ber-contextspecific ( n str -- byte-array )
-    >r HEX: 80 + set-tag r> >ber ;
+    [ HEX: 80 + set-tag ] dip >ber ;
 
 ! =========================================================
 ! Array
index ed9b4bf0c4ef56a3687f4dae9b5f5333ce36dce3..f1b018f54eeaefa46fa5b800cdc703af46a8a8bb 100755 (executable)
@@ -10,10 +10,10 @@ IN: assocs.lib
     dupd at [ nip ] when* ;
 
 : replace-at ( assoc value key -- assoc )
-    >r >r dup r> 1vector r> rot set-at ;
+    [ dupd 1vector ] dip rot set-at ;
 
 : peek-at* ( assoc key -- obj ? )
-    swap at* dup [ >r peek r> ] when ;
+    swap at* dup [ [ peek ] dip ] when ;
 
 : peek-at ( assoc key -- obj )
     peek-at* drop ;
@@ -27,7 +27,7 @@ IN: assocs.lib
 : insert ( value variable -- ) namespace push-at ;
 
 : generate-key ( assoc -- str )
-    >r 32 random-bits >hex r>
+    [ 32 random-bits >hex ] dip
     2dup key? [ nip generate-key ] [ drop ] if ;
 
 : set-at-unique ( value assoc -- key )
index 5a8e7595b552d0ec454ffe1a91fe697935daba00..a1e892229ad8a0f84e0b4a82fcb58bf4cf3c2738 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel vocabs vocabs.loader tools.time tools.vocabs
 arrays assocs io.styles io help.markup prettyprint sequences
-continuations debugger ;
+continuations debugger math ;
 IN: benchmark
 
 : run-benchmark ( vocab -- result )
@@ -17,12 +17,12 @@ IN: benchmark
     standard-table-style [
         [
             [ "Benchmark" write ] with-cell
-            [ "Time (ms)" write ] with-cell
+            [ "Time (seconds)" write ] with-cell
         ] with-row
         [
             [
                 [ [ 1array $vocab-link ] with-cell ]
-                [ pprint-cell ] bi*
+                [ [ 1000000 /f pprint-cell ] [ "failed" write ] if* ] bi*
             ] with-row
         ] assoc-each
     ] tabular-output ;
index 7cff06d1bc68fefd6e54a9b7856572980369524c..5cd40bc0981d1a8b40525c1af40c91052352cc17 100644 (file)
@@ -1,21 +1,16 @@
-USING: sequences alien.c-types math hints kernel byte-arrays ;
+USING: sequences hints kernel math specialized-arrays.int fry ;
 IN: benchmark.dawes
 
 ! Phil Dawes's performance problem
 
-: int-length ( byte-array -- n ) length "int" heap-size /i ; inline
+: count-ones ( int-array -- n ) [ 1 = ] count ; inline
 
-: count-ones ( byte-array -- n )
-    0 swap [ int-length ] keep [
-        int-nth 1 = [ 1 + ] when
-    ] curry each-integer ;
+HINTS: count-ones int-array ;
 
-HINTS: count-ones byte-array ;
-
-: make-byte-array ( -- byte-array )
-    120000 [ 255 bitand ] map >c-int-array ;
+: make-int-array ( -- int-array )
+    120000 [ 255 bitand ] int-array{ } map-as ;
 
 : dawes-benchmark ( -- )
-    make-byte-array 200 swap [ count-ones ] curry replicate drop ;
+    make-int-array 200 swap '[ _ count-ones ] replicate drop ;
 
 MAIN: dawes-benchmark
index 93b42c3e6c9091ba5072e0d8f4115162f124d487..c9d4f9ffa282d3a047bffb8ac43079f3ec91856b 100644 (file)
@@ -1,5 +1,5 @@
 USING: make math sequences splitting grouping
-kernel columns float-arrays bit-arrays ;
+kernel columns specialized-arrays.double bit-arrays ;
 IN: benchmark.dispatch2
 
 : sequences ( -- seq )
@@ -10,7 +10,7 @@ IN: benchmark.dispatch2
         "hello world" ,
         SBUF" sbuf world" ,
         V{ "a" "b" "c" } ,
-        F{ 1.0 2.0 3.0 } ,
+        double-array{ 1.0 2.0 3.0 } ,
         "hello world" 4 tail-slice ,
         10 f <repetition> ,
         100 2 <sliced-groups> ,
index aa3d11e2fb7c3e6553fa60619deead02d68e0616..94925f0d7958853e6ad724880605b72940feea4f 100644 (file)
@@ -1,6 +1,6 @@
 USING: sequences math mirrors splitting grouping
 kernel make assocs alien.syntax columns
-float-arrays bit-arrays ;
+specialized-arrays.double bit-arrays ;
 IN: benchmark.dispatch3
 
 GENERIC: g ( obj -- str )
@@ -26,7 +26,7 @@ M: object g drop "object" ;
         "hello world" ,
         SBUF" sbuf world" ,
         V{ "a" "b" "c" } ,
-        F{ 1.0 2.0 3.0 } ,
+        double-array{ 1.0 2.0 3.0 } ,
         "hello world" 4 tail-slice ,
         10 f <repetition> ,
         100 2 <sliced-groups> ,
diff --git a/extra/benchmark/fannkuch/fannkuch.factor b/extra/benchmark/fannkuch/fannkuch.factor
new file mode 100644 (file)
index 0000000..a69c538
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel fry math math.combinatorics math.order sequences
+io prettyprint ;
+IN: benchmark.fannkuch
+
+: count ( quot: ( -- ? ) -- n )
+    #! Call quot until it returns false, return number of times
+    #! it was true
+    [ 0 ] dip '[ _ dip swap [ [ 1+ ] when ] keep ] loop ; inline
+
+: count-flips ( perm -- flip# )
+    '[
+        _ dup first dup 1 =
+        [ 2drop f ] [ head-slice reverse-here t ] if
+    ] count ; inline
+
+: write-permutation ( perm -- )
+    [ CHAR: 0 + write1 ] each nl ; inline
+
+: fannkuch-step ( counter max-flips perm -- counter max-flips )
+    pick 30 < [ [ 1+ ] [ ] [ dup write-permutation ] tri* ] when
+    count-flips max ; inline
+
+: fannkuch ( n -- )
+    [
+        [ 0 0 ] dip [ 1+ ] B{ } map-as
+        [ fannkuch-step ] each-permutation nip
+    ] keep
+    "Pfannkuchen(" write pprint ") = " write . ;
+
+: fannkuch-main ( -- )
+    9 fannkuch ;
+
+MAIN: fannkuch-main
index 015f762c7b97e75db60a8d8acd3b4925b59a80a0..32d35349202f52c98c8744208103ca8395839379 100755 (executable)
@@ -1,7 +1,7 @@
 ! Based on http://shootout.alioth.debian.org/gp4/benchmark.php?test=fasta&lang=java&id=2
 USING: math kernel io io.files locals multiline assocs sequences
 sequences.private benchmark.reverse-complement hints io.encodings.ascii
-byte-arrays float-arrays ;
+byte-arrays specialized-arrays.double ;
 IN: benchmark.fasta
 
 : IM 139968 ; inline
@@ -49,7 +49,7 @@ HINTS: random fixnum ;
 
 : make-cumulative ( freq -- chars floats )
     dup keys >byte-array
-    swap values >float-array unclip [ + ] accumulate swap suffix ;
+    swap values >double-array unclip [ + ] accumulate swap suffix ;
 
 :: select-random ( seed chars floats -- seed elt )
     floats seed random -rot
index 6bd2d69cfa50a1f58ef820243adcf15658942cb9..7b8e2d34c98b55662ebf9d726310a7657fdda459 100644 (file)
@@ -9,7 +9,7 @@ IN: benchmark.knucleotide
     "." split1 rot
     over length over <
     [ CHAR: 0 pad-right ] 
-    [ head ] if "." swap 3append ;
+    [ head ] if "." glue ;
 
 : discard-lines ( -- )
     readln
diff --git a/extra/benchmark/nbody/nbody.factor b/extra/benchmark/nbody/nbody.factor
new file mode 100644 (file)
index 0000000..305fc2e
--- /dev/null
@@ -0,0 +1,105 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors specialized-arrays.double fry kernel locals make math
+math.constants math.functions math.vectors prettyprint
+sequences hints arrays ;
+IN: benchmark.nbody
+
+: solar-mass 4 pi sq * ; inline
+: days-per-year 365.24 ; inline
+
+TUPLE: body
+{ location double-array }
+{ velocity double-array }
+{ mass float read-only } ;
+
+: <body> ( location velocity mass -- body )
+    [ days-per-year v*n ] [ solar-mass * ] bi* body boa ; inline
+
+: <jupiter> ( -- body )
+    double-array{ 4.84143144246472090e+00 -1.16032004402742839e+00 -1.03622044471123109e-01 }
+    double-array{ 1.66007664274403694e-03 7.69901118419740425e-03 -6.90460016972063023e-05 }
+    9.54791938424326609e-04
+    <body> ;
+
+: <saturn> ( -- body )
+    double-array{ 8.34336671824457987e+00 4.12479856412430479e+00 -4.03523417114321381e-01 }
+    double-array{ -2.76742510726862411e-03 4.99852801234917238e-03 2.30417297573763929e-05 }
+    2.85885980666130812e-04
+    <body> ;
+
+: <uranus> ( -- body )
+    double-array{ 1.28943695621391310e+01 -1.51111514016986312e+01 -2.23307578892655734e-01 }
+    double-array{ 2.96460137564761618e-03 2.37847173959480950e-03 -2.96589568540237556e-05 }
+    4.36624404335156298e-05
+    <body> ;
+
+: <neptune> ( -- body )
+    double-array{ 1.53796971148509165e+01 -2.59193146099879641e+01 1.79258772950371181e-01 }
+    double-array{ 2.68067772490389322e-03 1.62824170038242295e-03 -9.51592254519715870e-05 }
+    5.15138902046611451e-05
+    <body> ;
+
+: <sun> ( -- body )
+    double-array{ 0 0 0 } double-array{ 0 0 0 } 1 <body> ;
+    
+: offset-momentum ( body offset -- body )
+    vneg solar-mass v/n >>velocity ; inline
+
+TUPLE: nbody-system { bodies array read-only } ;
+
+: init-bodies ( bodies -- )
+    [ first ] [ double-array{ 0 0 0 } [ [ velocity>> ] [ mass>> ] bi v*n v+ ] reduce ] bi
+    offset-momentum drop ; inline
+
+: <nbody-system> ( -- system )
+    [ <sun> , <jupiter> , <saturn> , <uranus> , <neptune> , ] { } make nbody-system boa
+    dup bodies>> init-bodies ; inline
+
+:: each-pair ( bodies pair-quot: ( other-body body -- ) each-quot: ( body -- ) -- )
+    bodies [| body i |
+        body each-quot call
+        bodies i 1+ tail-slice [
+            body pair-quot call
+        ] each
+    ] each-index ; inline
+
+: update-position ( body dt -- )
+    [ dup velocity>> ] dip '[ _ _ v*n v+ ] change-location drop ;
+
+: mag ( dt body other-body -- mag d )
+    [ location>> ] bi@ v- [ norm-sq dup sqrt * / ] keep ; inline
+
+:: update-velocity ( other-body body dt -- )
+    dt body other-body mag
+    [ [ body ] 2dip '[ other-body mass>> _ * _ n*v v- ] change-velocity drop ]
+    [ [ other-body ] 2dip '[ body mass>> _ * _ n*v v+ ] change-velocity drop ] 2bi ;
+
+: advance ( system dt -- )
+    [ bodies>> ] dip
+    [ '[ _ update-velocity ] [ drop ] each-pair ]
+    [ '[ _ update-position ] each ]
+    2bi ; inline
+
+: inertia ( body -- e )
+    [ mass>> ] [ velocity>> norm-sq ] bi * 0.5 * ;
+
+: newton's-law ( other-body body -- e )
+    [ [ mass>> ] bi@ * ] [ [ location>> ] bi@ distance ] 2bi / ;
+
+: energy ( system -- x )
+    [ 0.0 ] dip bodies>> [ newton's-law - ] [ inertia + ] each-pair ; inline
+
+: nbody ( n -- )
+    <nbody-system>
+    [ energy . ] [ '[ _ 0.01 advance ] times ] [ energy . ] tri ;
+
+HINTS: update-position body float ;
+HINTS: update-velocity body body float ;
+HINTS: inertia body ;
+HINTS: newton's-law body body ;
+HINTS: nbody fixnum ;
+
+: nbody-main ( -- ) 1000000 nbody ;
+
+MAIN: nbody-main
index 2d8cdc40c7299eb20860ebe1ac2b22410dd4e04e..7c7c68b12d741a7e87a48ca32bed0139cb26d918 100644 (file)
@@ -1,63 +1,44 @@
-USING: math math.functions kernel sequences io io.styles
-prettyprint words hints ;
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math math.functions kernel io io.styles prettyprint
+combinators hints fry namespaces sequences ;
 IN: benchmark.partial-sums
 
-: summing ( n quot -- y )
-    [ >float ] swap [ + ] 3compose
-    0.0 -rot 1 -rot (each-integer) ; inline
-
-: 2/3^k ( n -- y ) [ 2.0 3.0 / swap 1- ^ ] summing ;
-
-HINTS: 2/3^k fixnum ;
-
-: k^-0.5 ( n -- y ) [ -0.5 ^ ] summing ;
-
-HINTS: k^-0.5 fixnum ;
-
-: 1/k(k+1) ( n -- y ) [ dup 1+ * recip ] summing ;
-
-HINTS: 1/k(k+1) fixnum ;
-
+! Helper words
+: summing-integers ( n quot -- y ) [ 0.0 ] 2dip '[ 1+ @ + ] each ; inline
+: summing-floats ( n quot -- y ) '[ >float @ ] summing-integers ; inline
 : cube ( x -- y ) dup dup * * ; inline
-
-: flint-hills ( n -- y )
-    [ dup cube swap sin sq * recip ] summing ;
-
-HINTS: flint-hills fixnum ;
-
-: cookson-hills ( n -- y )
-    [ dup cube swap cos sq * recip ] summing ;
-
-HINTS: cookson-hills fixnum ;
-
-: harmonic ( n -- y ) [ recip ] summing ;
-
-HINTS: harmonic fixnum ;
-
-: riemann-zeta ( n -- y ) [ sq recip ] summing ;
-
-HINTS: riemann-zeta fixnum ;
-
-: -1^ 2 mod zero? 1 -1 ? ; inline
-
-: alternating-harmonic ( n -- y ) [ dup -1^ swap / ] summing ;
-
-HINTS: alternating-harmonic fixnum ;
-
-: gregory ( n -- y ) [ dup -1^ swap 2 * 1- / ] summing ;
-
-HINTS: gregory fixnum ;
-
-: functions
-    { 2/3^k k^-0.5 1/k(k+1) flint-hills cookson-hills harmonic riemann-zeta alternating-harmonic gregory } ;
-
-: partial-sums ( n -- )
-    standard-table-style [
-        functions [
-            [ tuck execute pprint-cell pprint-cell ] with-row
-        ] with each
-    ] tabular-output ;
-
-: partial-sums-main ( -- ) 2500000 partial-sums ;
+: -1^ ( n -- -1/1 ) 2 mod 2 * 1- ; inline
+
+! The functions
+: 2/3^k ( n -- y ) [ 2.0 3.0 / swap 1- ^ ] summing-floats ; inline
+: k^-0.5 ( n -- y ) [ -0.5 ^ ] summing-floats ; inline
+: 1/k(k+1) ( n -- y ) [ dup 1+ * recip ] summing-floats ; inline
+: flint-hills ( n -- y ) [ [ cube ] [ sin sq ] bi * recip ] summing-floats ; inline
+: cookson-hills ( n -- y ) [ [ cube ] [ cos sq ] bi * recip ] summing-floats ; inline
+: harmonic ( n -- y ) [ recip ] summing-floats ; inline
+: riemann-zeta ( n -- y ) [ sq recip ] summing-floats ; inline
+: alternating-harmonic ( n -- y ) [ [ -1^ ] keep /f ] summing-integers ; inline
+: gregory ( n -- y ) [ [ -1^ ] [ 2.0 * 1- ] bi / ] summing-integers ; inline
+
+: partial-sums ( n -- results )
+    [
+        {
+            [ 2/3^k                 \ 2/3^k                set ]
+            [ k^-0.5                \ k^-0.5               set ]
+            [ 1/k(k+1)              \ 1/k(k+1)             set ]
+            [ flint-hills           \ flint-hills          set ]
+            [ cookson-hills         \ cookson-hills        set ]
+            [ harmonic              \ harmonic             set ]
+            [ riemann-zeta          \ riemann-zeta         set ]
+            [ alternating-harmonic  \ alternating-harmonic set ]
+            [ gregory               \ gregory              set ]
+        } cleave
+    ] { } make-assoc ;
+
+HINTS: partial-sums fixnum ;
+
+: partial-sums-main ( -- )
+    2500000 partial-sums simple-table. ;
 
 MAIN: partial-sums-main
index 34bac61292a159f3e35a5010a6d1ddb3f73a8a07..7fe46e9c367783af1786e7ac4b66b8246fbe61cd 100755 (executable)
@@ -1,7 +1,7 @@
 ! Factor port of the raytracer benchmark from
 ! http://www.ffconsultancy.com/free/ray_tracer/languages.html
 
-USING: arrays accessors float-arrays io io.files
+USING: arrays accessors specialized-arrays.double io io.files
 io.encodings.binary kernel math math.functions math.vectors
 math.parser make sequences sequences.private words hints ;
 IN: benchmark.raytracer
@@ -9,7 +9,7 @@ IN: benchmark.raytracer
 ! parameters
 : light
     #! Normalized { -1 -3 2 }.
-    F{
+    double-array{
         -0.2672612419124244
         -0.8017837257372732
         0.5345224838248488
@@ -23,17 +23,17 @@ IN: benchmark.raytracer
 
 : delta 1.4901161193847656E-8 ; inline
 
-TUPLE: ray { orig float-array read-only } { dir float-array read-only } ;
+TUPLE: ray { orig double-array read-only } { dir double-array read-only } ;
 
 C: <ray> ray
 
-TUPLE: hit { normal float-array read-only } { lambda float read-only } ;
+TUPLE: hit { normal double-array read-only } { lambda float read-only } ;
 
 C: <hit> hit
 
 GENERIC: intersect-scene ( hit ray scene -- hit )
 
-TUPLE: sphere { center float-array read-only } { radius float read-only } ;
+TUPLE: sphere { center double-array read-only } { radius float read-only } ;
 
 C: <sphere> sphere
 
@@ -87,7 +87,7 @@ TUPLE: group < sphere { objs array read-only } ;
 M: group intersect-scene ( hit ray group -- hit )
     [ drop objs>> [ intersect-scene ] with each ] if-ray-sphere ;
 
-: initial-hit T{ hit f F{ 0.0 0.0 0.0 } 1/0. } ; inline
+: initial-hit T{ hit f double-array{ 0.0 0.0 0.0 } 1/0. } ; inline
 
 : initial-intersect ( ray scene -- hit )
     [ initial-hit ] 2dip intersect-scene ; inline
@@ -120,10 +120,10 @@ DEFER: create ( level c r -- scene )
 
 : create-offsets ( quot -- )
     {
-        F{ -1.0 1.0 -1.0 }
-        F{ 1.0 1.0 -1.0 }
-        F{ -1.0 1.0 1.0 }
-        F{ 1.0 1.0 1.0 }
+        double-array{ -1.0 1.0 -1.0 }
+        double-array{ 1.0 1.0 -1.0 }
+        double-array{ -1.0 1.0 1.0 }
+        double-array{ 1.0 1.0 1.0 }
     } swap each ; inline
 
 : create-bound ( c r -- sphere ) 3.0 * <sphere> ;
@@ -138,14 +138,14 @@ DEFER: create ( level c r -- scene )
     pick 1 = [ <sphere> nip ] [ create-group ] if ;
 
 : ss-point ( dx dy -- point )
-    [ oversampling /f ] bi@ 0.0 3float-array ;
+    [ oversampling /f ] bi@ 0.0 double-array{ } 3sequence ;
 
 : ss-grid ( -- ss-grid )
     oversampling [ oversampling [ ss-point ] with map ] map ;
 
 : ray-grid ( point ss-grid -- ray-grid )
     [
-        [ v+ normalize F{ 0.0 0.0 -4.0 } swap <ray> ] with map
+        [ v+ normalize double-array{ 0.0 0.0 -4.0 } swap <ray> ] with map
     ] with map ;
 
 : ray-pixel ( scene point -- n )
@@ -156,7 +156,7 @@ DEFER: create ( level c r -- scene )
     size reverse [
         size [
             [ size 0.5 * - ] bi@ swap size
-            3float-array
+            double-array{ } 3sequence
         ] with map
     ] map ;
 
@@ -169,7 +169,7 @@ DEFER: create ( level c r -- scene )
     pixel-grid [ [ ray-pixel ] with map ] with map ;
 
 : run ( -- string )
-    levels F{ 0.0 -1.0 0.0 } 1.0 create ray-trace [
+    levels double-array{ 0.0 -1.0 0.0 } 1.0 create ray-trace [
         size size pgm-header
         [ [ oversampling sq / pgm-pixel ] each ] each
     ] B{ } make ;
index 0c21de0363f4824579e3db1d8fd5ba8be814a0b4..8c0aee596de53c0427b17abfc72ec597ff72ed02 100644 (file)
@@ -11,14 +11,14 @@ IN: benchmark.regex-dna
 
 : count-patterns ( string -- )
     {
-        R/ agggtaaa|tttaccct/i,
-        R/ [cgt]gggtaaa|tttaccc[acg]/i,
-        R/ a[act]ggtaaa|tttacc[agt]t/i,
-        R/ ag[act]gtaaa|tttac[agt]ct/i,
-        R/ agg[act]taaa|ttta[agt]cct/i,
-        R/ aggg[acg]aaa|ttt[cgt]ccct/i,
-        R/ agggt[cgt]aa|tt[acg]accct/i,
-        R/ agggta[cgt]a|t[acg]taccct/i,
+        R/ agggtaaa|tttaccct/i
+        R/ [cgt]gggtaaa|tttaccc[acg]/i
+        R/ a[act]ggtaaa|tttacc[agt]t/i
+        R/ ag[act]gtaaa|tttac[agt]ct/i
+        R/ agg[act]taaa|ttta[agt]cct/i
+        R/ aggg[acg]aaa|ttt[cgt]ccct/i
+        R/ agggt[cgt]aa|tt[acg]accct/i
+        R/ agggta[cgt]a|t[acg]taccct/i
         R/ agggtaa[cgt]|[acg]ttaccct/i
     } [
         [ raw>> write bl ]
index 245027ef77009f94c16970811e6863f739a52c31..64d2bdbb1f8fd9b897df4786cb57cb5515c050e3 100644 (file)
@@ -1,8 +1,8 @@
 ! Factor port of
 ! http://shootout.alioth.debian.org/gp4/benchmark.php?test=spectralnorm&lang=all
-USING: float-arrays kernel math math.functions math.vectors
-sequences sequences.private prettyprint words
-hints locals ;
+USING: specialized-arrays.double kernel math math.functions
+math.vectors sequences sequences.private prettyprint words hints
+locals ;
 IN: benchmark.spectral-norm
 
 :: inner-loop ( u n quot -- seq )
@@ -10,7 +10,7 @@ IN: benchmark.spectral-norm
         n 0.0 [| j |
             u i j quot call +
         ] reduce
-    ] F{ } map-as ; inline
+    ] double-array{ } map-as ; inline
 
 : eval-A ( i j -- n )
     [ >float ] bi@
@@ -32,7 +32,7 @@ IN: benchmark.spectral-norm
 : eval-AtA-times-u ( u n -- seq )
     [ eval-A-times-u ] [ eval-At-times-u ] bi ; inline
 
-: ones ( n -- seq ) [ 1.0 ] F{ } replicate-as ; inline
+: ones ( n -- seq ) [ 1.0 ] double-array{ } replicate-as ; inline
 
 :: u/v ( n -- u v )
     n ones dup
diff --git a/extra/benchmark/xml/xml.factor b/extra/benchmark/xml/xml.factor
new file mode 100644 (file)
index 0000000..a61293c
--- /dev/null
@@ -0,0 +1,11 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.encodings.utf8 io.files kernel sequences xml ;
+IN: benchmark.xml
+
+: xml-benchmark ( -- )
+    "resource:basis/xmode/modes/" [
+        [ utf8 <file-reader> read-xml drop ] each
+    ] with-directory-files ;
+
+MAIN: xml-benchmark
index 5eb41cd94389b62dd3356f3a8b2c6d18a3c5fa26..90e588be48661f39a37cffc574fd8f9a80fee422 100755 (executable)
@@ -80,7 +80,7 @@ M: check< summary drop "Number exceeds upper bound" ;
     [ ":" split1 string>number [ dup length ] unless* ] { } map>assoc ;
 
 : define-slots ( prefix names quots -- )
-    >r [ "-" swap 3append create-in ] with map r>
+    >r [ "-" glue create-in ] with map r>
     [ define ] 2each ;
 
 : define-accessors ( classname slots -- )
index eeebe1c12de9184d3bbe20224ffe4fc415632cbc..8319a2d8d9d824a7b54a98415fe4c065ec264ded 100644 (file)
 
-USING: kernel namespaces
+USING: kernel
+       namespaces
+       arrays
+       accessors
+       strings
+       sequences
+       locals
+       threads
        math
-       math.constants
        math.functions
+       math.trig
        math.order
+       math.ranges
        math.vectors
-       math.trig
-       math.physics.pos
-       math.physics.vel
-       combinators arrays sequences random vars
-       combinators.lib
+       random
+       calendar
+       opengl.gl
+       opengl
+       ui
+       ui.gadgets
+       ui.gadgets.tracks
+       ui.gadgets.frames
+       ui.gadgets.grids
+       ui.render
+       multi-methods
+       multi-method-syntax
        combinators.short-circuit
-       accessors ;
+       processing.shapes
+       flatland ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 IN: boids
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-TUPLE: boid < vel ;
+: constrain ( n a b -- n ) rot min max ;
 
-C: <boid> boid
+: angle-between ( vec vec -- angle )
+  [ v. ] [ [ norm ] bi@ * ] 2bi / -1 1 constrain acos rad>deg ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-VAR: boids
-VAR: world-size
-VAR: time-slice
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: relative-position ( self other -- v ) swap [ pos>> ] bi@ v- ;
 
-VAR: cohesion-weight
-VAR: alignment-weight
-VAR: separation-weight
+: relative-angle ( self other -- angle )
+  over vel>> -rot relative-position angle-between ;
 
-VAR: cohesion-view-angle
-VAR: alignment-view-angle
-VAR: separation-view-angle
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-VAR: cohesion-radius
-VAR: alignment-radius
-VAR: separation-radius
+: in-radius? ( self other radius -- ? ) [ distance       ] dip     <= ;
+: in-view?   ( self other angle  -- ? ) [ relative-angle ] dip 2 / <= ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: init-variables ( -- )
-  1.0 >cohesion-weight
-  1.0 >alignment-weight
-  1.0 >separation-weight
-
-  75 >cohesion-radius
-  50 >alignment-radius
-  25 >separation-radius
+: vsum ( vector-of-vectors -- vec ) { 0 0 } [ v+ ] reduce ;
 
-  180 >cohesion-view-angle
-  180 >alignment-view-angle
-  180 >separation-view-angle
+: vaverage ( seq-of-vectors -- seq ) [ vsum ] [ length ] bi v/n ;
 
-  10 >time-slice ;
+: average-position ( boids -- pos ) [ pos>> ] map vaverage ;
+: average-velocity ( boids -- vel ) [ vel>> ] map vaverage ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! random-boid and random-boids
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: random-range ( a b -- n ) 1+ over - random + ;
 
-: random-pos ( -- pos ) world-size> [ random ] map ;
+TUPLE: <boid> < <vel> ;
 
-: random-vel ( -- vel ) 2 [ drop -10 10 random-range ] map ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: random-boid ( -- boid ) random-pos random-vel <boid> ;
+TUPLE: <behaviour>
+  { weight     initial: 1.0 }
+  { view-angle initial: 180 }
+  { radius                  } ;
 
-: random-boids ( n -- boids ) [ drop random-boid ] map ;
+TUPLE: <cohesion>   < <behaviour> { radius initial: 75 } ;
+TUPLE: <alignment>  < <behaviour> { radius initial: 50 } ;
+TUPLE: <separation> < <behaviour> { radius initial: 25 } ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: constrain ( n a b -- n ) rot min max ;
+:: within-neighborhood? ( SELF OTHER BEHAVIOUR -- ? )
 
-: angle-between ( vec vec -- angle )
-  2dup v. -rot norm swap norm * / -1 1 constrain acos rad>deg ;
+  SELF OTHER
+    {
+      [ BEHAVIOUR radius>>     in-radius? ]
+      [ BEHAVIOUR view-angle>> in-view?   ]
+      [ eq? not                           ]
+    }
+  2&& ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+:: neighborhood ( SELF OTHERS BEHAVIOUR -- boids )
+  OTHERS [| OTHER | SELF OTHER BEHAVIOUR within-neighborhood? ] filter ;
 
-: relative-position ( self other -- v ) swap [ pos>> ] bi@ v- ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: relative-angle ( self other -- angle )
-  over vel>> -rot relative-position angle-between ;
+: normalize* ( u -- v ) { 0.001 0.001 } v+ normalize ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: vsum ( vector-of-vectors -- vec ) { 0 0 } [ v+ ] reduce ;
+GENERIC: force* ( sequence <boid> <behaviour> -- force )
 
-: vaverage ( seq-of-vectors -- seq ) [ vsum ] [ length ] bi v/n ;
+:: cohesion-force ( OTHERS SELF BEHAVIOUR -- force )
+  OTHERS average-position SELF pos>> v- normalize* BEHAVIOUR weight>> v*n ;
 
-: average-position ( boids -- pos ) [ pos>> ] map vaverage ;
+:: alignment-force ( OTHERS SELF BEHAVIOUR -- force )
+  OTHERS average-velocity normalize* BEHAVIOUR weight>> v*n ;
 
-: average-velocity ( boids -- vel ) [ vel>> ] map vaverage ;
+:: separation-force ( OTHERS SELF BEHAVIOUR -- force )
+  SELF pos>> OTHERS average-position v- normalize* BEHAVIOUR weight>> v*n ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+METHOD: force* ( sequence <boid> <cohesion>   -- force ) cohesion-force   ;
+METHOD: force* ( sequence <boid> <alignment>  -- force ) alignment-force  ;
+METHOD: force* ( sequence <boid> <separation> -- force ) separation-force ;
 
-: in-range? ( self other radius -- ? ) >r distance r> <= ;
+:: force ( OTHERS SELF BEHAVIOUR -- force )
+  SELF OTHERS BEHAVIOUR neighborhood
+    [ { 0 0 } ]
+    [ SELF BEHAVIOUR force* ]
+  if-empty ;
 
-: in-view? ( self other angle -- ? ) >r relative-angle r> 2 / <= ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: random-boids ( count -- boids )
+  [
+    drop
+    <boid> new
+      2 [ drop         1000 random ] map >>pos
+      2 [ drop -10 10 [a,b] random ] map >>vel
+  ]
+  map ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: normalize* ( u -- v ) { 0.001 0.001 } v+ normalize ;
+: draw-boid ( boid -- )
+  glPushMatrix
+    dup pos>> gl-translate-2d
+        vel>> first2 rect> arg rad>deg 0 0 1 glRotated
+    { { 0 5 } { 0 -5 } { 20 0 } } triangle
+    fill-mode
+  glPopMatrix ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-! average_position(neighbors) - self_position
+: gadget->sky ( gadget -- sky ) { 0 0 } swap dim>> <rectangle> boa ;
 
-: within-cohesion-neighborhood? ( self other -- ? )
-  { [ cohesion-radius> in-range? ]
-    [ cohesion-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: cohesion-neighborhood ( self -- boids )
-  boids> [ within-cohesion-neighborhood? ] with filter ;
+USE: syntax ! Switch back to non-multi-method 'TUPLE:' syntax
 
-: cohesion-force ( self -- force )
-  dup cohesion-neighborhood
-  dup empty?
-  [ 2drop { 0 0 } ]
-  [ average-position swap pos>> v- normalize* cohesion-weight> v*n ]
-  if ;
+TUPLE: <boids-gadget> < gadget paused boids behaviours time-slice ;
+
+M:  <boids-gadget> pref-dim*    ( <boids-gadget> -- dim ) drop { 600 400 } ;
+M:  <boids-gadget> ungraft*     ( <boids-gadget> --     ) t >>paused drop  ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-! self_position - average_position(neighbors)
+:: iterate-system ( BOIDS-GADGET -- )
 
-: within-separation-neighborhood? ( self other -- ? )
-  { [ separation-radius> in-range? ]
-    [ separation-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+  [let | SKY        [ BOIDS-GADGET gadget->sky   ]
+         BOIDS      [ BOIDS-GADGET boids>>       ]
+         TIME-SLICE [ BOIDS-GADGET time-slice>>  ]
+         BEHAVIOURS [ BOIDS-GADGET behaviours>>  ] |
 
-: separation-neighborhood ( self -- boids )
-  boids> [ within-separation-neighborhood? ] with filter ;
+    BOIDS
 
-: separation-force ( self -- force )
-  dup separation-neighborhood
-  dup empty?
-  [ 2drop { 0 0 } ]
-  [ average-position swap pos>> swap v- normalize* separation-weight> v*n ]
-  if ;
+      [| SELF |
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        [wlet | force-due-to [| BEHAVIOUR | BOIDS SELF BEHAVIOUR force ] |
 
-! average_velocity(neighbors)
+          ! F = m a. M is 1. So F = a.
+            
+          [let | ACCEL [ BEHAVIOURS [ force-due-to ] map vsum ] |
 
-: within-alignment-neighborhood? ( self other -- ? )
-  { [ alignment-radius> in-range? ]
-    [ alignment-view-angle> in-view? ]
-    [ eq? not ] }
-  2&& ;
+            [let | POS [ SELF pos>> SELF vel>> TIME-SLICE v*n v+ ]
+                   VEL [ SELF vel>> ACCEL      TIME-SLICE v*n v+ ] |
 
-: alignment-neighborhood ( self -- boids )
-  boids> [ within-alignment-neighborhood? ] with filter ;
+              [let | POS [ POS SKY wrap   ]
+                     VEL [ VEL normalize* ] |
+                    
+                T{ <boid> f POS VEL } ] ] ] ]
 
-: alignment-force ( self -- force )
-  alignment-neighborhood
-  dup empty?
-  [ drop { 0 0 } ]
-  [ average-velocity normalize* alignment-weight> v*n ]
-  if ;
+      ]
+      
+    map
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    BOIDS-GADGET (>>boids) ] ;
 
-! F = m a
-!
-! We let m be equal to 1 so then this is simply: F = a
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: acceleration ( boid -- acceleration )
-  { separation-force alignment-force cohesion-force } map-exec-with vsum ;
+M:: <boids-gadget> draw-gadget* ( BOIDS-GADGET -- )
+  origin get
+    [ BOIDS-GADGET boids>> [ draw-boid ] each ]
+  with-translation ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! iterate-boid
+
+:: start-boids-thread ( GADGET -- )
+  GADGET f >>paused drop
+  [
+    [
+      GADGET paused>>
+        [ f ]
+        [ GADGET iterate-system GADGET relayout-1 1 milliseconds sleep t ]
+      if
+    ]
+    loop
+  ]
+  in-thread ;
+
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: world-width ( -- w ) world-size> first ;
+: default-behaviours ( -- seq )
+  { <cohesion> <alignment> <separation> } [ new ] map ;
+
+: boids-gadget ( -- gadget )
+  <boids-gadget> new-gadget
+    100 random-boids   >>boids
+    default-behaviours >>behaviours
+    10                 >>time-slice
+    t                  >>clipped? ;
 
-: world-height ( -- w ) world-size> second ;
+: run-boids ( -- ) boids-gadget dup "Boids" open-window start-boids-thread ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: below? ( n a b -- ? ) drop < ;
+USING: math.parser
+       ui.gadgets.labels
+       ui.gadgets.buttons
+       ui.gadgets.packs ;
+
+: truncate-number ( n -- n ) 10 * round 10 / ;
+
+:: make-behaviour-control ( NAME BEHAVIOUR -- gadget )
+  [let | NAME-LABEL  [ NAME           <label> reverse-video-theme ]
+         VALUE-LABEL [ 20 32 <string> <label> reverse-video-theme ] |
+
+    [wlet | update-value-label [ ! ( -- )
+              BEHAVIOUR weight>> truncate-number number>string
+              VALUE-LABEL
+              set-label-string ] |
+
+      update-value-label
+      
+    <pile> 1 >>fill
+      { 1 0 } <track>
+        NAME-LABEL  0.5 track-add
+        VALUE-LABEL 0.5 track-add
+      add-gadget
+      
+      "+0.1"
+      [
+        drop
+        BEHAVIOUR [ 0.1 + ] change-weight drop
+        update-value-label
+      ]
+      <bevel-button> add-gadget
+      
+      "-0.1"
+      [
+        drop
+        BEHAVIOUR weight>> 0.1 >
+        [
+          BEHAVIOUR [ 0.1 - ] change-weight drop
+          update-value-label
+        ]
+        when
+      ]
+      <bevel-button> add-gadget ] ] ;
 
-: above? ( n a b -- ? ) nip > ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: wrap ( n a b -- n )
-  {
-    { [ 3dup below? ] [ 2nip     ] }
-    { [ 3dup above? ] [ drop nip ] }
-    { [ t           ] [ 2drop    ] }
-  }
-  cond ;
+:: make-population-control ( BOIDS-GADGET -- gadget )
+  [let | VALUE-LABEL [ 20 32 <string> <label> reverse-video-theme ] |
+
+    [wlet | update-value-label [ ( -- )
+              BOIDS-GADGET boids>> length number>string
+              VALUE-LABEL
+              set-label-string ] |
+
+      update-value-label
+      
+      <pile> 1 >>fill
+    
+        { 1 0 } <track>
+          "Population: " <label> reverse-video-theme 0.5 track-add
+          VALUE-LABEL                                0.5 track-add
+        add-gadget
+
+        "Add 10"
+        [
+          drop
+          BOIDS-GADGET
+            BOIDS-GADGET boids>> 10 random-boids append
+          >>boids
+          drop
+          update-value-label
+        ]
+        <bevel-button>
+        add-gadget
+
+        "Sub 10"
+        [
+          drop
+          BOIDS-GADGET boids>> length 10 >
+          [
+            BOIDS-GADGET
+              BOIDS-GADGET boids>> 10 tail
+            >>boids
+            drop
+            update-value-label
+          ]
+          when
+        ]
+        <bevel-button>
+        add-gadget ] ] ( gadget -- gadget ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: wrap-x ( x -- x ) 0 world-width 1- wrap ;
+:: pause-toggle ( BOIDS-GADGET -- )
+  BOIDS-GADGET paused>>
+    [ BOIDS-GADGET start-boids-thread ]
+    [ BOIDS-GADGET t >>paused drop    ]
+  if ;
 
-: wrap-y ( y -- y ) 0 world-height 1- wrap ;
+:: randomize-boids ( BOIDS-GADGET -- )
+  BOIDS-GADGET   BOIDS-GADGET boids>> length random-boids   >>boids drop ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: boids-app ( -- )
 
-: new-pos ( boid -- pos ) [ pos>> ] [ vel>> time-slice> v*n ] bi v+ ;
+  [let | BOIDS-GADGET [ boids-gadget ] |
 
-: new-vel ( boid -- vel )
-  [ vel>> ] [ acceleration time-slice> v*n ] bi v+ normalize* ;
+    <frame>
 
-: wrap-pos ( pos -- pos ) { [ wrap-x ] [ wrap-y ] } parallel-call ;
+      <shelf>
 
-: iterate-boid ( self -- self ) [ new-pos wrap-pos ] [ new-vel ] bi <boid> ;
+        1 >>fill
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        "Pause" [ drop BOIDS-GADGET pause-toggle ] <bevel-button> add-gadget
 
-: iterate-boids ( -- ) boids> [ iterate-boid ] map >boids ;
+        "Randomize"
+        [ drop BOIDS-GADGET randomize-boids ] <bevel-button> add-gadget
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        BOIDS-GADGET make-population-control add-gadget
+    
+        "Cohesion:   " BOIDS-GADGET behaviours>> first  make-behaviour-control 
+        "Alignment:  " BOIDS-GADGET behaviours>> second make-behaviour-control
+        "Separation: " BOIDS-GADGET behaviours>> third  make-behaviour-control
 
-: init-boids ( -- ) 100 random-boids >boids ;
+        [ add-gadget ] tri@
 
-: init-world-size ( -- ) { 100 100 } >world-size ;
+      @top grid-add
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      BOIDS-GADGET @center grid-add
+
+    "Boids" open-window
 
-: randomize ( -- ) boids> length random-boids >boids ;
+    BOIDS-GADGET start-boids-thread ] ;
 
-: inc* ( variable -- ) dup  get 0.1 +  0 1 constrain  swap set ;
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: dec* ( variable -- ) dup  get 0.1 -  0 1 constrain  swap set ;
+: boids-main ( -- ) [ boids-app ] with-ui ;
 
+MAIN: boids-main
\ No newline at end of file
diff --git a/extra/boids/ui/authors.txt b/extra/boids/ui/authors.txt
deleted file mode 100755 (executable)
index 6cfd5da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Eduardo Cavazos
diff --git a/extra/boids/ui/deploy.factor b/extra/boids/ui/deploy.factor
deleted file mode 100755 (executable)
index 8b3c0ba..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-USING: tools.deploy.config ;
-H{
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-c-types? f }
-    { deploy-ui? t }
-    { deploy-io 2 }
-    { deploy-threads? t }
-    { deploy-word-defs? f }
-    { deploy-compiler? t }
-    { deploy-unicode? f }
-    { deploy-name "Boids" }
-    { "stop-after-last-window?" t }
-    { deploy-reflection 1 }
-}
diff --git a/extra/boids/ui/tags.txt b/extra/boids/ui/tags.txt
deleted file mode 100644 (file)
index cb5fc20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-demos
diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor
deleted file mode 100755 (executable)
index ddb25cc..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-
-USING: combinators.short-circuit kernel namespaces
-       math
-       math.trig
-       math.functions
-       math.vectors
-       math.parser
-       hashtables sequences threads
-       colors
-       opengl
-       opengl.gl
-       ui
-       ui.gadgets
-       ui.gadgets.handler
-       ui.gadgets.slate
-       ui.gadgets.theme
-       ui.gadgets.frames
-       ui.gadgets.labels
-       ui.gadgets.buttons
-       ui.gadgets.packs
-       ui.gadgets.grids
-       ui.gestures
-       assocs.lib vars rewrite-closures boids accessors
-       math.geometry.rect
-       newfx
-       processing.shapes ;
-
-IN: boids.ui
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! draw-boid
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: draw-boid ( boid -- )
-  glPushMatrix
-    dup pos>> gl-translate-2d
-        vel>> first2 rect> arg rad>deg 0 0 1 glRotated
-    { { 0 5 } { 0 -5 } { 20 0 } } triangle
-    fill-mode
-  glPopMatrix ;
-
-: draw-boids ( -- ) boids> [ draw-boid ] each ;
-
-: boid-color ( -- color ) T{ rgba f 1.0 0 0 0.3 } ;
-
-: display ( -- )
-  boid-color >fill-color
-  draw-boids ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: slate
-
-VAR: loop
-
-: run ( -- )
-  slate> rect-dim >world-size
-  iterate-boids
-  slate> relayout-1
-  yield
-  loop> [ run ] when ;
-
-: button* ( string quot -- button ) closed-quot <bevel-button> ;
-
-: toggle-loop ( -- ) loop> [ loop off ] [ loop on [ run ] in-thread ] if ;
-
-VARS: population-label cohesion-label alignment-label separation-label ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: update-population-label ( -- )
-  "Population: " boids> length number>string append
-  20 32 pad-right population-label> set-label-string ;
-
-: add-10-boids ( -- )
-  boids> 10 random-boids append >boids update-population-label ;
-
-: sub-10-boids ( -- )
-  boids> 10 tail >boids update-population-label ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: truncate-value ( n -- n ) 10 * round 10 / ;
-
-: update-cohesion-label ( -- )
-  "Cohesion: " cohesion-weight> truncate-value number>string append
-  20 32 pad-right cohesion-label> set-label-string ;
-
-: update-alignment-label ( -- )
-  "Alignment: " alignment-weight> truncate-value number>string append
-  20 32 pad-right alignment-label> set-label-string ;
-
-: update-separation-label ( -- )
-  "Separation: " separation-weight> truncate-value number>string append
-  20 32 pad-right separation-label> set-label-string ;
-
-: inc-cohesion-weight ( -- ) cohesion-weight inc* update-cohesion-label ;
-: dec-cohesion-weight ( -- ) cohesion-weight dec* update-cohesion-label ;
-
-: inc-alignment-weight ( -- ) alignment-weight inc* update-alignment-label ;
-: dec-alignment-weight ( -- ) alignment-weight dec* update-alignment-label ;
-
-: inc-separation-weight ( -- ) separation-weight inc* update-separation-label ;
-: dec-separation-weight ( -- ) separation-weight dec* update-separation-label ;
-
-: boids-window* ( -- )
-  init-variables init-world-size init-boids loop on
-
-  "" <label> reverse-video-theme >population-label update-population-label
-  "" <label> reverse-video-theme >cohesion-label   update-cohesion-label
-  "" <label> reverse-video-theme >alignment-label  update-alignment-label
-  "" <label> reverse-video-theme >separation-label update-separation-label
-
-  <frame>
-
-    <shelf>
-
-       1 >>fill
-
-      "ESC - Pause" [ drop toggle-loop ] button* add-gadget
-    
-      "1 - Randomize" [ drop randomize ] button* add-gadget
-    
-      <pile> 1 >>fill
-        population-label> add-gadget
-        "3 - Add 10" [ drop add-10-boids ] button* add-gadget
-        "2 - Sub 10" [ drop sub-10-boids ] button* add-gadget
-      add-gadget
-    
-      <pile> 1 >>fill
-        cohesion-label> add-gadget
-        "q - +0.1" [ drop inc-cohesion-weight ] button* add-gadget
-        "a - -0.1" [ drop dec-cohesion-weight ] button* add-gadget
-      add-gadget
-
-      <pile> 1 >>fill
-        alignment-label> add-gadget
-        "w - +0.1" [ drop inc-alignment-weight ] button* add-gadget
-        "s - -0.1" [ drop dec-alignment-weight ] button* add-gadget
-      add-gadget
-
-      <pile> 1 >>fill
-        separation-label> add-gadget
-        "e - +0.1" [ drop inc-separation-weight ] button* add-gadget
-        "d - -0.1" [ drop dec-separation-weight ] button* add-gadget
-      add-gadget
-
-    @top grid-add
-
-    C[ display ] <slate>
-      dup                    >slate
-      t                      >>clipped?
-      { 600 400 }            >>pdim
-      C[ [ run ] in-thread ] >>graft
-      C[ loop off ]          >>ungraft
-    @center grid-add
-
-  <handler> 
-    H{ } clone
-      T{ key-down f f "1"   } C[ drop randomize             ] is
-      T{ key-down f f "2"   } C[ drop sub-10-boids          ] is
-      T{ key-down f f "3"   } C[ drop add-10-boids          ] is
-      T{ key-down f f "q"   } C[ drop inc-cohesion-weight   ] is
-      T{ key-down f f "a"   } C[ drop dec-cohesion-weight   ] is
-      T{ key-down f f "w"   } C[ drop inc-alignment-weight  ] is
-      T{ key-down f f "s"   } C[ drop dec-alignment-weight  ] is
-      T{ key-down f f "e"   } C[ drop inc-separation-weight ] is
-      T{ key-down f f "d"   } C[ drop dec-separation-weight ] is
-      T{ key-down f f "ESC" } C[ drop toggle-loop           ] is
-    >>table
-
-  "Boids" open-window ;
-
-: boids-window ( -- ) [ [ boids-window* ] with-scope ] with-ui ;
-
-MAIN: boids-window
old mode 100644 (file)
new mode 100755 (executable)
index 0bad9cc..0791773
@@ -1,5 +1,6 @@
 USING: alien.c-types continuations destructors kernel
-opengl opengl.gl bunny.model ;
+opengl opengl.gl bunny.model specialized-arrays.float
+accessors ;
 IN: bunny.fixed-pipeline
 
 TUPLE: bunny-fixed-pipeline ;
@@ -13,7 +14,7 @@ M: bunny-fixed-pipeline draw-bunny
     GL_LIGHTING glEnable
     GL_LIGHT0 glEnable
     GL_COLOR_MATERIAL glEnable
-    GL_LIGHT0 GL_POSITION { 1.0 -1.0 1.0 1.0 } >c-float-array glLightfv
+    GL_LIGHT0 GL_POSITION float-array{ 1.0 -1.0 1.0 1.0 } underlying>> glLightfv
     GL_FRONT_AND_BACK GL_SHININESS 100.0 glMaterialf
     GL_FRONT_AND_BACK GL_SPECULAR glColorMaterial
     GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE glColorMaterial
index 1bbaf796ade41f3e01c1818059a0f91c97490993..452adf56891cb7da3d46d14525df42d2812ed834 100755 (executable)
@@ -2,7 +2,8 @@ USING: accessors alien.c-types arrays combinators destructors
 http.client io io.encodings.ascii io.files kernel math
 math.matrices math.parser math.vectors opengl
 opengl.capabilities opengl.gl opengl.demo-support sequences
-sequences.lib splitting vectors words ;
+sequences.lib splitting vectors words
+specialized-arrays.float specialized-arrays.uint ;
 IN: bunny.model
 
 : numbers ( str -- seq )
@@ -65,11 +66,11 @@ TUPLE: bunny-buffers array element-array nv ni ;
     {
         [
             [ first concat ] [ second concat ] bi
-            append >c-float-array
+            append >float-array underlying>>
             GL_ARRAY_BUFFER swap GL_STATIC_DRAW <gl-buffer>
         ]
         [
-            third concat >c-uint-array
+            third concat >uint-array underlying>>
             GL_ELEMENT_ARRAY_BUFFER swap GL_STATIC_DRAW <gl-buffer>
         ]
         [ first length 3 * ]
index 0f21142f2a3e94468187a8b2801256d983c609fb..bdd02c9e1330f245d2f64b06f201776dcefb20db 100644 (file)
@@ -5,7 +5,7 @@
 ! http://cairographics.org/samples/
 USING: cairo cairo.ffi locals math.constants math
 io.backend kernel alien.c-types libc namespaces
-cairo.gadgets ui.gadgets accessors ;
+cairo.gadgets ui.gadgets accessors specialized-arrays.double ;
 
 IN: cairo.samples
 
@@ -69,7 +69,7 @@ M:: clip-image-gadget render-cairo* ( gadget -- )
 
 TUPLE: dash-gadget < cairo-gadget ;
 M:: dash-gadget render-cairo* ( gadget -- )
-    [let | dashes [ { 50 10 10 10 } >c-double-array ]
+    [let | dashes [ double-array{ 50 10 10 10 } underlying>> ]
            ndash [ 4 ] |
         cr dashes ndash -50 cairo_set_dash
         cr 10 cairo_set_line_width
index 3bd1a5f174d42bc22dd65e281fcb6cadf80c7c6b..716435775d651534c39fc27f9af775f356c6b491 100644 (file)
@@ -2,7 +2,7 @@
 ! 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
-models opengl.framebuffers ui.gadgets.worlds ui.gadgets fry alien.syntax ;
+models ui.gadgets.worlds ui.gadgets fry alien.syntax ;
 IN: cap
 
 : screenshot-array ( world -- byte-array )
index 3278cc6ec1f04a9ca5f995abba938b52facf6336..e1c89374fd2cae73de6f188dd9ea41d6e3084ca9 100644 (file)
@@ -6,8 +6,10 @@ USING: kernel alien.c-types combinators namespaces make arrays
        vars colors self self.slots
        random-weighted colors.hsv cfdg.gl accessors
        ui.gadgets.handler ui.gestures assocs ui.gadgets macros
-       qualified ;
+       qualified specialized-arrays.double ;
+
 QUALIFIED: syntax
+
 IN: cfdg
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -53,7 +55,10 @@ VAR: color-stack
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: double-nth* ( c-array indices -- seq ) swap [ double-nth ] curry map ;
+! : double-nth* ( c-array indices -- seq ) swap [ double-nth ] curry map ;
+
+: double-nth* ( c-array indices -- seq )
+  swap byte-array>double-array [ nth ] curry map ;
 
 : check-size ( modelview -- num ) { 0 1 4 5 } double-nth* [ abs ] map biggest ;
 
@@ -75,7 +80,7 @@ VAR: threshold
     2 * sin ,   2 * cos neg ,   0 ,   0 ,
           0 ,             0 ,   1 ,   0 , 
           0 ,             0 ,   0 ,   1 , ]
-  { } make >c-double-array glMultMatrixd ;
+  double-array{ } make underlying>> glMultMatrixd ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
diff --git a/extra/combinators/cleave/enhanced/enhanced.factor b/extra/combinators/cleave/enhanced/enhanced.factor
new file mode 100644 (file)
index 0000000..b55979a
--- /dev/null
@@ -0,0 +1,31 @@
+
+USING: combinators.cleave fry kernel macros parser quotations ;
+
+IN: combinators.cleave.enhanced
+
+: \\
+  scan-word literalize parsed
+  scan-word literalize parsed ; parsing
+
+MACRO: bi ( p q -- quot )
+  [ >quot ] dip
+    >quot
+  '[ _ _ [ keep ] dip call ] ;
+
+MACRO: tri ( p q r -- quot )
+  [ >quot ] 2dip
+  [ >quot ] dip
+    >quot
+  '[ _ _ _ [ [ keep ] dip keep ] dip call ] ;
+
+MACRO: bi* ( p q -- quot )
+  [ >quot ] dip
+    >quot
+  '[ _ _ [ dip ] dip call ] ;
+
+MACRO: tri* ( p q r -- quot )
+  [ >quot ] 2dip
+  [ >quot ] dip
+    >quot
+  '[ _ _ _ [ [ 2dip ] dip dip ] dip call ] ;
+
index dd8fbd89f57b220c24930a11b501e8ae05211245..ac8c3d11d8e6bc9218c6bfd8d23b658b429498b2 100755 (executable)
@@ -31,7 +31,7 @@ IN: combinators.lib
 ! Generalized versions of core combinators
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: quad ( x p q r s -- ) >r >r >r keep r> keep r> keep r> call ; inline
+: quad ( x p q r s -- ) [ keep ] 3dip [ keep ] 2dip [ keep ] dip call ; inline
 
 : 4slip ( quot a b c d -- a b c d ) 4 nslip ; inline
 
@@ -123,10 +123,10 @@ MACRO: construct-slots ( assoc tuple-class -- tuple )
     >r pick >r with r> r> swapd with ;
 
 : or? ( obj quot1 quot2 -- ? )
-    >r keep r> rot [ 2nip ] [ call ] if* ; inline
+    [ keep ] dip rot [ 2nip ] [ call ] if* ; inline
 
 : and? ( obj quot1 quot2 -- ? )
-    >r keep r> rot [ call ] [ 2drop f ] if ; inline
+    [ keep ] dip rot [ call ] [ 2drop f ] if ; inline
 
 MACRO: multikeep ( word out-indexes -- ... )
     [
@@ -135,19 +135,16 @@ MACRO: multikeep ( word out-indexes -- ... )
         r> [ drop \ r> , ] each
     ] [ ] make ;
 
-: retry ( quot n -- )
-    [ drop ] rot compose attempt-all ; inline
-
 : do-while ( pred body tail -- )
-    >r tuck 2slip r> while ; inline
+    [ tuck 2slip ] dip while ; inline
 
 : generate ( generator predicate -- obj )
-    [ dup ] swap [ dup [ nip ] unless not ] 3compose
+    '[ dup @ dup [ nip ] unless not ]
     swap [ ] do-while ;
 
 MACRO: predicates ( seq -- quot/f )
     dup [ 1quotation [ drop ] prepend ] map
-    >r [ [ dup ] prepend ] map r> zip [ drop f ] suffix
+    [ [ [ dup ] prepend ] map ] dip zip [ drop f ] suffix
     [ cond ] curry ;
 
 : %chance ( quot n -- ) 100 random > swap when ; inline
index f6fcac52970843105f067a39a214fb5493b51152..4d6479db915d00bb1bfb9fa31de98a05d29a5148 100755 (executable)
@@ -1,7 +1,7 @@
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io.files io.launcher io.styles io.encodings.ascii io
-hashtables kernel sequences sequences.lib assocs system sorting
+USING: io.files io.launcher io.styles io.encodings.ascii
+prettyprint io hashtables kernel sequences assocs system sorting
 math.parser sets ;
 IN: contributors
 
@@ -16,15 +16,8 @@ IN: contributors
     { } map>assoc ;
 
 : contributors ( -- )
-    changelog patch-counts sort-values <reversed>
-    standard-table-style [
-        [
-            [
-                first2 swap
-                [ write ] with-cell
-                [ number>string write ] with-cell
-            ] with-row
-        ] each
-    ] tabular-output ;
+    changelog patch-counts
+    sort-values <reversed>
+    simple-table. ;
 
 MAIN: contributors
index 214b45ce0c0ef8fd70025a472ffa6dcfc406cc70..be3ba40ac008da4261d74951333af733e414683e 100644 (file)
@@ -285,7 +285,7 @@ SYMBOLS: NO-ERROR FORMAT-ERROR SERVER-FAILURE NAME-ERROR NOT-IMPLEMENTED
           [ get-label ]
           [ skip-label get-name ]
           2bi
-          "." swap 3append
+          "." glue 
         ]
       }
     }
diff --git a/extra/flatland/flatland.factor b/extra/flatland/flatland.factor
new file mode 100644 (file)
index 0000000..c98c5a6
--- /dev/null
@@ -0,0 +1,220 @@
+
+USING: accessors arrays fry kernel math math.vectors sequences
+       math.intervals
+       multi-methods
+       combinators.cleave.enhanced
+       multi-method-syntax ;
+
+IN: flatland
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Two dimensional world protocol
+
+GENERIC: x ( obj -- x )
+GENERIC: y ( obj -- y )
+
+GENERIC: (x!) ( x obj -- )
+GENERIC: (y!) ( y obj -- )
+
+: x! ( obj x -- obj ) over (x!) ;
+: y! ( obj y -- obj ) over (y!) ;
+
+GENERIC: width  ( obj -- width  )
+GENERIC: height ( obj -- height )
+
+GENERIC: (width!)  ( width  obj -- )
+GENERIC: (height!) ( height obj -- )
+
+: width!  ( obj width  -- obj ) over (width!) ;
+: height! ( obj height -- obj ) over (width!) ;
+
+! Predicates on relative placement
+
+GENERIC: to-the-left-of?  ( obj obj -- ? )
+GENERIC: to-the-right-of? ( obj obj -- ? )
+
+GENERIC: below? ( obj obj -- ? )
+GENERIC: above? ( obj obj -- ? )
+
+GENERIC: in-between-horizontally? ( obj obj -- ? )
+
+GENERIC: horizontal-interval ( obj -- interval )
+
+GENERIC: move-to ( obj obj -- )
+
+GENERIC: move-by ( obj delta -- )
+
+GENERIC: move-left-by  ( obj obj -- )
+GENERIC: move-right-by ( obj obj -- )
+
+GENERIC: left   ( obj -- left   )
+GENERIC: right  ( obj -- right  )
+GENERIC: bottom ( obj -- bottom )
+GENERIC: top    ( obj -- top    )
+
+GENERIC: distance ( a b -- c )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Some of the above methods work on two element sequences.
+! A two element sequence may represent a point in space or describe
+! width and height.
+
+METHOD: x ( sequence -- x ) first  ;
+METHOD: y ( sequence -- y ) second ;
+
+METHOD: (x!) ( number sequence -- ) set-first  ;
+METHOD: (y!) ( number sequence -- ) set-second ;
+
+METHOD: width  ( sequence -- width  ) first  ;
+METHOD: height ( sequence -- height ) second ;
+
+: changed-x ( seq quot -- ) over [ [ x ] dip call ] dip (x!) ; inline
+: changed-y ( seq quot -- ) over [ [ y ] dip call ] dip (y!) ; inline
+
+METHOD: move-to ( sequence sequence -- )         [ x x! ] [ y y! ] bi drop ;
+METHOD: move-by ( sequence sequence -- ) dupd v+ [ x x! ] [ y y! ] bi drop ;
+
+METHOD: move-left-by  ( sequence number -- ) '[ _ - ] changed-x ;
+METHOD: move-right-by ( sequence number -- ) '[ _ + ] changed-x ;
+
+! METHOD: move-left-by  ( sequence number -- ) neg 0 2array move-by ;
+! METHOD: move-right-by ( sequence number -- )     0 2array move-by ;
+
+! METHOD:: move-left-by  ( SEQ:sequence X:number -- )
+!   SEQ { X 0 } { -1 0 } v* move-by ;
+
+METHOD: distance ( sequence sequence -- dist ) v- norm ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! A class for objects with a position
+
+TUPLE: <pos> pos ;
+
+METHOD: x ( <pos> -- x ) pos>> first  ;
+METHOD: y ( <pos> -- y ) pos>> second ;
+
+METHOD: (x!) ( number <pos> -- ) pos>> set-first  ;
+METHOD: (y!) ( number <pos> -- ) pos>> set-second ;
+
+METHOD: to-the-left-of?  ( <pos> number -- ? ) [ x ] dip < ;
+METHOD: to-the-right-of? ( <pos> number -- ? ) [ x ] dip > ;
+
+METHOD: move-left-by  ( <pos> number -- ) [ pos>> ] dip move-left-by  ;
+METHOD: move-right-by ( <pos> number -- ) [ pos>> ] dip move-right-by ;
+
+METHOD: above? ( <pos> number -- ? ) [ y ] dip > ;
+METHOD: below? ( <pos> number -- ? ) [ y ] dip < ;
+
+METHOD: move-by ( <pos> sequence -- ) '[ _ v+ ] change-pos drop ;
+
+METHOD: distance ( <pos> <pos> -- dist ) [ pos>> ] bi@ distance ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! A class for objects with velocity. It inherits from <pos>. Hey, if
+! it's moving it has a position right? Unless it's some alternate universe...
+
+TUPLE: <vel> < <pos> vel ;
+
+: moving-up?   ( obj -- ? ) vel>> y 0 > ;
+: moving-down? ( obj -- ? ) vel>> y 0 < ;
+
+: step-size ( vel time -- dist ) [ vel>> ] dip v*n      ;
+: move-for  ( vel time --      ) dupd step-size move-by ;
+
+: reverse-horizontal-velocity ( vel -- ) vel>> [ x neg ] [ ] bi (x!) ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! The 'pos' slot indicates the lower left hand corner of the
+! rectangle. The 'dim' is holds the width and height.
+
+TUPLE: <rectangle> < <pos> dim ;
+
+METHOD: width  ( <rectangle> -- width  ) dim>> first  ;
+METHOD: height ( <rectangle> -- height ) dim>> second ;
+
+METHOD: left   ( <rectangle> -- x )    x             ;
+METHOD: right  ( <rectangle> -- x ) \\ x width  bi + ;
+METHOD: bottom ( <rectangle> -- y )    y             ;
+METHOD: top    ( <rectangle> -- y ) \\ y height bi + ;
+
+: bottom-left ( rectangle -- pos ) pos>> ;
+
+: center-x ( rectangle -- x ) [ left   ] [ width  2 / ] bi + ;
+: center-y ( rectangle -- y ) [ bottom ] [ height 2 / ] bi + ;
+
+: center ( rectangle -- seq ) \\ center-x center-y bi 2array ;
+
+METHOD: to-the-left-of?  ( <pos> <rectangle> -- ? ) \\ x left  bi* < ;
+METHOD: to-the-right-of? ( <pos> <rectangle> -- ? ) \\ x right bi* > ;
+
+METHOD: below? ( <pos> <rectangle> -- ? ) \\ y bottom bi* < ;
+METHOD: above? ( <pos> <rectangle> -- ? ) \\ y top    bi* > ;
+
+METHOD: horizontal-interval ( <rectangle> -- interval )
+  \\ left right bi [a,b] ;
+
+METHOD: in-between-horizontally? ( <pos> <rectangle> -- ? )
+  \\ x horizontal-interval bi* interval-contains? ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <extent> left right bottom top ;
+
+METHOD: left   ( <extent> -- left   ) left>>   ;
+METHOD: right  ( <extent> -- right  ) right>>  ;
+METHOD: bottom ( <extent> -- bottom ) bottom>> ;
+METHOD: top    ( <extent> -- top    ) top>>    ;
+
+METHOD: width  ( <extent> -- width  ) \\ right>> left>>   bi - ;
+METHOD: height ( <extent> -- height ) \\ top>>   bottom>> bi - ;
+
+! METHOD: to-extent ( <rectangle> -- <extent> )
+!   { [ left>> ] [ right>> ] [ bottom>> ] [ top>> ] } cleave <extent> boa ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: to-the-left-of?  ( sequence <rectangle> -- ? ) \\ x left  bi* < ;
+METHOD: to-the-right-of? ( sequence <rectangle> -- ? ) \\ x right bi* > ;
+
+METHOD: below? ( sequence <rectangle> -- ? ) \\ y bottom bi* < ;
+METHOD: above? ( sequence <rectangle> -- ? ) \\ y top    bi* > ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Some support for the' 'rect' class from math.geometry.rect'
+
+! METHOD: width  ( rect -- width  ) dim>> first  ;
+! METHOD: height ( rect -- height ) dim>> second ;
+
+! METHOD: left  ( rect -- left  ) loc>> x
+! METHOD: right ( rect -- right ) [ loc>> x ] [ width ] bi + ;
+
+! METHOD: to-the-left-of?  ( sequence rect -- ? ) [ x ] [ loc>> x ] bi* < ;
+! METHOD: to-the-right-of? ( sequence rect -- ? ) [ x ] [ loc>> x ] bi* > ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: locals combinators ; 
+
+:: wrap ( POINT RECT -- POINT )
+    
+  {
+      { [ POINT RECT to-the-left-of?  ] [ RECT right ] }
+      { [ POINT RECT to-the-right-of? ] [ RECT left  ] }
+      { [ t                           ] [ POINT x    ] }
+  }
+  cond
+
+  {
+      { [ POINT RECT below? ] [ RECT top    ] }
+      { [ POINT RECT above? ] [ RECT bottom ] }
+      { [ t                 ] [ POINT y     ] }
+  }
+  cond
+
+  2array ;
diff --git a/extra/ftp/client/authors.txt b/extra/ftp/client/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/ftp/client/client.factor b/extra/ftp/client/client.factor
deleted file mode 100644 (file)
index 9c82cdb..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays classes.singleton combinators
-continuations io io.encodings.binary io.encodings.utf8
-io.files io.sockets kernel io.streams.duplex math
-math.parser sequences splitting namespaces strings fry ftp
-ftp.client.listing-parser urls ;
-IN: ftp.client
-
-: (ftp-response-code) ( str -- n )
-    3 head string>number ;
-
-: ftp-response-code ( string -- n/f )
-    dup fourth CHAR: - = [ drop f ] [ (ftp-response-code) ] if ;
-
-: read-response-loop ( ftp-response -- ftp-response )
-    readln
-    [ add-response-line ] [ ftp-response-code ] bi
-    over n>> = [ read-response-loop ] unless ;
-
-: read-response ( -- ftp-response )
-    <ftp-response> readln
-    [ (ftp-response-code) >>n ]
-    [ add-response-line ]
-    [ fourth CHAR: - = ] tri
-    [ read-response-loop ] when ;
-
-ERROR: ftp-error got expected ;
-
-: ftp-assert ( ftp-response n -- )
-    2dup [ n>> ] dip = [ 2drop ] [ ftp-error ] if ;
-
-: ftp-command ( string -- ftp-response )
-    ftp-send read-response ;
-
-: ftp-user ( url -- ftp-response )
-    username>> "USER " prepend ftp-command ;
-
-: ftp-password ( url -- ftp-response )
-    password>> "PASS " prepend ftp-command ;
-
-: ftp-cwd ( directory -- ftp-response )
-    "CWD " prepend ftp-command ;
-
-: ftp-retr ( filename -- ftp-response )
-    "RETR " prepend ftp-command ;
-
-: ftp-set-binary ( -- ftp-response ) "TYPE I" ftp-command ;
-
-: ftp-pwd ( -- ftp-response ) "PWD" ftp-command ;
-
-: ftp-list ( -- )
-    "LIST" ftp-command 150 ftp-assert ;
-
-: ftp-quit ( -- ftp-response ) "QUIT" ftp-command ;
-
-: ftp-epsv ( -- ftp-response )
-    "EPSV" ftp-command dup 229 ftp-assert ;
-
-: parse-epsv ( ftp-response -- port )
-    strings>> first "|" split 2 tail* first string>number ;
-
-: open-passive-client ( url protocol -- stream )
-    [ host>> ftp-epsv parse-epsv <inet> ] dip <client> drop ;
-
-: list ( url -- ftp-response )
-    utf8 open-passive-client
-    ftp-list
-    lines
-    <ftp-response> swap >>strings
-    read-response 226 ftp-assert
-    parse-list ;
-
-: (ftp-get) ( url path -- )
-    [ binary open-passive-client ] dip
-    [ ftp-retr 150 ftp-assert drop ]
-    [ binary <file-writer> stream-copy ] 2bi
-    read-response 226 ftp-assert ;
-
-: ftp-login ( url -- )
-    read-response 220 ftp-assert
-    [ ftp-user 331 ftp-assert ]
-    [ ftp-password 230 ftp-assert ] bi
-    ftp-set-binary 200 ftp-assert ;
-
-: ftp-connect ( url -- stream )
-    [ host>> ] [ port>> ] bi <inet> utf8 <client> drop ;
-
-: with-ftp-client ( url quot -- )
-    [ [ ftp-connect ] keep ] dip
-    '[ _ [ ftp-login ] _ bi ftp-quit drop ] with-stream ; inline
-
-: ensure-login ( url -- url )
-    dup username>> [
-        "anonymous" >>username
-        "ftp-client" >>password
-    ] unless ;
-
-: >ftp-url ( url -- url' ) >url ensure-port ensure-login ;
-
-: ftp-get ( url -- )
-    >ftp-url [
-        dup path>>
-        [ nip parent-directory ftp-cwd drop ]
-        [ file-name (ftp-get) ] 2bi
-    ] with-ftp-client ;
-
-
-
-
diff --git a/extra/ftp/client/listing-parser/authors.txt b/extra/ftp/client/listing-parser/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/extra/ftp/client/listing-parser/listing-parser.factor b/extra/ftp/client/listing-parser/listing-parser.factor
deleted file mode 100644 (file)
index 04e96ed..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators io.files kernel math.parser
-sequences splitting ;
-IN: ftp.client.listing-parser
-
-: ch>file-type ( ch -- type )
-    {
-        { CHAR: b [ +block-device+ ] }
-        { CHAR: c [ +character-device+ ] }
-        { CHAR: d [ +directory+ ] }
-        { CHAR: l [ +symbolic-link+ ] }
-        { CHAR: s [ +socket+ ] }
-        { CHAR: p [ +fifo+ ] }
-        { CHAR: - [ +regular-file+ ] }
-        [ drop +unknown+ ]
-    } case ;
-
-: file-type>ch ( type -- string )
-    {
-        { +block-device+ [ CHAR: b ] }
-        { +character-device+ [ CHAR: c ] }
-        { +directory+ [ CHAR: d ] }
-        { +symbolic-link+ [ CHAR: l ] }
-        { +socket+ [ CHAR: s ] }
-        { +fifo+ [ CHAR: p ] }
-        { +regular-file+ [ CHAR: - ] }
-        [ drop CHAR: - ]
-    } case ;
-
-: parse-permissions ( remote-file str -- remote-file )
-    [ first ch>file-type >>type ] [ rest >>permissions ] bi ;
-
-TUPLE: remote-file
-type permissions links owner group size month day time year
-name target ;
-
-: <remote-file> ( -- remote-file ) remote-file new ;
-
-: parse-list-11 ( lines -- seq )
-    [
-        11 f pad-right
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>owner ]
-            [ 3 swap nth >>group ]
-            [ 4 swap nth string>number >>size ]
-            [ 5 swap nth >>month ]
-            [ 6 swap nth >>day ]
-            [ 7 swap nth >>time ]
-            [ 8 swap nth >>name ]
-            [ 10 swap nth >>target ]
-        } cleave
-    ] map ;
-
-: parse-list-8 ( lines -- seq )
-    [
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>owner ]
-            [ 3 swap nth >>size ]
-            [ 4 swap nth >>month ]
-            [ 5 swap nth >>day ]
-            [ 6 swap nth >>time ]
-            [ 7 swap nth >>name ]
-        } cleave
-    ] map ;
-
-: parse-list-3 ( lines -- seq )
-    [
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>name ]
-        } cleave
-    ] map ;
-
-: parse-list ( ftp-response -- ftp-response )
-    dup strings>>
-    [ " " split harvest ] map
-    dup length {
-        { 11 [ parse-list-11 ] }
-        { 9 [ parse-list-11 ] }
-        { 8 [ parse-list-8 ] }
-        { 3 [ parse-list-3 ] }
-        [ drop ]
-    } case >>parsed ;
diff --git a/extra/ftp/client/tags.txt b/extra/ftp/client/tags.txt
deleted file mode 100644 (file)
index 992ae12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-network
diff --git a/extra/ftp/ftp.factor b/extra/ftp/ftp.factor
deleted file mode 100644 (file)
index adf7d5b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs combinators io io.files kernel
-math.parser sequences strings ;
-IN: ftp
-
-SINGLETON: active
-SINGLETON: passive
-
-TUPLE: ftp-response n strings parsed ;
-
-: <ftp-response> ( -- ftp-response )
-    ftp-response new
-        V{ } clone >>strings ;
-
-: add-response-line ( ftp-response string -- ftp-response )
-    over strings>> push ;
-
-: ftp-send ( string -- ) write "\r\n" write flush ;
-: ftp-ipv4 1 ; inline
-: ftp-ipv6 2 ; inline
diff --git a/extra/ftp/server/server.factor b/extra/ftp/server/server.factor
deleted file mode 100644 (file)
index 9095ded..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit accessors combinators io
-io.encodings.8-bit io.encodings io.encodings.binary
-io.encodings.utf8 io.files io.sockets kernel math.parser
-namespaces make sequences ftp io.unix.launcher.parser
-unicode.case splitting assocs classes io.servers.connection
-destructors calendar io.timeouts io.streams.duplex threads
-continuations math concurrency.promises byte-arrays
-io.backend sequences.lib tools.hexdump io.files.listing
-io.streams.string ;
-IN: ftp.server
-
-TUPLE: ftp-client url mode state command-promise user password ;
-
-: <ftp-client> ( url -- ftp-client )
-    ftp-client new
-        swap >>url ;
-    
-SYMBOL: client
-
-: ftp-server-directory ( -- str )
-    \ ftp-server-directory get-global "resource:temp" or
-    normalize-path ;
-
-TUPLE: ftp-command raw tokenized ;
-
-: <ftp-command> ( -- obj )
-    ftp-command new ;
-
-TUPLE: ftp-get path ;
-
-: <ftp-get> ( path -- obj )
-    ftp-get new
-        swap >>path ;
-
-TUPLE: ftp-put path ;
-
-: <ftp-put> ( path -- obj )
-    ftp-put new
-        swap >>path ;
-
-TUPLE: ftp-list ;
-
-C: <ftp-list> ftp-list
-
-: read-command ( -- ftp-command )
-    <ftp-command> readln
-    [ >>raw ] [ tokenize-command >>tokenized ] bi ;
-
-: (send-response) ( n string separator -- )
-    rot number>string write write ftp-send ;
-
-: send-response ( ftp-response -- )
-    [ n>> ] [ strings>> ] bi
-    [ but-last-slice [ "-" (send-response) ] with each ]
-    [ first " " (send-response) ] 2bi ;
-
-: server-response ( n string -- )
-    <ftp-response>
-        swap add-response-line
-        swap >>n
-    send-response ;
-
-: ftp-error ( string -- )
-    500 "Unrecognized command: " rot append server-response ;
-
-: send-banner ( -- )
-    220 "Welcome to " host-name append server-response ;
-
-: anonymous-only ( -- )
-    530 "This FTP server is anonymous only." server-response ;
-
-: handle-QUIT ( obj -- )
-    drop 221 "Goodbye." server-response ;
-
-: handle-USER ( ftp-command -- )
-    [
-        tokenized>> second client get (>>user)
-        331 "Please specify the password." server-response
-    ] [
-        2drop "bad USER" ftp-error
-    ] recover ;
-
-: handle-PASS ( ftp-command -- )
-    [
-        tokenized>> second client get (>>password)
-        230 "Login successful" server-response
-    ] [
-        2drop "PASS error" ftp-error
-    ] recover ;
-
-ERROR: type-error type ;
-
-: parse-type ( string -- string' )
-    >upper {
-        { "IMAGE" [ "Binary" ] }
-        { "I" [ "Binary" ] }
-        [ type-error ]
-    } case ;
-
-: handle-TYPE ( obj -- )
-    [
-        tokenized>> second parse-type
-        200 "Switching to " rot " mode" 3append server-response
-    ] [
-        2drop "TYPE is binary only" ftp-error
-    ] recover ;
-
-: random-local-server ( -- server )
-    remote-address get class new 0 >>port binary <server> ;
-
-: port>bytes ( port -- hi lo )
-    [ -8 shift ] keep [ HEX: ff bitand ] bi@ ;
-
-: handle-PWD ( obj -- )
-    drop
-    257 current-directory get "\"" "\"" surround server-response ;
-
-: handle-SYST ( obj -- )
-    drop
-    215 "UNIX Type: L8" server-response ;
-
-: if-command-promise ( quot -- )
-    [ client get command-promise>> ] dip
-    [ "Establish an active or passive connection first" ftp-error ] if* ;
-
-: handle-STOR ( obj -- )
-    [
-        tokenized>> second
-        [ [ <ftp-put> ] dip fulfill ] if-command-promise
-    ] [
-        2drop
-    ] recover ;
-
-! EPRT |2|::1|62138|
-! : handle-EPRT ( obj -- )
-    ! tokenized>> second "|" split harvest ;
-
-: start-directory ( -- )
-    150 "Here comes the directory listing." server-response ;
-
-: finish-directory ( -- )
-    226 "Directory send OK." server-response ;
-
-GENERIC: service-command ( stream obj -- )
-
-M: ftp-list service-command ( stream obj -- )
-    drop
-    start-directory [
-        utf8 encode-output
-        [ current-directory get directory. ] with-string-writer string-lines
-        harvest [ ftp-send ] each
-    ] with-output-stream
-    finish-directory ;
-
-: transfer-outgoing-file ( path -- )
-    150 "Opening BINARY mode data connection for "
-    rot   
-    [ file-name ] [
-        " " swap  file-info size>> number>string
-        "(" " bytes)." surround append
-    ] bi 3append server-response ;
-
-: transfer-incoming-file ( path -- )
-    150 "Opening BINARY mode data connection for " rot append
-    server-response ;
-
-: finish-file-transfer ( -- )
-    226 "File send OK." server-response ;
-
-M: ftp-get service-command ( stream obj -- )
-    [
-        path>>
-        [ transfer-outgoing-file ]
-        [ binary <file-reader> swap stream-copy ] bi
-        finish-file-transfer
-    ] [
-        3drop "File transfer failed" ftp-error
-    ] recover ;
-
-M: ftp-put service-command ( stream obj -- )
-    [
-        path>>
-        [ transfer-incoming-file ]
-        [ binary <file-writer> stream-copy ] bi
-        finish-file-transfer
-    ] [
-        3drop "File transfer failed" ftp-error
-    ] recover ;
-
-: passive-loop ( server -- )
-    [
-        [
-            |dispose
-            30 seconds over set-timeout
-            accept drop &dispose
-            client get command-promise>>
-            30 seconds ?promise-timeout
-            service-command
-        ]
-        [ client get f >>command-promise drop ]
-        [ drop ] cleanup
-    ] with-destructors ;
-
-: handle-LIST ( obj -- )
-    drop
-    [ [ <ftp-list> ] dip fulfill ] if-command-promise ;
-
-: handle-SIZE ( obj -- )
-    [
-        tokenized>> second file-info size>>
-        213 swap number>string server-response
-    ] [
-        2drop
-        550 "Could not get file size" server-response
-    ] recover ;
-
-: handle-RETR ( obj -- )
-    [ tokenized>> second <ftp-get> swap fulfill ]
-    curry if-command-promise ;
-
-: expect-connection ( -- port )
-    random-local-server
-    client get <promise> >>command-promise drop
-    [ [ passive-loop ] curry in-thread ]
-    [ addr>> port>> ] bi ;
-
-: handle-PASV ( obj -- )
-    drop client get passive >>mode drop
-    expect-connection
-    [
-        "Entering Passive Mode (127,0,0,1," %
-        port>bytes [ number>string ] bi@ "," splice %
-        ")" %
-    ] "" make 227 swap server-response ;
-
-: handle-EPSV ( obj -- )
-    drop
-    client get command-promise>> [
-        "You already have a passive stream" ftp-error
-    ] [
-        229 "Entering Extended Passive Mode (|||"
-        expect-connection number>string
-        "|)" 3append server-response
-    ] if ;
-
-! LPRT 6,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,242,186
-! : handle-LPRT ( obj -- ) tokenized>> "," split ;
-
-ERROR: not-a-directory ;
-ERROR: no-permissions ;
-
-: handle-CWD ( obj -- )
-    [
-        tokenized>> second dup normalize-path
-        dup ftp-server-directory head? [
-            no-permissions
-        ] unless
-
-        file-info directory? [
-            set-current-directory
-            250 "Directory successully changed." server-response
-        ] [
-            not-a-directory
-        ] if
-    ] [
-        2drop
-        550 "Failed to change directory." server-response
-    ] recover ;
-
-: unrecognized-command ( obj -- ) raw>> ftp-error ;
-
-: handle-client-loop ( -- )
-    <ftp-command> readln
-    USE: prettyprint    global [ dup . flush ] bind
-    [ >>raw ]
-    [ tokenize-command >>tokenized ] bi
-    dup tokenized>> first >upper {
-        { "USER" [ handle-USER t ] }
-        { "PASS" [ handle-PASS t ] }
-        { "ACCT" [ drop "ACCT unimplemented" ftp-error t ] }
-        { "CWD" [ handle-CWD t ] }
-        ! { "XCWD" [ ] }
-        ! { "CDUP" [ ] }
-        ! { "SMNT" [ ] }
-
-        ! { "REIN" [ drop client get reset-ftp-client t ] }
-        { "QUIT" [ handle-QUIT f ] }
-
-        ! { "PORT" [  ] } ! TODO
-        { "PASV" [ handle-PASV t ] }
-        ! { "MODE" [ ] }
-        { "TYPE" [ handle-TYPE t ] }
-        ! { "STRU" [ ] }
-
-        ! { "ALLO" [ ] }
-        ! { "REST" [ ] }
-        { "STOR" [ handle-STOR t ] }
-        ! { "STOU" [ ] }
-        { "RETR" [ handle-RETR t ] }
-        { "LIST" [ handle-LIST t ] }
-        { "SIZE" [ handle-SIZE t ] }
-        ! { "NLST" [ ] }
-        ! { "APPE" [ ] }
-        ! { "RNFR" [ ] }
-        ! { "RNTO" [ ] }
-        ! { "DELE" [ handle-DELE t ] }
-        ! { "RMD" [ handle-RMD t ] }
-        ! ! { "XRMD" [ handle-XRMD t ] }
-        ! { "MKD" [ handle-MKD t ] }
-        { "PWD" [ handle-PWD t ] }
-        ! { "ABOR" [ ] }
-
-        { "SYST" [ handle-SYST t ] }
-        ! { "STAT" [ ] }
-        ! { "HELP" [ ] }
-
-        ! { "SITE" [ ] }
-        ! { "NOOP" [ ] }
-
-        ! { "EPRT" [ handle-EPRT ] }
-        ! { "LPRT" [ handle-LPRT ] }
-        { "EPSV" [ handle-EPSV t ] }
-        ! { "LPSV" [ drop handle-LPSV t ] }
-        [ drop unrecognized-command t ]
-    } case [ handle-client-loop ] when ;
-
-TUPLE: ftp-server < threaded-server ;
-
-M: ftp-server handle-client* ( server -- )
-    drop
-    [
-        ftp-server-directory [
-            host-name <ftp-client> client set
-            send-banner handle-client-loop
-        ] with-directory
-    ] with-destructors ;
-
-: <ftp-server> ( port -- server )
-    ftp-server new-threaded-server
-        swap >>insecure
-        "ftp.server" >>name
-        5 minutes >>timeout
-        latin1 >>encoding ;
-
-: ftpd ( port -- )
-    <ftp-server> start-server ;
-
-: ftpd-main ( -- ) 2100 ftpd ;
-
-MAIN: ftpd-main
-
-! sudo tcpdump -i en1 -A -s 10000  tcp port 21
diff --git a/extra/ftp/server/tags.txt b/extra/ftp/server/tags.txt
deleted file mode 100644 (file)
index 992ae12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-network
diff --git a/extra/ftp/tags.txt b/extra/ftp/tags.txt
deleted file mode 100644 (file)
index 992ae12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-network
diff --git a/extra/fuel/authors.txt b/extra/fuel/authors.txt
new file mode 100644 (file)
index 0000000..ecfb757
--- /dev/null
@@ -0,0 +1,2 @@
+Jose Antonio Ortega Ruiz
+Eduardo Cavazos
diff --git a/extra/fuel/fuel-tests.factor b/extra/fuel/fuel-tests.factor
new file mode 100644 (file)
index 0000000..74bc5d4
--- /dev/null
@@ -0,0 +1,4 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test fuel ;
+IN: fuel.tests
diff --git a/extra/fuel/fuel.factor b/extra/fuel/fuel.factor
new file mode 100644 (file)
index 0000000..d8a363c
--- /dev/null
@@ -0,0 +1,121 @@
+! Copyright (C) 2008 Jose Antonio Ortega Ruiz.
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: accessors arrays classes.tuple compiler.units continuations debugger
+definitions eval io io.files io.streams.string kernel listener listener.private
+make math namespaces parser prettyprint quotations sequences strings
+vectors vocabs.loader ;
+
+IN: fuel
+
+! <PRIVATE
+
+TUPLE: fuel-status in use ds? ;
+
+SYMBOL: fuel-status-stack
+V{ } clone fuel-status-stack set-global
+
+: push-fuel-status ( -- )
+    in get use get clone display-stacks? get
+    fuel-status boa
+    fuel-status-stack get push ;
+
+: pop-fuel-status ( -- )
+    fuel-status-stack get empty? [
+        fuel-status-stack get pop
+        [ in>> in set ]
+        [ use>> clone use set ]
+        [ ds?>> display-stacks? swap [ on ] [ off ] if ] tri
+    ] unless ;
+
+SYMBOL: fuel-eval-result
+f clone fuel-eval-result set-global
+
+SYMBOL: fuel-eval-output
+f clone fuel-eval-result set-global
+
+! PRIVATE>
+
+GENERIC: fuel-pprint ( obj -- )
+
+M: object fuel-pprint pprint ;
+
+M: f fuel-pprint drop "nil" write ;
+
+M: integer fuel-pprint pprint ;
+
+M: string fuel-pprint pprint ;
+
+M: sequence fuel-pprint
+    dup empty? [ drop f fuel-pprint ] [
+        "(" write
+        [ " " write ] [ fuel-pprint ] interleave
+        ")" write
+    ] if ;
+
+M: tuple fuel-pprint tuple>array fuel-pprint ;
+
+M: continuation fuel-pprint drop "~continuation~" write ;
+
+: fuel-eval-set-result ( obj -- )
+    clone fuel-eval-result set-global ;
+
+: fuel-retort ( -- )
+    error get
+    fuel-eval-result get-global
+    fuel-eval-output get-global
+    3array fuel-pprint ;
+
+: fuel-forget-error ( -- )
+    f error set-global ;
+
+: (fuel-begin-eval) ( -- )
+    push-fuel-status
+    display-stacks? off
+    fuel-forget-error
+    f fuel-eval-result set-global
+    f fuel-eval-output set-global ;
+
+: (fuel-end-eval) ( quot -- )
+    with-string-writer fuel-eval-output set-global
+    fuel-retort
+    pop-fuel-status ;
+
+: (fuel-eval) ( lines -- )
+    [ [ parse-lines ] with-compilation-unit call ] curry [ drop ] recover ;
+
+: (fuel-eval-each) ( lines -- )
+    [ 1vector (fuel-eval) ] each ;
+
+: (fuel-eval-usings) ( usings -- )
+    [ "USING: " prepend " ;" append ] map
+    (fuel-eval-each) fuel-forget-error ;
+
+: (fuel-eval-in) ( in -- )
+    [ dup "IN: " prepend 1vector (fuel-eval) in set ] when* ;
+
+: fuel-eval-in-context ( lines in usings -- )
+    (fuel-begin-eval) [
+        (fuel-eval-usings)
+        (fuel-eval-in)
+        (fuel-eval)
+    ] (fuel-end-eval) ;
+
+: fuel-begin-eval ( in -- )
+    (fuel-begin-eval)
+    (fuel-eval-in)
+    fuel-retort ;
+
+: fuel-eval ( lines -- )
+    (fuel-begin-eval) [ (fuel-eval) ] (fuel-end-eval) ;
+
+: fuel-end-eval ( -- )
+    [ ] (fuel-end-eval) ;
+
+: fuel-get-edit-location ( defspec -- )
+    where [ first2 [ (normalize-path) ] dip 2array fuel-eval-set-result ] when* ;
+
+: fuel-startup ( -- )
+    "listener" run ;
+
+MAIN: fuel-startup
diff --git a/extra/golden-section/authors.txt b/extra/golden-section/authors.txt
deleted file mode 100644 (file)
index 6cfd5da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Eduardo Cavazos
diff --git a/extra/golden-section/deploy.factor b/extra/golden-section/deploy.factor
deleted file mode 100755 (executable)
index 0aa3185..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: tools.deploy.config ;
-V{
-    { deploy-ui? t }
-    { deploy-io 1 }
-    { deploy-reflection 1 }
-    { deploy-compiler? t }
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-c-types? f }
-    { "stop-after-last-window?" t }
-    { deploy-name "Golden Section" }
-}
diff --git a/extra/golden-section/golden-section.factor b/extra/golden-section/golden-section.factor
deleted file mode 100644 (file)
index 8d1e6b4..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-
-USING: kernel namespaces math math.constants math.functions math.order
-       arrays sequences
-       opengl opengl.gl opengl.glu ui ui.render ui.gadgets ui.gadgets.theme
-       ui.gadgets.cartesian colors accessors combinators.cleave
-       processing.shapes ;
-
-IN: golden-section
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! omega(i) = 2*pi*i*(phi-1)
-
-! x(i) = 0.5*i*cos(omega(i))
-! y(i) = 0.5*i*sin(omega(i))
-
-! radius(i) = 10*sin((pi*i)/720)
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: omega ( i -- omega ) phi 1- * 2 * pi * ;
-
-: x ( i -- x ) [ omega cos ] [ 0.5 * ] bi * ;
-: y ( i -- y ) [ omega sin ] [ 0.5 * ] bi * ;
-
-: center ( i -- point ) { x y } 1arr ;
-
-: radius ( i -- radius ) pi * 720 / sin 10 * ;
-
-: color ( i -- i ) dup 360.0 / dup 0.25 1 rgba boa >fill-color ;
-
-: line-width ( i -- i ) dup radius 0.5 * 1 max glLineWidth ;
-
-: draw ( i -- ) [ center ] [ radius 1.5 * 2 * ] bi circle ;
-
-: dot ( i -- ) color line-width draw ;
-
-: golden-section ( -- ) 720 [ dot ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: <golden-section> ( -- gadget )
-  <cartesian>
-    {  600 600 }       >>pdim
-    { -400 400 }       x-range
-    { -400 400 }       y-range
-    [ golden-section ] >>action ;
-
-: golden-section-window ( -- )
-  [ <golden-section> "Golden Section" open-window ] with-ui ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-MAIN: golden-section-window
diff --git a/extra/golden-section/summary.txt b/extra/golden-section/summary.txt
deleted file mode 100644 (file)
index 5f44091..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Golden section demo
diff --git a/extra/golden-section/tags.txt b/extra/golden-section/tags.txt
deleted file mode 100644 (file)
index cb5fc20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-demos
index c61a3c8b8a4e150bd613f7fe78c4d3b1777b4f16..6537661b3e4fead36c137222332aa40508fcfb79 100755 (executable)
@@ -5,7 +5,7 @@ IN: hardware-info.windows.ce
 : memory-status ( -- MEMORYSTATUS )
     "MEMORYSTATUS" <c-object>
     "MEMORYSTATUS" heap-size over set-MEMORYSTATUS-dwLength
-    [ GlobalMemoryStatus ] keep ;
+    dup GlobalMemoryStatus ;
 
 M: wince cpus ( -- n ) 1 ;
 
index 51af5c594977ada21bf40b8d52b20ade31d229cd..6274e7974c97998fd5f1c6908a728cd97bde5f18 100755 (executable)
@@ -1,18 +1,16 @@
 USING: alien alien.c-types alien.strings
 kernel libc math namespaces hardware-info.backend
-windows windows.advapi32 windows.kernel32 system ;
+hardware-info.windows windows windows.advapi32
+windows.kernel32 system byte-arrays ;
 IN: hardware-info.windows.nt
 
-: system-info ( -- SYSTEM_INFO )
-    "SYSTEM_INFO" <c-object> [ GetSystemInfo ] keep ;
-
 M: winnt cpus ( -- n )
     system-info SYSTEM_INFO-dwNumberOfProcessors ;
 
 : memory-status ( -- MEMORYSTATUSEX )
     "MEMORYSTATUSEX" <c-object>
     "MEMORYSTATUSEX" heap-size over set-MEMORYSTATUSEX-dwLength
-    [ GlobalMemoryStatusEx ] keep swap zero? [ win32-error ] when ;
+    dup GlobalMemoryStatusEx win32-error=0/f ;
 
 M: winnt memory-load ( -- n )
     memory-status MEMORYSTATUSEX-dwMemoryLoad ;
@@ -35,21 +33,12 @@ M: winnt total-virtual-mem ( -- n )
 M: winnt available-virtual-mem ( -- n )
     memory-status MEMORYSTATUSEX-ullAvailVirtual ;
 
-: pull-win32-string ( alien -- string )
-    [ utf16n alien>string ] keep free ;
-
 : computer-name ( -- string )
-    MAX_COMPUTERNAME_LENGTH 1+ [ malloc ] keep
-    <int> dupd GetComputerName zero? [
-        free win32-error f
-    ] [
-        pull-win32-string
-    ] if ;
+    MAX_COMPUTERNAME_LENGTH 1+
+    [ <byte-array> dup ] keep <uint>
+    GetComputerName win32-error=0/f alien>native-string ;
  
 : username ( -- string )
-    UNLEN 1+ [ malloc ] keep
-    <int> dupd GetUserName zero? [
-        free win32-error f
-    ] [
-        pull-win32-string
-    ] if ;
+    UNLEN 1+
+    [ <byte-array> dup ] keep <uint>
+    GetUserName win32-error=0/f alien>native-string ;
index 3aa6824ff6b4dacd42f11c30ff1c7bf137c48469..d3ebe875010be96307b54732a6a9001090ab485e 100755 (executable)
@@ -21,7 +21,7 @@ IN: hardware-info.windows
 : os-version ( -- os-version )
     "OSVERSIONINFO" <c-object>
     "OSVERSIONINFO" heap-size over set-OSVERSIONINFO-dwOSVersionInfoSize
-    [ GetVersionEx ] keep swap zero? [ win32-error ] when ;
+    dup GetVersionEx win32-error=0/f ;
 
 : windows-major ( -- n )
     os-version OSVERSIONINFO-dwMajorVersion ;
@@ -36,7 +36,7 @@ IN: hardware-info.windows
     os-version OSVERSIONINFO-dwPlatformId ;
 
 : windows-service-pack ( -- string )
-    os-version OSVERSIONINFO-szCSDVersion utf16n alien>string ;
+    os-version OSVERSIONINFO-szCSDVersion alien>native-string ;
 
 : feature-present? ( n -- ? )
     IsProcessorFeaturePresent zero? not ;
@@ -51,8 +51,8 @@ IN: hardware-info.windows
     "ushort" <c-array> ;
 
 : get-directory ( word -- str )
-    >r MAX_UNICODE_PATH [ <u16-string-object> ] keep dupd r>
-    execute win32-error=0/f utf16n alien>string ; inline
+    [ MAX_UNICODE_PATH [ <u16-string-object> ] keep dupd ] dip
+    execute win32-error=0/f alien>native-string ; inline
 
 : windows-directory ( -- str )
     \ GetWindowsDirectory get-directory ;
index 219fe0ca05d583ac1d1d06615f208c8eb183a40d..64ea481b030f0485346abfa0c59d2dbd96a7a8c6 100755 (executable)
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-c-types? f }
-    { deploy-name "Hello world (console)" }
-    { deploy-threads? f }
+    { deploy-unicode? f }
+    { deploy-reflection 1 }
     { deploy-word-props? f }
-    { deploy-reflection 2 }
-    { deploy-io 2 }
     { deploy-math? f }
+    { deploy-name "Hello world (console)" }
+    { deploy-word-defs? f }
+    { "stop-after-last-window?" t }
     { deploy-ui? f }
     { deploy-compiler? f }
-    { "stop-after-last-window?" t }
-    { deploy-word-defs? f }
+    { deploy-io 2 }
+    { deploy-c-types? f }
 }
index e084ea6806f3f8f4c48ccb0fd9f2df20239b329e..836693026a41da1152f6851da2b6f79ca5c9376d 100644 (file)
@@ -26,7 +26,7 @@ SYMBOL: tagstack
         swap >>name ;
 
 : make-tag ( string attribs -- tag )
-    >r [ closing-tag? ] keep "/" trim1 r> rot <tag> ;
+    [ [ closing-tag? ] keep "/" trim1 ] dip rot <tag> ;
 
 : make-text-tag ( string -- tag )
     tag new
index dfef23b56a4f86490f105595f5fae33ba031f41b..61c5da6bca2147376e4f2e251d4a00be4466e1aa 100755 (executable)
@@ -5,7 +5,8 @@ sequences assocs math arrays stack-checker effects generalizations
 continuations debugger classes.tuple namespaces make vectors
 bit-arrays byte-arrays strings sbufs math.functions macros
 sequences.private combinators mirrors
-combinators.short-circuit ;
+combinators.short-circuit fry qualified ;
+RENAME: _ fry => __
 IN: inverse
 
 TUPLE: fail ;
@@ -46,7 +47,7 @@ M: no-inverse summary
     dup word? [ "Badly formed math inverse" throw ] when 1quotation ;
 
 : swap-inverse ( math-inverse revquot -- revquot* quot )
-    next assure-constant rot second [ swap ] swap 3compose ;
+    next assure-constant rot second '[ @ swap @ ] ;
 
 : pull-inverse ( math-inverse revquot const -- revquot* quot )
     assure-constant rot first compose ;
@@ -236,8 +237,7 @@ DEFER: _
     ] recover ; inline
 
 : true-out ( quot effect -- quot' )
-    out>> [ ndrop ] curry
-    [ t ] 3compose ;
+    out>> '[ @ __ ndrop t ] ;
 
 : false-recover ( effect -- quot )
     in>> [ ndrop f ] curry [ recover-fail ] curry ;
diff --git a/extra/io/files/unique/backend/backend.factor b/extra/io/files/unique/backend/backend.factor
deleted file mode 100644 (file)
index 7b9809f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: io.backend ;
-IN: io.files.unique.backend
-
-HOOK: (make-unique-file) io-backend ( path -- )
-HOOK: temporary-path io-backend ( -- path )
diff --git a/extra/io/files/unique/unique-docs.factor b/extra/io/files/unique/unique-docs.factor
deleted file mode 100644 (file)
index bb4e9ef..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-USING: help.markup help.syntax io io.ports kernel math
-io.files.unique.private math.parser io.files ;
-IN: io.files.unique
-
-ARTICLE: "unique" "Making and using unique files"
-"Files:"
-{ $subsection make-unique-file }
-{ $subsection with-unique-file }
-"Directories:"
-{ $subsection make-unique-directory }
-{ $subsection with-unique-directory } ;
-
-ABOUT: "unique"
-
-HELP: make-unique-file ( prefix suffix -- path )
-{ $values { "prefix" "a string" } { "suffix" "a string" }
-{ "path" "a pathname string" } }
-{ $description "Creates a file that is guaranteed not to exist in a platform-specific temporary directory.  The file name is composed of a prefix, a number of random digits and letters, and the suffix.  Returns the full pathname." }
-{ $errors "Throws an error if a new unique file cannot be created after a number of tries.  Since each try generates a new random name, the most likely error is incorrect directory permissions on the temporary directory." }
-{ $see-also with-unique-file } ;
-
-HELP: make-unique-directory ( -- path )
-{ $values { "path" "a pathname string" } }
-{ $description "Creates a directory that is guaranteed not to exist in a platform-specific temporary directory and returns the full pathname." }
-{ $errors "Throws an error if the directory cannot be created after a number of tries.  Since each try generates a new random name, the most likely error is incorrect directory permissions on the temporary directory." }
-{ $see-also with-unique-directory } ;
-
-HELP: with-unique-file ( prefix suffix quot -- )
-{ $values { "prefix" "a string" } { "suffix" "a string" }
-{ "quot" "a quotation" } }
-{ $description "Creates a file with " { $link make-unique-file } " and calls the quotation with the path name on the stack." }
-{ $notes "The unique file will be deleted after calling this word." } ;
-
-HELP: with-unique-directory ( quot -- )
-{ $values { "quot" "a quotation" } }
-{ $description "Creates a directory with " { $link make-unique-directory } " and calls the quotation with the pathname on the stack." }
-{ $notes "The directory will be deleted after calling this word." } ;
diff --git a/extra/io/files/unique/unique-tests.factor b/extra/io/files/unique/unique-tests.factor
deleted file mode 100644 (file)
index c29a94f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-USING: io.encodings.ascii sequences strings io io.files accessors
-tools.test kernel io.files.unique ;
-IN: io.files.unique.tests
-
-[ 123 ] [
-    "core" ".test" [
-        [
-            ascii [
-                123 CHAR: a <repetition> >string write
-            ] with-file-writer
-        ] keep file-info size>>
-    ] with-unique-file
-] unit-test
diff --git a/extra/io/files/unique/unique.factor b/extra/io/files/unique/unique.factor
deleted file mode 100644 (file)
index db11471..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.bitwise combinators.lib math.parser
-random sequences sequences.lib continuations namespaces
-io.files io arrays io.files.unique.backend system
-combinators vocabs.loader ;
-IN: io.files.unique
-
-<PRIVATE
-: random-letter ( -- ch )
-    26 random { CHAR: a CHAR: A } random + ;
-
-: random-ch ( -- ch )
-    { t f } random
-    [ 10 random CHAR: 0 + ] [ random-letter ] if ;
-
-: random-name ( n -- string )
-    [ random-ch ] "" replicate-as ;
-
-: unique-length ( -- n ) 10 ; inline
-: unique-retries ( -- n ) 10 ; inline
-PRIVATE>
-
-: make-unique-file ( prefix suffix -- path )
-    temporary-path -rot
-    [
-        unique-length random-name swap 3append append-path
-        dup (make-unique-file)
-    ] 3curry unique-retries retry ;
-
-: with-unique-file ( prefix suffix quot -- )
-    >r make-unique-file r> keep delete-file ; inline
-
-: make-unique-directory ( -- path )
-    [
-        temporary-path unique-length random-name append-path
-        dup make-directory
-    ] unique-retries retry ;
-
-: with-unique-directory ( quot -- )
-    >r make-unique-directory r>
-    [ with-directory ] curry keep delete-tree ; inline
-
-{
-    { [ os unix? ] [ "io.unix.files.unique" ] }
-    { [ os windows? ] [ "io.windows.files.unique" ] }
-} cond require
index 327bfc629282a0dfd47cb6a12a40fc71b0440de6..622b5eaa2ce3a20e149920bd8791b2f542d33d21 100644 (file)
@@ -19,7 +19,7 @@ M: mb-reader stream-readln ( mb-reader -- str/f ) lines>> mailbox-get ;
 M: mb-writer stream-nl ( mb-writer -- )
     [ [ last-line>> concat ] [ lines>> ] bi push ] keep
     V{ } clone >>last-line drop ;
-M: mb-reader dispose drop ;
+M: mb-reader dispose f swap push-line ;
 M: mb-writer dispose drop ;
 
 : spawn-client ( -- irc-client )
@@ -39,7 +39,7 @@ M: mb-writer dispose drop ;
     [ in-messages>> 0.1 seconds ] dip mailbox-get-timeout? ;
 
 : with-irc ( quot: ( -- ) -- )
-    [ spawn-client ] dip [ f %push-line ] compose with-irc-client ; inline
+    [ spawn-client ] dip [ irc> terminate-irc ] compose with-irc-client ; inline
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !                       TESTS
@@ -60,17 +60,16 @@ M: mb-writer dispose drop ;
 
 ! Test login and nickname set
 [ { "factorbot2" } [
-     ":some.where 001 factorbot2 :Welcome factorbot2" %push-line
-      irc> nick>>
+    ":some.where 001 factorbot2 :Welcome factorbot2" %push-line
+    irc> nick>>
   ] unit-test
 ] with-irc
 
 ! Test connect
 { V{ "NICK factorbot" "USER factorbot hostname servername :irc.factor" } } [
-   "someserver" irc-port "factorbot" f <irc-profile> <irc-client>
+    "someserver" irc-port "factorbot" f <irc-profile> <irc-client>
     [ 2drop <test-stream> t ] >>connect
-    [ connect-irc ] keep
-    stream>> [ in>> [ f ] dip push-line ] [ out>> lines>> ] bi
+    [ connect-irc ] [ stream>> out>> lines>> ] [ terminate-irc ] tri
 ] unit-test
 
 ! Test join
index d79e8e0ee5a52f353d83b66ff9cbd96ae530b145..8199347feb0c0a2b6529a8374b97044a9c3e99ca 100755 (executable)
@@ -297,7 +297,7 @@ DEFER: (connect-irc)
         |dispose stream-readln [
             parse-irc-line handle-reader-message t
         ] [
-            irc> terminate-irc f
+            handle-disconnect
         ] if*
     ] with-destructors ;
 
diff --git a/extra/irc/gitbot/gitbot.factor b/extra/irc/gitbot/gitbot.factor
new file mode 100644 (file)
index 0000000..3b7694a
--- /dev/null
@@ -0,0 +1,55 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: fry irc.client irc.client.private kernel namespaces
+sequences threads io.encodings.8-bit io.launcher io splitting
+make mason.common mason.updates calendar math alarms ;
+IN: irc.gitbot
+
+: bot-profile ( -- obj )
+    "irc.freenode.org" 6667 "jackass" f <irc-profile> ;
+
+: bot-channel ( -- seq ) "#concatenative" ;
+
+GENERIC: handle-message ( msg -- )
+
+M: object handle-message drop ;
+
+: bot-loop ( chat -- )
+    dup hear handle-message bot-loop ;
+
+: start-bot ( -- chat )
+    bot-profile <irc-client>
+    [ connect-irc ]
+    [
+        [ bot-channel <irc-channel-chat> dup ] dip
+        '[ _ [ _ attach-chat ] [ bot-loop ] bi ]
+        "GitBot" spawn drop
+    ] bi ;
+
+: git-log ( from to -- lines )
+    [
+        "git-log" ,
+        "--no-merges" ,
+        "--pretty=format:%h %an: %s" ,
+        ".." glue ,
+    ] { } make
+    latin1 [ input-stream get lines ] with-process-reader ;
+
+: updates ( from to -- lines )
+    git-log reverse
+    dup length 4 > [ 4 head "... and more" suffix ] when ;
+
+: report-updates ( from to chat -- )
+    [ updates ] dip
+    [ 1 seconds sleep ] swap
+    '[ _ speak ] interleave ;
+
+: check-for-updates ( chat -- )
+    [ git-id git-pull-cmd short-running-process git-id ] dip
+    report-updates ;
+
+: bot ( -- )
+    start-bot
+    '[ _ check-for-updates ] 5 minutes every drop ;
+
+MAIN: bot
index 163517698ae94fa2636032c236c33c14707ecaee..5179997b0d33f44201e044b01ace1fcaa2607a80 100755 (executable)
@@ -5,8 +5,6 @@ USING: kernel vocabs.loader sequences strings splitting words irc.messages ;
 \r
 IN: irc.ui.commandparser\r
 \r
-"irc.ui.commands" require\r
-\r
 : command ( string string -- string command )\r
     [ "say" ] when-empty\r
     dup "irc.ui.commands" lookup\r
index e854d285b7e8f6be5580e34c5ec7e513cde52507..b96d3e1bdc3ada1173d99dfe73a0ff2730306e0c 100755 (executable)
@@ -9,7 +9,7 @@ USING: accessors kernel threads combinators concurrency.mailboxes
        ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels\r
        io io.styles namespaces calendar calendar.format models continuations\r
        irc.client irc.client.private irc.messages\r
-       irc.ui.commandparser irc.ui.load ;\r
+       irc.ui.commandparser irc.ui.load vocabs.loader ;\r
 \r
 RENAME: join sequences => sjoin\r
 \r
@@ -245,3 +245,5 @@ M: irc-tab pref-dim*
 : main-run ( -- ) run-ircui ;\r
 \r
 MAIN: main-run\r
+\r
+"irc.ui.commands" require\r
diff --git a/extra/jamshred/authors.txt b/extra/jamshred/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/deploy.factor b/extra/jamshred/deploy.factor
deleted file mode 100644 (file)
index 9a18cf1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: tools.deploy.config ;
-V{
-    { deploy-ui? t }
-    { deploy-io 1 }
-    { deploy-reflection 1 }
-    { deploy-compiler? t }
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-c-types? f }
-    { "stop-after-last-window?" t }
-    { deploy-name "Jamshred" }
-}
diff --git a/extra/jamshred/game/authors.txt b/extra/jamshred/game/authors.txt
deleted file mode 100755 (executable)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/game/game.factor b/extra/jamshred/game/game.factor
deleted file mode 100644 (file)
index 9cb5bc7..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel opengl arrays sequences jamshred.log jamshred.player jamshred.sound jamshred.tunnel math math.constants math.vectors ;
-IN: jamshred.game
-
-TUPLE: jamshred sounds tunnel players running quit ;
-
-: <jamshred> ( -- jamshred )
-    <sounds> <random-tunnel> "Player 1" pick <player>
-    2dup swap play-in-tunnel 1array f f jamshred boa ;
-
-: jamshred-player ( jamshred -- player )
-    ! TODO: support more than one player
-    players>> first ;
-
-: jamshred-update ( jamshred -- )
-    dup running>> [
-        jamshred-player update-player
-    ] [ drop ] if ;
-
-: toggle-running ( jamshred -- )
-    dup running>> [
-        f >>running drop
-    ] [
-        [ jamshred-player moved ]
-        [ t >>running drop ] bi
-    ] if ;
-
-: mouse-moved ( x-radians y-radians jamshred -- )
-    jamshred-player -rot turn-player ;
-
-: units-per-full-roll ( -- n ) 50 ;
-
-: jamshred-roll ( jamshred n -- )
-    [ jamshred-player ] dip 2 pi * * units-per-full-roll / roll-player ;
-        
-: mouse-scroll-x ( jamshred x -- ) jamshred-roll ;
-
-: mouse-scroll-y ( jamshred y -- )
-    neg swap jamshred-player change-player-speed ;
diff --git a/extra/jamshred/gl/authors.txt b/extra/jamshred/gl/authors.txt
deleted file mode 100755 (executable)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/gl/gl.factor b/extra/jamshred/gl/gl.factor
deleted file mode 100644 (file)
index 7bd6eb7..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types jamshred.game jamshred.oint
-jamshred.player jamshred.tunnel kernel math math.constants
-math.functions math.vectors opengl opengl.gl opengl.glu
-opengl.demo-support sequences float-arrays ;
-IN: jamshred.gl
-
-: min-vertices 6 ; inline
-: max-vertices 32 ; inline
-
-: n-vertices ( -- n ) 32 ; inline
-
-! render enough of the tunnel that it looks continuous
-: n-segments-ahead ( -- n ) 60 ; inline
-: n-segments-behind ( -- n ) 40 ; inline
-
-: wall-drawing-offset ( -- n )
-    #! so that we can't see through the wall, we draw it a bit further away
-    0.15 ;
-
-: wall-drawing-radius ( segment -- r )
-    radius>> wall-drawing-offset + ;
-
-: wall-up ( segment -- v )
-    [ wall-drawing-radius ] [ up>> ] bi n*v ;
-
-: wall-left ( segment -- v )
-    [ wall-drawing-radius ] [ left>> ] bi n*v ;
-
-: segment-vertex ( theta segment -- vertex )
-    [
-        [ wall-up swap sin v*n ] [ wall-left swap cos v*n ] 2bi v+
-    ] [
-        location>> v+
-    ] bi ;
-
-: segment-vertex-normal ( vertex segment -- normal )
-    location>> swap v- normalize ;
-
-: segment-vertex-and-normal ( segment theta -- vertex normal )
-    swap [ segment-vertex ] keep dupd segment-vertex-normal ;
-
-: equally-spaced-radians ( n -- seq )
-    #! return a sequence of n numbers between 0 and 2pi
-    dup [ / pi 2 * * ] curry map ;
-
-: draw-segment-vertex ( segment theta -- )
-    over color>> gl-color segment-vertex-and-normal
-    gl-normal gl-vertex ;
-
-: draw-vertex-pair ( theta next-segment segment -- )
-    rot tuck draw-segment-vertex draw-segment-vertex ;
-
-: draw-segment ( next-segment segment -- )
-    GL_QUAD_STRIP [
-        [ draw-vertex-pair ] 2curry
-        n-vertices equally-spaced-radians F{ 0.0 } append swap each
-    ] do-state ;
-
-: draw-segments ( segments -- )
-    1 over length pick subseq swap [ draw-segment ] 2each ;
-
-: segments-to-render ( player -- segments )
-    dup nearest-segment>> number>> dup n-segments-behind -
-    swap n-segments-ahead + rot tunnel>> sub-tunnel ;
-
-: draw-tunnel ( player -- )
-    segments-to-render draw-segments ;
-
-: init-graphics ( width height -- )
-    GL_DEPTH_TEST glEnable
-    GL_SCISSOR_TEST glDisable
-    1.0 glClearDepth
-    0.0 0.0 0.0 0.0 glClearColor
-    GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
-    GL_PROJECTION glMatrixMode glLoadIdentity
-    dup 0 = [ 2drop ] [ / >float 45.0 swap 0.1 100.0 gluPerspective ] if
-    GL_MODELVIEW glMatrixMode glLoadIdentity
-    GL_LEQUAL glDepthFunc
-    GL_LIGHTING glEnable
-    GL_LIGHT0 glEnable
-    GL_FOG glEnable
-    GL_FOG_DENSITY 0.09 glFogf
-    GL_FRONT GL_AMBIENT_AND_DIFFUSE glColorMaterial
-    GL_COLOR_MATERIAL glEnable
-    GL_LIGHT0 GL_POSITION F{ 0.0 0.0 0.0 1.0 } >c-float-array glLightfv
-    GL_LIGHT0 GL_AMBIENT F{ 0.2 0.2 0.2 1.0 } >c-float-array glLightfv
-    GL_LIGHT0 GL_DIFFUSE F{ 1.0 1.0 1.0 1.0 } >c-float-array glLightfv
-    GL_LIGHT0 GL_SPECULAR F{ 1.0 1.0 1.0 1.0 } >c-float-array glLightfv ;
-
-: player-view ( player -- )
-    [ location>> ]
-    [ [ location>> ] [ forward>> ] bi v+ ]
-    [ up>> ] tri gl-look-at ;
-
-: draw-jamshred ( jamshred width height -- )
-    init-graphics jamshred-player [ player-view ] [ draw-tunnel ] bi ;
-
diff --git a/extra/jamshred/jamshred.factor b/extra/jamshred/jamshred.factor
deleted file mode 100755 (executable)
index d0b7441..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays calendar jamshred.game jamshred.gl jamshred.player jamshred.log kernel math math.constants math.geometry.rect math.vectors namespaces sequences threads ui ui.backend ui.gadgets ui.gadgets.worlds ui.gestures ui.render ;
-IN: jamshred
-
-TUPLE: jamshred-gadget < gadget { jamshred jamshred } last-hand-loc ;
-
-: <jamshred-gadget> ( jamshred -- gadget )
-    jamshred-gadget new-gadget swap >>jamshred ;
-
-: default-width ( -- x ) 800 ;
-: default-height ( -- y ) 600 ;
-
-M: jamshred-gadget pref-dim*
-    drop default-width default-height 2array ;
-
-M: jamshred-gadget draw-gadget* ( gadget -- )
-    [ jamshred>> ] [ rect-dim first2 draw-jamshred ] bi ;
-
-: jamshred-loop ( gadget -- )
-    dup jamshred>> quit>> [
-        drop
-    ] [
-        [ jamshred>> jamshred-update ]
-        [ relayout-1 ]
-        [ 10 milliseconds sleep yield jamshred-loop ] tri
-    ] if ;
-
-: fullscreen ( gadget -- )
-    find-world t swap set-fullscreen* ;
-
-: no-fullscreen ( gadget -- )
-    find-world f swap set-fullscreen* ;
-
-: toggle-fullscreen ( world -- )
-    [ fullscreen? not ] keep set-fullscreen* ;
-
-M: jamshred-gadget graft* ( gadget -- )
-    [ jamshred-loop ] curry in-thread ;
-
-M: jamshred-gadget ungraft* ( gadget -- )
-    jamshred>> t swap (>>quit) ;
-
-: jamshred-restart ( jamshred-gadget -- )
-    <jamshred> >>jamshred drop ;
-
-: pix>radians ( n m -- theta )
-    / pi 4 * * ; ! 2 / / pi 2 * * ;
-
-: x>radians ( x gadget -- theta )
-    #! translate motion of x pixels to an angle
-    rect-dim first pix>radians neg ;
-
-: y>radians ( y gadget -- theta )
-    #! translate motion of y pixels to an angle
-    rect-dim second pix>radians ;
-
-: (handle-mouse-motion) ( jamshred-gadget mouse-motion -- )
-    over jamshred>> >r
-    [ first swap x>radians ] 2keep second swap y>radians
-    r> mouse-moved ;
-    
-: handle-mouse-motion ( jamshred-gadget -- )
-    hand-loc get [
-        over last-hand-loc>> [
-            v- (handle-mouse-motion) 
-        ] [ 2drop ] if* 
-    ] 2keep >>last-hand-loc drop ;
-
-: handle-mouse-scroll ( jamshred-gadget -- )
-    jamshred>> scroll-direction get
-    [ first mouse-scroll-x ]
-    [ second mouse-scroll-y ] 2bi ;
-
-: quit ( gadget -- )
-    [ no-fullscreen ] [ close-window ] bi ;
-
-jamshred-gadget H{
-    { T{ key-down f f "r" } [ jamshred-restart ] }
-    { T{ key-down f f " " } [ jamshred>> toggle-running ] }
-    { T{ key-down f f "f" } [ find-world toggle-fullscreen ] }
-    { T{ key-down f f "UP" } [ jamshred>> jamshred-player 1 swap change-player-speed ] }
-    { T{ key-down f f "DOWN" } [ jamshred>> jamshred-player -1 swap change-player-speed ] }
-    { T{ key-down f f "LEFT" } [ jamshred>> 1 jamshred-roll ] }
-    { T{ key-down f f "RIGHT" } [ jamshred>> -1 jamshred-roll ] }
-    { T{ key-down f f "q" } [ quit ] }
-    { T{ motion } [ handle-mouse-motion ] }
-    { T{ mouse-scroll } [ handle-mouse-scroll ] }
-} set-gestures
-
-: jamshred-window ( -- gadget )
-    [ <jamshred> <jamshred-gadget> dup "Jamshred" open-window ] with-ui ;
-
-MAIN: jamshred-window
diff --git a/extra/jamshred/log/log.factor b/extra/jamshred/log/log.factor
deleted file mode 100644 (file)
index 33498d8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-USING: kernel logging ;
-IN: jamshred.log
-
-LOG: (jamshred-log) DEBUG
-
-: with-jamshred-log ( quot -- )
-    "jamshred" swap with-logging ;
-
-: jamshred-log ( message -- )
-    [ (jamshred-log) ] with-jamshred-log ; ! ugly...
diff --git a/extra/jamshred/oint/authors.txt b/extra/jamshred/oint/authors.txt
deleted file mode 100755 (executable)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/oint/oint-tests.factor b/extra/jamshred/oint/oint-tests.factor
deleted file mode 100644 (file)
index 401935f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-USING: jamshred.oint tools.test ;
-IN: jamshred.oint-tests
-
-[ { 0 -1 -1 } ] [ { 0 1 -1 } { 0 -1 0 } reflect ] unit-test
-[ { 0 1 0 } ] [ { 1 1 0 } { 1 0 0 } proj-perp ] unit-test
-[ { 1 0 0 } ] [ { 1 1 0 } { 0 1 0 } proj-perp ] unit-test
-[ { 1/2 -1/2 0 } ] [ { 1 0 0 } { 1 1 0 } proj-perp ] unit-test
-[ { -1/2 1/2 0 } ] [ { 0 1 0 } { 1 1 0 } proj-perp ] unit-test
diff --git a/extra/jamshred/oint/oint.factor b/extra/jamshred/oint/oint.factor
deleted file mode 100644 (file)
index 808e92a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays float-arrays kernel locals math math.constants math.functions math.matrices math.vectors math.quaternions random sequences ;
-IN: jamshred.oint
-
-! An oint is a point with three linearly independent unit vectors
-! given relative to that point. In jamshred a player's location and
-! direction are given by the player's oint. Similarly, a tunnel
-! segment's location and orientation are given by an oint.
-
-TUPLE: oint location forward up left ;
-C: <oint> oint
-
-: rotation-quaternion ( theta axis -- quaternion )
-    swap 2 / dup cos swap sin rot n*v first3 rect> >r rect> r> 2array ;
-
-: rotate-vector ( q qrecip v -- v )
-    v>q swap q* q* q>v ;
-
-: rotate-oint ( oint theta axis -- )
-    rotation-quaternion dup qrecip pick
-    [ forward>> rotate-vector >>forward ]
-    [ up>> rotate-vector >>up ]
-    [ left>> rotate-vector >>left ] 3tri drop ;
-
-: left-pivot ( oint theta -- )
-    over left>> rotate-oint ;
-
-: up-pivot ( oint theta -- )
-    over up>> rotate-oint ;
-
-: forward-pivot ( oint theta -- )
-    over forward>> rotate-oint ;
-
-: random-float+- ( n -- m )
-    #! find a random float between -n/2 and n/2
-    dup 10000 * >fixnum random 10000 / swap 2 / - ;
-
-: random-turn ( oint theta -- )
-    2 / 2dup random-float+- left-pivot random-float+- up-pivot ;
-
-: location+ ( v oint -- )
-    [ location>> v+ ] [ (>>location) ] bi ;
-
-: go-forward ( distance oint -- )
-    [ forward>> n*v ] [ location+ ] bi ;
-
-: distance-vector ( oint oint -- vector )
-    [ location>> ] bi@ swap v- ;
-
-: distance ( oint oint -- distance )
-    distance-vector norm ;
-
-: scalar-projection ( v1 v2 -- n )
-    #! the scalar projection of v1 onto v2
-    tuck v. swap norm / ;
-
-: proj-perp ( u v -- w )
-    dupd proj v- ;
-
-: perpendicular-distance ( oint oint -- distance )
-    tuck distance-vector swap 2dup left>> scalar-projection abs
-    -rot up>> scalar-projection abs + ;
-
-:: reflect ( v n -- v' )
-    #! bounce v on a surface with normal n
-    v v n v. n n v. / 2 * n n*v v- ;
-
-: half-way ( p1 p2 -- p3 )
-    over v- 2 v/n v+ ;
-
-: half-way-between-oints ( o1 o2 -- p )
-    [ location>> ] bi@ half-way ;
diff --git a/extra/jamshred/player/authors.txt b/extra/jamshred/player/authors.txt
deleted file mode 100755 (executable)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/player/player.factor b/extra/jamshred/player/player.factor
deleted file mode 100644 (file)
index 72f26a2..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors colors combinators float-arrays jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel locals math math.constants math.order math.ranges math.vectors math.matrices sequences shuffle strings system ;
-IN: jamshred.player
-
-TUPLE: player < oint
-    { name string }
-    { sounds sounds }
-    tunnel
-    nearest-segment
-    { last-move integer }
-    { speed float } ;
-
-! speeds are in GL units / second
-: default-speed ( -- speed ) 1.0 ;
-: max-speed ( -- speed ) 30.0 ;
-
-: <player> ( name sounds -- player )
-    [ F{ 0 0 5 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } ] 2dip
-    f f 0 default-speed player boa ;
-
-: turn-player ( player x-radians y-radians -- )
-    >r over r> left-pivot up-pivot ;
-
-: roll-player ( player z-radians -- )
-    forward-pivot ;
-
-: to-tunnel-start ( player -- )
-    [ tunnel>> first dup location>> ]
-    [ tuck (>>location) (>>nearest-segment) ] bi ;
-
-: play-in-tunnel ( player segments -- )
-    >>tunnel to-tunnel-start ;
-
-: update-nearest-segment ( player -- )
-    [ tunnel>> ] [ dup nearest-segment>> nearest-segment ]
-    [ (>>nearest-segment) ] tri ;
-
-: update-time ( player -- seconds-passed )
-    millis swap [ last-move>> - 1000 / ] [ (>>last-move) ] 2bi ;
-
-: moved ( player -- ) millis swap (>>last-move) ;
-
-: speed-range ( -- range )
-    max-speed [0,b] ;
-
-: change-player-speed ( inc player -- )
-    [ + speed-range clamp-to-range ] change-speed drop ;
-
-: multiply-player-speed ( n player -- )
-    [ * speed-range clamp-to-range ] change-speed drop ; 
-
-: distance-to-move ( seconds-passed player -- distance )
-    speed>> * ;
-
-: bounce ( d-left player -- d-left' player )
-    {
-        [ dup nearest-segment>> bounce-off-wall ]
-        [ sounds>> bang ]
-        [ 3/4 swap multiply-player-speed ]
-        [ ]
-    } cleave ;
-
-:: (distance) ( heading player -- current next location heading )
-    player nearest-segment>>
-    player [ tunnel>> ] [ nearest-segment>> ] bi heading heading-segment
-    player location>> heading ;
-
-: distance-to-heading-segment ( heading player -- distance )
-    (distance) distance-to-next-segment ;
-
-: distance-to-heading-segment-area ( heading player -- distance )
-    (distance) distance-to-next-segment-area ;
-
-: distance-to-collision ( player -- distance )
-    dup nearest-segment>> (distance-to-collision) ;
-
-: almost-to-collision ( player -- distance )
-    distance-to-collision 0.1 - dup 0 < [ drop 0 ] when ;
-
-: from ( player -- radius distance-from-centre )
-    [ nearest-segment>> dup radius>> swap ] [ location>> ] bi
-    distance-from-centre ;
-
-: distance-from-wall ( player -- distance ) from - ;
-: fraction-from-centre ( player -- fraction ) from swap / ;
-: fraction-from-wall ( player -- fraction )
-    fraction-from-centre 1 swap - ;
-
-: update-nearest-segment2 ( heading player -- )
-    2dup distance-to-heading-segment-area 0 <= [
-        [ tunnel>> ] [ nearest-segment>> rot heading-segment ]
-        [ (>>nearest-segment) ] tri
-    ] [
-        2drop
-    ] if ;
-
-:: move-player-on-heading ( d-left player distance heading -- d-left' player )
-    [let* | d-to-move [ d-left distance min ]
-            move-v [ d-to-move heading n*v ] |
-        move-v player location+
-        heading player update-nearest-segment2
-        d-left d-to-move - player ] ;
-
-: distance-to-move-freely ( player -- distance )
-    [ almost-to-collision ]
-    [ [ forward>> ] keep distance-to-heading-segment-area ] bi min ;
-
-: ?move-player-freely ( d-left player -- d-left' player )
-    over 0 > [
-        ! must make sure we are moving a significant distance, otherwise
-        ! we can recurse endlessly due to floating-point imprecision.
-        ! (at least I /think/ that's what causes it...)
-        dup distance-to-move-freely dup 0.1 > [
-            over forward>> move-player-on-heading ?move-player-freely
-        ] [ drop ] if
-    ] when ;
-
-: drag-heading ( player -- heading )
-    [ forward>> ] [ nearest-segment>> forward>> proj ] bi ;
-
-: drag-player ( d-left player -- d-left' player )
-    dup [ [ drag-heading ] keep distance-to-heading-segment-area ]
-    [ drag-heading move-player-on-heading ] bi ;
-
-: (move-player) ( d-left player -- d-left' player )
-    ?move-player-freely over 0 > [
-        ! bounce
-        drag-player
-        (move-player)
-    ] when ;
-
-: move-player ( player -- )
-    [ update-time ] [ distance-to-move ] [ (move-player) 2drop ] tri ;
-
-: update-player ( player -- )
-    [ move-player ] [ nearest-segment>> white swap (>>color) ] bi ;
diff --git a/extra/jamshred/sound/bang.wav b/extra/jamshred/sound/bang.wav
deleted file mode 100644 (file)
index b15af14..0000000
Binary files a/extra/jamshred/sound/bang.wav and /dev/null differ
diff --git a/extra/jamshred/sound/sound.factor b/extra/jamshred/sound/sound.factor
deleted file mode 100644 (file)
index c19c676..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors io.files kernel openal sequences ;
-IN: jamshred.sound
-
-TUPLE: sounds bang ;
-
-: assign-sound ( source wav-path -- )
-    resource-path create-buffer-from-wav AL_BUFFER swap set-source-param ;
-
-: <sounds> ( -- sounds )
-    init-openal 1 gen-sources first sounds boa
-    dup bang>> "extra/jamshred/sound/bang.wav" assign-sound ;
-
-: bang ( sounds -- ) bang>> source-play check-error ;
diff --git a/extra/jamshred/summary.txt b/extra/jamshred/summary.txt
deleted file mode 100644 (file)
index e26fc1c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-A simple 3d tunnel racing game
diff --git a/extra/jamshred/tags.txt b/extra/jamshred/tags.txt
deleted file mode 100644 (file)
index 8ae5957..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-applications
-games
diff --git a/extra/jamshred/tunnel/authors.txt b/extra/jamshred/tunnel/authors.txt
deleted file mode 100755 (executable)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/jamshred/tunnel/tunnel-tests.factor b/extra/jamshred/tunnel/tunnel-tests.factor
deleted file mode 100644 (file)
index 9486713..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays float-arrays jamshred.oint jamshred.tunnel kernel math.vectors sequences tools.test ;
-IN: jamshred.tunnel.tests
-
-[ 0 ] [ T{ segment f { 0 0 0 } f f f 0 }
-        T{ segment f { 1 1 1 } f f f 1 }
-        T{ oint f { 0 0 0.25 } }
-        nearer-segment number>> ] unit-test
-
-[ 0 ] [ T{ oint f { 0 0 0 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
-[ 1 ] [ T{ oint f { 0 0 -1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
-[ 2 ] [ T{ oint f { 0 0.1 -2.1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
-
-[ 3 ] [ <straight-tunnel> T{ oint f { 0 0 -3.25 } } 0 nearest-segment-forward number>> ] unit-test
-
-[ F{ 0 0 0 } ] [ <straight-tunnel> T{ oint f { 0 0 -0.25 } } over first nearest-segment location>> ] unit-test
-
-: test-segment-oint ( -- oint )
-    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint> ;
-
-[ { -1 0 0 } ] [ test-segment-oint { 1 0 0 } vector-to-centre ] unit-test
-[ { 1 0 0 } ] [ test-segment-oint { -1 0 0 } vector-to-centre ] unit-test
-[ { 0 -1 0 } ] [ test-segment-oint { 0 1 0 } vector-to-centre ] unit-test
-[ { 0 1 0 } ] [ test-segment-oint { 0 -1 0 } vector-to-centre ] unit-test
-[ { -1 0 0 } ] [ test-segment-oint { 1 0 -1 } vector-to-centre ] unit-test
-[ { 1 0 0 } ] [ test-segment-oint { -1 0 -1 } vector-to-centre ] unit-test
-[ { 0 -1 0 } ] [ test-segment-oint { 0 1 -1 } vector-to-centre ] unit-test
-[ { 0 1 0 } ] [ test-segment-oint { 0 -1 -1 } vector-to-centre ] unit-test
-
-: simplest-straight-ahead ( -- oint segment )
-    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint>
-    initial-segment ;
-
-[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-heading ] unit-test
-[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-relative-location ] unit-test
-
-: simple-collision-up ( -- oint segment )
-    { 0 0 0 } { 0 1 0 } { 0 0 1 } { -1 0 0 } <oint>
-    initial-segment ;
-
-[ { 0.0 1.0 0.0 } ] [ simple-collision-up sideways-heading ] unit-test
-[ { 0.0 0.0 0.0 } ] [ simple-collision-up sideways-relative-location ] unit-test
-[ { 0.0 1.0 0.0 } ]
-[ simple-collision-up collision-vector 0 0 0 3array v+ ] unit-test
diff --git a/extra/jamshred/tunnel/tunnel.factor b/extra/jamshred/tunnel/tunnel.factor
deleted file mode 100755 (executable)
index 7082ace..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays colors combinators float-arrays kernel jamshred.oint locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ;
-USE: tools.walker
-IN: jamshred.tunnel
-
-: n-segments ( -- n ) 5000 ; inline
-
-TUPLE: segment < oint number color radius ;
-C: <segment> segment
-
-: segment-number++ ( segment -- )
-    [ number>> 1+ ] keep (>>number) ;
-
-: random-color ( -- color )
-    { 100 100 100 } [ random 100 / >float ] map first3 1.0 <rgba> ;
-
-: tunnel-segment-distance ( -- n ) 0.4 ;
-: random-rotation-angle ( -- theta ) pi 20 / ;
-
-: random-segment ( previous-segment -- segment )
-    clone dup random-rotation-angle random-turn
-    tunnel-segment-distance over go-forward
-    random-color >>color dup segment-number++ ;
-
-: (random-segments) ( segments n -- segments )
-    dup 0 > [
-        >r dup peek random-segment over push r> 1- (random-segments)
-    ] [ drop ] if ;
-
-: default-segment-radius ( -- r ) 1 ;
-
-: initial-segment ( -- segment )
-    F{ 0 0 0 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 }
-    0 random-color default-segment-radius <segment> ;
-
-: random-segments ( n -- segments )
-    initial-segment 1vector swap (random-segments) ;
-
-: simple-segment ( n -- segment )
-    [ F{ 0 0 -1 } n*v F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } ] keep
-    random-color default-segment-radius <segment> ;
-
-: simple-segments ( n -- segments )
-    [ simple-segment ] map ;
-
-: <random-tunnel> ( -- segments )
-    n-segments random-segments ;
-
-: <straight-tunnel> ( -- segments )
-    n-segments simple-segments ;
-
-: sub-tunnel ( from to segments -- segments )
-    #! return segments between from and to, after clamping from and to to
-    #! valid values
-    [ sequence-index-range [ clamp-to-range ] curry bi@ ] keep <slice> ;
-
-: nearer-segment ( segment segment oint -- segment )
-    #! return whichever of the two segments is nearer to the oint
-    >r 2dup r> tuck distance >r distance r> < -rot ? ;
-
-: (find-nearest-segment) ( nearest next oint -- nearest ? )
-    #! find the nearest of 'next' and 'nearest' to 'oint', and return
-    #! t if the nearest hasn't changed
-    pick >r nearer-segment dup r> = ;
-
-: find-nearest-segment ( oint segments -- segment )
-    dup first swap rest-slice rot [ (find-nearest-segment) ] curry
-    find 2drop ;
-    
-: nearest-segment-forward ( segments oint start -- segment )
-    rot dup length swap <slice> find-nearest-segment ;
-
-: nearest-segment-backward ( segments oint start -- segment )
-    swapd 1+ 0 spin <slice> <reversed> find-nearest-segment ;
-
-: nearest-segment ( segments oint start-segment -- segment )
-    #! find the segment nearest to 'oint', and return it.
-    #! start looking at segment 'start-segment'
-    number>> over >r
-    [ nearest-segment-forward ] 3keep
-    nearest-segment-backward r> nearer-segment ;
-
-: get-segment ( segments n -- segment )
-    over sequence-index-range clamp-to-range swap nth ;
-
-: next-segment ( segments current-segment -- segment )
-    number>> 1+ get-segment ;
-
-: previous-segment ( segments current-segment -- segment )
-    number>> 1- get-segment ;
-
-: heading-segment ( segments current-segment heading -- segment )
-    #! the next segment on the given heading
-    over forward>> v. 0 <=> {
-        { +gt+ [ next-segment ] }
-        { +lt+ [ previous-segment ] }
-        { +eq+ [ nip ] } ! current segment
-    } case ;
-
-:: distance-to-next-segment ( current next location heading -- distance )
-    [let | cf [ current forward>> ] |
-        cf next location>> v. cf location v. - cf heading v. / ] ;
-
-:: distance-to-next-segment-area ( current next location heading -- distance )
-    [let | cf [ current forward>> ]
-           h [ next current half-way-between-oints ] |
-        cf h v. cf location v. - cf heading v. / ] ;
-
-: vector-to-centre ( seg loc -- v )
-    over location>> swap v- swap forward>> proj-perp ;
-
-: distance-from-centre ( seg loc -- distance )
-    vector-to-centre norm ;
-
-: wall-normal ( seg oint -- n )
-    location>> vector-to-centre normalize ;
-
-: distant ( -- n ) 1000 ;
-
-: max-real ( a b -- c )
-    #! sometimes collision-coefficient yields complex roots, so we ignore these (hack)
-    dup real? [
-        over real? [ max ] [ nip ] if
-    ] [
-        drop dup real? [ drop distant ] unless
-    ] if ;
-
-:: collision-coefficient ( v w r -- c )
-    v norm 0 = [
-        distant
-    ] [
-        [let* | a [ v dup v. ]
-                b [ v w v. 2 * ]
-                c [ w dup v. r sq - ] |
-            c b a quadratic max-real ]
-    ] if ;
-
-: sideways-heading ( oint segment -- v )
-    [ forward>> ] bi@ proj-perp ;
-
-: sideways-relative-location ( oint segment -- loc )
-    [ [ location>> ] bi@ v- ] keep forward>> proj-perp ;
-
-: (distance-to-collision) ( oint segment -- distance )
-    [ sideways-heading ] [ sideways-relative-location ]
-    [ nip radius>> ] 2tri collision-coefficient ;
-
-: collision-vector ( oint segment -- v )
-    dupd (distance-to-collision) swap forward>> n*v ;
-
-: bounce-forward ( segment oint -- )
-    [ wall-normal ] [ forward>> swap reflect ] [ (>>forward) ] tri ;
-
-: bounce-left ( segment oint -- )
-    #! must be done after forward
-    [ forward>> vneg ] dip [ left>> swap reflect ]
-    [ forward>> proj-perp normalize ] [ (>>left) ] tri ;
-
-: bounce-up ( segment oint -- )
-    #! must be done after forward and left!
-    nip [ forward>> ] [ left>> cross ] [ (>>up) ] tri ;
-
-: bounce-off-wall ( oint segment -- )
-    swap [ bounce-forward ] [ bounce-left ] [ bounce-up ] 2tri ;
-
diff --git a/extra/line-art/authors.txt b/extra/line-art/authors.txt
deleted file mode 100644 (file)
index 6a0dc72..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Joe Groff
\ No newline at end of file
diff --git a/extra/line-art/summary.txt b/extra/line-art/summary.txt
deleted file mode 100644 (file)
index 06d16da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Stanford Bunny rendered with cartoon-style lines instead of shading
\ No newline at end of file
diff --git a/extra/line-art/tags.txt b/extra/line-art/tags.txt
deleted file mode 100644 (file)
index 0db7e8e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-demos
-opengl
-glsl
\ No newline at end of file
diff --git a/extra/lisp/authors.txt b/extra/lisp/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/lisp/lisp-docs.factor b/extra/lisp/lisp-docs.factor
deleted file mode 100644 (file)
index c970a1e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-IN: lisp
-USING: help.markup help.syntax ;
-HELP: <LISP
-{ $description "parsing word which converts the lisp code between <LISP and LISP> into factor quotations and calls it" }
-{ $see-also lisp-string>factor } ;
-
-HELP: lisp-string>factor
-{ $values { "str"  "a string of lisp code" } { "quot" "the quotation the lisp compiles into" } }
-{ $description "Turns a string of lisp into a factor quotation" } ;
-
-ARTICLE: "lisp" "Lisp in Factor"
-"This is a simple implementation of a Lisp dialect, which somewhat resembles Scheme." $nl
-"It works in two main stages: "
-{ $list
-  { "Parse (via "  { $vocab-link "lisp.parser" } " the Lisp code into a "
-    { $snippet "s-exp"  } " tuple." }
-  { "Transform the " { $snippet "s-exp" } " into a Factor quotation, via " { $link convert-form } }
-}
-
-{ $subsection "lisp.parser" } ;
-
-ABOUT: "lisp"
\ No newline at end of file
diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor
deleted file mode 100644 (file)
index 5f849c4..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: lisp lisp.parser tools.test sequences math kernel parser arrays lists
-quotations ;
-
-IN: lisp.test
-
-[
-    define-lisp-builtins
-    
-    { 5 } [
-        "(+ 2 3)" lisp-eval
-    ] unit-test
-    
-    { 8.3 } [
-        "(- 10.4 2.1)" lisp-eval
-    ] unit-test
-    
-    { 3 } [
-        "((lambda (x y) (+ x y)) 1 2)" lisp-eval
-    ] unit-test
-    
-    { 42 } [
-        "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval
-    ] unit-test
-    
-    { "b" } [
-        "(cond (#f \"a\") (#t \"b\"))" lisp-eval
-    ] unit-test
-    
-    { "b" } [
-        "(cond ((< 1 2) \"b\") (#t \"a\"))" lisp-eval
-    ] unit-test
-        
-    { +nil+ } [
-        "(list)" lisp-eval
-    ] unit-test
-    
-    { { 1 2 3 4 5 } } [
-        "(list 1 2 3 4 5)" lisp-eval list>seq
-    ] unit-test
-    
-    { { 1 2 { 3 { 4 } 5 } } } [
-        "(list 1 2 (list 3 (list 4) 5))" lisp-eval cons>seq
-    ] unit-test
-    
-    { 5 } [
-        "(begin (+ 1 4))" lisp-eval
-    ] unit-test
-    
-    { 5 } [
-        "(begin (+ 5 6) (+ 1 4))" lisp-eval
-    ] unit-test
-    
-    { t } [
-        T{ lisp-symbol f "if" } lisp-macro?
-    ] unit-test
-    
-    { 1 } [
-        "(if #t 1 2)" lisp-eval
-    ] unit-test
-    
-    { 3 } [
-        "((lambda (x) (if x (+ 1 2) (- 3 5))) #t)" lisp-eval
-    ] unit-test
-    
-    { { 5 4 3 } } [
-        "((lambda (x &rest xs) (cons x xs)) 5 4 3)" lisp-eval cons>seq
-    ] unit-test
-    
-    { { 5 } } [
-        "((lambda (x &rest xs) (cons x xs)) 5)" lisp-eval cons>seq
-    ] unit-test
-    
-    { { 1 2 3 4 } } [
-        "((lambda (&rest xs) xs) 1 2 3 4)" lisp-eval cons>seq
-    ] unit-test
-    
-    { 10 } [
-        <LISP (begin (+ 1 2) (+ 9 1)) LISP>
-    ] unit-test
-    
-    { 4 } [
-        <LISP ((lambda (x y) (if x (+ 1 y) (+ 2 y))) #t 3) LISP>
-    ] unit-test
-    
-    { { 3 3 4 } } [
-        <LISP (defun foo (x y &rest z)
-                  (cons (+ x y) z))
-              (foo 1 2 3 4)
-        LISP> cons>seq
-    ] unit-test
-    
-] with-interactive-vocabs
diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor
deleted file mode 100644 (file)
index 4a93350..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel peg sequences arrays strings 
-namespaces combinators math locals locals.private locals.backend accessors
-vectors syntax lisp.parser assocs parser words
-quotations fry lists summary combinators.short-circuit continuations multiline ;
-IN: lisp
-
-DEFER: convert-form
-DEFER: funcall
-DEFER: lookup-var
-DEFER: lookup-macro
-DEFER: lisp-macro?
-DEFER: lisp-var?
-DEFER: define-lisp-macro
-
-! Functions to convert s-exps to quotations
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: convert-body ( cons -- quot )
-    [ ] [ convert-form compose ] foldl ; inline
-
-: convert-cond ( cons -- quot )
-    cdr [ 2car [ convert-form ] bi@ 2array ]
-    { } lmap-as '[ _ cond ] ;
-
-: convert-general-form ( cons -- quot )
-    uncons [ convert-body ] [ convert-form ] bi* '[ _ @ funcall ] ;
-
-! words for convert-lambda
-<PRIVATE
-: localize-body ( assoc body -- newbody )
-    {
-      { [ dup list? ] [ [ lisp-symbol? ] rot '[ [ name>> _ at ] [ ] bi or ] traverse ] }
-      { [ dup lisp-symbol? ] [ name>> swap at ] }
-     [ nip ]
-    } cond ;
-
-: localize-lambda ( body vars -- newvars newbody )
-    swap [ make-locals dup push-locals ] dip
-    dupd [ localize-body convert-form ] with lmap>array
-    >quotation swap pop-locals ;
-
-: split-lambda ( cons -- body-cons vars-seq )
-    cdr uncons [ name>> ] lmap>array ; inline
-
-: rest-lambda ( body vars -- quot )
-    "&rest" swap [ remove ] [ index ] 2bi
-    [ localize-lambda <lambda> lambda-rewrite call ] dip
-    swap '[ _ cut '[ @ _ seq>list ] call _ call call ] 1quotation ;
-
-: normal-lambda ( body vars -- quot )
-    localize-lambda <lambda> lambda-rewrite '[ @ compose call call ] 1quotation ;
-PRIVATE>
-
-: convert-lambda ( cons -- quot )
-    split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ;
-
-: convert-quoted ( cons -- quot )
-    cadr 1quotation ;
-
-: convert-defmacro ( cons -- quot )
-    cdr [ convert-lambda ] [ car name>> ] bi define-lisp-macro [ ] ;
-
-: macro-expand ( cons -- quot )
-    uncons [ list>seq >quotation ] [ lookup-macro ] bi* call call ;
-
-: expand-macros ( cons -- cons )
-    dup list? [ [ expand-macros ] lmap dup car lisp-macro? [ macro-expand expand-macros ] when ] when ;
-    
-: convert-begin ( cons -- quot )
-    cdr [ convert-form ] [ ] lmap-as [ 1 tail* ] [ but-last ] bi
-    [ '[ { } _ with-datastack drop ] ] map prepend '[ _ [ call ] each ] ;
-
-: form-dispatch ( cons lisp-symbol -- quot )
-    name>>
-    { { "lambda" [ convert-lambda ] }
-      { "defmacro" [ convert-defmacro ] }
-      { "quote" [ convert-quoted ] }
-      { "cond" [ convert-cond ] }
-      { "begin" [ convert-begin ] }
-     [ drop convert-general-form ]
-    } case ;
-
-: convert-list-form ( cons -- quot )
-    dup car
-    {
-      { [ dup lisp-symbol? ] [ form-dispatch ] }
-     [ drop convert-general-form ]
-    } cond ;
-
-: convert-form ( lisp-form -- quot )
-    {
-      { [ dup cons? ] [ convert-list-form ] }
-      { [ dup lisp-var? ] [ lookup-var 1quotation ] }
-      { [ dup lisp-symbol? ] [ '[ _ lookup-var ] ] }
-     [ 1quotation ]
-    } cond ;
-
-: lisp-string>factor ( str -- quot )
-    lisp-expr expand-macros convert-form ;
-
-: lisp-eval ( str -- * )
-    lisp-string>factor call ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: lisp-env
-SYMBOL: macro-env
-
-ERROR: no-such-var variable-name ;
-M: no-such-var summary drop "No such variable" ;
-
-: init-env ( -- )
-    H{ } clone lisp-env set
-    H{ } clone macro-env set ;
-
-: lisp-define ( quot name -- )
-    lisp-env get set-at ;
-    
-: define-lisp-var ( lisp-symbol body --  )
-    swap name>> lisp-define ;
-
-: lisp-get ( name -- word )
-    lisp-env get at ;
-
-: lookup-var ( lisp-symbol -- quot )
-    [ name>> ] [ lisp-var? ] bi [ lisp-get ] [ no-such-var ] if ;
-
-: lisp-var? ( lisp-symbol -- ? )
-    dup lisp-symbol? [ name>> lisp-env get key? ] [ drop f ] if ;
-
-: funcall ( quot sym -- * )
-    [ 1array [ call ] with-datastack >quotation ] dip curry call ; inline
-
-: define-primitive ( name vocab word -- )
-    swap lookup 1quotation '[ _ compose call ] swap lisp-define ;
-
-: lookup-macro ( lisp-symbol -- lambda )
-    name>> macro-env get at ;
-
-: define-lisp-macro ( quot name -- )
-    macro-env get set-at ;
-
-: lisp-macro? ( car -- ? )
-    dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ;
-
-: define-lisp-builtins ( -- )
-   init-env
-
-   f "#f" lisp-define
-   t "#t" lisp-define
-
-   "+" "math" "+" define-primitive
-   "-" "math" "-" define-primitive
-   "<" "math" "<" define-primitive
-   ">" "math" ">" define-primitive
-
-   "cons" "lists" "cons" define-primitive
-   "car" "lists" "car" define-primitive
-   "cdr" "lists" "cdr" define-primitive
-   "append" "lists" "lappend" define-primitive
-   "nil" "lists" "nil" define-primitive
-   "nil?" "lists" "nil?" define-primitive
-
-   "set" "lisp" "define-lisp-var" define-primitive
-    
-   "(set 'list (lambda (&rest xs) xs))" lisp-eval
-   "(defmacro setq (var val) (list 'set (list 'quote var) val))" lisp-eval
-    
-   <" (defmacro defun (name vars &rest body)
-        (list 'setq name (cons 'lambda (cons vars body)))) "> lisp-eval
-    
-   "(defmacro if (pred tr fl) (list 'cond (list pred tr) (list (quote #t) fl)))" lisp-eval
-   ;
-
-: <LISP 
-    "LISP>" parse-multiline-string "(begin " prepend ")" append define-lisp-builtins
-    lisp-string>factor parsed \ call parsed ; parsing
\ No newline at end of file
diff --git a/extra/lisp/parser/authors.txt b/extra/lisp/parser/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/lisp/parser/parser-docs.factor b/extra/lisp/parser/parser-docs.factor
deleted file mode 100644 (file)
index fc16a0a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-IN: lisp.parser
-USING: help.markup help.syntax ;
-
-ARTICLE: "lisp.parser" "Parsing strings of Lisp"
-"This vocab uses " { $vocab-link "peg.ebnf" } " to turn strings of Lisp into " { $snippet "s-exp" } "s, which are then used by"
-{ $vocab-link "lisp" } " to produce Factor quotations." ;
\ No newline at end of file
diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor
deleted file mode 100644 (file)
index 911a8d3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: lisp.parser tools.test peg peg.ebnf lists ;
-
-IN: lisp.parser.tests
-
-{ 1234  }  [
-  "1234" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ -42  }  [
-    "-42" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ 37/52 } [
-    "37/52" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ 123.98 } [
-    "123.98" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "" } [
-    "\"\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "aoeu" } [
-    "\"aoeu\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ "aoeu\"de" } [
-    "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ T{ lisp-symbol f "foobar" } } [
-    "foobar" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ T{ lisp-symbol f "+" } } [
-    "+" "atom" \ lisp-expr rule parse
-] unit-test
-
-{ +nil+ } [
-    "()" lisp-expr
-] unit-test
-
-{ T{
-    cons
-    f
-    T{ lisp-symbol f "foo" }
-    T{
-        cons
-        f
-        1
-        T{ cons f 2 T{ cons f "aoeu" +nil+ } }
-    } } } [
-    "(foo 1 2 \"aoeu\")" lisp-expr
-] unit-test
-
-{ T{ cons f
-       1
-       T{ cons f
-           T{ cons f 3 T{ cons f 4 +nil+ } }
-           T{ cons f 2 +nil+ } }
-   }
-} [
-    "(1 (3 4) 2)" lisp-expr
-] unit-test
-    
-{ { T{ lisp-symbol { name "quote" } } { 1 2 3 } } } [
-    "'(1 2 3)" lisp-expr cons>seq
-] unit-test
-    
-{ { T{ lisp-symbol f "quote" } T{ lisp-symbol f "foo" } } } [
-    "'foo" lisp-expr cons>seq
-] unit-test
-    
-{ { 1 2 { T{ lisp-symbol { name "quote" } } { 3 4 } } 5 } } [
-    "(1 2 '(3 4) 5)" lisp-expr cons>seq
-] unit-test
\ No newline at end of file
diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor
deleted file mode 100644 (file)
index 50f5869..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel peg peg.ebnf math.parser sequences arrays strings
-math fry accessors lists combinators.short-circuit ;
-
-IN: lisp.parser
-
-TUPLE: lisp-symbol name ;
-C: <lisp-symbol> lisp-symbol
-
-EBNF: lisp-expr
-_            = (" " | "\t" | "\n")*
-LPAREN       = "("
-RPAREN       = ")"
-dquote       = '"'
-squote       = "'"
-digit        = [0-9]
-integer      = ("-")? (digit)+                           => [[ first2 append string>number ]]
-float        = integer "." (digit)*                      => [[ first3 >string [ number>string ] 2dip 3append string>number ]]
-rational     = integer "/" (digit)+                      => [[ first3 nip string>number / ]]
-number       = float
-              | rational
-              | integer
-id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":"
-              | "<" | "#" | " =" | ">" | "?" | "^" | "_"
-              | "~" | "+" | "-" | "." | "@"
-letters      = [a-zA-Z]                                  => [[ 1array >string ]]
-initials     = letters | id-specials
-numbers      = [0-9]                                     => [[ 1array >string ]]
-subsequents  = initials | numbers
-identifier   = initials (subsequents)*                   => [[ first2 concat append <lisp-symbol> ]]
-escaped      = "\" .                                     => [[ second ]]
-string       = dquote ( escaped | !(dquote) . )*  dquote => [[ second >string ]]
-atom         = number
-              | identifier
-              | string
-s-expression = LPAREN (list-item)* RPAREN                => [[ second seq>cons ]]
-list-item    = _ ( atom | s-expression | quoted ) _      => [[ second ]]
-quoted       = squote list-item                          => [[ second nil cons "quote" <lisp-symbol> swap cons ]]
-expr         = list-item
-;EBNF
\ No newline at end of file
diff --git a/extra/lisp/parser/summary.txt b/extra/lisp/parser/summary.txt
deleted file mode 100644 (file)
index aa407b3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-EBNF grammar for parsing Lisp
diff --git a/extra/lisp/parser/tags.txt b/extra/lisp/parser/tags.txt
deleted file mode 100644 (file)
index d1f6fa1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-lisp
-parsing
diff --git a/extra/lisp/summary.txt b/extra/lisp/summary.txt
deleted file mode 100644 (file)
index 7277c2a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-A Lisp interpreter/compiler in Factor 
diff --git a/extra/lisp/tags.txt b/extra/lisp/tags.txt
deleted file mode 100644 (file)
index c369cca..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-lisp
-languages
index fc7149e18154eb7a2ce97f1c219aa8b2098c1478..49f280fa84977ba8926d233d737b4398ccf1aff7 100644 (file)
@@ -15,9 +15,11 @@ IN: mason.common
 
 :: upload-safely ( local username host remote -- )
     [let* | temp [ remote ".incomplete" append ]
-            scp-remote [ { username "@" host ":" temp } concat ] |
-        { "scp" local scp-remote } short-running-process
-        { "ssh" host "-l" username "mv" temp remote } short-running-process
+            scp-remote [ { username "@" host ":" temp } concat ]
+            scp [ scp-command get ]
+            ssh [ ssh-command get ] |
+        { scp local scp-remote } short-running-process
+        { ssh host "-l" username "mv" temp remote } short-running-process
     ] ;
 
 : eval-file ( file -- obj )
index e4ef127413d88e33bf2177f99926a01adc56b35f..9169fbf1960d036784f2c2e53aa629b6bba61672 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: system io.files namespaces kernel accessors ;
+USING: system io.files namespaces kernel accessors assocs ;
 IN: mason.config
 
 ! (Optional) Location for build directories
@@ -77,3 +77,10 @@ SYMBOL: upload-username
 
 ! Directory with binary packages.
 SYMBOL: upload-directory
+
+! Optional: override ssh and scp command names
+SYMBOL: scp-command
+scp-command global [ "scp" or ] change-at
+
+SYMBOL: ssh-command
+ssh-command global [ "ssh" or ] change-at
index ae3ddb61fc994d8c146a548faffee02e3259ddc6..463f8b13c179f122228d6869ec606ca770c9aba3 100644 (file)
@@ -14,6 +14,7 @@ USING: mason.release.branch mason.config tools.test namespaces ;
 
 [ { "scp" "boot.unix-x86.64.image" "joe@blah.com:/stuff/clean/netbsd-x86-64" } ] [
     [
+        "scp" scp-command set
         "joe" image-username set
         "blah.com" image-host set
         "/stuff/clean" image-directory set
index ff2632a9b3a709a39959f9f9cf0b439c0c682ce6..600b08c6b66e4fbc0e05add1dca8eda90ec2f825 100644 (file)
@@ -1,8 +1,7 @@
 ! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces sequences prettyprint io.files
-io.launcher make
-mason.common mason.platform mason.config ;
+io.launcher make mason.common mason.platform mason.config ;
 IN: mason.release.branch
 
 : branch-name ( -- string ) "clean-" platform append ;
@@ -25,7 +24,7 @@ IN: mason.release.branch
 
 : upload-clean-image-cmd ( -- args )
     [
-        "scp" ,
+        scp-command get ,
         boot-image-name ,
         [
             image-username get % "@" %
index 3de1fa643f46f8d675a81bd368297263a0ab80e9..b23ad19e5e7d9836eaf9da261751c0e86fb56256 100644 (file)
@@ -3,7 +3,7 @@
 USING: kernel namespaces assocs io.files io.encodings.utf8
 prettyprint help.lint benchmark tools.time bootstrap.stage2
 tools.test tools.vocabs help.html mason.common words generic
-accessors compiler.errors sequences sets sorting ;
+accessors compiler.errors sequences sets sorting math ;
 IN: mason.test
 
 : do-load ( -- )
@@ -47,7 +47,7 @@ M: method-body word-vocabulary "method-generic" word-prop word-vocabulary ;
     ".." [
         bootstrap-time get boot-time-file to-file
         [ do-load do-compile-errors ] benchmark-ms load-time-file to-file
-        [ generate-help ]  html-help-time-file to-file
+        [ generate-help ] benchmark-ms html-help-time-file to-file
         [ do-tests ] benchmark-ms test-time-file to-file
         [ do-help-lint ] benchmark-ms help-lint-time-file to-file
         [ do-benchmarks ] benchmark-ms benchmark-time-file to-file
index 131007b9d07be36ee653e279b7f45c5fac0ce847..4c0a88f92938778c156fda659b4e8b51a3d69340 100644 (file)
@@ -5,6 +5,7 @@ IN: math.blas.cblas
     { [ os macosx? ] [ "libblas.dylib" "cdecl" add-library ] }
     { [ os windows? ] [ "blas.dll" "cdecl" add-library ] }
     { [ os openbsd? ] [ "libcblas.so" "cdecl" add-library ] }
+    { [ os freebsd? ] [ "libcblas.so" "cdecl" add-library ] }
     [ "libblas.so" "cdecl" add-library ]
 } cond >>
 
@@ -33,10 +34,10 @@ TYPEDEF: int CBLAS_SIDE
 
 TYPEDEF: int CBLAS_INDEX
 
-C-STRUCT: CBLAS_C
+C-STRUCT: float-complex
     { "float" "real" }
     { "float" "imag" } ;
-C-STRUCT: CBLAS_Z
+C-STRUCT: double-complex
     { "double" "real" }
     { "double" "imag" } ;
 
@@ -52,14 +53,14 @@ FUNCTION: double cblas_ddot
     ( int N,                 double*  X, int incX, double*  Y, int incY ) ;
 
 FUNCTION: void   cblas_cdotu_sub
-    ( int N,                 CBLAS_C* X, int incX, CBLAS_C* Y, int incY, CBLAS_C* dotu ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotu ) ;
 FUNCTION: void   cblas_cdotc_sub
-    ( int N,                 CBLAS_C* X, int incX, CBLAS_C* Y, int incY, CBLAS_C* dotc ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotc ) ;
 
 FUNCTION: void   cblas_zdotu_sub
-    ( int N,                 CBLAS_Z* X, int incX, CBLAS_Z* Y, int incY, CBLAS_Z* dotu ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotu ) ;
 FUNCTION: void   cblas_zdotc_sub
-    ( int N,                 CBLAS_Z* X, int incX, CBLAS_Z* Y, int incY, CBLAS_Z* dotc ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY, void*    dotc ) ;
 
 FUNCTION: float  cblas_snrm2
     ( int N,                 float*   X, int incX ) ;
@@ -72,23 +73,23 @@ FUNCTION: double cblas_dasum
     ( int N,                 double*  X, int incX ) ;
 
 FUNCTION: float  cblas_scnrm2
-    ( int N,                 CBLAS_C* X, int incX ) ;
+    ( int N,                 void*    X, int incX ) ;
 FUNCTION: float  cblas_scasum
-    ( int N,                 CBLAS_C* X, int incX ) ;
+    ( int N,                 void*    X, int incX ) ;
 
 FUNCTION: double cblas_dznrm2
-    ( int N,                 CBLAS_Z* X, int incX ) ;
+    ( int N,                 void*    X, int incX ) ;
 FUNCTION: double cblas_dzasum
-    ( int N,                 CBLAS_Z* X, int incX ) ;
+    ( 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,                 CBLAS_C* X, int incX ) ;
+    ( int N,                 void*    X, int incX ) ;
 FUNCTION: CBLAS_INDEX cblas_izamax
-    ( int N,                 CBLAS_Z* X, int incX ) ;
+    ( int N,                 void*    X, int incX ) ;
 
 FUNCTION: void cblas_sswap
     ( int N,                 float*   X, int incX, float*   Y, int incY ) ;
@@ -105,31 +106,31 @@ FUNCTION: void cblas_daxpy
     ( int N, double   alpha, double*  X, int incX, double*  Y, int incY ) ;
 
 FUNCTION: void cblas_cswap
-    ( int N,                 CBLAS_C* X, int incX, CBLAS_C* Y, int incY ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
 FUNCTION: void cblas_ccopy
-    ( int N,                 CBLAS_C* X, int incX, CBLAS_C* Y, int incY ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
 FUNCTION: void cblas_caxpy
-    ( int N, CBLAS_C* alpha, CBLAS_C* X, int incX, CBLAS_C* Y, int incY ) ;
+    ( int N, void*    alpha, void*    X, int incX, void*    Y, int incY ) ;
 
 FUNCTION: void cblas_zswap
-    ( int N,                 CBLAS_Z* X, int incX, CBLAS_Z* Y, int incY ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
 FUNCTION: void cblas_zcopy
-    ( int N,                 CBLAS_Z* X, int incX, CBLAS_Z* Y, int incY ) ;
+    ( int N,                 void*    X, int incX, void*    Y, int incY ) ;
 FUNCTION: void cblas_zaxpy
-    ( int N, CBLAS_Z* alpha, CBLAS_Z* X, int incX, CBLAS_Z* Y, int incY ) ;
+    ( 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, CBLAS_C* alpha, CBLAS_C* X, int incX ) ;
+    ( int N, void*    alpha, void*    X, int incX ) ;
 FUNCTION: void cblas_zscal
-    ( int N, CBLAS_Z* alpha, CBLAS_Z* X, int incX ) ;
+    ( int N, void*    alpha, void*    X, int incX ) ;
 FUNCTION: void cblas_csscal
-    ( int N, float    alpha, CBLAS_C* X, int incX ) ;
+    ( int N, float    alpha, void*    X, int incX ) ;
 FUNCTION: void cblas_zdscal
-    ( int N, double   alpha, CBLAS_Z* X, int incX ) ;
+    ( int N, double   alpha, void*    X, int incX ) ;
 
 FUNCTION: void cblas_srotg
     ( float* a, float* b, float* c, float* s ) ;
index dc6a86017ab9206fdcc0c3fa61470729707b5a69..01e0997405f3132ab2987f9355c93073ba097acd 100644 (file)
@@ -88,7 +88,7 @@ HELP: blas-matrix-base
 }
 "All of these subclasses share the same tuple layout:"
 { $list
-    { { $snippet "data" } " contains an alien pointer referencing or byte-array containing a packed, column-major array of float, double, float complex, or double complex values;" }
+    { { $snippet "underlying" } " contains an alien pointer referencing or byte-array containing a packed, column-major array of float, double, float complex, or double complex values;" }
     { { $snippet "ld" } " indicates the distance, in elements, between matrix columns;" }
     { { $snippet "rows" } " and " { $snippet "cols" } " indicate the number of significant rows and columns in the matrix;" }
     { "and " { $snippet "transpose" } ", if set to a true value, indicates that the matrix should be treated as transposed relative to its in-memory representation." }
index 4f50543e73ed479010b323b8a5164e4e06c22c81..c8a4ee6292654144f1ee7193055a1c770de3ba5a 100755 (executable)
@@ -1,31 +1,13 @@
 USING: accessors alien alien.c-types arrays byte-arrays combinators
-combinators.lib combinators.short-circuit fry kernel locals macros
+combinators.short-circuit fry kernel locals macros
 math math.blas.cblas math.blas.vectors math.blas.vectors.private
-math.complex math.functions math.order multi-methods qualified
-sequences sequences.merged sequences.private generalizations
-shuffle symbols ;
-QUALIFIED: syntax
+math.complex math.functions math.order functors words
+sequences sequences.merged sequences.private shuffle symbols
+specialized-arrays.direct.float specialized-arrays.direct.double
+specialized-arrays.float specialized-arrays.double ;
 IN: math.blas.matrices
 
-TUPLE: blas-matrix-base data ld rows cols transpose ;
-TUPLE: float-blas-matrix < blas-matrix-base ;
-TUPLE: double-blas-matrix < blas-matrix-base ;
-TUPLE: float-complex-blas-matrix < blas-matrix-base ;
-TUPLE: double-complex-blas-matrix < blas-matrix-base ;
-
-C: <float-blas-matrix> float-blas-matrix
-C: <double-blas-matrix> double-blas-matrix
-C: <float-complex-blas-matrix> float-complex-blas-matrix
-C: <double-complex-blas-matrix> double-complex-blas-matrix
-
-METHOD: element-type { float-blas-matrix }
-    drop "float" ;
-METHOD: element-type { double-blas-matrix }
-    drop "double" ;
-METHOD: element-type { float-complex-blas-matrix }
-    drop "CBLAS_C" ;
-METHOD: element-type { double-complex-blas-matrix }
-    drop "CBLAS_Z" ;
+TUPLE: blas-matrix-base underlying ld rows cols transpose ;
 
 : Mtransposed? ( matrix -- ? )
     transpose>> ; inline
@@ -34,6 +16,11 @@ METHOD: element-type { double-complex-blas-matrix }
 : Mheight ( matrix -- height )
     dup Mtransposed? [ cols>> ] [ rows>> ] if ; inline
 
+GENERIC: n*M.V+n*V! ( alpha A x beta y -- y=alpha*A.x+b*y )
+GENERIC: n*V(*)V+M! ( alpha x y A -- A=alpha*x(*)y+A )
+GENERIC: n*V(*)Vconj+M! ( alpha x y A -- A=alpha*x(*)yconj+A )
+GENERIC: n*M.M+n*M! ( alpha A B beta C -- C=alpha*A.B+beta*C )
+
 <PRIVATE
 
 : (blas-transpose) ( matrix -- integer )
@@ -41,53 +28,29 @@ METHOD: element-type { double-complex-blas-matrix }
 
 GENERIC: (blas-matrix-like) ( data ld rows cols transpose exemplar -- matrix )
 
-METHOD: (blas-matrix-like) { object object object object object float-blas-matrix }
-    drop <float-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object double-blas-matrix }
-    drop <double-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object float-complex-blas-matrix }
-    drop <float-complex-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object double-complex-blas-matrix }
-    drop <double-complex-blas-matrix> ;
-
-METHOD: (blas-matrix-like) { object object object object object float-blas-vector }
-    drop <float-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object double-blas-vector }
-    drop <double-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object float-complex-blas-vector }
-    drop <float-complex-blas-matrix> ;
-METHOD: (blas-matrix-like) { object object object object object double-complex-blas-vector }
-    drop <double-complex-blas-matrix> ;
-
-METHOD: (blas-vector-like) { object object object float-blas-matrix }
-    drop <float-blas-vector> ;
-METHOD: (blas-vector-like) { object object object double-blas-matrix }
-    drop <double-blas-vector> ;
-METHOD: (blas-vector-like) { object object object float-complex-blas-matrix }
-    drop <float-complex-blas-vector> ;
-METHOD: (blas-vector-like) { object object object double-complex-blas-matrix }
-    drop <double-complex-blas-vector> ;
-
 : (validate-gemv) ( A x y -- )
     {
         [ drop [ Mwidth  ] [ length>> ] bi* = ]
         [ nip  [ Mheight ] [ length>> ] bi* = ]
     } 3&&
-    [ "Mismatched matrix and vectors in matrix-vector multiplication" throw ] unless ;
+    [ "Mismatched matrix and vectors in matrix-vector multiplication" throw ]
+    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 )
+:: (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 )
     A x y (validate-gemv)
     CblasColMajor
     A (blas-transpose)
     A rows>>
     A cols>>
     alpha >c-arg call
-    A data>>
+    A underlying>>
     A ld>>
-    x data>>
+    x underlying>>
     x inc>>
     beta >c-arg call
-    y data>>
+    y underlying>>
     y inc>>
     y ; inline
 
@@ -96,19 +59,22 @@ METHOD: (blas-vector-like) { object object object double-complex-blas-matrix }
         [ nip  [ length>> ] [ Mheight ] bi* = ]
         [ nipd [ length>> ] [ Mwidth  ] bi* = ]
     } 3&&
-    [ "Mismatched vertices and matrix in vector outer product" throw ] unless ;
+    [ "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 )
+:: (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 )
     x y A (validate-ger)
     CblasColMajor
     A rows>>
     A cols>>
     alpha >c-arg call
-    x data>>
+    x underlying>>
     x inc>>
-    y data>>
+    y underlying>>
     y inc>>
-    A data>>
+    A underlying>>
     A ld>>
     A f >>transpose ; inline
 
@@ -117,9 +83,13 @@ METHOD: (blas-vector-like) { object object object double-complex-blas-matrix }
         [ drop [ Mwidth  ] [ Mheight ] bi* = ]
         [ nip  [ Mheight ] bi@ = ]
         [ nipd [ Mwidth  ] bi@ = ]
-    } 3&& [ "Mismatched matrices in matrix multiplication" throw ] unless ;
+    } 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 )
+:: (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 )
     A B C (validate-gemm)
     CblasColMajor
     A (blas-transpose)
@@ -128,12 +98,12 @@ METHOD: (blas-vector-like) { object object object double-complex-blas-matrix }
     C cols>>
     A Mwidth
     alpha >c-arg call
-    A data>>
+    A underlying>>
     A ld>>
-    B data>>
+    B underlying>>
     B ld>>
     beta >c-arg call
-    C data>>
+    C underlying>>
     C ld>>
     C f >>transpose ; inline
 
@@ -142,65 +112,22 @@ METHOD: (blas-vector-like) { object object object double-complex-blas-matrix }
 
 PRIVATE>
 
-: >float-blas-matrix ( arrays -- matrix )
-    [ >c-float-array ] (>matrix) <float-blas-matrix> ;
-: >double-blas-matrix ( arrays -- matrix )
-    [ >c-double-array ] (>matrix) <double-blas-matrix> ;
-: >float-complex-blas-matrix ( arrays -- matrix )
-    [ (flatten-complex-sequence) >c-float-array ] (>matrix)
-    <float-complex-blas-matrix> ;
-: >double-complex-blas-matrix ( arrays -- matrix )
-    [ (flatten-complex-sequence) >c-double-array ] (>matrix)
-    <double-complex-blas-matrix> ;
-
-GENERIC: n*M.V+n*V! ( alpha A x beta y -- y=alpha*A.x+b*y )
-GENERIC: n*V(*)V+M! ( alpha x y A -- A=alpha*x(*)y+A )
-GENERIC: n*V(*)Vconj+M! ( alpha x y A -- A=alpha*x(*)yconj+A )
-GENERIC: n*M.M+n*M! ( alpha A B beta C -- C=alpha*A.B+beta*C )
-
-METHOD: n*M.V+n*V! { real float-blas-matrix float-blas-vector real float-blas-vector }
-    [ ] (prepare-gemv) [ cblas_sgemv ] dip ;
-METHOD: n*M.V+n*V! { real double-blas-matrix double-blas-vector real double-blas-vector }
-    [ ] (prepare-gemv) [ cblas_dgemv ] dip ;
-METHOD: n*M.V+n*V! { number float-complex-blas-matrix float-complex-blas-vector number float-complex-blas-vector }
-    [ (>c-complex) ] (prepare-gemv) [ cblas_cgemv ] dip ;
-METHOD: n*M.V+n*V! { number double-complex-blas-matrix double-complex-blas-vector number double-complex-blas-vector }
-    [ (>z-complex) ] (prepare-gemv) [ cblas_zgemv ] dip ;
-
-METHOD: n*V(*)V+M! { real float-blas-vector float-blas-vector float-blas-matrix }
-    [ ] (prepare-ger) [ cblas_sger ] dip ;
-METHOD: n*V(*)V+M! { real double-blas-vector double-blas-vector double-blas-matrix }
-    [ ] (prepare-ger) [ cblas_dger ] dip ;
-METHOD: n*V(*)V+M! { number float-complex-blas-vector float-complex-blas-vector float-complex-blas-matrix }
-    [ (>c-complex) ] (prepare-ger) [ cblas_cgeru ] dip ;
-METHOD: n*V(*)V+M! { number double-complex-blas-vector double-complex-blas-vector double-complex-blas-matrix }
-    [ (>z-complex) ] (prepare-ger) [ cblas_zgeru ] dip ;
-
-METHOD: n*V(*)Vconj+M! { real float-blas-vector float-blas-vector float-blas-matrix }
-    [ ] (prepare-ger) [ cblas_sger ] dip ;
-METHOD: n*V(*)Vconj+M! { real double-blas-vector double-blas-vector double-blas-matrix }
-    [ ] (prepare-ger) [ cblas_dger ] dip ;
-METHOD: n*V(*)Vconj+M! { number float-complex-blas-vector float-complex-blas-vector float-complex-blas-matrix }
-    [ (>c-complex) ] (prepare-ger) [ cblas_cgerc ] dip ;
-METHOD: n*V(*)Vconj+M! { number double-complex-blas-vector double-complex-blas-vector double-complex-blas-matrix }
-    [ (>z-complex) ] (prepare-ger) [ cblas_zgerc ] dip ;
-
-METHOD: n*M.M+n*M! { real float-blas-matrix float-blas-matrix real float-blas-matrix }
-    [ ] (prepare-gemm) [ cblas_sgemm ] dip ;
-METHOD: n*M.M+n*M! { real double-blas-matrix double-blas-matrix real double-blas-matrix }
-    [ ] (prepare-gemm) [ cblas_dgemm ] dip ;
-METHOD: n*M.M+n*M! { number float-complex-blas-matrix float-complex-blas-matrix number float-complex-blas-matrix }
-    [ (>c-complex) ] (prepare-gemm) [ cblas_cgemm ] dip ;
-METHOD: n*M.M+n*M! { number double-complex-blas-matrix double-complex-blas-matrix number double-complex-blas-matrix }
-    [ (>z-complex) ] (prepare-gemm) [ cblas_zgemm ] dip ;
-
 ! XXX should do a dense clone
-syntax:M: blas-matrix-base clone
+M: blas-matrix-base clone
     [ 
-        [
-            { [ data>> ] [ ld>> ] [ cols>> ] [ element-type heap-size ] } cleave
-            * * memory>byte-array
-        ] [ { [ ld>> ] [ rows>> ] [ cols>> ] [ transpose>> ] } cleave ] bi
+        [ {
+            [ underlying>> ]
+            [ ld>> ]
+            [ cols>> ]
+            [ element-type heap-size ]
+        } cleave * * memory>byte-array ]
+        [ {
+            [ ld>> ]
+            [ rows>> ]
+            [ cols>> ]
+            [ transpose>> ]
+        } cleave ]
+        bi
     ] keep (blas-matrix-like) ;
 
 ! XXX try rounding stride to next 128 bit bound for better vectorizin'
@@ -246,29 +173,31 @@ syntax:M: blas-matrix-base clone
 
 :: (Msub) ( matrix row col height width -- data ld rows cols )
     matrix ld>> col * row + matrix element-type heap-size *
-    matrix data>> <displaced-alien>
+    matrix underlying>> <displaced-alien>
     matrix ld>>
     height
     width ;
 
-: Msub ( matrix row col height width -- sub )
-    5 npick dup transpose>>
-    [ nip [ [ swap ] 2dip swap ] when (Msub) ] 2keep
-    swap (blas-matrix-like) ;
+:: Msub ( matrix row col height width -- sub )
+    matrix dup transpose>>
+    [ col row width height ]
+    [ row col height width ] if (Msub)
+    matrix transpose>> matrix (blas-matrix-like) ;
 
-TUPLE: blas-matrix-rowcol-sequence parent inc rowcol-length rowcol-jump length ;
+TUPLE: blas-matrix-rowcol-sequence
+    parent inc rowcol-length rowcol-jump length ;
 C: <blas-matrix-rowcol-sequence> blas-matrix-rowcol-sequence
 
 INSTANCE: blas-matrix-rowcol-sequence sequence
 
-syntax:M: blas-matrix-rowcol-sequence length
+M: blas-matrix-rowcol-sequence length
     length>> ;
-syntax:M: blas-matrix-rowcol-sequence nth-unsafe
+M: blas-matrix-rowcol-sequence nth-unsafe
     {
         [
             [ rowcol-jump>> ]
             [ parent>> element-type heap-size ]
-            [ parent>> data>> ] tri
+            [ parent>> underlying>> ] tri
             [ * * ] dip <displaced-alien>
         ]
         [ rowcol-length>> ]
@@ -277,11 +206,11 @@ syntax:M: blas-matrix-rowcol-sequence nth-unsafe
     } cleave (blas-vector-like) ;
 
 : (Mcols) ( A -- columns )
-    { [ ] [ drop 1 ] [ rows>> ] [ ld>> ] [ cols>> ] } cleave
-    <blas-matrix-rowcol-sequence> ;
+    { [ ] [ drop 1 ] [ rows>> ] [ ld>> ] [ cols>> ] }
+    cleave <blas-matrix-rowcol-sequence> ;
 : (Mrows) ( A -- rows )
-    { [ ] [ ld>> ] [ cols>> ] [ drop 1 ] [ rows>> ] } cleave
-    <blas-matrix-rowcol-sequence> ;
+    { [ ] [ ld>> ] [ cols>> ] [ drop 1 ] [ rows>> ] }
+    cleave <blas-matrix-rowcol-sequence> ;
 
 : Mrows ( A -- rows )
     dup transpose>> [ (Mcols) ] [ (Mrows) ] if ;
@@ -300,11 +229,79 @@ syntax:M: blas-matrix-rowcol-sequence nth-unsafe
     recip swap n*M ; inline
 
 : Mtranspose ( matrix -- matrix^T )
-    [ { [ data>> ] [ ld>> ] [ rows>> ] [ cols>> ] [ transpose>> not ] } cleave ] keep (blas-matrix-like) ;
-
-syntax:M: blas-matrix-base equal?
+    [ {
+        [ underlying>> ]
+        [ ld>> ] [ rows>> ]
+        [ cols>> ]
+        [ transpose>> not ]
+    } cleave ] keep (blas-matrix-like) ;
+
+M: blas-matrix-base equal?
     {
         [ [ Mwidth ] bi@ = ]
         [ [ Mcols ] bi@ [ = ] 2all? ]
     } 2&& ;
 
+<<
+
+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}
+
+MATRIX      DEFINES ${TYPE}-blas-matrix
+<MATRIX>    DEFINES <${TYPE}-blas-matrix>
+>MATRIX     DEFINES >${TYPE}-blas-matrix
+
+WHERE
+
+TUPLE: MATRIX < blas-matrix-base ;
+: <MATRIX> ( underlying ld rows cols transpose -- matrix )
+    MATRIX boa ; inline
+
+M: MATRIX element-type
+    drop TYPE ;
+M: MATRIX (blas-matrix-like)
+    drop <MATRIX> execute ;
+M: VECTOR (blas-matrix-like)
+    drop <MATRIX> execute ;
+M: MATRIX (blas-vector-like)
+    drop <VECTOR> execute ;
+
+: >MATRIX ( arrays -- matrix )
+    [ >ARRAY execute underlying>> ] (>matrix)
+    <MATRIX> execute ;
+
+M: VECTOR n*M.V+n*V!
+    [ TYPE>ARG execute ] (prepare-gemv)
+    [ XGEMV execute ] dip ;
+M: MATRIX n*M.M+n*M!
+    [ TYPE>ARG execute ] (prepare-gemm)
+    [ XGEMM execute ] dip ;
+M: MATRIX n*V(*)V+M!
+    [ TYPE>ARG execute ] (prepare-ger)
+    [ XGERU execute ] dip ;
+M: MATRIX n*V(*)Vconj+M!
+    [ TYPE>ARG execute ] (prepare-ger)
+    [ XGERC execute ] dip ;
+
+;FUNCTOR
+
+
+: define-real-blas-matrix ( TYPE T -- )
+    "" "" (define-blas-matrix) ;
+: define-complex-blas-matrix ( TYPE T -- )
+    "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
+
+>>
index 6b4091068773b4adef445e88cdf63ad8c403abb0..95f9f7bd083b9c488b5febd8825b6d8ba2501ea4 100644 (file)
@@ -1,4 +1,4 @@
-USING: kernel math.blas.matrices math.blas.vectors parser
+USING: kernel math.blas.vectors math.blas.matrices parser
 arrays prettyprint.backend sequences ;
 IN: math.blas.syntax
 
@@ -20,15 +20,23 @@ IN: math.blas.syntax
 : zmatrix{
     \ } [ >double-complex-blas-matrix ] parse-literal ; parsing
 
-M: float-blas-vector pprint-delims drop \ svector{ \ } ;
-M: double-blas-vector pprint-delims drop \ dvector{ \ } ;
-M: float-complex-blas-vector pprint-delims drop \ cvector{ \ } ;
-M: double-complex-blas-vector pprint-delims drop \ zvector{ \ } ;
+M: float-blas-vector pprint-delims
+    drop \ svector{ \ } ;
+M: double-blas-vector pprint-delims
+    drop \ dvector{ \ } ;
+M: float-complex-blas-vector pprint-delims
+    drop \ cvector{ \ } ;
+M: double-complex-blas-vector pprint-delims
+    drop \ zvector{ \ } ;
 
-M: float-blas-matrix pprint-delims drop \ smatrix{ \ } ;
-M: double-blas-matrix pprint-delims drop \ dmatrix{ \ } ;
-M: float-complex-blas-matrix pprint-delims drop \ cmatrix{ \ } ;
-M: double-complex-blas-matrix pprint-delims drop \ zmatrix{ \ } ;
+M: float-blas-matrix pprint-delims
+    drop \ smatrix{ \ } ;
+M: double-blas-matrix pprint-delims
+    drop \ dmatrix{ \ } ;
+M: float-complex-blas-matrix pprint-delims
+    drop \ cmatrix{ \ } ;
+M: double-complex-blas-matrix pprint-delims
+    drop \ zmatrix{ \ } ;
 
 M: blas-vector-base >pprint-sequence ;
 M: blas-vector-base pprint* pprint-object ;
index 0595f0098916bd36df030bd4eb97ca0a731a2ab9..cb26d67334a4080c18ac701b86c44f12a1459366 100644 (file)
@@ -37,7 +37,7 @@ HELP: blas-vector-base
 }
 "All of these subclasses share the same tuple layout:"
 { $list
-    { { $snippet "data" } " contains an alien pointer referencing or byte-array containing a packed array of float, double, float complex, or double complex values;" }
+    { { $snippet "underlying" } " contains an alien pointer referencing or byte-array containing a packed array of float, double, float complex, or double complex values;" }
     { { $snippet "length" } " indicates the length of the vector;" }
     { "and " { $snippet "inc" } " indicates the distance, in elements, between elements." }
 } } ;
index a135f08f28d3136961c2af375cac3d90e1e6e640..db027b0ffd32c4a78dca5d47416fef20864392a1 100755 (executable)
 USING: accessors alien alien.c-types arrays byte-arrays combinators
-combinators.short-circuit fry kernel macros math math.blas.cblas
-math.complex math.functions math.order multi-methods qualified
-sequences sequences.private generalizations ;
-QUALIFIED: syntax
+combinators.short-circuit fry kernel math math.blas.cblas
+math.complex math.functions math.order sequences.complex
+sequences.complex-components sequences sequences.private
+functors words locals
+specialized-arrays.float specialized-arrays.double
+specialized-arrays.direct.float specialized-arrays.direct.double ;
 IN: math.blas.vectors
 
-TUPLE: blas-vector-base data length inc ;
-TUPLE: float-blas-vector < blas-vector-base ;
-TUPLE: double-blas-vector < blas-vector-base ;
-TUPLE: float-complex-blas-vector < blas-vector-base ;
-TUPLE: double-complex-blas-vector < blas-vector-base ;
+TUPLE: blas-vector-base underlying length inc ;
 
-INSTANCE: float-blas-vector sequence
-INSTANCE: double-blas-vector sequence
-INSTANCE: float-complex-blas-vector sequence
-INSTANCE: double-complex-blas-vector sequence
+INSTANCE: blas-vector-base virtual-sequence
 
-C: <float-blas-vector> float-blas-vector
-C: <double-blas-vector> double-blas-vector
-C: <float-complex-blas-vector> float-complex-blas-vector
-C: <double-complex-blas-vector> double-complex-blas-vector
+GENERIC: element-type ( v -- type )
 
 GENERIC: n*V+V! ( alpha x y -- y=alpha*x+y )
 GENERIC: n*V!   ( alpha x -- x=alpha*x )
-
 GENERIC: V. ( x y -- x.y )
 GENERIC: V.conj ( x y -- xconj.y )
 GENERIC: Vnorm ( x -- norm )
 GENERIC: Vasum ( x -- sum )
 GENERIC: Vswap ( x y -- x=y y=x )
-
 GENERIC: Viamax ( x -- max-i )
 
-GENERIC: element-type ( v -- type )
-
-METHOD: element-type { float-blas-vector }
-    drop "float" ;
-METHOD: element-type { double-blas-vector }
-    drop "double" ;
-METHOD: element-type { float-complex-blas-vector }
-    drop "CBLAS_C" ;
-METHOD: element-type { double-complex-blas-vector }
-    drop "CBLAS_Z" ;
-
 <PRIVATE
 
 GENERIC: (blas-vector-like) ( data length inc exemplar -- vector )
 
-METHOD: (blas-vector-like) { object object object float-blas-vector }
-    drop <float-blas-vector> ;
-METHOD: (blas-vector-like) { object object object double-blas-vector }
-    drop <double-blas-vector> ;
-METHOD: (blas-vector-like) { object object object float-complex-blas-vector }
-    drop <float-complex-blas-vector> ;
-METHOD: (blas-vector-like) { object object object double-complex-blas-vector }
-    drop <double-complex-blas-vector> ;
-
-: (prepare-copy) ( v element-size -- length v-data v-inc v-dest-data v-dest-inc )
-    [ [ length>> ] [ data>> ] [ inc>> ] tri ] dip
-    4 npick * <byte-array>
-    1 ;
-
-MACRO: (do-copy) ( copy make-vector -- )
-    '[ over 6 npick _ 2dip 1 @ ] ;
-
-: (prepare-swap) ( v1 v2 -- length v1-data v1-inc v2-data v2-inc v1 v2 )
-    [
-        [ [ length>> ] bi@ min ]
-        [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi
-    ] 2keep ;
-
-: (prepare-axpy) ( n v1 v2 -- length n v1-data v1-inc v2-data v2-inc v2 )
-    [
-        [ [ length>> ] bi@ min swap ]
-        [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi
-    ] keep ;
-
-: (prepare-scal) ( n v -- length n v-data v-inc v )
-    [ [ length>> swap ] [ data>> ] [ inc>> ] tri ] keep ;
+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
+: datas-and-incs ( v1 v2 -- v1-data v1-inc v2-data v2-inc )
+    [ data-and-inc ] bi@ ; inline
+
+:: (prepare-copy)
+    ( v element-size -- length v-data v-inc v-dest-data v-dest-inc
+                        copy-data copy-length copy-inc )
+    v [ length>> ] [ data-and-inc ] bi
+    v length>> element-size * <byte-array>
+    1 
+    over v length>> 1 ;
+
+: (prepare-swap)
+    ( v1 v2 -- length v1-data v1-inc v2-data v2-inc
+               v1 v2 )
+    [ shorter-length ] [ datas-and-incs ] [ ] 2tri ;
+
+:: (prepare-axpy)
+    ( n v1 v2 -- length n v1-data v1-inc v2-data v2-inc
+                 v2 )
+    v1 v2 shorter-length
+    n
+    v1 v2 datas-and-incs
+    v2 ;
+
+:: (prepare-scal)
+    ( n v -- length n v-data v-inc
+             v )
+    v length>>
+    n
+    v data-and-inc
+    v ;
 
 : (prepare-dot) ( v1 v2 -- length v1-data v1-inc v2-data v2-inc )
-    [ [ length>> ] bi@ min ]
-    [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi ;
-
-: (prepare-nrm2) ( v -- length v1-data v1-inc )
-    [ length>> ] [ data>> ] [ inc>> ] tri ;
-
-: (flatten-complex-sequence) ( seq -- seq' )
-    [ [ real-part ] [ imaginary-part ] bi 2array ] map concat ;
-
-: (>c-complex) ( complex -- alien )
-    [ real-part ] [ imaginary-part ] bi 2array >c-float-array ;
-: (>z-complex) ( complex -- alien )
-    [ real-part ] [ imaginary-part ] bi 2array >c-double-array ;
-
-: (c-complex>) ( alien -- complex )
-    2 c-float-array> first2 rect> ;
-: (z-complex>) ( alien -- complex )
-    2 c-double-array> first2 rect> ;
-
-: (prepare-nth) ( n v -- n*inc v-data )
-    [ inc>> ] [ data>> ] bi [ * ] dip ;
-
-MACRO: (complex-nth) ( nth-quot -- )
-    '[ 
-        [ 2 * dup 1+ ] dip
-        _ curry bi@ rect>
-    ] ;
-
-: (c-complex-nth) ( n alien -- complex )
-    [ float-nth ] (complex-nth) ;
-: (z-complex-nth) ( n alien -- complex )
-    [ double-nth ] (complex-nth) ;
-
-MACRO: (set-complex-nth) ( set-nth-quot -- )
-    '[
-        [
-            [ [ real-part ] [ imaginary-part ] bi ]
-            [ 2 * dup 1+ ] bi*
-            swapd
-        ] dip
-        _ curry 2bi@ 
-    ] ;
-
-: (set-c-complex-nth) ( complex n alien -- )
-    [ set-float-nth ] (set-complex-nth) ;
-: (set-z-complex-nth) ( complex n alien -- )
-    [ set-double-nth ] (set-complex-nth) ;
+    [ shorter-length ] [ datas-and-incs ] 2bi ;
+
+: (prepare-nrm2) ( v -- length data inc )
+    [ length>> ] [ data-and-inc ] bi ;
 
 PRIVATE>
 
+: n*V+V ( alpha x y -- alpha*x+y ) clone n*V+V! ; inline
+: n*V ( alpha x -- alpha*x ) clone n*V! ; inline
+
+: V+ ( x y -- x+y )
+    1.0 -rot n*V+V ; inline
+: V- ( x y -- x-y )
+    -1.0 spin n*V+V ; inline
+
+: Vneg ( x -- -x )
+    -1.0 swap n*V ; inline
+
+: V*n ( x alpha -- x*alpha )
+    swap n*V ; inline
+: V/n ( x alpha -- x/alpha )
+    recip swap n*V ; inline
+
+: Vamax ( x -- max )
+    [ Viamax ] keep nth ; inline
+
+:: Vsub ( v start length -- sub )
+    v inc>> start * v element-type heap-size *
+    v underlying>> <displaced-alien>
+    length v inc>> v (blas-vector-like) ;
+
 : <zero-vector> ( exemplar -- zero )
     [ element-type <c-object> ]
     [ length>> 0 ]
@@ -140,162 +106,167 @@ PRIVATE>
     [ 1 swap ] 2bi
     (blas-vector-like) ;
 
-syntax:M: blas-vector-base length
-    length>> ;
-
-syntax:M: float-blas-vector nth-unsafe
-    (prepare-nth) float-nth ;
-syntax:M: float-blas-vector set-nth-unsafe
-    (prepare-nth) set-float-nth ;
-
-syntax:M: double-blas-vector nth-unsafe
-    (prepare-nth) double-nth ;
-syntax:M: double-blas-vector set-nth-unsafe
-    (prepare-nth) set-double-nth ;
-
-syntax:M: float-complex-blas-vector nth-unsafe
-    (prepare-nth) (c-complex-nth) ;
-syntax:M: float-complex-blas-vector set-nth-unsafe
-    (prepare-nth) (set-c-complex-nth) ;
-
-syntax:M: double-complex-blas-vector nth-unsafe
-    (prepare-nth) (z-complex-nth) ;
-syntax:M: double-complex-blas-vector set-nth-unsafe
-    (prepare-nth) (set-z-complex-nth) ;
-
-syntax:M: blas-vector-base equal?
+M: blas-vector-base equal?
     {
         [ [ length ] bi@ = ]
         [ [ = ] 2all? ]
     } 2&& ;
 
-: >float-blas-vector ( seq -- v )
-    [ >c-float-array ] [ length ] bi 1 <float-blas-vector> ;
-: >double-blas-vector ( seq -- v )
-    [ >c-double-array ] [ length ] bi 1 <double-blas-vector> ;
-: >float-complex-blas-vector ( seq -- v )
-    [ (flatten-complex-sequence) >c-float-array ] [ length ] bi
-    1 <float-complex-blas-vector> ;
-: >double-complex-blas-vector ( seq -- v )
-    [ (flatten-complex-sequence) >c-double-array ] [ length ] bi
-    1 <double-complex-blas-vector> ;
-
-syntax:M: float-blas-vector clone
-    "float" heap-size (prepare-copy)
-    [ cblas_scopy ] [ <float-blas-vector> ] (do-copy) ;
-syntax:M: double-blas-vector clone
-    "double" heap-size (prepare-copy)
-    [ cblas_dcopy ] [ <double-blas-vector> ] (do-copy) ;
-syntax:M: float-complex-blas-vector clone
-    "CBLAS_C" heap-size (prepare-copy)
-    [ cblas_ccopy ] [ <float-complex-blas-vector> ] (do-copy) ;
-syntax:M: double-complex-blas-vector clone
-    "CBLAS_Z" heap-size (prepare-copy)
-    [ cblas_zcopy ] [ <double-complex-blas-vector> ] (do-copy) ;
-
-METHOD: Vswap { float-blas-vector float-blas-vector }
-    (prepare-swap) [ cblas_sswap ] 2dip ;
-METHOD: Vswap { double-blas-vector double-blas-vector }
-    (prepare-swap) [ cblas_dswap ] 2dip ;
-METHOD: Vswap { float-complex-blas-vector float-complex-blas-vector }
-    (prepare-swap) [ cblas_cswap ] 2dip ;
-METHOD: Vswap { double-complex-blas-vector double-complex-blas-vector }
-    (prepare-swap) [ cblas_zswap ] 2dip ;
-
-METHOD: n*V+V! { real float-blas-vector float-blas-vector }
-    (prepare-axpy) [ cblas_saxpy ] dip ;
-METHOD: n*V+V! { real double-blas-vector double-blas-vector }
-    (prepare-axpy) [ cblas_daxpy ] dip ;
-METHOD: n*V+V! { number float-complex-blas-vector float-complex-blas-vector }
-    [ (>c-complex) ] 2dip
-    (prepare-axpy) [ cblas_caxpy ] dip ;
-METHOD: n*V+V! { number double-complex-blas-vector double-complex-blas-vector }
-    [ (>z-complex) ] 2dip
-    (prepare-axpy) [ cblas_zaxpy ] dip ;
-
-METHOD: n*V! { real float-blas-vector }
-    (prepare-scal) [ cblas_sscal ] dip ;
-METHOD: n*V! { real double-blas-vector }
-    (prepare-scal) [ cblas_dscal ] dip ;
-METHOD: n*V! { number float-complex-blas-vector }
-    [ (>c-complex) ] dip
-    (prepare-scal) [ cblas_cscal ] dip ;
-METHOD: n*V! { number double-complex-blas-vector }
-    [ (>z-complex) ] dip
-    (prepare-scal) [ cblas_zscal ] dip ;
-
-: n*V+V ( alpha x y -- alpha*x+y ) clone n*V+V! ; inline
-: n*V ( alpha x -- alpha*x ) clone n*V! ; inline
+M: blas-vector-base length
+    length>> ;
+M: blas-vector-base virtual-seq
+    (blas-direct-array) ;
+M: blas-vector-base virtual@
+    [ inc>> * ] [ nip (blas-direct-array) ] 2bi ;
 
-: V+ ( x y -- x+y )
-    1.0 -rot n*V+V ; inline
-: V- ( x y -- x-y )
-    -1.0 spin n*V+V ; inline
+: float>arg ( f -- f ) ; inline
+: double>arg ( f -- f ) ; inline
+: arg>float ( f -- f ) ; inline
+: arg>double ( f -- f ) ; inline
 
-: Vneg ( x -- -x )
-    -1.0 swap n*V ; inline
+<<
 
-: V*n ( x alpha -- x*alpha )
-    swap n*V ; inline
-: V/n ( x alpha -- x/alpha )
-    recip swap n*V ; inline
+FUNCTOR: (define-blas-vector) ( TYPE T -- )
 
-METHOD: V. { float-blas-vector float-blas-vector }
-    (prepare-dot) cblas_sdot ;
-METHOD: V. { double-blas-vector double-blas-vector }
-    (prepare-dot) cblas_ddot ;
-METHOD: V. { float-complex-blas-vector float-complex-blas-vector }
-    (prepare-dot)
-    "CBLAS_C" <c-object> [ cblas_cdotu_sub ] keep (c-complex>) ;
-METHOD: V. { double-complex-blas-vector double-complex-blas-vector }
-    (prepare-dot)
-    "CBLAS_Z" <c-object> [ cblas_zdotu_sub ] keep (z-complex>) ;
-
-METHOD: V.conj { float-blas-vector float-blas-vector }
-    (prepare-dot) cblas_sdot ;
-METHOD: V.conj { double-blas-vector double-blas-vector }
-    (prepare-dot) cblas_ddot ;
-METHOD: V.conj { float-complex-blas-vector float-complex-blas-vector }
-    (prepare-dot)
-    "CBLAS_C" <c-object> [ cblas_cdotc_sub ] keep (c-complex>) ;
-METHOD: V.conj { double-complex-blas-vector double-complex-blas-vector }
-    (prepare-dot)
-    "CBLAS_Z" <c-object> [ cblas_zdotc_sub ] keep (z-complex>) ;
-
-METHOD: Vnorm { float-blas-vector }
-    (prepare-nrm2) cblas_snrm2 ;
-METHOD: Vnorm { double-blas-vector }
-    (prepare-nrm2) cblas_dnrm2 ;
-METHOD: Vnorm { float-complex-blas-vector }
-    (prepare-nrm2) cblas_scnrm2 ;
-METHOD: Vnorm { double-complex-blas-vector }
-    (prepare-nrm2) cblas_dznrm2 ;
-
-METHOD: Vasum { float-blas-vector }
-    (prepare-nrm2) cblas_sasum ;
-METHOD: Vasum { double-blas-vector }
-    (prepare-nrm2) cblas_dasum ;
-METHOD: Vasum { float-complex-blas-vector }
-    (prepare-nrm2) cblas_scasum ;
-METHOD: Vasum { double-complex-blas-vector }
-    (prepare-nrm2) cblas_dzasum ;
-
-METHOD: Viamax { float-blas-vector }
-    (prepare-nrm2) cblas_isamax ;
-METHOD: Viamax { double-blas-vector }
-    (prepare-nrm2) cblas_idamax ;
-METHOD: Viamax { float-complex-blas-vector }
-    (prepare-nrm2) cblas_icamax ;
-METHOD: Viamax { double-complex-blas-vector }
-    (prepare-nrm2) cblas_izamax ;
+<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
 
-: Vamax ( x -- max )
-    [ Viamax ] keep nth ; inline
+VECTOR         DEFINES ${TYPE}-blas-vector
+<VECTOR>       DEFINES <${TYPE}-blas-vector>
+>VECTOR        DEFINES >${TYPE}-blas-vector
+
+WHERE
+
+TUPLE: VECTOR < blas-vector-base ;
+: <VECTOR> ( underlying length inc -- vector ) VECTOR boa ; inline
+
+: >VECTOR ( seq -- v )
+    [ >ARRAY execute underlying>> ] [ length ] bi 1 <VECTOR> execute ;
+
+M: VECTOR clone
+    TYPE heap-size (prepare-copy)
+    [ XCOPY execute ] 3dip <VECTOR> execute ;
+
+M: VECTOR element-type
+    drop TYPE ;
+M: VECTOR Vswap
+    (prepare-swap) [ XSWAP execute ] 2dip ;
+M: VECTOR Viamax
+    (prepare-nrm2) IXAMAX execute ;
+
+M: VECTOR (blas-vector-like)
+    drop <VECTOR> execute ;
+
+M: VECTOR (blas-direct-array)
+    [ underlying>> ]
+    [ [ length>> ] [ inc>> ] bi * ] bi
+    <DIRECT-ARRAY> execute ;
+
+;FUNCTOR
+
+
+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
+
+WHERE
+
+M: VECTOR V.
+    (prepare-dot) XDOT execute ;
+M: VECTOR V.conj
+    (prepare-dot) XDOT execute ;
+M: VECTOR Vnorm
+    (prepare-nrm2) XNRM2 execute ;
+M: VECTOR Vasum
+    (prepare-nrm2) XASUM execute ;
+M: VECTOR n*V+V!
+    (prepare-axpy) [ XAXPY execute ] dip ;
+M: VECTOR n*V!
+    (prepare-scal) [ XSCAL execute ] 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> execute <complex-sequence> ;
+: >COMPLEX-ARRAY ( sequence -- sequence )
+    <complex-components> >ARRAY execute ;
+: COMPLEX>ARG ( complex -- alien )
+    >rect 2array >ARRAY execute underlying>> ;
+: ARG>COMPLEX ( alien -- complex )
+    2 <DIRECT-ARRAY> execute first2 rect> ;
+
+;FUNCTOR
+
+
+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}
+
+WHERE
+
+M: VECTOR V.
+    (prepare-dot) TYPE <c-object>
+    [ XDOTU_SUB execute ] keep
+    ARG>TYPE execute ;
+M: VECTOR V.conj
+    (prepare-dot) TYPE <c-object>
+    [ XDOTC_SUB execute ] keep
+    ARG>TYPE execute ;
+M: VECTOR Vnorm
+    (prepare-nrm2) XXNRM2 execute ;
+M: VECTOR Vasum
+    (prepare-nrm2) XXASUM execute ;
+M: VECTOR n*V+V!
+    [ TYPE>ARG execute ] 2dip
+    (prepare-axpy) [ XAXPY execute ] dip ;
+M: VECTOR n*V!
+    [ TYPE>ARG execute ] dip
+    (prepare-scal) [ XSCAL execute ] dip ;
+
+;FUNCTOR
+
+
+: 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
+
+>>
 
-: Vsub ( v start length -- sub )
-    rot [
-        [
-            nip [ inc>> ] [ element-type heap-size ] [ data>> ] tri
-            [ * * ] dip <displaced-alien>
-        ] [ swap 2nip ] [ 2nip inc>> ] 3tri
-    ] keep (blas-vector-like) ;
diff --git a/extra/math/combinatorics/authors.txt b/extra/math/combinatorics/authors.txt
deleted file mode 100644 (file)
index 708cc3e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Slava Pestov
-Doug Coleman
-Aaron Schaefer
diff --git a/extra/math/combinatorics/combinatorics-docs.factor b/extra/math/combinatorics/combinatorics-docs.factor
deleted file mode 100644 (file)
index 514c808..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-USING: help.markup help.syntax kernel math math.order sequences ;
-IN: math.combinatorics
-
-HELP: factorial
-{ $values { "n" "a non-negative integer" } { "n!" integer } }
-{ $description "Outputs the product of all positive integers less than or equal to " { $snippet "n" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "4 factorial ." "24" } } ;
-
-HELP: nPk
-{ $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nPk" integer } }
-{ $description "Outputs the total number of unique permutations of size " { $snippet "k" } " (order does matter) that can be taken from a set of size " { $snippet "n" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nPk ." "5040" } } ;
-
-HELP: nCk
-{ $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nCk" integer } }
-{ $description "Outputs the total number of unique combinations of size " { $snippet "k" } " (order does not matter) that can be taken from a set of size " { $snippet "n" } ". Commonly written as \"n choose k\"." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nCk ." "210" } } ;
-
-HELP: permutation
-{ $values { "n" "a non-negative integer" } { "seq" sequence } { "seq" sequence } }
-{ $description "Outputs the " { $snippet "nth" } " lexicographical permutation of " { $snippet "seq" } "." }
-{ $notes "Permutations are 0-based and a bounds error will be thrown if " { $snippet "n" } " is larger than " { $snippet "seq length factorial 1-" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "1 3 permutation ." "{ 0 2 1 }" } { $example "USING: math.combinatorics prettyprint ;" "5 { \"apple\" \"banana\" \"orange\" } permutation ." "{ \"orange\" \"banana\" \"apple\" }" } } ;
-
-HELP: all-permutations
-{ $values { "seq" sequence } { "seq" sequence } }
-{ $description "Outputs a sequence containing all permutations of " { $snippet "seq" } " in lexicographical order." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "3 all-permutations ." "{ { 0 1 2 } { 0 2 1 } { 1 0 2 } { 1 2 0 } { 2 0 1 } { 2 1 0 } }" } } ;
-
-HELP: inverse-permutation
-{ $values { "seq" sequence } { "permutation" sequence } }
-{ $description "Outputs a sequence of indices representing the lexicographical permutation of " { $snippet "seq" } "." }
-{ $notes "All items in " { $snippet "seq" } " must be comparable by " { $link <=> } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "\"dcba\" inverse-permutation ." "{ 3 2 1 0 }" } { $example "USING: math.combinatorics prettyprint ;" "{ 12 56 34 78 } inverse-permutation ." "{ 0 2 1 3 }" } } ;
-
-
-IN: math.combinatorics.private
-
-HELP: factoradic
-{ $values { "n" integer } { "factoradic" sequence } }
-{ $description "Converts a positive integer " { $snippet "n" } " to factoradic form.  The factoradic of an integer is its representation based on a mixed radix numerical system that corresponds to the values of " { $snippet "n" } " factorial." }
-{ $examples { $example "USING: math.combinatorics.private  prettyprint ;" "859 factoradic ." "{ 1 1 0 3 0 1 0 }" } } ;
-
-HELP: >permutation
-{ $values { "factoradic" sequence } { "permutation" sequence } }
-{ $description "Converts an integer represented in factoradic form into its corresponding unique permutation (0-based)." }
-{ $notes "For clarification, the following two statements are equivalent:" { $code "10 factoradic >permutation" "{ 1 2 0 0 } >permutation" } }
-{ $examples { $example "USING: math.combinatorics.private prettyprint ;" "{ 0 0 0 0 } >permutation ." "{ 0 1 2 3 }" } } ;
-
diff --git a/extra/math/combinatorics/combinatorics-tests.factor b/extra/math/combinatorics/combinatorics-tests.factor
deleted file mode 100644 (file)
index 5ef435a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-USING: math.combinatorics math.combinatorics.private tools.test ;
-IN: math.combinatorics.tests
-
-[ { } ] [ 0 factoradic ] unit-test
-[ { 1 0 } ] [ 1 factoradic ] unit-test
-[ { 1 1 0 3 0 1 0 } ] [ 859 factoradic ] unit-test
-
-[ { 0 1 2 3 } ] [ { 0 0 0 0 } >permutation ] unit-test
-[ { 0 1 3 2 } ] [ { 0 0 1 0 } >permutation ] unit-test
-[ { 1 2 0 6 3 5 4 } ] [ { 1 1 0 3 0 1 0 } >permutation ] unit-test
-
-[ { 0 1 2 3 } ] [ 0 4 permutation-indices ] unit-test
-[ { 0 1 3 2 } ] [ 1 4 permutation-indices ] unit-test
-[ { 1 2 0 6 3 5 4 } ] [ 859 7 permutation-indices ] unit-test
-
-[ 1 ] [ 0 factorial ] unit-test
-[ 1 ] [ 1 factorial ] unit-test
-[ 3628800 ] [ 10 factorial ] unit-test
-
-[ 1 ] [ 3 0 nPk ] unit-test
-[ 6 ] [ 3 2 nPk ] unit-test
-[ 6 ] [ 3 3 nPk ] unit-test
-[ 0 ] [ 3 4 nPk ] unit-test
-[ 311875200 ] [ 52 5 nPk ] unit-test
-[ 672151459757865654763838640470031391460745878674027315200000000000 ] [ 52 47 nPk ] unit-test
-
-[ 1 ] [ 3 0 nCk ] unit-test
-[ 3 ] [ 3 2 nCk ] unit-test
-[ 1 ] [ 3 3 nCk ] unit-test
-[ 0 ] [ 3 4 nCk ] unit-test
-[ 2598960 ] [ 52 5 nCk ] unit-test
-[ 2598960 ] [ 52 47 nCk ] unit-test
-
-[ { "a" "b" "c" "d" } ] [ 0 { "a" "b" "c" "d" } permutation ] unit-test
-[ { "d" "c" "b" "a" } ] [ 23 { "a" "b" "c" "d" } permutation ] unit-test
-[ { "d" "a" "b" "c" } ] [ 18 { "a" "b" "c" "d" } permutation ] unit-test
-
-[ { { "a" "b" "c" } { "a" "c" "b" }
-    { "b" "a" "c" } { "b" "c" "a" }
-    { "c" "a" "b" } { "c" "b" "a" } } ] [ { "a" "b" "c" } all-permutations ] unit-test
-
-[ { 0 1 2 } ] [ { "a" "b" "c" } inverse-permutation ] unit-test
-[ { 2 1 0 } ] [ { "c" "b" "a" } inverse-permutation ] unit-test
-[ { 3 0 2 1 } ] [ { 12 45 34 2 } inverse-permutation ] unit-test
-
diff --git a/extra/math/combinatorics/combinatorics.factor b/extra/math/combinatorics/combinatorics.factor
deleted file mode 100644 (file)
index 1bc692c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
-! See http://factorcode.org/license.txt for BSD license.
-USING: assocs kernel math math.order math.ranges mirrors
-namespaces sequences sorting fry ;
-IN: math.combinatorics
-
-<PRIVATE
-
-: possible? ( n m -- ? )
-    0 rot between? ; inline
-
-: twiddle ( n k -- n k )
-    2dup - dupd > [ dupd - ] when ; inline
-
-! See this article for explanation of the factoradic-based permutation methodology:
-! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
-
-: factoradic ( n -- factoradic )
-    0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
-
-: (>permutation) ( seq n -- seq )
-    [ '[ _ dupd >= [ 1+ ] when ] map ] keep prefix ;
-
-: >permutation ( factoradic -- permutation )
-    reverse 1 cut [ (>permutation) ] each ;
-
-: permutation-indices ( n seq -- permutation )
-    length [ factoradic ] dip 0 pad-left >permutation ;
-
-PRIVATE>
-
-: factorial ( n -- n! )
-    1 [ 1+ * ] reduce ;
-
-: nPk ( n k -- nPk )
-    2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
-
-: nCk ( n k -- nCk )
-    twiddle [ nPk ] keep factorial / ;
-
-: permutation ( n seq -- seq )
-    [ permutation-indices ] keep nths ;
-
-: all-permutations ( seq -- seq )
-    [ length factorial ] keep '[ _ permutation ] map ;
-
-: each-permutation ( seq quot -- )
-    [ [ length factorial ] keep ] dip
-    '[ _ permutation @ ] each ; inline
-
-: reduce-permutations ( seq initial quot -- result )
-    swapd each-permutation ; inline
-
-: inverse-permutation ( seq -- permutation )
-    <enum> >alist sort-values keys ;
diff --git a/extra/math/combinatorics/summary.txt b/extra/math/combinatorics/summary.txt
deleted file mode 100644 (file)
index ecd43de..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Permutations and combinations
diff --git a/extra/math/derivatives/authors.txt b/extra/math/derivatives/authors.txt
deleted file mode 100644 (file)
index 3be8a6d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Reginald Ford
-Eduardo Cavazos
\ No newline at end of file
diff --git a/extra/math/derivatives/derivatives-docs.factor b/extra/math/derivatives/derivatives-docs.factor
deleted file mode 100644 (file)
index 1630b2f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-USING: help.markup help.syntax math math.functions ;
-IN: math.derivatives
-
-HELP: derivative ( x function -- m )
-{ $values { "x" "a position on the function" } { "function" "a differentiable function" } { "m" number } }
-{ $description
-    "Approximates the slope of the tangent line by using Ridders' "
-    "method of computing derivatives, from the chapter \"Accurate computation "
-    "of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, Vol. 4, pp. 75-76 ."
-}
-{ $examples
-    { $example
-        "USING: math math.derivatives prettyprint ;"
-        "4 [ sq ] derivative >integer ."
-        "8"
-    }
-    { $notes
-        "For applied scientists, you may play with the settings "
-        "in the source file to achieve arbitrary accuracy. "
-    }
-} ;
-
-HELP: (derivative)
-{ $values
-    { "x" "a position on the function" }
-    { "func" "a differentiable function" }
-    {
-        "h" "distance between the points of the first secant line used for "
-        "approximation of the tangent. This distance will be divided "
-        "constantly, by " { $link con } ". See " { $link init-hh }
-        " for the code which enforces this. H should be .001 to .5 -- too "
-        "small can cause bad convergence. Also, h should be small enough "
-        "to give the correct sgn(f'(x)). In other words, if you're expecting "
-        "a positive derivative, make h small enough to give the same "
-        "when plugged into the academic limit definition of a derivative. "
-        "See " { $link update-hh } " for the code which performs this task."
-    }
-    {
-        "err" "maximum tolerance of increase in error. For example, if this "
-        "is set to 2.0, the program will terminate with its nearest answer "
-        "when the error multiplies by 2. See " { $link check-safe } " for "
-        "the enforcing code."
-    }
-    {   "ans" number }
-    {   "error" number }
-}
-{ $description
-    "Approximates the slope of the tangent line by using Ridders' "
-    "method of computing derivatives, from the chapter \"Accurate computation "
-    "of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, "
-    "Vol. 4, pp. 75-76 ."
-}
-{ $examples
-    { $example
-        "USING: math math.derivatives prettyprint ;"
-        "4 [ sq ] derivative >integer ."
-        "8"
-    }
-    { $notes
-        "For applied scientists, you may play with the settings "
-        "in the source file to achieve arbitrary accuracy. "
-    }
-} ;
-
-HELP: derivative-func
-{ $values { "func" "a differentiable function" } { "der" "the derivative" } }
-{ $description
-    "Provides the derivative of the function. The implementation simply "
-    "attaches the " { $link derivative } " word to the end of the function."
-}
-{ $examples
-    { $example
-        "USING: kernel math.derivatives math.functions math.trig prettyprint ;"
-        "60 deg>rad [ sin ] derivative-func call 0.5 .001 ~ ."
-        "t"
-    }
-    { $notes
-        "Without a heavy algebraic system, derivatives must be "
-        "approximated. With the current settings, there is a fair trade of "
-        "speed and accuracy; the first 12 digits "
-        "will always be correct with " { $link sin } " and " { $link cos }
-        ". The following code performs a minumum and maximum error test."
-        { $code
-            "USING: kernel math math.functions math.trig sequences sequences.lib ;"
-            "360"
-            "["
-            "           deg>rad"
-            "            [ [ sin ] derivative-func call ]"
-            "           ! Note: the derivative of sin is cos"
-            "            [ cos ]"
-            "       bi - abs"
-            "] map minmax"
-        }
-    }
-} ;
-
-ARTICLE: "derivatives" "The Derivative Toolkit"
-"A toolkit for computing the derivative of functions."
-{ $subsection derivative }
-{ $subsection derivative-func }
-{ $subsection (derivative) } ;
-
-ABOUT: "derivatives"
diff --git a/extra/math/derivatives/derivatives-tests.factor b/extra/math/derivatives/derivatives-tests.factor
deleted file mode 100644 (file)
index cfbc1fa..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: math math.derivatives tools.test ;
-IN: math.derivatives.test
-
-[ 8 ] [ 4 [ sq ] derivative >integer ] unit-test
-
diff --git a/extra/math/derivatives/derivatives.factor b/extra/math/derivatives/derivatives.factor
deleted file mode 100644 (file)
index 7922a48..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-! Copyright (c) 2008 Reginald Keith Ford II, Eduardo Cavazos.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel continuations combinators sequences math math.order math.ranges
-    accessors float-arrays ;
-IN: math.derivatives
-
-TUPLE: state x func h err i j errt fac hh ans a done ;
-
-: largest-float ( -- x ) HEX: 7fefffffffffffff bits>double ; foldable
-: ntab ( -- val ) 8 ; inline
-: con ( -- val ) 1.6 ; inline
-: con2 ( -- val ) con con * ; inline
-: big ( -- val ) largest-float ; inline
-: safe ( -- val ) 2.0 ; inline
-
-! Yes, this was ported from C code.
-: a[i][i]     ( state -- elt ) [ i>>     ] [ i>>     ] [ a>> ] tri nth nth ;
-: a[j][i]     ( state -- elt ) [ i>>     ] [ j>>     ] [ a>> ] tri nth nth ;
-: a[j-1][i]   ( state -- elt ) [ i>>     ] [ j>> 1 - ] [ a>> ] tri nth nth ;
-: a[j-1][i-1] ( state -- elt ) [ i>> 1 - ] [ j>> 1 - ] [ a>> ] tri nth nth ;
-: a[i-1][i-1] ( state -- elt ) [ i>> 1 - ] [ i>> 1 - ] [ a>> ] tri nth nth ;
-
-: check-h ( state -- state )
-    dup h>> 0 = [ "h must be nonzero in dfridr" throw ] when ;
-
-: init-a     ( state -- state ) ntab [ ntab <float-array> ] replicate >>a ;
-: init-hh    ( state -- state ) dup h>> >>hh ;
-: init-err   ( state -- state ) big >>err ;
-: update-hh  ( state -- state ) dup hh>> con / >>hh ;
-: reset-fac  ( state -- state ) con2 >>fac ;
-: update-fac ( state -- state ) dup fac>> con2 * >>fac ;
-
-! If error is decreased, save the improved answer
-: error-decreased? ( state -- state ? ) [ ] [ errt>> ] [ err>> ] tri <= ;
-
-: save-improved-answer ( state -- state )
-    dup err>>   >>errt
-    dup a[j][i] >>ans ;
-
-! If higher order is worse by a significant factor SAFE, then quit early.
-: check-safe ( state -- state )
-    dup [ [ a[i][i] ] [ a[i-1][i-1] ] bi - abs ]
-    [ err>> safe * ] bi >= [ t >>done ] when ;
-
-: x+hh ( state -- val ) [ x>> ] [ hh>> ] bi + ;
-: x-hh ( state -- val ) [ x>> ] [ hh>> ] bi - ;
-
-: limit-approx ( state -- val )
-    [
-        [ [ x+hh ] [ func>> ] bi call ]
-        [ [ x-hh ] [ func>> ] bi call ] bi -
-    ] [ hh>> 2.0 * ] bi / ;
-
-: a[0][0]! ( state -- state )
-    { [ ] [ limit-approx ] [ drop 0 ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
-
-: a[0][i]! ( state -- state )
-    { [ ] [ limit-approx ] [ i>> ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
-
-: a[j-1][i]*fac ( state -- val ) [ a[j-1][i] ] [ fac>> ] bi * ;
-
-: new-a[j][i] ( state -- val )
-    [ [ a[j-1][i]*fac ] [ a[j-1][i-1] ] bi - ]
-    [ fac>> 1.0 - ] bi / ;
-
-: a[j][i]! ( state -- state )
-    { [ ] [ new-a[j][i] ] [ i>> ] [ j>> ] [ a>> ] } cleave nth set-nth ;
-
-: update-errt ( state -- state )
-    dup [ [ a[j][i] ] [ a[j-1][i] ] bi - abs ]
-    [ [ a[j][i] ] [ a[j-1][i-1] ] bi - abs ] bi max >>errt ;
-
-: not-done? ( state -- state ? ) dup done>> not ;
-
-: derive ( state -- state )
-    init-a
-    check-h
-    init-hh
-    a[0][0]!
-    init-err
-    1 ntab [a,b) [
-        >>i not-done? [
-            update-hh
-            a[0][i]!
-            reset-fac
-            1 over i>> [a,b] [
-                >>j
-                a[j][i]!
-                update-fac
-                update-errt
-                error-decreased? [ save-improved-answer ] when
-            ] each check-safe
-        ] when
-   ] each ;
-
-: derivative-state ( x func h err -- state )
-    state new
-    swap >>err
-    swap >>h
-    swap >>func
-    swap >>x ;
-
-! For scientists:
-! h should be .001 to .5 -- too small can cause bad convergence,
-! h should be small enough to give the correct sgn(f'(x))
-! err is the max tolerance of gain in error for a single iteration-
-: (derivative) ( x func h err -- ans error )
-    derivative-state derive [ ans>> ] [ errt>> ] bi ;
-
-: derivative ( x func -- m ) 0.01 2.0 (derivative) drop ;
-: derivative-func ( func -- der ) [ derivative ] curry ;
index 2a60d30d02777b27a7179e933dd472e30655f6fc..9e5b5c67aa91bbb9c9b0ea9c7872f4588bfc4838 100644 (file)
@@ -1,4 +1,15 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test math.floating-point ;
+USING: tools.test math.floating-point math.constants kernel
+math.constants fry sequences kernel math ;
 IN: math.floating-point.tests
+
+[ t ] [ pi >double< >double pi = ] unit-test
+[ t ] [ -1.0 >double< >double -1.0 = ] unit-test
+
+[ t ] [ 1/0. infinity? ] unit-test
+[ t ] [ -1/0. infinity? ] unit-test
+[ f ] [ 0/0. infinity? ] unit-test
+[ f ] [ 10. infinity? ] unit-test
+[ f ] [ -10. infinity? ] unit-test
+[ f ] [ 0. infinity? ] unit-test
index 3792d6ba9b3e95f53a9f0eca3a6e077e6622c11d..522f149bc1c7dbfd92fd814a6ed3091cc3f7fc83 100644 (file)
@@ -1,20 +1,20 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math sequences prettyprint math.parser io
-math.functions ;
+math.functions math.bitwise combinators.short-circuit ;
 IN: math.floating-point
 
 : (double-sign) ( bits -- n ) -63 shift ; inline
 : double-sign ( double -- n ) double>bits (double-sign) ;
 
 : (double-exponent-bits) ( bits -- n )
-    -52 shift 11 2^ 1- bitand ; inline
+    -52 shift 11 on-bits mask ; inline
 
 : double-exponent-bits ( double -- n )
     double>bits (double-exponent-bits) ;
 
 : (double-mantissa-bits) ( double -- n )
-    52 2^ 1- bitand ;
+    52 on-bits mask ;
 
 : double-mantissa-bits ( double -- n )
     double>bits (double-mantissa-bits) ;
@@ -38,3 +38,9 @@ IN: math.floating-point
         11 [ bl ] times print
     ] tri ;
 
+: infinity? ( double -- ? )
+    double>bits
+    {
+        [ (double-exponent-bits) 11 on-bits = ]
+        [ (double-mantissa-bits) 0 = ]
+    } 1&& ;
index ee2516e9a6bf4a74b862df23ec68a6fd60332f4b..6f87109ba08a55c96ccb800e18fe915362f8c539 100644 (file)
@@ -102,3 +102,5 @@ USING: math.matrices math.vectors tools.test math ;
 [ { 0 0 -1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
 [ { 1 0 0 } ] [ { 0 1 0 } { 0 0 1 } cross ] unit-test
 [ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
+
+[ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
diff --git a/extra/math/newtons-method/authors.txt b/extra/math/newtons-method/authors.txt
deleted file mode 100644 (file)
index 137b160..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Reginald Ford
\ No newline at end of file
diff --git a/extra/math/newtons-method/newtons-method.factor b/extra/math/newtons-method/newtons-method.factor
deleted file mode 100644 (file)
index 4b53b12..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-! Copyright (c) 2008 Reginald Keith Ford II.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.derivatives ;
-IN: math.newtons-method
-
-! Newton's method of approximating roots
-
-<PRIVATE
-
-: newton-step ( x function -- x2 )
-    dupd [ call ] [ derivative ] 2bi / - ; inline
-
-: newton-precision ( -- n ) 13 ; inline
-
-PRIVATE>
-
-: newtons-method ( guess function -- x )
-    newton-precision [ [ newton-step ] keep ] times drop ;
diff --git a/extra/math/polynomials/authors.txt b/extra/math/polynomials/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/math/polynomials/polynomials-docs.factor b/extra/math/polynomials/polynomials-docs.factor
deleted file mode 100644 (file)
index edffa53..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-USING: help.markup help.syntax math sequences ;
-IN: math.polynomials
-
-ARTICLE: "polynomials" "Polynomials"
-"A polynomial is a vector with the highest powers on the right:"
-{ $code "{ 1 1 0 1 } -> 1 + x + x^3" "{ } -> 0" }
-"Numerous words are defined to help with polynomial arithmetic:"
-{ $subsection p= }
-{ $subsection p+ }
-{ $subsection p- }
-{ $subsection p* }
-{ $subsection p-sq }
-{ $subsection powers }
-{ $subsection n*p }
-{ $subsection p/mod }
-{ $subsection pgcd }
-{ $subsection polyval }
-{ $subsection pdiff }
-{ $subsection pextend-conv }
-{ $subsection ptrim }
-{ $subsection 2ptrim } ;
-
-ABOUT: "polynomials"
-
-HELP: powers
-{ $values { "n" integer } { "x" number } { "seq" sequence } }
-{ $description "Output a sequence having " { $snippet "n" } " elements in the format: " { $snippet "{ 1 x x^2 x^3 ... }" } "." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "4 2 powers ." "{ 1 2 4 8 }" } } ;
-
-HELP: p=
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "?" "a boolean" } }
-{ $description "Tests if two polynomials are equal." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 } { 0 1 0 } p= ." "t" } } ;
-
-HELP: ptrim
-{ $values { "p" "a polynomial" } { "p" "a polynomial" } }
-{ $description "Trims excess zeros from a polynomial." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 0 0 } ptrim ." "{ 0 1 }" } } ;
-
-HELP: 2ptrim
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
-{ $description "Trims excess zeros from two polynomials." }
-{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 0 1 0 0 } { 1 0 0 } 2ptrim [ . ] bi@" "{ 0 1 }\n{ 1 }" } } ;
-
-HELP: p+
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
-{ $description "Adds " { $snippet "p" } " and " { $snippet "q" } " component-wise." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 0 1 } { 0 1 } p+ ." "{ 1 1 1 }" } } ;
-
-HELP: p-
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
-{ $description "Subtracts " { $snippet "q" } " from " { $snippet "p" } " component-wise." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 1 1 } { 0 1 } p- ." "{ 1 0 1 }" } } ;
-
-HELP: n*p
-{ $values { "n" number } { "p" "a polynomial" } { "n*p" "a polynomial" } }
-{ $description "Multiplies each element of " { $snippet "p" } " by " { $snippet "n" } "." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "4 { 3 0 1 } n*p ." "{ 12 0 4 }" } } ;
-
-HELP: pextend-conv
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
-{ $description "Convulution, extending to " { $snippet "p_m + q_n - 1" } "." }
-{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 1 0 1 } { 0 1 } pextend-conv [ . ] bi@" "V{ 1 0 1 0 }\nV{ 0 1 0 0 }" } } ;
-
-HELP: p*
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "r" "a polynomial" } }
-{ $description "Multiplies two polynomials." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 2 3 0 0 0 } { 1 2 0 0 } p* ." "{ 1 4 7 6 0 0 0 0 0 }" } } ;
-
-HELP: p-sq
-{ $values { "p" "a polynomial" } { "p^2" "a polynomial" } }
-{ $description "Squares a polynomial." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 2 0 } p-sq ." "{ 1 4 4 0 0 }" } } ;
-
-HELP: p/mod
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "z" "a polynomial" } { "w" "a polynomial" } }
-{ $description "Computes to quotient " { $snippet "z" } " and remainder " { $snippet "w" } " of dividing " { $snippet "p" } " by " { $snippet "q" } "." }
-{ $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 1 1 1 1 } { 3 1 } p/mod [ . ] bi@" "V{ 7 -2 1 }\nV{ -20 0 0 }" } } ;
-
-HELP: pgcd
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "a" "a polynomial" } { "d" "a polynomial" } }
-{ $description "Computes the greatest common divisor " { $snippet "d" } " of " { $snippet "p" } " and " { $snippet "q" } ", and another value " { $snippet "a" } " satisfying:" { $code "a*q = d mod p" } }
-{ $notes "GCD in the case of polynomials is a monic polynomial of the highest possible degree that divides into both " { $snippet "p" } " and " { $snippet "q" } "." }
-{ $examples
-    { $example "USING: kernel math.polynomials prettyprint ;"
-               "{ 1 1 1 1 } { 1 1 } pgcd [ . ] bi@"
-               "{ 0 0 }\n{ 1 1 }"
-    }
-} ;
-
-HELP: pdiff
-{ $values { "p" "a polynomial" } { "p'" "a polynomial" } }
-{ $description "Finds the derivative of " { $snippet "p" } "." } ;
-
-HELP: polyval
-{ $values { "p" "a polynomial" } { "x" number } { "p[x]" number } }
-{ $description "Evaluate " { $snippet "p" } " with the input " { $snippet "x" } "." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 0 1 } 2 polyval ." "5" } } ;
-
diff --git a/extra/math/polynomials/polynomials-tests.factor b/extra/math/polynomials/polynomials-tests.factor
deleted file mode 100644 (file)
index cd88d19..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-USING: kernel math math.polynomials tools.test ;
-IN: math.polynomials.tests
-
-[ { 0 1 } ] [ { 0 1 0 0 } ptrim ] unit-test
-[ { 1 } ] [ { 1 0 0 } ptrim ] unit-test
-[ { 0 } ] [ { 0 } ptrim ] unit-test
-[ { 3 10 8 } ] [ { 1 2 } { 3 4 } p* ] unit-test
-[ { 3 10 8 } ] [ { 3 4 } { 1 2 } p* ] unit-test
-[ { 0 0 0 0 0 0 0 0 0 0 } ] [ { 0 0 0 } { 0 0 0 0 0 0 0 0 } p* ] unit-test
-[ { 0 1 } ] [ { 0 1 } { 1 } p* ] unit-test
-[ { 0 } ] [ { } { } p* ] unit-test
-[ { 0 } ] [ { 0 } { } p* ] unit-test
-[ { 0 } ] [ { } { 0 } p* ] unit-test
-[ { 0 0 0 } ] [ { 0 0 0 } { 0 0 0 } p+ ] unit-test
-[ { 0 0 0 } ] [ { 0 0 0 } { 0 0 0 } p- ] unit-test
-[ { 0 0 0 } ] [ 4 { 0 0 0 } n*p ] unit-test
-[ { 4 8 0 12 } ] [ 4 { 1 2 0 3 } n*p ] unit-test
-[ { 1 4 7 6 0 0 0 0 0 } ] [ { 1 2 3 0 0 0 } { 1 2 0 0 } p* ] unit-test
-[ V{ 7 -2 1 } V{ -20 0 0 } ] [ { 1 1 1 1 } { 3 1 } p/mod ] unit-test
-[ V{ 0 0 } V{ 1 1 } ] [ { 1 1 } { 1 1 1 1 } p/mod ] unit-test
-[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 } { 1 1 } p/mod ] unit-test
-[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 } { 1 1 0 0 0 0 0 0 } p/mod ] unit-test
-[ V{ 1 0 1 } V{ 0 0 0 } ] [ { 1 1 1 1 0 0 0 0 } { 1 1 0 0 } p/mod ] unit-test
-[ V{ 5.0 } V{ 0 } ] [ { 10.0 } { 2.0 } p/mod ] unit-test
-[ V{ 15/16 } V{ 0 } ] [ { 3/4 } { 4/5 } p/mod ] unit-test
-[ t ] [ { 0 1 } { 0 1 0 } p= ] unit-test
-[ f ] [ { 0 0 1 } { 0 1 0 } p= ] unit-test
-[ t ] [ { 1 1 1 } { 1 1 1 } p= ] unit-test
-[ { 0 0 } { 1 1 } ] [ { 1 1 1 1 } { 1 1 } pgcd ] unit-test
-
diff --git a/extra/math/polynomials/polynomials.factor b/extra/math/polynomials/polynomials.factor
deleted file mode 100644 (file)
index 13090b6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-! 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
-    splitting vectors ;
-IN: math.polynomials
-
-<PRIVATE
-
-: 2pad-left ( p q n -- p q ) [ 0 pad-left ] curry bi@ ;
-: 2pad-right ( p q n -- p q ) [ 0 pad-right ] curry bi@ ;
-: pextend ( p q -- p q ) 2dup [ length ] bi@ max 2pad-right ;
-: pextend-left ( p q -- p q ) 2dup [ length ] bi@ max 2pad-left ;
-: unempty ( seq -- seq ) [ { 0 } ] when-empty ;
-: 2unempty ( seq seq -- seq seq ) [ unempty ] bi@ ;
-
-PRIVATE>
-
-: powers ( n x -- seq )
-    <array> 1 [ * ] accumulate nip ;
-
-: p= ( p q -- ? ) pextend = ;
-
-: ptrim ( p -- p )
-    dup length 1 = [ [ zero? ] trim-right ] unless ;
-
-: 2ptrim ( p q -- p q ) [ ptrim ] bi@ ;
-: p+ ( p q -- r ) pextend v+ ;
-: p- ( p q -- r ) pextend v- ;
-: n*p ( n p -- n*p ) n*v ;
-
-: pextend-conv ( p q -- p q )
-    2dup [ length ] bi@ + 1- 2pad-right [ >vector ] bi@ ;
-
-: p* ( p q -- r )
-    2unempty pextend-conv <reversed> dup length
-    [ over length pick <slice> pick [ * ] 2map sum ] map 2nip reverse ;
-
-: p-sq ( p -- p^2 )
-    dup p* ;
-
-<PRIVATE
-
-: p/mod-setup ( p p -- p p n )
-    2ptrim
-    2dup [ length ] bi@ -
-    dup 1 < [ drop 1 ] when
-    [ over length + 0 pad-left pextend ] keep 1+ ;
-
-: /-last ( seq seq -- a )
-    #! divide the last two numbers in the sequences
-    [ peek ] bi@ / ;
-
-: (p/mod) ( p p -- p p )
-    2dup /-last
-    2dup , n*p swapd
-    p- >vector
-    dup pop* swap rest-slice ;
-
-PRIVATE>
-
-: p/mod ( p q -- z w )
-    p/mod-setup [ [ (p/mod) ] times ] V{ } make
-    reverse nip swap 2ptrim pextend ;
-
-<PRIVATE
-
-: (pgcd) ( b a y x -- a d )
-    dup V{ 0 } clone p= [
-        drop nip
-    ] [
-        tuck p/mod [ pick p* swap [ swapd p- ] dip ] dip (pgcd)
-    ] if ;
-
-PRIVATE>
-
-: pgcd ( p q -- a d )
-    swap V{ 0 } clone V{ 1 } clone 2swap (pgcd) [ >array ] bi@ ;
-
-: pdiff ( p -- p' )
-    dup length v* { 0 } ?head drop ;
-
-: polyval ( p x -- p[x] )
-    [ dup length ] dip powers v. ;
-
diff --git a/extra/math/polynomials/summary.txt b/extra/math/polynomials/summary.txt
deleted file mode 100644 (file)
index 5c237a2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Polynomial arithmetic
diff --git a/extra/math/quaternions/authors.txt b/extra/math/quaternions/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/extra/math/quaternions/quaternions-docs.factor b/extra/math/quaternions/quaternions-docs.factor
deleted file mode 100644 (file)
index bb34ec8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-USING: help.markup help.syntax math math.vectors vectors ;
-IN: math.quaternions
-
-HELP: q*
-{ $values { "u" "a quaternion" } { "v" "a quaternion" } { "u*v" "a quaternion" } }
-{ $description "Multiply quaternions." }
-{ $examples { $example "USING: math.quaternions prettyprint ;" "{ C{ 0 1 } 0 } { 0 1 } q* ." "{ 0 C{ 0 1 } }" } } ;
-
-HELP: qconjugate
-{ $values { "u" "a quaternion" } { "u'" "a quaternion" } }
-{ $description "Quaternion conjugate." } ;
-
-HELP: qrecip
-{ $values { "u" "a quaternion" } { "1/u" "a quaternion" } }
-{ $description "Quaternion inverse." } ;
-
-HELP: q/
-{ $values { "u" "a quaternion" } { "v" "a quaternion" } { "u/v" "a quaternion" } }
-{ $description "Divide quaternions." }
-{ $examples { $example "USING: math.quaternions prettyprint ;" "{ 0 C{ 0 1 } } { 0 1 } q/ ." "{ C{ 0 1 } 0 }" } } ;
-
-HELP: q*n
-{ $values { "q" "a quaternion" } { "n" number } { "q" "a quaternion" } }
-{ $description "Multiplies each element of " { $snippet "q" } " by " { $snippet "n" } "." }
-{ $notes "You will get the wrong result if you try to multiply a quaternion by a complex number on the right using " { $link v*n } ". Use this word instead."
-    $nl "Note that " { $link v*n } " with a quaternion and a real is okay." } ;
-
-HELP: c>q
-{ $values { "c" number } { "q" "a quaternion" } }
-{ $description "Turn a complex number into a quaternion." }
-{ $examples { $example "USING: math.quaternions prettyprint ;" "C{ 0 1 } c>q ." "{ C{ 0 1 } 0 }" } } ;
-
-HELP: v>q
-{ $values { "v" vector } { "q" "a quaternion" } }
-{ $description "Turn a 3-vector into a quaternion with real part 0." }
-{ $examples { $example "USING: math.quaternions prettyprint ;" "{ 1 0 0 } v>q ." "{ C{ 0 1 } 0 }" } } ;
-
-HELP: q>v
-{ $values { "q" "a quaternion" } { "v" vector } }
-{ $description "Get the vector part of a quaternion, discarding the real part." }
-{ $examples { $example "USING: math.quaternions prettyprint ;" "{ C{ 0 1 } 0 } q>v ." "{ 1 0 0 }" } } ;
-
-HELP: euler
-{ $values { "phi" number } { "theta" number } { "psi" number } { "q" "a quaternion" } }
-{ $description "Convert a rotation given by Euler angles (phi, theta, and psi) to a quaternion." } ;
-
diff --git a/extra/math/quaternions/quaternions-tests.factor b/extra/math/quaternions/quaternions-tests.factor
deleted file mode 100644 (file)
index a6d255e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-IN: math.quaternions.tests
-USING: tools.test math.quaternions kernel math.vectors
-math.constants ;
-
-[ 1.0 ] [ qi norm ] unit-test
-[ 1.0 ] [ qj norm ] unit-test
-[ 1.0 ] [ qk norm ] unit-test
-[ 1.0 ] [ q1 norm ] unit-test
-[ 0.0 ] [ q0 norm ] unit-test
-[ t ] [ qi qj q* qk = ] unit-test
-[ t ] [ qj qk q* qi = ] unit-test
-[ t ] [ qk qi q* qj = ] unit-test
-[ t ] [ qi qi q* q1 v+ q0 = ] unit-test
-[ t ] [ qj qj q* q1 v+ q0 = ] unit-test
-[ t ] [ qk qk q* q1 v+ q0 = ] unit-test
-[ t ] [ qi qj qk q* q* q1 v+ q0 = ] unit-test
-[ t ] [ C{ 0 1 } qj n*v qk = ] unit-test
-[ t ] [ qj C{ 0 1 } q*n qk v+ q0 = ] unit-test
-[ t ] [ qk qj q/ qi = ] unit-test
-[ t ] [ qi qk q/ qj = ] unit-test
-[ t ] [ qj qi q/ qk = ] unit-test
-[ t ] [ qi q>v v>q qi = ] unit-test
-[ t ] [ qj q>v v>q qj = ] unit-test
-[ t ] [ qk q>v v>q qk = ] unit-test
-[ t ] [ 1 c>q q1 = ] unit-test
-[ t ] [ C{ 0 1 } c>q qi = ] unit-test
diff --git a/extra/math/quaternions/quaternions.factor b/extra/math/quaternions/quaternions.factor
deleted file mode 100755 (executable)
index bb0d025..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math math.functions math.vectors sequences ;
-IN: math.quaternions
-
-! Everybody's favorite non-commutative skew field, the quaternions!
-
-! Quaternions are represented as pairs of complex numbers, using the
-! identity: (a+bi)+(c+di)j = a+bi+cj+dk.
-
-<PRIVATE
-
-: ** conjugate * ; inline
-
-: 2q ( u v -- u' u'' v' v'' ) [ first2 ] bi@ ; inline
-
-: q*a ( u v -- a ) 2q swapd ** [ * ] dip - ; inline
-
-: q*b ( u v -- b ) 2q [ ** swap ] dip * + ; inline
-
-PRIVATE>
-
-: q* ( u v -- u*v )
-    [ q*a ] [ q*b ] 2bi 2array ;
-
-: qconjugate ( u -- u' )
-    first2 [ conjugate ] [ neg  ] bi* 2array ;
-
-: qrecip ( u -- 1/u )
-    qconjugate dup norm-sq v/n ;
-
-: q/ ( u v -- u/v )
-    qrecip q* ;
-
-: q*n ( q n -- q )
-    conjugate v*n ;
-
-: c>q ( c -- q )
-    0 2array ;
-
-: v>q ( v -- q )
-    first3 rect> [ 0 swap rect> ] dip 2array ;
-
-: q>v ( q -- v )
-    first2 [ imaginary-part ] dip >rect 3array ;
-
-! Zero
-: q0 { 0 0 } ;
-
-! Units
-: q1 { 1 0 } ;
-: qi { C{ 0 1 } 0 } ;
-: qj { 0 1 } ;
-: qk { 0 C{ 0 1 } } ;
-
-! Euler angles
-
-<PRIVATE
-
-: (euler) ( theta unit -- q )
-    [ -0.5 * [ cos c>q ] [ sin ] bi ] dip n*v v- ;
-
-PRIVATE>
-
-: euler ( phi theta psi -- q )
-  [ qi (euler) ] [ qj (euler) ] [ qk (euler) ] tri* q* q* ;
diff --git a/extra/math/quaternions/summary.txt b/extra/math/quaternions/summary.txt
deleted file mode 100644 (file)
index 756750b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Quaternion arithmetic and Euler angles
diff --git a/extra/math/statistics/authors.txt b/extra/math/statistics/authors.txt
deleted file mode 100644 (file)
index 176ca5c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Doug Coleman
-Michael Judge
diff --git a/extra/math/statistics/statistics-docs.factor b/extra/math/statistics/statistics-docs.factor
deleted file mode 100644 (file)
index 695834b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-USING: help.markup help.syntax debugger ;
-IN: math.statistics
-
-HELP: geometric-mean
-{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
-{ $description "Computes the geometric mean of all elements in " { $snippet "seq" } ".  The geometric mean measures the central tendency of a data set that minimizes the effects of extreme values." }
-{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } geometric-mean ." "1.81712059283214" } }
-{ $errors "Throws a " { $link signal-error. } " (square-root of 0) if the sequence is empty." } ;
-
-HELP: harmonic-mean
-{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
-{ $description "Computes the harmonic mean of the elements in " { $snippet "seq" } ".  The harmonic mean is appropriate when the average of rates is desired." }
-{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } harmonic-mean ." "6/11" } }
-{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
-
-HELP: mean
-{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
-{ $description "Computes the arithmetic mean of all elements in " { $snippet "seq" } "." }
-{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } mean ." "2" } }
-{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
-
-HELP: median
-{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
-{ $description "Computes the median of " { $snippet "seq" } " by sorting the sequence from lowest value to highest and outputting the middle one. If there is an even number of elements in the sequence, the median is not unique, so the mean of the two middle values is outputted." }
-{ $examples
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } median ." "2" }
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } median ." "2+1/2" } }
-{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
-
-HELP: range
-{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
-{ $description "Computes the distance of the maximum and minimum values in " { $snippet "seq" } "." }
-{ $examples
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } range ." "2" }
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } range ." "3" } }  ;
-
-HELP: std
-{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
-{ $description "Computes the standard deviation of " { $snippet "seq" } " by squaring the variance of the sequence.  It measures how widely spread the values in a sequence are about the mean." }
-{ $examples
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } std ." "1.0" }
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } std ." "1.290994448735806" } } ;
-
-HELP: ste
-  { $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
-  { $description "Computes the standard error of the mean for " { $snippet "seq" } ".  It's defined as the standard deviation divided by the square root of the length of the sequence, and measures uncertainty associated with the estimate of the mean." }
-  { $examples
-    { $example "USING: math.statistics prettyprint ;" "{ -2 2 } ste ." "2.0" }
-    { $example "USING: math.statistics prettyprint ;" "{ -2 2 2 } ste ." "1.333333333333333" } } ;
-
-HELP: var
-{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
-{ $description "Computes the variance of " { $snippet "seq" } ".  It's a measurement of the spread of values in a sequence.  The larger the variance, the larger the distance of values from the mean." }
-{ $notes "If the number of elements in " { $snippet "seq" } " is 1 or less, it outputs 0." }
-{ $examples
-  { $example "USING: math.statistics prettyprint ;" "{ 1 } var ." "0" }
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } var ." "1" }
-  { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 4 } var ." "1+2/3" } } ;
-
diff --git a/extra/math/statistics/statistics-tests.factor b/extra/math/statistics/statistics-tests.factor
deleted file mode 100644 (file)
index b6ff421..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-USING: kernel math math.functions math.statistics tools.test ;
-IN: math.statistics.tests
-
-[ 1 ] [ { 1 } mean ] unit-test
-[ 3/2 ] [ { 1 2 } mean ] unit-test
-[ 0 ] [ { 0 0 0 } geometric-mean ] unit-test
-[ t ] [ { 2 2 2 2 } geometric-mean 2.0 .0001 ~ ] unit-test
-[ 1.0 ] [ { 1 1 1 } geometric-mean ] unit-test
-[ 1/3 ] [ { 1 1 1 } harmonic-mean ] unit-test
-
-[ 0 ] [ { 1 } range ] unit-test
-[ 89 ] [ { 1 2 30 90 } range ] unit-test
-[ 2 ] [ { 1 2 3 } median ] unit-test
-[ 5/2 ] [ { 1 2 3 4 } median ] unit-test
-
-[ 1 ] [ { 1 2 3 } var ] unit-test
-[ 1.0 ] [ { 1 2 3 } std ] unit-test
-[ t ] [ { 1 2 3 4 } ste 0.6454972243679028 - .0001 < ] unit-test
-
-[ t ] [ { 23.2 33.4 22.5 66.3 44.5 } std 18.1906 - .0001 < ] unit-test
-
-[ 0 ] [ { 1 } var ] unit-test
-[ 0.0 ] [ { 1 } std ] unit-test
-[ 0.0 ] [ { 1 } ste ] unit-test
diff --git a/extra/math/statistics/statistics.factor b/extra/math/statistics/statistics.factor
deleted file mode 100644 (file)
index 7568af5..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-! Copyright (C) 2008 Doug Coleman, Michael Judge.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays combinators kernel math math.analysis math.functions sequences
-    sequences.lib sorting ;
-IN: math.statistics
-
-: mean ( seq -- n )
-    #! arithmetic mean, sum divided by length
-    [ sum ] [ length ] bi / ;
-
-: geometric-mean ( seq -- n )
-    #! geometric mean, nth root of product
-    [ length ] [ product ] bi nth-root ;
-
-: harmonic-mean ( seq -- n )
-    #! harmonic mean, reciprocal of sum of reciprocals.
-    #! positive reals only
-    [ recip ] sigma recip ;
-
-: median ( seq -- n )
-    #! middle number if odd, avg of two middle numbers if even
-    natural-sort dup length even? [
-        [ midpoint@ dup 1- 2array ] keep nths mean
-    ] [
-        [ midpoint@ ] keep nth
-    ] if ;
-
-: range ( seq -- n )
-    #! max - min
-    minmax swap - ;
-
-: var ( seq -- x )
-    #! variance, normalize by N-1
-    dup length 1 <= [
-        drop 0
-    ] [
-        [ [ mean ] keep [ - sq ] with sigma ] keep
-        length 1- /
-    ] if ;
-
-: std ( seq -- x )
-    #! standard deviation, sqrt of variance
-    var sqrt ;
-
-: ste ( seq -- x )
-    #! standard error, standard deviation / sqrt ( length of sequence )
-    [ std ] [ length ] bi sqrt / ;
-
-: ((r)) ( mean(x) mean(y) {x} {y} -- (r) )
-    ! finds sigma((xi-mean(x))(yi-mean(y))
-    0 [ [ [ pick ] dip swap - ] bi@ * + ] 2reduce 2nip ;
-
-: (r) ( mean(x) mean(y) {x} {y} sx sy -- r )
-    * recip [ [ ((r)) ] keep length 1- / ] dip * ;
-
-: [r] ( {{x,y}...} -- mean(x) mean(y) {x} {y} sx sy )
-    first2 [ [ [ mean ] bi@ ] 2keep ] 2keep [ std ] bi@ ;
-
-: r ( {{x,y}...} -- r )
-    [r] (r) ;
-
-: r^2 ( {{x,y}...} -- r )
-    r sq ;
-
-: least-squares ( {{x,y}...} -- alpha beta )
-    [r] { [ 2dup ] [ ] [ ] [ ] [ ] } spread
-    ! stack is mean(x) mean(y) mean(x) mean(y) {x} {y} sx sy
-    [ (r) ] 2keep ! stack is mean(x) mean(y) r sx sy
-    swap / * ! stack is mean(x) mean(y) beta
-    [ swapd * - ] keep ;
-
diff --git a/extra/math/statistics/summary.txt b/extra/math/statistics/summary.txt
deleted file mode 100644 (file)
index 628c9ad..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Mean, median, standard deviation, and other statistical routines
index 58dab74cdbb10d61a5c8462a110fa09577fb86c4..41f19b9b07b7e2a93d53a27006d6bf5d5635a46c 100755 (executable)
@@ -56,7 +56,7 @@ SYMBOL: and-needed?
 
 : text-with-scale ( index seq -- str )
     [ nth 3digits>text ] [ drop scale-numbers ] 2bi
-    [ " " swap 3append ] unless-empty ;
+    [ " " glue ] unless-empty ;
 
 : append-with-conjunction ( str1 str2 -- newstr )
     over length zero? [
index 40e12a97c9a2b2bf8d8964485bbd390afc240c3a..de345e732ec9d5cd3a66045d1ce662b64359532b 100644 (file)
@@ -1,7 +1,7 @@
 ! From http://www.ffconsultancy.com/ocaml/maze/index.html
 USING: sequences namespaces math math.vectors opengl opengl.gl
-opengl.demo-support arrays kernel random ui ui.gadgets
-ui.gadgets.canvas ui.render math.order math.geometry.rect ;
+arrays kernel random ui ui.gadgets ui.gadgets.canvas ui.render
+math.order math.geometry.rect ;
 IN: maze
 
 : line-width 8 ;
@@ -28,7 +28,7 @@ SYMBOL: visited
 : (draw-maze) ( cell -- )
     dup vertex
     glEnd
-    GL_POINTS [ dup vertex ] do-state
+    GL_POINTS glBegin dup vertex glEnd
     GL_LINE_STRIP glBegin
     dup vertex
     dup visit
@@ -41,7 +41,6 @@ SYMBOL: visited
     ] if ;
 
 : draw-maze ( n -- )
-    -0.5 0.5 0 glTranslated
     line-width 2 - glLineWidth
     line-width 2 - glPointSize
     1.0 1.0 1.0 1.0 glColor4d
index 78c168015f9e7484eb10b45eaac0d2e660d6d131..226b7126766b84bd0c11559bf80e89c66ab0d08a 100644 (file)
@@ -12,10 +12,14 @@ IN: money.tests
 [ 1/10 ] [ DECIMAL: .1 ] unit-test
 [ 1/10 ] [ DECIMAL: 0.1 ] unit-test
 [ 1/10 ] [ DECIMAL: 00.10 ] unit-test
-
-
+[ 23 ] [ DECIMAL: 23 ] unit-test
+[ -23 ] [ DECIMAL: -23 ] unit-test
+[ -23-1/100 ] [ DECIMAL: -23.01 ] unit-test
 
 [ "DECIMAL: ." eval ] must-fail
 [ "DECIMAL: f" eval ] must-fail
 [ "DECIMAL: 0.f" eval ] must-fail
 [ "DECIMAL: f.0" eval ] must-fail
+
+[ "$100.00" ] [ DECIMAL: 100.0 money>string ] unit-test
+[ "$0.00" ] [ DECIMAL: 0.0 money>string ] unit-test
index 5fa76d5f531be6676644d9f9e4e2dfc2b4368cd4..553c473cce17721394d3d085dbe0f4d921b7299a 100644 (file)
@@ -3,28 +3,31 @@ namespaces make sequences splitting grouping combinators
 continuations ;
 IN: money
 
+SYMBOL: currency-token
+CHAR: $ \ currency-token set-global
+
 : dollars/cents ( dollars -- dollars cents )
     100 * 100 /mod round ;
 
+: (money>string) ( dollars cents -- string )
+    [ number>string ] bi@
+    [ <reversed> 3 group "," join <reversed> ]
+    [ 2 CHAR: 0 pad-left ] bi* "." glue ;
+
 : money>string ( object -- string )
-    dollars/cents [
-        "$" %
-        swap number>string
-        <reversed> 3 group "," join <reversed> %
-        "." % number>string 2 CHAR: 0 pad-left %
-    ] "" make ;
+    dollars/cents (money>string) currency-token get prefix ;
 
-: money. ( object -- )
-    money>string print ;
+: money. ( object -- ) money>string print ;
 
-ERROR: not-a-decimal x ;
+ERROR: not-an-integer x ;
 
 : parse-decimal ( str -- ratio )
     "." split1
-    >r dup "-" head? [ drop t "0" ] [ f swap ] if r>
+    [ "-" ?head swap ] dip
     [ [ "0" ] when-empty ] bi@
-    dup length
-    >r [ dup string>number [ nip ] [ not-a-decimal ] if* ] bi@ r>
+    [
+        [ dup string>number [ nip ] [ not-an-integer ] if* ] bi@
+    ] keep length
     10 swap ^ / + swap [ neg ] when ;
 
 : DECIMAL:
diff --git a/extra/morse/authors.txt b/extra/morse/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/morse/morse-docs.factor b/extra/morse/morse-docs.factor
deleted file mode 100644 (file)
index e35967d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax ;
-IN: morse
-
-HELP: ch>morse
-{ $values
-    { "ch" "A character that has a morse code translation" } { "str" "A string consisting of zero or more dots and dashes" } }
-{ $description "If the given character has a morse code translation, then return that translation, otherwise return an empty string." } ;
-
-HELP: morse>ch
-{ $values
-    { "str" "A string of dots and dashes that represents a single character in morse code" } { "ch" "The translated character" } }
-{ $description "If the given string represents a morse code character, then return that character, otherwise return f" } ;
-
-HELP: >morse
-{ $values
-    { "str" "A string of ASCII characters which can be translated into morse code" } { "str" "A string in morse code" } }
-{ $description "Translates ASCII text into morse code, represented by a series of dots, dashes, and slashes." }
-{ $see-also morse> ch>morse } ;
-
-HELP: morse>
-{ $values { "str" "A string of morse code, in which the character '.' represents dots, '-' dashes, ' ' spaces between letters, and ' / ' spaces between words." } { "str" "The ASCII translation of the given string" } }
-{ $description "Translates morse code into ASCII text" }
-{ $see-also >morse morse>ch } ;
-
-HELP: play-as-morse*
-{ $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } }
-{ $description "Plays a string as morse code" } ;
-
-HELP: play-as-morse
-{ $values { "str" "A string of ascii characters which can be translated into morse code" } }
-{ $description "Plays a string as morse code" } ;
diff --git a/extra/morse/morse-tests.factor b/extra/morse/morse-tests.factor
deleted file mode 100644 (file)
index 1444489..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays morse strings tools.test ;
-
-[ "" ] [ CHAR: \\ ch>morse ] unit-test
-[ "..." ] [ CHAR: s ch>morse ] unit-test
-[ CHAR: s ] [ "..." morse>ch ] unit-test
-[ f ] [ "..--..--.." morse>ch ] unit-test
-[ "-- --- .-. ... . / -.-. --- -.. ." ] [ "morse code" >morse ] unit-test
-[ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test
-[ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test
-! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
-! [ ] [ "Factor rocks!" play-as-morse ] unit-test
diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor
deleted file mode 100644 (file)
index 2951c96..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs combinators hashtables kernel lists math
-namespaces make openal parser-combinators promises sequences
-strings symbols synth synth.buffers unicode.case ;
-IN: morse
-
-<PRIVATE
-: morse-codes ( -- array )
-    {
-        { CHAR: a ".-"    }
-        { CHAR: b "-..."  }
-        { CHAR: c "-.-."  }
-        { CHAR: d "-.."   }
-        { CHAR: e "."     }
-        { CHAR: f "..-."  }
-        { CHAR: g "--."   }
-        { CHAR: h "...."  }
-        { CHAR: i ".."    }
-        { CHAR: j ".---"  }
-        { CHAR: k "-.-"   }
-        { CHAR: l ".-.."  }
-        { CHAR: m "--"    }
-        { CHAR: n "-."    }
-        { CHAR: o "---"   }
-        { CHAR: p ".--."  }
-        { CHAR: q "--.-"  }
-        { CHAR: r ".-."   }
-        { CHAR: s "..."   }
-        { CHAR: t "-"     }
-        { CHAR: u "..-"   }
-        { CHAR: v "...-"  }
-        { CHAR: w ".--"   }
-        { CHAR: x "-..-"  }
-        { CHAR: y "-.--"  }
-        { CHAR: z "--.."  }
-        { CHAR: 1 ".----" }
-        { CHAR: 2 "..---" }
-        { CHAR: 3 "...--" }
-        { CHAR: 4 "....-" }
-        { CHAR: 5 "....." }
-        { CHAR: 6 "-...." }
-        { CHAR: 7 "--..." }
-        { CHAR: 8 "---.." }
-        { CHAR: 9 "----." }
-        { CHAR: 0 "-----" }
-        { CHAR: . ".-.-.-" }
-        { CHAR: , "--..--" }
-        { CHAR: ? "..--.." }
-        { CHAR: ' ".----." }
-        { CHAR: ! "-.-.--" }
-        { CHAR: / "-..-."  }
-        { CHAR: ( "-.--."  }
-        { CHAR: ) "-.--.-" }
-        { CHAR: & ".-..."  }
-        { CHAR: : "---..." }
-        { CHAR: ; "-.-.-." }
-        { CHAR: = "-...- " }
-        { CHAR: + ".-.-."  }
-        { CHAR: - "-....-" }
-        { CHAR: _ "..--.-" }
-        { CHAR: " ".-..-." }
-        { CHAR: $ "...-..-" }
-        { CHAR: @ ".--.-." }
-        { CHAR: \s "/" }
-    } ;
-
-: ch>morse-assoc ( -- assoc )
-    morse-codes >hashtable ;
-
-: morse>ch-assoc ( -- assoc )
-    morse-codes [ reverse ] map >hashtable ;
-
-PRIVATE>
-
-: ch>morse ( ch -- str )
-    ch>lower ch>morse-assoc at* swap "" ? ;
-
-: morse>ch ( str -- ch )
-    morse>ch-assoc at* swap f ? ;
-
-: >morse ( str -- str )
-    [
-        [ CHAR: \s , ] [ ch>morse % ] interleave
-    ] "" make ;
-
-<PRIVATE
-
-: dot-char ( -- ch ) CHAR: . ;
-: dash-char ( -- ch ) CHAR: - ;
-: char-gap-char ( -- ch ) CHAR: \s ;
-: word-gap-char ( -- ch ) CHAR: / ;
-
-: =parser ( obj -- parser )
-    [ = ] curry satisfy ;
-
-LAZY: 'dot' ( -- parser )
-    dot-char =parser ;
-
-LAZY: 'dash' ( -- parser )
-    dash-char =parser ;
-
-LAZY: 'char-gap' ( -- parser )
-    char-gap-char =parser ;
-
-LAZY: 'word-gap' ( -- parser )
-    word-gap-char =parser ;
-
-LAZY: 'morse-char' ( -- parser )
-    'dot' 'dash' <|> <+> ;
-
-LAZY: 'morse-word' ( -- parser )
-    'morse-char' 'char-gap' list-of ;
-
-LAZY: 'morse-words' ( -- parser )
-    'morse-word' 'word-gap' list-of ;
-
-PRIVATE>
-
-: morse> ( str -- str )
-    'morse-words' parse car parsed>> [
-        [ 
-            >string morse>ch
-        ] map >string
-    ] map [ [ CHAR: \s , ] [ % ] interleave ] "" make ;
-
-<PRIVATE
-SYMBOLS: source dot-buffer dash-buffer intra-char-gap-buffer letter-gap-buffer ;
-
-: queue ( symbol -- )
-    get source get swap queue-buffer ;
-
-: dot ( -- ) dot-buffer queue ;
-: dash ( -- ) dash-buffer queue ;
-: intra-char-gap ( -- ) intra-char-gap-buffer queue ;
-: letter-gap ( -- ) letter-gap-buffer queue ;
-
-: beep-freq 880 ;
-
-: <morse-buffer> ( -- buffer )
-    half-sample-freq <8bit-mono-buffer> ;
-
-: sine-buffer ( seconds -- id )
-    beep-freq swap <morse-buffer> >sine-wave-buffer
-    send-buffer id>> ;
-
-: silent-buffer ( seconds -- id )
-    <morse-buffer> >silent-buffer send-buffer id>> ;
-
-: make-buffers ( unit-length -- )
-    {
-        [ sine-buffer dot-buffer set ]
-        [ 3 * sine-buffer dash-buffer set ]
-        [ silent-buffer intra-char-gap-buffer set ]
-        [ 3 * silent-buffer letter-gap-buffer set ]
-    } cleave ;
-
-: playing-morse ( quot unit-length -- )
-    [
-        init-openal 1 gen-sources first source set make-buffers
-        call
-        source get source-play
-    ] with-scope ;
-
-: play-char ( ch -- )
-    [ intra-char-gap ] [
-        {
-            { dot-char [ dot ] }
-            { dash-char [ dash ] }
-            { word-gap-char [ intra-char-gap ] }
-        } case
-    ] interleave ;
-
-PRIVATE>
-
-: play-as-morse* ( str unit-length -- )
-    [
-        [ letter-gap ] [ ch>morse play-char ] interleave
-    ] swap playing-morse ;
-
-: play-as-morse ( str -- )
-    0.05 play-as-morse* ;
diff --git a/extra/morse/summary.txt b/extra/morse/summary.txt
deleted file mode 100644 (file)
index 2c1f091..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Converts between text and morse code, and plays morse code.
diff --git a/extra/morse/tags.txt b/extra/morse/tags.txt
deleted file mode 100644 (file)
index 1e107f5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-examples
diff --git a/extra/multi-method-syntax/multi-method-syntax.factor b/extra/multi-method-syntax/multi-method-syntax.factor
new file mode 100644 (file)
index 0000000..9f05525
--- /dev/null
@@ -0,0 +1,23 @@
+
+USING: accessors effects.parser kernel lexer multi-methods
+       parser sequences words ;
+
+IN: multi-method-syntax
+
+! A nicer specializer syntax to hold us over till multi-methods go in
+! officially.
+!
+! Use both 'multi-methods' and 'multi-method-syntax' in that order.
+
+: scan-specializer ( -- specializer )
+
+  scan drop ! eat opening parenthesis
+
+  ")" parse-effect in>> [ search ] map ;
+
+: CREATE-METHOD ( -- method )
+  scan-word scan-specializer swap create-method-in ;
+
+: (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
+
+: METHOD: (METHOD:) define ; parsing
\ No newline at end of file
diff --git a/extra/nehe/2/2.factor b/extra/nehe/2/2.factor
deleted file mode 100644 (file)
index 29d4ccf..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu
-opengl.demo-support ui ui.gadgets ui.render ;
-IN: nehe.2
-
-TUPLE: nehe2-gadget < gadget ;
-
-: width 256 ;
-: height 256 ;
-
-: <nehe2-gadget> (  -- gadget )
-  nehe2-gadget new-gadget ;
-
-M: nehe2-gadget pref-dim* ( gadget -- dim )
-  drop width height 2array ;
-
-M: nehe2-gadget draw-gadget* ( gadget -- )
-  drop
-  GL_PROJECTION glMatrixMode
-  glLoadIdentity
-  45.0 width height / >float 0.1 100.0 gluPerspective
-  GL_MODELVIEW glMatrixMode
-  glLoadIdentity
-  GL_SMOOTH glShadeModel
-  0.0 0.0 0.0 0.0 glClearColor
-  1.0 glClearDepth
-  GL_DEPTH_TEST glEnable
-  GL_LEQUAL glDepthFunc
-  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
-  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
-  glLoadIdentity
-  -1.5 0.0 -6.0 glTranslatef
-  GL_TRIANGLES [
-    0.0 1.0 0.0 glVertex3f
-    -1.0 -1.0 0.0 glVertex3f
-    1.0 -1.0 0.0 glVertex3f
-  ] do-state
-  3.0 0.0 0.0 glTranslatef
-  GL_QUADS [
-    -1.0 1.0 0.0 glVertex3f
-    1.0 1.0 0.0 glVertex3f
-    1.0 -1.0 0.0 glVertex3f
-    -1.0 -1.0 0.0 glVertex3f
-  ] do-state ;
-
-: run2 ( -- )
-  <nehe2-gadget> "NeHe Tutorial 2" open-window ;
diff --git a/extra/nehe/2/authors.txt b/extra/nehe/2/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/nehe/3/3.factor b/extra/nehe/3/3.factor
deleted file mode 100644 (file)
index 75f2e57..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu
-opengl.demo-support ui ui.gadgets ui.render ;
-IN: nehe.3
-
-TUPLE: nehe3-gadget < gadget ;
-
-: width 256 ;
-: height 256 ;
-
-: <nehe3-gadget> (  -- gadget )
-  nehe3-gadget new-gadget ;
-
-M: nehe3-gadget pref-dim* ( gadget -- dim )
-  drop width height 2array ;
-
-M: nehe3-gadget draw-gadget* ( gadget -- )
-  drop
-  GL_PROJECTION glMatrixMode
-  glLoadIdentity
-  45.0 width height / >float 0.1 100.0 gluPerspective
-  GL_MODELVIEW glMatrixMode
-  glLoadIdentity
-  GL_SMOOTH glShadeModel
-  0.0 0.0 0.0 0.0 glClearColor
-  1.0 glClearDepth
-  GL_DEPTH_TEST glEnable
-  GL_LEQUAL glDepthFunc
-  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
-  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
-  glLoadIdentity
-  -1.5 0.0 -6.0 glTranslatef
-  GL_TRIANGLES [
-    1.0 0.0 0.0 glColor3f
-    0.0 1.0 0.0 glVertex3f
-    0.0 1.0 0.0 glColor3f
-    -1.0 -1.0 0.0 glVertex3f
-    0.0 0.0 1.0 glColor3f
-    1.0 -1.0 0.0 glVertex3f
-  ] do-state
-  3.0 0.0 0.0 glTranslatef
-  0.5 0.5 1.0 glColor3f
-  GL_QUADS [
-    -1.0 1.0 0.0 glVertex3f
-    1.0 1.0 0.0 glVertex3f
-    1.0 -1.0 0.0 glVertex3f
-    -1.0 -1.0 0.0 glVertex3f
-  ] do-state ;
-
-: run3 ( -- )
-  <nehe3-gadget> "NeHe Tutorial 3" open-window ;
diff --git a/extra/nehe/3/authors.txt b/extra/nehe/3/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/nehe/4/4.factor b/extra/nehe/4/4.factor
deleted file mode 100644 (file)
index 10217c9..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu
-opengl.demo-support ui ui.gadgets ui.render threads accessors
-calendar ;
-IN: nehe.4
-
-TUPLE: nehe4-gadget < gadget rtri rquad thread quit? ;
-
-: width 256 ;
-: height 256 ;
-: redraw-interval 10 milliseconds ;
-
-: <nehe4-gadget> (  -- gadget )
-  nehe4-gadget new-gadget
-    0.0 >>rtri
-    0.0 >>rquad ;
-
-M: nehe4-gadget pref-dim* ( gadget -- dim )
-  drop width height 2array ;
-
-M: nehe4-gadget draw-gadget* ( gadget -- )
-  GL_PROJECTION glMatrixMode
-  glLoadIdentity
-  45.0 width height / >float 0.1 100.0 gluPerspective
-  GL_MODELVIEW glMatrixMode
-  glLoadIdentity
-  GL_SMOOTH glShadeModel
-  0.0 0.0 0.0 0.0 glClearColor
-  1.0 glClearDepth
-  GL_DEPTH_TEST glEnable
-  GL_LEQUAL glDepthFunc
-  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
-  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
-  glLoadIdentity
-  -1.5 0.0 -6.0 glTranslatef
-  dup rtri>> 0.0 1.0 0.0 glRotatef
-
-  GL_TRIANGLES [
-    1.0 0.0 0.0 glColor3f
-    0.0 1.0 0.0 glVertex3f
-    0.0 1.0 0.0 glColor3f
-    -1.0 -1.0 0.0 glVertex3f
-    0.0 0.0 1.0 glColor3f
-    1.0 -1.0 0.0 glVertex3f
-  ] do-state
-
-  glLoadIdentity
-
-  1.5 0.0 -6.0 glTranslatef
-  dup rquad>> 1.0 0.0 0.0 glRotatef
-  0.5 0.5 1.0 glColor3f
-  GL_QUADS [
-    -1.0 1.0 0.0 glVertex3f
-    1.0 1.0 0.0 glVertex3f
-    1.0 -1.0 0.0 glVertex3f
-    -1.0 -1.0 0.0 glVertex3f
-  ] do-state
-  [ 0.2 + ] change-rtri
-  [ 0.15 - ] change-rquad drop ;
-
-: nehe4-update-thread ( gadget -- )
-  dup quit?>> [ drop ] [
-    redraw-interval sleep
-    dup relayout-1
-    nehe4-update-thread
-  ] if ;
-
-M: nehe4-gadget graft* ( gadget -- )
-  f >>quit?
-  [ nehe4-update-thread ] curry in-thread ;
-
-M: nehe4-gadget ungraft* ( gadget -- )
-  t >>quit? drop ;
-
-: run4 ( -- )
-  <nehe4-gadget> "NeHe Tutorial 4" open-window ;
diff --git a/extra/nehe/4/authors.txt b/extra/nehe/4/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/nehe/5/5.factor b/extra/nehe/5/5.factor
deleted file mode 100755 (executable)
index 2c9b51c..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu\r
-opengl.demo-support ui ui.gadgets ui.render threads accessors\r
-calendar ;\r
-IN: nehe.5\r
-\r
-TUPLE: nehe5-gadget < gadget rtri rquad thread quit? ;\r
-: width 256 ;\r
-: height 256 ;\r
-: redraw-interval 10 milliseconds ;\r
-\r
-: <nehe5-gadget> (  -- gadget )\r
-  nehe5-gadget new-gadget\r
-    0.0 >>rtri\r
-    0.0 >>rquad ;\r
-\r
-M: nehe5-gadget pref-dim* ( gadget -- dim )\r
-  drop width height 2array ;\r
-\r
-M: nehe5-gadget draw-gadget* ( gadget -- )\r
-  GL_PROJECTION glMatrixMode\r
-  glLoadIdentity\r
-  45.0 width height / >float 0.1 100.0 gluPerspective\r
-  GL_MODELVIEW glMatrixMode\r
-  glLoadIdentity\r
-  GL_SMOOTH glShadeModel\r
-  0.0 0.0 0.0 0.0 glClearColor\r
-  1.0 glClearDepth\r
-  GL_DEPTH_TEST glEnable\r
-  GL_LEQUAL glDepthFunc\r
-  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint\r
-  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear\r
-  glLoadIdentity\r
-  -1.5 0.0 -6.0 glTranslatef\r
-  dup rtri>> 0.0 1.0 0.0 glRotatef\r
-\r
-  GL_TRIANGLES [\r
-    1.0 0.0 0.0 glColor3f\r
-    0.0 1.0 0.0 glVertex3f\r
-    0.0 1.0 0.0 glColor3f\r
-    -1.0 -1.0 1.0 glVertex3f\r
-    0.0 0.0 1.0 glColor3f\r
-    1.0 -1.0 1.0 glVertex3f\r
-\r
-    1.0 0.0 0.0 glColor3f\r
-    0.0 1.0 0.0 glVertex3f\r
-    0.0 0.0 1.0 glColor3f\r
-    1.0 -1.0 1.0 glVertex3f\r
-    0.0 1.0 0.0 glColor3f\r
-    1.0 -1.0 -1.0 glVertex3f\r
-\r
-    1.0 0.0 0.0 glColor3f\r
-    0.0 1.0 0.0 glVertex3f\r
-    0.0 1.0 0.0 glColor3f\r
-    1.0 -1.0 -1.0 glVertex3f\r
-    0.0 0.0 1.0 glColor3f\r
-    -1.0 -1.0 -1.0 glVertex3f\r
-\r
-    1.0 0.0 0.0 glColor3f\r
-    0.0 1.0 0.0 glVertex3f\r
-    0.0 0.0 1.0 glColor3f\r
-    -1.0 -1.0 -1.0 glVertex3f\r
-    0.0 1.0 0.0 glColor3f\r
-    -1.0 -1.0 1.0 glVertex3f\r
-  ] do-state\r
-\r
-  glLoadIdentity\r
-\r
-  1.5 0.0 -7.0 glTranslatef\r
-  dup rquad>> 1.0 0.0 0.0 glRotatef\r
-  GL_QUADS [\r
-    0.0 1.0 0.0 glColor3f\r
-    1.0 1.0 -1.0 glVertex3f\r
-    -1.0 1.0 -1.0 glVertex3f\r
-    -1.0 1.0 1.0 glVertex3f\r
-    1.0 1.0 1.0 glVertex3f\r
-\r
-    1.0 0.5 0.0 glColor3f\r
-    1.0 -1.0 1.0 glVertex3f\r
-    -1.0 -1.0 1.0 glVertex3f\r
-    -1.0 -1.0 -1.0 glVertex3f\r
-    1.0 -1.0 -1.0 glVertex3f\r
-\r
-    1.0 0.0 0.0 glColor3f\r
-    1.0 1.0 1.0 glVertex3f\r
-    -1.0 1.0 1.0 glVertex3f\r
-    -1.0 -1.0 1.0 glVertex3f\r
-    1.0 -1.0 1.0 glVertex3f\r
-\r
-    1.0 1.0 0.0 glColor3f\r
-    1.0 -1.0 -1.0 glVertex3f\r
-    -1.0 -1.0 -1.0 glVertex3f\r
-    -1.0 1.0 -1.0 glVertex3f\r
-    1.0 1.0 -1.0 glVertex3f\r
-\r
-    0.0 0.0 1.0 glColor3f\r
-    -1.0 1.0 1.0 glVertex3f\r
-    -1.0 1.0 -1.0 glVertex3f\r
-    -1.0 -1.0 -1.0 glVertex3f\r
-    -1.0 -1.0 1.0 glVertex3f\r
-\r
-    1.0 0.0 1.0 glColor3f\r
-    1.0 1.0 -1.0 glVertex3f\r
-    1.0 1.0 1.0 glVertex3f\r
-    1.0 -1.0 1.0 glVertex3f\r
-    1.0 -1.0 -1.0 glVertex3f\r
-  ] do-state \r
-  [ 0.2 + ] change-rtri\r
-  [ 0.15 - ] change-rquad drop ;\r
-\r
-: nehe5-update-thread ( gadget -- )  \r
-  dup quit?>> [\r
-    drop\r
-  ] [\r
-    redraw-interval sleep \r
-    dup relayout-1  \r
-    nehe5-update-thread \r
-  ] if ;\r
-\r
-M: nehe5-gadget graft* ( gadget -- )\r
-  f >>quit?\r
-  [ nehe5-update-thread ] curry in-thread ;\r
-\r
-M: nehe5-gadget ungraft* ( gadget -- )\r
-  t >>quit? drop ;\r
-\r
-\r
-: run5 ( -- )\r
-  <nehe5-gadget> "NeHe Tutorial 5" open-window ;\r
diff --git a/extra/nehe/5/authors.txt b/extra/nehe/5/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/nehe/authors.txt b/extra/nehe/authors.txt
deleted file mode 100644 (file)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/nehe/deploy.factor b/extra/nehe/deploy.factor
deleted file mode 100755 (executable)
index 6cf9543..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: tools.deploy.config ;
-V{
-    { deploy-ui? t }
-    { deploy-io 1 }
-    { deploy-reflection 1 }
-    { deploy-compiler? t }
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-c-types? f }
-    { "stop-after-last-window?" t }
-    { deploy-name "NeHe OpenGL demos" }
-}
diff --git a/extra/nehe/nehe.factor b/extra/nehe/nehe.factor
deleted file mode 100644 (file)
index a96c024..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-USING: ui.gadgets.buttons ui.gadgets.packs ui.gadgets ui
-nehe.2 nehe.3 nehe.4 nehe.5 kernel ;
-IN: nehe
-
-: nehe-window ( -- )
-    [
-        <filled-pile>
-            "Nehe 2" [ drop run2 ] <bevel-button> add-gadget
-            "Nehe 3" [ drop run3 ] <bevel-button> add-gadget
-            "Nehe 4" [ drop run4 ] <bevel-button> add-gadget
-            "Nehe 5" [ drop run5 ] <bevel-button> add-gadget
-        "Nehe examples" open-window
-    ] with-ui ;
-
-MAIN: nehe-window
diff --git a/extra/nehe/summary.txt b/extra/nehe/summary.txt
deleted file mode 100644 (file)
index 7811f84..0000000
+++ /dev/null
@@ -1 +0,0 @@
-NeHe OpenGL tutorials ported to Factor
diff --git a/extra/nehe/tags.txt b/extra/nehe/tags.txt
deleted file mode 100644 (file)
index cb5fc20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-demos
diff --git a/extra/openal/authors.txt b/extra/openal/authors.txt
deleted file mode 100644 (file)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/openal/backend/authors.txt b/extra/openal/backend/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/openal/backend/backend.factor b/extra/openal/backend/backend.factor
deleted file mode 100644 (file)
index 41069dc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-USING: namespaces system ;
-IN: openal.backend
-
-HOOK: load-wav-file os ( filename -- format data size frequency )
diff --git a/extra/openal/example/authors.txt b/extra/openal/example/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/openal/example/example.factor b/extra/openal/example/example.factor
deleted file mode 100644 (file)
index ae0b50a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-! Copyright (C) 2007 Chris Double.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-!\r
-IN: openal.example\r
-USING: openal kernel alien threads sequences calendar ;\r
-\r
-: play-hello ( -- )\r
-  init-openal\r
-  1 gen-sources\r
-  first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param\r
-  source-play\r
-  1000 milliseconds sleep ;\r
-  \r
-: (play-file) ( source -- )\r
-  100 milliseconds sleep\r
-  dup source-playing? [ (play-file) ] [ drop ] if ;\r
-\r
-: play-file ( filename -- )\r
-  init-openal\r
-  create-buffer-from-file \r
-  1 gen-sources\r
-  first dup >r AL_BUFFER rot set-source-param r>\r
-  dup source-play\r
-  check-error\r
-  (play-file) ;\r
-\r
-: play-wav ( filename -- )\r
-  init-openal\r
-  create-buffer-from-wav \r
-  1 gen-sources\r
-  first dup >r AL_BUFFER rot set-source-param r>\r
-  dup source-play\r
-  check-error\r
-  (play-file) ;
\ No newline at end of file
diff --git a/extra/openal/macosx/authors.txt b/extra/openal/macosx/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/openal/macosx/macosx.factor b/extra/openal/macosx/macosx.factor
deleted file mode 100644 (file)
index d2a0422..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types kernel alien alien.syntax shuffle
-combinators.lib openal.backend namespaces system ;
-IN: openal.macosx
-
-LIBRARY: alut
-
-FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency ) ;
-
-M: macosx load-wav-file ( path -- format data size frequency )
-  0 <int> f <void*> 0 <int> 0 <int>
-  [ alutLoadWAVFile ] 4keep
-  >r >r >r *int r> *void* r> *int r> *int ;
diff --git a/extra/openal/macosx/tags.txt b/extra/openal/macosx/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/openal/openal.factor b/extra/openal/openal.factor
deleted file mode 100644 (file)
index 2a8959b..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel arrays alien system combinators alien.syntax namespaces
-       alien.c-types sequences vocabs.loader shuffle combinators.lib
-       openal.backend ;
-IN: openal
-
-<< "alut" {
-        { [ os windows? ]  [ "alut.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libalut.so" ] }
-    } cond "cdecl" add-library >>
-
-<< "openal" {
-        { [ os windows? ]  [ "OpenAL32.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libopenal.so" ] }
-    } cond "cdecl" add-library >>
-
-LIBRARY: openal
-
-TYPEDEF: char ALboolean 
-TYPEDEF: char ALchar
-TYPEDEF: char ALbyte
-TYPEDEF: uchar ALubyte
-TYPEDEF: short ALshort
-TYPEDEF: ushort ALushort
-TYPEDEF: int ALint
-TYPEDEF: uint ALuint
-TYPEDEF: int ALsizei
-TYPEDEF: int ALenum
-TYPEDEF: float ALfloat
-TYPEDEF: double ALdouble
-
-: AL_INVALID ( -- number ) -1 ; inline
-: AL_NONE ( -- number ) 0 ; inline
-: AL_FALSE ( -- number ) 0 ; inline
-: AL_TRUE ( -- number ) 1 ; inline
-: AL_SOURCE_RELATIVE ( -- number ) HEX: 202 ; inline
-: AL_CONE_INNER_ANGLE ( -- nmber ) HEX: 1001 ; inline
-: AL_CONE_OUTER_ANGLE ( -- number ) HEX: 1002 ; inline
-: AL_PITCH ( -- number ) HEX: 1003 ; inline
-: AL_POSITION ( -- number ) HEX: 1004 ; inline
-: AL_DIRECTION ( -- number ) HEX: 1005 ; inline
-: AL_VELOCITY ( -- number ) HEX: 1006 ; inline
-: AL_LOOPING ( -- number ) HEX: 1007 ; inline
-: AL_BUFFER ( -- number ) HEX: 1009 ; inline
-: AL_GAIN ( -- number ) HEX: 100A ; inline
-: AL_MIN_GAIN ( -- number ) HEX: 100D ; inline
-: AL_MAX_GAIN ( -- number ) HEX: 100E ; inline
-: AL_ORIENTATION ( -- number ) HEX: 100F ; inline
-: AL_CHANNEL_MASK ( -- number ) HEX: 3000 ; inline
-: AL_SOURCE_STATE ( -- number ) HEX: 1010 ; inline
-: AL_INITIAL ( -- number ) HEX: 1011 ; inline
-: AL_PLAYING ( -- number ) HEX: 1012 ; inline
-: AL_PAUSED ( -- number ) HEX: 1013 ; inline
-: AL_STOPPED ( -- number ) HEX: 1014 ; inline
-: AL_BUFFERS_QUEUED ( -- number ) HEX: 1015 ; inline
-: AL_BUFFERS_PROCESSED ( -- number ) HEX: 1016 ; inline
-: AL_SEC_OFFSET ( -- number ) HEX: 1024 ; inline
-: AL_SAMPLE_OFFSET ( -- number ) HEX: 1025 ; inline
-: AL_BYTE_OFFSET ( -- number ) HEX: 1026 ; inline
-: AL_SOURCE_TYPE ( -- number ) HEX: 1027 ; inline
-: AL_STATIC ( -- number ) HEX: 1028 ; inline
-: AL_STREAMING ( -- number ) HEX: 1029 ; inline
-: AL_UNDETERMINED ( -- number ) HEX: 1030 ; inline
-: AL_FORMAT_MONO8 ( -- number ) HEX: 1100 ; inline
-: AL_FORMAT_MONO16 ( -- number ) HEX: 1101 ; inline
-: AL_FORMAT_STEREO8 ( -- number ) HEX: 1102 ; inline
-: AL_FORMAT_STEREO16 ( -- number ) HEX: 1103 ; inline
-: AL_REFERENCE_DISTANCE ( -- number ) HEX: 1020 ; inline
-: AL_ROLLOFF_FACTOR ( -- number ) HEX: 1021 ; inline
-: AL_CONE_OUTER_GAIN ( -- number ) HEX: 1022 ; inline
-: AL_MAX_DISTANCE ( -- number ) HEX: 1023 ; inline
-: AL_FREQUENCY ( -- number ) HEX: 2001 ; inline
-: AL_BITS ( -- number ) HEX: 2002 ; inline
-: AL_CHANNELS ( -- number ) HEX: 2003 ; inline
-: AL_SIZE ( -- number ) HEX: 2004 ; inline
-: AL_UNUSED ( -- number ) HEX: 2010 ; inline
-: AL_PENDING ( -- number ) HEX: 2011 ; inline
-: AL_PROCESSED ( -- number ) HEX: 2012 ; inline
-: AL_NO_ERROR ( -- number ) AL_FALSE ; inline
-: AL_INVALID_NAME ( -- number ) HEX: A001 ; inline
-: AL_ILLEGAL_ENUM ( -- number ) HEX: A002 ; inline
-: AL_INVALID_ENUM ( -- number ) HEX: A002 ; inline
-: AL_INVALID_VALUE ( -- number ) HEX: A003 ; inline
-: AL_ILLEGAL_COMMAND ( -- number ) HEX: A004 ; inline
-: AL_INVALID_OPERATION ( -- number ) HEX: A004 ; inline
-: AL_OUT_OF_MEMORY ( -- number ) HEX: A005 ; inline
-: AL_VENDOR ( -- number ) HEX: B001 ; inline
-: AL_VERSION ( -- number ) HEX: B002 ; inline
-: AL_RENDERER ( -- number ) HEX: B003 ; inline
-: AL_EXTENSIONS ( -- number ) HEX: B004 ; inline
-: AL_DOPPLER_FACTOR ( -- number ) HEX: C000 ; inline
-: AL_DOPPLER_VELOCITY ( -- number ) HEX: C001 ; inline
-: AL_SPEED_OF_SOUND ( -- number ) HEX: C003 ; inline
-: AL_DISTANCE_MODEL ( -- number ) HEX: D000 ; inline
-: AL_INVERSE_DISTANCE ( -- number ) HEX: D001 ; inline
-: AL_INVERSE_DISTANCE_CLAMPED ( -- number ) HEX: D002 ; inline
-: AL_LINEAR_DISTANCE ( -- number ) HEX: D003 ; inline
-: AL_LINEAR_DISTANCE_CLAMPED ( -- number ) HEX: D004 ; inline
-: AL_EXPONENT_DISTANCE ( -- number ) HEX: D005 ; inline
-: AL_EXPONENT_DISTANCE_CLAMPED ( -- number ) HEX: D006 ; inline
-
-FUNCTION: void alEnable ( ALenum capability ) ;
-FUNCTION: void alDisable ( ALenum capability ) ; 
-FUNCTION: ALboolean alIsEnabled ( ALenum capability ) ; 
-FUNCTION: ALchar* alGetString ( ALenum param ) ;
-FUNCTION: void alGetBooleanv ( ALenum param, ALboolean* data ) ;
-FUNCTION: void alGetIntegerv ( ALenum param, ALint* data ) ;
-FUNCTION: void alGetFloatv ( ALenum param, ALfloat* data ) ;
-FUNCTION: void alGetDoublev ( ALenum param, ALdouble* data ) ;
-FUNCTION: ALboolean alGetBoolean ( ALenum param ) ;
-FUNCTION: ALint alGetInteger ( ALenum param ) ;
-FUNCTION: ALfloat alGetFloat ( ALenum param ) ;
-FUNCTION: ALdouble alGetDouble ( ALenum param ) ;
-FUNCTION: ALenum alGetError (  ) ;
-FUNCTION: ALboolean alIsExtensionPresent ( ALchar* extname ) ;
-FUNCTION: void* alGetProcAddress ( ALchar* fname ) ;
-FUNCTION: ALenum alGetEnumValue ( ALchar* ename ) ;
-FUNCTION: void alListenerf ( ALenum param, ALfloat value ) ;
-FUNCTION: void alListener3f ( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alListenerfv ( ALenum param, ALfloat* values ) ; 
-FUNCTION: void alListeneri ( ALenum param, ALint value ) ;
-FUNCTION: void alListener3i ( ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alListeneriv ( ALenum param, ALint* values ) ;
-FUNCTION: void alGetListenerf ( ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetListener3f ( ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) ;
-FUNCTION: void alGetListenerfv ( ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetListeneri ( ALenum param, ALint* value ) ;
-FUNCTION: void alGetListener3i ( ALenum param, ALint* value1, ALint* value2, ALint* value3 ) ;
-FUNCTION: void alGetListeneriv ( ALenum param, ALint* values ) ;
-FUNCTION: void alGenSources ( ALsizei n, ALuint* sources ) ; 
-FUNCTION: void alDeleteSources ( ALsizei n, ALuint* sources ) ;
-FUNCTION: ALboolean alIsSource ( ALuint sid ) ; 
-FUNCTION: void alSourcef ( ALuint sid, ALenum param, ALfloat value ) ; 
-FUNCTION: void alSource3f ( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ; 
-FUNCTION: void alSourcei ( ALuint sid, ALenum param, ALint value ) ; 
-FUNCTION: void alSource3i ( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alSourceiv ( ALuint sid, ALenum param, ALint* values ) ;
-FUNCTION: void alGetSourcef ( ALuint sid, ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetSource3f ( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
-FUNCTION: void alGetSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetSourcei ( ALuint sid,  ALenum param, ALint* value ) ;
-FUNCTION: void alGetSource3i ( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
-FUNCTION: void alGetSourceiv ( ALuint sid,  ALenum param, ALint* values ) ;
-FUNCTION: void alSourcePlayv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourceStopv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourceRewindv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourcePausev ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourcePlay ( ALuint sid ) ;
-FUNCTION: void alSourceStop ( ALuint sid ) ;
-FUNCTION: void alSourceRewind ( ALuint sid ) ;
-FUNCTION: void alSourcePause ( ALuint sid ) ;
-FUNCTION: void alSourceQueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
-FUNCTION: void alSourceUnqueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
-FUNCTION: void alGenBuffers ( ALsizei n, ALuint* buffers ) ;
-FUNCTION: void alDeleteBuffers ( ALsizei n, ALuint* buffers ) ;
-FUNCTION: ALboolean alIsBuffer ( ALuint bid ) ;
-FUNCTION: void alBufferData ( ALuint bid, ALenum format, void* data, ALsizei size, ALsizei freq ) ;
-FUNCTION: void alBufferf ( ALuint bid, ALenum param, ALfloat value ) ;
-FUNCTION: void alBuffer3f ( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alBufferi ( ALuint bid, ALenum param, ALint value ) ;
-FUNCTION: void alBuffer3i ( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
-FUNCTION: void alGetBufferf ( ALuint bid, ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetBuffer3f ( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
-FUNCTION: void alGetBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetBufferi ( ALuint bid, ALenum param, ALint* value ) ;
-FUNCTION: void alGetBuffer3i ( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
-FUNCTION: void alGetBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
-FUNCTION: void alDopplerFactor ( ALfloat value ) ;
-FUNCTION: void alDopplerVelocity ( ALfloat value ) ;
-FUNCTION: void alSpeedOfSound ( ALfloat value ) ;
-FUNCTION: void alDistanceModel ( ALenum distanceModel ) ;
-
-LIBRARY: alut
-
-: ALUT_API_MAJOR_VERSION ( -- number ) 1 ; inline
-: ALUT_API_MINOR_VERSION ( -- number ) 1 ; inline
-: ALUT_ERROR_NO_ERROR ( -- number ) 0 ; inline
-: ALUT_ERROR_OUT_OF_MEMORY ( -- number ) HEX: 200 ; inline
-: ALUT_ERROR_INVALID_ENUM ( -- number ) HEX: 201 ; inline
-: ALUT_ERROR_INVALID_VALUE ( -- number ) HEX: 202 ; inline
-: ALUT_ERROR_INVALID_OPERATION ( -- number ) HEX: 203 ; inline
-: ALUT_ERROR_NO_CURRENT_CONTEXT ( -- number ) HEX: 204 ; inline
-: ALUT_ERROR_AL_ERROR_ON_ENTRY ( -- number ) HEX: 205 ; inline
-: ALUT_ERROR_ALC_ERROR_ON_ENTRY ( -- number ) HEX: 206 ; inline
-: ALUT_ERROR_OPEN_DEVICE ( -- number ) HEX: 207 ; inline
-: ALUT_ERROR_CLOSE_DEVICE ( -- number ) HEX: 208 ; inline
-: ALUT_ERROR_CREATE_CONTEXT ( -- number ) HEX: 209 ; inline
-: ALUT_ERROR_MAKE_CONTEXT_CURRENT ( -- number ) HEX: 20A ; inline
-: ALUT_ERROR_DESTRY_CONTEXT ( -- number ) HEX: 20B ; inline
-: ALUT_ERROR_GEN_BUFFERS ( -- number ) HEX: 20C ; inline
-: ALUT_ERROR_BUFFER_DATA ( -- number ) HEX: 20D ; inline
-: ALUT_ERROR_IO_ERROR ( -- number ) HEX: 20E ; inline
-: ALUT_ERROR_UNSUPPORTED_FILE_TYPE ( -- number ) HEX: 20F ; inline
-: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE ( -- number ) HEX: 210 ; inline
-: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA ( -- number ) HEX: 211 ; inline
-: ALUT_WAVEFORM_SINE ( -- number ) HEX: 100 ; inline
-: ALUT_WAVEFORM_SQUARE ( -- number ) HEX: 101 ; inline
-: ALUT_WAVEFORM_SAWTOOTH ( -- number ) HEX: 102 ; inline
-: ALUT_WAVEFORM_WHITENOISE ( -- number ) HEX: 103 ; inline
-: ALUT_WAVEFORM_IMPULSE ( -- number ) HEX: 104 ; inline
-: ALUT_LOADER_BUFFER ( -- number ) HEX: 300 ; inline
-: ALUT_LOADER_MEMORY ( -- number ) HEX: 301 ; inline
-
-FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutExit ( ) ;
-FUNCTION: ALenum alutGetError ( ) ;
-FUNCTION: char* alutGetErrorString ( ALenum error ) ;
-FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
-FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
-FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
-FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
-FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
-FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
-FUNCTION: ALint alutGetMajorVersion ( ) ;
-FUNCTION: ALint alutGetMinorVersion ( ) ;
-FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
-
-FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
-
-SYMBOL: init
-
-: init-openal ( -- )
-  init get-global expired? [
-    f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
-    1337 <alien> init set-global
-  ] when ;
-
-: exit-openal ( -- )
-  init get-global expired? [
-    alutExit 0 = [ "Could not close OpenAL" throw ] when
-    f init set-global
-  ] unless ;
-
-: <uint-array> ( n -- byte-array ) "ALuint" <c-array> ;
-
-: gen-sources ( size -- seq )
-  dup <uint-array> 2dup alGenSources swap c-uint-array> ;
-
-: gen-buffers ( size -- seq )
-  dup <uint-array> 2dup alGenBuffers swap c-uint-array> ;
-
-: gen-buffer ( -- buffer ) 1 gen-buffers first ;
-
-: create-buffer-from-file ( filename -- buffer )
-  alutCreateBufferFromFile dup AL_NONE = [
-    "create-buffer-from-file failed" throw
-  ] when ;
-
-os macosx? "openal.macosx" "openal.other" ? require
-
-: create-buffer-from-wav ( filename -- buffer )
-  gen-buffer dup rot load-wav-file
-  [ alBufferData ] 4keep alutUnloadWAV ;
-
-: queue-buffers ( source buffers -- )
-    [ length ] [ >c-uint-array ] bi alSourceQueueBuffers ;
-
-: queue-buffer ( source buffer -- )
-    1array queue-buffers ;
-
-: set-source-param ( source param value -- )
-  alSourcei ;
-
-: get-source-param ( source param -- value )
-  0 <uint> dup >r alGetSourcei r> *uint ;
-
-: set-buffer-param ( source param value -- )
-  alBufferi ;
-
-: get-buffer-param ( source param -- value )
-  0 <uint> dup >r alGetBufferi r> *uint ;
-
-: source-play ( source -- )
-  alSourcePlay ;
-
-: source-stop ( source -- )
-  alSourceStop ;
-
-: check-error ( -- )
-  alGetError dup ALUT_ERROR_NO_ERROR = [
-    drop
-  ] [
-    alGetString throw
-  ] if ;
-
-: source-playing? ( source -- bool )
-  AL_SOURCE_STATE get-source-param AL_PLAYING = ;
diff --git a/extra/openal/other/authors.txt b/extra/openal/other/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/openal/other/other.factor b/extra/openal/other/other.factor
deleted file mode 100644 (file)
index d0429fb..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: openal.backend alien.c-types kernel alien alien.syntax
-shuffle combinators.lib ;
-IN: openal.other
-
-LIBRARY: alut
-
-FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency, ALboolean* looping ) ;
-
-M: object load-wav-file ( filename -- format data size frequency )
-  0 <int> f <void*> 0 <int> 0 <int>
-  [ 0 <char> alutLoadWAVFile ] 4keep
-  >r >r >r *int r> *void* r> *int r> *int ;
diff --git a/extra/openal/summary.txt b/extra/openal/summary.txt
deleted file mode 100644 (file)
index 5df8b3a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-OpenAL 3D audio library binding
diff --git a/extra/openal/tags.txt b/extra/openal/tags.txt
deleted file mode 100644 (file)
index a5b2257..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-bindings
-audio
index d52e55417ff558f3f743f851032e77cb9908a402..476bb1be7137556b3763fa907e4f489b1fa8c996 100755 (executable)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel opengl.gl alien.c-types continuations namespaces
 assocs alien alien.strings libc opengl math sequences combinators
-combinators.lib macros arrays io.encodings.ascii fry ;
+combinators.lib macros arrays io.encodings.ascii fry
+specialized-arrays.uint destructors accessors ;
 IN: opengl.shaders
 
 : with-gl-shader-source-ptr ( string quot -- )
@@ -44,9 +45,10 @@ IN: opengl.shaders
 
 : gl-shader-info-log ( shader -- log )
     dup gl-shader-info-log-length dup [
+        1 calloc &free
         [ 0 <int> swap glGetShaderInfoLog ] keep
         ascii alien>string
-    ] with-malloc ;
+    ] with-destructors ;
 
 : check-gl-shader ( shader -- shader )
     dup gl-shader-ok? [ dup gl-shader-info-log throw ] unless ;
@@ -79,9 +81,10 @@ PREDICATE: fragment-shader < gl-shader (fragment-shader?) ;
 
 : gl-program-info-log ( program -- log )
     dup gl-program-info-log-length dup [
+        1 calloc &free
         [ 0 <int> swap glGetProgramInfoLog ] keep
         ascii alien>string
-    ] with-malloc ;
+    ] with-destructors ;
 
 : check-gl-program ( program -- program )
     dup gl-program-ok? [ dup gl-program-info-log throw ] unless ;
@@ -91,10 +94,9 @@ PREDICATE: fragment-shader < gl-shader (fragment-shader?) ;
 
 : gl-program-shaders ( program -- shaders )
     dup gl-program-shaders-length
-    dup "GLuint" <c-array>
-    0 <int> swap
-    [ glGetAttachedShaders ] { 3 1 } multikeep
-    c-uint-array> ;
+    0 <int>
+    over <uint-array>
+    [ underlying>> glGetAttachedShaders ] keep ;
 
 : delete-gl-program-only ( program -- )
     glDeleteProgram ; inline
diff --git a/extra/pong/pong.factor b/extra/pong/pong.factor
new file mode 100644 (file)
index 0000000..befb64a
--- /dev/null
@@ -0,0 +1,195 @@
+
+USING: kernel accessors locals math math.intervals math.order
+       namespaces sequences threads
+       ui
+       ui.gadgets
+       ui.gestures
+       ui.render
+       calendar
+       multi-methods
+       multi-method-syntax
+       combinators.short-circuit.smart
+       combinators.cleave.enhanced
+       processing.shapes
+       flatland ;
+
+IN: pong
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: clamp-to-interval ( x interval -- x )
+  [ from>> first max ] [ to>> first min ] bi ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <play-field> < <rectangle>    ;
+TUPLE: <paddle>     < <rectangle>    ;
+
+TUPLE: <computer>   < <paddle> { speed initial: 10 } ;
+
+: computer-move-left  ( computer -- ) dup speed>> move-left-by  ;
+: computer-move-right ( computer -- ) dup speed>> move-right-by ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <ball> < <vel>
+  { diameter   initial: 20   }
+  { bounciness initial:  1.2 }
+  { max-speed  initial: 10   } ;
+
+: above-lower-bound? ( ball field -- ? ) bottom 50 - above? ;
+: below-upper-bound? ( ball field -- ? ) top    50 + below? ;
+
+: in-bounds? ( ball field -- ? )
+  {
+    [ above-lower-bound? ]
+    [ below-upper-bound? ]
+  } && ;
+
+:: bounce-change-vertical-velocity ( BALL -- )
+
+  BALL vel>> y neg
+  BALL bounciness>> *
+
+  BALL max-speed>> min
+
+  BALL vel>> (y!) ;
+
+:: bounce-off-paddle ( BALL PADDLE -- )
+
+   BALL bounce-change-vertical-velocity
+
+   BALL x   PADDLE center x   -   0.25 *   BALL vel>> (x!)
+
+   PADDLE top   BALL pos>> (y!) ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: mouse-x ( -- x ) hand-loc get first ;
+
+:: valid-paddle-interval ( PADDLE PLAY-FIELD -- interval )
+    
+   PLAY-FIELD [ left ] [ right ] bi PADDLE width - [a,b] ;
+
+:: align-paddle-with-mouse ( PADDLE PLAY-FIELD -- )
+
+   mouse-x
+
+   PADDLE PLAY-FIELD valid-paddle-interval
+
+   clamp-to-interval
+
+   PADDLE pos>> (x!) ;
+   
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Protocol for drawing PONG objects
+
+GENERIC: draw ( obj -- )
+
+METHOD: draw ( <paddle> -- ) [ bottom-left ] [ dim>>          ] bi rectangle ;
+METHOD: draw ( <ball>   -- ) [ pos>>       ] [ diameter>> 2 / ] bi circle    ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USE: syntax ! Switch back to core 'TUPLE:' instead of the one provided
+            ! by multi-methods
+
+TUPLE: <pong> < gadget draw closed ;
+
+M: <pong> pref-dim*    ( <pong> -- dim ) drop { 400 400 } ;
+M: <pong> draw-gadget* ( <pong> --     ) draw>> call      ;
+M: <pong> ungraft*     ( <pong> --     ) t >>closed drop  ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-draw-closure ( -- closure )
+
+  ! Establish some bindings
+
+  [let | PLAY-FIELD [ T{ <play-field> { pos {  0  0 } } { dim { 400 400 } } } ]
+         BALL       [ T{ <ball>       { pos { 50 50 } } { vel {   3   4 } } } ]
+
+         PLAYER   [ T{ <paddle>   { pos { 200 396 } } { dim { 75 4 } } } ]
+         COMPUTER [ T{ <computer> { pos { 200   0 } } { dim { 75 4 } } } ] |
+
+    ! Define some internal words in terms of those bindings ...
+
+    [wlet | align-player-with-mouse [ ( -- )
+              PLAYER PLAY-FIELD align-paddle-with-mouse ]
+
+            move-ball [ ( -- ) BALL 1 move-for ]
+
+            player-blocked-ball? [ ( -- ? )
+              BALL PLAYER { [ above? ] [ in-between-horizontally? ] } && ]
+
+            computer-blocked-ball? [ ( -- ? )
+              BALL COMPUTER { [ below? ] [ in-between-horizontally? ] } && ]
+
+            bounce-off-wall? [ ( -- ? )
+              BALL PLAY-FIELD in-between-horizontally? not ] |
+
+      ! Note, we're returning a quotation.
+      ! The quotation closes over the bindings established by the 'let'.
+      ! Thus the name of the word 'make-draw-closure'.
+      ! This closure is intended to be placed in the 'draw' slot of a
+      ! <pong> gadget.
+      
+      [
+
+        BALL PLAY-FIELD in-bounds?
+          [
+            align-player-with-mouse
+              
+            move-ball
+  
+            ! computer reaction
+  
+            BALL COMPUTER to-the-left-of?  [ COMPUTER computer-move-left  ] when
+            BALL COMPUTER to-the-right-of? [ COMPUTER computer-move-right ] when
+
+            ! check if ball bounced off something
+              
+            player-blocked-ball?   [ BALL PLAYER   bounce-off-paddle  ] when
+            computer-blocked-ball? [ BALL COMPUTER bounce-off-paddle  ] when
+            bounce-off-wall?       [ BALL reverse-horizontal-velocity ] when
+
+            ! draw the objects
+              
+            COMPUTER draw
+            PLAYER   draw
+            BALL     draw
+  
+          ]
+        when
+
+      ] ] ] ( -- closure ) ; ! The trailing stack effect here is a workaround.
+                             ! The stack effects in the wlet expression throw
+                             ! off the effect for the whole word, so we reset
+                             ! it to the correct one here.
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: pong-loop-step ( PONG -- ? )
+  PONG closed>>
+    [ f ]
+    [ PONG relayout-1 25 milliseconds sleep t ]
+  if ;
+
+:: start-pong-thread ( PONG -- ) [ [ PONG pong-loop-step ] loop ] in-thread ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: play-pong ( -- )
+
+  <pong> new-gadget
+    make-draw-closure >>draw
+  dup "PONG" open-window
+    
+  start-pong-thread ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: play-pong-main ( -- ) [ play-pong ] with-ui ;
+
+MAIN: play-pong-main
\ No newline at end of file
index 0120891e1294dc34e81a03e1de3ff95a25b97720..ac02efba693eff48a2386df5c5a2a7b1ecbd78c7 100644 (file)
@@ -28,7 +28,7 @@ IN: printf
     [ 0 ] [ string>number ] if-empty ;
 
 : pad-digits ( string digits -- string' )
-    [ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." swap 3append ;
+    [ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." glue ;
 
 : max-digits ( n digits -- n' )
     10 swap ^ [ * round ] keep / ;
index a530be64fa5fce4988d565e36ede58523cef0957..51979dc96acc3c020ac02b0ca1ec1a4bee4ed26a 100644 (file)
@@ -2,13 +2,17 @@
 USING: kernel namespaces arrays sequences grouping
        alien.c-types
        math math.vectors math.geometry.rect
-       opengl.gl opengl.glu opengl.demo-support opengl generalizations vars
+       opengl.gl opengl.glu opengl generalizations vars
        combinators.cleave colors ;
 
 IN: processing.shapes
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+: do-state ( mode quot -- ) swap glBegin call glEnd ; inline
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
 VAR: fill-color
 VAR: stroke-color
 
index bb0251858071d66df3cb41c4b3840e9d77daa1d5..46015bee3edb82112343a09a1bb705650eda2ded 100644 (file)
@@ -3,3 +3,4 @@ IN: project-euler.002.tests
 
 [ 4613732 ] [ euler002 ] unit-test
 [ 4613732 ] [ euler002a ] unit-test
+[ 4613732 ] [ euler002b ] unit-test
index fae535cba9dfaaf39b9290959b520f7c54585bc3..da20c874b5c5bb150619ccc89d2c427383f0b82d 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2007 Aaron Schaefer, Alexander Solovyov.
+! Copyright (c) 2007, 2008 Aaron Schaefer, Alexander Solovyov, Vishal Talwar.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math sequences shuffle ;
 IN: project-euler.002
@@ -50,4 +50,31 @@ PRIVATE>
 ! [ euler002a ] 100 ave-time
 ! 0 ms ave run time - 0.2 SD (100 trials)
 
-MAIN: euler002a
+
+<PRIVATE
+
+: next-fibs ( x y -- y x+y )
+    tuck + ;
+
+: ?retotal ( total fib- fib+ -- retotal fib- fib+ )
+    dup even? [ [ nip + ] 2keep ] when ;
+
+: (sum-even-fibs-below) ( partial fib- fib+ max -- total )
+    2dup > [
+        3drop
+    ] [
+        [ ?retotal next-fibs ] dip (sum-even-fibs-below)
+    ] if ;
+
+PRIVATE>
+
+: sum-even-fibs-below ( max -- sum )
+    [ 0 0 1 ] dip (sum-even-fibs-below) ;
+
+: euler002b ( -- answer )
+    4000000 sum-even-fibs-below ;
+
+! [ euler002b ] 100 ave-time
+! 0 ms ave run time - 0.0 SD (100 trials)
+
+MAIN: euler002b
diff --git a/extra/project-euler/050/050-tests.factor b/extra/project-euler/050/050-tests.factor
new file mode 100644 (file)
index 0000000..2bd5482
--- /dev/null
@@ -0,0 +1,6 @@
+USING: project-euler.050 project-euler.050.private tools.test ;
+IN: project-euler.050.tests
+
+[ 41 ] [ 100 solve ] unit-test
+[ 953 ] [ 1000 solve ] unit-test
+[ 997651 ] [ euler050 ] unit-test
diff --git a/extra/project-euler/050/050.factor b/extra/project-euler/050/050.factor
new file mode 100644 (file)
index 0000000..f8ce68d
--- /dev/null
@@ -0,0 +1,90 @@
+! Copyright (c) 2008 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays kernel locals math math.primes sequences ;
+IN: project-euler.050
+
+! http://projecteuler.net/index.php?section=problems&id=50
+
+! DESCRIPTION
+! -----------
+
+! The prime 41, can be written as the sum of six consecutive primes:
+
+!     41 = 2 + 3 + 5 + 7 + 11 + 13
+
+! This is the longest sum of consecutive primes that adds to a prime below
+! one-hundred.
+
+! The longest sum of consecutive primes below one-thousand that adds to a
+! prime, contains 21 terms, and is equal to 953.
+
+! Which prime, below one-million, can be written as the sum of the most
+! consecutive primes?
+
+
+! SOLUTION
+! --------
+
+! 1) Create an sequence of all primes under 1000000.
+! 2) Start summing elements in the sequence until the next number would put you
+!    over 1000000.
+! 3) Check if that sum is prime, if not, subtract the last number added.
+! 4) Repeat step 3 until you get a prime number, and store it along with the
+!    how many consecutive numbers from the original sequence it took to get there.
+! 5) Drop the first number from the sequence of primes, and do steps 2-4 again
+! 6) Compare the longest chain from the first run with the second run, and store
+!    the longer of the two.
+! 7) If the sequence of primes is still longer than the longest chain, then
+!    repeat steps 5-7...otherwise, you've found the longest sum of consecutive
+!    primes!
+
+<PRIVATE
+
+:: sum-upto ( seq limit -- length sum )
+    0 seq [ + dup limit > ] find
+    [ swapd - ] [ drop seq length swap ] if* ;
+
+: pop-until-prime ( seq sum -- seq prime )
+    over length 0 > [
+        [ unclip-last-slice ] dip swap -
+        dup prime? [ pop-until-prime ] unless
+    ] [
+        2drop { } 0
+    ] if ;
+
+! a pair is { length of chain, prime the chain sums to }
+
+: longest-prime ( seq limit -- pair )
+    dupd sum-upto dup prime? [
+        2array nip
+    ] [
+        [ head-slice ] dip pop-until-prime
+        [ length ] dip 2array
+    ] if ;
+
+: longest ( pair pair -- longest )
+    2dup [ first ] bi@ > [ drop ] [ nip ] if ;
+
+: continue? ( pair seq -- ? )
+    [ first ] [ length 1- ] bi* < ;
+
+: (find-longest) ( best seq limit -- best )
+    [ longest-prime longest ] 2keep 2over continue? [
+        [ rest-slice ] dip (find-longest)
+    ] [ 2drop ] if ;
+
+: find-longest ( seq limit -- best )
+    { 1 2 } -rot (find-longest) ;
+
+: solve ( n -- answer )
+    [ primes-upto ] keep find-longest second ;
+
+PRIVATE>
+
+: euler050 ( -- answer )
+    1000000 solve ;
+
+! [ euler050 ] 100 ave-time
+! 291 ms run / 20.6 ms GC ave time - 100 trials
+
+MAIN: euler050
index f176bbc7d2782b6bec5feb34268137fb1330e82d..a7762836f19bbe23b00d1e53607d70d2bac89b44 100644 (file)
@@ -1,21 +1,24 @@
-! Copyright (c) 2007 Aaron Schaefer.
+! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations fry io kernel make math math.functions math.parser
     math.statistics memory tools.time ;
 IN: project-euler.ave-time
 
+: nth-place ( x n -- y )
+    10 swap ^ [ * round >integer ] keep /f ;
+
 : collect-benchmarks ( quot n -- seq )
     [
         [ datastack ]
-        [ '[ _ gc benchmark , ] tuck '[ _ _ with-datastack drop ] ]
+        [
+            '[ _ gc benchmark 1000 / , ] tuck
+            '[ _ _ with-datastack drop ]
+        ]
         [ 1- ] tri* swap times call
     ] { } make ; inline
 
-: nth-place ( x n -- y )
-    10 swap ^ [ * round ] keep / ;
-
 : ave-time ( quot n -- )
     [ collect-benchmarks ] keep swap
-    [ std 2 nth-place ] [ mean round ] bi [
+    [ std 2 nth-place ] [ mean round >integer ] bi [
         # " ms ave run time - " % # " SD (" % # " trials)" %
     ] "" make print flush ; inline
diff --git a/extra/sequences/complex-components/authors.txt b/extra/sequences/complex-components/authors.txt
new file mode 100644 (file)
index 0000000..f13c9c1
--- /dev/null
@@ -0,0 +1 @@
+Joe Groff
diff --git a/extra/sequences/complex-components/complex-components-docs.factor b/extra/sequences/complex-components/complex-components-docs.factor
new file mode 100644 (file)
index 0000000..386735a
--- /dev/null
@@ -0,0 +1,35 @@
+USING: help.markup help.syntax math multiline
+sequences sequences.complex-components ;
+IN: sequences.complex-components
+
+ARTICLE: "sequences.complex-components" "Complex component virtual sequences"
+"The " { $link complex-components } " class wraps a sequence of " { $link complex } " number values, presenting a sequence of " { $link real } " values made by interleaving the real and imaginary parts of the complex values in the original sequence."
+{ $subsection complex-components }
+{ $subsection <complex-components> } ;
+
+ABOUT: "sequences.complex-components"
+
+HELP: complex-components
+{ $class-description "Sequence wrapper class that transforms a sequence of " { $link complex } " number values into a sequence of " { $link real } " values, interleaving the real and imaginary parts of the complex values in the original sequence." }
+{ $examples { $example <"
+USING: prettyprint sequences arrays sequences.complex-components ;
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> >array .
+"> "{ 1.0 -1.0 -2.0 0 3.0 1.0 }" } } ;
+
+HELP: <complex-components>
+{ $values { "sequence" sequence } { "complex-components" complex-components } }
+{ $description "Wraps " { $snippet "sequence" } " in a " { $link complex-components } " wrapper." }
+{ $examples
+{ $example <"
+USING: prettyprint sequences arrays
+sequences.complex-components ;
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> third .
+"> "-2.0" }
+{ $example <"
+USING: prettyprint sequences arrays
+sequences.complex-components ;
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> fourth .
+"> "0" }
+} ;
+
+{ complex-components <complex-components> } related-words
diff --git a/extra/sequences/complex-components/complex-components-tests.factor b/extra/sequences/complex-components/complex-components-tests.factor
new file mode 100644 (file)
index 0000000..f0c8e92
--- /dev/null
@@ -0,0 +1,16 @@
+USING: sequences.complex-components
+kernel sequences tools.test arrays accessors ;
+IN: sequences.complex-components.tests
+
+: test-array ( -- x )
+    { C{ 1.0 2.0 } 3.0 C{ 5.0 6.0 } } <complex-components> ;
+
+[ 6 ] [ test-array length ] unit-test
+
+[ 1.0 ] [ test-array first  ] unit-test
+[ 2.0 ] [ test-array second ] unit-test
+[ 3.0 ] [ test-array third  ] unit-test
+[ 0   ] [ test-array fourth ] unit-test
+
+[ { 1.0 2.0 3.0 0 5.0 6.0 } ] [ test-array >array ] unit-test
+
diff --git a/extra/sequences/complex-components/complex-components.factor b/extra/sequences/complex-components/complex-components.factor
new file mode 100644 (file)
index 0000000..ae80897
--- /dev/null
@@ -0,0 +1,28 @@
+USING: accessors kernel math math.functions combinators
+sequences sequences.private ;
+IN: sequences.complex-components
+
+TUPLE: complex-components seq ;
+INSTANCE: complex-components sequence
+
+: <complex-components> ( sequence -- complex-components )
+    complex-components boa ; inline
+
+<PRIVATE
+
+: complex-components@ ( n seq -- remainder n' seq' )
+    [ [ 1 bitand ] [ -1 shift ] bi ] [ seq>> ] bi* ; inline
+: complex-component ( remainder complex -- component )
+    swap {
+        { 0 [ real-part ] }
+        { 1 [ imaginary-part ] }
+    } case ;
+
+PRIVATE>
+
+M: complex-components length
+    seq>> length 1 shift ;
+M: complex-components nth-unsafe
+    complex-components@ nth-unsafe complex-component ;
+M: complex-components set-nth-unsafe
+    immutable ;
diff --git a/extra/sequences/complex-components/summary.txt b/extra/sequences/complex-components/summary.txt
new file mode 100644 (file)
index 0000000..af00158
--- /dev/null
@@ -0,0 +1 @@
+Virtual sequence wrapper to convert complex values into real value pairs
diff --git a/extra/sequences/complex-components/tags.txt b/extra/sequences/complex-components/tags.txt
new file mode 100644 (file)
index 0000000..64cdcd9
--- /dev/null
@@ -0,0 +1,2 @@
+sequences
+math
diff --git a/extra/sequences/complex/authors.txt b/extra/sequences/complex/authors.txt
new file mode 100644 (file)
index 0000000..f13c9c1
--- /dev/null
@@ -0,0 +1 @@
+Joe Groff
diff --git a/extra/sequences/complex/complex-docs.factor b/extra/sequences/complex/complex-docs.factor
new file mode 100644 (file)
index 0000000..65dd520
--- /dev/null
@@ -0,0 +1,31 @@
+USING: help.markup help.syntax math multiline
+sequences sequences.complex ;
+IN: sequences.complex
+
+ARTICLE: "sequences.complex" "Complex virtual sequences"
+"The " { $link complex-sequence } " class wraps a sequence of " { $link real } " number values, presenting a sequence of " { $link complex } " values made by treating the underlying sequence as pairs of alternating real and imaginary values."
+{ $subsection complex-sequence }
+{ $subsection <complex-sequence> } ;
+
+ABOUT: "sequences.complex"
+
+HELP: complex-sequence
+{ $class-description "Sequence wrapper class that transforms a sequence of " { $link real } " number values into a sequence of " { $link complex } " values, treating the underlying sequence as pairs of alternating real and imaginary values."  }
+{ $examples { $example <"
+USING: prettyprint
+specialized-arrays.double sequences.complex
+sequences arrays ;
+double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> >array .
+"> "{ C{ 1.0 -1.0 } C{ -2.0 2.0 } C{ 3.0 0.0 } }" } } ;
+
+HELP: <complex-sequence>
+{ $values { "sequence" sequence } { "complex-sequence" complex-sequence } }
+{ $description "Wraps " { $snippet "sequence" } " in a " { $link complex-sequence } "." }
+{ $examples { $example <"
+USING: prettyprint
+specialized-arrays.double sequences.complex
+sequences arrays ;
+double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> second .
+"> "C{ -2.0 2.0 }" } } ;
+
+{ complex-sequence <complex-sequence> } related-words
diff --git a/extra/sequences/complex/complex-tests.factor b/extra/sequences/complex/complex-tests.factor
new file mode 100644 (file)
index 0000000..5861bc8
--- /dev/null
@@ -0,0 +1,26 @@
+USING: specialized-arrays.float sequences.complex
+kernel sequences tools.test arrays accessors ;
+IN: sequences.complex.tests
+
+: test-array ( -- x )
+    float-array{ 1.0 2.0 3.0 4.0 } clone <complex-sequence> ;
+: odd-length-test-array ( -- x )
+    float-array{ 1.0 2.0 3.0 4.0 5.0 } clone <complex-sequence> ;
+
+[ 2 ] [ test-array length ] unit-test
+[ 2 ] [ odd-length-test-array length ] unit-test
+
+[ C{ 1.0 2.0 } ] [ test-array first ] unit-test
+[ C{ 3.0 4.0 } ] [ test-array second ] unit-test
+
+[ { C{ 1.0 2.0 } C{ 3.0 4.0 } } ]
+[ test-array >array ] unit-test
+
+[ float-array{ 1.0 2.0 5.0 6.0 } ]
+[ test-array [ C{ 5.0 6.0 } 1 rot set-nth ] [ seq>> ] bi ]
+unit-test
+
+[ float-array{ 7.0 0.0 3.0 4.0 } ]
+[ test-array [ 7.0 0 rot set-nth ] [ seq>> ] bi ]
+unit-test
+
diff --git a/extra/sequences/complex/complex.factor b/extra/sequences/complex/complex.factor
new file mode 100644 (file)
index 0000000..93f9727
--- /dev/null
@@ -0,0 +1,25 @@
+USING: accessors kernel math math.functions
+sequences sequences.private ;
+IN: sequences.complex
+
+TUPLE: complex-sequence seq ;
+INSTANCE: complex-sequence sequence
+
+: <complex-sequence> ( sequence -- complex-sequence )
+    complex-sequence boa ; inline
+
+<PRIVATE
+
+: complex@ ( n seq -- n' seq' )
+    [ 1 shift ] [ seq>> ] bi* ; inline
+
+PRIVATE>
+
+M: complex-sequence length
+    seq>> length -1 shift ;
+M: complex-sequence nth-unsafe
+    complex@ [ nth-unsafe ] [ [ 1+ ] dip nth-unsafe ] 2bi rect> ;
+M: complex-sequence set-nth-unsafe
+    complex@
+    [ [ real-part      ] [    ] [ ] tri* set-nth-unsafe ]
+    [ [ imaginary-part ] [ 1+ ] [ ] tri* set-nth-unsafe ] 3bi ;
diff --git a/extra/sequences/complex/summary.txt b/extra/sequences/complex/summary.txt
new file mode 100644 (file)
index 0000000..d94c4ba
--- /dev/null
@@ -0,0 +1 @@
+Virtual sequence wrapper to convert real pairs into complex values
diff --git a/extra/sequences/complex/tags.txt b/extra/sequences/complex/tags.txt
new file mode 100644 (file)
index 0000000..64cdcd9
--- /dev/null
@@ -0,0 +1,2 @@
+sequences
+math
index 9dc01c04faea05e4b1be0121400133d938ff71bd..72944c09b4daa049a35ddb17d21b5801b3ccaf83 100755 (executable)
@@ -5,7 +5,7 @@ USING: combinators.lib kernel sequences math namespaces make
 assocs random sequences.private shuffle math.functions arrays
 math.parser math.private sorting strings ascii macros assocs.lib
 quotations hashtables math.order locals generalizations
-math.ranges random  ;
+math.ranges random fry ;
 IN: sequences.lib
 
 : each-withn ( seq quot n -- ) nwith each ; inline
@@ -23,11 +23,11 @@ IN: sequences.lib
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : each-percent ( seq quot -- )
-  >r
-  dup length
-  dup [ / ] curry
-  [ 1+ ] prepose
-  r> compose
+  [
+    dup length
+    dup [ / ] curry
+    [ 1+ ] prepose
+  ] dip compose
   2each ;                       inline
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -68,7 +68,7 @@ IN: sequences.lib
 
 : minmax ( seq -- min max )
     #! find the min and max of a seq in one pass
-    1/0. -1/0. rot [ tuck max >r min r> ] each ;
+    1/0. -1/0. rot [ tuck max [ min ] dip ] each ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -78,7 +78,7 @@ IN: sequences.lib
 
 : (monotonic-split) ( seq quot -- newseq )
     [
-        >r dup unclip suffix r>
+        [ dup unclip suffix ] dip
         v, [ pick ,, call [ v, ] unless ] curry 2each ,v
     ] { } make ;
 
@@ -88,14 +88,10 @@ IN: sequences.lib
 ERROR: element-not-found ;
 : split-around ( seq quot -- before elem after )
     dupd find over [ element-not-found ] unless
-    >r cut rest r> swap ; inline
-
-: (map-until) ( quot pred -- quot )
-    [ dup ] swap 3compose
-    [ [ drop t ] [ , f ] if ] compose [ find 2drop ] curry ;
+    [ cut rest ] dip swap ; inline
 
 : map-until ( seq quot pred -- newseq )
-    (map-until) { } make ;
+    '[ [ @ dup @ [ drop t ] [ , f ] if ] find 2drop ] { } make ;
 
 : take-while ( seq quot -- newseq )
     [ not ] compose
@@ -119,14 +115,14 @@ ERROR: element-not-found ;
 PRIVATE>
 
 : exact-strings ( alphabet length -- seqs )
-    >r dup length r> exact-number-strings map-alphabet ;
+    [ dup length ] dip exact-number-strings map-alphabet ;
 
 : strings ( alphabet length -- seqs )
-    >r dup length r> number-strings map-alphabet ;
+    [ dup length ] dip number-strings map-alphabet ;
 
 : switches ( seq1 seq -- subseq )
     ! seq1 is a sequence of ones and zeroes
-    >r [ length ] keep [ nth 1 = ] curry filter r>
+    [ [ length ] keep [ nth 1 = ] curry filter ] dip
     [ nth ] curry { } map-as ;
 
 : power-set ( seq -- subsets )
@@ -151,7 +147,3 @@ PRIVATE>
     dup length 1 (a,b] [ dup random pick exchange ] each ;
 
 : enumerate ( seq -- seq' ) <enum> >alist ;
-
-: splice ( left-seq right-seq seq -- newseq ) swap 3append ;
-
-: surround ( seq left-seq right-seq -- newseq ) swapd 3append ;
index 826c66851e048974c8b82aee0cdedb10ccf436d7..7a0c0d2e77992f562cf31924fc5cb12d77f7965f 100755 (executable)
@@ -225,8 +225,8 @@ M: spheres-gadget pref-dim* ( gadget -- dim )
         plane-program>> [
             {
                 [ "checker_size_inv" glGetUniformLocation 0.125 glUniform1f ]
-                [ "checker_color_1"  glGetUniformLocation 1.0 0.5 0.0 1.0 glUniform4f ]
-                [ "checker_color_2"  glGetUniformLocation 0.0 0.0 0.0 1.0 glUniform4f ]
+                [ "checker_color_1"  glGetUniformLocation 1.0 0.0 0.0 1.0 glUniform4f ]
+                [ "checker_color_2"  glGetUniformLocation 1.0 1.0 1.0 1.0 glUniform4f ]
             } cleave
             GL_QUADS [
                 -1000.0 -30.0  1000.0 glVertex3f
diff --git a/extra/sto/sto.factor b/extra/sto/sto.factor
new file mode 100644 (file)
index 0000000..b43c9cc
--- /dev/null
@@ -0,0 +1,20 @@
+
+USING: kernel lexer parser words quotations compiler.units ;
+
+IN: sto
+
+! Use 'sto' to bind a value on the stack to a word.
+!
+! Example:
+!
+!   10 sto A
+
+: sto
+  \ 1quotation parsed
+  scan
+    current-vocab create
+    dup set-word
+  literalize parsed
+  \ swap parsed
+  [ define ] parsed
+  \ with-compilation-unit parsed ;                              parsing
diff --git a/extra/synth/authors.txt b/extra/synth/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/synth/buffers/authors.txt b/extra/synth/buffers/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/synth/buffers/buffers.factor b/extra/synth/buffers/buffers.factor
deleted file mode 100644 (file)
index faff19d..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types combinators kernel locals math math.ranges openal sequences sequences.merged ;
-IN: synth.buffers
-
-TUPLE: buffer sample-freq 8bit? id ;
-
-: <buffer> ( sample-freq 8bit? -- buffer )
-    f buffer boa ;
-
-TUPLE: mono-buffer < buffer data ;
-
-: <mono-buffer> ( sample-freq 8bit? -- buffer )
-    f f mono-buffer boa ;
-
-: <8bit-mono-buffer> ( sample-freq -- buffer ) t <mono-buffer> ;
-: <16bit-mono-buffer> ( sample-freq -- buffer ) f <mono-buffer> ;
-
-TUPLE: stereo-buffer < buffer left-data right-data ;
-
-: <stereo-buffer> ( sample-freq 8bit? -- buffer )
-    f f f stereo-buffer boa ;
-
-: <8bit-stereo-buffer> ( sample-freq -- buffer ) t <stereo-buffer> ;
-: <16bit-stereo-buffer> ( sample-freq -- buffer ) f <stereo-buffer> ;
-
-PREDICATE: 8bit-buffer < buffer 8bit?>> ;
-PREDICATE: 16bit-buffer < buffer 8bit?>> not ;
-INTERSECTION: 8bit-mono-buffer 8bit-buffer mono-buffer ;
-INTERSECTION: 16bit-mono-buffer 16bit-buffer mono-buffer ;
-INTERSECTION: 8bit-stereo-buffer 8bit-buffer stereo-buffer ;
-INTERSECTION: 16bit-stereo-buffer 16bit-buffer stereo-buffer ;
-
-GENERIC: buffer-format ( buffer -- format )
-M: 8bit-mono-buffer buffer-format drop AL_FORMAT_MONO8 ;
-M: 16bit-mono-buffer buffer-format drop AL_FORMAT_MONO16 ;
-M: 8bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO8 ;
-M: 16bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO16 ;
-
-: 8bit-buffer-data ( seq -- data size )
-    [ 128 * >integer 128 + ] map [ >c-uchar-array ] [ length ] bi ;
-
-: 16bit-buffer-data ( seq -- data size )
-    [ 32768 * >integer ] map [ >c-short-array ] [ length 2 * ] bi ;
-
-: stereo-data ( stereo-buffer -- left right )
-    [ left-data>> ] [ right-data>> ] bi@ ;
-
-: interleaved-stereo-data ( stereo-buffer -- data )
-    stereo-data <2merged> ;
-
-GENERIC: buffer-data ( buffer -- data size )
-M: 8bit-mono-buffer buffer-data data>> 8bit-buffer-data ;
-M: 16bit-mono-buffer buffer-data data>> 16bit-buffer-data ;
-M: 8bit-stereo-buffer buffer-data
-    interleaved-stereo-data 8bit-buffer-data ;
-M: 16bit-stereo-buffer buffer-data
-    interleaved-stereo-data 16bit-buffer-data ;
-
-: telephone-sample-freq 8000 ;
-: half-sample-freq 22050 ;
-: cd-sample-freq 44100 ;
-: digital-sample-freq 48000 ;
-: professional-sample-freq 88200 ;
-
-: send-buffer ( buffer -- buffer )
-    {
-        [ gen-buffer dup [ >>id ] dip ]
-        [ buffer-format ]
-        [ buffer-data ]
-        [ sample-freq>> alBufferData ]
-    } cleave ;
-
-: ?send-buffer ( buffer -- buffer )
-    dup id>> [ send-buffer ] unless ;
-
diff --git a/extra/synth/example/authors.txt b/extra/synth/example/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/extra/synth/example/example.factor b/extra/synth/example/example.factor
deleted file mode 100644 (file)
index 747cfb9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel namespaces make openal sequences
-synth synth.buffers ;
-IN: synth.example
-
-: play-sine-wave ( freq seconds sample-freq -- )
-    init-openal
-    <16bit-mono-buffer> >sine-wave-buffer send-buffer id>>
-    1 gen-sources first
-    [ AL_BUFFER rot set-source-param ] [ source-play ] bi
-    check-error ;
-
-: test-instrument1 ( -- harmonics )
-    [
-        1 0.5 <harmonic> ,
-        2 0.125 <harmonic> ,
-        3 0.0625 <harmonic> ,
-        4 0.03125 <harmonic> ,
-    ] { } make ;
-
-: test-instrument2 ( -- harmonics )
-    [
-        1 0.25 <harmonic> ,
-        2 0.25 <harmonic> ,
-        3 0.25 <harmonic> ,
-        4 0.25 <harmonic> ,
-    ] { } make ;
-
-: sine-instrument ( -- harmonics )
-    1 1 <harmonic> 1array ;
-
-: test-note-buffer ( note -- )
-    init-openal
-    test-instrument2 swap cd-sample-freq <16bit-mono-buffer>
-    >note send-buffer id>>
-    1 gen-sources first [ swap queue-buffer ] [ source-play ] bi
-    check-error ;
diff --git a/extra/synth/summary.txt b/extra/synth/summary.txt
deleted file mode 100644 (file)
index ece5893..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Simple sound synthesis using OpenAL.
diff --git a/extra/synth/synth.factor b/extra/synth/synth.factor
deleted file mode 100644 (file)
index be1e594..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel locals math math.constants math.functions memoize openal synth.buffers sequences sequences.modified sequences.repeating ;
-IN: synth
-
-MEMO: single-sine-wave ( samples/wave -- seq )
-    pi 2 * over / [ * sin ] curry map ;
-
-: (sine-wave) ( samples/wave n-samples -- seq )
-    [ single-sine-wave ] dip <repeating> ;
-
-: sine-wave ( sample-freq freq seconds -- seq )
-    pick * >integer [ /i ] dip (sine-wave) ;
-
-: >sine-wave-buffer ( freq seconds buffer -- buffer )
-    [ sample-freq>> -rot sine-wave ] keep swap >>data ;
-
-: >silent-buffer ( seconds buffer -- buffer )
-    tuck sample-freq>> * >integer 0 <repetition> >>data ;
-
-TUPLE: harmonic n amplitude ;
-C: <harmonic> harmonic
-
-TUPLE: note hz secs ;
-C: <note> note
-
-: harmonic-freq ( note harmonic -- freq )
-    n>> swap hz>> * ;
-
-:: note-harmonic-data ( harmonic note buffer -- data )
-    buffer sample-freq>> note harmonic harmonic-freq note secs>> sine-wave
-    harmonic amplitude>> <scaled> ;
-
-: >note ( harmonics note buffer -- buffer )
-    dup -roll [ note-harmonic-data ] 2curry map <summed> >>data ;
-
index a529762c81500a2d75cbab65007d207f40c6945f..002299fef17ef281ab7be7550f0508aee4dc020e 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel money tools.test
 taxes.usa taxes.usa.federal taxes.usa.mn
-taxes.utils taxes.usa.w4 usa-cities ;
+calendar taxes.usa.w4 usa-cities ;
 IN: taxes.usa.tests
 
 [
diff --git a/extra/taxes/utils/utils.factor b/extra/taxes/utils/utils.factor
deleted file mode 100644 (file)
index a5c2240..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: math ;
-IN: taxes.utils
-
-: monthly ( x -- y ) 12 / ;
-: semimonthly ( x -- y ) 24 / ;
-: biweekly ( x -- y ) 26 / ;
-: weekly ( x -- y ) 52 / ;
-: daily ( x -- y ) 360 / ;
diff --git a/extra/ui/gadgets/plot/plot.factor b/extra/ui/gadgets/plot/plot.factor
deleted file mode 100644 (file)
index 52cd2fa..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-
-USING: kernel quotations arrays sequences math math.ranges fry
-       opengl opengl.gl ui.render ui.gadgets.cartesian processing.shapes
-       accessors ;
-
-IN: ui.gadgets.plot
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: plot < cartesian functions points ;
-
-: init-plot ( plot -- plot )
-  init-cartesian
-    { } >>functions
-    100 >>points ;
-
-: <plot> ( -- plot ) plot new init-plot ;
-
-: step-size ( plot -- step-size )
-  [ [ x-max>> ] [ x-min>> ] bi - ] [ points>> ] bi / ;
-
-: plot-range ( plot -- range )
-  [ x-min>> ] [ x-max>> ] [ step-size ] tri <range> ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: function function color ;
-
-GENERIC: plot-function ( plot object -- plot )
-
-M: callable plot-function ( plot quotation -- plot )
-  >r dup plot-range r> '[ dup @ 2array ] map line-strip ;
-
-M: function plot-function ( plot function -- plot )
-   dup color>> dup [ >stroke-color ] [ drop ] if
-   >r dup plot-range r> function>> '[ dup @ 2array ] map line-strip ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: plot-functions ( plot -- plot ) dup functions>> [ plot-function ] each ;
-
-: draw-axis ( plot -- plot )
-  dup
-    [ [ x-min>> ] [ drop 0  ] bi 2array ]
-    [ [ x-max>> ] [ drop 0  ] bi 2array ] bi line*
-  dup
-    [ [ drop 0  ] [ y-min>> ] bi 2array ]
-    [ [ drop 0  ] [ y-max>> ] bi 2array ] bi line* ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USING: ui.gadgets.slate ;
-
-M: plot draw-slate ( plot -- plot )
-   2 glLineWidth
-   draw-axis
-   plot-functions
-   fill-mode
-   1 glLineWidth ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: add-function ( plot function -- plot )
-  over functions>> swap suffix >>functions ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: x-span ( plot -- span ) [ x-max>> ] [ x-min>> ] bi - ;
-: y-span ( plot -- span ) [ y-max>> ] [ y-min>> ] bi - ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USING: ui.gestures ui.gadgets ;
-
-: left ( plot -- plot )
-  dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min
-  dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max
-  dup relayout-1 ;
-
-: right ( plot -- plot )
-  dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min
-  dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max
-  dup relayout-1 ;
-
-: down ( plot -- plot )
-  dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min
-  dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max
-  dup relayout-1 ;
-
-: up ( plot -- plot )
-  dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min
-  dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max
-  dup relayout-1 ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: zoom-in-horizontal ( plot -- plot )
-  dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min
-  dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max ;
-
-: zoom-in-vertical ( plot -- plot )
-  dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min
-  dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max ;
-
-: zoom-in ( plot -- plot )
-  zoom-in-horizontal
-  zoom-in-vertical
-  dup relayout-1 ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: zoom-out-horizontal ( plot -- plot )
-  dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min
-  dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max ;
-
-: zoom-out-vertical ( plot -- plot )
-  dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min
-  dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max ;
-
-: zoom-out ( plot -- plot )
-  zoom-out-horizontal
-  zoom-out-vertical
-  dup relayout-1 ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-plot
-  H{
-    { T{ mouse-enter } [ request-focus ] }
-    { T{ key-down f f "LEFT"  } [ left drop  ] }
-    { T{ key-down f f "RIGHT" } [ right drop ] }
-    { T{ key-down f f "DOWN"  } [ down drop  ] }
-    { T{ key-down f f "UP"    } [ up drop    ] }
-    { T{ key-down f f "a"     } [ zoom-in  drop ] }
-    { T{ key-down f f "z"     } [ zoom-out drop ] }
-  }
-set-gestures
\ No newline at end of file
index e035090fb0426b9b8b4bec46212729c13dba61c4..c16450bb251e79083b3e46fbf2d70f7549e934ff 100644 (file)
@@ -50,7 +50,7 @@ M: entity feed-entry-date date>> ;
 TUPLE: post < entity title comments ;
 
 M: post feed-entry-title
-    [ author>> ] [ title>> ] bi ": " swap 3append ;
+    [ author>> ] [ title>> ] bi ": " glue ;
 
 M: post entity-url
     id>> view-post-url ;
index 6f2c4f004250c303287ad68f5cbc9ae8943e7b83..96401b6afd65e73a0f9d3db54fbc6d68ef60e2bb 100644 (file)
@@ -2,11 +2,15 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors http.server.dispatchers
 http.server.static furnace.actions furnace.redirection urls
-validators locals io.files html.forms help.html ;
+validators locals io.files html.forms html.components help.html ;
 IN: webapps.help
 
 TUPLE: help-webapp < dispatcher ;
 
+M: result link-title title>> ;
+
+M: result link-href href>> ;
+
 :: <search-action> ( help-dir -- action )
     <page-action>
         { help-webapp "search" } >>template
index 4e22de60bcb761233099b57827907452e849744d..c2ae0f852076ba64257254f189b3c3f20f184644 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors furnace.actions http.server
-http.server.dispatchers html.forms io.servers.connection
+http.server.dispatchers html.forms io.sockets
 namespaces prettyprint ;
 IN: webapps.ip
 
index e4a4a6a853939457e5388783cd4be90b6174e332..bc429a0af6d8a8f4b5bdefca0b9cd38b975b0060 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2007 Doug Coleman.
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.ranges sequences random accessors combinators.lib
+USING: math.ranges sequences random accessors 
 kernel namespaces fry db.types db.tuples urls validators
 html.components html.forms http http.server.dispatchers furnace
-furnace.actions furnace.boilerplate furnace.redirection ;
+furnace.actions furnace.boilerplate furnace.redirection 
+furnace.utilities continuations ;
 IN: webapps.wee-url
 
 TUPLE: wee-url < dispatcher ;
index b833cc8cc2b8ae5e666e7ea100a47e458a058509..b78dc25d7997fb074d331012800c6b2e4ff7db57 100644 (file)
@@ -7,8 +7,8 @@ syndication farkup
 html.components html.forms
 http.server
 http.server.dispatchers
-furnace
 furnace.actions
+furnace.utilities
 furnace.redirection
 furnace.auth
 furnace.auth.login
index 15a9c100713c63a7d9049e6610f48ee011aeced6..803f0c2a66de1d53146d76cd35f7ffa65e00ef92 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel sequences namespaces make math assocs words arrays
 tools.annotations vocabs sorting prettyprint io system
-math.statistics accessors ;
+math.statistics accessors tools.time ;
 IN: wordtimer
 
 SYMBOL: *wordtimes*
diff --git a/extra/xml/syntax/syntax.factor b/extra/xml/syntax/syntax.factor
deleted file mode 100644 (file)
index 91b31ec..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-! Copyright (C) 2008 Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: lexer parser splitting kernel quotations namespaces make
-sequences assocs sequences.lib xml.generator xml.utilities
-xml.data ;
-IN: xml.syntax
-
-: parsed-name ( accum -- accum )
-    scan ":" split1 [ f <name> ] [ <simple-name> ] if* parsed ;
-
-: run-combinator ( accum quot1 quot2 -- accum )
-    >r [ ] like parsed r> [ parsed ] each ;
-
-: parse-tag-contents ( accum contained? -- accum )
-    [ \ contained*, parsed ] [
-        scan-word \ [ =
-        [ POSTPONE: [ \ tag*, parsed ]
-        [ "Expected [ missing" throw ] if
-    ] if ;
-
-DEFER: >>
-
-: attributes-parsed ( accum quot -- accum )
-    [ f parsed ] [
-        >r \ >r parsed r> parsed
-        [ H{ } make-assoc r> swap ] [ parsed ] each
-    ] if-empty ;
-
-: <<
-    parsed-name [
-        \ >> parse-until >quotation
-        attributes-parsed \ contained? get
-    ] with-scope parse-tag-contents ; parsing
-
-: ==
-    \ call parsed parsed-name \ set parsed ; parsing
-
-: //
-    \ contained? on ; parsing
-
-: parse-special ( accum end-token word -- accum )
-    >r parse-tokens " " join parsed r> parsed ;
-
-: <!-- "-->" \ comment, parse-special ; parsing
-
-: <!  ">" \ directive, parse-special ; parsing
-
-: <? "?>" \ instruction, parse-special ; parsing
-
-: >xml-document ( seq -- xml )
-    dup first prolog? [ unclip-slice ] [ standard-prolog ] if swap
-    [ tag? ] split-around <xml> ;
-
-DEFER: XML>
-
-: <XML
-    \ XML> [ >quotation ] parse-literal
-    { } parsed \ make parsed \ >xml-document parsed ; parsing
index 351b0e97d1d16c8ea42e3192d5f537bd83147ad7..5f56072c1d950dfc729afa662162df1573fc180a 100644 (file)
@@ -36,6 +36,7 @@
 (require 'font-lock)
 (require 'comint)
 (require 'view)
+(require 'ring)
 
 ;;; Customization:
 
@@ -89,6 +90,11 @@ buffer."
   :type 'boolean
   :group 'factor)
 
+(defcustom factor-help-use-minibuffer t
+  "When enabled, use the minibuffer for short help messages."
+  :type 'boolean
+  :group 'factor)
+
 (defcustom factor-display-compilation-output t
   "Display the REPL buffer before compiling files."
   :type 'boolean
@@ -109,49 +115,51 @@ buffer."
   :group 'factor
   :group 'faces)
 
-(defsubst factor--face (face) `((t ,(face-attr-construct face))))
-
-(defface factor-font-lock-parsing-word (factor--face font-lock-keyword-face)
+(defface factor-font-lock-parsing-word (face-default-spec font-lock-keyword-face)
   "Face for parsing words."
   :group 'factor-faces)
 
-(defface factor-font-lock-comment (factor--face font-lock-comment-face)
+(defface factor-font-lock-declaration (face-default-spec font-lock-keyword-face)
+  "Face for declaration words (inline, parsing ...)."
+  :group 'factor-faces)
+
+(defface factor-font-lock-comment (face-default-spec font-lock-comment-face)
   "Face for comments."
   :group 'factor-faces)
 
-(defface factor-font-lock-string (factor--face font-lock-string-face)
+(defface factor-font-lock-string (face-default-spec font-lock-string-face)
   "Face for strings."
   :group 'factor-faces)
 
-(defface factor-font-lock-stack-effect (factor--face font-lock-comment-face)
+(defface factor-font-lock-stack-effect (face-default-spec font-lock-comment-face)
   "Face for stack effect specifications."
   :group 'factor-faces)
 
-(defface factor-font-lock-word-definition (factor--face font-lock-function-name-face)
+(defface factor-font-lock-word-definition (face-default-spec font-lock-function-name-face)
   "Face for word, generic or method being defined."
   :group 'factor-faces)
 
-(defface factor-font-lock-symbol-definition (factor--face font-lock-variable-name-face)
+(defface factor-font-lock-symbol-definition (face-default-spec font-lock-variable-name-face)
   "Face for name of symbol being defined."
   :group 'factor-faces)
 
-(defface factor-font-lock-vocabulary-name (factor--face font-lock-constant-face)
+(defface factor-font-lock-vocabulary-name (face-default-spec font-lock-constant-face)
   "Face for names of vocabularies in USE or USING."
   :group 'factor-faces)
 
-(defface factor-font-lock-type-definition (factor--face font-lock-type-face)
+(defface factor-font-lock-type-definition (face-default-spec font-lock-type-face)
   "Face for type (tuple) names."
   :group 'factor-faces)
 
-(defface factor-font-lock-constructor (factor--face font-lock-type-face)
+(defface factor-font-lock-constructor (face-default-spec font-lock-type-face)
   "Face for constructors (<foo>)."
   :group 'factor-faces)
 
-(defface factor-font-lock-setter-word (factor--face font-lock-function-name-face)
+(defface factor-font-lock-setter-word (face-default-spec font-lock-function-name-face)
   "Face for setter words (>>foo)."
   :group 'factor-faces)
 
-(defface factor-font-lock-parsing-word (factor--face font-lock-keyword-face)
+(defface factor-font-lock-parsing-word (face-default-spec font-lock-keyword-face)
   "Face for parsing words."
   :group 'factor-faces)
 
@@ -159,6 +167,15 @@ buffer."
   "Face for headlines in help buffers."
   :group 'factor-faces)
 
+\f
+;;; Compatibility
+(when (not (fboundp 'ring-member))
+  (defun ring-member (ring item)
+    (catch 'found
+      (dotimes (ind (ring-length ring) nil)
+        (when (equal item (ring-ref ring ind))
+          (throw 'found ind))))))
+
 \f
 ;;; Factor mode font lock:
 
@@ -172,21 +189,29 @@ buffer."
     "OCT:" "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
     "REQUIRE:"  "REQUIRES:" "SINGLETON:" "SLOT:" "SYMBOL:" "SYMBOLS:"
     "TUPLE:" "T{" "t\\??" "TYPEDEF:"
-    "UNION:" "USE:" "USING:" "V{" "VAR:" "VARS:" "W{"))
+    "UNION:" "USE:" "USING:" "V{" "VARS:" "W{"))
 
 (defconst factor--regex-parsing-words-ext
-  (regexp-opt '("B" "call-next-method" "delimiter" "f" "flushable" "foldable"
-                "initial:" "inline" "parsing" "read-only" "recursive")
+  (regexp-opt '("B" "call-next-method" "delimiter" "f" "initial:" "read-only")
               'words))
 
+(defconst factor--declaration-words
+  '("flushable" "foldable" "inline" "parsing" "recursive"))
+
+(defconst factor--regex-declaration-words
+  (regexp-opt factor--declaration-words 'words))
+
 (defsubst factor--regex-second-word (prefixes)
   (format "^%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
 
+(defconst factor--regex-method-definition
+  "^M: +\\([^ ]+\\) +\\([^ ]+\\)")
+
 (defconst factor--regex-word-definition
-  (factor--regex-second-word '(":" "::" "M:" "GENERIC:")))
+  (factor--regex-second-word '(":" "::" "GENERIC:")))
 
 (defconst factor--regex-type-definition
-  (factor--regex-second-word '("TUPLE:")))
+  (factor--regex-second-word '("TUPLE:" "SINGLETON:")))
 
 (defconst factor--regex-parent-type "^TUPLE: +[^ ]+ +< +\\([^ ]+\\)")
 
@@ -195,36 +220,51 @@ buffer."
 (defconst factor--regex-setter "\\W>>[^ ]+\\b")
 
 (defconst factor--regex-symbol-definition
-  (factor--regex-second-word '("SYMBOL:")))
+  (factor--regex-second-word '("SYMBOL:" "VAR:")))
+
+(defconst factor--regex-stack-effect " ( .* )")
+
+(defconst factor--regex-using-lines "^USING: +\\(\\([^;]\\|[\n\r\f]\\)*\\);")
 
-(defconst factor--regex-using-line "^USING: +\\([^;]*\\);")
 (defconst factor--regex-use-line "^USE: +\\(.*\\)$")
 
-(defconst factor-font-lock-keywords
-  `(("#!.*$" . 'factor-font-lock-comment)
-    ("!( .* )" . 'factor-font-lock-comment)
-    ("^!.*$" . 'factor-font-lock-comment)
-    (" !.*$" . 'factor-font-lock-comment)
-    ("( .* )" . 'factor-font-lock-stack-effect)
-    ("\"\\(\\\\\"\\|[^\"]\\)*\"" . 'factor-font-lock-string)
+(defconst factor--font-lock-keywords
+  `((,factor--regex-stack-effect . 'factor-font-lock-stack-effect)
     ("\\(P\\|SBUF\\)\"" 1 'factor-font-lock-parsing-word)
     ,@(mapcar #'(lambda (w) (cons (concat "\\(^\\| \\)\\(" w "\\)\\($\\| \\)")
                              '(2 'factor-font-lock-parsing-word)))
               factor--parsing-words)
     (,factor--regex-parsing-words-ext . 'factor-font-lock-parsing-word)
+    (,factor--regex-declaration-words 1 'factor-font-lock-declaration)
     (,factor--regex-word-definition 2 'factor-font-lock-word-definition)
     (,factor--regex-type-definition 2 'factor-font-lock-type-definition)
+    (,factor--regex-method-definition (1 'factor-font-lock-type-definition)
+                                      (2 'factor-font-lock-word-definition))
     (,factor--regex-parent-type 1 'factor-font-lock-type-definition)
     (,factor--regex-constructor . 'factor-font-lock-constructor)
     (,factor--regex-setter . 'factor-font-lock-setter-word)
     (,factor--regex-symbol-definition 2 'factor-font-lock-symbol-definition)
-    (,factor--regex-using-line 1 'factor-font-lock-vocabulary-name)
     (,factor--regex-use-line 1 'factor-font-lock-vocabulary-name))
   "Font lock keywords definition for Factor mode.")
 
 \f
 ;;; Factor mode syntax:
 
+(defconst factor--regex-definition-starters
+  (regexp-opt '("VARS" "TUPLE" "MACRO" "MACRO:" "M" ":" "")))
+
+(defconst factor--regex-definition-start
+  (format "^\\(%s:\\) " factor--regex-definition-starters))
+
+(defconst factor--regex-definition-end
+  (format "\\(;\\( +%s\\)*\\)" factor--regex-declaration-words))
+
+(defconst factor--font-lock-syntactic-keywords
+  `(("\\(#!\\)" (1 "<"))
+    (" \\(!\\)" (1 "<"))
+    ("^\\(!\\)" (1 "<"))
+    ("\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))))
+
 (defvar factor-mode-syntax-table nil
   "Syntax table used while in Factor mode.")
 
@@ -254,11 +294,14 @@ buffer."
 
     ;; Whitespace
     (modify-syntax-entry ?\t " " factor-mode-syntax-table)
-    (modify-syntax-entry ?\n ">" factor-mode-syntax-table)
     (modify-syntax-entry ?\f " " factor-mode-syntax-table)
     (modify-syntax-entry ?\r " " factor-mode-syntax-table)
     (modify-syntax-entry ?  " " factor-mode-syntax-table)
 
+    ;; (end of) Comments
+    (modify-syntax-entry ?\n ">" factor-mode-syntax-table)
+
+    ;; Parenthesis
     (modify-syntax-entry ?\[ "(]  " factor-mode-syntax-table)
     (modify-syntax-entry ?\] ")[  " factor-mode-syntax-table)
     (modify-syntax-entry ?{ "(}  " factor-mode-syntax-table)
@@ -266,7 +309,30 @@ buffer."
 
     (modify-syntax-entry ?\( "()" factor-mode-syntax-table)
     (modify-syntax-entry ?\) ")(" factor-mode-syntax-table)
-    (modify-syntax-entry ?\" "\"    " factor-mode-syntax-table)))
+
+    ;; Strings
+    (modify-syntax-entry ?\" "\"" factor-mode-syntax-table)
+    (modify-syntax-entry ?\\ "/" factor-mode-syntax-table)))
+
+\f
+;;; symbol-at-point
+
+(defun factor--beginning-of-symbol ()
+  "Move point to the beginning of the current symbol."
+  (while (eq (char-before) ?:) (backward-char))
+  (skip-syntax-backward "w_"))
+
+(defun factor--end-of-symbol ()
+  "Move point to the end of the current symbol."
+  (skip-syntax-forward "w_")
+  (while (looking-at ":") (forward-char)))
+
+(put 'factor-symbol 'end-op 'factor--end-of-symbol)
+(put 'factor-symbol 'beginning-op 'factor--beginning-of-symbol)
+
+(defsubst factor--symbol-at-point ()
+  (let ((s (substring-no-properties (thing-at-point 'factor-symbol))))
+    (and (> (length s) 0) s)))
 
 \f
 ;;; Factor mode indentation:
@@ -275,10 +341,6 @@ buffer."
  (defvar factor-indent-width factor-default-indent-width
    "Indentation width in factor buffers. A local variable."))
 
-(defconst factor--regexp-word-start
-  (let ((sws '("" ":" "TUPLE" "MACRO" "MACRO:" "M")))
-    (format "^\\(%s\\): " (mapconcat 'identity sws "\\|"))))
-
 (defun factor--guess-indent-width ()
   "Chooses an indentation value from existing code."
   (let ((word-cont "^ +[^ ]")
@@ -286,7 +348,7 @@ buffer."
     (save-excursion
       (beginning-of-buffer)
       (while (not iw)
-        (if (not (re-search-forward factor--regexp-word-start nil t))
+        (if (not (re-search-forward factor--regex-definition-start nil t))
             (setq iw factor-default-indent-width)
           (forward-line)
           (when (looking-at word-cont)
@@ -299,30 +361,47 @@ buffer."
 (defsubst factor--ppss-brackets-start ()
   (nth 1 (syntax-ppss)))
 
+(defun factor--ppss-brackets-end ()
+  (save-excursion
+    (goto-char (factor--ppss-brackets-start))
+    (condition-case nil
+        (progn (forward-sexp)
+               (1- (point)))
+      (error -1))))
+
 (defsubst factor--indentation-at (pos)
   (save-excursion (goto-char pos) (current-indentation)))
 
-(defconst factor--regex-closing-paren "[])}]")
-(defsubst factor--at-closing-paren-p ()
-  (looking-at factor--regex-closing-paren))
-
 (defsubst factor--at-first-char-p ()
   (= (- (point) (line-beginning-position)) (current-indentation)))
 
 (defconst factor--regex-single-liner
   (format "^%s" (regexp-opt '("DEFER:" "GENERIC:" "IN:"
-                              "PRIVATE>" "<PRIVATE" "SYMBOL:" "USE:"))))
+                              "PRIVATE>" "<PRIVATE"
+                              "SINGLETON:" "SYMBOL:" "USE:" "VAR:"))))
+
+(defconst factor--regex-begin-of-def
+  (format "^USING: \\|\\(%s\\)\\|\\(%s .*\\)"
+          factor--regex-definition-start
+          factor--regex-single-liner))
+
+(defconst factor--regex-end-of-def-line
+  (format "^.*%s" factor--regex-definition-end))
+
+(defconst factor--regex-end-of-def
+  (format "\\(%s\\)\\|\\(%s .*\\)"
+          factor--regex-end-of-def-line
+          factor--regex-single-liner))
 
 (defsubst factor--at-begin-of-def ()
-  (looking-at "\\([^ ]\\|^\\)+:"))
+  (looking-at factor--regex-begin-of-def))
+
+(defsubst factor--at-end-of-def ()
+  (looking-at factor--regex-end-of-def))
 
 (defsubst factor--looking-at-emptiness ()
   (looking-at "^[ \t]*$"))
 
-(defun factor--at-end-of-def ()
-  (or (looking-at ".*;[ \t]*$")
-      (looking-at factor--regex-single-liner)))
-
 (defun factor--at-setter-line ()
   (save-excursion
     (beginning-of-line)
@@ -345,13 +424,12 @@ buffer."
 (defun factor--indent-in-brackets ()
   (save-excursion
     (beginning-of-line)
-    (when (or (and (re-search-forward factor--regex-closing-paren
-                                      (line-end-position) t)
-                   (not (backward-char)))
-              (> (factor--ppss-brackets-depth) 0))
-      (let ((op (factor--ppss-brackets-start)))
-        (when (> (line-number-at-pos) (line-number-at-pos op))
-          (if (factor--at-closing-paren-p)
+    (when (> (factor--ppss-brackets-depth) 0)
+      (let ((op (factor--ppss-brackets-start))
+            (cl (factor--ppss-brackets-end))
+            (ln (line-number-at-pos)))
+        (when (> ln (line-number-at-pos op))
+          (if (and (> cl 0) (= ln (line-number-at-pos cl)))
               (factor--indentation-at op)
             (factor--increased-indentation (factor--indentation-at op))))))))
 
@@ -380,7 +458,8 @@ buffer."
       (forward-line -1))
     (if (or (factor--at-end-of-def) (factor--at-setter-line))
         (factor--decreased-indentation)
-      (if (factor--at-begin-of-def)
+      (if (and (factor--at-begin-of-def)
+               (not (looking-at factor--regex-using-lines)))
           (factor--increased-indentation)
         (current-indentation)))))
 
@@ -407,7 +486,91 @@ buffer."
           (goto-char (- (point-max) pos))))))
 
 \f
-;;; Factor mode commands:
+;; Factor mode:
+(defvar factor-mode-map (make-sparse-keymap)
+  "Key map used by Factor mode.")
+
+(defsubst factor--beginning-of-defun (&optional times)
+  (re-search-backward factor--regex-begin-of-def nil t times))
+
+(defsubst factor--end-of-defun ()
+  (re-search-forward factor--regex-end-of-def nil t))
+
+;;;###autoload
+(defun factor-mode ()
+  "A mode for editing programs written in the Factor programming language.
+\\{factor-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map factor-mode-map)
+  (setq major-mode 'factor-mode)
+  (setq mode-name "Factor")
+  ;; Font locking
+  (set (make-local-variable 'comment-start) "! ")
+  (set (make-local-variable 'parse-sexp-lookup-properties) t)
+  (set (make-local-variable 'font-lock-comment-face) 'factor-font-lock-comment)
+  (set (make-local-variable 'font-lock-string-face) 'factor-font-lock-string)
+  (set (make-local-variable 'font-lock-defaults)
+       `(factor--font-lock-keywords
+         nil nil nil nil
+         (font-lock-syntactic-keywords . ,factor--font-lock-syntactic-keywords)))
+
+  (set-syntax-table factor-mode-syntax-table)
+  ;; Defun navigation
+  (set (make-local-variable 'beginning-of-defun-function) 'factor--beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) 'factor--end-of-defun)
+  (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
+  ;; Indentation
+  (set (make-local-variable 'indent-line-function) 'factor--indent-line)
+  (setq factor-indent-width (factor--guess-indent-width))
+  (setq indent-tabs-mode nil)
+  ;; ElDoc
+  (set (make-local-variable 'eldoc-documentation-function) 'factor--eldoc)
+
+  (run-hooks 'factor-mode-hook))
+
+(add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode))
+
+\f
+;;; Factor listener mode:
+
+;;;###autoload
+(define-derived-mode factor-listener-mode comint-mode "Factor Listener"
+  "Major mode for interacting with an inferior Factor listener process.
+\\{factor-listener-mode-map}"
+  (set (make-local-variable 'comint-prompt-regexp) "^( [^)]+ ) "))
+
+(defvar factor--listener-buffer nil
+  "The buffer in which the Factor listener is running.")
+
+(defun factor--listener-start-process ()
+  "Start an inferior Factor listener process, using
+`factor-binary' and `factor-image'."
+  (setq factor--listener-buffer
+        (apply 'make-comint "factor" (expand-file-name factor-binary) nil
+               `("-run=listener" ,(format "-i=%s" (expand-file-name factor-image)))))
+  (with-current-buffer factor--listener-buffer
+    (factor-listener-mode)))
+
+(defun factor--listener-process (&optional start)
+  (or (and (buffer-live-p factor--listener-buffer)
+           (get-buffer-process factor--listener-buffer))
+      (if (not start)
+          (error "No running factor listener. Try M-x run-factor.")
+        (factor--listener-start-process)
+        (factor--listener-process t))))
+
+;;;###autoload
+(defalias 'switch-to-factor 'run-factor)
+;;;###autoload
+(defun run-factor (&optional arg)
+  "Show the factor-listener buffer, starting the process if needed."
+  (interactive)
+  (let ((buf (process-buffer (factor--listener-process t)))
+        (pop-up-windows factor-listener-window-allow-split))
+    (if factor-listener-use-other-window
+        (pop-to-buffer buf)
+      (switch-to-buffer buf))))
 
 (defun factor-telnet-to-port (port)
   (interactive "nPort: ")
@@ -422,21 +585,159 @@ buffer."
   (interactive)
   (factor-telnet-to-port 9010))
 
+\f
+;;; Factor listener interaction:
+
+(defun factor--listener-send-cmd (cmd)
+  (let ((proc (factor--listener-process)))
+    (when proc
+      (let* ((out (get-buffer-create "*factor messages*"))
+             (beg (with-current-buffer out (goto-char (point-max)))))
+        (comint-redirect-send-command-to-process cmd out proc nil t)
+        (with-current-buffer factor--listener-buffer
+          (while (not comint-redirect-completed) (sleep-for 0 1)))
+        (with-current-buffer out
+          (split-string (buffer-substring-no-properties beg (point-max))
+                        "[\"\f\n\r\v]+" t))))))
+
+;;;;; Current vocabulary:
+(make-variable-buffer-local
+ (defvar factor--current-vocab nil
+   "Current vocabulary."))
+
+(defconst factor--regexp-current-vocab "^IN: +\\([^ \r\n\f]+\\)")
+
+(defun factor--current-buffer-vocab ()
+  (save-excursion
+    (when (or (re-search-backward factor--regexp-current-vocab nil t)
+              (re-search-forward factor--regexp-current-vocab nil t))
+      (setq factor--current-vocab (match-string-no-properties 1)))))
+
+(defun factor--current-listener-vocab ()
+  (car (factor--listener-send-cmd "USING: parser ; in get .")))
+
+(defun factor--set-current-listener-vocab (&optional vocab)
+  (factor--listener-send-cmd
+   (format "IN: %s" (or vocab (factor--current-buffer-vocab))))
+  t)
+
+(defmacro factor--with-vocab (vocab &rest body)
+  (let ((current (make-symbol "current")))
+    `(let ((,current (factor--current-listener-vocab)))
+       (factor--set-current-listener-vocab ,vocab)
+       (prog1 (condition-case nil (progn . ,body) (error nil))
+         (factor--set-current-listener-vocab ,current)))))
+
+(put 'factor--with-vocab 'lisp-indent-function 1)
+
+;;;;; Synchronous interaction:
+
+(defsubst factor--listener-vocab-cmds (cmds &optional vocab)
+  (factor--with-vocab vocab
+    (mapcar #'factor--listener-send-cmd cmds)))
+
+(defsubst factor--listener-vocab-cmd (cmd &optional vocab)
+  (factor--with-vocab vocab
+    (factor--listener-send-cmd cmd)))
+
+\f
+;;;;; Buffer cycling and docs
+
+
+(defconst factor--cycle-endings
+  '(".factor" "-tests.factor" "-docs.factor"))
+
+(defconst factor--regex-cycle-endings
+  (format "\\(.*?\\)\\(%s\\)$"
+          (regexp-opt factor--cycle-endings)))
+
+(defconst factor--cycle-endings-ring
+  (let ((ring (make-ring (length factor--cycle-endings))))
+    (dolist (e factor--cycle-endings ring)
+      (ring-insert ring e))))
+
+(defun factor--cycle-next (file)
+  (let* ((match (string-match factor--regex-cycle-endings file))
+         (base (and match (match-string-no-properties 1 file)))
+         (ending (and match (match-string-no-properties 2 file)))
+         (idx (and ending (ring-member factor--cycle-endings-ring ending)))
+         (gfl (lambda (i) (concat base (ring-ref factor--cycle-endings-ring i)))))
+    (if (not idx) file
+      (let ((l (length factor--cycle-endings)) (i 1) next)
+        (while (and (not next) (< i l))
+          (when (file-exists-p (funcall gfl (+ idx i)))
+            (setq next (+ idx i)))
+          (setq i (1+ i)))
+        (funcall gfl (or next idx))))))
+
+(defun factor-visit-other-file (&optional file)
+  "Cycle between code, tests and docs factor files."
+  (interactive)
+  (find-file (factor--cycle-next (or file (buffer-file-name)))))
+
+\f
+;;;;; Interface: See
+
+(defconst factor--regex-error-marker "^Type :help for debugging")
+(defconst factor--regex-data-stack "^--- Data stack:")
+
+(defun factor--prune-ans-strings (ans)
+  (nreverse
+   (catch 'done
+     (let ((res))
+       (dolist (a ans res)
+         (cond ((string-match factor--regex-stack-effect a)
+                (throw 'done (cons a res)))
+               ((string-match factor--regex-data-stack a)
+                (throw 'done res))
+               ((string-match factor--regex-error-marker a)
+                (throw 'done nil))
+               (t (push a res))))))))
+
+(defun factor--see-ans-to-string (ans)
+  (let ((s (mapconcat #'identity (factor--prune-ans-strings ans) " "))
+        (font-lock-verbose nil))
+    (and (> (length s) 0)
+         (with-temp-buffer
+           (insert s)
+           (factor-mode)
+           (font-lock-fontify-buffer)
+           (buffer-string)))))
+
+(defun factor--see-current-word (&optional word)
+  (let ((word (or word (factor--symbol-at-point))))
+    (when word
+      (let ((answer (factor--listener-send-cmd (format "\\ %s see" word))))
+        (and answer (factor--see-ans-to-string answer))))))
+
+(defalias 'factor--eldoc 'factor--see-current-word)
+
+(defun factor-see-current-word (&optional word)
+  "Echo in the minibuffer information about word at point."
+  (interactive)
+  (let* ((proc (factor--listener-process))
+         (word (or word (factor--symbol-at-point)))
+         (msg (factor--see-current-word word)))
+    (if msg (message "%s" msg)
+      (if word (message "No help found for '%s'" word)
+        (message "No word at point")))))
+
+;;; to fix:
 (defun factor-run-file ()
   (interactive)
   (when (and (buffer-modified-p)
-                        (y-or-n-p (format "Save file %s? " (buffer-file-name))))
-       (save-buffer))
+             (y-or-n-p (format "Save file %s? " (buffer-file-name))))
+    (save-buffer))
   (when factor-display-compilation-output
-       (factor-display-output-buffer))
+    (factor-display-output-buffer))
   (comint-send-string "*factor*" (format "\"%s\"" (buffer-file-name)))
   (comint-send-string "*factor*" " run-file\n"))
 
 (defun factor-display-output-buffer ()
   (with-current-buffer "*factor*"
-       (goto-char (point-max))
-       (unless (get-buffer-window (current-buffer) t)
-         (display-buffer (current-buffer) t))))
+    (goto-char (point-max))
+    (unless (get-buffer-window (current-buffer) t)
+      (display-buffer (current-buffer) t))))
 
 (defun factor-send-string (str)
   (let ((n (length (split-string str "\n"))))
@@ -478,71 +779,6 @@ buffer."
   (beginning-of-line)
   (insert "! "))
 
-(defvar factor-mode-map (make-sparse-keymap)
-  "Key map used by Factor mode.")
-
-\f
-;; Factor mode:
-
-;;;###autoload
-(defun factor-mode ()
-  "A mode for editing programs written in the Factor programming language.
-\\{factor-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map factor-mode-map)
-  (setq major-mode 'factor-mode)
-  (setq mode-name "Factor")
-  (set (make-local-variable 'comment-start) "! ")
-  (set (make-local-variable 'font-lock-defaults)
-       '(factor-font-lock-keywords t nil nil nil))
-  (set-syntax-table factor-mode-syntax-table)
-  (set (make-local-variable 'indent-line-function) 'factor--indent-line)
-  (setq factor-indent-width (factor--guess-indent-width))
-  (setq indent-tabs-mode nil)
-  (run-hooks 'factor-mode-hook))
-
-(add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode))
-
-\f
-;;; Factor listener mode:
-
-;;;###autoload
-(define-derived-mode factor-listener-mode comint-mode "Factor Listener"
-  "Major mode for interacting with an inferior Factor listener process.
-\\{factor-listener-mode-map}"
-  (set (make-local-variable 'comint-prompt-regexp) "^( [^)]+ ) "))
-
-(defvar factor--listener-buffer nil
-  "The buffer in which the Factor listener is running.")
-
-(defun factor--listener-start-process ()
-  "Start an inferior Factor listener process, using
-`factor-binary' and `factor-image'."
-  (setq factor--listener-buffer
-        (apply 'make-comint "factor" (expand-file-name factor-binary) nil
-               `("-run=listener" ,(format "-i=%s" (expand-file-name factor-image)))))
-  (with-current-buffer factor--listener-buffer
-    (factor-listener-mode)))
-
-(defun factor--listener-process ()
-  (or (and (buffer-live-p factor--listener-buffer)
-           (get-buffer-process factor--listener-buffer))
-      (progn (factor--listener-start-process)
-             (factor--listener-process))))
-
-;;;###autoload
-(defalias 'switch-to-factor 'run-factor)
-;;;###autoload
-(defun run-factor (&optional arg)
-  "Show the factor-listener buffer, starting the process if needed."
-  (interactive)
-  (let ((buf (process-buffer (factor--listener-process)))
-        (pop-up-windows factor-listener-window-allow-split))
-    (if factor-listener-use-other-window
-        (pop-to-buffer buf)
-      (switch-to-buffer buf))))
-
 \f
 ;;;; Factor help mode:
 
@@ -550,19 +786,23 @@ buffer."
   "Keymap for Factor help mode.")
 
 (defconst factor--help-headlines
-  (regexp-opt '("Parent topics:"
-                "Inputs and outputs"
-                "Word description"
+  (regexp-opt '("Definition"
+                "Examples"
                 "Generic word contract"
+                "Inputs and outputs"
+                "Parent topics:"
+                "See also"
+                "Syntax"
                 "Vocabulary"
-                "Definition")
+                "Warning"
+                "Word description")
               t))
 
 (defconst factor--help-headlines-regexp (format "^%s" factor--help-headlines))
 
 (defconst factor--help-font-lock-keywords
   `((,factor--help-headlines-regexp . 'factor-font-lock-help-mode-headlines)
-    ,@factor-font-lock-keywords))
+    ,@factor--font-lock-keywords))
 
 (defun factor-help-mode ()
   "Major mode for displaying Factor help messages.
@@ -575,6 +815,7 @@ buffer."
   (set (make-local-variable 'font-lock-defaults)
        '(factor--help-font-lock-keywords t nil nil nil))
   (set (make-local-variable 'comint-redirect-subvert-readonly) t)
+  (set (make-local-variable 'comint-redirect-echo-input) nil)
   (set (make-local-variable 'view-no-disable-on-exit) t)
   (view-mode)
   (setq view-exit-action
@@ -586,33 +827,44 @@ buffer."
   (run-mode-hooks 'factor-help-mode-hook))
 
 (defun factor--listener-help-buffer ()
-  (set-buffer (get-buffer-create "*factor-help*"))
-  (let ((inhibit-read-only t))
-    (delete-region (point-min) (point-max)))
-  (factor-help-mode)
-  (current-buffer))
+  (with-current-buffer (get-buffer-create "*factor-help*")
+    (let ((inhibit-read-only t)) (erase-buffer))
+    (factor-help-mode)
+    (current-buffer)))
 
 (defvar factor--help-history nil)
 
 (defun factor--listener-show-help (&optional see)
-  (let* ((def (thing-at-point 'sexp))
-         (prompt (format "%s (%s): " (if see "See" "Help") def))
+  (let* ((proc (factor--listener-process))
+         (def (factor--symbol-at-point))
+         (prompt (format "See%s help on%s: " (if see " short" "")
+                         (if def (format " (%s)" def) "")))
          (ask (or (not (eq major-mode 'factor-mode))
                   (not def)
                   factor-help-always-ask))
          (cmd (format "\\ %s %s"
                       (if ask (read-string prompt nil 'factor--help-history def) def)
                       (if see "see" "help")))
-         (hb (factor--listener-help-buffer))
-         (proc (factor--listener-process)))
+         (hb (factor--listener-help-buffer)))
     (comint-redirect-send-command-to-process cmd hb proc nil)
-    (pop-to-buffer hb)))
+    (pop-to-buffer hb)
+    (beginning-of-buffer hb)))
 
-(defun factor-see ()
-  (interactive)
-  (factor--listener-show-help t))
+;;;; Interface: see/help commands
+
+(defun factor-see (&optional arg)
+  "See a help summary of symbol at point.
+By default, the information is shown in the minibuffer. When
+called with a prefix argument, the information is displayed in a
+separate help buffer."
+  (interactive "P")
+  (if (if factor-help-use-minibuffer (not arg) arg)
+      (factor-see-current-word)
+    (factor--listener-show-help t)))
 
 (defun factor-help ()
+  "Show extended help about the symbol at point, using a help
+buffer."
   (interactive)
   (factor--listener-show-help))
 
@@ -627,22 +879,35 @@ vocabularies which have been modified on disk."
 \f
 ;;; Key bindings:
 
-(defmacro factor--define-key (key cmd)
-  `(progn
-     (define-key factor-mode-map [(control ?c) ,key] ,cmd)
-     (define-key factor-mode-map [(control ?c) (control ,key)] ,cmd)))
+(defun factor--define-key (key cmd &optional both)
+  (let ((ms (list factor-mode-map)))
+    (when both (push factor-help-mode-map ms))
+    (dolist (m ms)
+      (define-key m (vector '(control ?c) key) cmd)
+      (define-key m (vector '(control ?c) `(control ,key)) cmd))))
+
+(defun factor--define-auto-indent-key (key)
+  (define-key factor-mode-map (vector key)
+    (lambda (n)
+      (interactive "p")
+      (self-insert-command n)
+      (indent-for-tab-command))))
 
 (factor--define-key ?f 'factor-run-file)
 (factor--define-key ?r 'factor-send-region)
 (factor--define-key ?d 'factor-send-definition)
-(factor--define-key ?s 'factor-see)
+(factor--define-key ?s 'factor-see t)
 (factor--define-key ?e 'factor-edit)
-(factor--define-key ?z 'switch-to-factor)
+(factor--define-key ?z 'switch-to-factor t)
+(factor--define-key ?o 'factor-visit-other-file)
 (factor--define-key ?c 'comment-region)
 
+(factor--define-auto-indent-key ?\])
+(factor--define-auto-indent-key ?\})
+
 (define-key factor-mode-map "\C-ch" 'factor-help)
+(define-key factor-help-mode-map "\C-ch" 'factor-help)
 (define-key factor-mode-map "\C-m" 'newline-and-indent)
-(define-key factor-mode-map [tab] 'indent-for-tab-command)
 
 (define-key factor-listener-mode-map [f8] 'factor-refresh-all)
 
diff --git a/misc/fuel/README b/misc/fuel/README
new file mode 100644 (file)
index 0000000..078490a
--- /dev/null
@@ -0,0 +1,64 @@
+FUEL, Factor's Ultimate Emacs Library
+-------------------------------------
+
+FUEL provides a complete environment for your Factor coding pleasure
+inside Emacs, including source code edition and interaction with a
+Factor listener instance running within Emacs.
+
+FUEL was started by Jose A Ortega as an extension to Ed Cavazos'
+original factor.el code.
+
+Installation
+------------
+
+FUEL comes bundled with Factor's distribution. The folder misc/fuel
+contains Elisp code, and there's a fuel vocabulary in extras/fuel.
+
+To install FUEL, either add this line to your Emacs initialisation:
+
+  (load-file "<path/to/factor/installation>/misc/fuel/fu.el")
+
+or
+
+  (add-to-list load-path "<path/to/factor/installation>/fuel")
+  (require 'fuel)
+
+If all you want is a major mode for editing Factor code with pretty
+font colors and indentation, without running the factor listener
+inside Emacs, you can use instead:
+
+  (add-to-list load-path "<path/to/factor/installation>/fuel")
+  (setq factor-mode-use-fuel nil)
+  (require 'factor-mode)
+
+Basic usage
+-----------
+
+If you're using the default factor binary and images locations inside
+the Factor's source tree, that should be enough to start using FUEL.
+Editing any file with the extension .factor will put you in
+factor-mode; try C-hm for a summary of available commands.
+
+To start the listener, try M-x run-factor.
+
+Many aspects of the environment can be customized:
+M-x customize-group fuel will show you how many.
+
+Quick key reference
+-------------------
+
+ - C-cz : switch to listener
+ - C-co : cycle between code, tests and docs factor files
+
+ - M-. : edit word at point in Emacs
+
+ - C-cr, C-cC-er : eval region
+ - C-M-r, C-cC-ee : eval region, extending it to definition boundaries
+ - C-M-x, C-cC-ex : eval definition around point
+
+ - C-cC-da : toggle autodoc mode
+ - C-cC-dd : help for word at point
+ - C-cC-ds : short help word at point
+
+Chords ending in a single letter <x> accept also C-<x> (e.g. C-cC-z is
+the same as C-cz).
diff --git a/misc/fuel/factor-mode.el b/misc/fuel/factor-mode.el
new file mode 100644 (file)
index 0000000..d79930b
--- /dev/null
@@ -0,0 +1,239 @@
+;;; factor-mode.el -- mode for editing Factor source
+
+;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages, fuel, factor
+;; Start date: Tue Dec 02, 2008 21:32
+
+;;; Comentary:
+
+;; Definition of factor-mode, a major Emacs for editing Factor source
+;; code.
+
+;;; Code:
+
+(require 'fuel-base)
+(require 'fuel-syntax)
+(require 'fuel-font-lock)
+
+(require 'ring)
+
+\f
+;;; Customization:
+
+(defgroup factor-mode nil
+  "Major mode for Factor source code"
+  :group 'fuel)
+
+(defcustom factor-mode-use-fuel t
+  "Whether to use the full FUEL facilities in factor mode.
+
+Set this variable to nil if you just want to use Emacs as the
+external editor of your Factor environment, e.g., by putting
+these lines in your .emacs:
+
+  (add-to-list 'load-path \"/path/to/factor/misc/fuel\")
+  (setq factor-mode-use-fuel nil)
+  (require 'factor-mode)
+"
+  :type 'boolean
+  :group 'factor-mode)
+
+(defcustom factor-mode-default-indent-width 4
+  "Default indentation width for factor-mode.
+
+This value will be used for the local variable
+`factor-mode-indent-width' in new factor buffers. For existing
+code, we first check if `factor-mode-indent-width' is set
+explicitly in a local variable section or line (e.g.
+'! -*- factor-mode-indent-witdth: 2 -*-'). If that's not the case,
+`factor-mode' tries to infer its correct value from the existing
+code in the buffer."
+  :type 'integer
+  :group 'fuel)
+
+(defcustom factor-mode-hook nil
+  "Hook run when entering Factor mode."
+  :type 'hook
+  :group 'factor-mode)
+
+\f
+;;; Syntax table:
+
+(defun factor-mode--syntax-setup ()
+  (set-syntax-table fuel-syntax--syntax-table)
+  (set (make-local-variable 'beginning-of-defun-function)
+       'fuel-syntax--beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) 'fuel-syntax--end-of-defun)
+  (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
+  (fuel-syntax--enable-usings))
+
+\f
+;;; Indentation:
+
+(make-variable-buffer-local
+ (defvar factor-mode-indent-width factor-mode-default-indent-width
+   "Indentation width in factor buffers. A local variable."))
+
+(defun factor-mode--guess-indent-width ()
+  "Chooses an indentation value from existing code."
+  (let ((word-cont "^ +[^ ]")
+        (iw))
+    (save-excursion
+      (beginning-of-buffer)
+      (while (not iw)
+        (if (not (re-search-forward fuel-syntax--definition-start-regex nil t))
+            (setq iw factor-mode-default-indent-width)
+          (forward-line)
+          (when (looking-at word-cont)
+            (setq iw (current-indentation))))))
+    iw))
+
+(defun factor-mode--indent-in-brackets ()
+  (save-excursion
+    (beginning-of-line)
+    (when (> (fuel-syntax--brackets-depth) 0)
+      (let ((op (fuel-syntax--brackets-start))
+            (cl (fuel-syntax--brackets-end))
+            (ln (line-number-at-pos)))
+        (when (> ln (line-number-at-pos op))
+          (if (and (> cl 0) (= ln (line-number-at-pos cl)))
+              (fuel-syntax--indentation-at op)
+            (fuel-syntax--increased-indentation (fuel-syntax--indentation-at op))))))))
+
+(defun factor-mode--indent-definition ()
+  (save-excursion
+    (beginning-of-line)
+    (when (fuel-syntax--at-begin-of-def) 0)))
+
+(defun factor-mode--indent-setter-line ()
+  (when (fuel-syntax--at-setter-line)
+    (save-excursion
+      (let ((indent (and (fuel-syntax--at-constructor-line) (current-indentation))))
+        (while (not (or indent
+                        (bobp)
+                        (fuel-syntax--at-begin-of-def)
+                        (fuel-syntax--at-end-of-def)))
+          (if (fuel-syntax--at-constructor-line)
+              (setq indent (fuel-syntax--increased-indentation))
+            (forward-line -1)))
+        indent))))
+
+(defun factor-mode--indent-continuation ()
+  (save-excursion
+    (forward-line -1)
+    (while (and (not (bobp))
+                (fuel-syntax--looking-at-emptiness))
+      (forward-line -1))
+    (cond ((or (fuel-syntax--at-end-of-def)
+               (fuel-syntax--at-setter-line))
+           (fuel-syntax--decreased-indentation))
+          ((and (fuel-syntax--at-begin-of-def)
+                (not (fuel-syntax--at-using)))
+           (fuel-syntax--increased-indentation))
+          (t (current-indentation)))))
+
+(defun factor-mode--calculate-indentation ()
+  "Calculate Factor indentation for line at point."
+  (or (and (bobp) 0)
+      (factor-mode--indent-definition)
+      (factor-mode--indent-in-brackets)
+      (factor-mode--indent-setter-line)
+      (factor-mode--indent-continuation)
+      0))
+
+(defun factor-mode--indent-line ()
+  "Indent current line as Factor code"
+  (let ((target (factor-mode--calculate-indentation))
+        (pos (- (point-max) (point))))
+    (if (= target (current-indentation))
+        (if (< (current-column) (current-indentation))
+            (back-to-indentation))
+      (beginning-of-line)
+      (delete-horizontal-space)
+      (indent-to target)
+      (if (> (- (point-max) pos) (point))
+          (goto-char (- (point-max) pos))))))
+
+(defun factor-mode--indentation-setup ()
+  (set (make-local-variable 'indent-line-function) 'factor-mode--indent-line)
+  (setq factor-indent-width (factor-mode--guess-indent-width))
+  (setq indent-tabs-mode nil))
+
+\f
+;;; Buffer cycling:
+
+(defconst factor-mode--cycle-endings
+  '(".factor" "-tests.factor" "-docs.factor"))
+
+(defconst factor-mode--regex-cycle-endings
+  (format "\\(.*?\\)\\(%s\\)$"
+          (regexp-opt factor-mode--cycle-endings)))
+
+(defconst factor-mode--cycle-endings-ring
+  (let ((ring (make-ring (length factor-mode--cycle-endings))))
+    (dolist (e factor-mode--cycle-endings ring)
+      (ring-insert ring e))))
+
+(defun factor-mode--cycle-next (file)
+  (let* ((match (string-match factor-mode--regex-cycle-endings file))
+         (base (and match (match-string-no-properties 1 file)))
+         (ending (and match (match-string-no-properties 2 file)))
+         (idx (and ending (ring-member factor-mode--cycle-endings-ring ending)))
+         (gfl (lambda (i) (concat base (ring-ref factor-mode--cycle-endings-ring i)))))
+    (if (not idx) file
+      (let ((l (length factor-mode--cycle-endings)) (i 1) next)
+        (while (and (not next) (< i l))
+          (when (file-exists-p (funcall gfl (+ idx i)))
+            (setq next (+ idx i)))
+          (setq i (1+ i)))
+        (funcall gfl (or next idx))))))
+
+(defun factor-mode-visit-other-file (&optional file)
+  "Cycle between code, tests and docs factor files."
+  (interactive)
+  (find-file (factor-mode--cycle-next (or file (buffer-file-name)))))
+
+\f
+;;; Keymap:
+
+(defun factor-mode-insert-and-indent (n)
+  (interactive "p")
+  (self-insert-command n)
+  (indent-for-tab-command))
+
+(defvar factor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [?\]] 'factor-mode-insert-and-indent)
+    (define-key map [?}] 'factor-mode-insert-and-indent)
+    (define-key map "\C-m" 'newline-and-indent)
+    (define-key map "\C-co" 'factor-mode-visit-other-file)
+    (define-key map "\C-c\C-o" 'factor-mode-visit-other-file)
+    map))
+
+(defun factor-mode--keymap-setup ()
+  (use-local-map factor-mode-map))
+
+\f
+;;; Factor mode:
+
+;;;###autoload
+(defun factor-mode ()
+  "A mode for editing programs written in the Factor programming language.
+\\{factor-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'factor-mode)
+  (setq mode-name "Factor")
+  (fuel-font-lock--font-lock-setup)
+  (factor-mode--keymap-setup)
+  (factor-mode--indentation-setup)
+  (factor-mode--syntax-setup)
+  (when factor-mode-use-fuel (require 'fuel-mode) (fuel-mode))
+  (run-hooks 'factor-mode-hook))
+
+\f
+(provide 'factor-mode)
+;;; factor-mode.el ends here
diff --git a/misc/fuel/fu.el b/misc/fuel/fu.el
new file mode 100644 (file)
index 0000000..508d7ef
--- /dev/null
@@ -0,0 +1,26 @@
+;;; fu.el --- Startup file for FUEL
+
+;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+
+;;; Code:
+
+(add-to-list 'load-path (file-name-directory load-file-name))
+
+(add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode))
+(autoload 'factor-mode "factor-mode.el"
+  "Major mode for editing Factor source." t)
+
+(autoload 'run-factor "fuel-listener.el"
+  "Start a Factor listener, or switch to a running one." t)
+
+(autoload 'fuel-autodoc-mode "fuel-help.el"
+  "Minor mode showing in the minibuffer a synopsis of Factor word at point."
+  t)
+
+
+\f
+;;; fu.el ends here
diff --git a/misc/fuel/fuel-base.el b/misc/fuel/fuel-base.el
new file mode 100644 (file)
index 0000000..a62d16c
--- /dev/null
@@ -0,0 +1,63 @@
+;;; fuel-base.el --- Basic FUEL support code
+
+;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+
+;;; Commentary:
+
+;; Basic definitions likely to be used by all FUEL modules.
+
+;;; Code:
+
+(defconst fuel-version "1.0")
+
+;;;###autoload
+(defsubst fuel-version ()
+  "Echoes FUEL's version."
+  (interactive)
+  (message "FUEL %s" fuel-version))
+
+\f
+;;; Customization:
+
+;;;###autoload
+(defgroup fuel nil
+  "Factor's Ultimate Emacs Library"
+  :group 'language)
+
+\f
+;;; Emacs compatibility:
+
+(eval-after-load "ring"
+  '(when (not (fboundp 'ring-member))
+     (defun ring-member (ring item)
+       (catch 'found
+         (dotimes (ind (ring-length ring) nil)
+           (when (equal item (ring-ref ring ind))
+             (throw 'found ind)))))))
+
+\f
+;;; Utilities
+
+(defun fuel--shorten-str (str len)
+  (let ((sl (length str)))
+    (if (<= sl len) str
+      (let* ((sep " ... ")
+             (sepl (length sep))
+             (segl (/ (- len sepl) 2)))
+        (format "%s%s%s"
+                (substring str 0 segl)
+                sep
+                (substring str (- sl segl)))))))
+
+(defun fuel--shorten-region (begin end len)
+  (fuel--shorten-str (mapconcat 'identity
+                                (split-string (buffer-substring begin end) nil t)
+                                " ")
+                     len))
+
+(provide 'fuel-base)
+;;; fuel-base.el ends here
diff --git a/misc/fuel/fuel-eval.el b/misc/fuel/fuel-eval.el
new file mode 100644 (file)
index 0000000..bef7171
--- /dev/null
@@ -0,0 +1,112 @@
+;;; fuel-eval.el --- utilities for communication with fuel-listener
+
+;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+;; Start date: Tue Dec 02, 2008
+
+;;; Commentary:
+
+;; Protocols for handling communications via a comint buffer running a
+;; factor listener.
+
+;;; Code:
+
+(require 'fuel-base)
+(require 'fuel-syntax)
+
+\f
+;;; Syncronous string sending:
+
+(defvar fuel-eval-log-max-length 16000)
+
+(defvar fuel-eval--default-proc-function nil)
+(defsubst fuel-eval--default-proc ()
+  (and fuel-eval--default-proc-function
+       (funcall fuel-eval--default-proc-function)))
+
+(defvar fuel-eval--proc nil)
+(defvar fuel-eval--log t)
+
+(defun fuel-eval--send-string (str)
+  (let ((proc (or fuel-eval--proc (fuel-eval--default-proc))))
+    (when proc
+      (with-current-buffer (get-buffer-create "*factor messages*")
+        (goto-char (point-max))
+        (when (and (> fuel-eval-log-max-length 0)
+                   (> (point) fuel-eval-log-max-length))
+          (erase-buffer))
+        (when fuel-eval--log (insert "\n>> " (fuel--shorten-str str 256) "\n"))
+        (let ((beg (point)))
+          (comint-redirect-send-command-to-process str (current-buffer) proc nil t)
+          (with-current-buffer (process-buffer proc)
+            (while (not comint-redirect-completed) (sleep-for 0 1)))
+          (goto-char beg)
+          (current-buffer))))))
+
+\f
+;;; Evaluation protocol
+
+(defsubst fuel-eval--retort-make (err result &optional output)
+  (list err result output))
+
+(defsubst fuel-eval--retort-error (ret) (nth 0 ret))
+(defsubst fuel-eval--retort-result (ret) (nth 1 ret))
+(defsubst fuel-eval--retort-output (ret) (nth 2 ret))
+
+(defsubst fuel-eval--retort-p (ret) (listp ret))
+
+(defsubst fuel-eval--error-name (err) (car err))
+
+(defsubst fuel-eval--make-parse-error-retort (str)
+  (fuel-eval--retort-make 'parse-retort-error nil str))
+
+(defun fuel-eval--parse-retort (buffer)
+  (save-current-buffer
+    (set-buffer buffer)
+    (condition-case nil
+        (read (current-buffer))
+      (error (fuel-eval--make-parse-error-retort
+              (buffer-substring-no-properties (point) (point-max)))))))
+
+(defsubst fuel-eval--send/retort (str)
+  (fuel-eval--parse-retort (fuel-eval--send-string str)))
+
+(defsubst fuel-eval--eval-begin ()
+  (fuel-eval--send/retort "fuel-begin-eval"))
+
+(defsubst fuel-eval--eval-end ()
+  (fuel-eval--send/retort "fuel-begin-eval"))
+
+(defsubst fuel-eval--factor-array (strs)
+  (format "V{ %S }" (mapconcat 'identity strs " ")))
+
+(defsubst fuel-eval--eval-strings (strs)
+  (let ((str (format "%s fuel-eval" (fuel-eval--factor-array strs))))
+    (fuel-eval--send/retort str)))
+
+(defsubst fuel-eval--eval-string (str)
+  (fuel-eval--eval-strings (list str)))
+
+(defun fuel-eval--eval-strings/context (strs)
+  (let ((usings (fuel-syntax--usings-update)))
+    (fuel-eval--send/retort
+     (format "%s %S %s fuel-eval-in-context"
+             (fuel-eval--factor-array strs)
+             (or fuel-syntax--current-vocab "f")
+             (if usings (fuel-eval--factor-array usings) "f")))))
+
+(defsubst fuel-eval--eval-string/context (str)
+  (fuel-eval--eval-strings/context (list str)))
+
+(defun fuel-eval--eval-region/context (begin end)
+  (let ((lines (split-string (buffer-substring-no-properties begin end)
+                             "[\f\n\r\v]+" t)))
+    (when (> (length lines) 0)
+      (fuel-eval--eval-strings/context lines))))
+
+\f
+(provide 'fuel-eval)
+;;; fuel-eval.el ends here
diff --git a/misc/fuel/fuel-font-lock.el b/misc/fuel/fuel-font-lock.el
new file mode 100644 (file)
index 0000000..c8673f7
--- /dev/null
@@ -0,0 +1,88 @@
+;;; fuel-font-lock.el -- font lock for factor code
+
+;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages, fuel, factor
+;; Start date: Wed Dec 03, 2008 21:40
+
+;;; Comentary:
+
+;; Font lock setup for highlighting Factor code.
+
+;;; Code:
+
+(require 'fuel-base)
+(require 'fuel-syntax)
+
+(require 'font-lock)
+
+\f
+;;; Faces:
+
+(defmacro fuel-font-lock--face (face def doc)
+  (let ((face (intern (format "factor-font-lock-%s" (symbol-name face))))
+        (def (intern (format "font-lock-%s-face" (symbol-name def)))))
+    `(defface ,face (face-default-spec ,def)
+       ,(format "Face for %s." doc)
+       :group 'factor-mode
+       :group 'faces)))
+
+(defmacro fuel-font-lock--faces-setup ()
+  (cons 'progn
+        (mapcar (lambda (f) (cons 'fuel-font-lock--face f))
+                '((comment comment "comments")
+                  (constructor type  "constructors (<foo>)")
+                  (declaration keyword "declaration words")
+                  (parsing-word keyword  "parsing words")
+                  (setter-word function-name "setter words (>>foo)")
+                  (stack-effect comment "stack effect specifications")
+                  (string string "strings")
+                  (symbol variable-name "name of symbol being defined")
+                  (type-name type "type names")
+                  (vocabulary-name constant "vocabulary names")
+                  (word function-name "word, generic or method being defined")))))
+
+(fuel-font-lock--faces-setup)
+
+\f
+;;; Font lock:
+
+(defconst fuel-font-lock--parsing-lock-keywords
+  (cons '("\\(P\\|SBUF\\)\"" 1 'factor-font-lock-parsing-word)
+        (mapcar (lambda (w) `(,(format "\\(^\\| \\)\\(%s\\)\\($\\| \\)" w)
+                         2 'factor-font-lock-parsing-word))
+                fuel-syntax--parsing-words)))
+
+(defconst fuel-font-lock--font-lock-keywords
+  `(,@fuel-font-lock--parsing-lock-keywords
+    (,fuel-syntax--stack-effect-regex . 'factor-font-lock-stack-effect)
+    (,fuel-syntax--parsing-words-ext-regex . 'factor-font-lock-parsing-word)
+    (,fuel-syntax--declaration-words-regex 1 'factor-font-lock-declaration)
+    (,fuel-syntax--word-definition-regex 2 'factor-font-lock-word)
+    (,fuel-syntax--type-definition-regex 2 'factor-font-lock-type-name)
+    (,fuel-syntax--method-definition-regex (1 'factor-font-lock-type-name)
+                                           (2 'factor-font-lock-word))
+    (,fuel-syntax--parent-type-regex 1 'factor-font-lock-type)
+    (,fuel-syntax--constructor-regex . 'factor-font-lock-constructor)
+    (,fuel-syntax--setter-regex . 'factor-font-lock-setter-word)
+    (,fuel-syntax--symbol-definition-regex 2 'factor-font-lock-symbol)
+    (,fuel-syntax--use-line-regex 1 'factor-font-lock-vocabulary-name))
+  "Font lock keywords definition for Factor mode.")
+
+(defun fuel-font-lock--font-lock-setup (&optional keywords no-syntax)
+  (set (make-local-variable 'comment-start) "! ")
+  (set (make-local-variable 'parse-sexp-lookup-properties) t)
+  (set (make-local-variable 'font-lock-comment-face) 'factor-font-lock-comment)
+  (set (make-local-variable 'font-lock-string-face) 'factor-font-lock-string)
+  (set (make-local-variable 'font-lock-defaults)
+       `(,(or keywords 'fuel-font-lock--font-lock-keywords)
+         nil nil nil nil
+         ,@(if no-syntax nil
+             (list (cons 'font-lock-syntactic-keywords
+                         fuel-syntax--syntactic-keywords))))))
+
+\f
+(provide 'fuel-font-lock)
+;;; fuel-font-lock.el ends here
diff --git a/misc/fuel/fuel-help.el b/misc/fuel/fuel-help.el
new file mode 100644 (file)
index 0000000..dcf17d2
--- /dev/null
@@ -0,0 +1,208 @@
+;;; fuel-help.el -- accessing Factor's help system
+
+;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages, fuel, factor
+;; Start date: Wed Dec 03, 2008 21:41
+
+;;; Comentary:
+
+;; Modes and functions interfacing Factor's 'see' and 'help'
+;; utilities, as well as an ElDoc-based autodoc mode.
+
+;;; Code:
+
+(require 'fuel-base)
+(require 'fuel-font-lock)
+(require 'fuel-eval)
+
+\f
+;;; Customization:
+
+(defgroup fuel-help nil
+  "Options controlling FUEL's help system"
+  :group 'fuel)
+
+(defcustom fuel-help-minibuffer-font-lock t
+  "Whether to use font lock for info messages in the minibuffer."
+  :group 'fuel-help
+  :type 'boolean)
+
+(defcustom fuel-help-always-ask t
+  "When enabled, always ask for confirmation in help prompts."
+  :type 'boolean
+  :group 'fuel-help)
+
+(defcustom fuel-help-use-minibuffer t
+  "When enabled, use the minibuffer for short help messages."
+  :type 'boolean
+  :group 'fuel-help)
+
+(defcustom fuel-help-mode-hook nil
+  "Hook run by `factor-help-mode'."
+  :type 'hook
+  :group 'fuel-help)
+
+(defface fuel-help-font-lock-headlines '((t (:bold t :weight bold)))
+  "Face for headlines in help buffers."
+  :group 'fuel-help
+  :group 'faces)
+
+\f
+;;; Autodoc mode:
+
+(defvar fuel-help--font-lock-buffer
+  (let ((buffer (get-buffer-create " *fuel help minibuffer messages*")))
+    (set-buffer buffer)
+    (fuel-font-lock--font-lock-setup)
+    buffer))
+
+(defun fuel-help--font-lock-str (str)
+  (set-buffer fuel-help--font-lock-buffer)
+  (erase-buffer)
+  (insert str)
+  (let ((font-lock-verbose nil)) (font-lock-fontify-buffer))
+  (buffer-string))
+
+(defun fuel-help--word-synopsis (&optional word)
+  (let ((word (or word (fuel-syntax-symbol-at-point)))
+        (fuel-eval--log nil))
+    (when word
+      (let ((ret (fuel-eval--eval-string/context
+                  (format "\\ %s synopsis fuel-eval-set-result" word))))
+        (when (not (fuel-eval--retort-error ret))
+          (if fuel-help-minibuffer-font-lock
+              (fuel-help--font-lock-str (fuel-eval--retort-result ret))
+            (fuel-eval--retort-result ret)))))))
+
+(make-variable-buffer-local
+ (defvar fuel-autodoc-mode-string " A"
+   "Modeline indicator for fuel-autodoc-mode"))
+
+(define-minor-mode fuel-autodoc-mode
+  "Toggle Fuel's Autodoc mode.
+With no argument, this command toggles the mode.
+Non-null prefix argument turns on the mode.
+Null prefix argument turns off the mode.
+
+When Autodoc mode is enabled, a synopsis of the word at point is
+displayed in the minibuffer."
+  :init-value nil
+  :lighter fuel-autodoc-mode-string
+  :group 'fuel
+
+  (set (make-local-variable 'eldoc-documentation-function)
+       (when fuel-autodoc-mode 'fuel-help--word-synopsis))
+  (set (make-local-variable 'eldoc-minor-mode-string) nil)
+  (eldoc-mode fuel-autodoc-mode)
+  (message "Fuel Autodoc %s" (if fuel-autodoc-mode "enabled" "disabled")))
+
+\f
+;;;; Factor help mode:
+
+(defvar fuel-help-mode-map (make-sparse-keymap)
+  "Keymap for Factor help mode.")
+
+(define-key fuel-help-mode-map [(return)] 'fuel-help)
+
+(defconst fuel-help--headlines
+  (regexp-opt '("Class description"
+                "Definition"
+                "Examples"
+                "Generic word contract"
+                "Inputs and outputs"
+                "Methods"
+                "Notes"
+                "Parent topics:"
+                "See also"
+                "Syntax"
+                "Vocabulary"
+                "Warning"
+                "Word description")
+              t))
+
+(defconst fuel-help--headlines-regexp (format "^%s" fuel-help--headlines))
+
+(defconst fuel-help--font-lock-keywords
+  `(,@fuel-font-lock--font-lock-keywords
+    (,fuel-help--headlines-regexp . 'fuel-help-font-lock-headlines)))
+
+(defun fuel-help-mode ()
+  "Major mode for displaying Factor documentation.
+\\{fuel-help-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map fuel-help-mode-map)
+  (setq mode-name "Factor Help")
+  (setq major-mode 'fuel-help-mode)
+
+  (fuel-font-lock--font-lock-setup fuel-help--font-lock-keywords t)
+
+  (set (make-local-variable 'view-no-disable-on-exit) t)
+  (view-mode)
+  (setq view-exit-action
+        (lambda (buffer)
+          ;; Use `with-current-buffer' to make sure that `bury-buffer'
+          ;; also removes BUFFER from the selected window.
+          (with-current-buffer buffer
+            (bury-buffer))))
+
+  (setq fuel-autodoc-mode-string "")
+  (fuel-autodoc-mode)
+  (run-mode-hooks 'fuel-help-mode-hook))
+
+(defun fuel-help--help-buffer ()
+  (with-current-buffer (get-buffer-create "*fuel-help*")
+    (fuel-help-mode)
+    (current-buffer)))
+
+(defvar fuel-help--history nil)
+
+(defun fuel-help--show-help (&optional see)
+  (let* ((def (fuel-syntax-symbol-at-point))
+         (prompt (format "See%s help on%s: " (if see " short" "")
+                         (if def (format " (%s)" def) "")))
+         (ask (or (not (memq major-mode '(factor-mode fuel-help-mode)))
+                  (not def)
+                  fuel-help-always-ask))
+         (def (if ask (read-string prompt nil 'fuel-help--history def) def))
+         (cmd (format "\\ %s %s" def (if see "see" "help")))
+         (fuel-eval--log nil)
+         (ret (fuel-eval--eval-string/context cmd))
+         (out (fuel-eval--retort-output ret)))
+    (if (or (fuel-eval--retort-error ret) (empty-string-p out))
+        (message "No help for '%s'" def)
+      (let ((hb (fuel-help--help-buffer))
+            (inhibit-read-only t)
+            (font-lock-verbose nil))
+        (set-buffer hb)
+        (erase-buffer)
+        (insert out)
+        (set-buffer-modified-p nil)
+        (pop-to-buffer hb)
+        (goto-char (point-min))))))
+
+\f
+;;; Interface: see/help commands
+
+(defun fuel-help-short (&optional arg)
+  "See a help summary of symbol at point.
+By default, the information is shown in the minibuffer. When
+called with a prefix argument, the information is displayed in a
+separate help buffer."
+  (interactive "P")
+  (if (if fuel-help-use-minibuffer (not arg) arg)
+      (fuel-help--word-synopsis)
+    (fuel-help--show-help t)))
+
+(defun fuel-help ()
+  "Show extended help about the symbol at point, using a help
+buffer."
+  (interactive)
+  (fuel-help--show-help))
+
+\f
+(provide 'fuel-help)
+;;; fuel-help.el ends here
diff --git a/misc/fuel/fuel-listener.el b/misc/fuel/fuel-listener.el
new file mode 100644 (file)
index 0000000..c741a77
--- /dev/null
@@ -0,0 +1,124 @@
+;;; fuel-listener.el --- starting the fuel listener
+
+;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+
+;;; Commentary:
+
+;; Utilities to maintain and switch to a factor listener comint
+;; buffer, with an accompanying major fuel-listener-mode.
+
+;;; Code:
+
+(require 'fuel-eval)
+(require 'fuel-base)
+(require 'comint)
+
+\f
+;;; Customization:
+
+(defgroup fuel-listener nil
+  "Interacting with a Factor listener inside Emacs"
+  :group 'fuel)
+
+(defcustom fuel-listener-factor-binary "~/factor/factor"
+  "Full path to the factor executable to use when starting a listener."
+  :type '(file :must-match t)
+  :group 'fuel-listener)
+
+(defcustom fuel-listener-factor-image "~/factor/factor.image"
+  "Full path to the factor image to use when starting a listener."
+  :type '(file :must-match t)
+  :group 'fuel-listener)
+
+(defcustom fuel-listener-use-other-window t
+  "Use a window other than the current buffer's when switching to
+the factor-listener buffer."
+  :type 'boolean
+  :group 'fuel-listener)
+
+(defcustom fuel-listener-window-allow-split t
+  "Allow window splitting when switching to the fuel listener
+buffer."
+  :type 'boolean
+  :group 'fuel-listener)
+
+\f
+;;; Fuel listener buffer/process:
+
+(defvar fuel-listener-buffer nil
+  "The buffer in which the Factor listener is running.")
+
+(defun fuel-listener--start-process ()
+  (let ((factor (expand-file-name fuel-listener-factor-binary))
+        (image (expand-file-name fuel-listener-factor-image)))
+    (unless (file-executable-p factor)
+      (error "Could not run factor: %s is not executable" factor))
+    (unless (file-readable-p image)
+      (error "Could not run factor: image file %s not readable" image))
+    (setq fuel-listener-buffer
+          (make-comint "fuel listener" factor nil "-run=fuel" (format "-i=%s" image)))
+    (with-current-buffer fuel-listener-buffer
+      (fuel-listener-mode))))
+
+(defun fuel-listener--process (&optional start)
+  (or (and (buffer-live-p fuel-listener-buffer)
+           (get-buffer-process fuel-listener-buffer))
+      (if (not start)
+          (error "No running factor listener (try M-x run-factor)")
+        (fuel-listener--start-process)
+        (fuel-listener--process))))
+
+(setq fuel-eval--default-proc-function 'fuel-listener--process)
+
+\f
+;;; Interface: starting fuel listener
+
+(defalias 'switch-to-factor 'run-factor)
+(defalias 'switch-to-fuel-listener 'run-factor)
+;;;###autoload
+(defun run-factor (&optional arg)
+  "Show the fuel-listener buffer, starting the process if needed."
+  (interactive)
+  (let ((buf (process-buffer (fuel-listener--process t)))
+        (pop-up-windows fuel-listener-window-allow-split))
+    (if fuel-listener-use-other-window
+        (pop-to-buffer buf)
+      (switch-to-buffer buf))))
+
+\f
+;;; Fuel listener mode:
+
+(defconst fuel-listener--prompt-regex "( [^)]* ) ")
+
+(defun fuel-listener--wait-for-prompt (&optional timeout)
+  (let ((proc (fuel-listener--process)))
+    (with-current-buffer fuel-listener-buffer
+      (goto-char comint-last-input-end)
+      (while (not (or (re-search-forward comint-prompt-regexp nil t)
+                      (not (accept-process-output proc timeout))))
+        (goto-char comint-last-input-end))
+      (goto-char (point-max)))))
+
+(defun fuel-listener--startup ()
+  (fuel-listener--wait-for-prompt)
+  (fuel-eval--send-string "USE: fuel")
+  (message "FUEL listener up and running!"))
+
+(define-derived-mode fuel-listener-mode comint-mode "Fuel Listener"
+  "Major mode for interacting with an inferior Factor listener process.
+\\{fuel-listener-mode-map}"
+  (set (make-local-variable 'comint-prompt-regexp)
+       fuel-listener--prompt-regex)
+  (set (make-local-variable 'comint-prompt-read-only) t)
+  (fuel-listener--startup))
+
+;; (define-key fuel-listener-mode-map "\C-w" 'comint-kill-region)
+;; (define-key fuel-listener-mode-map "\C-k" 'comint-kill-whole-line)
+
+\f
+(provide 'fuel-listener)
+;;; fuel-listener.el ends here
diff --git a/misc/fuel/fuel-mode.el b/misc/fuel/fuel-mode.el
new file mode 100644 (file)
index 0000000..bd9b127
--- /dev/null
@@ -0,0 +1,148 @@
+;;; fuel-mode.el -- Minor mode enabling FUEL niceties
+
+;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages, fuel, factor
+;; Start date: Sat Dec 06, 2008 00:52
+
+;;; Comentary:
+
+;; Enhancements to vanilla factor-mode (notably, listener interaction)
+;; enabled by means of a minor mode.
+
+;;; Code:
+
+(require 'factor-mode)
+(require 'fuel-base)
+(require 'fuel-syntax)
+(require 'fuel-font-lock)
+(require 'fuel-help)
+(require 'fuel-eval)
+(require 'fuel-listener)
+
+\f
+;;; Customization:
+
+(defgroup fuel-mode nil
+  "Mode enabling FUEL's ultimate abilities."
+  :group 'fuel)
+
+(defcustom fuel-mode-autodoc-p t
+  "Whether `fuel-autodoc-mode' gets enable by default in fuel buffers."
+  :group 'fuel-mode
+  :type 'boolean)
+
+\f
+;;; User commands
+
+(defun fuel-eval-region (begin end &optional arg)
+  "Sends region to Fuel's listener for evaluation.
+With prefix, switchs to the listener's buffer afterwards."
+  (interactive "r\nP")
+  (let* ((ret (fuel-eval--eval-region/context begin end))
+         (err (fuel-eval--retort-error ret)))
+    (message "%s" (or err (fuel--shorten-region begin end 70))))
+  (when arg (pop-to-buffer fuel-listener-buffer)))
+
+(defun fuel-eval-extended-region (begin end &optional arg)
+  "Sends region extended outwards to nearest definitions,
+to Fuel's listener for evaluation. With prefix, switchs to the
+listener's buffer afterwards."
+  (interactive "r\nP")
+  (fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
+                    (save-excursion (goto-char end) (mark-defun) (mark))))
+
+(defun fuel-eval-definition (&optional arg)
+  "Sends definition around point to Fuel's listener for evaluation.
+With prefix, switchs to the listener's buffer afterwards."
+  (interactive "P")
+  (save-excursion
+    (mark-defun)
+    (let* ((begin (point))
+           (end (mark)))
+      (unless (< begin end) (error "No evaluable definition around point"))
+      (fuel-eval-region begin end))))
+
+(defun fuel-edit-word-at-point (&optional arg)
+  "Opens a new window visiting the definition of the word at point.
+With prefix, asks for the word to edit."
+  (interactive "P")
+  (let* ((word (fuel-syntax-symbol-at-point))
+         (ask (or arg (not word)))
+         (word (if ask
+                   (read-string nil
+                                (format "Edit word%s: "
+                                        (if word (format " (%s)" word) ""))
+                                word)
+                 word)))
+    (let* ((ret (fuel-eval--eval-string/context
+                 (format "\\ %s fuel-get-edit-location" word)))
+           (err (fuel-eval--retort-error ret))
+           (loc (fuel-eval--retort-result ret)))
+      (when (or err (not loc) (not (listp loc)) (not (stringp (car loc))))
+        (error "Couldn't find edit location for '%s'" word))
+      (unless (file-readable-p (car loc))
+        (error "Couldn't open '%s' for read" (car loc)))
+      (find-file-other-window (car loc))
+      (goto-line (if (numberp (cadr loc)) (cadr loc) 1)))))
+
+\f
+;;; Minor mode definition:
+
+(make-variable-buffer-local
+ (defvar fuel-mode-string " F"
+   "Modeline indicator for fuel-mode"))
+
+(defvar fuel-mode-map (make-sparse-keymap)
+  "Key map for fuel-mode")
+
+(define-minor-mode fuel-mode
+  "Toggle Fuel's mode.
+With no argument, this command toggles the mode.
+Non-null prefix argument turns on the mode.
+Null prefix argument turns off the mode.
+
+When Fuel mode is enabled, a host of nice utilities for
+interacting with a factor listener is at your disposal.
+\\{fuel-mode-map}"
+  :init-value nil
+  :lighter fuel-mode-string
+  :group 'fuel
+  :keymap fuel-mode-map
+
+  (setq fuel-autodoc-mode-string "/A")
+  (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode)))
+
+\f
+;;; Keys:
+
+(defun fuel-mode--key-1 (k c)
+  (define-key fuel-mode-map (vector '(control ?c) k) c)
+  (define-key fuel-mode-map (vector '(control ?c) `(control ,k))  c))
+
+(defun fuel-mode--key (p k c)
+  (define-key fuel-mode-map (vector '(control ?c) `(control ,p) k) c)
+  (define-key fuel-mode-map (vector '(control ?c) `(control ,p) `(control ,k)) c))
+
+(fuel-mode--key-1 ?z 'run-factor)
+
+(define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
+(fuel-mode--key ?e ?x 'fuel-eval-definition)
+
+(fuel-mode--key-1 ?r 'fuel-eval-region)
+(fuel-mode--key ?e ?r 'fuel-eval-region)
+
+(define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
+(fuel-mode--key ?e ?e 'fuel-eval-extended-region)
+
+(define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
+
+(fuel-mode--key ?d ?a 'fuel-autodoc-mode)
+(fuel-mode--key ?d ?d 'fuel-help)
+(fuel-mode--key ?d ?s 'fuel-help-short)
+
+\f
+(provide 'fuel-mode)
+;;; fuel-mode.el ends here
diff --git a/misc/fuel/fuel-syntax.el b/misc/fuel/fuel-syntax.el
new file mode 100644 (file)
index 0000000..a0485f9
--- /dev/null
@@ -0,0 +1,281 @@
+;;; fuel-syntax.el --- auxiliar definitions for factor code navigation.
+
+;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+
+;;; Commentary:
+
+;; Auxiliar constants and functions to parse factor code.
+
+;;; Code:
+
+(require 'thingatpt)
+
+\f
+;;; Thing-at-point support for factor symbols:
+
+(defun fuel-syntax--beginning-of-symbol ()
+  "Move point to the beginning of the current symbol."
+  (while (eq (char-before) ?:) (backward-char))
+  (skip-syntax-backward "w_"))
+
+(defun fuel-syntax--end-of-symbol ()
+  "Move point to the end of the current symbol."
+  (skip-syntax-forward "w_")
+  (while (looking-at ":") (forward-char)))
+
+(put 'factor-symbol 'end-op 'fuel-syntax--end-of-symbol)
+(put 'factor-symbol 'beginning-op 'fuel-syntax--beginning-of-symbol)
+
+(defsubst fuel-syntax-symbol-at-point ()
+  (let ((s (substring-no-properties (thing-at-point 'factor-symbol))))
+    (and (> (length s) 0) s)))
+
+\f
+;;; Regexps galore:
+
+(defconst fuel-syntax--parsing-words
+  '("{" "}" "^:" "^::" ";" "<<" "<PRIVATE" ">>"
+    "BIN:" "BV{" "B{" "C:" "C-STRUCT:" "C-UNION:" "CHAR:" "CS{" "C{"
+    "DEFER:" "ERROR:" "EXCLUDE:" "FORGET:"
+    "GENERIC#" "GENERIC:" "HEX:" "HOOK:" "H{"
+    "IN:" "INSTANCE:" "INTERSECTION:"
+    "M:" "MACRO:" "MACRO::" "MAIN:" "MATH:" "METHOD:" "MIXIN:"
+    "OCT:" "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
+    "REQUIRE:"  "REQUIRES:" "SINGLETON:" "SLOT:" "SYMBOL:" "SYMBOLS:"
+    "TUPLE:" "T{" "t\\??" "TYPEDEF:"
+    "UNION:" "USE:" "USING:" "V{" "VARS:" "W{"))
+
+(defconst fuel-syntax--parsing-words-ext-regex
+  (regexp-opt '("B" "call-next-method" "delimiter" "f" "initial:" "read-only")
+              'words))
+
+(defconst fuel-syntax--declaration-words
+  '("flushable" "foldable" "inline" "parsing" "recursive"))
+
+(defconst fuel-syntax--declaration-words-regex
+  (regexp-opt fuel-syntax--declaration-words 'words))
+
+(defsubst fuel-syntax--second-word-regex (prefixes)
+  (format "^%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
+
+(defconst fuel-syntax--method-definition-regex
+  "^M: +\\([^ ]+\\) +\\([^ ]+\\)")
+
+(defconst fuel-syntax--word-definition-regex
+  (fuel-syntax--second-word-regex '(":" "::" "GENERIC:")))
+
+(defconst fuel-syntax--type-definition-regex
+  (fuel-syntax--second-word-regex '("TUPLE:" "SINGLETON:")))
+
+(defconst fuel-syntax--parent-type-regex "^TUPLE: +[^ ]+ +< +\\([^ ]+\\)")
+
+(defconst fuel-syntax--constructor-regex "<[^ >]+>")
+
+(defconst fuel-syntax--setter-regex "\\W>>[^ ]+\\b")
+
+(defconst fuel-syntax--symbol-definition-regex
+  (fuel-syntax--second-word-regex '("SYMBOL:" "VAR:")))
+
+(defconst fuel-syntax--stack-effect-regex " ( .* )")
+
+(defconst fuel-syntax--using-lines-regex "^USING: +\\([^;]+\\);")
+
+(defconst fuel-syntax--use-line-regex "^USE: +\\(.*\\)$")
+
+(defconst fuel-syntax--current-vocab-regex "^IN: +\\([^ \r\n\f]+\\)")
+
+(defconst fuel-syntax--sub-vocab-regex "^<\\([^ \n]+\\) *$")
+
+(defconst fuel-syntax--definition-starters-regex
+  (regexp-opt '("VARS" "TUPLE" "MACRO" "MACRO:" "M" ":" "")))
+
+(defconst fuel-syntax--definition-start-regex
+  (format "^\\(%s:\\) " fuel-syntax--definition-starters-regex))
+
+(defconst fuel-syntax--definition-end-regex
+  (format "\\(\\(^\\| +\\);\\( +%s\\)*\\($\\| +\\)\\)"
+          fuel-syntax--declaration-words-regex))
+
+(defconst fuel-syntax--single-liner-regex
+  (format "^%s" (regexp-opt '("DEFER:" "GENERIC:" "IN:"
+                              "PRIVATE>" "<PRIVATE"
+                              "SINGLETON:" "SYMBOL:" "USE:" "VAR:"))))
+
+(defconst fuel-syntax--begin-of-def-regex
+  (format "^USING: \\|\\(%s\\)\\|\\(%s .*\\)"
+          fuel-syntax--definition-start-regex
+          fuel-syntax--single-liner-regex))
+
+(defconst fuel-syntax--end-of-def-line-regex
+  (format "^.*%s" fuel-syntax--definition-end-regex))
+
+(defconst fuel-syntax--end-of-def-regex
+  (format "\\(%s\\)\\|\\(%s .*\\)"
+          fuel-syntax--end-of-def-line-regex
+          fuel-syntax--single-liner-regex))
+\f
+;;; Factor syntax table
+
+(defvar fuel-syntax--syntax-table
+  (let ((i 0)
+        (table (make-syntax-table)))
+    ;; Default is atom-constituent
+    (while (< i 256)
+      (modify-syntax-entry i "_   " table)
+      (setq i (1+ i)))
+
+    ;; Word components.
+    (setq i ?0)
+    (while (<= i ?9)
+      (modify-syntax-entry i "w   " table)
+      (setq i (1+ i)))
+    (setq i ?A)
+    (while (<= i ?Z)
+      (modify-syntax-entry i "w   " table)
+      (setq i (1+ i)))
+    (setq i ?a)
+    (while (<= i ?z)
+      (modify-syntax-entry i "w   " table)
+      (setq i (1+ i)))
+
+    ;; Whitespace
+    (modify-syntax-entry ?\t " " table)
+    (modify-syntax-entry ?\f " " table)
+    (modify-syntax-entry ?\r " " table)
+    (modify-syntax-entry ?  " " table)
+
+    ;; (end of) Comments
+    (modify-syntax-entry ?\n ">" table)
+
+    ;; Parenthesis
+    (modify-syntax-entry ?\[ "(]  " table)
+    (modify-syntax-entry ?\] ")[  " table)
+    (modify-syntax-entry ?{ "(}  " table)
+    (modify-syntax-entry ?} "){  " table)
+
+    (modify-syntax-entry ?\( "()" table)
+    (modify-syntax-entry ?\) ")(" table)
+
+    ;; Strings
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?\\ "/" table)
+    table)
+  "Syntax table used while in Factor mode.")
+
+(defconst fuel-syntax--syntactic-keywords
+  `(("\\(#!\\)" (1 "<"))
+    (" \\(!\\)" (1 "<"))
+    ("^\\(!\\)" (1 "<"))
+    ("\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
+    ("\\([[({]\\)\\([^ \"\n]\\)" (1 "_") (2 "_"))
+    ("\\([^ \"\n]\\)\\([])}]\\)" (1 "_") (2 "_"))))
+
+\f
+;;; Source code analysis:
+
+(defsubst fuel-syntax--brackets-depth ()
+  (nth 0 (syntax-ppss)))
+
+(defsubst fuel-syntax--brackets-start ()
+  (nth 1 (syntax-ppss)))
+
+(defun fuel-syntax--brackets-end ()
+  (save-excursion
+    (goto-char (fuel-syntax--brackets-start))
+    (condition-case nil
+        (progn (forward-sexp)
+               (1- (point)))
+      (error -1))))
+
+(defsubst fuel-syntax--indentation-at (pos)
+  (save-excursion (goto-char pos) (current-indentation)))
+
+(defsubst fuel-syntax--increased-indentation (&optional i)
+  (+ (or i (current-indentation)) factor-indent-width))
+(defsubst fuel-syntax--decreased-indentation (&optional i)
+  (- (or i (current-indentation)) factor-indent-width))
+
+(defsubst fuel-syntax--at-begin-of-def ()
+  (looking-at fuel-syntax--begin-of-def-regex))
+
+(defsubst fuel-syntax--at-end-of-def ()
+  (looking-at fuel-syntax--end-of-def-regex))
+
+(defsubst fuel-syntax--looking-at-emptiness ()
+  (looking-at "^[ \t]*$"))
+
+(defun fuel-syntax--at-setter-line ()
+  (save-excursion
+    (beginning-of-line)
+    (if (not (fuel-syntax--looking-at-emptiness))
+        (re-search-forward fuel-syntax--setter-regex (line-end-position) t)
+      (forward-line -1)
+      (or (fuel-syntax--at-constructor-line)
+          (fuel-syntax--at-setter-line)))))
+
+(defun fuel-syntax--at-constructor-line ()
+  (save-excursion
+    (beginning-of-line)
+    (re-search-forward fuel-syntax--constructor-regex (line-end-position) t)))
+
+(defsubst fuel-syntax--at-using ()
+  (looking-at fuel-syntax--using-lines-regex))
+
+(defsubst fuel-syntax--beginning-of-defun (&optional times)
+  (re-search-backward fuel-syntax--begin-of-def-regex nil t times))
+
+(defsubst fuel-syntax--end-of-defun ()
+  (re-search-forward fuel-syntax--end-of-def-regex nil t))
+
+\f
+;;; USING/IN:
+
+(make-variable-buffer-local
+ (defvar fuel-syntax--current-vocab nil))
+
+(make-variable-buffer-local
+ (defvar fuel-syntax--usings nil))
+
+(defun fuel-syntax--current-vocab ()
+  (let ((ip
+         (save-excursion
+           (when (re-search-backward fuel-syntax--current-vocab-regex nil t)
+             (setq fuel-syntax--current-vocab (match-string-no-properties 1))
+             (point)))))
+    (when ip
+      (let ((pp (save-excursion
+                  (when (re-search-backward fuel-syntax--sub-vocab-regex ip t)
+                    (point)))))
+        (when (and pp (> pp ip))
+          (let ((sub (match-string-no-properties 1)))
+            (unless (save-excursion (search-backward (format "%s>" sub) pp t))
+              (setq fuel-syntax--current-vocab
+                    (format "%s.%s" fuel-syntax--current-vocab (downcase sub)))))))))
+  fuel-syntax--current-vocab)
+
+(defun fuel-syntax--usings-update ()
+  (save-excursion
+    (setq fuel-syntax--usings (list (fuel-syntax--current-vocab)))
+    (while (re-search-backward fuel-syntax--using-lines-regex nil t)
+      (dolist (u (split-string (match-string-no-properties 1) nil t))
+        (push u fuel-syntax--usings)))
+    fuel-syntax--usings))
+
+(defsubst fuel-syntax--usings-update-hook ()
+  (fuel-syntax--usings-update)
+  nil)
+
+(defun fuel-syntax--enable-usings ()
+  (add-hook 'before-save-hook 'fuel-syntax--usings-update-hook nil t)
+  (fuel-syntax--usings-update))
+
+(defsubst fuel-syntax--usings ()
+  (or fuel-syntax--usings (fuel-syntax--usings-update)))
+
+\f
+(provide 'fuel-syntax)
+;;; fuel-syntax.el ends here
diff --git a/unmaintained/golden-section/authors.txt b/unmaintained/golden-section/authors.txt
new file mode 100644 (file)
index 0000000..6cfd5da
--- /dev/null
@@ -0,0 +1 @@
+Eduardo Cavazos
diff --git a/unmaintained/golden-section/deploy.factor b/unmaintained/golden-section/deploy.factor
new file mode 100755 (executable)
index 0000000..0aa3185
--- /dev/null
@@ -0,0 +1,12 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 1 }
+    { deploy-reflection 1 }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Golden Section" }
+}
diff --git a/unmaintained/golden-section/golden-section.factor b/unmaintained/golden-section/golden-section.factor
new file mode 100644 (file)
index 0000000..8d1e6b4
--- /dev/null
@@ -0,0 +1,54 @@
+
+USING: kernel namespaces math math.constants math.functions math.order
+       arrays sequences
+       opengl opengl.gl opengl.glu ui ui.render ui.gadgets ui.gadgets.theme
+       ui.gadgets.cartesian colors accessors combinators.cleave
+       processing.shapes ;
+
+IN: golden-section
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! omega(i) = 2*pi*i*(phi-1)
+
+! x(i) = 0.5*i*cos(omega(i))
+! y(i) = 0.5*i*sin(omega(i))
+
+! radius(i) = 10*sin((pi*i)/720)
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: omega ( i -- omega ) phi 1- * 2 * pi * ;
+
+: x ( i -- x ) [ omega cos ] [ 0.5 * ] bi * ;
+: y ( i -- y ) [ omega sin ] [ 0.5 * ] bi * ;
+
+: center ( i -- point ) { x y } 1arr ;
+
+: radius ( i -- radius ) pi * 720 / sin 10 * ;
+
+: color ( i -- i ) dup 360.0 / dup 0.25 1 rgba boa >fill-color ;
+
+: line-width ( i -- i ) dup radius 0.5 * 1 max glLineWidth ;
+
+: draw ( i -- ) [ center ] [ radius 1.5 * 2 * ] bi circle ;
+
+: dot ( i -- ) color line-width draw ;
+
+: golden-section ( -- ) 720 [ dot ] each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: <golden-section> ( -- gadget )
+  <cartesian>
+    {  600 600 }       >>pdim
+    { -400 400 }       x-range
+    { -400 400 }       y-range
+    [ golden-section ] >>action ;
+
+: golden-section-window ( -- )
+  [ <golden-section> "Golden Section" open-window ] with-ui ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+MAIN: golden-section-window
diff --git a/unmaintained/golden-section/summary.txt b/unmaintained/golden-section/summary.txt
new file mode 100644 (file)
index 0000000..5f44091
--- /dev/null
@@ -0,0 +1 @@
+Golden section demo
diff --git a/unmaintained/golden-section/tags.txt b/unmaintained/golden-section/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
diff --git a/unmaintained/jamshred/authors.txt b/unmaintained/jamshred/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/deploy.factor b/unmaintained/jamshred/deploy.factor
new file mode 100644 (file)
index 0000000..9a18cf1
--- /dev/null
@@ -0,0 +1,12 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 1 }
+    { deploy-reflection 1 }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Jamshred" }
+}
diff --git a/unmaintained/jamshred/game/authors.txt b/unmaintained/jamshred/game/authors.txt
new file mode 100755 (executable)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/game/game.factor b/unmaintained/jamshred/game/game.factor
new file mode 100644 (file)
index 0000000..9cb5bc7
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel opengl arrays sequences jamshred.log jamshred.player jamshred.sound jamshred.tunnel math math.constants math.vectors ;
+IN: jamshred.game
+
+TUPLE: jamshred sounds tunnel players running quit ;
+
+: <jamshred> ( -- jamshred )
+    <sounds> <random-tunnel> "Player 1" pick <player>
+    2dup swap play-in-tunnel 1array f f jamshred boa ;
+
+: jamshred-player ( jamshred -- player )
+    ! TODO: support more than one player
+    players>> first ;
+
+: jamshred-update ( jamshred -- )
+    dup running>> [
+        jamshred-player update-player
+    ] [ drop ] if ;
+
+: toggle-running ( jamshred -- )
+    dup running>> [
+        f >>running drop
+    ] [
+        [ jamshred-player moved ]
+        [ t >>running drop ] bi
+    ] if ;
+
+: mouse-moved ( x-radians y-radians jamshred -- )
+    jamshred-player -rot turn-player ;
+
+: units-per-full-roll ( -- n ) 50 ;
+
+: jamshred-roll ( jamshred n -- )
+    [ jamshred-player ] dip 2 pi * * units-per-full-roll / roll-player ;
+        
+: mouse-scroll-x ( jamshred x -- ) jamshred-roll ;
+
+: mouse-scroll-y ( jamshred y -- )
+    neg swap jamshred-player change-player-speed ;
diff --git a/unmaintained/jamshred/gl/authors.txt b/unmaintained/jamshred/gl/authors.txt
new file mode 100755 (executable)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/gl/gl.factor b/unmaintained/jamshred/gl/gl.factor
new file mode 100644 (file)
index 0000000..b78e7de
--- /dev/null
@@ -0,0 +1,99 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types jamshred.game jamshred.oint
+jamshred.player jamshred.tunnel kernel math math.constants
+math.functions math.vectors opengl opengl.gl opengl.glu
+opengl.demo-support sequences specialized-arrays.float ;
+IN: jamshred.gl
+
+: min-vertices 6 ; inline
+: max-vertices 32 ; inline
+
+: n-vertices ( -- n ) 32 ; inline
+
+! render enough of the tunnel that it looks continuous
+: n-segments-ahead ( -- n ) 60 ; inline
+: n-segments-behind ( -- n ) 40 ; inline
+
+: wall-drawing-offset ( -- n )
+    #! so that we can't see through the wall, we draw it a bit further away
+    0.15 ;
+
+: wall-drawing-radius ( segment -- r )
+    radius>> wall-drawing-offset + ;
+
+: wall-up ( segment -- v )
+    [ wall-drawing-radius ] [ up>> ] bi n*v ;
+
+: wall-left ( segment -- v )
+    [ wall-drawing-radius ] [ left>> ] bi n*v ;
+
+: segment-vertex ( theta segment -- vertex )
+    [
+        [ wall-up swap sin v*n ] [ wall-left swap cos v*n ] 2bi v+
+    ] [
+        location>> v+
+    ] bi ;
+
+: segment-vertex-normal ( vertex segment -- normal )
+    location>> swap v- normalize ;
+
+: segment-vertex-and-normal ( segment theta -- vertex normal )
+    swap [ segment-vertex ] keep dupd segment-vertex-normal ;
+
+: equally-spaced-radians ( n -- seq )
+    #! return a sequence of n numbers between 0 and 2pi
+    dup [ / pi 2 * * ] curry map ;
+
+: draw-segment-vertex ( segment theta -- )
+    over color>> gl-color segment-vertex-and-normal
+    gl-normal gl-vertex ;
+
+: draw-vertex-pair ( theta next-segment segment -- )
+    rot tuck draw-segment-vertex draw-segment-vertex ;
+
+: draw-segment ( next-segment segment -- )
+    GL_QUAD_STRIP [
+        [ draw-vertex-pair ] 2curry
+        n-vertices equally-spaced-radians F{ 0.0 } append swap each
+    ] do-state ;
+
+: draw-segments ( segments -- )
+    1 over length pick subseq swap [ draw-segment ] 2each ;
+
+: segments-to-render ( player -- segments )
+    dup nearest-segment>> number>> dup n-segments-behind -
+    swap n-segments-ahead + rot tunnel>> sub-tunnel ;
+
+: draw-tunnel ( player -- )
+    segments-to-render draw-segments ;
+
+: init-graphics ( width height -- )
+    GL_DEPTH_TEST glEnable
+    GL_SCISSOR_TEST glDisable
+    1.0 glClearDepth
+    0.0 0.0 0.0 0.0 glClearColor
+    GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
+    GL_PROJECTION glMatrixMode glLoadIdentity
+    dup 0 = [ 2drop ] [ / >float 45.0 swap 0.1 100.0 gluPerspective ] if
+    GL_MODELVIEW glMatrixMode glLoadIdentity
+    GL_LEQUAL glDepthFunc
+    GL_LIGHTING glEnable
+    GL_LIGHT0 glEnable
+    GL_FOG glEnable
+    GL_FOG_DENSITY 0.09 glFogf
+    GL_FRONT GL_AMBIENT_AND_DIFFUSE glColorMaterial
+    GL_COLOR_MATERIAL glEnable
+    GL_LIGHT0 GL_POSITION float-array{ 0.0 0.0 0.0 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_AMBIENT float-array{ 0.2 0.2 0.2 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_DIFFUSE float-array{ 1.0 1.0 1.0 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_SPECULAR float-array{ 1.0 1.0 1.0 1.0 } underlying>> glLightfv ;
+
+: player-view ( player -- )
+    [ location>> ]
+    [ [ location>> ] [ forward>> ] bi v+ ]
+    [ up>> ] tri gl-look-at ;
+
+: draw-jamshred ( jamshred width height -- )
+    init-graphics jamshred-player [ player-view ] [ draw-tunnel ] bi ;
+
diff --git a/unmaintained/jamshred/jamshred.factor b/unmaintained/jamshred/jamshred.factor
new file mode 100755 (executable)
index 0000000..d0b7441
--- /dev/null
@@ -0,0 +1,94 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays calendar jamshred.game jamshred.gl jamshred.player jamshred.log kernel math math.constants math.geometry.rect math.vectors namespaces sequences threads ui ui.backend ui.gadgets ui.gadgets.worlds ui.gestures ui.render ;
+IN: jamshred
+
+TUPLE: jamshred-gadget < gadget { jamshred jamshred } last-hand-loc ;
+
+: <jamshred-gadget> ( jamshred -- gadget )
+    jamshred-gadget new-gadget swap >>jamshred ;
+
+: default-width ( -- x ) 800 ;
+: default-height ( -- y ) 600 ;
+
+M: jamshred-gadget pref-dim*
+    drop default-width default-height 2array ;
+
+M: jamshred-gadget draw-gadget* ( gadget -- )
+    [ jamshred>> ] [ rect-dim first2 draw-jamshred ] bi ;
+
+: jamshred-loop ( gadget -- )
+    dup jamshred>> quit>> [
+        drop
+    ] [
+        [ jamshred>> jamshred-update ]
+        [ relayout-1 ]
+        [ 10 milliseconds sleep yield jamshred-loop ] tri
+    ] if ;
+
+: fullscreen ( gadget -- )
+    find-world t swap set-fullscreen* ;
+
+: no-fullscreen ( gadget -- )
+    find-world f swap set-fullscreen* ;
+
+: toggle-fullscreen ( world -- )
+    [ fullscreen? not ] keep set-fullscreen* ;
+
+M: jamshred-gadget graft* ( gadget -- )
+    [ jamshred-loop ] curry in-thread ;
+
+M: jamshred-gadget ungraft* ( gadget -- )
+    jamshred>> t swap (>>quit) ;
+
+: jamshred-restart ( jamshred-gadget -- )
+    <jamshred> >>jamshred drop ;
+
+: pix>radians ( n m -- theta )
+    / pi 4 * * ; ! 2 / / pi 2 * * ;
+
+: x>radians ( x gadget -- theta )
+    #! translate motion of x pixels to an angle
+    rect-dim first pix>radians neg ;
+
+: y>radians ( y gadget -- theta )
+    #! translate motion of y pixels to an angle
+    rect-dim second pix>radians ;
+
+: (handle-mouse-motion) ( jamshred-gadget mouse-motion -- )
+    over jamshred>> >r
+    [ first swap x>radians ] 2keep second swap y>radians
+    r> mouse-moved ;
+    
+: handle-mouse-motion ( jamshred-gadget -- )
+    hand-loc get [
+        over last-hand-loc>> [
+            v- (handle-mouse-motion) 
+        ] [ 2drop ] if* 
+    ] 2keep >>last-hand-loc drop ;
+
+: handle-mouse-scroll ( jamshred-gadget -- )
+    jamshred>> scroll-direction get
+    [ first mouse-scroll-x ]
+    [ second mouse-scroll-y ] 2bi ;
+
+: quit ( gadget -- )
+    [ no-fullscreen ] [ close-window ] bi ;
+
+jamshred-gadget H{
+    { T{ key-down f f "r" } [ jamshred-restart ] }
+    { T{ key-down f f " " } [ jamshred>> toggle-running ] }
+    { T{ key-down f f "f" } [ find-world toggle-fullscreen ] }
+    { T{ key-down f f "UP" } [ jamshred>> jamshred-player 1 swap change-player-speed ] }
+    { T{ key-down f f "DOWN" } [ jamshred>> jamshred-player -1 swap change-player-speed ] }
+    { T{ key-down f f "LEFT" } [ jamshred>> 1 jamshred-roll ] }
+    { T{ key-down f f "RIGHT" } [ jamshred>> -1 jamshred-roll ] }
+    { T{ key-down f f "q" } [ quit ] }
+    { T{ motion } [ handle-mouse-motion ] }
+    { T{ mouse-scroll } [ handle-mouse-scroll ] }
+} set-gestures
+
+: jamshred-window ( -- gadget )
+    [ <jamshred> <jamshred-gadget> dup "Jamshred" open-window ] with-ui ;
+
+MAIN: jamshred-window
diff --git a/unmaintained/jamshred/log/log.factor b/unmaintained/jamshred/log/log.factor
new file mode 100644 (file)
index 0000000..33498d8
--- /dev/null
@@ -0,0 +1,10 @@
+USING: kernel logging ;
+IN: jamshred.log
+
+LOG: (jamshred-log) DEBUG
+
+: with-jamshred-log ( quot -- )
+    "jamshred" swap with-logging ;
+
+: jamshred-log ( message -- )
+    [ (jamshred-log) ] with-jamshred-log ; ! ugly...
diff --git a/unmaintained/jamshred/oint/authors.txt b/unmaintained/jamshred/oint/authors.txt
new file mode 100755 (executable)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/oint/oint-tests.factor b/unmaintained/jamshred/oint/oint-tests.factor
new file mode 100644 (file)
index 0000000..401935f
--- /dev/null
@@ -0,0 +1,8 @@
+USING: jamshred.oint tools.test ;
+IN: jamshred.oint-tests
+
+[ { 0 -1 -1 } ] [ { 0 1 -1 } { 0 -1 0 } reflect ] unit-test
+[ { 0 1 0 } ] [ { 1 1 0 } { 1 0 0 } proj-perp ] unit-test
+[ { 1 0 0 } ] [ { 1 1 0 } { 0 1 0 } proj-perp ] unit-test
+[ { 1/2 -1/2 0 } ] [ { 1 0 0 } { 1 1 0 } proj-perp ] unit-test
+[ { -1/2 1/2 0 } ] [ { 0 1 0 } { 1 1 0 } proj-perp ] unit-test
diff --git a/unmaintained/jamshred/oint/oint.factor b/unmaintained/jamshred/oint/oint.factor
new file mode 100644 (file)
index 0000000..808e92a
--- /dev/null
@@ -0,0 +1,73 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays float-arrays kernel locals math math.constants math.functions math.matrices math.vectors math.quaternions random sequences ;
+IN: jamshred.oint
+
+! An oint is a point with three linearly independent unit vectors
+! given relative to that point. In jamshred a player's location and
+! direction are given by the player's oint. Similarly, a tunnel
+! segment's location and orientation are given by an oint.
+
+TUPLE: oint location forward up left ;
+C: <oint> oint
+
+: rotation-quaternion ( theta axis -- quaternion )
+    swap 2 / dup cos swap sin rot n*v first3 rect> >r rect> r> 2array ;
+
+: rotate-vector ( q qrecip v -- v )
+    v>q swap q* q* q>v ;
+
+: rotate-oint ( oint theta axis -- )
+    rotation-quaternion dup qrecip pick
+    [ forward>> rotate-vector >>forward ]
+    [ up>> rotate-vector >>up ]
+    [ left>> rotate-vector >>left ] 3tri drop ;
+
+: left-pivot ( oint theta -- )
+    over left>> rotate-oint ;
+
+: up-pivot ( oint theta -- )
+    over up>> rotate-oint ;
+
+: forward-pivot ( oint theta -- )
+    over forward>> rotate-oint ;
+
+: random-float+- ( n -- m )
+    #! find a random float between -n/2 and n/2
+    dup 10000 * >fixnum random 10000 / swap 2 / - ;
+
+: random-turn ( oint theta -- )
+    2 / 2dup random-float+- left-pivot random-float+- up-pivot ;
+
+: location+ ( v oint -- )
+    [ location>> v+ ] [ (>>location) ] bi ;
+
+: go-forward ( distance oint -- )
+    [ forward>> n*v ] [ location+ ] bi ;
+
+: distance-vector ( oint oint -- vector )
+    [ location>> ] bi@ swap v- ;
+
+: distance ( oint oint -- distance )
+    distance-vector norm ;
+
+: scalar-projection ( v1 v2 -- n )
+    #! the scalar projection of v1 onto v2
+    tuck v. swap norm / ;
+
+: proj-perp ( u v -- w )
+    dupd proj v- ;
+
+: perpendicular-distance ( oint oint -- distance )
+    tuck distance-vector swap 2dup left>> scalar-projection abs
+    -rot up>> scalar-projection abs + ;
+
+:: reflect ( v n -- v' )
+    #! bounce v on a surface with normal n
+    v v n v. n n v. / 2 * n n*v v- ;
+
+: half-way ( p1 p2 -- p3 )
+    over v- 2 v/n v+ ;
+
+: half-way-between-oints ( o1 o2 -- p )
+    [ location>> ] bi@ half-way ;
diff --git a/unmaintained/jamshred/player/authors.txt b/unmaintained/jamshred/player/authors.txt
new file mode 100755 (executable)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/player/player.factor b/unmaintained/jamshred/player/player.factor
new file mode 100644 (file)
index 0000000..72f26a2
--- /dev/null
@@ -0,0 +1,137 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors colors combinators float-arrays jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel locals math math.constants math.order math.ranges math.vectors math.matrices sequences shuffle strings system ;
+IN: jamshred.player
+
+TUPLE: player < oint
+    { name string }
+    { sounds sounds }
+    tunnel
+    nearest-segment
+    { last-move integer }
+    { speed float } ;
+
+! speeds are in GL units / second
+: default-speed ( -- speed ) 1.0 ;
+: max-speed ( -- speed ) 30.0 ;
+
+: <player> ( name sounds -- player )
+    [ F{ 0 0 5 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } ] 2dip
+    f f 0 default-speed player boa ;
+
+: turn-player ( player x-radians y-radians -- )
+    >r over r> left-pivot up-pivot ;
+
+: roll-player ( player z-radians -- )
+    forward-pivot ;
+
+: to-tunnel-start ( player -- )
+    [ tunnel>> first dup location>> ]
+    [ tuck (>>location) (>>nearest-segment) ] bi ;
+
+: play-in-tunnel ( player segments -- )
+    >>tunnel to-tunnel-start ;
+
+: update-nearest-segment ( player -- )
+    [ tunnel>> ] [ dup nearest-segment>> nearest-segment ]
+    [ (>>nearest-segment) ] tri ;
+
+: update-time ( player -- seconds-passed )
+    millis swap [ last-move>> - 1000 / ] [ (>>last-move) ] 2bi ;
+
+: moved ( player -- ) millis swap (>>last-move) ;
+
+: speed-range ( -- range )
+    max-speed [0,b] ;
+
+: change-player-speed ( inc player -- )
+    [ + speed-range clamp-to-range ] change-speed drop ;
+
+: multiply-player-speed ( n player -- )
+    [ * speed-range clamp-to-range ] change-speed drop ; 
+
+: distance-to-move ( seconds-passed player -- distance )
+    speed>> * ;
+
+: bounce ( d-left player -- d-left' player )
+    {
+        [ dup nearest-segment>> bounce-off-wall ]
+        [ sounds>> bang ]
+        [ 3/4 swap multiply-player-speed ]
+        [ ]
+    } cleave ;
+
+:: (distance) ( heading player -- current next location heading )
+    player nearest-segment>>
+    player [ tunnel>> ] [ nearest-segment>> ] bi heading heading-segment
+    player location>> heading ;
+
+: distance-to-heading-segment ( heading player -- distance )
+    (distance) distance-to-next-segment ;
+
+: distance-to-heading-segment-area ( heading player -- distance )
+    (distance) distance-to-next-segment-area ;
+
+: distance-to-collision ( player -- distance )
+    dup nearest-segment>> (distance-to-collision) ;
+
+: almost-to-collision ( player -- distance )
+    distance-to-collision 0.1 - dup 0 < [ drop 0 ] when ;
+
+: from ( player -- radius distance-from-centre )
+    [ nearest-segment>> dup radius>> swap ] [ location>> ] bi
+    distance-from-centre ;
+
+: distance-from-wall ( player -- distance ) from - ;
+: fraction-from-centre ( player -- fraction ) from swap / ;
+: fraction-from-wall ( player -- fraction )
+    fraction-from-centre 1 swap - ;
+
+: update-nearest-segment2 ( heading player -- )
+    2dup distance-to-heading-segment-area 0 <= [
+        [ tunnel>> ] [ nearest-segment>> rot heading-segment ]
+        [ (>>nearest-segment) ] tri
+    ] [
+        2drop
+    ] if ;
+
+:: move-player-on-heading ( d-left player distance heading -- d-left' player )
+    [let* | d-to-move [ d-left distance min ]
+            move-v [ d-to-move heading n*v ] |
+        move-v player location+
+        heading player update-nearest-segment2
+        d-left d-to-move - player ] ;
+
+: distance-to-move-freely ( player -- distance )
+    [ almost-to-collision ]
+    [ [ forward>> ] keep distance-to-heading-segment-area ] bi min ;
+
+: ?move-player-freely ( d-left player -- d-left' player )
+    over 0 > [
+        ! must make sure we are moving a significant distance, otherwise
+        ! we can recurse endlessly due to floating-point imprecision.
+        ! (at least I /think/ that's what causes it...)
+        dup distance-to-move-freely dup 0.1 > [
+            over forward>> move-player-on-heading ?move-player-freely
+        ] [ drop ] if
+    ] when ;
+
+: drag-heading ( player -- heading )
+    [ forward>> ] [ nearest-segment>> forward>> proj ] bi ;
+
+: drag-player ( d-left player -- d-left' player )
+    dup [ [ drag-heading ] keep distance-to-heading-segment-area ]
+    [ drag-heading move-player-on-heading ] bi ;
+
+: (move-player) ( d-left player -- d-left' player )
+    ?move-player-freely over 0 > [
+        ! bounce
+        drag-player
+        (move-player)
+    ] when ;
+
+: move-player ( player -- )
+    [ update-time ] [ distance-to-move ] [ (move-player) 2drop ] tri ;
+
+: update-player ( player -- )
+    [ move-player ] [ nearest-segment>> white swap (>>color) ] bi ;
diff --git a/unmaintained/jamshred/sound/bang.wav b/unmaintained/jamshred/sound/bang.wav
new file mode 100644 (file)
index 0000000..b15af14
Binary files /dev/null and b/unmaintained/jamshred/sound/bang.wav differ
diff --git a/unmaintained/jamshred/sound/sound.factor b/unmaintained/jamshred/sound/sound.factor
new file mode 100644 (file)
index 0000000..c19c676
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors io.files kernel openal sequences ;
+IN: jamshred.sound
+
+TUPLE: sounds bang ;
+
+: assign-sound ( source wav-path -- )
+    resource-path create-buffer-from-wav AL_BUFFER swap set-source-param ;
+
+: <sounds> ( -- sounds )
+    init-openal 1 gen-sources first sounds boa
+    dup bang>> "extra/jamshred/sound/bang.wav" assign-sound ;
+
+: bang ( sounds -- ) bang>> source-play check-error ;
diff --git a/unmaintained/jamshred/summary.txt b/unmaintained/jamshred/summary.txt
new file mode 100644 (file)
index 0000000..e26fc1c
--- /dev/null
@@ -0,0 +1 @@
+A simple 3d tunnel racing game
diff --git a/unmaintained/jamshred/tags.txt b/unmaintained/jamshred/tags.txt
new file mode 100644 (file)
index 0000000..8ae5957
--- /dev/null
@@ -0,0 +1,2 @@
+applications
+games
diff --git a/unmaintained/jamshred/tunnel/authors.txt b/unmaintained/jamshred/tunnel/authors.txt
new file mode 100755 (executable)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/jamshred/tunnel/tunnel-tests.factor b/unmaintained/jamshred/tunnel/tunnel-tests.factor
new file mode 100644 (file)
index 0000000..9486713
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays float-arrays jamshred.oint jamshred.tunnel kernel math.vectors sequences tools.test ;
+IN: jamshred.tunnel.tests
+
+[ 0 ] [ T{ segment f { 0 0 0 } f f f 0 }
+        T{ segment f { 1 1 1 } f f f 1 }
+        T{ oint f { 0 0 0.25 } }
+        nearer-segment number>> ] unit-test
+
+[ 0 ] [ T{ oint f { 0 0 0 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+[ 1 ] [ T{ oint f { 0 0 -1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+[ 2 ] [ T{ oint f { 0 0.1 -2.1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+
+[ 3 ] [ <straight-tunnel> T{ oint f { 0 0 -3.25 } } 0 nearest-segment-forward number>> ] unit-test
+
+[ F{ 0 0 0 } ] [ <straight-tunnel> T{ oint f { 0 0 -0.25 } } over first nearest-segment location>> ] unit-test
+
+: test-segment-oint ( -- oint )
+    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint> ;
+
+[ { -1 0 0 } ] [ test-segment-oint { 1 0 0 } vector-to-centre ] unit-test
+[ { 1 0 0 } ] [ test-segment-oint { -1 0 0 } vector-to-centre ] unit-test
+[ { 0 -1 0 } ] [ test-segment-oint { 0 1 0 } vector-to-centre ] unit-test
+[ { 0 1 0 } ] [ test-segment-oint { 0 -1 0 } vector-to-centre ] unit-test
+[ { -1 0 0 } ] [ test-segment-oint { 1 0 -1 } vector-to-centre ] unit-test
+[ { 1 0 0 } ] [ test-segment-oint { -1 0 -1 } vector-to-centre ] unit-test
+[ { 0 -1 0 } ] [ test-segment-oint { 0 1 -1 } vector-to-centre ] unit-test
+[ { 0 1 0 } ] [ test-segment-oint { 0 -1 -1 } vector-to-centre ] unit-test
+
+: simplest-straight-ahead ( -- oint segment )
+    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint>
+    initial-segment ;
+
+[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-heading ] unit-test
+[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-relative-location ] unit-test
+
+: simple-collision-up ( -- oint segment )
+    { 0 0 0 } { 0 1 0 } { 0 0 1 } { -1 0 0 } <oint>
+    initial-segment ;
+
+[ { 0.0 1.0 0.0 } ] [ simple-collision-up sideways-heading ] unit-test
+[ { 0.0 0.0 0.0 } ] [ simple-collision-up sideways-relative-location ] unit-test
+[ { 0.0 1.0 0.0 } ]
+[ simple-collision-up collision-vector 0 0 0 3array v+ ] unit-test
diff --git a/unmaintained/jamshred/tunnel/tunnel.factor b/unmaintained/jamshred/tunnel/tunnel.factor
new file mode 100755 (executable)
index 0000000..52f2d38
--- /dev/null
@@ -0,0 +1,167 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays colors combinators float-arrays kernel
+locals math math.constants math.matrices math.order math.ranges
+math.vectors math.quadratic random sequences vectors jamshred.oint ;
+IN: jamshred.tunnel
+
+: n-segments ( -- n ) 5000 ; inline
+
+TUPLE: segment < oint number color radius ;
+C: <segment> segment
+
+: segment-number++ ( segment -- )
+    [ number>> 1+ ] keep (>>number) ;
+
+: random-color ( -- color )
+    { 100 100 100 } [ random 100 / >float ] map first3 1.0 <rgba> ;
+
+: tunnel-segment-distance ( -- n ) 0.4 ;
+: random-rotation-angle ( -- theta ) pi 20 / ;
+
+: random-segment ( previous-segment -- segment )
+    clone dup random-rotation-angle random-turn
+    tunnel-segment-distance over go-forward
+    random-color >>color dup segment-number++ ;
+
+: (random-segments) ( segments n -- segments )
+    dup 0 > [
+        >r dup peek random-segment over push r> 1- (random-segments)
+    ] [ drop ] if ;
+
+: default-segment-radius ( -- r ) 1 ;
+
+: initial-segment ( -- segment )
+    F{ 0 0 0 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 }
+    0 random-color default-segment-radius <segment> ;
+
+: random-segments ( n -- segments )
+    initial-segment 1vector swap (random-segments) ;
+
+: simple-segment ( n -- segment )
+    [ F{ 0 0 -1 } n*v F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } ] keep
+    random-color default-segment-radius <segment> ;
+
+: simple-segments ( n -- segments )
+    [ simple-segment ] map ;
+
+: <random-tunnel> ( -- segments )
+    n-segments random-segments ;
+
+: <straight-tunnel> ( -- segments )
+    n-segments simple-segments ;
+
+: sub-tunnel ( from to segments -- segments )
+    #! return segments between from and to, after clamping from and to to
+    #! valid values
+    [ sequence-index-range [ clamp-to-range ] curry bi@ ] keep <slice> ;
+
+: nearer-segment ( segment segment oint -- segment )
+    #! return whichever of the two segments is nearer to the oint
+    >r 2dup r> tuck distance >r distance r> < -rot ? ;
+
+: (find-nearest-segment) ( nearest next oint -- nearest ? )
+    #! find the nearest of 'next' and 'nearest' to 'oint', and return
+    #! t if the nearest hasn't changed
+    pick >r nearer-segment dup r> = ;
+
+: find-nearest-segment ( oint segments -- segment )
+    dup first swap rest-slice rot [ (find-nearest-segment) ] curry
+    find 2drop ;
+    
+: nearest-segment-forward ( segments oint start -- segment )
+    rot dup length swap <slice> find-nearest-segment ;
+
+: nearest-segment-backward ( segments oint start -- segment )
+    swapd 1+ 0 spin <slice> <reversed> find-nearest-segment ;
+
+: nearest-segment ( segments oint start-segment -- segment )
+    #! find the segment nearest to 'oint', and return it.
+    #! start looking at segment 'start-segment'
+    number>> over >r
+    [ nearest-segment-forward ] 3keep
+    nearest-segment-backward r> nearer-segment ;
+
+: get-segment ( segments n -- segment )
+    over sequence-index-range clamp-to-range swap nth ;
+
+: next-segment ( segments current-segment -- segment )
+    number>> 1+ get-segment ;
+
+: previous-segment ( segments current-segment -- segment )
+    number>> 1- get-segment ;
+
+: heading-segment ( segments current-segment heading -- segment )
+    #! the next segment on the given heading
+    over forward>> v. 0 <=> {
+        { +gt+ [ next-segment ] }
+        { +lt+ [ previous-segment ] }
+        { +eq+ [ nip ] } ! current segment
+    } case ;
+
+:: distance-to-next-segment ( current next location heading -- distance )
+    [let | cf [ current forward>> ] |
+        cf next location>> v. cf location v. - cf heading v. / ] ;
+
+:: distance-to-next-segment-area ( current next location heading -- distance )
+    [let | cf [ current forward>> ]
+           h [ next current half-way-between-oints ] |
+        cf h v. cf location v. - cf heading v. / ] ;
+
+: vector-to-centre ( seg loc -- v )
+    over location>> swap v- swap forward>> proj-perp ;
+
+: distance-from-centre ( seg loc -- distance )
+    vector-to-centre norm ;
+
+: wall-normal ( seg oint -- n )
+    location>> vector-to-centre normalize ;
+
+: distant ( -- n ) 1000 ;
+
+: max-real ( a b -- c )
+    #! sometimes collision-coefficient yields complex roots, so we ignore these (hack)
+    dup real? [
+        over real? [ max ] [ nip ] if
+    ] [
+        drop dup real? [ drop distant ] unless
+    ] if ;
+
+:: collision-coefficient ( v w r -- c )
+    v norm 0 = [
+        distant
+    ] [
+        [let* | a [ v dup v. ]
+                b [ v w v. 2 * ]
+                c [ w dup v. r sq - ] |
+            c b a quadratic max-real ]
+    ] if ;
+
+: sideways-heading ( oint segment -- v )
+    [ forward>> ] bi@ proj-perp ;
+
+: sideways-relative-location ( oint segment -- loc )
+    [ [ location>> ] bi@ v- ] keep forward>> proj-perp ;
+
+: (distance-to-collision) ( oint segment -- distance )
+    [ sideways-heading ] [ sideways-relative-location ]
+    [ nip radius>> ] 2tri collision-coefficient ;
+
+: collision-vector ( oint segment -- v )
+    dupd (distance-to-collision) swap forward>> n*v ;
+
+: bounce-forward ( segment oint -- )
+    [ wall-normal ] [ forward>> swap reflect ] [ (>>forward) ] tri ;
+
+: bounce-left ( segment oint -- )
+    #! must be done after forward
+    [ forward>> vneg ] dip [ left>> swap reflect ]
+    [ forward>> proj-perp normalize ] [ (>>left) ] tri ;
+
+: bounce-up ( segment oint -- )
+    #! must be done after forward and left!
+    nip [ forward>> ] [ left>> cross ] [ (>>up) ] tri ;
+
+: bounce-off-wall ( oint segment -- )
+    swap [ bounce-forward ] [ bounce-left ] [ bounce-up ] 2tri ;
+
diff --git a/unmaintained/lisp/authors.txt b/unmaintained/lisp/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/unmaintained/lisp/lisp-docs.factor b/unmaintained/lisp/lisp-docs.factor
new file mode 100644 (file)
index 0000000..c970a1e
--- /dev/null
@@ -0,0 +1,22 @@
+IN: lisp
+USING: help.markup help.syntax ;
+HELP: <LISP
+{ $description "parsing word which converts the lisp code between <LISP and LISP> into factor quotations and calls it" }
+{ $see-also lisp-string>factor } ;
+
+HELP: lisp-string>factor
+{ $values { "str"  "a string of lisp code" } { "quot" "the quotation the lisp compiles into" } }
+{ $description "Turns a string of lisp into a factor quotation" } ;
+
+ARTICLE: "lisp" "Lisp in Factor"
+"This is a simple implementation of a Lisp dialect, which somewhat resembles Scheme." $nl
+"It works in two main stages: "
+{ $list
+  { "Parse (via "  { $vocab-link "lisp.parser" } " the Lisp code into a "
+    { $snippet "s-exp"  } " tuple." }
+  { "Transform the " { $snippet "s-exp" } " into a Factor quotation, via " { $link convert-form } }
+}
+
+{ $subsection "lisp.parser" } ;
+
+ABOUT: "lisp"
\ No newline at end of file
diff --git a/unmaintained/lisp/lisp-tests.factor b/unmaintained/lisp/lisp-tests.factor
new file mode 100644 (file)
index 0000000..5f849c4
--- /dev/null
@@ -0,0 +1,94 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: lisp lisp.parser tools.test sequences math kernel parser arrays lists
+quotations ;
+
+IN: lisp.test
+
+[
+    define-lisp-builtins
+    
+    { 5 } [
+        "(+ 2 3)" lisp-eval
+    ] unit-test
+    
+    { 8.3 } [
+        "(- 10.4 2.1)" lisp-eval
+    ] unit-test
+    
+    { 3 } [
+        "((lambda (x y) (+ x y)) 1 2)" lisp-eval
+    ] unit-test
+    
+    { 42 } [
+        "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval
+    ] unit-test
+    
+    { "b" } [
+        "(cond (#f \"a\") (#t \"b\"))" lisp-eval
+    ] unit-test
+    
+    { "b" } [
+        "(cond ((< 1 2) \"b\") (#t \"a\"))" lisp-eval
+    ] unit-test
+        
+    { +nil+ } [
+        "(list)" lisp-eval
+    ] unit-test
+    
+    { { 1 2 3 4 5 } } [
+        "(list 1 2 3 4 5)" lisp-eval list>seq
+    ] unit-test
+    
+    { { 1 2 { 3 { 4 } 5 } } } [
+        "(list 1 2 (list 3 (list 4) 5))" lisp-eval cons>seq
+    ] unit-test
+    
+    { 5 } [
+        "(begin (+ 1 4))" lisp-eval
+    ] unit-test
+    
+    { 5 } [
+        "(begin (+ 5 6) (+ 1 4))" lisp-eval
+    ] unit-test
+    
+    { t } [
+        T{ lisp-symbol f "if" } lisp-macro?
+    ] unit-test
+    
+    { 1 } [
+        "(if #t 1 2)" lisp-eval
+    ] unit-test
+    
+    { 3 } [
+        "((lambda (x) (if x (+ 1 2) (- 3 5))) #t)" lisp-eval
+    ] unit-test
+    
+    { { 5 4 3 } } [
+        "((lambda (x &rest xs) (cons x xs)) 5 4 3)" lisp-eval cons>seq
+    ] unit-test
+    
+    { { 5 } } [
+        "((lambda (x &rest xs) (cons x xs)) 5)" lisp-eval cons>seq
+    ] unit-test
+    
+    { { 1 2 3 4 } } [
+        "((lambda (&rest xs) xs) 1 2 3 4)" lisp-eval cons>seq
+    ] unit-test
+    
+    { 10 } [
+        <LISP (begin (+ 1 2) (+ 9 1)) LISP>
+    ] unit-test
+    
+    { 4 } [
+        <LISP ((lambda (x y) (if x (+ 1 y) (+ 2 y))) #t 3) LISP>
+    ] unit-test
+    
+    { { 3 3 4 } } [
+        <LISP (defun foo (x y &rest z)
+                  (cons (+ x y) z))
+              (foo 1 2 3 4)
+        LISP> cons>seq
+    ] unit-test
+    
+] with-interactive-vocabs
diff --git a/unmaintained/lisp/lisp.factor b/unmaintained/lisp/lisp.factor
new file mode 100644 (file)
index 0000000..4a93350
--- /dev/null
@@ -0,0 +1,178 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel peg sequences arrays strings 
+namespaces combinators math locals locals.private locals.backend accessors
+vectors syntax lisp.parser assocs parser words
+quotations fry lists summary combinators.short-circuit continuations multiline ;
+IN: lisp
+
+DEFER: convert-form
+DEFER: funcall
+DEFER: lookup-var
+DEFER: lookup-macro
+DEFER: lisp-macro?
+DEFER: lisp-var?
+DEFER: define-lisp-macro
+
+! Functions to convert s-exps to quotations
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: convert-body ( cons -- quot )
+    [ ] [ convert-form compose ] foldl ; inline
+
+: convert-cond ( cons -- quot )
+    cdr [ 2car [ convert-form ] bi@ 2array ]
+    { } lmap-as '[ _ cond ] ;
+
+: convert-general-form ( cons -- quot )
+    uncons [ convert-body ] [ convert-form ] bi* '[ _ @ funcall ] ;
+
+! words for convert-lambda
+<PRIVATE
+: localize-body ( assoc body -- newbody )
+    {
+      { [ dup list? ] [ [ lisp-symbol? ] rot '[ [ name>> _ at ] [ ] bi or ] traverse ] }
+      { [ dup lisp-symbol? ] [ name>> swap at ] }
+     [ nip ]
+    } cond ;
+
+: localize-lambda ( body vars -- newvars newbody )
+    swap [ make-locals dup push-locals ] dip
+    dupd [ localize-body convert-form ] with lmap>array
+    >quotation swap pop-locals ;
+
+: split-lambda ( cons -- body-cons vars-seq )
+    cdr uncons [ name>> ] lmap>array ; inline
+
+: rest-lambda ( body vars -- quot )
+    "&rest" swap [ remove ] [ index ] 2bi
+    [ localize-lambda <lambda> lambda-rewrite call ] dip
+    swap '[ _ cut '[ @ _ seq>list ] call _ call call ] 1quotation ;
+
+: normal-lambda ( body vars -- quot )
+    localize-lambda <lambda> lambda-rewrite '[ @ compose call call ] 1quotation ;
+PRIVATE>
+
+: convert-lambda ( cons -- quot )
+    split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ;
+
+: convert-quoted ( cons -- quot )
+    cadr 1quotation ;
+
+: convert-defmacro ( cons -- quot )
+    cdr [ convert-lambda ] [ car name>> ] bi define-lisp-macro [ ] ;
+
+: macro-expand ( cons -- quot )
+    uncons [ list>seq >quotation ] [ lookup-macro ] bi* call call ;
+
+: expand-macros ( cons -- cons )
+    dup list? [ [ expand-macros ] lmap dup car lisp-macro? [ macro-expand expand-macros ] when ] when ;
+    
+: convert-begin ( cons -- quot )
+    cdr [ convert-form ] [ ] lmap-as [ 1 tail* ] [ but-last ] bi
+    [ '[ { } _ with-datastack drop ] ] map prepend '[ _ [ call ] each ] ;
+
+: form-dispatch ( cons lisp-symbol -- quot )
+    name>>
+    { { "lambda" [ convert-lambda ] }
+      { "defmacro" [ convert-defmacro ] }
+      { "quote" [ convert-quoted ] }
+      { "cond" [ convert-cond ] }
+      { "begin" [ convert-begin ] }
+     [ drop convert-general-form ]
+    } case ;
+
+: convert-list-form ( cons -- quot )
+    dup car
+    {
+      { [ dup lisp-symbol? ] [ form-dispatch ] }
+     [ drop convert-general-form ]
+    } cond ;
+
+: convert-form ( lisp-form -- quot )
+    {
+      { [ dup cons? ] [ convert-list-form ] }
+      { [ dup lisp-var? ] [ lookup-var 1quotation ] }
+      { [ dup lisp-symbol? ] [ '[ _ lookup-var ] ] }
+     [ 1quotation ]
+    } cond ;
+
+: lisp-string>factor ( str -- quot )
+    lisp-expr expand-macros convert-form ;
+
+: lisp-eval ( str -- * )
+    lisp-string>factor call ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: lisp-env
+SYMBOL: macro-env
+
+ERROR: no-such-var variable-name ;
+M: no-such-var summary drop "No such variable" ;
+
+: init-env ( -- )
+    H{ } clone lisp-env set
+    H{ } clone macro-env set ;
+
+: lisp-define ( quot name -- )
+    lisp-env get set-at ;
+    
+: define-lisp-var ( lisp-symbol body --  )
+    swap name>> lisp-define ;
+
+: lisp-get ( name -- word )
+    lisp-env get at ;
+
+: lookup-var ( lisp-symbol -- quot )
+    [ name>> ] [ lisp-var? ] bi [ lisp-get ] [ no-such-var ] if ;
+
+: lisp-var? ( lisp-symbol -- ? )
+    dup lisp-symbol? [ name>> lisp-env get key? ] [ drop f ] if ;
+
+: funcall ( quot sym -- * )
+    [ 1array [ call ] with-datastack >quotation ] dip curry call ; inline
+
+: define-primitive ( name vocab word -- )
+    swap lookup 1quotation '[ _ compose call ] swap lisp-define ;
+
+: lookup-macro ( lisp-symbol -- lambda )
+    name>> macro-env get at ;
+
+: define-lisp-macro ( quot name -- )
+    macro-env get set-at ;
+
+: lisp-macro? ( car -- ? )
+    dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ;
+
+: define-lisp-builtins ( -- )
+   init-env
+
+   f "#f" lisp-define
+   t "#t" lisp-define
+
+   "+" "math" "+" define-primitive
+   "-" "math" "-" define-primitive
+   "<" "math" "<" define-primitive
+   ">" "math" ">" define-primitive
+
+   "cons" "lists" "cons" define-primitive
+   "car" "lists" "car" define-primitive
+   "cdr" "lists" "cdr" define-primitive
+   "append" "lists" "lappend" define-primitive
+   "nil" "lists" "nil" define-primitive
+   "nil?" "lists" "nil?" define-primitive
+
+   "set" "lisp" "define-lisp-var" define-primitive
+    
+   "(set 'list (lambda (&rest xs) xs))" lisp-eval
+   "(defmacro setq (var val) (list 'set (list 'quote var) val))" lisp-eval
+    
+   <" (defmacro defun (name vars &rest body)
+        (list 'setq name (cons 'lambda (cons vars body)))) "> lisp-eval
+    
+   "(defmacro if (pred tr fl) (list 'cond (list pred tr) (list (quote #t) fl)))" lisp-eval
+   ;
+
+: <LISP 
+    "LISP>" parse-multiline-string "(begin " prepend ")" append define-lisp-builtins
+    lisp-string>factor parsed \ call parsed ; parsing
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/authors.txt b/unmaintained/lisp/parser/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/unmaintained/lisp/parser/parser-docs.factor b/unmaintained/lisp/parser/parser-docs.factor
new file mode 100644 (file)
index 0000000..fc16a0a
--- /dev/null
@@ -0,0 +1,6 @@
+IN: lisp.parser
+USING: help.markup help.syntax ;
+
+ARTICLE: "lisp.parser" "Parsing strings of Lisp"
+"This vocab uses " { $vocab-link "peg.ebnf" } " to turn strings of Lisp into " { $snippet "s-exp" } "s, which are then used by"
+{ $vocab-link "lisp" } " to produce Factor quotations." ;
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/parser-tests.factor b/unmaintained/lisp/parser/parser-tests.factor
new file mode 100644 (file)
index 0000000..911a8d3
--- /dev/null
@@ -0,0 +1,80 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: lisp.parser tools.test peg peg.ebnf lists ;
+
+IN: lisp.parser.tests
+
+{ 1234  }  [
+  "1234" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ -42  }  [
+    "-42" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ 37/52 } [
+    "37/52" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ 123.98 } [
+    "123.98" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "" } [
+    "\"\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "aoeu" } [
+    "\"aoeu\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ "aoeu\"de" } [
+    "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ T{ lisp-symbol f "foobar" } } [
+    "foobar" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ T{ lisp-symbol f "+" } } [
+    "+" "atom" \ lisp-expr rule parse
+] unit-test
+
+{ +nil+ } [
+    "()" lisp-expr
+] unit-test
+
+{ T{
+    cons
+    f
+    T{ lisp-symbol f "foo" }
+    T{
+        cons
+        f
+        1
+        T{ cons f 2 T{ cons f "aoeu" +nil+ } }
+    } } } [
+    "(foo 1 2 \"aoeu\")" lisp-expr
+] unit-test
+
+{ T{ cons f
+       1
+       T{ cons f
+           T{ cons f 3 T{ cons f 4 +nil+ } }
+           T{ cons f 2 +nil+ } }
+   }
+} [
+    "(1 (3 4) 2)" lisp-expr
+] unit-test
+    
+{ { T{ lisp-symbol { name "quote" } } { 1 2 3 } } } [
+    "'(1 2 3)" lisp-expr cons>seq
+] unit-test
+    
+{ { T{ lisp-symbol f "quote" } T{ lisp-symbol f "foo" } } } [
+    "'foo" lisp-expr cons>seq
+] unit-test
+    
+{ { 1 2 { T{ lisp-symbol { name "quote" } } { 3 4 } } 5 } } [
+    "(1 2 '(3 4) 5)" lisp-expr cons>seq
+] unit-test
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/parser.factor b/unmaintained/lisp/parser/parser.factor
new file mode 100644 (file)
index 0000000..50f5869
--- /dev/null
@@ -0,0 +1,41 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel peg peg.ebnf math.parser sequences arrays strings
+math fry accessors lists combinators.short-circuit ;
+
+IN: lisp.parser
+
+TUPLE: lisp-symbol name ;
+C: <lisp-symbol> lisp-symbol
+
+EBNF: lisp-expr
+_            = (" " | "\t" | "\n")*
+LPAREN       = "("
+RPAREN       = ")"
+dquote       = '"'
+squote       = "'"
+digit        = [0-9]
+integer      = ("-")? (digit)+                           => [[ first2 append string>number ]]
+float        = integer "." (digit)*                      => [[ first3 >string [ number>string ] 2dip 3append string>number ]]
+rational     = integer "/" (digit)+                      => [[ first3 nip string>number / ]]
+number       = float
+              | rational
+              | integer
+id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":"
+              | "<" | "#" | " =" | ">" | "?" | "^" | "_"
+              | "~" | "+" | "-" | "." | "@"
+letters      = [a-zA-Z]                                  => [[ 1array >string ]]
+initials     = letters | id-specials
+numbers      = [0-9]                                     => [[ 1array >string ]]
+subsequents  = initials | numbers
+identifier   = initials (subsequents)*                   => [[ first2 concat append <lisp-symbol> ]]
+escaped      = "\" .                                     => [[ second ]]
+string       = dquote ( escaped | !(dquote) . )*  dquote => [[ second >string ]]
+atom         = number
+              | identifier
+              | string
+s-expression = LPAREN (list-item)* RPAREN                => [[ second seq>cons ]]
+list-item    = _ ( atom | s-expression | quoted ) _      => [[ second ]]
+quoted       = squote list-item                          => [[ second nil cons "quote" <lisp-symbol> swap cons ]]
+expr         = list-item
+;EBNF
\ No newline at end of file
diff --git a/unmaintained/lisp/parser/summary.txt b/unmaintained/lisp/parser/summary.txt
new file mode 100644 (file)
index 0000000..aa407b3
--- /dev/null
@@ -0,0 +1 @@
+EBNF grammar for parsing Lisp
diff --git a/unmaintained/lisp/parser/tags.txt b/unmaintained/lisp/parser/tags.txt
new file mode 100644 (file)
index 0000000..d1f6fa1
--- /dev/null
@@ -0,0 +1,2 @@
+lisp
+parsing
diff --git a/unmaintained/lisp/summary.txt b/unmaintained/lisp/summary.txt
new file mode 100644 (file)
index 0000000..7277c2a
--- /dev/null
@@ -0,0 +1 @@
+A Lisp interpreter/compiler in Factor 
diff --git a/unmaintained/lisp/tags.txt b/unmaintained/lisp/tags.txt
new file mode 100644 (file)
index 0000000..c369cca
--- /dev/null
@@ -0,0 +1,2 @@
+lisp
+languages
diff --git a/unmaintained/math/derivatives/authors.txt b/unmaintained/math/derivatives/authors.txt
new file mode 100644 (file)
index 0000000..3be8a6d
--- /dev/null
@@ -0,0 +1,2 @@
+Reginald Ford
+Eduardo Cavazos
\ No newline at end of file
diff --git a/unmaintained/math/derivatives/derivatives-docs.factor b/unmaintained/math/derivatives/derivatives-docs.factor
new file mode 100644 (file)
index 0000000..1630b2f
--- /dev/null
@@ -0,0 +1,103 @@
+USING: help.markup help.syntax math math.functions ;
+IN: math.derivatives
+
+HELP: derivative ( x function -- m )
+{ $values { "x" "a position on the function" } { "function" "a differentiable function" } { "m" number } }
+{ $description
+    "Approximates the slope of the tangent line by using Ridders' "
+    "method of computing derivatives, from the chapter \"Accurate computation "
+    "of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, Vol. 4, pp. 75-76 ."
+}
+{ $examples
+    { $example
+        "USING: math math.derivatives prettyprint ;"
+        "4 [ sq ] derivative >integer ."
+        "8"
+    }
+    { $notes
+        "For applied scientists, you may play with the settings "
+        "in the source file to achieve arbitrary accuracy. "
+    }
+} ;
+
+HELP: (derivative)
+{ $values
+    { "x" "a position on the function" }
+    { "func" "a differentiable function" }
+    {
+        "h" "distance between the points of the first secant line used for "
+        "approximation of the tangent. This distance will be divided "
+        "constantly, by " { $link con } ". See " { $link init-hh }
+        " for the code which enforces this. H should be .001 to .5 -- too "
+        "small can cause bad convergence. Also, h should be small enough "
+        "to give the correct sgn(f'(x)). In other words, if you're expecting "
+        "a positive derivative, make h small enough to give the same "
+        "when plugged into the academic limit definition of a derivative. "
+        "See " { $link update-hh } " for the code which performs this task."
+    }
+    {
+        "err" "maximum tolerance of increase in error. For example, if this "
+        "is set to 2.0, the program will terminate with its nearest answer "
+        "when the error multiplies by 2. See " { $link check-safe } " for "
+        "the enforcing code."
+    }
+    {   "ans" number }
+    {   "error" number }
+}
+{ $description
+    "Approximates the slope of the tangent line by using Ridders' "
+    "method of computing derivatives, from the chapter \"Accurate computation "
+    "of F'(x) and F'(x)F''(x)\", from \"Advances in Engineering Software, "
+    "Vol. 4, pp. 75-76 ."
+}
+{ $examples
+    { $example
+        "USING: math math.derivatives prettyprint ;"
+        "4 [ sq ] derivative >integer ."
+        "8"
+    }
+    { $notes
+        "For applied scientists, you may play with the settings "
+        "in the source file to achieve arbitrary accuracy. "
+    }
+} ;
+
+HELP: derivative-func
+{ $values { "func" "a differentiable function" } { "der" "the derivative" } }
+{ $description
+    "Provides the derivative of the function. The implementation simply "
+    "attaches the " { $link derivative } " word to the end of the function."
+}
+{ $examples
+    { $example
+        "USING: kernel math.derivatives math.functions math.trig prettyprint ;"
+        "60 deg>rad [ sin ] derivative-func call 0.5 .001 ~ ."
+        "t"
+    }
+    { $notes
+        "Without a heavy algebraic system, derivatives must be "
+        "approximated. With the current settings, there is a fair trade of "
+        "speed and accuracy; the first 12 digits "
+        "will always be correct with " { $link sin } " and " { $link cos }
+        ". The following code performs a minumum and maximum error test."
+        { $code
+            "USING: kernel math math.functions math.trig sequences sequences.lib ;"
+            "360"
+            "["
+            "           deg>rad"
+            "            [ [ sin ] derivative-func call ]"
+            "           ! Note: the derivative of sin is cos"
+            "            [ cos ]"
+            "       bi - abs"
+            "] map minmax"
+        }
+    }
+} ;
+
+ARTICLE: "derivatives" "The Derivative Toolkit"
+"A toolkit for computing the derivative of functions."
+{ $subsection derivative }
+{ $subsection derivative-func }
+{ $subsection (derivative) } ;
+
+ABOUT: "derivatives"
diff --git a/unmaintained/math/derivatives/derivatives-tests.factor b/unmaintained/math/derivatives/derivatives-tests.factor
new file mode 100644 (file)
index 0000000..cfbc1fa
--- /dev/null
@@ -0,0 +1,5 @@
+USING: math math.derivatives tools.test ;
+IN: math.derivatives.test
+
+[ 8 ] [ 4 [ sq ] derivative >integer ] unit-test
+
diff --git a/unmaintained/math/derivatives/derivatives.factor b/unmaintained/math/derivatives/derivatives.factor
new file mode 100644 (file)
index 0000000..7922a48
--- /dev/null
@@ -0,0 +1,111 @@
+! Copyright (c) 2008 Reginald Keith Ford II, Eduardo Cavazos.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel continuations combinators sequences math math.order math.ranges
+    accessors float-arrays ;
+IN: math.derivatives
+
+TUPLE: state x func h err i j errt fac hh ans a done ;
+
+: largest-float ( -- x ) HEX: 7fefffffffffffff bits>double ; foldable
+: ntab ( -- val ) 8 ; inline
+: con ( -- val ) 1.6 ; inline
+: con2 ( -- val ) con con * ; inline
+: big ( -- val ) largest-float ; inline
+: safe ( -- val ) 2.0 ; inline
+
+! Yes, this was ported from C code.
+: a[i][i]     ( state -- elt ) [ i>>     ] [ i>>     ] [ a>> ] tri nth nth ;
+: a[j][i]     ( state -- elt ) [ i>>     ] [ j>>     ] [ a>> ] tri nth nth ;
+: a[j-1][i]   ( state -- elt ) [ i>>     ] [ j>> 1 - ] [ a>> ] tri nth nth ;
+: a[j-1][i-1] ( state -- elt ) [ i>> 1 - ] [ j>> 1 - ] [ a>> ] tri nth nth ;
+: a[i-1][i-1] ( state -- elt ) [ i>> 1 - ] [ i>> 1 - ] [ a>> ] tri nth nth ;
+
+: check-h ( state -- state )
+    dup h>> 0 = [ "h must be nonzero in dfridr" throw ] when ;
+
+: init-a     ( state -- state ) ntab [ ntab <float-array> ] replicate >>a ;
+: init-hh    ( state -- state ) dup h>> >>hh ;
+: init-err   ( state -- state ) big >>err ;
+: update-hh  ( state -- state ) dup hh>> con / >>hh ;
+: reset-fac  ( state -- state ) con2 >>fac ;
+: update-fac ( state -- state ) dup fac>> con2 * >>fac ;
+
+! If error is decreased, save the improved answer
+: error-decreased? ( state -- state ? ) [ ] [ errt>> ] [ err>> ] tri <= ;
+
+: save-improved-answer ( state -- state )
+    dup err>>   >>errt
+    dup a[j][i] >>ans ;
+
+! If higher order is worse by a significant factor SAFE, then quit early.
+: check-safe ( state -- state )
+    dup [ [ a[i][i] ] [ a[i-1][i-1] ] bi - abs ]
+    [ err>> safe * ] bi >= [ t >>done ] when ;
+
+: x+hh ( state -- val ) [ x>> ] [ hh>> ] bi + ;
+: x-hh ( state -- val ) [ x>> ] [ hh>> ] bi - ;
+
+: limit-approx ( state -- val )
+    [
+        [ [ x+hh ] [ func>> ] bi call ]
+        [ [ x-hh ] [ func>> ] bi call ] bi -
+    ] [ hh>> 2.0 * ] bi / ;
+
+: a[0][0]! ( state -- state )
+    { [ ] [ limit-approx ] [ drop 0 ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+
+: a[0][i]! ( state -- state )
+    { [ ] [ limit-approx ] [ i>> ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+
+: a[j-1][i]*fac ( state -- val ) [ a[j-1][i] ] [ fac>> ] bi * ;
+
+: new-a[j][i] ( state -- val )
+    [ [ a[j-1][i]*fac ] [ a[j-1][i-1] ] bi - ]
+    [ fac>> 1.0 - ] bi / ;
+
+: a[j][i]! ( state -- state )
+    { [ ] [ new-a[j][i] ] [ i>> ] [ j>> ] [ a>> ] } cleave nth set-nth ;
+
+: update-errt ( state -- state )
+    dup [ [ a[j][i] ] [ a[j-1][i] ] bi - abs ]
+    [ [ a[j][i] ] [ a[j-1][i-1] ] bi - abs ] bi max >>errt ;
+
+: not-done? ( state -- state ? ) dup done>> not ;
+
+: derive ( state -- state )
+    init-a
+    check-h
+    init-hh
+    a[0][0]!
+    init-err
+    1 ntab [a,b) [
+        >>i not-done? [
+            update-hh
+            a[0][i]!
+            reset-fac
+            1 over i>> [a,b] [
+                >>j
+                a[j][i]!
+                update-fac
+                update-errt
+                error-decreased? [ save-improved-answer ] when
+            ] each check-safe
+        ] when
+   ] each ;
+
+: derivative-state ( x func h err -- state )
+    state new
+    swap >>err
+    swap >>h
+    swap >>func
+    swap >>x ;
+
+! For scientists:
+! h should be .001 to .5 -- too small can cause bad convergence,
+! h should be small enough to give the correct sgn(f'(x))
+! err is the max tolerance of gain in error for a single iteration-
+: (derivative) ( x func h err -- ans error )
+    derivative-state derive [ ans>> ] [ errt>> ] bi ;
+
+: derivative ( x func -- m ) 0.01 2.0 (derivative) drop ;
+: derivative-func ( func -- der ) [ derivative ] curry ;
diff --git a/unmaintained/math/newtons-method/authors.txt b/unmaintained/math/newtons-method/authors.txt
new file mode 100644 (file)
index 0000000..137b160
--- /dev/null
@@ -0,0 +1 @@
+Reginald Ford
\ No newline at end of file
diff --git a/unmaintained/math/newtons-method/newtons-method.factor b/unmaintained/math/newtons-method/newtons-method.factor
new file mode 100644 (file)
index 0000000..4b53b12
--- /dev/null
@@ -0,0 +1,18 @@
+! Copyright (c) 2008 Reginald Keith Ford II.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.derivatives ;
+IN: math.newtons-method
+
+! Newton's method of approximating roots
+
+<PRIVATE
+
+: newton-step ( x function -- x2 )
+    dupd [ call ] [ derivative ] 2bi / - ; inline
+
+: newton-precision ( -- n ) 13 ; inline
+
+PRIVATE>
+
+: newtons-method ( guess function -- x )
+    newton-precision [ [ newton-step ] keep ] times drop ;
diff --git a/unmaintained/morse/authors.txt b/unmaintained/morse/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/morse/morse-docs.factor b/unmaintained/morse/morse-docs.factor
new file mode 100644 (file)
index 0000000..e35967d
--- /dev/null
@@ -0,0 +1,33 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax ;
+IN: morse
+
+HELP: ch>morse
+{ $values
+    { "ch" "A character that has a morse code translation" } { "str" "A string consisting of zero or more dots and dashes" } }
+{ $description "If the given character has a morse code translation, then return that translation, otherwise return an empty string." } ;
+
+HELP: morse>ch
+{ $values
+    { "str" "A string of dots and dashes that represents a single character in morse code" } { "ch" "The translated character" } }
+{ $description "If the given string represents a morse code character, then return that character, otherwise return f" } ;
+
+HELP: >morse
+{ $values
+    { "str" "A string of ASCII characters which can be translated into morse code" } { "str" "A string in morse code" } }
+{ $description "Translates ASCII text into morse code, represented by a series of dots, dashes, and slashes." }
+{ $see-also morse> ch>morse } ;
+
+HELP: morse>
+{ $values { "str" "A string of morse code, in which the character '.' represents dots, '-' dashes, ' ' spaces between letters, and ' / ' spaces between words." } { "str" "The ASCII translation of the given string" } }
+{ $description "Translates morse code into ASCII text" }
+{ $see-also >morse morse>ch } ;
+
+HELP: play-as-morse*
+{ $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } }
+{ $description "Plays a string as morse code" } ;
+
+HELP: play-as-morse
+{ $values { "str" "A string of ascii characters which can be translated into morse code" } }
+{ $description "Plays a string as morse code" } ;
diff --git a/unmaintained/morse/morse-tests.factor b/unmaintained/morse/morse-tests.factor
new file mode 100644 (file)
index 0000000..1444489
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays morse strings tools.test ;
+
+[ "" ] [ CHAR: \\ ch>morse ] unit-test
+[ "..." ] [ CHAR: s ch>morse ] unit-test
+[ CHAR: s ] [ "..." morse>ch ] unit-test
+[ f ] [ "..--..--.." morse>ch ] unit-test
+[ "-- --- .-. ... . / -.-. --- -.. ." ] [ "morse code" >morse ] unit-test
+[ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test
+[ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test
+! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
+! [ ] [ "Factor rocks!" play-as-morse ] unit-test
diff --git a/unmaintained/morse/morse.factor b/unmaintained/morse/morse.factor
new file mode 100644 (file)
index 0000000..2951c96
--- /dev/null
@@ -0,0 +1,182 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs combinators hashtables kernel lists math
+namespaces make openal parser-combinators promises sequences
+strings symbols synth synth.buffers unicode.case ;
+IN: morse
+
+<PRIVATE
+: morse-codes ( -- array )
+    {
+        { CHAR: a ".-"    }
+        { CHAR: b "-..."  }
+        { CHAR: c "-.-."  }
+        { CHAR: d "-.."   }
+        { CHAR: e "."     }
+        { CHAR: f "..-."  }
+        { CHAR: g "--."   }
+        { CHAR: h "...."  }
+        { CHAR: i ".."    }
+        { CHAR: j ".---"  }
+        { CHAR: k "-.-"   }
+        { CHAR: l ".-.."  }
+        { CHAR: m "--"    }
+        { CHAR: n "-."    }
+        { CHAR: o "---"   }
+        { CHAR: p ".--."  }
+        { CHAR: q "--.-"  }
+        { CHAR: r ".-."   }
+        { CHAR: s "..."   }
+        { CHAR: t "-"     }
+        { CHAR: u "..-"   }
+        { CHAR: v "...-"  }
+        { CHAR: w ".--"   }
+        { CHAR: x "-..-"  }
+        { CHAR: y "-.--"  }
+        { CHAR: z "--.."  }
+        { CHAR: 1 ".----" }
+        { CHAR: 2 "..---" }
+        { CHAR: 3 "...--" }
+        { CHAR: 4 "....-" }
+        { CHAR: 5 "....." }
+        { CHAR: 6 "-...." }
+        { CHAR: 7 "--..." }
+        { CHAR: 8 "---.." }
+        { CHAR: 9 "----." }
+        { CHAR: 0 "-----" }
+        { CHAR: . ".-.-.-" }
+        { CHAR: , "--..--" }
+        { CHAR: ? "..--.." }
+        { CHAR: ' ".----." }
+        { CHAR: ! "-.-.--" }
+        { CHAR: / "-..-."  }
+        { CHAR: ( "-.--."  }
+        { CHAR: ) "-.--.-" }
+        { CHAR: & ".-..."  }
+        { CHAR: : "---..." }
+        { CHAR: ; "-.-.-." }
+        { CHAR: = "-...- " }
+        { CHAR: + ".-.-."  }
+        { CHAR: - "-....-" }
+        { CHAR: _ "..--.-" }
+        { CHAR: " ".-..-." }
+        { CHAR: $ "...-..-" }
+        { CHAR: @ ".--.-." }
+        { CHAR: \s "/" }
+    } ;
+
+: ch>morse-assoc ( -- assoc )
+    morse-codes >hashtable ;
+
+: morse>ch-assoc ( -- assoc )
+    morse-codes [ reverse ] map >hashtable ;
+
+PRIVATE>
+
+: ch>morse ( ch -- str )
+    ch>lower ch>morse-assoc at* swap "" ? ;
+
+: morse>ch ( str -- ch )
+    morse>ch-assoc at* swap f ? ;
+
+: >morse ( str -- str )
+    [
+        [ CHAR: \s , ] [ ch>morse % ] interleave
+    ] "" make ;
+
+<PRIVATE
+
+: dot-char ( -- ch ) CHAR: . ;
+: dash-char ( -- ch ) CHAR: - ;
+: char-gap-char ( -- ch ) CHAR: \s ;
+: word-gap-char ( -- ch ) CHAR: / ;
+
+: =parser ( obj -- parser )
+    [ = ] curry satisfy ;
+
+LAZY: 'dot' ( -- parser )
+    dot-char =parser ;
+
+LAZY: 'dash' ( -- parser )
+    dash-char =parser ;
+
+LAZY: 'char-gap' ( -- parser )
+    char-gap-char =parser ;
+
+LAZY: 'word-gap' ( -- parser )
+    word-gap-char =parser ;
+
+LAZY: 'morse-char' ( -- parser )
+    'dot' 'dash' <|> <+> ;
+
+LAZY: 'morse-word' ( -- parser )
+    'morse-char' 'char-gap' list-of ;
+
+LAZY: 'morse-words' ( -- parser )
+    'morse-word' 'word-gap' list-of ;
+
+PRIVATE>
+
+: morse> ( str -- str )
+    'morse-words' parse car parsed>> [
+        [ 
+            >string morse>ch
+        ] map >string
+    ] map [ [ CHAR: \s , ] [ % ] interleave ] "" make ;
+
+<PRIVATE
+SYMBOLS: source dot-buffer dash-buffer intra-char-gap-buffer letter-gap-buffer ;
+
+: queue ( symbol -- )
+    get source get swap queue-buffer ;
+
+: dot ( -- ) dot-buffer queue ;
+: dash ( -- ) dash-buffer queue ;
+: intra-char-gap ( -- ) intra-char-gap-buffer queue ;
+: letter-gap ( -- ) letter-gap-buffer queue ;
+
+: beep-freq 880 ;
+
+: <morse-buffer> ( -- buffer )
+    half-sample-freq <8bit-mono-buffer> ;
+
+: sine-buffer ( seconds -- id )
+    beep-freq swap <morse-buffer> >sine-wave-buffer
+    send-buffer id>> ;
+
+: silent-buffer ( seconds -- id )
+    <morse-buffer> >silent-buffer send-buffer id>> ;
+
+: make-buffers ( unit-length -- )
+    {
+        [ sine-buffer dot-buffer set ]
+        [ 3 * sine-buffer dash-buffer set ]
+        [ silent-buffer intra-char-gap-buffer set ]
+        [ 3 * silent-buffer letter-gap-buffer set ]
+    } cleave ;
+
+: playing-morse ( quot unit-length -- )
+    [
+        init-openal 1 gen-sources first source set make-buffers
+        call
+        source get source-play
+    ] with-scope ;
+
+: play-char ( ch -- )
+    [ intra-char-gap ] [
+        {
+            { dot-char [ dot ] }
+            { dash-char [ dash ] }
+            { word-gap-char [ intra-char-gap ] }
+        } case
+    ] interleave ;
+
+PRIVATE>
+
+: play-as-morse* ( str unit-length -- )
+    [
+        [ letter-gap ] [ ch>morse play-char ] interleave
+    ] swap playing-morse ;
+
+: play-as-morse ( str -- )
+    0.05 play-as-morse* ;
diff --git a/unmaintained/morse/summary.txt b/unmaintained/morse/summary.txt
new file mode 100644 (file)
index 0000000..2c1f091
--- /dev/null
@@ -0,0 +1 @@
+Converts between text and morse code, and plays morse code.
diff --git a/unmaintained/morse/tags.txt b/unmaintained/morse/tags.txt
new file mode 100644 (file)
index 0000000..1e107f5
--- /dev/null
@@ -0,0 +1 @@
+examples
diff --git a/unmaintained/nehe/2/2.factor b/unmaintained/nehe/2/2.factor
new file mode 100644 (file)
index 0000000..29d4ccf
--- /dev/null
@@ -0,0 +1,46 @@
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render ;
+IN: nehe.2
+
+TUPLE: nehe2-gadget < gadget ;
+
+: width 256 ;
+: height 256 ;
+
+: <nehe2-gadget> (  -- gadget )
+  nehe2-gadget new-gadget ;
+
+M: nehe2-gadget pref-dim* ( gadget -- dim )
+  drop width height 2array ;
+
+M: nehe2-gadget draw-gadget* ( gadget -- )
+  drop
+  GL_PROJECTION glMatrixMode
+  glLoadIdentity
+  45.0 width height / >float 0.1 100.0 gluPerspective
+  GL_MODELVIEW glMatrixMode
+  glLoadIdentity
+  GL_SMOOTH glShadeModel
+  0.0 0.0 0.0 0.0 glClearColor
+  1.0 glClearDepth
+  GL_DEPTH_TEST glEnable
+  GL_LEQUAL glDepthFunc
+  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
+  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
+  glLoadIdentity
+  -1.5 0.0 -6.0 glTranslatef
+  GL_TRIANGLES [
+    0.0 1.0 0.0 glVertex3f
+    -1.0 -1.0 0.0 glVertex3f
+    1.0 -1.0 0.0 glVertex3f
+  ] do-state
+  3.0 0.0 0.0 glTranslatef
+  GL_QUADS [
+    -1.0 1.0 0.0 glVertex3f
+    1.0 1.0 0.0 glVertex3f
+    1.0 -1.0 0.0 glVertex3f
+    -1.0 -1.0 0.0 glVertex3f
+  ] do-state ;
+
+: run2 ( -- )
+  <nehe2-gadget> "NeHe Tutorial 2" open-window ;
diff --git a/unmaintained/nehe/2/authors.txt b/unmaintained/nehe/2/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/nehe/3/3.factor b/unmaintained/nehe/3/3.factor
new file mode 100644 (file)
index 0000000..75f2e57
--- /dev/null
@@ -0,0 +1,50 @@
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render ;
+IN: nehe.3
+
+TUPLE: nehe3-gadget < gadget ;
+
+: width 256 ;
+: height 256 ;
+
+: <nehe3-gadget> (  -- gadget )
+  nehe3-gadget new-gadget ;
+
+M: nehe3-gadget pref-dim* ( gadget -- dim )
+  drop width height 2array ;
+
+M: nehe3-gadget draw-gadget* ( gadget -- )
+  drop
+  GL_PROJECTION glMatrixMode
+  glLoadIdentity
+  45.0 width height / >float 0.1 100.0 gluPerspective
+  GL_MODELVIEW glMatrixMode
+  glLoadIdentity
+  GL_SMOOTH glShadeModel
+  0.0 0.0 0.0 0.0 glClearColor
+  1.0 glClearDepth
+  GL_DEPTH_TEST glEnable
+  GL_LEQUAL glDepthFunc
+  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
+  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
+  glLoadIdentity
+  -1.5 0.0 -6.0 glTranslatef
+  GL_TRIANGLES [
+    1.0 0.0 0.0 glColor3f
+    0.0 1.0 0.0 glVertex3f
+    0.0 1.0 0.0 glColor3f
+    -1.0 -1.0 0.0 glVertex3f
+    0.0 0.0 1.0 glColor3f
+    1.0 -1.0 0.0 glVertex3f
+  ] do-state
+  3.0 0.0 0.0 glTranslatef
+  0.5 0.5 1.0 glColor3f
+  GL_QUADS [
+    -1.0 1.0 0.0 glVertex3f
+    1.0 1.0 0.0 glVertex3f
+    1.0 -1.0 0.0 glVertex3f
+    -1.0 -1.0 0.0 glVertex3f
+  ] do-state ;
+
+: run3 ( -- )
+  <nehe3-gadget> "NeHe Tutorial 3" open-window ;
diff --git a/unmaintained/nehe/3/authors.txt b/unmaintained/nehe/3/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/nehe/4/4.factor b/unmaintained/nehe/4/4.factor
new file mode 100644 (file)
index 0000000..fda22d2
--- /dev/null
@@ -0,0 +1,75 @@
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render threads accessors
+calendar ;
+IN: nehe.4
+
+TUPLE: nehe4-gadget < gadget rtri rquad thread quit? ;
+
+: width 256 ;
+: height 256 ;
+: redraw-interval ( -- dt ) 10 milliseconds ;
+
+: <nehe4-gadget> (  -- gadget )
+  nehe4-gadget new-gadget
+    0.0 >>rtri
+    0.0 >>rquad ;
+
+M: nehe4-gadget pref-dim* ( gadget -- dim )
+  drop width height 2array ;
+
+M: nehe4-gadget draw-gadget* ( gadget -- )
+  GL_PROJECTION glMatrixMode
+  glLoadIdentity
+  45.0 width height / >float 0.1 100.0 gluPerspective
+  GL_MODELVIEW glMatrixMode
+  glLoadIdentity
+  GL_SMOOTH glShadeModel
+  0.0 0.0 0.0 0.0 glClearColor
+  1.0 glClearDepth
+  GL_DEPTH_TEST glEnable
+  GL_LEQUAL glDepthFunc
+  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint
+  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
+  glLoadIdentity
+  -1.5 0.0 -6.0 glTranslatef
+  dup rtri>> 0.0 1.0 0.0 glRotatef
+
+  GL_TRIANGLES [
+    1.0 0.0 0.0 glColor3f
+    0.0 1.0 0.0 glVertex3f
+    0.0 1.0 0.0 glColor3f
+    -1.0 -1.0 0.0 glVertex3f
+    0.0 0.0 1.0 glColor3f
+    1.0 -1.0 0.0 glVertex3f
+  ] do-state
+
+  glLoadIdentity
+
+  1.5 0.0 -6.0 glTranslatef
+  dup rquad>> 1.0 0.0 0.0 glRotatef
+  0.5 0.5 1.0 glColor3f
+  GL_QUADS [
+    -1.0 1.0 0.0 glVertex3f
+    1.0 1.0 0.0 glVertex3f
+    1.0 -1.0 0.0 glVertex3f
+    -1.0 -1.0 0.0 glVertex3f
+  ] do-state
+  [ 0.2 + ] change-rtri
+  [ 0.15 - ] change-rquad drop ;
+
+: nehe4-update-thread ( gadget -- )
+  dup quit?>> [ drop ] [
+    redraw-interval sleep
+    dup relayout-1
+    nehe4-update-thread
+  ] if ;
+
+M: nehe4-gadget graft* ( gadget -- )
+  f >>quit?
+  [ nehe4-update-thread ] curry in-thread ;
+
+M: nehe4-gadget ungraft* ( gadget -- )
+  t >>quit? drop ;
+
+: run4 ( -- )
+  <nehe4-gadget> "NeHe Tutorial 4" open-window ;
diff --git a/unmaintained/nehe/4/authors.txt b/unmaintained/nehe/4/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/nehe/5/5.factor b/unmaintained/nehe/5/5.factor
new file mode 100755 (executable)
index 0000000..30d0991
--- /dev/null
@@ -0,0 +1,128 @@
+USING: arrays kernel math opengl opengl.gl opengl.glu\r
+opengl.demo-support ui ui.gadgets ui.render threads accessors\r
+calendar ;\r
+IN: nehe.5\r
+\r
+TUPLE: nehe5-gadget < gadget rtri rquad thread quit? ;\r
+: width 256 ;\r
+: height 256 ;\r
+: redraw-interval ( -- dt ) 10 milliseconds ;\r
+\r
+: <nehe5-gadget> (  -- gadget )\r
+  nehe5-gadget new-gadget\r
+    0.0 >>rtri\r
+    0.0 >>rquad ;\r
+\r
+M: nehe5-gadget pref-dim* ( gadget -- dim )\r
+  drop width height 2array ;\r
+\r
+M: nehe5-gadget draw-gadget* ( gadget -- )\r
+  GL_PROJECTION glMatrixMode\r
+  glLoadIdentity\r
+  45.0 width height / >float 0.1 100.0 gluPerspective\r
+  GL_MODELVIEW glMatrixMode\r
+  glLoadIdentity\r
+  GL_SMOOTH glShadeModel\r
+  0.0 0.0 0.0 0.0 glClearColor\r
+  1.0 glClearDepth\r
+  GL_DEPTH_TEST glEnable\r
+  GL_LEQUAL glDepthFunc\r
+  GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glHint\r
+  GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear\r
+  glLoadIdentity\r
+  -1.5 0.0 -6.0 glTranslatef\r
+  dup rtri>> 0.0 1.0 0.0 glRotatef\r
+\r
+  GL_TRIANGLES [\r
+    1.0 0.0 0.0 glColor3f\r
+    0.0 1.0 0.0 glVertex3f\r
+    0.0 1.0 0.0 glColor3f\r
+    -1.0 -1.0 1.0 glVertex3f\r
+    0.0 0.0 1.0 glColor3f\r
+    1.0 -1.0 1.0 glVertex3f\r
+\r
+    1.0 0.0 0.0 glColor3f\r
+    0.0 1.0 0.0 glVertex3f\r
+    0.0 0.0 1.0 glColor3f\r
+    1.0 -1.0 1.0 glVertex3f\r
+    0.0 1.0 0.0 glColor3f\r
+    1.0 -1.0 -1.0 glVertex3f\r
+\r
+    1.0 0.0 0.0 glColor3f\r
+    0.0 1.0 0.0 glVertex3f\r
+    0.0 1.0 0.0 glColor3f\r
+    1.0 -1.0 -1.0 glVertex3f\r
+    0.0 0.0 1.0 glColor3f\r
+    -1.0 -1.0 -1.0 glVertex3f\r
+\r
+    1.0 0.0 0.0 glColor3f\r
+    0.0 1.0 0.0 glVertex3f\r
+    0.0 0.0 1.0 glColor3f\r
+    -1.0 -1.0 -1.0 glVertex3f\r
+    0.0 1.0 0.0 glColor3f\r
+    -1.0 -1.0 1.0 glVertex3f\r
+  ] do-state\r
+\r
+  glLoadIdentity\r
+\r
+  1.5 0.0 -7.0 glTranslatef\r
+  dup rquad>> 1.0 0.0 0.0 glRotatef\r
+  GL_QUADS [\r
+    0.0 1.0 0.0 glColor3f\r
+    1.0 1.0 -1.0 glVertex3f\r
+    -1.0 1.0 -1.0 glVertex3f\r
+    -1.0 1.0 1.0 glVertex3f\r
+    1.0 1.0 1.0 glVertex3f\r
+\r
+    1.0 0.5 0.0 glColor3f\r
+    1.0 -1.0 1.0 glVertex3f\r
+    -1.0 -1.0 1.0 glVertex3f\r
+    -1.0 -1.0 -1.0 glVertex3f\r
+    1.0 -1.0 -1.0 glVertex3f\r
+\r
+    1.0 0.0 0.0 glColor3f\r
+    1.0 1.0 1.0 glVertex3f\r
+    -1.0 1.0 1.0 glVertex3f\r
+    -1.0 -1.0 1.0 glVertex3f\r
+    1.0 -1.0 1.0 glVertex3f\r
+\r
+    1.0 1.0 0.0 glColor3f\r
+    1.0 -1.0 -1.0 glVertex3f\r
+    -1.0 -1.0 -1.0 glVertex3f\r
+    -1.0 1.0 -1.0 glVertex3f\r
+    1.0 1.0 -1.0 glVertex3f\r
+\r
+    0.0 0.0 1.0 glColor3f\r
+    -1.0 1.0 1.0 glVertex3f\r
+    -1.0 1.0 -1.0 glVertex3f\r
+    -1.0 -1.0 -1.0 glVertex3f\r
+    -1.0 -1.0 1.0 glVertex3f\r
+\r
+    1.0 0.0 1.0 glColor3f\r
+    1.0 1.0 -1.0 glVertex3f\r
+    1.0 1.0 1.0 glVertex3f\r
+    1.0 -1.0 1.0 glVertex3f\r
+    1.0 -1.0 -1.0 glVertex3f\r
+  ] do-state \r
+  [ 0.2 + ] change-rtri\r
+  [ 0.15 - ] change-rquad drop ;\r
+\r
+: nehe5-update-thread ( gadget -- )  \r
+  dup quit?>> [\r
+    drop\r
+  ] [\r
+    redraw-interval sleep \r
+    dup relayout-1  \r
+    nehe5-update-thread \r
+  ] if ;\r
+\r
+M: nehe5-gadget graft* ( gadget -- )\r
+  f >>quit?\r
+  [ nehe5-update-thread ] curry in-thread ;\r
+\r
+M: nehe5-gadget ungraft* ( gadget -- )\r
+  t >>quit? drop ;\r
+\r
+\r
+: run5 ( -- )\r
+  <nehe5-gadget> "NeHe Tutorial 5" open-window ;\r
diff --git a/unmaintained/nehe/5/authors.txt b/unmaintained/nehe/5/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/nehe/authors.txt b/unmaintained/nehe/authors.txt
new file mode 100644 (file)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/nehe/deploy.factor b/unmaintained/nehe/deploy.factor
new file mode 100755 (executable)
index 0000000..6cf9543
--- /dev/null
@@ -0,0 +1,12 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 1 }
+    { deploy-reflection 1 }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "NeHe OpenGL demos" }
+}
diff --git a/unmaintained/nehe/nehe.factor b/unmaintained/nehe/nehe.factor
new file mode 100644 (file)
index 0000000..a96c024
--- /dev/null
@@ -0,0 +1,15 @@
+USING: ui.gadgets.buttons ui.gadgets.packs ui.gadgets ui
+nehe.2 nehe.3 nehe.4 nehe.5 kernel ;
+IN: nehe
+
+: nehe-window ( -- )
+    [
+        <filled-pile>
+            "Nehe 2" [ drop run2 ] <bevel-button> add-gadget
+            "Nehe 3" [ drop run3 ] <bevel-button> add-gadget
+            "Nehe 4" [ drop run4 ] <bevel-button> add-gadget
+            "Nehe 5" [ drop run5 ] <bevel-button> add-gadget
+        "Nehe examples" open-window
+    ] with-ui ;
+
+MAIN: nehe-window
diff --git a/unmaintained/nehe/summary.txt b/unmaintained/nehe/summary.txt
new file mode 100644 (file)
index 0000000..7811f84
--- /dev/null
@@ -0,0 +1 @@
+NeHe OpenGL tutorials ported to Factor
diff --git a/unmaintained/nehe/tags.txt b/unmaintained/nehe/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
diff --git a/unmaintained/openal/authors.txt b/unmaintained/openal/authors.txt
new file mode 100644 (file)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/openal/backend/authors.txt b/unmaintained/openal/backend/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/openal/backend/backend.factor b/unmaintained/openal/backend/backend.factor
new file mode 100644 (file)
index 0000000..41069dc
--- /dev/null
@@ -0,0 +1,4 @@
+USING: namespaces system ;
+IN: openal.backend
+
+HOOK: load-wav-file os ( filename -- format data size frequency )
diff --git a/unmaintained/openal/example/authors.txt b/unmaintained/openal/example/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/openal/example/example.factor b/unmaintained/openal/example/example.factor
new file mode 100644 (file)
index 0000000..ae0b50a
--- /dev/null
@@ -0,0 +1,34 @@
+! Copyright (C) 2007 Chris Double.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+!\r
+IN: openal.example\r
+USING: openal kernel alien threads sequences calendar ;\r
+\r
+: play-hello ( -- )\r
+  init-openal\r
+  1 gen-sources\r
+  first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param\r
+  source-play\r
+  1000 milliseconds sleep ;\r
+  \r
+: (play-file) ( source -- )\r
+  100 milliseconds sleep\r
+  dup source-playing? [ (play-file) ] [ drop ] if ;\r
+\r
+: play-file ( filename -- )\r
+  init-openal\r
+  create-buffer-from-file \r
+  1 gen-sources\r
+  first dup >r AL_BUFFER rot set-source-param r>\r
+  dup source-play\r
+  check-error\r
+  (play-file) ;\r
+\r
+: play-wav ( filename -- )\r
+  init-openal\r
+  create-buffer-from-wav \r
+  1 gen-sources\r
+  first dup >r AL_BUFFER rot set-source-param r>\r
+  dup source-play\r
+  check-error\r
+  (play-file) ;
\ No newline at end of file
diff --git a/unmaintained/openal/macosx/authors.txt b/unmaintained/openal/macosx/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/openal/macosx/macosx.factor b/unmaintained/openal/macosx/macosx.factor
new file mode 100644 (file)
index 0000000..d2a0422
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types kernel alien alien.syntax shuffle
+combinators.lib openal.backend namespaces system ;
+IN: openal.macosx
+
+LIBRARY: alut
+
+FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency ) ;
+
+M: macosx load-wav-file ( path -- format data size frequency )
+  0 <int> f <void*> 0 <int> 0 <int>
+  [ alutLoadWAVFile ] 4keep
+  >r >r >r *int r> *void* r> *int r> *int ;
diff --git a/unmaintained/openal/macosx/tags.txt b/unmaintained/openal/macosx/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/unmaintained/openal/openal.factor b/unmaintained/openal/openal.factor
new file mode 100644 (file)
index 0000000..40593d1
--- /dev/null
@@ -0,0 +1,301 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel arrays alien system combinators alien.syntax namespaces
+       alien.c-types sequences vocabs.loader shuffle combinators.lib
+       openal.backend specialized-arrays.uint ;
+IN: openal
+
+<< "alut" {
+        { [ os windows? ]  [ "alut.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libalut.so" ] }
+    } cond "cdecl" add-library >>
+
+<< "openal" {
+        { [ os windows? ]  [ "OpenAL32.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libopenal.so" ] }
+    } cond "cdecl" add-library >>
+
+LIBRARY: openal
+
+TYPEDEF: char ALboolean 
+TYPEDEF: char ALchar
+TYPEDEF: char ALbyte
+TYPEDEF: uchar ALubyte
+TYPEDEF: short ALshort
+TYPEDEF: ushort ALushort
+TYPEDEF: int ALint
+TYPEDEF: uint ALuint
+TYPEDEF: int ALsizei
+TYPEDEF: int ALenum
+TYPEDEF: float ALfloat
+TYPEDEF: double ALdouble
+
+: AL_INVALID ( -- number ) -1 ; inline
+: AL_NONE ( -- number ) 0 ; inline
+: AL_FALSE ( -- number ) 0 ; inline
+: AL_TRUE ( -- number ) 1 ; inline
+: AL_SOURCE_RELATIVE ( -- number ) HEX: 202 ; inline
+: AL_CONE_INNER_ANGLE ( -- nmber ) HEX: 1001 ; inline
+: AL_CONE_OUTER_ANGLE ( -- number ) HEX: 1002 ; inline
+: AL_PITCH ( -- number ) HEX: 1003 ; inline
+: AL_POSITION ( -- number ) HEX: 1004 ; inline
+: AL_DIRECTION ( -- number ) HEX: 1005 ; inline
+: AL_VELOCITY ( -- number ) HEX: 1006 ; inline
+: AL_LOOPING ( -- number ) HEX: 1007 ; inline
+: AL_BUFFER ( -- number ) HEX: 1009 ; inline
+: AL_GAIN ( -- number ) HEX: 100A ; inline
+: AL_MIN_GAIN ( -- number ) HEX: 100D ; inline
+: AL_MAX_GAIN ( -- number ) HEX: 100E ; inline
+: AL_ORIENTATION ( -- number ) HEX: 100F ; inline
+: AL_CHANNEL_MASK ( -- number ) HEX: 3000 ; inline
+: AL_SOURCE_STATE ( -- number ) HEX: 1010 ; inline
+: AL_INITIAL ( -- number ) HEX: 1011 ; inline
+: AL_PLAYING ( -- number ) HEX: 1012 ; inline
+: AL_PAUSED ( -- number ) HEX: 1013 ; inline
+: AL_STOPPED ( -- number ) HEX: 1014 ; inline
+: AL_BUFFERS_QUEUED ( -- number ) HEX: 1015 ; inline
+: AL_BUFFERS_PROCESSED ( -- number ) HEX: 1016 ; inline
+: AL_SEC_OFFSET ( -- number ) HEX: 1024 ; inline
+: AL_SAMPLE_OFFSET ( -- number ) HEX: 1025 ; inline
+: AL_BYTE_OFFSET ( -- number ) HEX: 1026 ; inline
+: AL_SOURCE_TYPE ( -- number ) HEX: 1027 ; inline
+: AL_STATIC ( -- number ) HEX: 1028 ; inline
+: AL_STREAMING ( -- number ) HEX: 1029 ; inline
+: AL_UNDETERMINED ( -- number ) HEX: 1030 ; inline
+: AL_FORMAT_MONO8 ( -- number ) HEX: 1100 ; inline
+: AL_FORMAT_MONO16 ( -- number ) HEX: 1101 ; inline
+: AL_FORMAT_STEREO8 ( -- number ) HEX: 1102 ; inline
+: AL_FORMAT_STEREO16 ( -- number ) HEX: 1103 ; inline
+: AL_REFERENCE_DISTANCE ( -- number ) HEX: 1020 ; inline
+: AL_ROLLOFF_FACTOR ( -- number ) HEX: 1021 ; inline
+: AL_CONE_OUTER_GAIN ( -- number ) HEX: 1022 ; inline
+: AL_MAX_DISTANCE ( -- number ) HEX: 1023 ; inline
+: AL_FREQUENCY ( -- number ) HEX: 2001 ; inline
+: AL_BITS ( -- number ) HEX: 2002 ; inline
+: AL_CHANNELS ( -- number ) HEX: 2003 ; inline
+: AL_SIZE ( -- number ) HEX: 2004 ; inline
+: AL_UNUSED ( -- number ) HEX: 2010 ; inline
+: AL_PENDING ( -- number ) HEX: 2011 ; inline
+: AL_PROCESSED ( -- number ) HEX: 2012 ; inline
+: AL_NO_ERROR ( -- number ) AL_FALSE ; inline
+: AL_INVALID_NAME ( -- number ) HEX: A001 ; inline
+: AL_ILLEGAL_ENUM ( -- number ) HEX: A002 ; inline
+: AL_INVALID_ENUM ( -- number ) HEX: A002 ; inline
+: AL_INVALID_VALUE ( -- number ) HEX: A003 ; inline
+: AL_ILLEGAL_COMMAND ( -- number ) HEX: A004 ; inline
+: AL_INVALID_OPERATION ( -- number ) HEX: A004 ; inline
+: AL_OUT_OF_MEMORY ( -- number ) HEX: A005 ; inline
+: AL_VENDOR ( -- number ) HEX: B001 ; inline
+: AL_VERSION ( -- number ) HEX: B002 ; inline
+: AL_RENDERER ( -- number ) HEX: B003 ; inline
+: AL_EXTENSIONS ( -- number ) HEX: B004 ; inline
+: AL_DOPPLER_FACTOR ( -- number ) HEX: C000 ; inline
+: AL_DOPPLER_VELOCITY ( -- number ) HEX: C001 ; inline
+: AL_SPEED_OF_SOUND ( -- number ) HEX: C003 ; inline
+: AL_DISTANCE_MODEL ( -- number ) HEX: D000 ; inline
+: AL_INVERSE_DISTANCE ( -- number ) HEX: D001 ; inline
+: AL_INVERSE_DISTANCE_CLAMPED ( -- number ) HEX: D002 ; inline
+: AL_LINEAR_DISTANCE ( -- number ) HEX: D003 ; inline
+: AL_LINEAR_DISTANCE_CLAMPED ( -- number ) HEX: D004 ; inline
+: AL_EXPONENT_DISTANCE ( -- number ) HEX: D005 ; inline
+: AL_EXPONENT_DISTANCE_CLAMPED ( -- number ) HEX: D006 ; inline
+
+FUNCTION: void alEnable ( ALenum capability ) ;
+FUNCTION: void alDisable ( ALenum capability ) ; 
+FUNCTION: ALboolean alIsEnabled ( ALenum capability ) ; 
+FUNCTION: ALchar* alGetString ( ALenum param ) ;
+FUNCTION: void alGetBooleanv ( ALenum param, ALboolean* data ) ;
+FUNCTION: void alGetIntegerv ( ALenum param, ALint* data ) ;
+FUNCTION: void alGetFloatv ( ALenum param, ALfloat* data ) ;
+FUNCTION: void alGetDoublev ( ALenum param, ALdouble* data ) ;
+FUNCTION: ALboolean alGetBoolean ( ALenum param ) ;
+FUNCTION: ALint alGetInteger ( ALenum param ) ;
+FUNCTION: ALfloat alGetFloat ( ALenum param ) ;
+FUNCTION: ALdouble alGetDouble ( ALenum param ) ;
+FUNCTION: ALenum alGetError (  ) ;
+FUNCTION: ALboolean alIsExtensionPresent ( ALchar* extname ) ;
+FUNCTION: void* alGetProcAddress ( ALchar* fname ) ;
+FUNCTION: ALenum alGetEnumValue ( ALchar* ename ) ;
+FUNCTION: void alListenerf ( ALenum param, ALfloat value ) ;
+FUNCTION: void alListener3f ( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alListenerfv ( ALenum param, ALfloat* values ) ; 
+FUNCTION: void alListeneri ( ALenum param, ALint value ) ;
+FUNCTION: void alListener3i ( ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alListeneriv ( ALenum param, ALint* values ) ;
+FUNCTION: void alGetListenerf ( ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetListener3f ( ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) ;
+FUNCTION: void alGetListenerfv ( ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetListeneri ( ALenum param, ALint* value ) ;
+FUNCTION: void alGetListener3i ( ALenum param, ALint* value1, ALint* value2, ALint* value3 ) ;
+FUNCTION: void alGetListeneriv ( ALenum param, ALint* values ) ;
+FUNCTION: void alGenSources ( ALsizei n, ALuint* sources ) ; 
+FUNCTION: void alDeleteSources ( ALsizei n, ALuint* sources ) ;
+FUNCTION: ALboolean alIsSource ( ALuint sid ) ; 
+FUNCTION: void alSourcef ( ALuint sid, ALenum param, ALfloat value ) ; 
+FUNCTION: void alSource3f ( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ; 
+FUNCTION: void alSourcei ( ALuint sid, ALenum param, ALint value ) ; 
+FUNCTION: void alSource3i ( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alSourceiv ( ALuint sid, ALenum param, ALint* values ) ;
+FUNCTION: void alGetSourcef ( ALuint sid, ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetSource3f ( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
+FUNCTION: void alGetSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetSourcei ( ALuint sid,  ALenum param, ALint* value ) ;
+FUNCTION: void alGetSource3i ( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
+FUNCTION: void alGetSourceiv ( ALuint sid,  ALenum param, ALint* values ) ;
+FUNCTION: void alSourcePlayv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourceStopv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourceRewindv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourcePausev ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourcePlay ( ALuint sid ) ;
+FUNCTION: void alSourceStop ( ALuint sid ) ;
+FUNCTION: void alSourceRewind ( ALuint sid ) ;
+FUNCTION: void alSourcePause ( ALuint sid ) ;
+FUNCTION: void alSourceQueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
+FUNCTION: void alSourceUnqueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
+FUNCTION: void alGenBuffers ( ALsizei n, ALuint* buffers ) ;
+FUNCTION: void alDeleteBuffers ( ALsizei n, ALuint* buffers ) ;
+FUNCTION: ALboolean alIsBuffer ( ALuint bid ) ;
+FUNCTION: void alBufferData ( ALuint bid, ALenum format, void* data, ALsizei size, ALsizei freq ) ;
+FUNCTION: void alBufferf ( ALuint bid, ALenum param, ALfloat value ) ;
+FUNCTION: void alBuffer3f ( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alBufferi ( ALuint bid, ALenum param, ALint value ) ;
+FUNCTION: void alBuffer3i ( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
+FUNCTION: void alGetBufferf ( ALuint bid, ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetBuffer3f ( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
+FUNCTION: void alGetBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetBufferi ( ALuint bid, ALenum param, ALint* value ) ;
+FUNCTION: void alGetBuffer3i ( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
+FUNCTION: void alGetBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
+FUNCTION: void alDopplerFactor ( ALfloat value ) ;
+FUNCTION: void alDopplerVelocity ( ALfloat value ) ;
+FUNCTION: void alSpeedOfSound ( ALfloat value ) ;
+FUNCTION: void alDistanceModel ( ALenum distanceModel ) ;
+
+LIBRARY: alut
+
+: ALUT_API_MAJOR_VERSION ( -- number ) 1 ; inline
+: ALUT_API_MINOR_VERSION ( -- number ) 1 ; inline
+: ALUT_ERROR_NO_ERROR ( -- number ) 0 ; inline
+: ALUT_ERROR_OUT_OF_MEMORY ( -- number ) HEX: 200 ; inline
+: ALUT_ERROR_INVALID_ENUM ( -- number ) HEX: 201 ; inline
+: ALUT_ERROR_INVALID_VALUE ( -- number ) HEX: 202 ; inline
+: ALUT_ERROR_INVALID_OPERATION ( -- number ) HEX: 203 ; inline
+: ALUT_ERROR_NO_CURRENT_CONTEXT ( -- number ) HEX: 204 ; inline
+: ALUT_ERROR_AL_ERROR_ON_ENTRY ( -- number ) HEX: 205 ; inline
+: ALUT_ERROR_ALC_ERROR_ON_ENTRY ( -- number ) HEX: 206 ; inline
+: ALUT_ERROR_OPEN_DEVICE ( -- number ) HEX: 207 ; inline
+: ALUT_ERROR_CLOSE_DEVICE ( -- number ) HEX: 208 ; inline
+: ALUT_ERROR_CREATE_CONTEXT ( -- number ) HEX: 209 ; inline
+: ALUT_ERROR_MAKE_CONTEXT_CURRENT ( -- number ) HEX: 20A ; inline
+: ALUT_ERROR_DESTRY_CONTEXT ( -- number ) HEX: 20B ; inline
+: ALUT_ERROR_GEN_BUFFERS ( -- number ) HEX: 20C ; inline
+: ALUT_ERROR_BUFFER_DATA ( -- number ) HEX: 20D ; inline
+: ALUT_ERROR_IO_ERROR ( -- number ) HEX: 20E ; inline
+: ALUT_ERROR_UNSUPPORTED_FILE_TYPE ( -- number ) HEX: 20F ; inline
+: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE ( -- number ) HEX: 210 ; inline
+: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA ( -- number ) HEX: 211 ; inline
+: ALUT_WAVEFORM_SINE ( -- number ) HEX: 100 ; inline
+: ALUT_WAVEFORM_SQUARE ( -- number ) HEX: 101 ; inline
+: ALUT_WAVEFORM_SAWTOOTH ( -- number ) HEX: 102 ; inline
+: ALUT_WAVEFORM_WHITENOISE ( -- number ) HEX: 103 ; inline
+: ALUT_WAVEFORM_IMPULSE ( -- number ) HEX: 104 ; inline
+: ALUT_LOADER_BUFFER ( -- number ) HEX: 300 ; inline
+: ALUT_LOADER_MEMORY ( -- number ) HEX: 301 ; inline
+
+FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutExit ( ) ;
+FUNCTION: ALenum alutGetError ( ) ;
+FUNCTION: char* alutGetErrorString ( ALenum error ) ;
+FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
+FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
+FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
+FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
+FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
+FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
+FUNCTION: ALint alutGetMajorVersion ( ) ;
+FUNCTION: ALint alutGetMinorVersion ( ) ;
+FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
+
+FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
+
+SYMBOL: init
+
+: init-openal ( -- )
+  init get-global expired? [
+    f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
+    1337 <alien> init set-global
+  ] when ;
+
+: exit-openal ( -- )
+  init get-global expired? [
+    alutExit 0 = [ "Could not close OpenAL" throw ] when
+    f init set-global
+  ] unless ;
+
+: <uint-array> ( n -- byte-array ) "ALuint" <c-array> ;
+
+: gen-sources ( size -- seq )
+  dup <uint-array> 2dup underlying>> alGenSources swap ;
+
+: gen-buffers ( size -- seq )
+  dup <uint-array> 2dup underlying>> alGenBuffers swap ;
+
+: gen-buffer ( -- buffer ) 1 gen-buffers first ;
+
+: create-buffer-from-file ( filename -- buffer )
+  alutCreateBufferFromFile dup AL_NONE = [
+    "create-buffer-from-file failed" throw
+  ] when ;
+
+os macosx? "openal.macosx" "openal.other" ? require
+
+: create-buffer-from-wav ( filename -- buffer )
+  gen-buffer dup rot load-wav-file
+  [ alBufferData ] 4keep alutUnloadWAV ;
+
+: queue-buffers ( source buffers -- )
+    [ length ] [ >uint-array underlying>> ] bi alSourceQueueBuffers ;
+
+: queue-buffer ( source buffer -- )
+    1array queue-buffers ;
+
+: set-source-param ( source param value -- )
+  alSourcei ;
+
+: get-source-param ( source param -- value )
+  0 <uint> dup >r alGetSourcei r> *uint ;
+
+: set-buffer-param ( source param value -- )
+  alBufferi ;
+
+: get-buffer-param ( source param -- value )
+  0 <uint> dup >r alGetBufferi r> *uint ;
+
+: source-play ( source -- )
+  alSourcePlay ;
+
+: source-stop ( source -- )
+  alSourceStop ;
+
+: check-error ( -- )
+  alGetError dup ALUT_ERROR_NO_ERROR = [
+    drop
+  ] [
+    alGetString throw
+  ] if ;
+
+: source-playing? ( source -- bool )
+  AL_SOURCE_STATE get-source-param AL_PLAYING = ;
diff --git a/unmaintained/openal/other/authors.txt b/unmaintained/openal/other/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/unmaintained/openal/other/other.factor b/unmaintained/openal/other/other.factor
new file mode 100644 (file)
index 0000000..d0429fb
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: openal.backend alien.c-types kernel alien alien.syntax
+shuffle combinators.lib ;
+IN: openal.other
+
+LIBRARY: alut
+
+FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency, ALboolean* looping ) ;
+
+M: object load-wav-file ( filename -- format data size frequency )
+  0 <int> f <void*> 0 <int> 0 <int>
+  [ 0 <char> alutLoadWAVFile ] 4keep
+  >r >r >r *int r> *void* r> *int r> *int ;
diff --git a/unmaintained/openal/summary.txt b/unmaintained/openal/summary.txt
new file mode 100644 (file)
index 0000000..5df8b3a
--- /dev/null
@@ -0,0 +1 @@
+OpenAL 3D audio library binding
diff --git a/unmaintained/openal/tags.txt b/unmaintained/openal/tags.txt
new file mode 100644 (file)
index 0000000..a5b2257
--- /dev/null
@@ -0,0 +1,2 @@
+bindings
+audio
diff --git a/unmaintained/plot/plot.factor b/unmaintained/plot/plot.factor
new file mode 100644 (file)
index 0000000..52cd2fa
--- /dev/null
@@ -0,0 +1,137 @@
+
+USING: kernel quotations arrays sequences math math.ranges fry
+       opengl opengl.gl ui.render ui.gadgets.cartesian processing.shapes
+       accessors ;
+
+IN: ui.gadgets.plot
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: plot < cartesian functions points ;
+
+: init-plot ( plot -- plot )
+  init-cartesian
+    { } >>functions
+    100 >>points ;
+
+: <plot> ( -- plot ) plot new init-plot ;
+
+: step-size ( plot -- step-size )
+  [ [ x-max>> ] [ x-min>> ] bi - ] [ points>> ] bi / ;
+
+: plot-range ( plot -- range )
+  [ x-min>> ] [ x-max>> ] [ step-size ] tri <range> ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: function function color ;
+
+GENERIC: plot-function ( plot object -- plot )
+
+M: callable plot-function ( plot quotation -- plot )
+  >r dup plot-range r> '[ dup @ 2array ] map line-strip ;
+
+M: function plot-function ( plot function -- plot )
+   dup color>> dup [ >stroke-color ] [ drop ] if
+   >r dup plot-range r> function>> '[ dup @ 2array ] map line-strip ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: plot-functions ( plot -- plot ) dup functions>> [ plot-function ] each ;
+
+: draw-axis ( plot -- plot )
+  dup
+    [ [ x-min>> ] [ drop 0  ] bi 2array ]
+    [ [ x-max>> ] [ drop 0  ] bi 2array ] bi line*
+  dup
+    [ [ drop 0  ] [ y-min>> ] bi 2array ]
+    [ [ drop 0  ] [ y-max>> ] bi 2array ] bi line* ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: ui.gadgets.slate ;
+
+M: plot draw-slate ( plot -- plot )
+   2 glLineWidth
+   draw-axis
+   plot-functions
+   fill-mode
+   1 glLineWidth ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: add-function ( plot function -- plot )
+  over functions>> swap suffix >>functions ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: x-span ( plot -- span ) [ x-max>> ] [ x-min>> ] bi - ;
+: y-span ( plot -- span ) [ y-max>> ] [ y-min>> ] bi - ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: ui.gestures ui.gadgets ;
+
+: left ( plot -- plot )
+  dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min
+  dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max
+  dup relayout-1 ;
+
+: right ( plot -- plot )
+  dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min
+  dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max
+  dup relayout-1 ;
+
+: down ( plot -- plot )
+  dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min
+  dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max
+  dup relayout-1 ;
+
+: up ( plot -- plot )
+  dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min
+  dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max
+  dup relayout-1 ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: zoom-in-horizontal ( plot -- plot )
+  dup [ x-min>> ] [ x-span 1/10 * ] bi + >>x-min
+  dup [ x-max>> ] [ x-span 1/10 * ] bi - >>x-max ;
+
+: zoom-in-vertical ( plot -- plot )
+  dup [ y-min>> ] [ y-span 1/10 * ] bi + >>y-min
+  dup [ y-max>> ] [ y-span 1/10 * ] bi - >>y-max ;
+
+: zoom-in ( plot -- plot )
+  zoom-in-horizontal
+  zoom-in-vertical
+  dup relayout-1 ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: zoom-out-horizontal ( plot -- plot )
+  dup [ x-min>> ] [ x-span 1/10 * ] bi - >>x-min
+  dup [ x-max>> ] [ x-span 1/10 * ] bi + >>x-max ;
+
+: zoom-out-vertical ( plot -- plot )
+  dup [ y-min>> ] [ y-span 1/10 * ] bi - >>y-min
+  dup [ y-max>> ] [ y-span 1/10 * ] bi + >>y-max ;
+
+: zoom-out ( plot -- plot )
+  zoom-out-horizontal
+  zoom-out-vertical
+  dup relayout-1 ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+plot
+  H{
+    { T{ mouse-enter } [ request-focus ] }
+    { T{ key-down f f "LEFT"  } [ left drop  ] }
+    { T{ key-down f f "RIGHT" } [ right drop ] }
+    { T{ key-down f f "DOWN"  } [ down drop  ] }
+    { T{ key-down f f "UP"    } [ up drop    ] }
+    { T{ key-down f f "a"     } [ zoom-in  drop ] }
+    { T{ key-down f f "z"     } [ zoom-out drop ] }
+  }
+set-gestures
\ No newline at end of file
diff --git a/unmaintained/synth/authors.txt b/unmaintained/synth/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/synth/buffers/authors.txt b/unmaintained/synth/buffers/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/synth/buffers/buffers.factor b/unmaintained/synth/buffers/buffers.factor
new file mode 100644 (file)
index 0000000..b0128ca
--- /dev/null
@@ -0,0 +1,76 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types combinators kernel locals math math.ranges openal sequences sequences.merged ;
+IN: synth.buffers
+
+TUPLE: buffer sample-freq 8bit? id ;
+
+: <buffer> ( sample-freq 8bit? -- buffer )
+    f buffer boa ;
+
+TUPLE: mono-buffer < buffer data ;
+
+: <mono-buffer> ( sample-freq 8bit? -- buffer )
+    f f mono-buffer boa ;
+
+: <8bit-mono-buffer> ( sample-freq -- buffer ) t <mono-buffer> ;
+: <16bit-mono-buffer> ( sample-freq -- buffer ) f <mono-buffer> ;
+
+TUPLE: stereo-buffer < buffer left-data right-data ;
+
+: <stereo-buffer> ( sample-freq 8bit? -- buffer )
+    f f f stereo-buffer boa ;
+
+: <8bit-stereo-buffer> ( sample-freq -- buffer ) t <stereo-buffer> ;
+: <16bit-stereo-buffer> ( sample-freq -- buffer ) f <stereo-buffer> ;
+
+PREDICATE: 8bit-buffer < buffer 8bit?>> ;
+PREDICATE: 16bit-buffer < buffer 8bit?>> not ;
+INTERSECTION: 8bit-mono-buffer 8bit-buffer mono-buffer ;
+INTERSECTION: 16bit-mono-buffer 16bit-buffer mono-buffer ;
+INTERSECTION: 8bit-stereo-buffer 8bit-buffer stereo-buffer ;
+INTERSECTION: 16bit-stereo-buffer 16bit-buffer stereo-buffer ;
+
+GENERIC: buffer-format ( buffer -- format )
+M: 8bit-mono-buffer buffer-format drop AL_FORMAT_MONO8 ;
+M: 16bit-mono-buffer buffer-format drop AL_FORMAT_MONO16 ;
+M: 8bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO8 ;
+M: 16bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO16 ;
+
+: 8bit-buffer-data ( seq -- data size )
+    [ 128 * >integer 128 + ] uchar-array{ } map-as [ underlying>> ] [ length ] bi ;
+
+: 16bit-buffer-data ( seq -- data size )
+    [ 32768 * >integer ] short-array{ } map-as [ underlying>> ] [ byte-length ] bi ;
+
+: stereo-data ( stereo-buffer -- left right )
+    [ left-data>> ] [ right-data>> ] bi@ ;
+
+: interleaved-stereo-data ( stereo-buffer -- data )
+    stereo-data <2merged> ;
+
+GENERIC: buffer-data ( buffer -- data size )
+M: 8bit-mono-buffer buffer-data data>> 8bit-buffer-data ;
+M: 16bit-mono-buffer buffer-data data>> 16bit-buffer-data ;
+M: 8bit-stereo-buffer buffer-data
+    interleaved-stereo-data 8bit-buffer-data ;
+M: 16bit-stereo-buffer buffer-data
+    interleaved-stereo-data 16bit-buffer-data ;
+
+: telephone-sample-freq 8000 ;
+: half-sample-freq 22050 ;
+: cd-sample-freq 44100 ;
+: digital-sample-freq 48000 ;
+: professional-sample-freq 88200 ;
+
+: send-buffer ( buffer -- buffer )
+    {
+        [ gen-buffer dup [ >>id ] dip ]
+        [ buffer-format ]
+        [ buffer-data ]
+        [ sample-freq>> alBufferData ]
+    } cleave ;
+
+: ?send-buffer ( buffer -- buffer )
+    dup id>> [ send-buffer ] unless ;
+
diff --git a/unmaintained/synth/example/authors.txt b/unmaintained/synth/example/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/unmaintained/synth/example/example.factor b/unmaintained/synth/example/example.factor
new file mode 100644 (file)
index 0000000..747cfb9
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays kernel namespaces make openal sequences
+synth synth.buffers ;
+IN: synth.example
+
+: play-sine-wave ( freq seconds sample-freq -- )
+    init-openal
+    <16bit-mono-buffer> >sine-wave-buffer send-buffer id>>
+    1 gen-sources first
+    [ AL_BUFFER rot set-source-param ] [ source-play ] bi
+    check-error ;
+
+: test-instrument1 ( -- harmonics )
+    [
+        1 0.5 <harmonic> ,
+        2 0.125 <harmonic> ,
+        3 0.0625 <harmonic> ,
+        4 0.03125 <harmonic> ,
+    ] { } make ;
+
+: test-instrument2 ( -- harmonics )
+    [
+        1 0.25 <harmonic> ,
+        2 0.25 <harmonic> ,
+        3 0.25 <harmonic> ,
+        4 0.25 <harmonic> ,
+    ] { } make ;
+
+: sine-instrument ( -- harmonics )
+    1 1 <harmonic> 1array ;
+
+: test-note-buffer ( note -- )
+    init-openal
+    test-instrument2 swap cd-sample-freq <16bit-mono-buffer>
+    >note send-buffer id>>
+    1 gen-sources first [ swap queue-buffer ] [ source-play ] bi
+    check-error ;
diff --git a/unmaintained/synth/summary.txt b/unmaintained/synth/summary.txt
new file mode 100644 (file)
index 0000000..ece5893
--- /dev/null
@@ -0,0 +1 @@
+Simple sound synthesis using OpenAL.
diff --git a/unmaintained/synth/synth.factor b/unmaintained/synth/synth.factor
new file mode 100644 (file)
index 0000000..be1e594
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel locals math math.constants math.functions memoize openal synth.buffers sequences sequences.modified sequences.repeating ;
+IN: synth
+
+MEMO: single-sine-wave ( samples/wave -- seq )
+    pi 2 * over / [ * sin ] curry map ;
+
+: (sine-wave) ( samples/wave n-samples -- seq )
+    [ single-sine-wave ] dip <repeating> ;
+
+: sine-wave ( sample-freq freq seconds -- seq )
+    pick * >integer [ /i ] dip (sine-wave) ;
+
+: >sine-wave-buffer ( freq seconds buffer -- buffer )
+    [ sample-freq>> -rot sine-wave ] keep swap >>data ;
+
+: >silent-buffer ( seconds buffer -- buffer )
+    tuck sample-freq>> * >integer 0 <repetition> >>data ;
+
+TUPLE: harmonic n amplitude ;
+C: <harmonic> harmonic
+
+TUPLE: note hz secs ;
+C: <note> note
+
+: harmonic-freq ( note harmonic -- freq )
+    n>> swap hz>> * ;
+
+:: note-harmonic-data ( harmonic note buffer -- data )
+    buffer sample-freq>> note harmonic harmonic-freq note secs>> sine-wave
+    harmonic amplitude>> <scaled> ;
+
+: >note ( harmonics note buffer -- buffer )
+    dup -roll [ note-harmonic-data ] 2curry map <summed> >>data ;
+
diff --git a/unmaintained/xml/syntax/syntax.factor b/unmaintained/xml/syntax/syntax.factor
new file mode 100644 (file)
index 0000000..91b31ec
--- /dev/null
@@ -0,0 +1,58 @@
+! Copyright (C) 2008 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: lexer parser splitting kernel quotations namespaces make
+sequences assocs sequences.lib xml.generator xml.utilities
+xml.data ;
+IN: xml.syntax
+
+: parsed-name ( accum -- accum )
+    scan ":" split1 [ f <name> ] [ <simple-name> ] if* parsed ;
+
+: run-combinator ( accum quot1 quot2 -- accum )
+    >r [ ] like parsed r> [ parsed ] each ;
+
+: parse-tag-contents ( accum contained? -- accum )
+    [ \ contained*, parsed ] [
+        scan-word \ [ =
+        [ POSTPONE: [ \ tag*, parsed ]
+        [ "Expected [ missing" throw ] if
+    ] if ;
+
+DEFER: >>
+
+: attributes-parsed ( accum quot -- accum )
+    [ f parsed ] [
+        >r \ >r parsed r> parsed
+        [ H{ } make-assoc r> swap ] [ parsed ] each
+    ] if-empty ;
+
+: <<
+    parsed-name [
+        \ >> parse-until >quotation
+        attributes-parsed \ contained? get
+    ] with-scope parse-tag-contents ; parsing
+
+: ==
+    \ call parsed parsed-name \ set parsed ; parsing
+
+: //
+    \ contained? on ; parsing
+
+: parse-special ( accum end-token word -- accum )
+    >r parse-tokens " " join parsed r> parsed ;
+
+: <!-- "-->" \ comment, parse-special ; parsing
+
+: <!  ">" \ directive, parse-special ; parsing
+
+: <? "?>" \ instruction, parse-special ; parsing
+
+: >xml-document ( seq -- xml )
+    dup first prolog? [ unclip-slice ] [ standard-prolog ] if swap
+    [ tag? ] split-around <xml> ;
+
+DEFER: XML>
+
+: <XML
+    \ XML> [ >quotation ] parse-literal
+    { } parsed \ make parsed \ >xml-document parsed ; parsing
index e2063c4a75834ceadb382642eb7fdf21259ccfc9..7ef5f89559e24018c06e12e1f755985c8e412936 100644 (file)
@@ -1,3 +1,3 @@
 include vm/Config.macosx
 include vm/Config.x86.64
-CFLAGS += -arch x86_64
+CFLAGS += -m64
index 72616afbc5ace7bf9d5598a3437474e56d2f23a4..1f4bc3ce7693f0435c41792bf884422eb5b6cf89 100644 (file)
@@ -1396,7 +1396,7 @@ allot_bignum_zeroed(bignum_length_type length, int negative_p)
 }
 
 #define BIGNUM_REDUCE_LENGTH(source, length) \
-     source = reallot_array(source,length + 1,0)
+     source = reallot_array(source,length + 1)
 
 /* allocates memory */
 bignum_type
index 59e99b0260911974f1184b10ecca3bcdfa2a1342..c15185944af5fed1522cb505dd1fc6fba19e89df 100755 (executable)
@@ -259,13 +259,43 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
 /* Copy all literals referenced from a code block to newspace */
 void collect_literals_step(F_COMPILED *compiled, CELL code_start, CELL literals_start)
 {
-       CELL scan;
-       CELL literal_end = literals_start + compiled->literals_length;
+       if(collecting_gen >= compiled->last_scan)
+       {
+               CELL scan;
+               CELL literal_end = literals_start + compiled->literals_length;
+
+               if(collecting_accumulation_gen_p())
+                       compiled->last_scan = collecting_gen;
+               else
+                       compiled->last_scan = collecting_gen + 1;
+
+               for(scan = literals_start; scan < literal_end; scan += CELLS)
+                       copy_handle((CELL*)scan);
+
+               if(compiled->relocation != F)
+               {
+                       copy_handle(&compiled->relocation);
 
-       copy_handle(&compiled->relocation);
+                       F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
 
-       for(scan = literals_start; scan < literal_end; scan += CELLS)
-               copy_handle((CELL*)scan);
+                       F_REL *rel = (F_REL *)(relocation + 1);
+                       F_REL *rel_end = (F_REL *)((char *)rel + byte_array_capacity(relocation));
+
+                       while(rel < rel_end)
+                       {
+                               if(REL_TYPE(rel) == RT_IMMEDIATE)
+                               {
+                                       CELL offset = rel->offset + code_start;
+                                       F_FIXNUM absolute_value = get(CREF(literals_start,REL_ARGUMENT(rel)));
+                                       apply_relocation(REL_CLASS(rel),offset,absolute_value);
+                               }
+
+                               rel++;
+                       }
+               }
+
+               flush_icache(code_start,literals_start - code_start);
+       }
 }
 
 /* Copy literals referenced from all code blocks to newspace */
index f3a4071e98482d089fe1b26ea0be65ab93ed9866..6ed5ea43095574c53287202c81cecf174bd3f0e2 100755 (executable)
@@ -7,8 +7,6 @@ void undefined_symbol(void)
        general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
 }
 
-#define CREF(array,i) ((CELL)(array) + CELLS * (i))
-
 INLINE CELL get_literal(CELL literals_start, CELL num)
 {
        return get(CREF(literals_start,num));
@@ -55,18 +53,22 @@ void *get_rel_symbol(F_REL *rel, CELL literals_start)
 INLINE CELL compute_code_rel(F_REL *rel,
        CELL code_start, CELL literals_start)
 {
+       CELL obj;
+
        switch(REL_TYPE(rel))
        {
        case RT_PRIMITIVE:
                return (CELL)primitives[REL_ARGUMENT(rel)];
        case RT_DLSYM:
                return (CELL)get_rel_symbol(rel,literals_start);
-       case RT_LITERAL:
-               return CREF(literals_start,REL_ARGUMENT(rel));
        case RT_IMMEDIATE:
                return get(CREF(literals_start,REL_ARGUMENT(rel)));
        case RT_XT:
-               return (CELL)untag_word(get(CREF(literals_start,REL_ARGUMENT(rel))))->xt;
+               obj = get(CREF(literals_start,REL_ARGUMENT(rel)));
+               if(type_of(obj) == WORD_TYPE)
+                       return (CELL)untag_word(obj)->xt;
+               else
+                       return (CELL)untag_quotation(obj)->xt;
        case RT_HERE:
                return rel->offset + code_start + (short)REL_ARGUMENT(rel);
        case RT_LABEL:
@@ -277,6 +279,7 @@ F_COMPILED *add_compiled_block(
        /* compiled header */
        F_COMPILED *header = (void *)here;
        header->type = type;
+       header->last_scan = NURSERY;
        header->code_length = code_length;
        header->literals_length = literals_length;
        header->relocation = relocation;
index 7b1545ddf57d803799ec1045f22f90cb69c10834..d167ece7fae052699e33ee3d132f2fc382d9b338 100755 (executable)
@@ -3,8 +3,6 @@ typedef enum {
        RT_PRIMITIVE,
        /* arg is a literal table index, holding an array pair (symbol/dll) */
        RT_DLSYM,
-       /* an indirect literal from the word's literal table */
-       RT_LITERAL,
        /* a pointer to a compiled word reference */
        RT_DISPATCH,
        /* a compiled word reference */
@@ -57,6 +55,10 @@ typedef struct {
        unsigned int offset;
 } F_REL;
 
+#define CREF(array,i) ((CELL)(array) + CELLS * (i))
+
+void apply_relocation(CELL class, CELL offset, F_FIXNUM absolute_value);
+
 void relocate_code_block(F_COMPILED *relocating, CELL code_start, CELL literals_start);
 
 void default_word_code(F_WORD *word, bool relocate);
index d98c033a4f003ddd5137218b326e92e8e6d1aa25..09e3331b990ed7a65dbce3ac4b38ff94f64603f5 100755 (executable)
@@ -117,7 +117,7 @@ DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
 DEF(void,lazy_jit_compile,(CELL quot)):
        mov r1,sp            /* save stack pointer */
        PROLOGUE
-       bl MANGLE(primitive_jit_compile)
+       bl MANGLE(lazy_jit_compile_impl)
        EPILOGUE
         JUMP_QUOT            /* call the quotation */
 
index 620bc9e99169a308d2a3f843072e5780af2f3866..4cf997a51534d2652259f970ae775173889c277d 100755 (executable)
@@ -2,6 +2,47 @@
 in the public domain. */
 #include "asm.h"
 
+#define DS_REG r29
+
+DEF(void,primitive_fixnum_add,(void)):
+    lwz r3,0(DS_REG)
+    lwz r4,-4(DS_REG)
+    subi DS_REG,DS_REG,4
+    li r0,0
+    mtxer r0
+    addo. r5,r3,r4
+    bso add_overflow
+    stw r5,0(DS_REG)
+    blr
+add_overflow:
+       b MANGLE(overflow_fixnum_add)
+
+DEF(void,primitive_fixnum_subtract,(void)):
+    lwz r3,-4(DS_REG)
+    lwz r4,0(DS_REG)
+    subi DS_REG,DS_REG,4
+    li r0,0
+    mtxer r0
+    subfo. r5,r4,r3
+       bso sub_overflow
+    stw r5,0(DS_REG)
+    blr
+sub_overflow:
+    b MANGLE(overflow_fixnum_subtract)
+
+DEF(void,primitive_fixnum_multiply,(void)):
+    lwz r3,0(DS_REG)
+    lwz r4,-4(DS_REG)
+    subi DS_REG,DS_REG,4
+    srawi r3,r3,3
+    mullwo. r5,r3,r4
+    bso multiply_overflow
+    stw r5,0(DS_REG)
+    blr
+multiply_overflow:
+    srawi r4,r4,3
+    b MANGLE(overflow_fixnum_multiply)
+    
 /* Note that the XT is passed to the quotation in r11 */
 #define CALL_OR_JUMP_QUOT \
        lwz r11,9(r3)      /* load quotation-xt slot */ XX \
@@ -165,7 +206,7 @@ DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
 DEF(void,lazy_jit_compile,(CELL quot)):
        mr r4,r1           /* save stack pointer */
        PROLOGUE
-       bl MANGLE(primitive_jit_compile)
+       bl MANGLE(lazy_jit_compile_impl)
        EPILOGUE
        JUMP_QUOT          /* call the quotation */
 
index 6ddbd52da2db80c73adc63365856ec6dc6204f96..36db5d6c80bcdc489db117f0ff4a162a0a610429 100755 (executable)
@@ -12,6 +12,10 @@ and the callstack top is passed in EDX */
 
 #define NV_TEMP_REG %ebx
 
+#define ARITH_TEMP_1 %ebp
+#define ARITH_TEMP_2 %ebx
+#define DIV_RESULT %eax
+
 #define CELL_SIZE 4
 #define STACK_PADDING 12
 
index c981095d62ac85104ba3667919b1617a2454282e..7b5b5f3167fdfb9eb0ef43bc4fa4b423b5cad0bc 100644 (file)
@@ -9,6 +9,10 @@
 
 #define NV_TEMP_REG %rbp
 
+#define ARITH_TEMP_1 %r8
+#define ARITH_TEMP_2 %r9
+#define DIV_RESULT %rax
+
 #ifdef WINDOWS
 
        #define ARG0 %rcx
index 1857fb0ed806de7728148f01ee12da53c800768d..7a0d738fe063b279fbd66ed66a9f14507afbdee5 100755 (executable)
@@ -1,3 +1,39 @@
+DEF(void,primitive_fixnum_add,(void)):
+    mov (DS_REG),ARG0
+    mov -CELL_SIZE(DS_REG),ARG1
+    sub $CELL_SIZE,DS_REG
+    mov ARG1,ARITH_TEMP_1
+    add ARG0,ARITH_TEMP_1
+    jo MANGLE(overflow_fixnum_add)
+    mov ARITH_TEMP_1,(DS_REG)
+    ret
+
+DEF(void,primitive_fixnum_subtract,(void)):
+    mov (DS_REG),ARG1
+    mov -CELL_SIZE(DS_REG),ARG0
+    sub $CELL_SIZE,DS_REG
+    mov ARG0,ARITH_TEMP_1
+    sub ARG1,ARITH_TEMP_1
+    jo MANGLE(overflow_fixnum_subtract)
+    mov ARITH_TEMP_1,(DS_REG)
+    ret
+
+DEF(void,primitive_fixnum_multiply,(void)):
+    mov (DS_REG),ARITH_TEMP_1
+    mov ARITH_TEMP_1,DIV_RESULT
+    mov -CELL_SIZE(DS_REG),ARITH_TEMP_2
+    sar $3,ARITH_TEMP_2
+    sub $CELL_SIZE,DS_REG
+    imul ARITH_TEMP_2
+    jo multiply_overflow
+    mov DIV_RESULT,(DS_REG)
+    ret
+multiply_overflow:
+    sar $3,ARITH_TEMP_1
+    mov ARITH_TEMP_1,ARG0
+    mov ARITH_TEMP_2,ARG1
+    jmp MANGLE(overflow_fixnum_multiply)
+
 DEF(F_FASTCALL void,c_to_factor,(CELL quot)):
        PUSH_NONVOLATILE
        mov ARG0,NV_TEMP_REG
@@ -27,7 +63,7 @@ DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
 DEF(FASTCALL void,lazy_jit_compile,(CELL quot)):
        mov STACK_REG,ARG1           /* Save stack pointer */
        sub $STACK_PADDING,STACK_REG
-       call MANGLE(primitive_jit_compile)
+       call MANGLE(lazy_jit_compile_impl)
        mov RETURN_REG,ARG0          /* No-op on 32-bit */
        add $STACK_PADDING,STACK_REG
         jmp *QUOT_XT_OFFSET(ARG0)    /* Call the quotation */
index 23836c560c62530e9c1d5a564175abe868b9d3ea..513a7c429c258c458003aec40d5a8792899454e5 100755 (executable)
@@ -111,8 +111,7 @@ void clear_cards(CELL from, CELL to)
        /* NOTE: reverse order due to heap layout. */
        F_CARD *first_card = ADDR_TO_CARD(data_heap->generations[to].start);
        F_CARD *last_card = ADDR_TO_CARD(data_heap->generations[from].end);
-       F_CARD *ptr;
-       for(ptr = first_card; ptr < last_card; ptr++) *ptr = 0;
+       memset(first_card,0,last_card - first_card);
 }
 
 void clear_decks(CELL from, CELL to)
@@ -120,8 +119,7 @@ void clear_decks(CELL from, CELL to)
        /* NOTE: reverse order due to heap layout. */
        F_DECK *first_deck = ADDR_TO_DECK(data_heap->generations[to].start);
        F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[from].end);
-       F_DECK *ptr;
-       for(ptr = first_deck; ptr < last_deck; ptr++) *ptr = 0;
+       memset(first_deck,0,last_deck - first_deck);
 }
 
 void clear_allot_markers(CELL from, CELL to)
@@ -129,8 +127,7 @@ void clear_allot_markers(CELL from, CELL to)
        /* NOTE: reverse order due to heap layout. */
        F_CARD *first_card = ADDR_TO_ALLOT_MARKER(data_heap->generations[to].start);
        F_CARD *last_card = ADDR_TO_ALLOT_MARKER(data_heap->generations[from].end);
-       F_CARD *ptr;
-       for(ptr = first_card; ptr < last_card; ptr++) *ptr = INVALID_ALLOT_MARKER;
+       memset(first_card,INVALID_ALLOT_MARKER,last_card - first_card);
 }
 
 void set_data_heap(F_DATA_HEAP *data_heap_)
@@ -303,21 +300,15 @@ void primitive_end_scan(void)
 /* Scan all the objects in the card */
 void collect_card(F_CARD *ptr, CELL gen, CELL here)
 {
-       CELL offset = CARD_OFFSET(ptr);
-
-       if(offset != INVALID_ALLOT_MARKER)
-       {
-               if(offset & TAG_MASK)
-                       critical_error("Bad card",(CELL)ptr);
+       CELL card_scan = (CELL)CARD_TO_ADDR(ptr) + CARD_OFFSET(ptr);
+       CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1);
 
-               CELL card_scan = (CELL)CARD_TO_ADDR(ptr) + offset;
-               CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1);
+       if(here < card_end)
+               card_end = here;
 
-               while(card_scan < card_end && card_scan < here)
-                       card_scan = collect_next(card_scan);
+       collect_next_loop(card_scan,&card_end);
 
-               cards_scanned++;
-       }
+       cards_scanned++;
 }
 
 void collect_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
@@ -497,11 +488,10 @@ void collect_roots(void)
 /* Given a pointer to oldspace, copy it to newspace */
 INLINE void *copy_untagged_object(void *pointer, CELL size)
 {
-       void *newpointer;
        if(newspace->here + size >= newspace->end)
                longjmp(gc_jmp,1);
        allot_barrier(newspace->here);
-       newpointer = allot_zone(newspace,size);
+       void *newpointer = allot_zone(newspace,size);
 
        F_GC_STATS *s = &gc_stats[collecting_gen];
        s->object_count++;
@@ -571,6 +561,9 @@ the GC. Some types have a binary payload at the end (string, word, DLL) which
 we ignore. */
 CELL binary_payload_start(CELL pointer)
 {
+       F_TUPLE *tuple;
+       F_TUPLE_LAYOUT *layout;
+
        switch(untag_header(get(pointer)))
        {
        /* these objects do not refer to other objects at all */
@@ -591,8 +584,21 @@ CELL binary_payload_start(CELL pointer)
        case STRING_TYPE:
                return sizeof(F_STRING);
        /* everything else consists entirely of pointers */
+       case ARRAY_TYPE:
+               return array_size(array_capacity((F_ARRAY*)pointer));
+       case TUPLE_TYPE:
+               tuple = untag_object(pointer);
+               layout = untag_object(tuple->layout);
+               return tuple_size(layout);
+       case RATIO_TYPE:
+               return sizeof(F_RATIO);
+       case COMPLEX_TYPE:
+               return sizeof(F_COMPLEX);
+       case WRAPPER_TYPE:
+               return sizeof(F_WRAPPER);
        default:
-               return unaligned_object_size(pointer);
+               critical_error("Invalid header",pointer);
+               return -1; /* can't happen */
        }
 }
 
@@ -622,19 +628,15 @@ void do_code_slots(CELL scan)
        }
 }
 
-/* This function is performance-critical */
-CELL collect_next(CELL scan)
+CELL collect_next_nursery(CELL scan)
 {
        CELL *obj = (CELL *)scan;
        CELL *end = (CELL *)(scan + binary_payload_start(scan));
 
-       obj++;
-
-       CELL newspace_start = newspace->start;
-       CELL newspace_end = newspace->end;
-
-       if(HAVE_NURSERY_P && collecting_gen == NURSERY)
+       if(obj != end)
        {
+               obj++;
+
                CELL nursery_start = nursery.start;
                CELL nursery_end = nursery.end;
 
@@ -647,12 +649,24 @@ CELL collect_next(CELL scan)
                                *obj = copy_object(pointer);
                }
        }
-       else if(HAVE_AGING_P && collecting_gen == AGING)
+
+       return scan + untagged_object_size(scan);
+}
+
+CELL collect_next_aging(CELL scan)
+{
+       CELL *obj = (CELL *)scan;
+       CELL *end = (CELL *)(scan + binary_payload_start(scan));
+
+       if(obj != end)
        {
-               F_ZONE *tenured = &data_heap->generations[TENURED];
+               obj++;
 
-               CELL tenured_start = tenured->start;
-               CELL tenured_end = tenured->end;
+               CELL tenured_start = data_heap->generations[TENURED].start;
+               CELL tenured_end = data_heap->generations[TENURED].end;
+
+               CELL newspace_start = newspace->start;
+               CELL newspace_end = newspace->end;
 
                for(; obj < end; obj++)
                {
@@ -664,25 +678,56 @@ CELL collect_next(CELL scan)
                                *obj = copy_object(pointer);
                }
        }
-       else if(collecting_gen == TENURED)
+
+       return scan + untagged_object_size(scan);
+}
+
+/* This function is performance-critical */
+CELL collect_next_tenured(CELL scan)
+{
+       CELL *obj = (CELL *)scan;
+       CELL *end = (CELL *)(scan + binary_payload_start(scan));
+
+       if(obj != end)
        {
+               obj++;
+
+               CELL newspace_start = newspace->start;
+               CELL newspace_end = newspace->end;
+
                for(; obj < end; obj++)
                {
                        CELL pointer = *obj;
 
-                       if(!immediate_p(pointer)
-                               && !(pointer >= newspace_start && pointer < newspace_end))
+                       if(!immediate_p(pointer) && !(pointer >= newspace_start && pointer < newspace_end))
                                *obj = copy_object(pointer);
                }
-
-               do_code_slots(scan);
        }
-       else
-               critical_error("Bug in collect_next",0);
+
+       do_code_slots(scan);
 
        return scan + untagged_object_size(scan);
 }
 
+void collect_next_loop(CELL scan, CELL *end)
+{
+       if(HAVE_NURSERY_P && collecting_gen == NURSERY)
+       {
+               while(scan < *end)
+                       scan = collect_next_nursery(scan);
+       }
+       else if(HAVE_AGING_P && collecting_gen == AGING)
+       {
+               while(scan < *end)
+                       scan = collect_next_aging(scan);
+       }
+       else if(collecting_gen == TENURED)
+       {
+               while(scan < *end)
+                       scan = collect_next_tenured(scan);
+       }
+}
+
 INLINE void reset_generation(CELL i)
 {
        F_ZONE *z = (i == NURSERY ? &nursery : &data_heap->generations[i]);
@@ -763,6 +808,10 @@ void end_gc(CELL gc_elapsed)
                if(collecting_gen != NURSERY)
                        reset_generations(NURSERY,collecting_gen - 1);
        }
+       else if(HAVE_NURSERY_P && collecting_gen == NURSERY)
+       {
+               nursery.here = nursery.start;
+       }
        else
        {
                /* all generations up to and including the one
@@ -836,12 +885,13 @@ void garbage_collection(CELL gen,
        /* collect objects referenced from older generations */
        collect_cards();
 
-       if(collecting_gen != TENURED)
+       /* don't scan code heap unless it has pointers to this
+       generation or younger */
+       if(collecting_gen >= last_code_heap_scan)
        {
-               /* don't scan code heap unless it has pointers to this
-               generation or younger */
-               if(collecting_gen >= last_code_heap_scan)
+               if(collecting_gen != TENURED)
                {
+               
                        /* if we are doing code GC, then we will copy over
                        literals from any code block which gets marked as live.
                        if we are not doing code GC, just consider all literals
@@ -849,16 +899,15 @@ void garbage_collection(CELL gen,
                        code_heap_scans++;
 
                        collect_literals();
-
-                       if(collecting_accumulation_gen_p())
-                               last_code_heap_scan = collecting_gen;
-                       else
-                               last_code_heap_scan = collecting_gen + 1;
                }
+
+               if(collecting_accumulation_gen_p())
+                       last_code_heap_scan = collecting_gen;
+               else
+                       last_code_heap_scan = collecting_gen + 1;
        }
 
-       while(scan < newspace->here)
-               scan = collect_next(scan);
+       collect_next_loop(scan,&newspace->here);
 
        CELL gc_elapsed = (current_micros() - start);
 
@@ -936,6 +985,7 @@ void primitive_become(void)
        }
 
        gc();
+       iterate_code_heap(relocate_code_block);
 }
 
 CELL find_all_words(void)
index a407ed761cf0dd801f32c5cb826625b4d4688c74..4ec3fdd5f2be752ed84bb41924ad756b3ee4acc7 100755 (executable)
@@ -386,7 +386,7 @@ INLINE void* allot_object(CELL type, CELL a)
        return object;
 }
 
-CELL collect_next(CELL scan);
+void collect_next_loop(CELL scan, CELL *end);
 
 void primitive_gc(void);
 void primitive_gc_stats(void);
index db8e60c781232a67f4d36b39973089c5e758b205..909cc8f710e71cd3ed28eab6e5e57627a80180e5 100755 (executable)
@@ -129,7 +129,7 @@ void print_nested_obj(CELL obj, F_FIXNUM nesting)
                print_string(" ]");
                break;
        default:
-               print_string("#<type "); print_cell(type_of(obj)); print_string(" @ "); print_cell_hex(obj);
+               print_string("#<type "); print_cell(type_of(obj)); print_string(" @ "); print_cell_hex(obj); print_string(">");
                break;
        }
 }
index 0e6591f8d80db956b95906e3b8bc9fb07725e004..6fb5910392d2e5626b07215472f742e50dbff93e 100755 (executable)
@@ -174,21 +174,6 @@ void primitive_save_image(void)
        save_image(unbox_native_string());
 }
 
-void strip_compiled_quotations(void)
-{
-       begin_scan();
-       CELL obj;
-       while((obj = next_object()) != F)
-       {
-               if(type_of(obj) == QUOTATION_TYPE)
-               {
-                       F_QUOTATION *quot = untag_object(obj);
-                       quot->compiledp = F;
-               }
-       }
-       gc_off = false;
-}
-
 void primitive_save_image_and_exit(void)
 {
        /* We unbox this before doing anything else. This is the only point
@@ -198,9 +183,6 @@ void primitive_save_image_and_exit(void)
 
        REGISTER_C_STRING(path);
 
-       /* This reduces deployed image size */
-       strip_compiled_quotations();
-
        /* strip out userenv data which is set on startup anyway */
        CELL i;
        for(i = 0; i < FIRST_SAVE_ENV; i++)
index e55a5e9fd369e0128b24f6ce52fbb515b4edf9b6..74a4c0475e00d7e7d03a5448821eb31c89e95be8 100755 (executable)
@@ -104,7 +104,8 @@ typedef struct {
 /* The compiled code heap is structured into blocks. */
 typedef struct
 {
-       CELL type; /* this is WORD_TYPE or QUOTATION_TYPE */
+       char type; /* this is WORD_TYPE or QUOTATION_TYPE */
+       char last_scan; /* the youngest generation in which this block's literals may live */
        CELL code_length; /* # bytes */
        CELL literals_length; /* # bytes */
        CELL relocation; /* tagged pointer to byte-array or f */
index 07493a947fa7955dc2d59887387bc4a272eb4668..dd01e852ad0d68107688286645b43d0e6392cc81 100644 (file)
--- a/vm/math.c
+++ b/vm/math.c
@@ -1,7 +1,6 @@
 #include "master.h"
 
 /* Fixnums */
-
 F_FIXNUM to_fixnum(CELL tagged)
 {
        switch(TAG(tagged))
@@ -31,50 +30,35 @@ void primitive_float_to_fixnum(void)
        drepl(tag_fixnum(float_to_fixnum(dpeek())));
 }
 
-#define POP_FIXNUMS(x,y) \
-       F_FIXNUM y = untag_fixnum_fast(dpop()); \
-       F_FIXNUM x = untag_fixnum_fast(dpeek());
-
-void primitive_fixnum_add(void)
+/* The fixnum+, fixnum- and fixnum* primitives are defined in cpu_*.S. On
+overflow, they call these functions. */
+F_FASTCALL void overflow_fixnum_add(F_FIXNUM x, F_FIXNUM y)
 {
-       POP_FIXNUMS(x,y)
-       drepl(allot_integer(x + y));
+       drepl(tag_bignum(fixnum_to_bignum(
+               untag_fixnum_fast(x) + untag_fixnum_fast(y))));
 }
 
-void primitive_fixnum_subtract(void)
+F_FASTCALL void overflow_fixnum_subtract(F_FIXNUM x, F_FIXNUM y)
 {
-       POP_FIXNUMS(x,y)
-       drepl(allot_integer(x - y));
+       drepl(tag_bignum(fixnum_to_bignum(
+               untag_fixnum_fast(x) - untag_fixnum_fast(y))));
 }
 
-/* Multiply two integers, and trap overflow.
-Thanks to David Blaikie (The_Vulture from freenode #java) for the hint. */
-void primitive_fixnum_multiply(void)
+F_FASTCALL void overflow_fixnum_multiply(F_FIXNUM x, F_FIXNUM y)
 {
-       POP_FIXNUMS(x,y)
-
-       if(x == 0 || y == 0)
-               drepl(tag_fixnum(0));
-       else
-       {
-               F_FIXNUM prod = x * y;
-               /* if this is not equal, we have overflow */
-               if(prod / x == y)
-                       drepl(allot_integer(prod));
-               else
-               {
-                       F_ARRAY *bx = fixnum_to_bignum(x);
-                       REGISTER_BIGNUM(bx);
-                       F_ARRAY *by = fixnum_to_bignum(y);
-                       UNREGISTER_BIGNUM(bx);
-                       drepl(tag_bignum(bignum_multiply(bx,by)));
-               }
-       }
+       F_ARRAY *bx = fixnum_to_bignum(x);
+       REGISTER_BIGNUM(bx);
+       F_ARRAY *by = fixnum_to_bignum(y);
+       UNREGISTER_BIGNUM(bx);
+       drepl(tag_bignum(bignum_multiply(bx,by)));
 }
 
+/* Division can only overflow when we are dividing the most negative fixnum
+by -1. */
 void primitive_fixnum_divint(void)
 {
-       POP_FIXNUMS(x,y)
+       F_FIXNUM y = untag_fixnum_fast(dpop()); \
+       F_FIXNUM x = untag_fixnum_fast(dpeek());
        F_FIXNUM result = x / y;
        if(result == -FIXNUM_MIN)
                drepl(allot_integer(-FIXNUM_MIN));
@@ -99,31 +83,30 @@ void primitive_fixnum_divmod(void)
 }
 
 /*
- * Note the hairy overflow check.
  * If we're shifting right by n bits, we won't overflow as long as none of the
  * high WORD_SIZE-TAG_BITS-n bits are set.
  */
+#define SIGN_MASK(x) ((x) >> (WORD_SIZE - 1))
+#define BRANCHLESS_MAX(x,y) ((x) - (((x) - (y)) & SIGN_MASK((x) - (y))))
+#define BRANCHLESS_ABS(x) ((x ^ SIGN_MASK(x)) - SIGN_MASK(x))
+
 void primitive_fixnum_shift(void)
 {
-       POP_FIXNUMS(x,y)
+       F_FIXNUM y = untag_fixnum_fast(dpop()); \
+       F_FIXNUM x = untag_fixnum_fast(dpeek());
 
-       if(x == 0 || y == 0)
-       {
-               drepl(tag_fixnum(x));
+       if(x == 0)
                return;
-       }
        else if(y < 0)
        {
-               if(y <= -WORD_SIZE)
-                       drepl(x < 0 ? tag_fixnum(-1) : tag_fixnum(0));
-               else
-                       drepl(tag_fixnum(x >> -y));
+               y = BRANCHLESS_MAX(y,-WORD_SIZE + 1);
+               drepl(tag_fixnum(x >> -y));
                return;
        }
        else if(y < WORD_SIZE - TAG_BITS)
        {
                F_FIXNUM mask = -((F_FIXNUM)1 << (WORD_SIZE - 1 - TAG_BITS - y));
-               if((x > 0 && (x & mask) == 0) || (x & mask) == mask)
+               if(!(BRANCHLESS_ABS(x) & mask))
                {
                        drepl(tag_fixnum(x << y));
                        return;
index 4fa3c8d35f086d1a60e85404a4c87ed38f878e57..f94f12b76d40e047f30164bb864477d2e1ad06ae 100644 (file)
--- a/vm/math.h
+++ b/vm/math.h
@@ -12,6 +12,11 @@ void primitive_float_to_fixnum(void);
 void primitive_fixnum_add(void);
 void primitive_fixnum_subtract(void);
 void primitive_fixnum_multiply(void);
+
+DLLEXPORT F_FASTCALL void overflow_fixnum_add(F_FIXNUM x, F_FIXNUM y);
+DLLEXPORT F_FASTCALL void overflow_fixnum_subtract(F_FIXNUM x, F_FIXNUM y);
+DLLEXPORT F_FASTCALL void overflow_fixnum_multiply(F_FIXNUM x, F_FIXNUM y);
+
 void primitive_fixnum_divint(void);
 void primitive_fixnum_divmod(void);
 void primitive_fixnum_shift(void);
index d14e6ceb23a10880327e3de1442223373347da9e..9b0366ff757adc0154c33410088d2592a9d72c60 100644 (file)
@@ -25,6 +25,14 @@ NS_ENDHANDLER
 
 void early_init(void)
 {
+       SInt32 version;
+       Gestalt(gestaltSystemVersion,&version);
+       if(version <= 0x1050)
+       {
+               printf("Factor requires Mac OS X 10.5 or later.\n");
+               exit(1);
+       }
+
        [[NSAutoreleasePool alloc] init];
 }
 
index 97b1b39129e8e92b4d05762c388994c9f7c7f144..b2a1735fd798ea6dd14592de8b2fa24f44bfdccd 100755 (executable)
@@ -23,6 +23,7 @@ typedef char F_SYMBOL;
 #define STRNCMP strncmp
 #define STRDUP strdup
 
+#define FIXNUM_FORMAT "%ld"
 #define CELL_FORMAT "%lu"
 #define CELL_HEX_FORMAT "%lx"
 
index 0aeb77741ba896c072c4a6f241348c66a9e33429..ee2c7211119e59212abdd3104bcc12ce15a3a8ac 100755 (executable)
@@ -168,5 +168,5 @@ long getpagesize(void)
 
 void sleep_micros(DWORD usec)
 {
-       Sleep(msec / 1000);
+       Sleep(usec);
 }
index b12d677af2bd1f5ae9d0b47055ffab3bb757e6ba..af9b75bca5c931d1028c629ac666eb113c227b29 100755 (executable)
@@ -20,13 +20,13 @@ typedef wchar_t F_CHAR;
 #define STRNCMP wcsncmp
 #define STRDUP _wcsdup
 
+#define FIXNUM_FORMAT "%Id"
+#define CELL_FORMAT "%lu"
+#define CELL_HEX_FORMAT "%Ix"
+
 #ifdef WIN64
-        #define CELL_FORMAT "%Iu"
-        #define CELL_HEX_FORMAT "%Ix"
        #define CELL_HEX_PAD_FORMAT "%016Ix"
 #else
-        #define CELL_FORMAT "%lu"
-        #define CELL_HEX_FORMAT "%lx"
        #define CELL_HEX_PAD_FORMAT "%08lx"
 #endif
 
index 5adb135c820d5f46c26474d5443f37b8e67c39d7..a01a8653b7879a6af41d873b1ab0fd1506fe3c6e 100755 (executable)
@@ -105,7 +105,8 @@ void *primitives[] = {
        primitive_alien_address,
        primitive_set_slot,
        primitive_string_nth,
-       primitive_set_string_nth,
+       primitive_set_string_nth_fast,
+       primitive_set_string_nth_slow,
        primitive_resize_array,
        primitive_resize_string,
        primitive_array,
@@ -140,4 +141,6 @@ void *primitives[] = {
        primitive_dll_validp,
        primitive_unimplemented,
        primitive_gc_reset,
+       primitive_jit_compile,
+       primitive_load_locals,
 };
index 179224f7987d0acaa6047d98302b5c520dc81b36..a187fecbbb51ad5cebe7af040b98be9ba2444ad5 100755 (executable)
@@ -9,6 +9,10 @@ The non-optimizing compiler compiles a quotation at a time by concatenating
 machine code chunks; prolog, epilog, call word, jump to word, etc. These machine
 code chunks are generated from Factor code in core/cpu/.../bootstrap.factor.
 
+Calls to words and constant quotations (referenced by conditionals and dips)
+are direct jumps to machine code blocks. Literals are also referenced directly
+without going through the literal table.
+
 It actually does do a little bit of very simple optimization:
 
 1) Tail call optimization.
@@ -21,12 +25,15 @@ generated.
 'if' and 'dispatch' conditionals are generated inline, instead of as a call to
 the 'if' word.
 
-4) When preceded by an array, calls to the 'declare' word are optimized out
+4) When preceded by a quotation, calls to 'dip', '2dip' and '3dip' are
+open-coded as retain stack manipulation surrounding a subroutine call.
+
+5) When preceded by an array, calls to the 'declare' word are optimized out
 entirely. This word is only used by the optimizing compiler, and with the
 non-optimizing compiler it would otherwise just decrease performance to have to
 push the array and immediately drop it after.
 
-5) Sub-primitives are primitive words which are implemented in assembly and not
+6) Sub-primitives are primitive words which are implemented in assembly and not
 in the VM. They are open-coded and no subroutine call is generated. This
 includes stack shufflers, some fixnum arithmetic words, and words such as tag,
 slot and eq?. A primitive call is relatively expensive (two subroutine calls)
@@ -232,7 +239,7 @@ void jit_compile(CELL quot, bool relocate)
                case WRAPPER_TYPE:
                        wrapper = untag_object(obj);
                        GROWABLE_ARRAY_ADD(literals,wrapper->object);
-                       EMIT(userenv[JIT_PUSH_LITERAL],literals_count - 1);
+                       EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
                        break;
                case FIXNUM_TYPE:
                        if(jit_primitive_call_p(untag_object(array),i))
@@ -251,9 +258,13 @@ void jit_compile(CELL quot, bool relocate)
                                if(stack_frame)
                                        EMIT(userenv[JIT_EPILOG],0);
 
+                               jit_compile(array_nth(untag_object(array),i),relocate);
+                               jit_compile(array_nth(untag_object(array),i + 1),relocate);
+
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
+                               EMIT(userenv[JIT_IF_1],literals_count - 1);
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i + 1));
-                               EMIT(userenv[JIT_IF_JUMP],literals_count - 2);
+                               EMIT(userenv[JIT_IF_2],literals_count - 1);
 
                                i += 2;
 
@@ -262,6 +273,8 @@ void jit_compile(CELL quot, bool relocate)
                        }
                        else if(jit_fast_dip_p(untag_object(array),i))
                        {
+                               jit_compile(obj,relocate);
+
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
                                EMIT(userenv[JIT_DIP],literals_count - 1);
 
@@ -270,6 +283,8 @@ void jit_compile(CELL quot, bool relocate)
                        }
                        else if(jit_fast_2dip_p(untag_object(array),i))
                        {
+                               jit_compile(obj,relocate);
+
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
                                EMIT(userenv[JIT_2DIP],literals_count - 1);
 
@@ -278,6 +293,8 @@ void jit_compile(CELL quot, bool relocate)
                        }
                        else if(jit_fast_3dip_p(untag_object(array),i))
                        {
+                               jit_compile(obj,relocate);
+
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
                                EMIT(userenv[JIT_3DIP],literals_count - 1);
 
@@ -305,7 +322,7 @@ void jit_compile(CELL quot, bool relocate)
                        }
                default:
                        GROWABLE_ARRAY_ADD(literals,obj);
-                       EMIT(userenv[immediate_p(obj) ? JIT_PUSH_IMMEDIATE : JIT_PUSH_LITERAL],literals_count - 1);
+                       EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
                        break;
                }
        }
@@ -348,8 +365,10 @@ worse than the duplication itself (eg, putting all state in some global
 struct.) */
 #define COUNT(name,scan) \
        { \
+               CELL size = array_capacity(code_to_emit(name)) * code_format; \
                if(offset == 0) return scan - 1; \
-               offset -= array_capacity(code_to_emit(name)) * code_format; \
+               if(offset < size) return scan + 1; \
+               offset -= size; \
        }
 
 F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
@@ -392,7 +411,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
                                COUNT(userenv[JIT_WORD_CALL],i)
                        break;
                case WRAPPER_TYPE:
-                       COUNT(userenv[JIT_PUSH_LITERAL],i)
+                       COUNT(userenv[JIT_PUSH_IMMEDIATE],i)
                        break;
                case FIXNUM_TYPE:
                        if(jit_primitive_call_p(untag_object(array),i))
@@ -411,29 +430,29 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
                                if(stack_frame)
                                        COUNT(userenv[JIT_EPILOG],i)
 
+                               COUNT(userenv[JIT_IF_1],i)
+                               COUNT(userenv[JIT_IF_2],i)
                                i += 2;
 
-                               COUNT(userenv[JIT_IF_JUMP],i)
-
                                tail_call = true;
                                break;
                        }
                        else if(jit_fast_dip_p(untag_object(array),i))
                        {
-                               i++;
                                COUNT(userenv[JIT_DIP],i)
+                               i++;
                                break;
                        }
                        else if(jit_fast_2dip_p(untag_object(array),i))
                        {
-                               i++;
                                COUNT(userenv[JIT_2DIP],i)
+                               i++;
                                break;
                        }
                        else if(jit_fast_3dip_p(untag_object(array),i))
                        {
-                               i++;
                                COUNT(userenv[JIT_3DIP],i)
+                               i++;
                                break;
                        }
                case ARRAY_TYPE:
@@ -458,7 +477,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
                                break;
                        }
                default:
-                       COUNT(userenv[immediate_p(obj) ? JIT_PUSH_IMMEDIATE : JIT_PUSH_LITERAL],i)
+                       COUNT(userenv[JIT_PUSH_IMMEDIATE],i)
                        break;
                }
        }
@@ -474,7 +493,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
        return -1;
 }
 
-F_FASTCALL CELL primitive_jit_compile(CELL quot, F_STACK_FRAME *stack)
+F_FASTCALL CELL lazy_jit_compile_impl(CELL quot, F_STACK_FRAME *stack)
 {
        stack_chain->callstack_top = stack;
        REGISTER_ROOT(quot);
@@ -483,6 +502,11 @@ F_FASTCALL CELL primitive_jit_compile(CELL quot, F_STACK_FRAME *stack)
        return quot;
 }
 
+void primitive_jit_compile(void)
+{
+       jit_compile(dpop(),true);
+}
+
 /* push a new quotation on the stack */
 void primitive_array_to_quotation(void)
 {
index 45bf78d14fb384d299f0a0ae5e392d8ab1f2f0aa..ff84977fd9dd935bad786dfe9ab6ba2e178a7acc 100755 (executable)
@@ -1,6 +1,7 @@
 void set_quot_xt(F_QUOTATION *quot, F_COMPILED *code);
 void jit_compile(CELL quot, bool relocate);
-F_FASTCALL CELL primitive_jit_compile(CELL quot, F_STACK_FRAME *stack);
+F_FASTCALL CELL lazy_jit_compile_impl(CELL quot, F_STACK_FRAME *stack);
 F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset);
 void primitive_array_to_quotation(void);
 void primitive_quotation_xt(void);
+void primitive_jit_compile(void);
index a28a956f2974257e6a25099037103a4b88e72499..c7002eb0ecaadcccd23f935ff72e9ff8af9fad9a 100755 (executable)
--- a/vm/run.c
+++ b/vm/run.c
@@ -190,3 +190,11 @@ void primitive_set_slot(void)
        CELL value = dpop();
        set_slot(obj,slot,value);
 }
+
+void primitive_load_locals(void)
+{
+       F_FIXNUM count = untag_fixnum_fast(dpop());
+       memcpy((CELL *)(rs + CELLS),(CELL *)(ds - CELLS * (count - 1)),CELLS * count);
+       ds -= CELLS * count;
+       rs += CELLS * count;
+}
index eae0146298835c70a74129fbd6b1cd4be78168c0..06b631701508d282f0640a22d34e1709e26c2657 100755 (executable)
--- a/vm/run.h
+++ b/vm/run.h
@@ -39,9 +39,9 @@ typedef enum {
        JIT_PRIMITIVE,
        JIT_WORD_JUMP,
        JIT_WORD_CALL,
-       JIT_PUSH_LITERAL,
        JIT_IF_WORD,
-       JIT_IF_JUMP,
+       JIT_IF_1,
+       JIT_IF_2,
        JIT_DISPATCH_WORD,
        JIT_DISPATCH,
        JIT_EPILOG,
@@ -247,5 +247,6 @@ void primitive_set_os_envs(void);
 void primitive_micros(void);
 void primitive_sleep(void);
 void primitive_set_slot(void);
+void primitive_load_locals(void);
 
 bool stage2;
index f1588465a4dae398fb45659060dc8ef9f9c780ef..1afbcd3a4062fb2ef7597851fad0274a658b599c 100755 (executable)
@@ -139,18 +139,6 @@ CELL allot_array_1(CELL obj)
        return tag_object(a);
 }
 
-CELL allot_array_2(CELL v1, CELL v2)
-{
-       REGISTER_ROOT(v1);
-       REGISTER_ROOT(v2);
-       F_ARRAY *a = allot_array_internal(ARRAY_TYPE,2);
-       UNREGISTER_ROOT(v2);
-       UNREGISTER_ROOT(v1);
-       set_array_nth(a,0,v1);
-       set_array_nth(a,1,v2);
-       return tag_object(a);
-}
-
 CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
 {
        REGISTER_ROOT(v1);
@@ -169,27 +157,18 @@ CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
        return tag_object(a);
 }
 
-F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill)
+F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity)
 {
-       int i;
-       F_ARRAY* new_array;
-
        CELL to_copy = array_capacity(array);
        if(capacity < to_copy)
                to_copy = capacity;
 
        REGISTER_UNTAGGED(array);
-       REGISTER_ROOT(fill);
-
-       new_array = allot_array_internal(untag_header(array->header),capacity);
-
-       UNREGISTER_ROOT(fill);
+       F_ARRAY* new_array = allot_array_internal(untag_header(array->header),capacity);
        UNREGISTER_UNTAGGED(array);
 
        memcpy(new_array + 1,array + 1,to_copy * CELLS);
-
-       for(i = to_copy; i < capacity; i++)
-               put(AREF(new_array,i),fill);
+       memset((char *)AREF(new_array,to_copy),'\0',(capacity - to_copy) * CELLS);
 
        return new_array;
 }
@@ -198,7 +177,7 @@ void primitive_resize_array(void)
 {
        F_ARRAY* array = untag_array(dpop());
        CELL capacity = unbox_array_size();
-       dpush(tag_object(reallot_array(array,capacity,F)));
+       dpush(tag_object(reallot_array(array,capacity)));
 }
 
 F_ARRAY *growable_array_add(F_ARRAY *result, CELL elt, CELL *result_count)
@@ -207,8 +186,7 @@ F_ARRAY *growable_array_add(F_ARRAY *result, CELL elt, CELL *result_count)
 
        if(*result_count == array_capacity(result))
        {
-               result = reallot_array(result,
-                       *result_count * 2,F);
+               result = reallot_array(result,*result_count * 2);
        }
 
        UNREGISTER_ROOT(elt);
@@ -226,7 +204,7 @@ F_ARRAY *growable_array_append(F_ARRAY *result, F_ARRAY *elts, CELL *result_coun
        CELL new_size = *result_count + elts_size;
 
        if(new_size >= array_capacity(result))
-               result = reallot_array(result,new_size * 2,F);
+               result = reallot_array(result,new_size * 2);
 
        UNREGISTER_UNTAGGED(elts);
 
@@ -331,58 +309,71 @@ void primitive_tuple_boa(void)
 {
        F_TUPLE_LAYOUT *layout = untag_object(dpop());
        F_FIXNUM size = untag_fixnum_fast(layout->size);
-
-       REGISTER_UNTAGGED(layout);
        F_TUPLE *tuple = allot_tuple(layout);
-       UNREGISTER_UNTAGGED(layout);
-
-       F_FIXNUM i;
-       for(i = size - 1; i >= 0; i--)
-               put(AREF(tuple,i),dpop());
-
+       memcpy(tuple + 1,(CELL *)(ds - CELLS * (size - 1)),CELLS * size);
+       ds -= CELLS * size;
        dpush(tag_tuple(tuple));
 }
 
 /* Strings */
 CELL string_nth(F_STRING* string, CELL index)
 {
+       /* If high bit is set, the most significant 16 bits of the char
+       come from the aux vector. The least significant bit of the
+       corresponding aux vector entry is negated, so that we can
+       XOR the two components together and get the original code point
+       back. */
        CELL ch = bget(SREF(string,index));
-       if(string->aux == F)
+       if((ch & 0x80) == 0)
                return ch;
        else
        {
                F_BYTE_ARRAY *aux = untag_object(string->aux);
-               return (cget(BREF(aux,index * sizeof(u16))) << 8) | ch;
+               return (cget(BREF(aux,index * sizeof(u16))) << 7) ^ ch;
        }
 }
 
-/* allocates memory */
-void set_string_nth(F_STRING* string, CELL index, CELL value)
+void set_string_nth_fast(F_STRING* string, CELL index, CELL ch)
 {
-       bput(SREF(string,index),value & 0xff);
+       bput(SREF(string,index),ch);
+}
 
+void set_string_nth_slow(F_STRING* string, CELL index, CELL ch)
+{
        F_BYTE_ARRAY *aux;
 
+       bput(SREF(string,index),(ch & 0x7f) | 0x80);
+
        if(string->aux == F)
        {
-               if(value <= 0xff)
-                       return;
-               else
-               {
-                       REGISTER_UNTAGGED(string);
-                       aux = allot_byte_array(
-                               untag_fixnum_fast(string->length)
-                               * sizeof(u16));
-                       UNREGISTER_UNTAGGED(string);
+               REGISTER_UNTAGGED(string);
+               /* We don't need to pre-initialize the
+               byte array with any data, since we
+               only ever read from the aux vector
+               if the most significant bit of a
+               character is set. Initially all of
+               the bits are clear. */
+               aux = allot_byte_array_internal(
+                       untag_fixnum_fast(string->length)
+                       * sizeof(u16));
+               UNREGISTER_UNTAGGED(string);
 
-                       write_barrier((CELL)string);
-                       string->aux = tag_object(aux);
-               }
+               write_barrier((CELL)string);
+               string->aux = tag_object(aux);
        }
        else
                aux = untag_object(string->aux);
 
-       cput(BREF(aux,index * sizeof(u16)),value >> 8);
+       cput(BREF(aux,index * sizeof(u16)),(ch >> 7) ^ 1);
+}
+
+/* allocates memory */
+void set_string_nth(F_STRING* string, CELL index, CELL ch)
+{
+       if(ch <= 0x7f)
+               set_string_nth_fast(string,index,ch);
+       else
+               set_string_nth_slow(string,index,ch);
 }
 
 /* untagged */
@@ -400,17 +391,8 @@ F_STRING* allot_string_internal(CELL capacity)
 /* allocates memory */
 void fill_string(F_STRING *string, CELL start, CELL capacity, CELL fill)
 {
-       if(fill == 0)
-       {
-               memset((void *)SREF(string,start),'\0',capacity - start);
-
-               if(string->aux != F)
-               {
-                       F_BYTE_ARRAY *aux = untag_object(string->aux);
-                       memset((void *)BREF(aux,start * sizeof(u16)),'\0',
-                               (capacity - start) * sizeof(u16));
-               }
-       }
+       if(fill <= 0x7f)
+               memset((void *)SREF(string,start),fill,capacity - start);
        else
        {
                CELL i;
@@ -441,7 +423,7 @@ void primitive_string(void)
        dpush(tag_object(allot_string(length,initial)));
 }
 
-F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill)
+F_STRING* reallot_string(F_STRING* string, CELL capacity)
 {
        CELL to_copy = string_capacity(string);
        if(capacity < to_copy)
@@ -470,7 +452,7 @@ F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill)
 
        REGISTER_UNTAGGED(string);
        REGISTER_UNTAGGED(new_string);
-       fill_string(new_string,to_copy,capacity,fill);
+       fill_string(new_string,to_copy,capacity,'\0');
        UNREGISTER_UNTAGGED(new_string);
        UNREGISTER_UNTAGGED(string);
 
@@ -481,7 +463,7 @@ void primitive_resize_string(void)
 {
        F_STRING* string = untag_string(dpop());
        CELL capacity = unbox_array_size();
-       dpush(tag_object(reallot_string(string,capacity,0)));
+       dpush(tag_object(reallot_string(string,capacity)));
 }
 
 /* Some ugly macros to prevent a 2x code duplication */
@@ -590,3 +572,19 @@ void primitive_set_string_nth(void)
        CELL value = untag_fixnum_fast(dpop());
        set_string_nth(string,index,value);
 }
+
+void primitive_set_string_nth_fast(void)
+{
+       F_STRING *string = untag_object(dpop());
+       CELL index = untag_fixnum_fast(dpop());
+       CELL value = untag_fixnum_fast(dpop());
+       set_string_nth_fast(string,index,value);
+}
+
+void primitive_set_string_nth_slow(void)
+{
+       F_STRING *string = untag_object(dpop());
+       CELL index = untag_fixnum_fast(dpop());
+       CELL value = untag_fixnum_fast(dpop());
+       set_string_nth_slow(string,index,value);
+}
index ebbb8a264241aa22382e0e7cd11c542323f6f32c..ba8d9689fe8b810c5c02ddc25944b2cebc44fba2 100755 (executable)
@@ -109,7 +109,6 @@ F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill);
 F_BYTE_ARRAY *allot_byte_array(CELL size);
 
 CELL allot_array_1(CELL obj);
-CELL allot_array_2(CELL v1, CELL v2);
 CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4);
 
 void primitive_array(void);
@@ -119,7 +118,7 @@ void primitive_tuple_layout(void);
 void primitive_byte_array(void);
 void primitive_clone(void);
 
-F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill);
+F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity);
 F_BYTE_ARRAY *reallot_byte_array(F_BYTE_ARRAY *array, CELL capacity);
 void primitive_resize_array(void);
 void primitive_resize_byte_array(void);
@@ -127,7 +126,7 @@ void primitive_resize_byte_array(void);
 F_STRING* allot_string_internal(CELL capacity);
 F_STRING* allot_string(CELL capacity, CELL fill);
 void primitive_string(void);
-F_STRING *reallot_string(F_STRING *string, CELL capacity, CELL fill);
+F_STRING *reallot_string(F_STRING *string, CELL capacity);
 void primitive_resize_string(void);
 
 F_STRING *memory_to_char_string(const char *string, CELL length);
@@ -153,7 +152,8 @@ CELL string_nth(F_STRING* string, CELL index);
 void set_string_nth(F_STRING* string, CELL index, CELL value);
 
 void primitive_string_nth(void);
-void primitive_set_string_nth(void);
+void primitive_set_string_nth_slow(void);
+void primitive_set_string_nth_fast(void);
 
 F_WORD *allot_word(CELL vocab, CELL name);
 void primitive_word(void);
@@ -177,7 +177,7 @@ F_ARRAY *growable_array_append(F_ARRAY *result, F_ARRAY *elts, CELL *result_coun
        result = tag_object(growable_array_append(untag_object(result),elts,&result##_count))
 
 #define GROWABLE_ARRAY_TRIM(result) \
-       result = tag_object(reallot_array(untag_object(result),result##_count,F))
+       result = tag_object(reallot_array(untag_object(result),result##_count))
 
 /* Macros to simulate a byte vector in C */
 #define GROWABLE_BYTE_ARRAY(result) \
index 35fc7ad087f19f1e726e006c00bb9e336f1352c0..d97b540884b8a7e3bab9a38598d4d548151e14d5 100755 (executable)
@@ -44,7 +44,7 @@ void print_cell_hex_pad(CELL x)
 
 void print_fixnum(F_FIXNUM x)
 {
-       printf(CELL_FORMAT,x);
+       printf(FIXNUM_FORMAT,x);
 }
 
 CELL read_cell_hex(void)