]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor into tangle
authorAlex Chapman <chapman.alex@gmail.com>
Mon, 14 Apr 2008 15:58:49 +0000 (01:58 +1000)
committerAlex Chapman <chapman.alex@gmail.com>
Mon, 14 Apr 2008 15:58:49 +0000 (01:58 +1000)
Conflicts:

extra/semantic-db/hierarchy/hierarchy.factor
extra/semantic-db/semantic-db.factor

507 files changed:
README.txt
build-support/factor.sh
core/alien/alien-docs.factor
core/alien/alien.factor
core/alien/c-types/c-types.factor
core/alien/compiler/compiler.factor
core/alien/structs/structs.factor
core/alien/syntax/syntax.factor
core/arrays/arrays.factor
core/assocs/assocs-docs.factor
core/assocs/assocs-tests.factor
core/assocs/assocs.factor
core/bit-arrays/bit-arrays.factor
core/bit-vectors/bit-vectors.factor
core/bit-vectors/summary.txt [new file with mode: 0644]
core/bit-vectors/tags.txt [new file with mode: 0644]
core/bootstrap/compiler/compiler.factor
core/bootstrap/layouts/layouts.factor
core/bootstrap/primitives.factor
core/bootstrap/stage2.factor
core/boxes/boxes.factor
core/byte-arrays/byte-arrays.factor
core/byte-vectors/byte-vectors.factor
core/byte-vectors/summary.txt [new file with mode: 0644]
core/byte-vectors/tags.txt [new file with mode: 0644]
core/classes/algebra/algebra.factor
core/classes/classes.factor
core/classes/mixin/mixin.factor
core/classes/tuple/tuple-docs.factor
core/classes/tuple/tuple-tests.factor
core/classes/tuple/tuple.factor
core/combinators/combinators-docs.factor
core/combinators/combinators-tests.factor
core/combinators/combinators.factor
core/command-line/command-line-docs.factor
core/compiler/compiler.factor
core/compiler/tests/simple.factor
core/compiler/tests/tuples.factor
core/compiler/units/units.factor
core/continuations/continuations-docs.factor
core/cpu/architecture/architecture.factor
core/cpu/x86/32/32.factor
core/cpu/x86/assembler/assembler.factor
core/debugger/debugger.factor
core/definitions/definitions-tests.factor
core/dlists/dlists-tests.factor
core/dlists/dlists.factor
core/effects/effects.factor
core/float-arrays/float-arrays.factor
core/float-vectors/float-vectors.factor
core/float-vectors/summary.txt [new file with mode: 0644]
core/float-vectors/tags.txt [new file with mode: 0644]
core/generator/fixup/fixup.factor
core/generator/generator.factor
core/generator/registers/registers.factor
core/generic/generic.factor
core/generic/math/math.factor
core/generic/standard/engines/predicate/predicate.factor
core/generic/standard/engines/tuple/tuple.factor
core/generic/standard/standard-tests.factor
core/generic/standard/standard.factor
core/graphs/graphs-docs.factor
core/hashtables/hashtables-docs.factor
core/hashtables/hashtables-tests.factor
core/hashtables/hashtables.factor
core/heaps/heaps.factor
core/heaps/tags.txt [new file with mode: 0644]
core/inference/backend/backend-docs.factor
core/inference/backend/backend.factor
core/inference/dataflow/dataflow.factor
core/inference/inference-docs.factor
core/inference/known-words/known-words.factor
core/inference/transforms/transforms-tests.factor
core/inference/transforms/transforms.factor
core/inspector/inspector.factor
core/io/encodings/encodings.factor
core/io/encodings/utf8/utf8.factor
core/io/files/files-docs.factor
core/io/files/files.factor
core/io/streams/duplex/duplex-docs.factor
core/io/streams/duplex/duplex-tests.factor
core/io/streams/duplex/duplex.factor
core/io/streams/nested/nested.factor
core/kernel/kernel.factor
core/math/intervals/intervals.factor
core/math/math.factor
core/math/parser/parser.factor
core/mirrors/mirrors.factor
core/optimizer/backend/backend.factor
core/optimizer/control/control-tests.factor
core/optimizer/control/control.factor
core/optimizer/inlining/inlining.factor
core/optimizer/known-words/known-words.factor
core/optimizer/optimizer-tests.factor
core/optimizer/pattern-match/pattern-match.factor
core/optimizer/specializers/specializers.factor
core/parser/parser-docs.factor
core/parser/parser.factor
core/prettyprint/prettyprint-docs.factor
core/prettyprint/prettyprint.factor
core/prettyprint/sections/sections-docs.factor
core/prettyprint/sections/sections.factor
core/sbufs/sbufs-tests.factor
core/sbufs/sbufs.factor
core/sequences/sequences-docs.factor
core/sequences/sequences-tests.factor
core/sequences/sequences.factor
core/sets/authors.txt [new file with mode: 0644]
core/sets/sets-docs.factor [new file with mode: 0644]
core/sets/sets-tests.factor [new file with mode: 0644]
core/sets/sets.factor [new file with mode: 0644]
core/sets/summary.txt [new file with mode: 0644]
core/sets/tags.txt [new file with mode: 0644]
core/source-files/source-files.factor
core/splitting/splitting.factor
core/strings/strings-tests.factor
core/strings/strings.factor
core/syntax/syntax-docs.factor
core/syntax/syntax.factor
core/system/system-docs.factor
core/system/system-tests.factor
core/threads/threads.factor
core/vectors/vectors-tests.factor
core/vectors/vectors.factor
core/vocabs/loader/loader-tests.factor
core/vocabs/vocabs.factor
core/words/words-docs.factor
core/words/words.factor
extra/alarms/alarms.factor
extra/arrays/lib/summary.txt [new file with mode: 0644]
extra/arrays/lib/tags.txt [new file with mode: 0644]
extra/asn1/asn1.factor
extra/benchmark/dispatch1/dispatch1.factor
extra/benchmark/dispatch5/dispatch5.factor
extra/benchmark/typecheck1/typecheck1.factor
extra/benchmark/typecheck2/typecheck2.factor
extra/benchmark/typecheck3/typecheck3.factor
extra/benchmark/typecheck4/typecheck4.factor
extra/bitfields/bitfields.factor
extra/bootstrap/random/random.factor
extra/bubble-chamber/bubble-chamber-docs.factor [new file with mode: 0644]
extra/bubble-chamber/bubble-chamber.factor [new file with mode: 0644]
extra/bubble-chamber/common/common.factor [new file with mode: 0644]
extra/bubble-chamber/particle/axion/axion.factor [new file with mode: 0644]
extra/bubble-chamber/particle/hadron/hadron.factor [new file with mode: 0644]
extra/bubble-chamber/particle/muon/colors/colors.factor [new file with mode: 0644]
extra/bubble-chamber/particle/muon/muon.factor [new file with mode: 0644]
extra/bubble-chamber/particle/particle.factor [new file with mode: 0644]
extra/bubble-chamber/particle/quark/quark.factor [new file with mode: 0644]
extra/builder/build/build.factor [new file with mode: 0644]
extra/builder/builder.factor
extra/builder/child/child.factor [new file with mode: 0644]
extra/builder/cleanup/cleanup.factor [new file with mode: 0644]
extra/builder/common/common.factor
extra/builder/email/email.factor [new file with mode: 0644]
extra/builder/release/archive/archive.factor [new file with mode: 0644]
extra/builder/release/branch/branch.factor [new file with mode: 0644]
extra/builder/release/release.factor
extra/builder/release/tidy/tidy.factor [new file with mode: 0644]
extra/builder/release/upload/upload.factor [new file with mode: 0644]
extra/builder/report/report.factor [new file with mode: 0644]
extra/builder/test/test.factor
extra/builder/updates/updates.factor [new file with mode: 0644]
extra/builder/util/util.factor
extra/bunny/model/model.factor
extra/cairo/png/png.factor
extra/calendar/windows/tags.txt [new file with mode: 0644]
extra/calendar/windows/windows.factor
extra/channels/channels.factor
extra/circular/circular.factor
extra/classes/tuple/lib/lib-docs.factor
extra/classes/tuple/lib/lib-tests.factor
extra/cocoa/application/application.factor
extra/cocoa/messages/messages.factor
extra/combinators/lib/lib.factor
extra/concurrency/combinators/combinators-tests.factor
extra/concurrency/count-downs/count-downs.factor
extra/concurrency/exchangers/exchangers.factor
extra/concurrency/flags/flags.factor
extra/concurrency/locks/locks.factor
extra/concurrency/mailboxes/mailboxes-docs.factor
extra/concurrency/mailboxes/mailboxes-tests.factor
extra/concurrency/mailboxes/mailboxes.factor
extra/concurrency/messaging/messaging-docs.factor
extra/concurrency/messaging/messaging-tests.factor
extra/concurrency/messaging/messaging.factor
extra/concurrency/promises/promises.factor
extra/concurrency/semaphores/semaphores.factor
extra/contributors/contributors.factor
extra/core-foundation/core-foundation.factor
extra/core-foundation/fsevents/fsevents.factor
extra/core-foundation/run-loop/run-loop.factor [new file with mode: 0644]
extra/coroutines/coroutines.factor
extra/cpu/8080/emulator/emulator.factor
extra/crypto/test/blum-blum-shub.factor [deleted file]
extra/db/db.factor
extra/db/mysql/lib/lib.factor
extra/db/mysql/mysql.factor
extra/db/postgresql/ffi/ffi.factor
extra/db/sql/sql-tests.factor
extra/db/sql/sql.factor
extra/db/sqlite/lib/lib.factor
extra/db/tuples/tuples.factor
extra/delegate/delegate.factor
extra/delegate/protocols/protocols.factor
extra/destructors/destructors-tests.factor
extra/destructors/destructors.factor
extra/digraphs/digraphs.factor
extra/digraphs/tags.txt [new file with mode: 0644]
extra/disjoint-set/authors.txt [new file with mode: 0644]
extra/disjoint-set/disjoint-set.factor [new file with mode: 0644]
extra/disjoint-set/summary.txt [new file with mode: 0644]
extra/disjoint-set/tags.txt [new file with mode: 0644]
extra/documents/documents.factor
extra/editors/editors.factor
extra/farkup/farkup.factor
extra/fry/fry.factor
extra/gap-buffer/cursortree/cursortree.factor
extra/gap-buffer/gap-buffer.factor
extra/gap-buffer/tags.txt
extra/hardware-info/hardware-info.factor
extra/hardware-info/windows/tags.txt [new file with mode: 0644]
extra/help/cookbook/cookbook.factor
extra/help/handbook/handbook.factor
extra/help/help.factor
extra/help/lint/lint.factor
extra/help/markup/markup.factor
extra/help/topics/topics.factor
extra/html/html-tests.factor
extra/html/html.factor
extra/html/parser/printer/printer.factor
extra/http/http-tests.factor
extra/http/http.factor
extra/http/server/actions/actions.factor
extra/http/server/auth/login/login.factor
extra/http/server/auth/providers/assoc/assoc-tests.factor
extra/http/server/auth/providers/assoc/assoc.factor
extra/http/server/auth/providers/db/db-tests.factor
extra/http/server/auth/providers/providers.factor
extra/http/server/callbacks/callbacks.factor
extra/http/server/components/components-tests.factor
extra/http/server/components/components.factor
extra/http/server/components/farkup/farkup.factor
extra/http/server/crud/crud.factor
extra/http/server/db/db.factor
extra/http/server/forms/forms.factor [new file with mode: 0644]
extra/http/server/server.factor
extra/http/server/sessions/sessions.factor
extra/http/server/sessions/storage/assoc/assoc.factor
extra/http/server/sessions/storage/db/db.factor
extra/http/server/static/static.factor
extra/http/server/templating/fhtml/fhtml.factor
extra/http/server/validators/validators.factor
extra/inverse/inverse-tests.factor
extra/inverse/inverse.factor
extra/io/buffers/buffers.factor
extra/io/encodings/8-bit/8-bit-docs.factor
extra/io/encodings/8-bit/8-bit.factor
extra/io/encodings/strict/strict.factor
extra/io/launcher/launcher-docs.factor
extra/io/launcher/launcher.factor
extra/io/mmap/mmap-tests.factor
extra/io/monitors/monitors-docs.factor
extra/io/monitors/monitors-tests.factor [new file with mode: 0644]
extra/io/monitors/monitors.factor
extra/io/monitors/recursive/recursive-tests.factor [new file with mode: 0644]
extra/io/monitors/recursive/recursive.factor [new file with mode: 0644]
extra/io/nonblocking/nonblocking-docs.factor
extra/io/nonblocking/nonblocking.factor
extra/io/paths/paths.factor
extra/io/server/server.factor
extra/io/sockets/impl/impl.factor
extra/io/sockets/sockets-docs.factor
extra/io/sockets/sockets.factor
extra/io/timeouts/timeouts-docs.factor
extra/io/unix/backend/backend.factor [changed mode: 0755->0644]
extra/io/unix/bsd/bsd.factor
extra/io/unix/epoll/epoll.factor
extra/io/unix/files/files.factor
extra/io/unix/kqueue/kqueue.factor [changed mode: 0755->0644]
extra/io/unix/launcher/launcher.factor
extra/io/unix/linux/linux.factor
extra/io/unix/linux/monitors/monitors.factor [new file with mode: 0644]
extra/io/unix/macosx/macosx.factor
extra/io/unix/mmap/mmap.factor
extra/io/unix/select/select.factor
extra/io/unix/sockets/sockets.factor
extra/io/unix/unix-tests.factor
extra/io/windows/files/files.factor
extra/io/windows/launcher/launcher.factor
extra/io/windows/mmap/mmap.factor
extra/io/windows/nt/backend/backend.factor
extra/io/windows/nt/files/files.factor
extra/io/windows/nt/launcher/launcher.factor
extra/io/windows/nt/monitors/monitors-tests.factor [new file with mode: 0755]
extra/io/windows/nt/monitors/monitors.factor
extra/io/windows/nt/pipes/pipes.factor
extra/io/windows/nt/sockets/sockets.factor
extra/io/windows/tags.txt [new file with mode: 0644]
extra/io/windows/windows.factor
extra/irc/irc.factor
extra/jamshred/game/game.factor
extra/jamshred/oint/oint.factor
extra/jamshred/player/player.factor
extra/jamshred/tunnel/tunnel.factor
extra/koszul/koszul.factor
extra/lazy-lists/lazy-lists.factor
extra/lint/authors.txt [deleted file]
extra/lint/lint-tests.factor [deleted file]
extra/lint/lint.factor [deleted file]
extra/lint/summary.txt [deleted file]
extra/locals/locals.factor
extra/logging/parser/parser.factor
extra/logging/server/server.factor
extra/macros/summary.txt
extra/match/match.factor
extra/math/erato/erato.factor
extra/math/functions/functions.factor
extra/math/miller-rabin/miller-rabin.factor
extra/math/primes/primes.factor
extra/math/ranges/ranges.factor
extra/models/models-tests.factor
extra/models/models.factor
extra/morse/tags.txt [new file with mode: 0644]
extra/multi-methods/multi-methods-tests.factor [deleted file]
extra/multi-methods/multi-methods.factor
extra/multi-methods/tests/canonicalize.factor [new file with mode: 0644]
extra/multi-methods/tests/definitions.factor [new file with mode: 0644]
extra/multi-methods/tests/legacy.factor [new file with mode: 0644]
extra/multi-methods/tests/syntax.factor [new file with mode: 0644]
extra/multi-methods/tests/topological-sort.factor [new file with mode: 0644]
extra/newfx/newfx.factor
extra/odbc/odbc.factor
extra/ogg/player/player.factor
extra/opengl/capabilities/capabilities.factor
extra/opengl/gl/extensions/extensions.factor
extra/opengl/gl/windows/tags.txt [new file with mode: 0644]
extra/opengl/opengl.factor
extra/optimizer/debugger/debugger.factor
extra/oracle/oracle.factor
extra/parser-combinators/parser-combinators.factor
extra/peg/ebnf/ebnf-tests.factor
extra/peg/ebnf/ebnf.factor
extra/peg/parsers/parsers.factor
extra/peg/peg.factor
extra/porter-stemmer/porter-stemmer.factor
extra/processing/gadget/gadget.factor
extra/processing/gallery/bubble-chamber/bubble-chamber-docs.factor [deleted file]
extra/processing/gallery/bubble-chamber/bubble-chamber.factor [deleted file]
extra/processing/processing.factor
extra/project-euler/004/004.factor
extra/project-euler/023/023.factor
extra/project-euler/029/029.factor
extra/project-euler/032/032.factor
extra/project-euler/035/035.factor
extra/project-euler/043/043.factor
extra/project-euler/059/059.factor
extra/project-euler/079/079.factor
extra/project-euler/169/169.factor
extra/project-euler/175/175.factor
extra/project-euler/186/186.factor [new file with mode: 0644]
extra/project-euler/authors.txt
extra/promises/promises.factor
extra/qualified/qualified-docs.factor
extra/qualified/qualified-tests.factor
extra/qualified/qualified.factor
extra/random-tester/authors.txt [deleted file]
extra/random-tester/databank/authors.txt [deleted file]
extra/random-tester/databank/databank.factor [deleted file]
extra/random-tester/random-tester.factor [deleted file]
extra/random-tester/random/authors.txt [deleted file]
extra/random-tester/random/random.factor [deleted file]
extra/random-tester/safe-words/authors.txt [deleted file]
extra/random-tester/safe-words/safe-words.factor [deleted file]
extra/random-tester/utils/authors.txt [deleted file]
extra/random-tester/utils/utils.factor [deleted file]
extra/random/blum-blum-shub/blum-blum-shub-tests.factor [new file with mode: 0644]
extra/random/blum-blum-shub/blum-blum-shub.factor
extra/random/mersenne-twister/mersenne-twister.factor
extra/random/random.factor
extra/random/unix/unix.factor
extra/random/windows/tags.txt [new file with mode: 0644]
extra/random/windows/windows.factor
extra/regexp/regexp.factor
extra/reports/noise/noise.factor
extra/roman/roman.factor
extra/rot13/rot13.factor
extra/semantic-db/semantic-db.factor
extra/sequences/lib/lib.factor
extra/sequences/lib/summary.txt [new file with mode: 0644]
extra/sequences/next/next.factor
extra/sequences/next/summary.txt [new file with mode: 0644]
extra/serialize/serialize.factor
extra/smtp/server/server.factor
extra/smtp/smtp.factor
extra/space-invaders/space-invaders.factor
extra/state-machine/state-machine.factor
extra/state-parser/state-parser.factor
extra/sudoku/sudoku.factor
extra/tar/tar.factor
extra/taxes/tags.txt [new file with mode: 0644]
extra/taxes/taxes.factor
extra/tetris/board/board.factor
extra/tools/completion/completion.factor
extra/tools/deploy/backend/backend.factor
extra/tools/deploy/config/config.factor
extra/tools/deploy/deploy-tests.factor
extra/tools/deploy/shaker/shaker.factor
extra/tools/deploy/shaker/strip-cocoa.factor
extra/tools/deploy/windows/tags.txt
extra/tools/threads/threads.factor
extra/tools/vocabs/browser/browser.factor
extra/tools/vocabs/monitor/monitor-tests.factor [new file with mode: 0644]
extra/tools/vocabs/monitor/monitor.factor
extra/tools/vocabs/vocabs-tests.factor [new file with mode: 0644]
extra/tools/vocabs/vocabs.factor
extra/tools/walker/walker.factor
extra/trees/avl/avl.factor
extra/trees/avl/tags.txt [new file with mode: 0644]
extra/trees/splay/splay.factor
extra/trees/splay/summary.txt
extra/trees/trees.factor
extra/tuple-arrays/tuple-arrays.factor
extra/tuple-syntax/tuple-syntax.factor
extra/turtle/turtle.factor
extra/ui/clipboards/clipboards.factor
extra/ui/cocoa/views/views.factor
extra/ui/commands/commands.factor
extra/ui/gadgets/borders/borders.factor
extra/ui/gadgets/buttons/buttons.factor
extra/ui/gadgets/frames/frames.factor
extra/ui/gadgets/gadgets-tests.factor
extra/ui/gadgets/gadgets.factor
extra/ui/gadgets/labelled/labelled.factor
extra/ui/gadgets/panes/panes.factor
extra/ui/gadgets/presentations/presentations.factor
extra/ui/gadgets/scrollers/scrollers.factor
extra/ui/gadgets/slots/slots.factor
extra/ui/gestures/gestures.factor
extra/ui/operations/operations-tests.factor
extra/ui/operations/operations.factor
extra/ui/render/render.factor
extra/ui/tools/browser/browser.factor
extra/ui/tools/debugger/debugger.factor
extra/ui/tools/deploy/deploy.factor
extra/ui/tools/inspector/inspector.factor
extra/ui/tools/interactor/interactor-tests.factor
extra/ui/tools/interactor/interactor.factor
extra/ui/tools/listener/listener.factor
extra/ui/tools/profiler/profiler.factor
extra/ui/tools/search/search.factor
extra/ui/tools/tools-docs.factor
extra/ui/tools/tools.factor
extra/ui/tools/traceback/traceback.factor
extra/ui/tools/walker/walker.factor
extra/ui/traverse/traverse.factor
extra/ui/ui.factor
extra/ui/windows/windows.factor
extra/ui/x11/x11.factor
extra/unicode/breaks/breaks.factor
extra/unicode/case/case.factor
extra/unicode/data/data.factor
extra/unicode/normalize/normalize.factor
extra/units/units.factor
extra/unix/stat/stat.factor
extra/windows/advapi32/advapi32.factor
extra/windows/messages/messages.factor
extra/windows/tags.txt
extra/x11/clipboard/clipboard.factor
extra/x11/events/events.factor
extra/xml-rpc/xml-rpc.factor
extra/xml/data/data.factor
extra/xml/tests/test.factor
extra/xml/tokenize/tokenize.factor
extra/xml/utilities/utilities.factor
extra/xml/writer/writer.factor
extra/xmode/catalog/catalog.factor
extra/xmode/keyword-map/keyword-map.factor
extra/xmode/loader/loader.factor
extra/xmode/rules/rules.factor
extra/xmode/utilities/utilities-tests.factor
unmaintained/lint/authors.txt [new file with mode: 0644]
unmaintained/lint/lint-tests.factor [new file with mode: 0644]
unmaintained/lint/lint.factor [new file with mode: 0644]
unmaintained/lint/summary.txt [new file with mode: 0755]
unmaintained/random-tester/authors.txt [new file with mode: 0755]
unmaintained/random-tester/databank/authors.txt [new file with mode: 0755]
unmaintained/random-tester/databank/databank.factor [new file with mode: 0644]
unmaintained/random-tester/random-tester.factor [new file with mode: 0755]
unmaintained/random-tester/random/authors.txt [new file with mode: 0755]
unmaintained/random-tester/random/random.factor [new file with mode: 0755]
unmaintained/random-tester/safe-words/authors.txt [new file with mode: 0755]
unmaintained/random-tester/safe-words/safe-words.factor [new file with mode: 0755]
unmaintained/random-tester/utils/authors.txt [new file with mode: 0755]
unmaintained/random-tester/utils/utils.factor [new file with mode: 0644]
vm/Config.unix
vm/data_gc.h
vm/os-linux-ppc.h
vm/os-macosx.h
vm/os-unix-ucontext.h [deleted file]
vm/os-unix.c
vm/os-windows.c
vm/platform.h
vm/primitives.c
vm/run.c
vm/run.h
vm/types.c

index 12dade5ba1427c172d9d8cb7abd9831310693943..dd7c3e7ad3dbd1b375cbb26caeca236a21ff74eb 100755 (executable)
@@ -6,7 +6,6 @@ implementation. It is not an introduction to the language itself.
 
 * Contents
 
-- Platform support
 - Compiling the Factor VM
 - Libraries needed for compilation
 - Bootstrapping the Factor image
@@ -19,80 +18,50 @@ implementation. It is not an introduction to the language itself.
 - Source organization
 - Community
 
-* Platform support
-
-Factor supports the following platforms:
-
-  Linux/x86
-  Linux/AMD64
-  Linux/PowerPC
-  Linux/ARM
-  Mac OS X/x86
-  Mac OS X/PowerPC
-  FreeBSD/x86
-  FreeBSD/AMD64
-  OpenBSD/x86
-  OpenBSD/AMD64
-  Solaris/x86
-  Solaris/AMD64
-  MS Windows/x86 (XP and above)
-  MS Windows CE/ARM
-
-Please donate time or hardware if you wish to see Factor running on
-other platforms. In particular, we are interested in:
-
-  Windows/AMD64
-  Mac OS X/AMD64
-  Solaris/UltraSPARC
-  Linux/MIPS
-
 * Compiling the Factor VM
 
 The Factor runtime is written in GNU C99, and is built with GNU make and
 gcc.
 
-Factor requires gcc 3.4 or later. On x86, it /will not/ build using gcc
-3.3 or earlier. If you are using gcc 4.3, you might get an unusable
-Factor binary unless you add 'SITE_CFLAGS=-fno-forward-propagate' to the
-command-line arguments for make.
+Factor supports various platforms. For an up-to-date list, see
+<http://factorcode.org/getfactor.fhtml>.
+
+Factor requires gcc 3.4 or later.
+
+On x86, Factor /will not/ build using gcc 3.3 or earlier.
+
+If you are using gcc 4.3, you might get an unusable Factor binary unless
+you add 'SITE_CFLAGS=-fno-forward-propagate' to the command-line
+arguments for make.
 
-Run 'make' (or 'gmake' on *BSD) with no parameters to see a list of
-targets and build options. Then run 'make' with the appropriate target
-for your platform.
+Run 'make' ('gmake' on *BSD) with no parameters to build the Factor VM.
 
 Compilation will yield an executable named 'factor' on Unix,
-'factor-nt.exe' on Windows XP/Vista, and 'factor-ce.exe' on Windows CE.
+'factor.exe' on Windows XP/Vista, and 'factor-ce.exe' on Windows CE.
 
 * Libraries needed for compilation
 
-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
+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
 
-sudo apt-get install libc6-dev libfreetype6-dev libx11-dev glutg3-dev
+    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 :)
+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
 
-The boot images are no longer included with the Factor distribution
-due to size concerns. Instead, download a boot image from:
-
-  http://factorcode.org/images/
-
 Once you have compiled the Factor runtime, you must bootstrap the Factor
 system using the image that corresponds to your CPU architecture.
 
-Once you download the right image, bootstrap the system with the
+Boot images can be obtained from <http://factorcode.org/images/latest/>.
+
+Once you download the right image, bootstrap Factor with the
 following command line:
 
 ./factor -i=boot.<cpu>.image
 
-Or this command for Mac OS X systems:
-
-./Factor.app/Contents/MacOS/factor -i=boot.<cpu>.image
-
 Bootstrap can take a while, depending on your system. When the process
 completes, a 'factor.image' file will be generated. Note that this image
 is both CPU and OS-specific, so in general cannot be shared between
@@ -122,9 +91,8 @@ The latter keeps the terminal listener running.
 
 * Running Factor on Mac OS X - Cocoa UI
 
-On Mac OS X 10.4 and later, a Cocoa UI is available in addition to the
-terminal listener. If you are using Mac OS X 10.3, you can only run the
-X11 UI, as documented in the next section.
+On Mac OS X, a Cocoa UI is available in addition to the terminal
+listener.
 
 The 'factor' executable runs the terminal listener:
 
@@ -136,17 +104,16 @@ contains factor.image and the library sources.
 
 * Running Factor on Mac OS X - X11 UI
 
-The X11 UI is available on Mac OS X, however its use is not recommended
-since it does not integrate with the host OS. However, if you are
-running Mac OS X 10.3, it is your only choice.
+The X11 UI is also available on Mac OS X, however its use is not
+recommended since it does not integrate with the host OS.
 
 When compiling Factor, pass the X11=1 parameter:
 
-  make macosx-ppc X11=1
+  make X11=1
 
 Then bootstrap with the following switches:
 
-  ./factor -i=boot.ppc.image -ui-backend=x11
+  ./factor -i=boot.<cpu>.image -ui-backend=x11
 
 Now if $DISPLAY is set, running ./factor will start the UI.
 
@@ -155,40 +122,36 @@ Now if $DISPLAY is set, running ./factor will start the UI.
 If you did not download the binary package, you can bootstrap Factor in
 the command prompt:
 
-  factor-nt.exe -i=boot.x86.32.image
+  factor.exe -i=boot.<cpu>.image
 
 Once bootstrapped, double-clicking factor.exe starts the Factor UI.
 
 To run the listener in the command prompt:
 
-  factor-nt.exe -run=listener
+  factor.exe -run=listener
 
 * The Factor FAQ
 
-The Factor FAQ lives online at http://factorcode.org/faq.fhtml
+The Factor FAQ is available at <http://factorcode.org/faq.fhtml>.
 
 * Command line usage
 
-The Factor VM supports a number of command line switches. To read
-command line usage documentation, either enter the following in the UI
-listener:
+Factor supports a number of command line switches. To read command line
+usage documentation, enter the following in the UI listener:
 
   "command-line" about
 
 * Source organization
 
-The following two directories are managed by the module system; consult
-the documentation for details:
+The Factor source tree is organized as follows:
 
+  build-support/ - scripts used for compiling Factor
   core/ - Factor core library and compiler
   extra/ - more libraries
-
-The following directories contain additional files:
-
-  misc/ - editor modes, icons, etc
-  vm/ - sources for the Factor runtime, written in C
   fonts/ - TrueType fonts used by UI
+  misc/ - editor modes, icons, etc
   unmaintained/ - unmaintained contributions, please help!
+  vm/ - sources for the Factor VM, written in C
 
 * Community
 
index ea0c35aa83f32203e59284e6e074cc55d1d408db..4bcd9e3086222d8957db3e25eeaa1815dc82a2f6 100755 (executable)
@@ -89,6 +89,11 @@ set_md5sum() {
 set_gcc() {
     case $OS in
         openbsd) ensure_program_installed egcc; CC=egcc;;
+       netbsd) if [[ $WORD -eq 64 ]] ; then
+                       CC=/usr/pkg/gcc34/bin/gcc
+               else
+                       CC=gcc
+               fi ;;
         *) CC=gcc;;
     esac
 }
@@ -185,6 +190,7 @@ find_architecture() {
        i386) ARCH=x86;;
        i686) ARCH=x86;;
        amd64) ARCH=x86;;
+       ppc64) ARCH=ppc;;
        *86) ARCH=x86;;
        *86_64) ARCH=x86;;
        "Power Macintosh") ARCH=ppc;;
index 136af91bb2f00d0ad1de5696f4cf84e55715afa2..7d13080e3c046deb72ae93a5af04eeecd0b3c05d 100755 (executable)
@@ -78,7 +78,7 @@ $nl
     "<< \"freetype\" {"
     "    { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
     "    { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
-    "    { [ t ] [ drop ] }"
+    "    [ drop ]"
     "} cond >>"
 }
 "Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
index 2f82e5db9844b2547567dde140015cc478feaf50..f664e1175a0ceed8dea1f2ca5ddf1647ed28ad8c 100755 (executable)
@@ -54,7 +54,7 @@ TUPLE: library path abi dll ;
 : library ( name -- library ) libraries get at ;
 
 : <library> ( path abi -- library )
-    over dup [ dlopen ] when \ library construct-boa ;
+    over dup [ dlopen ] when \ library boa ;
 
 : load-library ( name -- dll )
     library dup [ library-dll ] when ;
index 508fcd61a61d0960ad2ac846c25b0ee9300178d2..c97c76069572e13d4a22ba25b9c1e440605eadb1 100755 (executable)
@@ -18,12 +18,12 @@ boxer prep unboxer
 getter setter
 reg-class size align stack-align? ;
 
-: construct-c-type ( class -- type )
-    construct-empty
+: new-c-type ( class -- type )
+    new
         int-regs >>reg-class ;
 
 : <c-type> ( -- type )
-    \ c-type construct-c-type ;
+    \ c-type new-c-type ;
 
 SYMBOL: c-types
 
@@ -189,7 +189,7 @@ DEFER: >c-ushort-array
 TUPLE: long-long-type < c-type ;
 
 : <long-long-type> ( -- type )
-    long-long-type construct-c-type ;
+    long-long-type new-c-type ;
 
 M: long-long-type unbox-parameter ( n type -- )
     c-type-unboxer %unbox-long-long ;
index 0f74f52d60dd787b4ce41e53298900fdbdbe7f38..b6fcbe6176182aefa5764597b72f2ddb1f08e485 100755 (executable)
@@ -220,7 +220,7 @@ M: no-such-library compiler-error-type
     drop +linkage+ ;
 
 : no-such-library ( name -- )
-    \ no-such-library construct-boa
+    \ no-such-library boa
     compiling-word get compiler-error ;
 
 TUPLE: no-such-symbol name ;
@@ -232,7 +232,7 @@ M: no-such-symbol compiler-error-type
     drop +linkage+ ;
 
 : no-such-symbol ( name -- )
-    \ no-such-symbol construct-boa
+    \ no-such-symbol boa
     compiling-word get compiler-error ;
 
 : check-dlsym ( symbols dll -- )
@@ -251,7 +251,7 @@ M: no-such-symbol compiler-error-type
 \ alien-invoke [
     ! Four literals
     4 ensure-values
-    #alien-invoke construct-empty
+    #alien-invoke new
     ! Compile-time parameters
     pop-parameters >>parameters
     pop-literal nip >>function
@@ -288,7 +288,7 @@ M: alien-indirect-error summary
     ! Three literals and function pointer
     4 ensure-values
     4 reify-curries
-    #alien-indirect construct-empty
+    #alien-indirect new
     ! Compile-time parameters
     pop-literal nip >>abi
     pop-parameters >>parameters
@@ -335,7 +335,7 @@ M: alien-callback-error summary
 
 \ alien-callback [
     4 ensure-values
-    #alien-callback construct-empty dup node,
+    #alien-callback new dup node,
     pop-literal nip >>quot
     pop-literal nip >>abi
     pop-parameters >>parameters
@@ -375,13 +375,13 @@ TUPLE: callback-context ;
     return>> {
         { [ dup "void" = ] [ drop [ ] ] }
         { [ dup large-struct? ] [ heap-size [ memcpy ] curry ] }
-        { [ t ] [ c-type c-type-prep ] }
+        [ c-type c-type-prep ]
     } cond ;
 
 : wrap-callback-quot ( node -- quot )
     [
         [ quot>> ] [ prepare-callback-return ] bi append ,
-        [ callback-context construct-empty do-callback ] %
+        [ callback-context new do-callback ] %
     ] [ ] make ;
 
 : %unnest-stacks ( -- ) "unnest_stacks" f %alien-invoke ;
@@ -390,7 +390,7 @@ TUPLE: callback-context ;
     {
         { [ dup abi>> "stdcall" = ] [ alien-stack-frame ] }
         { [ dup return>> large-struct? ] [ drop 4 ] }
-        { [ t ] [ drop 0 ] }
+        [ drop 0 ]
     } cond ;
 
 : %callback-return ( node -- )
index 491f4351a34df69716a712424b843204cbf8c848..6d98d317908436fd309eae7d64227bb1b4612f3b 100755 (executable)
@@ -68,7 +68,7 @@ M: struct-type stack-size
 
 : (define-struct) ( name vocab size align fields -- )
     >r [ align ] keep r>
-    struct-type construct-boa
+    struct-type boa
     -rot define-c-type ;
 
 : make-field ( struct-name vocab type field-name -- spec )
index 6e4b8b4e21d8bef988fddfb6778f937a37d6edd9..67ea30f379f9ee330609df42517a9663cb55eaf5 100755 (executable)
@@ -68,7 +68,7 @@ M: alien pprint*
     {
         { [ dup expired? ] [ drop "( alien expired )" text ] }
         { [ dup pinned-c-ptr? not ] [ drop "( displaced alien )" text ] }
-        { [ t ] [ \ ALIEN: [ alien-address pprint* ] pprint-prefix ] }
+        [ \ ALIEN: [ alien-address pprint* ] pprint-prefix ]
     } cond ;
 
 M: dll pprint* dll-path dup "DLL\" " "\"" pprint-string ;
index 414c64581e14cb29a0c28ffd1620b391cd8ee762..9c5f40d88327f3d2fc4d1686cfca22e207a45694 100755 (executable)
@@ -12,9 +12,9 @@ M: array resize resize-array ;
 
 : >array ( seq -- array ) { } clone-like ;
 
-M: object new drop f <array> ;
+M: object new-sequence drop f <array> ;
 
-M: f new drop dup zero? [ drop f ] [ f <array> ] if ;
+M: f new-sequence drop dup zero? [ drop f ] [ f <array> ] if ;
 
 M: array like drop dup array? [ >array ] unless ;
 
index e85789a4f272557cc39b108cbac87c2e24859b51..863fdaecb3cbbb56fc6d7a19bb013322bcf6c06b 100755 (executable)
@@ -69,14 +69,14 @@ ARTICLE: "assocs-lookup" "Lookup and querying of assocs"
 ARTICLE: "assocs-sets" "Set-theoretic operations on assocs"
 "It is often useful to use the keys of an associative mapping as a set, exploiting the constant or logarithmic lookup time of most implementations (" { $link "alists" } " being a notable exception)."
 { $subsection subassoc? }
-{ $subsection intersect }
+{ $subsection assoc-intersect }
 { $subsection update }
-{ $subsection union }
-{ $subsection diff }
+{ $subsection assoc-union }
+{ $subsection assoc-diff }
 { $subsection remove-all }
 { $subsection substitute }
 { $subsection substitute-here }
-{ $see-also key? } ;
+{ $see-also key? assoc-contains? assoc-all? "sets" } ;
 
 ARTICLE: "assocs-mutation" "Storing keys and values in assocs"
 "Utility operations built up from the " { $link "assocs-protocol" } ":"
@@ -97,6 +97,7 @@ $nl
 { $subsection assoc-map }
 { $subsection assoc-push-if }
 { $subsection assoc-subset }
+{ $subsection assoc-contains? }
 { $subsection assoc-all? }
 "Three additional combinators:"
 { $subsection cache }
@@ -206,9 +207,13 @@ HELP: assoc-subset
 { $values { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "subassoc" "a new assoc" } }
 { $description "Outputs an assoc of the same type as " { $snippet "assoc" } " consisting of all entries for which the predicate quotation yields true." } ;
 
+HELP: assoc-contains?
+{ $values { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "?" "a boolean" } }
+{ $description "Tests if the assoc contains an entry satisfying a predicate by applying the quotation to each entry in turn. Iteration stops if an entry is found for which the quotation outputs a true value." } ;
+
 HELP: assoc-all?
 { $values { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "?" "a boolean" } }
-{ $description "Applies a predicate quotation to entry in the assoc. Outputs true if the assoc yields true for each entry (which includes the case where the assoc is empty)." } ;
+{ $description "Tests if all entries in the assoc satisfy a predicate by applying the quotation to each entry in turn. a predicate quotation to entry in the assoc. Iteration stops if an entry is found for which the quotation outputs " { $link f } ". If the assoc is empty, always outputs " { $link t } "." } ;
 
 HELP: subassoc?
 { $values { "assoc1" assoc } { "assoc2" assoc } { "?" "a new assoc" } }
@@ -260,7 +265,7 @@ HELP: values
 
 { keys values } related-words
 
-HELP: intersect
+HELP: assoc-intersect
 { $values { "assoc1" assoc } { "assoc2" assoc } { "intersection" "a new assoc" } }
 { $description "Outputs an assoc consisting of all entries from " { $snippet "assoc2" } " such that the key is also present in " { $snippet "assoc1" } "." }
 { $notes "The values of the keys in " { $snippet "assoc1" } " are disregarded, so this word is usually used for set-theoretic calculations where the assoc in question either has dummy sentinels as values, or the values equal the keys." } ;
@@ -270,11 +275,11 @@ HELP: update
 { $description "Adds all entries from " { $snippet "assoc2" } " to " { $snippet "assoc1" } "." }
 { $side-effects "assoc1" } ;
 
-HELP: union
+HELP: assoc-union
 { $values { "assoc1" assoc } { "assoc2" assoc } { "union" "a new assoc" } }
 { $description "Outputs a assoc consisting of all entries from " { $snippet "assoc1" } " and " { $snippet "assoc2" } ", with entries from " { $snippet "assoc2" } " taking precedence in case the corresponding values are not equal." } ;
 
-HELP: diff
+HELP: assoc-diff
 { $values { "assoc1" assoc } { "assoc2" assoc } { "diff" "a new assoc" } }
 { $description "Outputs an assoc consisting of all entries from " { $snippet "assoc2" } " whose key is not contained in " { $snippet "assoc1" } "." } 
 ;
index c4db6047840c3365ab59eab3cb032c5c4f7d3d5a..76f484006dd313a67dbf00f0a5f045728f2eba3a 100755 (executable)
@@ -58,24 +58,24 @@ H{ } clone "cache-test" set
 ] [
     H{ { "factor" "rocks" } { "dup" "sq" } { 3 4 } }
     H{ { "factor" "rocks" } { 1 2 } { 2 3 } { 3 4 } }
-    intersect
+    assoc-intersect
 ] unit-test
 
 [
     H{ { 1 2 } { 2 3 } { 6 5 } }
 ] [
     H{ { 2 4 } { 6 5 } } H{ { 1 2 } { 2 3 } }
-    union
+    assoc-union
 ] unit-test
 
 [ H{ { 1 2 } { 2 3 } } t ] [
-    f H{ { 1 2 } { 2 3 } } [ union ] 2keep swap union dupd =
+    f H{ { 1 2 } { 2 3 } } [ assoc-union ] 2keep swap assoc-union dupd =
 ] unit-test
 
 [
     H{ { 1 f } }
 ] [
-    H{ { 1 f } } H{ { 1 f } } intersect
+    H{ { 1 f } } H{ { 1 f } } assoc-intersect
 ] unit-test
 
 [ { 1 3 } ] [ H{ { 2 2 } } { 1 2 3 } remove-all ] unit-test
index adb69d317c40d4cff0a1b52907bb965352a48448..4a6ecae4fe38f3aeb1a9bee95a1792ab088a0aca 100755 (executable)
@@ -109,17 +109,17 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
         >r over r> hashcode* 2/ >r dupd hashcode* r> bitxor
     ] { } assoc>map hashcode* ;
 
-: intersect ( assoc1 assoc2 -- intersection )
+: assoc-intersect ( assoc1 assoc2 -- intersection )
     swap [ nip key? ] curry assoc-subset ;
 
 : update ( assoc1 assoc2 -- )
     swap [ swapd set-at ] curry assoc-each ;
 
-: union ( assoc1 assoc2 -- union )
+: assoc-union ( assoc1 assoc2 -- union )
     2dup [ assoc-size ] bi@ + pick new-assoc
     [ rot update ] keep [ swap update ] keep ;
 
-: diff ( assoc1 assoc2 -- diff )
+: assoc-diff ( assoc1 assoc2 -- diff )
     swap [ nip key? not ] curry assoc-subset ;
 
 : remove-all ( assoc seq -- subseq )
index ee485d399ee65bba65bde6eef6fab4a0e1efe77a..ffb9f5d195d5d9b637a497b51aa51ab5c8136fa1 100755 (executable)
@@ -43,7 +43,7 @@ M: bit-array clone (clone) ;
 
 M: bit-array like drop dup bit-array? [ >bit-array ] unless ;
 
-M: bit-array new drop <bit-array> ;
+M: bit-array new-sequence drop <bit-array> ;
 
 M: bit-array equal?
     over bit-array? [ sequence= ] [ 2drop f ] if ;
index c418a24813ab773467234e56698e91d1cbf8a3d9..db941ac6f747a4d6182dbdffb4811c556f1ef9bb 100755 (executable)
@@ -7,7 +7,7 @@ IN: bit-vectors
 <PRIVATE\r
 \r
 : bit-array>vector ( bit-array length -- bit-vector )\r
-    bit-vector construct-boa ; inline\r
+    bit-vector boa ; inline\r
 \r
 PRIVATE>\r
 \r
@@ -22,7 +22,7 @@ M: bit-vector like
         [ dup length bit-array>vector ] [ >bit-vector ] if\r
     ] unless ;\r
 \r
-M: bit-vector new\r
+M: bit-vector new-sequence\r
     drop [ <bit-array> ] keep >fixnum bit-array>vector ;\r
 \r
 M: bit-vector equal?\r
diff --git a/core/bit-vectors/summary.txt b/core/bit-vectors/summary.txt
new file mode 100644 (file)
index 0000000..76a7d0f
--- /dev/null
@@ -0,0 +1 @@
+Growable bit arrays
diff --git a/core/bit-vectors/tags.txt b/core/bit-vectors/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 9e101126e6683ab4996d2d0efe84d4ed7eba843d..da3c634ebdb3a99a53d36f575c74d8cddd2efe68 100755 (executable)
@@ -53,7 +53,7 @@ nl
 "." write flush
 
 {
-    new nth push pop peek
+    new-sequence nth push pop peek
 } compile
 
 "." write flush
index ceb011d52b79925b753fd8a53de951964d27d0a8..e839576bc9cf5b8cef14875a054dd1003ff82ffb 100755 (executable)
@@ -36,4 +36,4 @@ tag-numbers get H{
     { word 17 }
     { byte-array 18 }
     { tuple-layout 19 }
-} union type-numbers set
+} assoc-union type-numbers set
index 233de6f4eee9d77fedc784168dfefa49e0c54d29..f1e41ac2b60e7a12d1563ce8487a2b4f7021ac05 100755 (executable)
@@ -390,7 +390,7 @@ define-builtin
 
 ! Create special tombstone values
 "tombstone" "hashtables.private" create
-"tuple" "kernel" lookup
+tuple
 { } define-tuple-class
 
 "((empty))" "hashtables.private" create
@@ -403,7 +403,7 @@ define-builtin
 
 ! Some tuple classes
 "hashtable" "hashtables" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "array-capacity" "sequences.private" }
@@ -424,7 +424,7 @@ define-builtin
 } define-tuple-class
 
 "sbuf" "sbufs" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "string" "strings" }
@@ -440,7 +440,7 @@ define-builtin
 } define-tuple-class
 
 "vector" "vectors" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "array" "arrays" }
@@ -456,7 +456,7 @@ define-builtin
 } define-tuple-class
 
 "byte-vector" "byte-vectors" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "byte-array" "byte-arrays" }
@@ -472,7 +472,7 @@ define-builtin
 } define-tuple-class
 
 "bit-vector" "bit-vectors" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "bit-array" "bit-arrays" }
@@ -488,7 +488,7 @@ define-builtin
 } define-tuple-class
 
 "float-vector" "float-vectors" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "float-array" "float-arrays" }
@@ -504,7 +504,7 @@ define-builtin
 } define-tuple-class
 
 "curry" "kernel" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "object" "kernel" }
@@ -525,7 +525,7 @@ define-builtin
 [ tuple-layout [ <tuple-boa> ] curry ] tri define
 
 "compose" "kernel" create
-"tuple" "kernel" lookup
+tuple
 {
     {
         { "object" "kernel" }
@@ -732,6 +732,8 @@ define-builtin
     { "set-innermost-frame-quot" "kernel.private" }
     { "call-clear" "kernel" }
     { "(os-envs)" "system.private" }
+    { "set-os-env" "system" }
+    { "unset-os-env" "system" }
     { "(set-os-envs)" "system.private" }
     { "resize-byte-array" "byte-arrays" }
     { "resize-bit-array" "bit-arrays" }
index a75b111e78a944394bb3931bdef6b7306717305a..ca90587ea9113cdb789ddb03c0faba9fc411ec14 100755 (executable)
@@ -5,7 +5,7 @@ kernel.private math memory continuations kernel io.files
 io.backend system parser vocabs sequences prettyprint
 vocabs.loader combinators splitting source-files strings
 definitions assocs compiler.errors compiler.units
-math.parser generic ;
+math.parser generic sets ;
 IN: bootstrap.stage2
 
 SYMBOL: bootstrap-time
@@ -24,7 +24,7 @@ SYMBOL: bootstrap-time
 : load-components ( -- )
     "exclude" "include"
     [ get-global " " split [ empty? not ] subset ] bi@
-    seq-diff
+    diff
     [ "bootstrap." prepend require ] each ;
 
 ! : compile-remaining ( -- )
index a989e091bbbff8effc7328a3d37ca2d94a073473..b56a46b6b3a626ed80d1b60b3cc1ad37d0c89970 100755 (executable)
@@ -5,7 +5,7 @@ IN: boxes
 \r
 TUPLE: box value full? ;\r
 \r
-: <box> ( -- box ) box construct-empty ;\r
+: <box> ( -- box ) box new ;\r
 \r
 : >box ( value box -- )\r
     dup box-full? [ "Box already has a value" throw ] when\r
index 548c293e7ce08d6aacb0a0b8b330f502c6730018..d6034708102abf55812b929702621822f7e42615 100755 (executable)
@@ -10,7 +10,7 @@ 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 drop <byte-array> ;
+M: byte-array new-sequence drop <byte-array> ;
 
 M: byte-array equal?
     over byte-array? [ sequence= ] [ 2drop f ] if ;
index 6a08f657a2d0d857e2195b0840ca70526cdbcf7f..206a23f43bf789ce69a4a604d90d97ba8fb12504 100755 (executable)
@@ -7,7 +7,7 @@ IN: byte-vectors
 <PRIVATE\r
 \r
 : byte-array>vector ( byte-array length -- byte-vector )\r
-    byte-vector construct-boa ; inline\r
+    byte-vector boa ; inline\r
 \r
 PRIVATE>\r
 \r
@@ -22,7 +22,7 @@ M: byte-vector like
         [ dup length byte-array>vector ] [ >byte-vector ] if\r
     ] unless ;\r
 \r
-M: byte-vector new\r
+M: byte-vector new-sequence\r
     drop [ <byte-array> ] keep >fixnum byte-array>vector ;\r
 \r
 M: byte-vector equal?\r
diff --git a/core/byte-vectors/summary.txt b/core/byte-vectors/summary.txt
new file mode 100644 (file)
index 0000000..e914ebb
--- /dev/null
@@ -0,0 +1 @@
+Growable byte arrays
diff --git a/core/byte-vectors/tags.txt b/core/byte-vectors/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 4614e4c4ce31050ec8c53e506c887f02a86a0d9a..b7a3e074e594d231aa85e7b502c7263f3d4cd7d4 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: kernel classes classes.builtin combinators accessors\r
 sequences arrays vectors assocs namespaces words sorting layouts\r
-math hashtables kernel.private ;\r
+math hashtables kernel.private sets ;\r
 IN: classes.algebra\r
 \r
 : 2cache ( key1 key2 assoc quot -- value )\r
@@ -84,7 +84,7 @@ C: <anonymous-complement> anonymous-complement
         { [ dup anonymous-complement? ] [ class>> classes-intersect? not ] }\r
         { [ dup members ] [ right-union-class< ] }\r
         { [ over superclass ] [ superclass< ] }\r
-        { [ t ] [ 2drop f ] }\r
+        [ 2drop f ]\r
     } cond ;\r
 \r
 : anonymous-union-intersect? ( first second -- ? )\r
@@ -104,14 +104,14 @@ C: <anonymous-complement> anonymous-complement
         { [ over tuple eq? ] [ 2drop t ] }\r
         { [ over builtin-class? ] [ 2drop f ] }\r
         { [ over tuple-class? ] [ [ class< ] [ swap class< ] 2bi or ] }\r
-        { [ t ] [ swap classes-intersect? ] }\r
+        [ swap classes-intersect? ]\r
     } cond ;\r
 \r
 : builtin-class-intersect? ( first second -- ? )\r
     {\r
         { [ 2dup eq? ] [ 2drop t ] }\r
         { [ over builtin-class? ] [ 2drop f ] }\r
-        { [ t ] [ swap classes-intersect? ] }\r
+        [ swap classes-intersect? ]\r
     } cond ;\r
 \r
 : (classes-intersect?) ( first second -- ? )\r
@@ -154,7 +154,7 @@ C: <anonymous-complement> anonymous-complement
         { [ over members ] [ left-union-and ] }\r
         { [ over anonymous-union? ] [ left-anonymous-union-and ] }\r
         { [ over anonymous-intersection? ] [ left-anonymous-intersection-and ] }\r
-        { [ t ] [ 2array <anonymous-intersection> ] }\r
+        [ 2array <anonymous-intersection> ]\r
     } cond ;\r
 \r
 : left-anonymous-union-or ( first second -- class )\r
@@ -169,7 +169,7 @@ C: <anonymous-complement> anonymous-complement
         { [ 2dup swap class< ] [ drop ] }\r
         { [ dup anonymous-union? ] [ right-anonymous-union-or ] }\r
         { [ over anonymous-union? ] [ left-anonymous-union-or ] }\r
-        { [ t ] [ 2array <anonymous-union> ] }\r
+        [ 2array <anonymous-union> ]\r
     } cond ;\r
 \r
 : (class-not) ( class -- complement )\r
@@ -177,7 +177,7 @@ C: <anonymous-complement> anonymous-complement
         { [ dup anonymous-complement? ] [ class>> ] }\r
         { [ dup object eq? ] [ drop null ] }\r
         { [ dup null eq? ] [ drop object ] }\r
-        { [ t ] [ <anonymous-complement> ] }\r
+        [ <anonymous-complement> ]\r
     } cond ;\r
 \r
 : largest-class ( seq -- n elt )\r
@@ -205,7 +205,7 @@ C: <anonymous-complement> anonymous-complement
         { [ dup builtin-class? ] [ dup set ] }\r
         { [ dup members ] [ members [ (flatten-class) ] each ] }\r
         { [ dup superclass ] [ superclass (flatten-class) ] }\r
-        { [ t ] [ drop ] }\r
+        [ drop ]\r
     } cond ;\r
 \r
 : flatten-class ( class -- assoc )\r
index b22e21eb9288ec5571b93ce293abbc46dcddcb04..4f43b86f641c7cfd83bb537d083f859e38c52ad7 100755 (executable)
@@ -89,7 +89,7 @@ M: word reset-class drop ;
     dup reset-class
     dup deferred? [ dup define-symbol ] when
     dup word-props
-    r> union over set-word-props
+    r> assoc-union over set-word-props
     dup predicate-word
     [ 1quotation "predicate" set-word-prop ]
     [ swap "predicating" set-word-prop ]
index aefd522269320c064a5b815312d241e194011c8d..33b0fc32fab1443cf88f2763dcfe77734765bc1c 100755 (executable)
@@ -24,7 +24,7 @@ TUPLE: check-mixin-class mixin ;
 
 : check-mixin-class ( mixin -- mixin )
     dup mixin-class? [
-        \ check-mixin-class construct-boa throw
+        \ check-mixin-class boa throw
     ] unless ;
 
 : if-mixin-member? ( class mixin true false -- )
@@ -49,7 +49,7 @@ M: mixin-instance equal?
         { [ over mixin-instance? not ] [ f ] }
         { [ 2dup [ mixin-instance-class ] bi@ = not ] [ f ] }
         { [ 2dup [ mixin-instance-mixin ] bi@ = not ] [ f ] }
-        { [ t ] [ t ] }
+        [ t ]
     } cond 2nip ;
 
 M: mixin-instance hashcode*
index 5d35afb7d3bc82ade46f71e1b9ba62c799483cfa..cdfdee97178db44e8cd102ab2ebe5ddab8114c45 100755 (executable)
@@ -4,7 +4,7 @@ generic.standard sequences definitions compiler.units ;
 IN: classes.tuple
 
 ARTICLE: "parametrized-constructors" "Parameterized constructors"
-"A " { $emphasis "parametrized constructor" } " is a word which directly or indirectly calls " { $link construct-empty } " or " { $link construct-boa } ", but instead of passing a literal class symbol, it takes the class symbol as an input from the stack."
+"A " { $emphasis "parametrized constructor" } " is a word which directly or indirectly calls " { $link new } " or " { $link boa } ", but instead of passing a literal class symbol, it takes the class symbol as an input from the stack."
 $nl
 "Parametrized constructors are useful in many situations, in particular with subclassing. For example, consider the following code:"
 { $code
@@ -14,14 +14,14 @@ $nl
     ""
     "TUPLE: car < vehicle engine ;"
     ": <car> ( max-speed engine -- car )"
-    "    car construct-empty"
+    "    car new"
     "        V{ } clone >>occupants"
     "        swap >>engine"
     "        swap >>max-speed ;"
     ""
     "TUPLE: aeroplane < vehicle max-altitude ;"
     ": <aeroplane> ( max-speed max-altitude -- aeroplane )"
-    "    aeroplane construct-empty"
+    "    aeroplane new"
     "        V{ } clone >>occupants"
     "        swap >>max-altitude"
     "        swap >>max-speed ;"
@@ -32,28 +32,28 @@ $nl
     ""
     ": add-occupant ( person vehicle -- ) occupants>> push ;"
     ""
-    ": construct-vehicle ( class -- vehicle )"
-    "    construct-empty"
+    ": new-vehicle ( class -- vehicle )"
+    "    new"
     "        V{ } clone >>occupants ;"
     ""
     "TUPLE: car < vehicle engine ;"
     ": <car> ( max-speed engine -- car )"
-    "    car construct-vehicle"
+    "    car new-vehicle"
     "        swap >>engine"
     "        swap >>max-speed ;"
     ""
     "TUPLE: aeroplane < vehicle max-altitude ;"
     ": <aeroplane> ( max-speed max-altitude -- aeroplane )"
-    "    aeroplane construct-vehicle"
+    "    aeroplane new-vehicle"
     "        swap >>max-altitude"
     "        swap >>max-speed ;"
 }
-"The naming convention for parametrized constructors is " { $snippet "construct-" { $emphasis "class" } } "." ;
+"The naming convention for parametrized constructors is " { $snippet "new-" { $emphasis "class" } } "." ;
 
 ARTICLE: "tuple-constructors" "Tuple constructors"
 "Tuples are created by calling one of two constructor primitives:"
-{ $subsection construct-empty }
-{ $subsection construct-boa }
+{ $subsection new }
+{ $subsection boa }
 "A shortcut for defining BOA 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>" } "."
@@ -64,13 +64,16 @@ $nl
 { $code
     "TUPLE: color red green blue alpha ;"
     ""
+    "! The following two are equivalent"
     "C: <rgba> rgba"
-    ": <rgba> color construct-boa ; ! identical to above"
+    ": <rgba> color boa ;"
     ""
+    "! We can define constructors which call other constructors"
     ": <rgb> f <rgba> ;"
     ""
-    ": <color> construct-empty ;"
-    ": <color> f f f f <rgba> ; ! identical to above"
+    "! The following two are equivalent"
+    ": <color> color new ;"
+    ": <color> f f f f <rgba> ;"
 }
 { $subsection "parametrized-constructors" } ;
 
@@ -129,7 +132,7 @@ $nl
 $nl
 "The second is to use ad-hoc slot polymorphism. If two classes define a slot with the same name, then code which uses " { $link "accessors" } " can operate on instances of both objects, assuming the values stored in that slot implement a common protocol. This allows code to be shared without creating contrieved relationships between classes."
 { $heading "Anti-pattern #3: subclassing to override a method definition" }
-"While method overriding is a very powerful tool, improper use can cause tight coupling of code and lead to difficulty in testing and refactoring. Subclassing should not be used as a means of ``monkey patching'' methods to fix bugs and add features. Only subclass from classes which were designed to be inherited from, and when writing classes of your own which are intended to be subclassed, clearly document that subclasses may and may not do. This includes construction policy; document whether subclasses should use " { $link construct-empty } ", " { $link construct-boa } ", or a custom parametrized constructor."
+"While method overriding is a very powerful tool, improper use can cause tight coupling of code and lead to difficulty in testing and refactoring. Subclassing should not be used as a means of ``monkey patching'' methods to fix bugs and add features. Only subclass from classes which were designed to be inherited from, and when writing classes of your own which are intended to be subclassed, clearly document that subclasses may and may not do. This includes construction policy; document whether subclasses should use " { $link new } ", " { $link boa } ", or a custom parametrized constructor."
 { $see-also "parametrized-constructors" } ;
 
 ARTICLE: "tuple-subclassing" "Tuple subclassing"
@@ -164,11 +167,11 @@ ARTICLE: "tuple-examples" "Tuple examples"
 }
 "We can define a constructor which makes an empty employee:"
 { $code ": <employee> ( -- employee )"
-    "    employee construct-empty ;" }
+    "    employee new ;" }
 "Or we may wish the default constructor to always give employees a starting salary:"
 { $code
     ": <employee> ( -- employee )"
-    "    employee construct-empty"
+    "    employee new"
     "        40000 >>salary ;"
 }
 "We can define more refined constructors:"
@@ -178,7 +181,7 @@ ARTICLE: "tuple-examples" "Tuple examples"
 "An alternative strategy is to define the most general BOA constructor first:"
 { $code
     ": <employee> ( name position -- person )"
-    "    40000 employee construct-boa ;"
+    "    40000 employee boa ;"
 }
 "Now we can define more specific constructors:"
 { $code
@@ -191,7 +194,7 @@ ARTICLE: "tuple-examples" "Tuple examples"
     "SYMBOL: checks"
     ""
     ": <check> ( to amount -- check )"
-    "    checks counter check construct-boa ;"
+    "    checks counter check boa ;"
     ""
     ": biweekly-paycheck ( employee -- check )"
     "    dup name>> swap salary>> 26 / <check> ;"
@@ -326,20 +329,20 @@ HELP: tuple>array ( tuple -- array )
 
 HELP: <tuple> ( layout -- tuple )
 { $values { "layout" tuple-layout } { "tuple" tuple } }
-{ $description "Low-level tuple constructor. User code should never call this directly, and instead use " { $link construct-empty } "." } ;
+{ $description "Low-level tuple constructor. User code should never call this directly, and instead use " { $link new } "." } ;
 
 HELP: <tuple-boa> ( ... layout -- tuple )
 { $values { "..." "values" } { "layout" tuple-layout } { "tuple" tuple } }
-{ $description "Low-level tuple constructor. User code should never call this directly, and instead use " { $link construct-boa } "." } ;
+{ $description "Low-level tuple constructor. User code should never call this directly, and instead use " { $link boa } "." } ;
 
-HELP: construct-empty
+HELP: new
 { $values { "class" tuple-class } { "tuple" tuple } }
 { $description "Creates a new instance of " { $snippet "class" } " with all slots initially set to " { $link f } "." }
 { $examples
     { $example
         "USING: kernel prettyprint ;"
         "TUPLE: employee number name department ;"
-        "employee construct-empty ."
+        "employee new ."
         "T{ employee f f f f }"
     }
 } ;
@@ -361,12 +364,12 @@ HELP: construct
         "    color construct ;"
     }
     "The last definition is actually equivalent to the following:"
-    { $code ": <rgba> ( r g b a -- color ) rgba construct-boa ;" }
+    { $code ": <rgba> ( r g b a -- color ) rgba boa ;" }
     "Which can be abbreviated further:"
     { $code "C: <rgba> color" }
 } ;
 
-HELP: construct-boa
+HELP: boa
 { $values { "..." "slot values" } { "class" tuple-class } { "tuple" tuple } }
 { $description "Creates a new instance of " { $snippet "class" } " and fill in the slots from the stack, with the top-most stack element being stored in the right-most slot." }
-{ $notes "The " { $snippet "-boa" } " suffix is shorthand for ``by order of arguments'', and ``BOA constructor'' is a pun on ``boa constrictor''." } ;
+{ $notes "The name " { $snippet "boa" } " is shorthand for ``by order of arguments'', and ``BOA constructor'' is a pun on ``boa constrictor''." } ;
index 2575570d2f2dfb11e18f438dfc3b6d1d3798dda6..ce6fd9367c0384535a2dc6ece2f4be658ed9acbf 100755 (executable)
@@ -7,7 +7,7 @@ calendar prettyprint io.streams.string splitting inspector ;
 IN: classes.tuple.tests
 
 TUPLE: rect x y w h ;
-: <rect> rect construct-boa ;
+: <rect> rect boa ;
 
 : move ( x rect -- rect )
     [ + ] change-x ;
@@ -198,8 +198,8 @@ SYMBOL: not-a-tuple-class
 ] unit-test
 
 ! Missing check
-[ not-a-tuple-class construct-boa ] must-fail
-[ not-a-tuple-class construct-empty ] must-fail
+[ not-a-tuple-class boa ] must-fail
+[ not-a-tuple-class new ] must-fail
 
 TUPLE: erg's-reshape-problem a b c d ;
 
@@ -207,8 +207,8 @@ C: <erg's-reshape-problem> erg's-reshape-problem
 
 ! We want to make sure constructors are recompiled when
 ! tuples are reshaped
-: cons-test-1 \ erg's-reshape-problem construct-empty ;
-: cons-test-2 \ erg's-reshape-problem construct-boa ;
+: cons-test-1 \ erg's-reshape-problem new ;
+: cons-test-2 \ erg's-reshape-problem boa ;
 
 "IN: classes.tuple.tests TUPLE: erg's-reshape-problem a b c d e f ;" eval
 
@@ -538,3 +538,6 @@ TUPLE: another-forget-accessors-test ;
         ] with-string-writer empty?
     ] with-variable
 ] unit-test
+
+! Missing error check
+[ "IN: tuples.test USE: words TUPLE: wrong-superclass < word ;" eval ] must-fail
index aa8ef6cdb7051ef6cee63012278dee56f2a58e6f..c14205e1d998f4c6e133b9aa532dca7b4064857f 100755 (executable)
@@ -58,6 +58,8 @@ PRIVATE>
 : all-slot-names ( class -- slots )
     superclasses [ slot-names ] map concat \ class prefix ;
 
+ERROR: bad-superclass class ;
+
 <PRIVATE
 
 : tuple= ( tuple1 tuple2 -- ? )
@@ -185,21 +187,28 @@ M: tuple-class update-class
 : tuple-class-unchanged? ( class superclass slots -- ? )
     rot tuck [ superclass = ] [ slot-names = ] 2bi* and ;
 
+: valid-superclass? ( class -- ? )
+    [ tuple-class? ] [ tuple eq? ] bi or ;
+
+: check-superclass ( superclass -- )
+    dup valid-superclass? [ bad-superclass ] unless drop ;
+
 PRIVATE>
 
 GENERIC# define-tuple-class 2 ( class superclass slots -- )
 
 M: word define-tuple-class
+    over check-superclass
     define-new-tuple-class ;
 
 M: tuple-class define-tuple-class
     3dup tuple-class-unchanged?
-    [ 3dup redefine-tuple-class ] unless
+    [ over check-superclass 3dup redefine-tuple-class ] unless
     3drop ;
 
 : define-error-class ( class superclass slots -- )
     [ define-tuple-class ] [ 2drop ] 3bi
-    dup [ construct-boa throw ] curry define ;
+    dup [ boa throw ] curry define ;
 
 M: tuple-class reset-class
     [
index f497fd20e52812fa1b6b4472a24159c109bb3db5..54c62c44fa83f16579d7657806c4e3ad6edd2530 100755 (executable)
@@ -64,9 +64,9 @@ HELP: alist>quot
 { $notes "This word is used to implement compile-time behavior for " { $link cond } ", and it is also used by the generic word system. Note that unlike " { $link cond } ", the constructed quotation performs the tests starting from the end and not the beginning." } ;
 
 HELP: cond
-{ $values { "assoc" "a sequence of quotation pairs" } }
+{ $values { "assoc" "a sequence of quotation pairs and an optional quotation" } }
 { $description
-    "Calls the second quotation in the first pair whose first quotation yields a true value."
+    "Calls the second quotation in the first pair whose first quotation yields a true value. A single quotation will always yield a true value."
     $nl
     "The following two phrases are equivalent:"
     { $code "{ { [ X ] [ Y ] } { [ Z ] [ T ] } } cond" }
@@ -78,7 +78,7 @@ HELP: cond
         "{"
         "    { [ dup 0 > ] [ \"positive\" ] }"
         "    { [ dup 0 < ] [ \"negative\" ] }"
-        "    { [ dup zero? ] [ \"zero\" ] }"
+        "    [ \"zero\" ]"
         "} cond"
     }
 } ;
@@ -88,9 +88,9 @@ HELP: no-cond
 { $error-description "Thrown by " { $link cond } " if none of the test quotations yield a true value. Some uses of " { $link cond } " include a default case where the test quotation is " { $snippet "[ t ]" } "; such a " { $link cond } " form will never throw this error." } ;
 
 HELP: case
-{ $values { "obj" object } { "assoc" "a sequence of object/quotation pairs, with an optional quotation at the end" } }
+{ $values { "obj" object } { "assoc" "a sequence of object/word,quotation pairs, with an optional quotation at the end" } }
 { $description
-    "Compares " { $snippet "obj" } " against the first element of every pair. If some pair matches, removes " { $snippet "obj" } " from the stack and calls the second element of that pair, which must be a quotation."
+    "Compares " { $snippet "obj" } " against the first element of every pair, first evaluating the first element if it is a word. If some pair matches, removes " { $snippet "obj" } " from the stack and calls the second element of that pair, which must be a quotation."
     $nl
     "If there is no case matching " { $snippet "obj" } ", the default case is taken. If the last element of " { $snippet "cases" } " is a quotation, the quotation is called with " { $snippet "obj" } " on the stack. Otherwise, a " { $link no-cond } " error is rasied."
     $nl
index 8abc53e43fc850f1441ca89372cbb58dcad68942..b612669b717dbb3cffd52b35b17bbf8726d28d8f 100755 (executable)
@@ -1,7 +1,54 @@
-IN: combinators.tests
 USING: alien strings kernel math tools.test io prettyprint
-namespaces combinators words ;
+namespaces combinators words classes sequences ;
+IN: combinators.tests
+
+! Compiled
+: cond-test-1 ( obj -- str )
+    {
+        { [ dup 2 mod 0 = ] [ drop "even" ] }
+        { [ dup 2 mod 1 = ] [ drop "odd" ] }
+    } cond ;
+
+\ cond-test-1 must-infer
+
+[ "even" ] [ 2 cond-test-1 ] unit-test
+[ "odd" ] [ 3 cond-test-1 ] unit-test
+
+: cond-test-2 ( obj -- str )
+    {
+        { [ dup t = ] [ drop "true" ] }
+        { [ dup f = ] [ drop "false" ] }
+        [ drop "something else" ]
+    } cond ;
+
+\ cond-test-2 must-infer
+
+[ "true" ] [ t cond-test-2 ] unit-test
+[ "false" ] [ f cond-test-2 ] unit-test
+[ "something else" ] [ "ohio" cond-test-2 ] unit-test
+
+: cond-test-3 ( obj -- str )
+    {
+        [ drop "something else" ]
+        { [ dup t = ] [ drop "true" ] }
+        { [ dup f = ] [ drop "false" ] }
+    } cond ;
+
+\ cond-test-3 must-infer
+
+[ "something else" ] [ t cond-test-3 ] unit-test
+[ "something else" ] [ f cond-test-3 ] unit-test
+[ "something else" ] [ "ohio" cond-test-3 ] unit-test
+
+: cond-test-4 ( -- )
+    {
+    } cond ;
+
+\ cond-test-4 must-infer
+
+[ cond-test-4 ] [ class \ no-cond = ] must-fail-with
 
+! Interpreted
 [ "even" ] [
     2 {
         { [ dup 2 mod 0 = ] [ drop "even" ] }
@@ -21,11 +68,66 @@ namespaces combinators words ;
         { [ dup string? ] [ drop "string" ] }
         { [ dup float? ] [ drop "float" ] }
         { [ dup alien? ] [ drop "alien" ] }
-        { [ t ] [ drop "neither" ] }
+        [ drop "neither" ]
+    } cond
+] unit-test
+
+[ "neither" ] [
+    3 {
+        { [ dup string? ] [ drop "string" ] }
+        { [ dup float? ] [ drop "float" ] }
+        { [ dup alien? ] [ drop "alien" ] }
+        [ drop "neither" ]
+    } cond
+] unit-test
+
+[ "neither" ] [
+    3 {
+        { [ dup string? ] [ drop "string" ] }
+        { [ dup float? ] [ drop "float" ] }
+        { [ dup alien? ] [ drop "alien" ] }
+        [ drop "neither" ]
+    } cond
+] unit-test
+
+[ "early" ] [
+    2 {
+        { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        [ drop "early" ]
+        { [ dup 2 mod 0 = ] [ drop "even" ] }
     } cond
 ] unit-test
 
-: case-test-1
+[ "really early" ] [
+    2 {
+       [ drop "really early" ]
+        { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        { [ dup 2 mod 0 = ] [ drop "even" ] }
+    } cond
+] unit-test
+
+[ { } cond ] [ class \ no-cond = ] must-fail-with
+[ "early" ] [
+    2 {
+        { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        [ drop "early" ]
+        { [ dup 2 mod 0 = ] [ drop "even" ] }
+    } cond
+] unit-test
+
+[ "really early" ] [
+    2 {
+        [ drop "really early" ]
+        { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        { [ dup 2 mod 0 = ] [ drop "even" ] }
+    } cond
+] unit-test
+
+[ { } cond ] [ class \ no-cond = ] must-fail-with
+
+! Compiled
+: case-test-1 ( obj -- obj' )
     {
         { 1 [ "one" ] }
         { 2 [ "two" ] }
@@ -33,6 +135,8 @@ namespaces combinators words ;
         { 4 [ "four" ] }
     } case ;
 
+\ case-test-1 must-infer
+
 [ "two" ] [ 2 case-test-1 ] unit-test
 
 ! Interpreted
@@ -40,7 +144,7 @@ namespaces combinators words ;
 
 [ "x" case-test-1 ] must-fail
 
-: case-test-2
+: case-test-2 ( obj -- obj' )
     {
         { 1 [ "one" ] }
         { 2 [ "two" ] }
@@ -49,12 +153,14 @@ namespaces combinators words ;
         [ sq ]
     } case ;
 
+\ case-test-2 must-infer
+
 [ 25 ] [ 5 case-test-2 ] unit-test
 
 ! Interpreted
 [ 25 ] [ 5 \ case-test-2 word-def call ] unit-test
 
-: case-test-3
+: case-test-3 ( obj -- obj' )
     {
         { 1 [ "one" ] }
         { 2 [ "two" ] }
@@ -65,8 +171,122 @@ namespaces combinators words ;
         [ sq ]
     } case ;
 
+\ case-test-3 must-infer
+
 [ "an array" ] [ { 1 2 3 } case-test-3 ] unit-test
 
+: case-const-1 1 ;
+: case-const-2 2 ; inline
+
+! Compiled
+: case-test-4 ( obj -- str )
+    {
+        { case-const-1 [ "uno" ] }
+        { case-const-2 [ "dos" ] }
+        { 3 [ "tres" ] } 
+        { 4 [ "cuatro" ] } 
+        { 5 [ "cinco" ] } 
+        [ drop "demasiado" ]
+    } case ;
+
+\ case-test-4 must-infer
+
+[ "uno" ] [ 1 case-test-4 ] unit-test
+[ "dos" ] [ 2 case-test-4 ] unit-test
+[ "tres" ] [ 3 case-test-4 ] unit-test
+[ "demasiado" ] [ 100 case-test-4 ] unit-test
+
+: case-test-5 ( obj -- )
+    {
+        { case-const-1 [ "uno" print ] }
+        { case-const-2 [ "dos" print ] }
+        { 3 [ "tres" print ] } 
+        { 4 [ "cuatro" print ] } 
+        { 5 [ "cinco" print ] } 
+        [ drop "demasiado" print ]
+    } case ;
+
+\ case-test-5 must-infer
+
+[ ] [ 1 case-test-5 ] unit-test
+
+! Interpreted
+[ "uno" ] [
+    1 {
+        { case-const-1 [ "uno" ] }
+        { case-const-2 [ "dos" ] }
+        { 3 [ "tres" ] } 
+        { 4 [ "cuatro" ] } 
+        { 5 [ "cinco" ] } 
+        [ drop "demasiado" ]
+    } case
+] unit-test
+
+[ "dos" ] [
+    2 {
+        { case-const-1 [ "uno" ] }
+        { case-const-2 [ "dos" ] }
+        { 3 [ "tres" ] } 
+        { 4 [ "cuatro" ] } 
+        { 5 [ "cinco" ] } 
+        [ drop "demasiado" ]
+    } case
+] unit-test
+
+[ "tres" ] [
+    3 {
+        { case-const-1 [ "uno" ] }
+        { case-const-2 [ "dos" ] }
+        { 3 [ "tres" ] } 
+        { 4 [ "cuatro" ] } 
+        { 5 [ "cinco" ] } 
+        [ drop "demasiado" ]
+    } case
+] unit-test
+
+[ "demasiado" ] [
+    100 {
+        { case-const-1 [ "uno" ] }
+        { case-const-2 [ "dos" ] }
+        { 3 [ "tres" ] } 
+        { 4 [ "cuatro" ] } 
+        { 5 [ "cinco" ] } 
+        [ drop "demasiado" ]
+    } case
+] unit-test
+
+: do-not-call "do not call" throw ;
+
+: test-case-6
+    {
+        { \ do-not-call [ "do-not-call" ] }
+        { 3 [ "three" ] }
+    } case ;
+
+[ "three" ] [ 3 test-case-6 ] unit-test
+[ "do-not-call" ] [ \ do-not-call test-case-6 ] unit-test
+
+[ "three" ] [
+    3 {
+        { \ do-not-call [ "do-not-call" ] }
+        { 3 [ "three" ] }
+    } case
+] unit-test
+
+[ "do-not-call" ] [
+    [ do-not-call ] first {
+        { \ do-not-call [ "do-not-call" ] }
+        { 3 [ "three" ] }
+    } case
+] unit-test
+
+[ "do-not-call" ] [
+    \ do-not-call {
+        { \ do-not-call [ "do-not-call" ] }
+        { 3 [ "three" ] }
+    } case
+] unit-test
+
 ! Interpreted
 [ "a hashtable" ] [ H{ } \ case-test-3 word-def call ] unit-test
 
index 96c4009ba9f0c1de2db9cfb753396caf7bd66cc4..e3d0f8868052ff98d490a13c79145357d4f620c2 100755 (executable)
@@ -3,7 +3,7 @@
 IN: combinators
 USING: arrays sequences sequences.private math.private
 kernel kernel.private math assocs quotations vectors
-hashtables sorting ;
+hashtables sorting words sets ;
 
 : cleave ( x seq -- )
     [ call ] with each ;
@@ -34,13 +34,24 @@ hashtables sorting ;
 ERROR: no-cond ;
 
 : cond ( assoc -- )
-    [ first call ] find nip dup [ second call ] [ no-cond ] if ;
+    [ dup callable? [ drop t ] [ first call ] if ] find nip
+    [ dup callable? [ call ] [ second call ] if ]
+    [ no-cond ] if* ;
 
 ERROR: no-case ;
+: case-find ( obj assoc -- obj' )
+    [
+        dup array? [
+            dupd first dup word? [
+                execute
+            ] [
+                dup wrapper? [ wrapped ] when
+            ] if =
+        ] [ quotation? ] if
+    ] find nip ;
 
 : case ( obj assoc -- )
-    [ dup array? [ dupd first = ] [ quotation? ] if ] find nip
-    {
+    case-find {
         { [ dup array? ] [ nip second call ] }
         { [ dup quotation? ] [ call ] }
         { [ dup not ] [ no-case ] }
@@ -73,11 +84,14 @@ M: hashtable hashcode*
     [ rot \ if 3array append [ ] like ] assoc-each ;
 
 : cond>quot ( assoc -- quot )
+    [ dup callable? [ [ t ] swap 2array ] when ] map
     reverse [ no-cond ] swap alist>quot ;
 
 : linear-case-quot ( default assoc -- quot )
-    [ >r [ dupd = ] curry r> \ drop prefix ] assoc-map
-    alist>quot ;
+    [
+        [ 1quotation \ dup prefix \ = suffix ]
+        [ \ drop prefix ] bi*
+    ] assoc-map alist>quot ;
 
 : (distribute-buckets) ( buckets pair keys -- )
     dup t eq? [
@@ -135,7 +149,9 @@ M: hashtable hashcode*
     dup empty? [
         drop
     ] [
-        dup length 4 <= [
+        dup length 4 <=
+        over keys [ word? ] contains? or
+        [
             linear-case-quot
         ] [
             dup keys contiguous-range? [
index e41d316792a628b085b660921d49f1fb8d1605da..88ea43be205e75814bf37a1d6fff9cf1de29c107 100644 (file)
@@ -7,9 +7,10 @@ ARTICLE: "runtime-cli-args" "Command line switches for the VM"
     { { $snippet "-i=" { $emphasis "image" } } { "Specifies the image file to use; see " { $link "images" } } }
     { { $snippet "-datastack=" { $emphasis "n" } } "Data stack size, kilobytes" }
     { { $snippet "-retainstack=" { $emphasis "n" } } "Retain stack size, kilobytes" }
-    { { $snippet "-generations=" { $emphasis "n" } } "Number of generations, must be >= 2" }
-    { { $snippet "-young=" { $emphasis "n" } } { "Size of " { $snippet { $emphasis "n" } "-1" } " youngest generations, megabytes" } }
-    { { $snippet "-aging=" { $emphasis "n" } } "Size of tenured and semi-spaces, megabytes" }
+    { { $snippet "-generations=" { $emphasis "n" } } "Number of generations, must equal 1, 2 or 3" }
+    { { $snippet "-young=" { $emphasis "n" } } { "Size of youngest generation (0), megabytes" } }
+    { { $snippet "-aging=" { $emphasis "n" } } "Size of aging generation (1), megabytes" }
+    { { $snippet "-tenured=" { $emphasis "n" } } "Size of oldest generation (2), megabytes" }
     { { $snippet "-codeheap=" { $emphasis "n" } } "Code heap size, megabytes" }
     { { $snippet "-securegc" } "If specified, unused portions of the data heap will be zeroed out after every garbage collection" }
 }
index 6f75ca873d56c010ca36a6f1690b3e0f87a1a980..806ea914bb7dc4eb1b923f3cb42b7d98abfe3e85 100755 (executable)
@@ -20,7 +20,7 @@ IN: compiler
 : finish-compile ( word effect dependencies -- )
     >r dupd save-effect r>
     over compiled-unxref
-    over crossref? [ compiled-xref ] [ 2drop ] if ;
+    over compiled-crossref? [ compiled-xref ] [ 2drop ] if ;
 
 : compile-succeeded ( word -- effect dependencies )
     [
index 09b0c190e6b82a40d6b935af63b9db22b7e4fbfd..dce2ec562a2dd25cc60c31cd2c2b262e7f71d212 100755 (executable)
@@ -187,7 +187,7 @@ DEFER: countdown-b
             { [ dup string? ] [ drop "string" ] }
             { [ dup float? ] [ drop "float" ] }
             { [ dup alien? ] [ drop "alien" ] }
-            { [ t ] [ drop "neither" ] }
+            [ drop "neither" ]
         } cond
     ] compile-call
 ] unit-test
@@ -196,7 +196,7 @@ DEFER: countdown-b
     [
         3 {
             { [ dup fixnum? ] [ ] }
-            { [ t ] [ drop t ] }
+            [ drop t ]
         } cond
     ] compile-call
 ] unit-test
index 97cde6261cd87ecedcde5569a6e1123bdc3618de..2b43ac6f56f8fd47af11d211e354db2815f14386 100755 (executable)
@@ -4,16 +4,16 @@ USING: kernel tools.test compiler.units ;
 TUPLE: color red green blue ;
 
 [ T{ color f 1 2 3 } ]
-[ 1 2 3 [ color construct-boa ] compile-call ] unit-test
+[ 1 2 3 [ color boa ] compile-call ] unit-test
 
 [ 1 3 ] [
-    1 2 3 color construct-boa
+    1 2 3 color boa
     [ { color-red color-blue } get-slots ] compile-call
 ] unit-test
 
 [ T{ color f 10 2 20 } ] [
     10 20
-    1 2 3 color construct-boa [
+    1 2 3 color boa [
         [
             { set-color-red set-color-blue } set-slots
         ] compile-call
@@ -21,4 +21,4 @@ TUPLE: color red green blue ;
 ] unit-test
 
 [ T{ color f f f f } ]
-[ [ color construct-empty ] compile-call ] unit-test
+[ [ color new ] compile-call ] unit-test
index a780e0a745963a1257b6a5e45f02a386898aebb5..65e57a8912f83f036cd2509861143bffabb33c43 100755 (executable)
@@ -10,7 +10,7 @@ SYMBOL: new-definitions
 TUPLE: redefine-error def ;
 
 : redefine-error ( definition -- )
-    \ redefine-error construct-boa
+    \ redefine-error boa
     { { "Continue" t } } throw-restarts drop ;
 
 : add-once ( key assoc -- )
@@ -66,7 +66,7 @@ GENERIC: definitions-changed ( assoc obj -- )
 
 : compile ( words -- )
     recompile-hook get call
-    dup [ drop crossref? ] assoc-contains?
+    dup [ drop compiled-crossref? ] assoc-contains?
     modify-code-heap ;
 
 SYMBOL: outdated-tuples
@@ -82,7 +82,7 @@ SYMBOL: update-tuples-hook
 : finish-compilation-unit ( -- )
     call-recompile-hook
     call-update-tuples-hook
-    dup [ drop crossref? ] assoc-contains? modify-code-heap
+    dup [ drop compiled-crossref? ] assoc-contains? modify-code-heap
     updated-definitions notify-definition-observers ;
 
 : with-compilation-unit ( quot -- )
index b3adb1b165c1fcce52ded4b8ee2c25ba96faf58a..b1db09b6bcf28e4059c8a9112468383b9ae29f9c 100755 (executable)
@@ -90,7 +90,11 @@ ABOUT: "continuations"
 
 HELP: dispose
 { $values { "object" "a disposable object" } }
-{ $contract "Releases operating system resources associated with a disposable object. No further operations can be performed on a disposable object after this call. Disposable objects include streams, memory mapped files, and so on." }
+{ $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on."
+$nl
+"No further operations can be performed on a disposable object after this call."
+$nl
+"Disposing an object which has already been disposed should have no effect, and in particular it should not fail with an error." }
 { $notes "You must close disposable objects after you are finished working with them, to avoid leaking operating system resources. A convenient way to automate this is by using the " { $link with-disposal } " word." } ;
 
 HELP: with-disposal
index 7ea8849d3073ff392c44cb9371ba3df368122b70..65d1763ea830815b79f57e7abb5b31e973410cdf 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays generic kernel kernel.private math memory
 namespaces sequences layouts system hashtables classes alien
-byte-arrays bit-arrays float-arrays combinators words ;
+byte-arrays bit-arrays float-arrays combinators words sets ;
 IN: cpu.architecture
 
 ! A pseudo-register class for parameters spilled on the stack
index 699670aecd95aad3d2f3236a44f4c8f651bdd5ce..cc3fceff230ba2601c946b1cbc9d1a9526bdc740 100755 (executable)
@@ -246,9 +246,8 @@ M: x86.32 %cleanup ( alien-node -- )
         } {
             [ dup return>> large-struct? ]
             [ drop EAX PUSH ]
-        } {
-            [ t ] [ drop ]
         }
+        [ drop ]
     } cond ;
 
 M: x86.32 %unwind ( n -- ) %epilogue-later RET ;
index a3ab256ea1936b198a00968d9894e7cc1dd0d9f5..3ad7d4f7b5c02b85d2ad39fb18d808a89ca043c3 100755 (executable)
@@ -104,7 +104,7 @@ M: indirect extended? indirect-base extended? ;
     canonicalize-ESP ;
 
 : <indirect> ( base index scale displacement -- indirect )
-    indirect construct-boa dup canonicalize ;
+    indirect boa dup canonicalize ;
 
 : reg-code "register" word-prop 7 bitand ;
 
@@ -189,7 +189,7 @@ UNION: operand register indirect ;
     {
         { [ dup register-128? ] [ drop operand-64? ] }
         { [ dup not ] [ drop operand-64? ] }
-        { [ t ] [ nip operand-64? ] }
+        [ nip operand-64? ]
     } cond and ;
 
 : rex.r
index 071535a01e07f8647ab0530e9406de8326205061..827a5c4e8d312b3f1fea3c0190c6b9672f9168ed 100755 (executable)
@@ -160,7 +160,7 @@ PREDICATE: kernel-error < array
     {
         { [ dup empty? ] [ drop f ] }
         { [ dup first "kernel-error" = not ] [ drop f ] }
-        { [ t ] [ second 0 15 between? ] }
+        [ second 0 15 between? ]
     } cond ;
 
 : kernel-errors
@@ -215,7 +215,10 @@ M: check-method summary
     drop "Invalid parameters for create-method" ;
 
 M: no-tuple-class summary
-    drop "Invalid class for define-constructor" ;
+    drop "BOA constructors can only be defined for tuple classes" ;
+
+M: bad-superclass summary
+    drop "Tuple classes can only inherit from other tuple classes" ;
 
 M: no-cond summary
     drop "Fall-through in cond" ;
index 3dc28139ea9d05ad6d042f7982af126ac0206eac..b20d81ec7ca6ed74d372d40539e622ec90023951 100755 (executable)
@@ -2,26 +2,6 @@ IN: definitions.tests
 USING: tools.test generic kernel definitions sequences
 compiler.units words ;
 
-TUPLE: combination-1 ;
-
-M: combination-1 perform-combination drop [ ] define ;
-
-M: combination-1 make-default-method 2drop [ "No method" throw ] ;
-
-SYMBOL: generic-1
-
-[
-    generic-1 T{ combination-1 } define-generic
-
-    object \ generic-1 create-method [ ] define
-] with-compilation-unit
-
-[ ] [
-    [
-        { combination-1 { object generic-1 } } forget-all
-    ] with-compilation-unit
-] unit-test
-
 GENERIC: some-generic ( a -- b )
 
 USE: arrays
index 28db6e1cbdde52a27604c4d63835ed936d2b7582..b0fe2a1157ddfa56b5c819f44ca3a82768740a7c 100755 (executable)
@@ -1,5 +1,5 @@
 USING: dlists dlists.private kernel tools.test random assocs
-hashtables sequences namespaces sorting debugger io prettyprint
+sets sequences namespaces sorting debugger io prettyprint
 math ;
 IN: dlists.tests
 
@@ -79,7 +79,7 @@ IN: dlists.tests
         [ dlist-push-all ] keep
         [ dlist-delete-all ] keep
         dlist>array
-    ] 2keep seq-diff assert-same-elements
+    ] 2keep diff assert-same-elements
 ] unit-test
 
 [ ] [
index 56134f3b54b4ddbc499720e71b29e078e6c0ef0c..e79907f11f68af9a668ddc3686492aa00d6faabf 100755 (executable)
@@ -7,7 +7,7 @@ IN: dlists
 TUPLE: dlist front back length ;
 
 : <dlist> ( -- obj )
-    dlist construct-empty
+    dlist new
     0 >>length ;
 
 : dlist-empty? ( dlist -- ? ) front>> not ;
@@ -126,7 +126,7 @@ PRIVATE>
     {
         { [ over front>> over eq? ] [ drop pop-front* ] }
         { [ over back>> over eq? ] [ drop pop-back* ] }
-        { [ t ] [ unlink-node dec-length ] }
+        [ unlink-node dec-length ]
     } cond ;
 
 : delete-node-if* ( dlist quot -- obj/f ? )
index aed4a64c6cd4c2efad730046d5b2c58a12bce98c..80a4f679c012b99b7aa22779edbe20405035f3de 100755 (executable)
@@ -8,7 +8,7 @@ TUPLE: effect in out terminated? ;
 
 : <effect> ( in out -- effect )
     dup { "*" } sequence= [ drop { } t ] [ f ] if
-    effect construct-boa ;
+    effect boa ;
 
 : effect-height ( effect -- n )
     dup effect-out length swap effect-in length - ;
@@ -20,7 +20,7 @@ TUPLE: effect in out terminated? ;
         { [ dup effect-terminated? ] [ f ] }
         { [ 2dup [ effect-in length ] bi@ > ] [ f ] }
         { [ 2dup [ effect-height ] bi@ = not ] [ f ] }
-        { [ t ] [ t ] }
+        [ t ]
     } cond 2nip ;
 
 GENERIC: (stack-picture) ( obj -- str )
index 33302572de82f50ade60b8301ceabe3492496360..d25d447a469470a3b0a228d83cdb4e09d6c18f77 100755 (executable)
@@ -24,7 +24,7 @@ M: float-array set-nth-unsafe
 M: float-array like
     drop dup float-array? [ >float-array ] unless ;
 
-M: float-array new drop 0.0 <float-array> ;
+M: float-array new-sequence drop 0.0 <float-array> ;
 
 M: float-array equal?
     over float-array? [ sequence= ] [ 2drop f ] if ;
index 2b023985a4728dadbda77c9bc4b3f50444ca4407..7f62f6f95c7181625308da14d313881bff6392d8 100755 (executable)
@@ -7,7 +7,7 @@ IN: float-vectors
 <PRIVATE\r
 \r
 : float-array>vector ( float-array length -- float-vector )\r
-    float-vector construct-boa ; inline\r
+    float-vector boa ; inline\r
 \r
 PRIVATE>\r
 \r
@@ -22,7 +22,7 @@ M: float-vector like
         [ dup length float-array>vector ] [ >float-vector ] if\r
     ] unless ;\r
 \r
-M: float-vector new\r
+M: float-vector new-sequence\r
     drop [ 0.0 <float-array> ] keep >fixnum float-array>vector ;\r
 \r
 M: float-vector equal?\r
diff --git a/core/float-vectors/summary.txt b/core/float-vectors/summary.txt
new file mode 100644 (file)
index 0000000..c476f41
--- /dev/null
@@ -0,0 +1 @@
+Growable float arrays
diff --git a/core/float-vectors/tags.txt b/core/float-vectors/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 5cc044246405306f7c39c8441d833f92ad5473ca..920690e9d8117a1606e70b909b35cfbf864738e0 100755 (executable)
@@ -10,7 +10,7 @@ IN: generator.fixup
 
 TUPLE: frame-required n ;
 
-: frame-required ( n -- ) \ frame-required construct-boa , ;
+: frame-required ( n -- ) \ frame-required boa , ;
 
 : stack-frame-size ( code -- n )
     no-stack-frame [
@@ -25,7 +25,7 @@ GENERIC: fixup* ( frame-size obj -- frame-size )
 
 TUPLE: label offset ;
 
-: <label> ( -- label ) label construct-empty ;
+: <label> ( -- label ) label new ;
 
 M: label fixup*
     compiled-offset swap set-label-offset ;
@@ -40,8 +40,8 @@ M: label fixup*
 
 M: word fixup*
     {
-        { %prologue-later [ dup [ %prologue ] if-stack-frame ] }
-        { %epilogue-later [ dup [ %epilogue ] if-stack-frame ] }
+        { %prologue-later [ dup [ %prologue ] if-stack-frame ] }
+        { %epilogue-later [ dup [ %epilogue ] if-stack-frame ] }
     } case ;
 
 SYMBOL: relocation-table
@@ -74,7 +74,7 @@ SYMBOL: label-table
 
 TUPLE: label-fixup label class ;
 
-: label-fixup ( label class -- ) \ label-fixup construct-boa , ;
+: label-fixup ( label class -- ) \ label-fixup boa , ;
 
 M: label-fixup fixup*
     dup label-fixup-class rc-absolute?
@@ -84,7 +84,7 @@ M: label-fixup fixup*
 
 TUPLE: rel-fixup arg class type ;
 
-: rel-fixup ( arg class type -- ) \ rel-fixup construct-boa , ;
+: rel-fixup ( arg class type -- ) \ rel-fixup boa , ;
 
 : (rel-fixup) ( arg class type offset -- pair )
     pick rc-absolute-cell = cell 4 ? -
index 3514947e3d5a62a13dc475ea0986cf1aa2ae0d65..919e89d3c8cdc4152b5443ee86586d5edaf1bb56 100755 (executable)
@@ -16,7 +16,7 @@ SYMBOL: compiled
         { [ dup compiled get key? ] [ drop ] }
         { [ dup inlined-block? ] [ drop ] }
         { [ dup primitive? ] [ drop ] }
-        { [ t ] [ dup compile-queue get set-at ] }
+        [ dup compile-queue get set-at ]
     } cond ;
 
 : maybe-compile ( word -- )
@@ -202,7 +202,7 @@ M: #dispatch generate-node
 : define-if>boolean-intrinsics ( word intrinsics -- )
     [
         >r [ if>boolean-intrinsic ] curry r>
-        { { f "if-scratch" } } +scratch+ associate union
+        { { f "if-scratch" } } +scratch+ associate assoc-union
     ] assoc-map "intrinsics" set-word-prop ;
 
 : define-if-intrinsics ( word intrinsics -- )
index f3dc0fb10e454a7402d26dd08a67c942903ae3ad..627f51acc2d5873a87f208f2445156a023f5ec49 100755 (executable)
@@ -4,7 +4,7 @@ USING: arrays assocs classes classes.private classes.algebra
 combinators cpu.architecture generator.fixup hashtables kernel
 layouts math namespaces quotations sequences system vectors
 words effects alien byte-arrays bit-arrays float-arrays
-accessors ;
+accessors sets ;
 IN: generator.registers
 
 SYMBOL: +input+
@@ -76,7 +76,7 @@ INSTANCE: temp-reg value
 ! A data stack location.
 TUPLE: ds-loc n class ;
 
-: <ds-loc> f ds-loc construct-boa ;
+: <ds-loc> f ds-loc boa ;
 
 M: ds-loc minimal-ds-loc* ds-loc-n min ;
 M: ds-loc operand-class* ds-loc-class ;
@@ -87,7 +87,7 @@ M: ds-loc live-loc?
 ! A retain stack location.
 TUPLE: rs-loc n class ;
 
-: <rs-loc> f rs-loc construct-boa ;
+: <rs-loc> f rs-loc boa ;
 M: rs-loc operand-class* rs-loc-class ;
 M: rs-loc set-operand-class set-rs-loc-class ;
 M: rs-loc live-loc?
@@ -128,7 +128,7 @@ INSTANCE: cached value
 TUPLE: tagged vreg class ;
 
 : <tagged> ( vreg -- tagged )
-    f tagged construct-boa ;
+    f tagged boa ;
 
 M: tagged v>operand tagged-vreg v>operand ;
 M: tagged set-operand-class set-tagged-class ;
@@ -195,7 +195,7 @@ INSTANCE: constant value
         { [ dup byte-array class< ] [ drop %unbox-byte-array ] }
         { [ dup bit-array class< ] [ drop %unbox-byte-array ] }
         { [ dup float-array class< ] [ drop %unbox-byte-array ] }
-        { [ t ] [ drop %unbox-any-c-ptr ] }
+        [ drop %unbox-any-c-ptr ]
     } cond ; inline
 
 : %move-via-temp ( dst src -- )
@@ -237,8 +237,8 @@ M: phantom-stack clone
 
 GENERIC: finalize-height ( stack -- )
 
-: construct-phantom-stack ( class -- stack )
-    >r 0 V{ } clone r> construct-boa ; inline
+: new-phantom-stack ( class -- stack )
+    >r 0 V{ } clone r> boa ; inline
 
 : (loc)
     #! Utility for methods on <loc>
@@ -257,7 +257,7 @@ GENERIC: <loc> ( n stack -- loc )
 TUPLE: phantom-datastack < phantom-stack ;
 
 : <phantom-datastack> ( -- stack )
-    phantom-datastack construct-phantom-stack ;
+    phantom-datastack new-phantom-stack ;
 
 M: phantom-datastack <loc> (loc) <ds-loc> ;
 
@@ -267,7 +267,7 @@ M: phantom-datastack finalize-height
 TUPLE: phantom-retainstack < phantom-stack ;
 
 : <phantom-retainstack> ( -- stack )
-    phantom-retainstack construct-phantom-stack ;
+    phantom-retainstack new-phantom-stack ;
 
 M: phantom-retainstack <loc> (loc) <rs-loc> ;
 
@@ -357,14 +357,14 @@ SYMBOL: fresh-objects
         { [ dup unboxed-c-ptr eq? ] [
             over { unboxed-byte-array unboxed-alien } member?
         ] }
-        { [ t ] [ f ] }
+        [ f ]
     } cond 2nip ;
 
 : allocation ( value spec -- reg-class )
     {
         { [ dup quotation? ] [ 2drop f ] }
         { [ 2dup compatible? ] [ 2drop f ] }
-        { [ t ] [ nip reg-spec>class ] }
+        [ nip reg-spec>class ]
     } cond ;
 
 : alloc-vreg-for ( value spec -- vreg )
@@ -381,7 +381,7 @@ M: value (lazy-load)
 : (compute-free-vregs) ( used class -- vector )
     #! Find all vregs in 'class' which are not in 'used'.
     [ vregs length reverse ] keep
-    [ <vreg> ] curry map seq-diff
+    [ <vreg> ] curry map diff
     >vector ;
 
 : compute-free-vregs ( -- )
index cd08e8051204ec81c16204ca426be0ec038915fa..caae16e8ed0d003cd4259f46593d783f64abf16e 100755 (executable)
@@ -50,7 +50,7 @@ TUPLE: check-method class generic ;
 
 : check-method ( class generic -- class generic )
     over class? over generic? and [
-        \ check-method construct-boa throw
+        \ check-method boa throw
     ] unless ; inline
 
 : with-methods ( generic quot -- )
index fce908bdef64265ce27df5a0e7bd42c7465b49a3..884ab8027ef637f1ddd23923eecc1ad900f26b7f 100755 (executable)
@@ -19,7 +19,7 @@ PREDICATE: math-class < class
     {
         { [ dup null class< ] [ drop { -1 -1 } ] }
         { [ dup math-class? ] [ class-types last/first ] }
-        { [ t ] [ drop { 100 100 } ] }
+        [ drop { 100 100 } ]
     } cond ;
     
 : math-class-max ( class class -- class )
index ce7d5c6c217f57b1b1b87f67f075953400b0fe8e..5335074deaf68784cf142de1d7499361d37349f1 100644 (file)
@@ -18,7 +18,7 @@ C: <predicate-dispatch-engine> predicate-dispatch-engine
         { [ dup empty? ] [ drop [ "Unreachable" throw ] { } ] }
         { [ dup length 1 = ] [ first second { } ] }
         { [ dup keep-going? ] [ 1 tail-slice prune-redundant-predicates ] }
-        { [ t ] [ [ first second ] [ 1 tail-slice ] bi ] }
+        [ [ first second ] [ 1 tail-slice ] bi ]
     } cond ;
 
 : sort-methods ( assoc -- assoc' )
index 69d73aa872d90a39400df46e43c62fbfe666a599..0ffd953d77f5e872db9fd22496fd290efcc8691e 100644 (file)
@@ -35,7 +35,7 @@ TUPLE: tuple-dispatch-engine echelons ;
             dupd <echelon-dispatch-engine>
         ] if
     ] assoc-map [ nip ] assoc-subset
-    \ tuple-dispatch-engine construct-boa ;
+    \ tuple-dispatch-engine boa ;
 
 : convert-tuple-methods ( assoc -- assoc' )
     tuple bootstrap-word
@@ -63,14 +63,14 @@ M: trivial-tuple-dispatch-engine engine>quot
     ] "" make ;
 
 PREDICATE: tuple-dispatch-engine-word < word
-    "tuple-dispatch-engine" word-prop ;
+    "tuple-dispatch-generic" word-prop generic? ;
 
 M: tuple-dispatch-engine-word stack-effect
     "tuple-dispatch-generic" word-prop
-    [ extra-values ] [ stack-effect clone ] bi
-    [ length + ] change-in ;
+    [ extra-values ] [ stack-effect ] bi
+    dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
 
-M: tuple-dispatch-engine-word crossref?
+M: tuple-dispatch-engine-word compiled-crossref?
     drop t ;
 
 : remember-engine ( word -- )
@@ -78,12 +78,10 @@ M: tuple-dispatch-engine-word crossref?
 
 : <tuple-dispatch-engine-word> ( engine -- word )
     tuple-dispatch-engine-word-name f <word>
-    {
-        [ t "tuple-dispatch-engine" set-word-prop ]
-        [ generic get "tuple-dispatch-generic" set-word-prop ]
-        [ remember-engine ]
-        [ ]
-    } cleave ;
+    [ generic get "tuple-dispatch-generic" set-word-prop ]
+    [ remember-engine ]
+    [ ]
+    tri ;
 
 : define-tuple-dispatch-engine-word ( engine quot -- word )
     >r <tuple-dispatch-engine-word> dup r> define ;
index a906acd3240b78966dce66879e9f0716bc6f9309..8799169445a4cb342325756dc836e2c367a60bb8 100644 (file)
@@ -2,7 +2,8 @@ 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
-quotations inference vectors growable ;
+quotations inference vectors growable hashtables sbufs
+prettyprint ;
 
 GENERIC: lo-tag-test
 
@@ -182,22 +183,22 @@ M: ceo salary
 
 [ salary ] must-infer
 
-[ 24000 ] [ employee construct-boa salary ] unit-test
+[ 24000 ] [ employee boa salary ] unit-test
 
-[ 24000 ] [ tape-monkey construct-boa salary ] unit-test
+[ 24000 ] [ tape-monkey boa salary ] unit-test
 
-[ 36000 ] [ junior-manager construct-boa salary ] unit-test
+[ 36000 ] [ junior-manager boa salary ] unit-test
 
-[ 41000 ] [ middle-manager construct-boa salary ] unit-test
+[ 41000 ] [ middle-manager boa salary ] unit-test
 
-[ 51000 ] [ senior-manager construct-boa salary ] unit-test
+[ 51000 ] [ senior-manager boa salary ] unit-test
 
-[ 102000 ] [ executive construct-boa salary ] unit-test
+[ 102000 ] [ executive boa salary ] unit-test
 
-[ ceo construct-boa salary ]
+[ ceo boa salary ]
 [ T{ inconsistent-next-method f ceo salary } = ] must-fail-with
 
-[ intern construct-boa salary ]
+[ intern boa salary ]
 [ T{ no-next-method f intern salary } = ] must-fail-with
 
 ! Weird shit
@@ -268,3 +269,13 @@ M: growable call-next-hooker call-next-method "growable " prepend ;
 [ "vector growable sequence" ] [
     V{ } my-var [ call-next-hooker ] with-variable
 ] unit-test
+
+GENERIC: no-stack-effect-decl
+
+M: hashtable no-stack-effect-decl ;
+M: vector no-stack-effect-decl ;
+M: sbuf no-stack-effect-decl ;
+
+[ ] [ \ no-stack-effect-decl see ] unit-test
+
+[ ] [ \ no-stack-effect-decl word-def . ] unit-test
index ed5134a624b2093fe9e6713c8ea768c49aaedfbb..98194e7ef3026fa29a92b77acfb79f0b8c7fe283 100644 (file)
@@ -110,6 +110,9 @@ ERROR: no-next-method class generic ;
         \ if ,
     ] [ ] make ;
 
+: single-effective-method ( obj word -- method )
+    [ order [ instance? ] with find-last nip ] keep method ;
+
 TUPLE: standard-combination # ;
 
 C: <standard-combination> standard-combination
@@ -142,8 +145,7 @@ M: standard-combination next-method-quot*
     ] with-standard ;
 
 M: standard-generic effective-method
-    [ dispatch# (picker) call ] keep
-    [ order [ instance? ] with find-last nip ] keep method ;
+    [ dispatch# (picker) call ] keep single-effective-method ;
 
 TUPLE: hook-combination var ;
 
@@ -161,6 +163,10 @@ M: hook-combination dispatch# drop 0 ;
 
 M: hook-generic extra-values drop 1 ;
 
+M: hook-generic effective-method
+    [ "combination" word-prop var>> get ] keep
+    single-effective-method ;
+
 M: hook-combination make-default-method
     [ error-method ] with-hook ;
 
index 1e4350d58c6105f3de7e662064204a1d28edbdbc..f16f8cca3b5f0a85d63c9e2f60f8b4d46dacd025 100644 (file)
@@ -21,12 +21,12 @@ HELP: graph
 
 HELP: add-vertex
 { $values { "vertex" object } { "edges" "a sequence" } { "graph" "an assoc mapping vertices to sequences of edges" } }
-{ $description "Adds a vertex to a directed graph, using the " { $snippet "edges" } " quotation to generate a sequence of edges leaving the vertex." }
+{ $description "Adds a vertex to a directed graph, with " { $snippet "edges" } "  as the outward edges from the vertex." }
 { $side-effects "graph" } ;
 
 HELP: remove-vertex
 { $values { "vertex" object } { "edges" "a sequence" } { "graph" "an assoc mapping vertices to sequences of edges" } }
-{ $description "Removes a vertex from a graph, using the quotation to generate a sequence of edges leaving the vertex." } 
+{ $description "Removes a vertex from a graph, using the given edges sequence." } 
 { $notes "The " { $snippet "edges" } " sequence must equal the value passed to " { $link add-vertex } ", otherwise some vertices of the graph may continue to refer to the removed vertex." }
 { $side-effects "graph" } ;
 
index 2a4be9c5708fd2b284e00ca2a1d3cf8ffd0ca5b1..aff59ee8a5f08ce495efd6c5ece13bf8a63bfdce 100755 (executable)
@@ -49,11 +49,7 @@ $nl
 ARTICLE: "hashtables.utilities" "Hashtable utilities"
 "Utility words to create a new hashtable from a single key/value pair:"
 { $subsection associate }
-{ $subsection ?set-at }
-"The final two words pertain to sequences but use a hashtable internally. Removing duplicate elements from a sequence in linear time, using a hashtable:"
-{ $subsection prune }
-"Test if a sequence contains duplicates in linear time:"
-{ $subsection all-unique? } ;
+{ $subsection ?set-at } ;
 
 ABOUT: "hashtables"
 
@@ -138,22 +134,6 @@ HELP: >hashtable
 { $values { "assoc" "an assoc" } { "hashtable" "a hashtable" } }
 { $description "Constructs a hashtable from any assoc." } ;
 
-HELP: prune
-{ $values { "seq" "a sequence" } { "newseq" "a sequence" } }
-{ $description "Outputs a new sequence with each distinct element of " { $snippet "seq" } " appearing only once. Elements are compared for equality using " { $link = } " and elements are ordered according to their position in " { $snippet "seq" } "." }
-{ $examples
-    { $example "USING: hashtables prettyprint ;" "{ 1 1 t 3 t } prune ." "V{ 1 t 3 }" }
-} ;
-
-HELP: all-unique?
-{ $values { "seq" sequence } { "?" "a boolean" } }
-{ $description "Tests whether a sequence contains any repeated elements." }
-{ $example
-    "USING: hashtables prettyprint ;"
-    "{ 0 1 1 2 3 5 } all-unique? ."
-    "f"
-} ;
-
 HELP: rehash
 { $values { "hash" hashtable } }
 { $description "Rebuild the hashtable. This word should be called if the hashcodes of the hashtable's keys have changed, or if the hashing algorithms themselves have changed, neither of which should occur during normal operation." } ;
index a62b306378778018c512d893fe18c25dfce79b00..f4e76aa68e9a6e8e73af490ce3ead7d7871c276e 100755 (executable)
@@ -164,6 +164,3 @@ H{ } "x" set
 [ { "one" "two" 3 } ] [
     { 1 2 3 } H{ { 1 "one" } { 2 "two" } } substitute
 ] unit-test
-
-[ f ] [ { 0 1 1 2 3 5 } all-unique? ] unit-test
-[ t ] [ { 0 1 2 3 4 5 } all-unique? ] unit-test
index 5ac49ffa2fcb56887d28de35ebdc56d26d07bd21..ea2f67255c02df70a27af3cf1de7025d71f2cf97 100755 (executable)
@@ -116,7 +116,7 @@ IN: hashtables
 PRIVATE>
 
 : <hashtable> ( n -- hash )
-    hashtable construct-empty [ reset-hash ] keep ;
+    hashtable new [ reset-hash ] keep ;
 
 M: hashtable at* ( key hash -- value ? )
     key@ [ 3 fixnum+fast slot t ] [ 2drop f f ] if ;
@@ -174,18 +174,4 @@ M: hashtable assoc-like
 : ?set-at ( value key assoc/f -- assoc )
     [ [ set-at ] keep ] [ associate ] if* ;
 
-: (prune) ( hash vec elt -- )
-    rot 2dup key?
-    [ 3drop ] [ dupd dupd set-at swap push ] if ; inline
-
-: prune ( seq -- newseq )
-    [ length <hashtable> ]
-    [ length <vector> ]
-    [ ] tri
-    [ >r 2dup r> (prune) ] each nip ;
-
-: all-unique? ( seq -- ? )
-    [ length ]
-    [ prune length ] bi = ;
-
 INSTANCE: hashtable assoc
index 783d662e43421c5cb35140fca0f87ba226bbc415..02a8b8d88b9891fc43134d620c0d747180c947f5 100755 (executable)
@@ -20,11 +20,11 @@ GENERIC: heap-size ( heap -- n )
 TUPLE: heap data ;
 
 : <heap> ( class -- heap )
-    >r V{ } clone r> construct-boa ; inline
+    >r V{ } clone r> boa ; inline
 
 TUPLE: entry value key heap index ;
 
-: <entry> ( value key heap -- entry ) f entry construct-boa ;
+: <entry> ( value key heap -- entry ) f entry boa ;
 
 PRIVATE>
 
diff --git a/core/heaps/tags.txt b/core/heaps/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 1d742e144a138ff890798525aadf160d6b06d053..0125f04efad796ff4d124fe62a20c31484f62f39 100755 (executable)
@@ -1,10 +1,11 @@
 USING: help.syntax help.markup words effects inference.dataflow
-inference.state inference.backend kernel sequences
+inference.state kernel sequences
 kernel.private combinators sequences.private ;
+IN: inference.backend
 
 HELP: literal-expected
 { $error-description "Thrown when inference encounters a " { $link call } " or " { $link if } " being applied to a value which is not known to be a literal. Such a form can have an arbitrary stack effect, and does not compile." }
-{ $notes "This error will be thrown when compiling any combinator, such as " { $link each } ". However, words calling combinators can compile of the combinator is declared " { $link POSTPONE: inline } " and the quotation being passed in is a literal." } ;
+{ $notes "This error will be thrown when compiling any combinator, such as " { $link each } ". However, words calling combinators can compile if the combinator is declared " { $link POSTPONE: inline } " and the quotation being passed in is a literal." } ;
 
 HELP: too-many->r
 { $error-description "Thrown if inference notices a quotation pushing elements on the retain stack without popping them at the end." }
index 3dcb1d236095674997746a78e8309d71c7dc8ce5..cf40944d1d01b4e7671b66df8b3b19452ebd96e5 100755 (executable)
@@ -39,9 +39,9 @@ M: inference-error compiler-error-type type>> ;
 M: inference-error error-help error>> error-help ;
 
 : (inference-error) ( ... class type -- * )
-    >r construct-boa r>
+    >r boa r>
     recursive-state get
-    \ inference-error construct-boa throw ; inline
+    \ inference-error boa throw ; inline
 
 : inference-error ( ... class -- * )
     +error+ (inference-error) ; inline
@@ -251,7 +251,7 @@ TUPLE: cannot-unify-specials ;
         { [ dup [ curried? ] all? ] [ unify-curries ] }
         { [ dup [ composed? ] all? ] [ unify-composed ] }
         { [ dup [ special? ] contains? ] [ cannot-unify-specials ] }
-        { [ t ] [ drop <computed> ] }
+        [ drop <computed> ]
     } cond ;
 
 : unify-stacks ( seq -- stack )
@@ -395,7 +395,7 @@ TUPLE: effect-error word effect ;
         { [ dup "infer" word-prop ] [ custom-infer ] }
         { [ dup "no-effect" word-prop ] [ no-effect ] }
         { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
-        { [ t ] [ dup infer-word make-call-node ] }
+        [ dup infer-word make-call-node ]
     } cond ;
 
 TUPLE: recursive-declare-error word ;
index a4b7ad1888f90ca74308f6d6d776b0285f0b0201..3fb047b781123ab33b97a1296a0fd3e9f3a6b7a9 100755 (executable)
@@ -12,7 +12,7 @@ IN: inference.dataflow
 TUPLE: value < identity-tuple literal uid recursion ;
 
 : <value> ( obj -- value )
-    <computed> recursive-state get value construct-boa ;
+    <computed> recursive-state get value boa ;
 
 M: value hashcode* nip value-uid ;
 
@@ -68,16 +68,16 @@ M: object flatten-curry , ;
     [ in-d>> ] [ out-d>> ] bi <effect> ;
 
 : param-node ( param class -- node )
-    construct-empty swap >>param ; inline
+    new swap >>param ; inline
 
 : in-node ( seq class -- node )
-    construct-empty swap >>in-d ; inline
+    new swap >>in-d ; inline
 
 : all-in-node ( class -- node )
     flatten-meta-d swap in-node ; inline
 
 : out-node ( seq class -- node )
-    construct-empty swap >>out-d ; inline
+    new swap >>out-d ; inline
 
 : all-out-node ( class -- node )
     flatten-meta-d swap out-node ; inline
@@ -111,19 +111,19 @@ TUPLE: #call-label < node ;
 
 TUPLE: #push < node ;
 
-: #push ( -- node ) \ #push construct-empty ;
+: #push ( -- node ) \ #push new ;
 
 TUPLE: #shuffle < node ;
 
-: #shuffle ( -- node ) \ #shuffle construct-empty ;
+: #shuffle ( -- node ) \ #shuffle new ;
 
 TUPLE: #>r < node ;
 
-: #>r ( -- node ) \ #>r construct-empty ;
+: #>r ( -- node ) \ #>r new ;
 
 TUPLE: #r> < node ;
 
-: #r> ( -- node ) \ #r> construct-empty ;
+: #r> ( -- node ) \ #r> new ;
 
 TUPLE: #values < node ;
 
@@ -150,7 +150,7 @@ TUPLE: #merge < node ;
 
 TUPLE: #terminate < node ;
 
-: #terminate ( -- node ) \ #terminate construct-empty ;
+: #terminate ( -- node ) \ #terminate new ;
 
 TUPLE: #declare < node ;
 
index a837cfce5e6d1924f8aabc1ef64dd2e3e0b8fb19..e32c94ed371263df9655a1a95b0293cd5205ce35 100755 (executable)
@@ -79,6 +79,18 @@ ARTICLE: "dataflow-graphs" "Inspecting the dataflow graph"
 "The " { $vocab-link "optimizer.debugger" } " tool prints the dataflow graph in human readable form."
 $nl ;
 
+ARTICLE: "inference-errors" "Inference errors"
+"Main wrapper for all inference errors:"
+{ $subsection inference-error }
+"Specific inference errors:"
+{ $subsection no-effect }
+{ $subsection literal-expected }
+{ $subsection too-many->r }
+{ $subsection too-many-r> }
+{ $subsection unbalanced-branches-error }
+{ $subsection effect-error }
+{ $subsection recursive-declare-error } ;
+
 ARTICLE: "inference" "Stack effect inference"
 "The stack effect inference tool is used to check correctness of code before it is run. It is also used by the compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile."
 $nl
@@ -93,7 +105,8 @@ $nl
 { $subsection "inference-combinators" }
 { $subsection "inference-branches" }
 { $subsection "inference-recursive" } 
-{ $subsection "inference-limitations" } 
+{ $subsection "inference-limitations" }
+{ $subsection "inference-errors" }
 { $subsection "dataflow-graphs" }
 { $subsection "compiler-transforms" } ;
 
@@ -105,16 +118,7 @@ HELP: inference-error
 { $error-description
     "Thrown by " { $link infer } " and " { $link dataflow } " when the stack effect of a quotation cannot be inferred."
     $nl
-    "The " { $snippet "error" } " slot contains one of the following classes of errors, which indicate the specific issue preventing a stack effect from being inferred:"
-    { $list
-        { $link no-effect }
-        { $link literal-expected }
-        { $link too-many->r }
-        { $link too-many-r> }
-        { $link unbalanced-branches-error }
-        { $link effect-error }
-        { $link recursive-declare-error }
-    }
+    "The " { $snippet "error" } " slot contains one of several possible " { $link "inference-errors" } "."
 } ;
 
 
index 33a5da87f4374b7e299f94f8db46345e8edf4fc6..453e2460b0362529e5f7ba7746f2931100d7248d 100755 (executable)
@@ -587,6 +587,10 @@ set-primitive-effect
 
 \ (os-envs) { } { array } <effect> set-primitive-effect
 
+\ set-os-env { string string } { } <effect> set-primitive-effect
+
+\ unset-os-env { string } { } <effect> set-primitive-effect
+
 \ (set-os-envs) { array } { } <effect> set-primitive-effect
 
 \ do-primitive [ \ do-primitive no-effect ] "infer" set-word-prop
index 3fc8f37b4fab0f1da56a590ae18d64bb9c26960c..a5b898315a625fa2c01671a40013c4c43bf0de80 100755 (executable)
@@ -20,7 +20,7 @@ classes ;
 
 [ 512 ] [ 1 { { 1+ 8 } } bitfield-quot call ] unit-test
 
-\ construct-empty must-infer
+\ new must-infer
 
 TUPLE: a-tuple x y z ;
 
index d95ff9c3bcda3445da1447db8a0213d7a0e97da6..624dcbbf980ae8d0a6284dda7d4b05d7b4856d7f 100755 (executable)
@@ -3,7 +3,7 @@
 USING: arrays kernel words sequences generic math namespaces
 quotations assocs combinators math.bitfields inference.backend
 inference.dataflow inference.state classes.tuple.private effects
-inspector hashtables classes generic ;
+inspector hashtables classes generic sets ;
 IN: inference.transforms
 
 : pop-literals ( n -- rstate seq )
@@ -82,12 +82,12 @@ M: duplicated-slots-error summary
     [ <reversed> [get-slots] ] [ duplicated-slots-error ] if
 ] 1 define-transform
 
-\ construct-boa [
+\ boa [
     dup +inlined+ depends-on
     tuple-layout [ <tuple-boa> ] curry
 ] 1 define-transform
 
-\ construct-empty [
+\ new [
     1 ensure-values
     peek-d value? [
         pop-literal
@@ -95,7 +95,7 @@ M: duplicated-slots-error summary
         tuple-layout [ <tuple> ] curry
         swap infer-quot
     ] [
-        \ construct-empty 1 1 <effect> make-call-node
+        \ new 1 1 <effect> make-call-node
     ] if
 ] "infer" set-word-prop
 
index 449d34f05b0235225174dd8526dfe6544f62a68e..c9bfbfad54cb43779aace0b3ee1d3b902fd3235f 100755 (executable)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays generic hashtables io kernel assocs math
 namespaces prettyprint sequences strings io.styles vectors words
-quotations mirrors splitting math.parser classes vocabs refs ;
+quotations mirrors splitting math.parser classes vocabs refs
+sets ;
 IN: inspector
 
 GENERIC: summary ( object -- string )
index 398fb6a068462a46fcabfee236b3617078bdaef2..4559cec666c5a1ed166447fa13ee0d20b3aac1c0 100755 (executable)
@@ -30,8 +30,8 @@ ERROR: encode-error ;
 
 <PRIVATE
 
-M: tuple-class <decoder> construct-empty <decoder> ;
-M: tuple <decoder> f decoder construct-boa ;
+M: tuple-class <decoder> new <decoder> ;
+M: tuple <decoder> f decoder boa ;
 
 : >decoder< ( decoder -- stream encoding )
     [ stream>> ] [ code>> ] bi ;
@@ -104,8 +104,8 @@ M: decoder stream-readln ( stream -- str )
 M: decoder dispose decoder-stream dispose ;
 
 ! Encoding
-M: tuple-class <encoder> construct-empty <encoder> ;
-M: tuple <encoder> encoder construct-boa ;
+M: tuple-class <encoder> new <encoder> ;
+M: tuple <encoder> encoder boa ;
 
 : >encoder< ( encoder -- stream encoding )
     [ stream>> ] [ code>> ] bi ;
index e98860f25dffed7382c91ad7b291c605ba985dce..7a22107f196862115b5317aef157ea0c20cd4709 100644 (file)
@@ -33,7 +33,7 @@ TUPLE: utf8 ;
         { [ dup -5 shift BIN: 110 number= ] [ double ] }
         { [ dup -4 shift BIN: 1110 number= ] [ triple ] }
         { [ dup -3 shift BIN: 11110 number= ] [ quad ] }
-        { [ t ] [ drop replacement-char ] }
+        [ drop replacement-char ]
     } cond ;
 
 : decode-utf8 ( stream -- char/f )
@@ -59,12 +59,12 @@ M: utf8 decode-char
             2dup -6 shift encoded
             encoded
         ] }
-        { [ t ] [
+        [
             2dup -18 shift BIN: 11110000 bitor swap stream-write1
             2dup -12 shift encoded
             2dup -6 shift encoded
             encoded
-        ] }
+        ]
     } cond ;
 
 M: utf8 encode-char
index e3f86c079d84b4ff2e5543f5849ae37dbcc683b5..ba17223a2937eec75a98eb6d5926e8e5a500084b 100755 (executable)
@@ -39,11 +39,19 @@ ARTICLE: "symbolic-links" "Symbolic links"
 "Not all operating systems support symbolic links."
 { $see-also link-info } ;
 
-ARTICLE: "directories" "Directories"
-"Current directory:"
+ARTICLE: "current-directory" "Current working directory"
+"File system I/O operations use the value of a variable to resolve relative pathnames:"
 { $subsection current-directory }
+"This variable can be changed with a pair of words:"
 { $subsection set-current-directory }
 { $subsection with-directory }
+"This variable is independent of the operating system notion of ``current working directory''. While all Factor I/O operations use the variable and not the operating system's value, care must be taken when making FFI calls which expect a pathname. The first option is to resolve relative paths:"
+{ $subsection (normalize-path) }
+"The second is to change the working directory of the current process:"
+{ $subsection cd }
+{ $subsection cwd } ;
+
+ARTICLE: "directories" "Directories"
 "Home directory:"
 { $subsection home }
 "Directory listing:"
@@ -51,7 +59,8 @@ ARTICLE: "directories" "Directories"
 { $subsection directory* }
 "Creating directories:"
 { $subsection make-directory }
-{ $subsection make-directories } ;
+{ $subsection make-directories }
+{ $subsection "current-directory" } ;
 
 ARTICLE: "file-types" "File Types"
 "Platform-independent types:"
@@ -112,8 +121,7 @@ ARTICLE: "io.files" "Basic file operations"
 { $subsection "file-streams" }
 { $subsection "fs-meta" }
 { $subsection "directories" }
-{ $subsection "delete-move-copy" }
-{ $see-also "os" } ;
+{ $subsection "delete-move-copy" } ;
 
 ABOUT: "io.files"
 
@@ -243,11 +251,21 @@ HELP: cd
 { cd cwd current-directory set-current-directory with-directory } related-words
 
 HELP: current-directory
-{ $description "A variable holding the current directory. Words that use the filesystem do so in relation to this variable.  On startup, an init hook sets this word to the directory from which Factor was run." } ;
+{ $description "A variable holding the current directory as an absolute path. Words that use the filesystem do so in relation to this variable."
+$nl
+"This variable should never be set directly; instead, use " { $link set-current-directory } " or " { $link with-directory } ". This preserves the invariant that the value of this variable is an absolute path." } ;
+
+HELP: set-current-directory
+{ $values { "path" "a pathname string" } }
+{ $description "Changes the " { $link current-directory } " variable."
+$nl
+"If " { $snippet "path" } " is relative, it is first resolved relative to the current directory. If " { $snippet "path" } " is absolute, it becomes the new current directory." } ;
 
 HELP: with-directory
 { $values { "path" "a pathname string" } { "quot" quotation } }
-{ $description "Changes the " { $link current-directory } " variable for the duration of a quotation's execution.  Words that use the file-system should call " { $link normalize-path } " in order to obtain a path relative to the current directory." } ;
+{ $description "Calls the quotation in a new dynamic scope with the " { $link current-directory } " variable rebound."
+$nl
+"If " { $snippet "path" } " is relative, it is first resolved relative to the current directory. If " { $snippet "path" } " is absolute, it becomes the new current directory." } ;
 
 HELP: append-path
 { $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } }
@@ -301,7 +319,7 @@ HELP: directory*
 
 HELP: resource-path
 { $values { "path" "a pathname string" } { "newpath" "a pathname string" } }
-{ $description "Resolve a path relative to the Factor source code location. This first checks if the " { $link resource-path } " variable is set to a path, and if not, uses the parent directory of the current image." } ;
+{ $description "Resolve a path relative to the Factor source code location." } ;
 
 HELP: pathname
 { $class-description "Class of pathname presentations. Path name presentations can be created by calling " { $link <pathname> } ". Instances can be passed to " { $link write-object } " to output a clickable pathname." } ;
index 6719d1334c0a9016387b7153bb2969fdfaf24889..061e6386dade88cb13f46e5956198b0db8d58554 100755 (executable)
@@ -95,7 +95,7 @@ ERROR: no-parent-directory path ;
             1 tail left-trim-separators append-path-empty
         ] }
         { [ dup head..? ] [ drop no-parent-directory ] }
-        { [ t ] [ nip ] }
+        [ nip ]
     } cond ;
 
 PRIVATE>
@@ -105,7 +105,7 @@ PRIVATE>
         { [ dup "\\\\?\\" head? ] [ t ] }
         { [ dup length 2 < ] [ f ] }
         { [ dup second CHAR: : = ] [ t ] }
-        { [ t ] [ f ] }
+        [ f ]
     } cond ;
 
 : absolute-path? ( path -- ? )
@@ -114,7 +114,7 @@ PRIVATE>
         { [ dup "resource:" head? ] [ t ] }
         { [ os windows? ] [ windows-absolute-path? ] }
         { [ dup first path-separator? ] [ t ] }
-        { [ t ] [ f ] }
+        [ f ]
     } cond nip ;
 
 : append-path ( str1 str2 -- str )
@@ -130,10 +130,10 @@ PRIVATE>
         { [ over absolute-path? over first path-separator? and ] [
             >r 2 head r> append
         ] }
-        { [ t ] [
+        [
             >r right-trim-separators "/" r>
             left-trim-separators 3append
-        ] }
+        ]
     } cond ;
 
 : prepend-path ( str1 str2 -- str )
@@ -220,10 +220,10 @@ HOOK: make-directory io-backend ( path -- )
         { [ dup root-directory? ] [ ] }
         { [ dup empty? ] [ ] }
         { [ dup exists? ] [ ] }
-        { [ t ] [
+        [
             dup parent-directory make-directories
             dup make-directory
-        ] }
+        ]
     } cond drop ;
 
 ! Directory listings
@@ -322,9 +322,10 @@ C: <pathname> pathname
 M: pathname <=> [ pathname-string ] compare ;
 
 ! Home directory
-: home ( -- dir )
-    {
-        { [ os winnt? ] [ "USERPROFILE" os-env ] }
-        { [ os wince? ] [ "" resource-path ] }
-        { [ os unix? ] [ "HOME" os-env ] }
-    } cond ;
+HOOK: home os ( -- dir )
+
+M: winnt home "USERPROFILE" os-env ;
+
+M: wince home "" resource-path ;
+
+M: unix home "HOME" os-env ;
index 6a956c6694f641a1ab62da6a9935d0624cff3a62..c9691af5ba7a2254f62647469fddefbf3e84301d 100755 (executable)
@@ -4,8 +4,7 @@ IN: io.streams.duplex
 ARTICLE: "io.streams.duplex" "Duplex streams"
 "Duplex streams combine an input stream and an output stream into a bidirectional stream."
 { $subsection duplex-stream }
-{ $subsection <duplex-stream> }
-{ $subsection check-closed } ;
+{ $subsection <duplex-stream> } ;
 
 ABOUT: "io.streams.duplex"
 
@@ -16,7 +15,5 @@ HELP: <duplex-stream>
 { $values { "in" "an input stream" } { "out" "an output stream" } { "stream" " a duplex stream" } }
 { $description "Creates a duplex stream. Writing to a duplex stream will write to " { $snippet "out" } ", and reading from a duplex stream will read from " { $snippet "in" } ". Closing a duplex stream closes both the input and output streams." } ;
 
-HELP: check-closed
-{ $values { "stream" "a duplex stream" } }
-{ $description "Throws a " { $link check-closed } " error if the stream has already been closed." }
+HELP: stream-closed-twice
 { $error-description "This error is thrown when performing an I/O operation on a " { $link duplex-stream } " which has been closed with " { $link dispose } "." } ;
index 65bad3de4103e8cee1a9a1aaf64496fd854d9198..ebc6b3be1f2f0464b0644d8dbf5515726b5ba900 100755 (executable)
@@ -4,7 +4,7 @@ IN: io.streams.duplex.tests
 ! Test duplex stream close behavior
 TUPLE: closing-stream closed? ;
 
-: <closing-stream> closing-stream construct-empty ;
+: <closing-stream> closing-stream new ;
 
 M: closing-stream dispose
     dup closing-stream-closed? [
@@ -15,7 +15,7 @@ M: closing-stream dispose
 
 TUPLE: unclosable-stream ;
 
-: <unclosable-stream> unclosable-stream construct-empty ;
+: <unclosable-stream> unclosable-stream new ;
 
 M: unclosable-stream dispose
     "Can't close me!" throw ;
index 83e991b7131e9427e0bf6c74664b88f0851e1811..40f0cb6e73881e77e9164f9f6720107659dd185c 100755 (executable)
@@ -1,75 +1,77 @@
-! Copyright (C) 2005 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
+USING: kernel continuations io accessors ;
 IN: io.streams.duplex
-USING: kernel continuations io ;
 
 ! We ensure that the stream can only be closed once, to preserve
 ! integrity of duplex I/O ports.
 
-TUPLE: duplex-stream in out closed? ;
+TUPLE: duplex-stream in out closed ;
 
 : <duplex-stream> ( in out -- stream )
-    f duplex-stream construct-boa ;
+    f duplex-stream boa ;
 
 ERROR: stream-closed-twice ;
 
-: check-closed ( stream -- )
-    duplex-stream-closed? [ stream-closed-twice ] when ;
+<PRIVATE
 
-: duplex-stream-in+ ( duplex -- stream )
-    dup check-closed duplex-stream-in ;
+: check-closed ( stream -- stream )
+    dup closed>> [ stream-closed-twice ] when ; inline
 
-: duplex-stream-out+ ( duplex -- stream )
-    dup check-closed duplex-stream-out ;
+: in ( duplex -- stream ) check-closed in>> ;
+
+: out ( duplex -- stream ) check-closed out>> ;
+
+PRIVATE>
 
 M: duplex-stream stream-flush
-    duplex-stream-out+ stream-flush ;
+    out stream-flush ;
 
 M: duplex-stream stream-readln
-    duplex-stream-in+ stream-readln ;
+    in stream-readln ;
 
 M: duplex-stream stream-read1
-    duplex-stream-in+ stream-read1 ;
+    in stream-read1 ;
 
 M: duplex-stream stream-read-until
-    duplex-stream-in+ stream-read-until ;
+    in stream-read-until ;
 
 M: duplex-stream stream-read-partial
-    duplex-stream-in+ stream-read-partial ;
+    in stream-read-partial ;
 
 M: duplex-stream stream-read
-    duplex-stream-in+ stream-read ;
+    in stream-read ;
 
 M: duplex-stream stream-write1
-    duplex-stream-out+ stream-write1 ;
+    out stream-write1 ;
 
 M: duplex-stream stream-write
-    duplex-stream-out+ stream-write ;
+    out stream-write ;
 
 M: duplex-stream stream-nl
-    duplex-stream-out+ stream-nl ;
+    out stream-nl ;
 
 M: duplex-stream stream-format
-    duplex-stream-out+ stream-format ;
+    out stream-format ;
 
 M: duplex-stream make-span-stream
-    duplex-stream-out+ make-span-stream ;
+    out make-span-stream ;
 
 M: duplex-stream make-block-stream
-    duplex-stream-out+ make-block-stream ;
+    out make-block-stream ;
 
 M: duplex-stream make-cell-stream
-    duplex-stream-out+ make-cell-stream ;
+    out make-cell-stream ;
 
 M: duplex-stream stream-write-table
-    duplex-stream-out+ stream-write-table ;
+    out stream-write-table ;
 
 M: duplex-stream dispose
     #! The output stream is closed first, in case both streams
     #! are attached to the same file descriptor, the output
     #! buffer needs to be flushed before we close the fd.
-    dup duplex-stream-closed? [
-        t over set-duplex-stream-closed?
-        [ dup duplex-stream-out dispose ]
-        [ dup duplex-stream-in dispose ] [ ] cleanup
+    dup closed>> [
+        t >>closed
+        [ dup out>> dispose ]
+        [ dup in>> dispose ] [ ] cleanup
     ] unless drop ;
index 6b8953f86ede8b0eaa18bfc21c4b1441f816688e..fd67910b6fb6fcfe4f35456885ade7edf7aafe33 100755 (executable)
@@ -45,7 +45,7 @@ C: <ignore-close-stream> ignore-close-stream
 TUPLE: style-stream < filter-writer style ;
 
 : do-nested-style ( style style-stream -- style stream )
-    [ style>> swap union ] [ stream>> ] bi ; inline
+    [ style>> swap assoc-union ] [ stream>> ] bi ; inline
 
 C: <style-stream> style-stream
 
index b54d0a7879a8abfe7140a9eaf1bcd6c916d199ee..95f0d60720fb124d1209f8a8328346f45e061102 100755 (executable)
@@ -142,10 +142,10 @@ M: object clone ;
 M: callstack clone (clone) ;
 
 ! Tuple construction
-: construct-empty ( class -- tuple )
+: new ( class -- tuple )
     tuple-layout <tuple> ;
 
-: construct-boa ( ... class -- tuple )
+: boa ( ... class -- tuple )
     tuple-layout <tuple-boa> ;
 
 ! Quotation building
@@ -203,7 +203,7 @@ GENERIC# get-slots 1 ( tuple slots -- ... )
 GENERIC# set-slots 1 ( ... tuple slots -- )
 
 : construct ( ... slots class -- tuple )
-    construct-empty [ swap set-slots ] keep ; inline
+    new [ swap set-slots ] keep ; inline
 
 : construct-delegate ( delegate class -- tuple )
     >r { set-delegate } r> construct ; inline
index cc51060f634b9d1436091a76ff59aab854d5c565..4ca1a8637c2eb3fe33b60e9b4ad0106f42151819 100755 (executable)
@@ -103,7 +103,7 @@ C: <interval> interval
             2drop over second over second and
             [ <interval> ] [ 2drop f ] if
         ] }
-        { [ t ] [ 2drop <interval> ] }
+        [ 2drop <interval> ]
     } cond ;
 
 : interval-intersect ( i1 i2 -- i3 )
@@ -202,7 +202,7 @@ SYMBOL: incomparable
         { [ 2dup interval-intersect not ] [ (interval<) ] }
         { [ 2dup left-endpoint-< ] [ f ] }
         { [ 2dup right-endpoint-< ] [ f ] }
-        { [ t ] [ incomparable ] }
+        [ incomparable ]
     } cond 2nip ;
 
 : left-endpoint-<= ( i1 i2 -- ? )
@@ -215,7 +215,7 @@ SYMBOL: incomparable
     {
         { [ 2dup interval-intersect not ] [ (interval<) ] }
         { [ 2dup right-endpoint-<= ] [ t ] }
-        { [ t ] [ incomparable ] }
+        [ incomparable ]
     } cond 2nip ;
 
 : interval> ( i1 i2 -- ? )
index cd908ea10fd5d9105e96707d4d429e65927fbecc..064b488ac30ed9df3d536059e881df0cdbfc0396 100755 (executable)
@@ -62,6 +62,8 @@ M: object zero? drop f ;
 : neg ( x -- -x ) 0 swap - ; foldable
 : recip ( x -- y ) 1 swap / ; foldable
 
+: ?1+ [ 1+ ] [ 0 ] if* ; inline
+
 : /f  ( x y -- z ) >r >float r> >float float/f ; inline
 
 : max ( x y -- z ) [ > ] most ; foldable
index 68c4768c871acff256b2f7b7e1a261a0874c8cbc..1a1a080564ab1637cbd92e13fde0e0069631ed62 100755 (executable)
@@ -62,7 +62,7 @@ SYMBOL: negative?
     {
         { [ dup empty? ] [ drop f ] }
         { [ f over memq? ] [ drop f ] }
-        { [ t ] [ radix get [ < ] curry all? ] }
+        [ radix get [ < ] curry all? ]
     } cond ;
 
 : string>integer ( str -- n/f )
@@ -77,7 +77,7 @@ PRIVATE>
         {
             { [ CHAR: / over member? ] [ string>ratio ] }
             { [ CHAR: . over member? ] [ string>float ] }
-            { [ t ] [ string>integer ] }
+            [ string>integer ]
         } cond
         r> [ dup [ neg ] when ] when
     ] with-radix ;
@@ -134,10 +134,8 @@ M: ratio >base
         } {
             [ CHAR: . over member? ]
             [ ]
-        } {
-            [ t ]
-            [ ".0" append ]
         }
+        [ ".0" append ]
     } cond ;
 
 M: float >base
@@ -145,7 +143,7 @@ M: float >base
         { [ dup 1.0/0.0 = ] [ drop "1.0/0.0" ] }
         { [ dup -1.0/0.0 = ] [ drop "-1.0/0.0" ] }
         { [ dup fp-nan? ] [ drop "0.0/0.0" ] }
-        { [ t ] [ float>string fix-float ] }
+        [ float>string fix-float ]
     } cond ;
 
 : number>string ( n -- str ) 10 >base ;
index 61cdbdad24ffefd20686762038c2a4ae455139d6..02afaf07fc65dc80fe0f41b1eeba3022c41d3c5e 100755 (executable)
@@ -14,7 +14,7 @@ IN: mirrors
 TUPLE: mirror object slots ;
 
 : <mirror> ( object -- mirror )
-    dup object-slots mirror construct-boa ;
+    dup object-slots mirror boa ;
 
 : >mirror< ( mirror -- obj slots )
     dup mirror-object swap mirror-slots ;
index e6b7533756b4d53d9aeeb59975497c43dc67628f..3237f095bf3b3cbf5ae87be6c737a74d40ad741d 100755 (executable)
@@ -17,7 +17,7 @@ SYMBOL: optimizer-changed
 GENERIC: optimize-node* ( node -- node/t changed? )
 
 : ?union ( assoc/f assoc -- hash )
-    over [ union ] [ nip ] if ;
+    over [ assoc-union ] [ nip ] if ;
 
 : add-node-literals ( assoc node -- )
     over assoc-empty? [
@@ -82,7 +82,7 @@ M: node optimize-node* drop t f ;
     2dup at* [ swap follow nip ] [ 2drop ] if ;
 
 : union* ( assoc1 assoc2 -- assoc )
-    union [ keys ] keep
+    assoc-union [ keys ] keep
     [ dupd follow ] curry
     H{ } map>assoc ;
 
index d7638fa66dee93a703f2046c979d25e8034fc96c..ce77cdd43a77d8094263becf6ff4aa53c7fdb9b9 100755 (executable)
@@ -9,23 +9,23 @@ optimizer ;
             { [ over #label? not ] [ 2drop f ] }
             { [ over #label-word over eq? not ] [ 2drop f ] }
             { [ over #label-loop? not ] [ 2drop f ] }
-            { [ t ] [ 2drop t ] }
+            [ 2drop t ]
         } cond
     ] curry node-exists? ;
 
 : label-is-not-loop? ( node word -- ? )
     [
         {
-            { [ over #label? not ] [ 2drop f ] }
-            { [ over #label-word over eq? not ] [ 2drop f ] }
-            { [ over #label-loop? ] [ 2drop f ] }
-            { [ t ] [ 2drop t ] }
-        } cond
+            { [ over #label? not ] [ f ] }
+            { [ over #label-word over eq? not ] [ f ] }
+            { [ over #label-loop? ] [ f ] }
+            [ t ]
+        } cond 2nip
     ] curry node-exists? ;
 
 : loop-test-1 ( a -- )
     dup [ 1+ loop-test-1 ] [ drop ] if ; inline
-
+                          
 [ t ] [
     [ loop-test-1 ] dataflow dup detect-loops
     \ loop-test-1 label-is-loop?
index 11228c879a5795d46863415223caf51c925bd4d8..f9f8901c41f6673b2d953939ed2efbb2dd9c6e9f 100755 (executable)
@@ -156,7 +156,7 @@ SYMBOL: potential-loops
             { [ dup null class< ] [ drop f f ] }
             { [ dup \ f class-not class< ] [ drop t t ] }
             { [ dup \ f class< ] [ drop f t ] }
-            { [ t ] [ drop f f ] }
+            [ drop f f ]
         } cond
     ] if ;
 
index 9d41d6eae1ef1e1975391b61848cda8af22d36f8..8447d1be5fe0bc1126ddbbaf8f30d870ba8847e5 100755 (executable)
@@ -36,7 +36,7 @@ DEFER: (flat-length)
         ! not inline
         { [ dup inline? not ] [ drop 1 ] }
         ! inline
-        { [ t ] [ dup dup set word-def (flat-length) ] }
+        [ dup dup set word-def (flat-length) ]
     } cond ;
 
 : (flat-length) ( seq -- n )
@@ -45,7 +45,7 @@ DEFER: (flat-length)
             { [ dup quotation? ] [ (flat-length) 1+ ] }
             { [ dup array? ] [ (flat-length) ] }
             { [ dup word? ] [ word-flat-length ] }
-            { [ t ] [ drop 1 ] }
+            [ drop 1 ]
         } cond
     ] map sum ;
 
@@ -94,7 +94,7 @@ DEFER: (flat-length)
     dup node-param {
         { [ dup standard-generic? ] [ inline-standard-method ] }
         { [ dup math-generic? ] [ inline-math-method ] }
-        { [ t ] [ 2drop t ] }
+        [ 2drop t ]
     } cond ;
 
 ! Resolve type checks at compile time where possible
@@ -217,5 +217,5 @@ M: #call optimize-node*
         { [ dup optimize-predicate? ] [ optimize-predicate ] }
         { [ dup optimistic-inline? ] [ optimistic-inline ] }
         { [ dup method-body-inline? ] [ optimistic-inline ] }
-        { [ t ] [ inline-method ] }
+        [ inline-method ]
     } cond dup not ;
index 2bce2dc94c8fc52105ef8a844097aee8b6f9901c..cf71af216ef2633728c979d1b739a3919bc4657d 100755 (executable)
@@ -19,7 +19,7 @@ sequences.private combinators ;
     ] "output-classes" set-word-prop
 ] each
 
-\ construct-empty [
+\ new [
     dup node-in-d peek node-literal
     dup class? [ drop tuple ] unless 1array f
 ] "output-classes" set-word-prop
index c8d7a0a0a05e1eb1da82fc75d6dfb7925bc86e0a..1a48e353a2aa4fc5e1ced8601758eae2c8507a7c 100755 (executable)
@@ -283,7 +283,7 @@ TUPLE: silly-tuple a b ;
 
 [ t ] [ \ node-successor-f-bug compiled? ] unit-test
 
-[ ] [ [ construct-empty ] dataflow optimize drop ] unit-test
+[ ] [ [ new ] dataflow optimize drop ] unit-test
 
 [ ] [ [ <tuple> ] dataflow optimize drop ] unit-test
 
index 0e7e80193855fb0659d820484cf04337bc256b47..5beb2555f0412fe52697036a882c41d38a87f28d 100755 (executable)
@@ -19,7 +19,7 @@ SYMBOL: @
         { [ dup @ eq? ] [ drop match-@ ] }
         { [ dup class? ] [ match-class ] }
         { [ over value? not ] [ 2drop f ] }
-        { [ t ] [ swap value-literal = ] }
+        [ swap value-literal = ]
     } cond ;
 
 : node-match? ( node values pattern -- ? )
index d115d0a1c6d8dd9064713fb5c1ebe3d1ac1d2cc7..b33a9e8fc27440a19553063209fc8ac06ea4a138 100755 (executable)
@@ -57,7 +57,7 @@ IN: optimizer.specializers
             [ dup "specializer" word-prop ]\r
             [ "specializer" word-prop specialize-quot ]\r
         }\r
-        { [ t ] [ drop ] }\r
+        [ drop ]\r
     } cond ;\r
 \r
 : specialized-length ( specializer -- n )\r
index e7984f7ec3e05156f50a2792867d912f7d0e6190..23363c30ad13cf588d8c9ec88ad9189d55a725a1 100755 (executable)
@@ -358,6 +358,18 @@ HELP: scan-word
 { $errors "Throws an error if the token does not name a word, and does not parse as a number." }
 $parsing-note ;
 
+HELP: invalid-slot-name
+{ $values { "name" string } }
+{ $description "Throws an " { $link invalid-slot-name } " error." }
+{ $error-description "Thrown by " { $link POSTPONE: TUPLE: } " and " { $link POSTPONE: ERROR: } " if a suspect token appears as a slot name." }
+{ $notes "The suspect tokens are chosen so that the following code raises this parse error, instead of silently greating a tuple with garbage slots:"
+    { $code
+        "TUPLE: my-mistaken-tuple slot-a slot-b"
+        ""
+        ": some-word ( a b c -- ) ... ;"
+    }
+} ;
+
 HELP: unexpected
 { $values { "want" "a " { $link word } " or " { $link f } } { "got" word } }
 { $description "Throws an " { $link unexpected } " error." }
index 6c09e08f848aa82f27dbbc2e0a78d754439c4b38..7639ebaa692a619982dd1aed217217952b8d0913 100755 (executable)
@@ -5,7 +5,7 @@ prettyprint sequences strings vectors words quotations inspector
 io.styles io combinators sorting splitting math.parser effects
 continuations debugger io.files io.streams.string vocabs
 io.encodings.utf8 source-files classes classes.tuple hashtables
-compiler.errors compiler.units accessors ;
+compiler.errors compiler.units accessors sets ;
 IN: parser
 
 TUPLE: lexer text line line-text line-length column ;
@@ -17,9 +17,14 @@ TUPLE: lexer text line line-text line-length column ;
     0 >>column
     drop ;
 
+: new-lexer ( text class -- lexer )
+    new
+        0 >>line
+        swap >>text
+    dup next-line ; inline
+
 : <lexer> ( text -- lexer )
-    0 { set-lexer-text set-lexer-line } lexer construct
-    dup next-line ;
+    lexer new-lexer ;
 
 : location ( -- loc )
     file get lexer get lexer-line 2dup and
@@ -159,7 +164,7 @@ name>char-hook global [
 TUPLE: parse-error file line column line-text error ;
 
 : <parse-error> ( msg -- error )
-    \ parse-error construct-empty
+    \ parse-error new
         file get >>file
         lexer get line>> >>line
         lexer get column>> >>column
@@ -184,6 +189,9 @@ M: parse-error summary
 M: parse-error compute-restarts
     error>> compute-restarts ;
 
+M: parse-error error-help
+    error>> error-help ;
+
 SYMBOL: use
 SYMBOL: in
 
@@ -253,7 +261,7 @@ M: no-word-error summary
     drop "Word not found in current vocabulary search path" ;
 
 : no-word ( name -- newword )
-    dup no-word-error construct-boa
+    dup no-word-error boa
     swap words-named [ forward-reference? not ] subset
     word-restarts throw-restarts
     dup word-vocabulary (use+) ;
@@ -285,7 +293,7 @@ M: no-word-error summary
     scan-word bootstrap-word scan-word create-method-in ;
 
 : shadowed-slots ( superclass slots -- shadowed )
-    >r all-slot-names r> seq-intersect ;
+    >r all-slot-names r> intersect ;
 
 : check-slot-shadowing ( class superclass slots -- )
     shadowed-slots [
@@ -298,12 +306,35 @@ M: no-word-error summary
         ] "" make note.
     ] with each ;
 
+ERROR: invalid-slot-name name ;
+
+M: invalid-slot-name summary
+    drop
+    "Invalid slot name" ;
+
+: (parse-tuple-slots) ( -- )
+    #! This isn't meant to enforce any kind of policy, just
+    #! to check for mistakes of this form:
+    #!
+    #! TUPLE: blahblah foo bing
+    #!
+    #! : ...
+    scan {
+        { [ dup not ] [ unexpected-eof ] }
+        { [ dup { ":" "(" "<" } member? ] [ invalid-slot-name ] }
+        { [ dup ";" = ] [ drop ] }
+        [ , (parse-tuple-slots) ]
+    } cond ;
+
+: parse-tuple-slots ( -- seq )
+    [ (parse-tuple-slots) ] { } make ;
+
 : parse-tuple-definition ( -- class superclass slots )
     CREATE-CLASS
     scan {
         { ";" [ tuple f ] }
-        { "<" [ scan-word ";" parse-tokens ] }
-        [ >r tuple ";" parse-tokens r> prefix ]
+        { "<" [ scan-word parse-tuple-slots ] }
+        [ >r tuple parse-tuple-slots r> prefix ]
     } case 3dup check-slot-shadowing ;
 
 ERROR: staging-violation word ;
@@ -324,7 +355,7 @@ M: staging-violation summary
         { [ dup not ] [ drop unexpected-eof t ] }
         { [ dup delimiter? ] [ unexpected t ] }
         { [ dup parsing? ] [ nip execute-parsing t ] }
-        { [ t ] [ pick push drop t ] }
+        [ pick push drop t ]
     } cond ;
 
 : (parse-until) ( accum end -- accum )
@@ -475,14 +506,14 @@ SYMBOL: interactive-vocabs
     ] if ;
 
 : filter-moved ( assoc1 assoc2 -- seq )
-    diff [
+    assoc-diff [
         drop where dup [ first ] when
         file get source-file-path =
     ] assoc-subset keys ;
 
 : removed-definitions ( -- assoc1 assoc2 )
     new-definitions old-definitions
-    [ get first2 union ] bi@ ;
+    [ get first2 assoc-union ] bi@ ;
 
 : removed-classes ( -- assoc1 assoc2 )
     new-definitions old-definitions
index 2b294115beb6cce230d735065ecb16152efb7263..7cc141be22290947a762e5fe358654a23f95b874 100755 (executable)
@@ -60,8 +60,8 @@ $nl
 { $subsection short-section }
 { $subsection long-section }
 "Utilities to use when implementing sections:"
-{ $subsection construct-section }
-{ $subsection construct-block }
+{ $subsection new-section }
+{ $subsection new-block }
 { $subsection add-section } ;
 
 ARTICLE: "prettyprint-sections" "Prettyprinter sections"
index 03d3e456cac3c0312eb6fdb25d06de7ab45b498f..525749cfae148e09b3beb7b026d0ccfe934fd3fa 100755 (executable)
@@ -7,7 +7,8 @@ vectors words prettyprint.backend prettyprint.sections
 prettyprint.config sorting splitting math.parser vocabs
 definitions effects classes.builtin classes.tuple io.files
 classes continuations hashtables classes.mixin classes.union
-classes.predicate classes.singleton combinators quotations ;
+classes.predicate classes.singleton combinators quotations
+sets ;
 
 : make-pprint ( obj quot -- block in use )
     [
@@ -107,7 +108,7 @@ SYMBOL: ->
                 { [ dup word? not ] [ , ] }
                 { [ dup "break?" word-prop ] [ drop ] }
                 { [ dup "step-into?" word-prop ] [ remove-step-into ] }
-                { [ t ] [ , ] }
+                [ , ]
             } cond
         ] each
     ] [ ] make ;
index bb1752b72ef73c7a43e2c7aad0c889d52c01f0d8..ceb37c2fe40ea5a59ef5862b372c14e3cdc17c68 100755 (executable)
@@ -78,7 +78,7 @@ HELP: section
     { { $snippet "overhang" } " - number of columns which must be left blank before the wrap margin for the prettyprinter to consider emitting this section as a " { $link short-section } ". Avoids lone hanging closing brackets" }
 } } ;
 
-HELP: construct-section
+HELP: new-section
 { $values { "length" integer } { "class" "a subclass of " { $link section } } { "section" section } }
 { $description "Creates a new section with the given length starting from " { $link position } ", advancing " { $link position } "." } ;
 
index 848947e624da55321f2baed19d920243fb3c7a19..319e5eab658e93675a231a8bd97e6028b3110b3f 100644 (file)
@@ -17,7 +17,7 @@ SYMBOL: pprinter-use
 
 TUPLE: pprinter last-newline line-count end-printing indent ;
 
-: <pprinter> ( -- pprinter ) 0 1 f 0 pprinter construct-boa ;
+: <pprinter> ( -- pprinter ) 0 1 f 0 pprinter boa ;
 
 : record-vocab ( word -- )
     word-vocabulary [ dup pprinter-use get set-at ] when* ;
@@ -71,8 +71,8 @@ start end
 start-group? end-group?
 style overhang ;
 
-: construct-section ( length class -- section )
-    construct-empty
+: new-section ( length class -- section )
+    new
         position get >>start
         swap position [ + ] change
         position get >>end
@@ -127,7 +127,7 @@ M: object short-section? section-fits? ;
 TUPLE: line-break < section type ;
 
 : <line-break> ( type -- section )
-    0 \ line-break construct-section
+    0 \ line-break new-section
         swap >>type ;
 
 M: line-break short-section drop ;
@@ -137,13 +137,13 @@ M: line-break long-section drop ;
 ! Block sections
 TUPLE: block < section sections ;
 
-: construct-block ( style class -- block )
-    0 swap construct-section
+: new-block ( style class -- block )
+    0 swap new-section
         V{ } clone >>sections
         swap >>style ; inline
 
 : <block> ( style -- block )
-    block construct-block ;
+    block new-block ;
 
 : pprinter-block ( -- block ) pprinter-stack get peek ;
 
@@ -200,7 +200,7 @@ M: block short-section ( block -- )
 TUPLE: text < section string ;
 
 : <text> ( string style -- text )
-    over length 1+ \ text construct-section
+    over length 1+ \ text new-section
         swap >>style
         swap >>string ;
 
@@ -216,7 +216,7 @@ M: text long-section short-section ;
 TUPLE: inset < block narrow? ;
 
 : <inset> ( narrow? -- block )
-    H{ } inset construct-block
+    H{ } inset new-block
         2 >>overhang
         swap >>narrow? ;
 
@@ -237,7 +237,7 @@ M: inset newline-after? drop t ;
 TUPLE: flow < block ;
 
 : <flow> ( -- block )
-    H{ } flow construct-block ;
+    H{ } flow new-block ;
 
 M: flow short-section? ( section -- ? )
     #! If we can make room for this entire block by inserting
@@ -253,7 +253,7 @@ M: flow short-section? ( section -- ? )
 TUPLE: colon < block ;
 
 : <colon> ( -- block )
-    H{ } colon construct-block ;
+    H{ } colon new-block ;
 
 M: colon long-section short-section ;
 
index b30812b06ff710094ec7c4a93416fc52c1614f51..ac3f565e5678784473968c1b752eedb3780a5cec 100644 (file)
@@ -19,6 +19,6 @@ IN: sbufs.tests
 
 [ SBUF" x" ] [ 1 <sbuf> CHAR: x >bignum over push ] unit-test
 
-[ fixnum ] [ 1 >bignum SBUF" " new length class ] unit-test
+[ fixnum ] [ 1 >bignum SBUF" " new-sequence length class ] unit-test
 
 [ fixnum ] [ 1 >bignum [ ] SBUF" " map-as length class ] unit-test
index 9de57c0801b21ed034bccb8676e32c3b5571efe4..f2f45b99c9565ab7ce653aca8c789b6c67245c9a 100755 (executable)
@@ -7,7 +7,7 @@ IN: sbufs
 <PRIVATE
 
 : string>sbuf ( string length -- sbuf )
-    sbuf construct-boa ; inline
+    sbuf boa ; inline
 
 PRIVATE>
 
@@ -16,7 +16,7 @@ PRIVATE>
 M: sbuf set-nth-unsafe
     underlying >r >r >fixnum r> >fixnum r> set-string-nth ;
 
-M: sbuf new drop [ 0 <string> ] keep >fixnum string>sbuf ;
+M: sbuf new-sequence drop [ 0 <string> ] keep >fixnum string>sbuf ;
 
 : >sbuf ( seq -- sbuf ) SBUF" " clone-like ; inline
 
index f5e5bfcdb3eaf346dd24a203f4f12dac673b5963..bb3dc9337e84317e351273e7e6668c84e0d39d66 100755 (executable)
@@ -33,7 +33,7 @@ ARTICLE: "sequence-protocol" "Sequence protocol"
 "An optional generic word for creating sequences of the same class as a given sequence:"
 { $subsection like }
 "Optional generic words for optimization purposes:"
-{ $subsection new }
+{ $subsection new-sequence }
 { $subsection new-resizable }
 { $see-also "sequences-unsafe" } ;
 
@@ -64,8 +64,7 @@ ARTICLE: "sequences-add-remove" "Adding and removing sequence elements"
 { $subsection prefix }
 { $subsection suffix }
 "Removing elements:"
-{ $subsection remove }
-{ $subsection seq-diff } ;
+{ $subsection remove } ;
 
 ARTICLE: "sequences-reshape" "Reshaping sequences"
 "A " { $emphasis "repetition" } " is a virtual sequence consisting of a single element repeated multiple times:"
@@ -233,6 +232,8 @@ $nl
 { $subsection "sequences-split" }
 { $subsection "sequences-destructive" }
 { $subsection "sequences-stacks" }
+{ $subsection "sequences-sorting" }
+{ $subsection "sets" }
 "For inner loops:"
 { $subsection "sequences-unsafe" } ;
 
@@ -280,7 +281,7 @@ HELP: immutable
 { $description "Throws an " { $link immutable } " error." }
 { $error-description "Thrown if an attempt is made to modify an immutable sequence." } ;
 
-HELP: new
+HELP: new-sequence
 { $values { "len" "a non-negative integer" } { "seq" sequence } { "newseq" "a mutable sequence" } }
 { $contract "Outputs a mutable sequence of length " { $snippet "n" } " which can hold the elements of " { $snippet "seq" } "." } ;
 
@@ -527,12 +528,7 @@ HELP: contains?
 
 HELP: all?
 { $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt -- ? )" } } { "?" "a boolean" } }
-{ $description "Tests if all elements in the sequence satisfy the predicate by checking each element in turn. Given an empty sequence, vacuously outputs " { $link t } "." }
-{ $notes
-    "The implementation makes use of a well-known logical identity:" 
-    $nl
-    { $snippet "P[x] for all x <==> not ((not P[x]) for some x)" }
-} ;
+{ $description "Tests if all elements in the sequence satisfy the predicate by checking each element in turn. Given an empty sequence, vacuously outputs " { $link t } "." } ;
 
 HELP: push-if
 { $values { "elt" object } { "quot" "a quotation with stack effect " { $snippet "( elt -- ? )" } } { "accum" "a resizable mutable sequence" } }
@@ -659,10 +655,6 @@ HELP: prefix
 { $example "USING: prettyprint sequences ;" "{ 1 2 3 } 0 prefix ." "{ 0 1 2 3 }" }
 } ;
 
-HELP: seq-diff
-{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } }
-{ $description "Outputs a sequence consisting of elements present in " { $snippet "seq2" } " but not " { $snippet "seq1" } ", comparing elements for equality." } ;
-
 HELP: sum-lengths
 { $values { "seq" "a sequence of sequences" } { "n" integer } }
 { $description "Outputs the sum of the lengths of all sequences in " { $snippet "seq" } "." } ;
index 281b27d540665992e0d3c3442d6476628ecb921c..e8db18b3d03872beb3ba6e5ff6cf18683e0cff68 100755 (executable)
@@ -240,8 +240,8 @@ unit-test
 
 [ ?{ f t } ] [ 0 2 ?{ f t f } subseq ] unit-test
 
-[ V{ f f f } ] [ 3 V{ } new ] unit-test
-[ SBUF" \0\0\0" ] [ 3 SBUF" " new ] unit-test
+[ V{ f f f } ] [ 3 V{ } new-sequence ] unit-test
+[ SBUF" \0\0\0" ] [ 3 SBUF" " new-sequence ] unit-test
 
 [ 0 ] [ f length ] unit-test
 [ f first ] must-fail
index 996aba8e6e1a6ae2bafac9992b62ba2e5e3f710e..252df543912ff901986da371bc02d48ea0b965d4 100755 (executable)
@@ -9,13 +9,13 @@ GENERIC: length ( seq -- n ) flushable
 GENERIC: set-length ( n seq -- )
 GENERIC: nth ( n seq -- elt ) flushable
 GENERIC: set-nth ( elt n seq -- )
-GENERIC: new ( len seq -- newseq ) flushable
+GENERIC: new-sequence ( len seq -- newseq ) flushable
 GENERIC: new-resizable ( len seq -- newseq ) flushable
 GENERIC: like ( seq exemplar -- newseq ) flushable
 GENERIC: clone-like ( seq exemplar -- newseq ) flushable
 
 : new-like ( len exemplar quot -- seq )
-    over >r >r new r> call r> like ; inline
+    over >r >r new-sequence r> call r> like ; inline
 
 M: sequence like drop ;
 
@@ -162,7 +162,7 @@ M: virtual-sequence set-nth virtual@ set-nth ;
 M: virtual-sequence nth-unsafe virtual@ nth-unsafe ;
 M: virtual-sequence set-nth-unsafe virtual@ set-nth-unsafe ;
 M: virtual-sequence like virtual-seq like ;
-M: virtual-sequence new virtual-seq new ;
+M: virtual-sequence new-sequence virtual-seq new-sequence ;
 
 INSTANCE: virtual-sequence sequence
 
@@ -197,7 +197,7 @@ ERROR: slice-error reason ;
 : <slice> ( from to seq -- slice )
     dup slice? [ collapse-slice ] when
     check-slice
-    slice construct-boa ; inline
+    slice boa ; inline
 
 M: slice virtual-seq slice-seq ;
 
@@ -250,7 +250,7 @@ INSTANCE: repetition immutable-sequence
     dup 0 <= [ 2drop 2drop ] [ 1- ((copy)) (copy) ] if ; inline
 
 : prepare-subseq ( from to seq -- dst i src j n )
-    [ >r swap - r> new dup 0 ] 3keep
+    [ >r swap - r> new-sequence dup 0 ] 3keep
     -rot drop roll length ; inline
 
 : check-copy ( src n dst -- )
@@ -275,7 +275,7 @@ PRIVATE>
     (copy) drop ; inline
 
 M: sequence clone-like
-    >r dup length r> new [ 0 swap copy ] keep ;
+    >r dup length r> new-sequence [ 0 swap copy ] keep ;
 
 M: immutable-sequence clone-like like ;
 
@@ -444,9 +444,6 @@ PRIVATE>
 : memq? ( obj seq -- ? )
     [ eq? ] with contains? ;
 
-: seq-intersect ( seq1 seq2 -- seq1/\seq2 )
-    swap [ member? ] curry subset ;
-
 : remove ( obj seq -- newseq )
     [ = not ] with subset ;
 
@@ -512,9 +509,6 @@ M: slice equal? over slice? [ sequence= ] [ 2drop f ] if ;
         [ 0 swap copy ] keep
     ] new-like ;
 
-: seq-diff ( seq1 seq2 -- newseq )
-    swap [ member? not ] curry subset ;
-
 : peek ( seq -- elt ) dup length 1- swap nth ;
 
 : pop* ( seq -- ) dup length 1- swap set-length ;
diff --git a/core/sets/authors.txt b/core/sets/authors.txt
new file mode 100644 (file)
index 0000000..f372b57
--- /dev/null
@@ -0,0 +1,2 @@
+Slava Pestov
+Doug Coleman
diff --git a/core/sets/sets-docs.factor b/core/sets/sets-docs.factor
new file mode 100644 (file)
index 0000000..8b68592
--- /dev/null
@@ -0,0 +1,61 @@
+USING: kernel help.markup help.syntax sequences ;
+IN: sets
+
+ARTICLE: "sets" "Set-theoretic operations on sequences"
+"Set-theoretic operations on sequences are defined on the " { $vocab-link "sets" } " vocabulary. These operations use hashtables internally to achieve linear running time."
+$nl
+"Remove duplicates:"
+{ $subsection prune }
+"Test for duplicates:"
+{ $subsection all-unique? }
+"Set operations on sequences:"
+{ $subsection diff }
+{ $subsection intersect }
+{ $subsection union }
+{ $see-also member? memq? contains? all? "assocs-sets" } ;
+
+HELP: unique
+{ $values { "seq" "a sequence" } { "assoc" "an assoc" } }
+{ $description "Outputs a new assoc where the keys and values are equal." }
+{ $examples
+    { $example "USING: sets prettyprint ;" "{ 1 1 2 2 3 3 } unique ." "H{ { 1 1 } { 2 2 } { 3 3 } }" }
+} ;
+
+HELP: prune
+{ $values { "seq" "a sequence" } { "newseq" "a sequence" } }
+{ $description "Outputs a new sequence with each distinct element of " { $snippet "seq" } " appearing only once. Elements are compared for equality using " { $link = } " and elements are ordered according to their position in " { $snippet "seq" } "." }
+{ $examples
+    { $example "USING: sets prettyprint ;" "{ 1 1 t 3 t } prune ." "V{ 1 t 3 }" }
+} ;
+
+HELP: all-unique?
+{ $values { "seq" sequence } { "?" "a boolean" } }
+{ $description "Tests whether a sequence contains any repeated elements." }
+{ $example
+    "USING: sets prettyprint ;"
+    "{ 0 1 1 2 3 5 } all-unique? ."
+    "f"
+} ;
+
+HELP: diff
+{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } }
+{ $description "Outputs a sequence consisting of elements present in " { $snippet "seq2" } " but not " { $snippet "seq1" } ", comparing elements for equality." 
+} { $examples
+    { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } diff ." "{ 4 }" }
+} ;
+
+HELP: intersect
+{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } }
+{ $description "Outputs a sequence consisting of elements present in both " { $snippet "seq1" } " and " { $snippet "seq2" } "." }
+{ $examples
+    { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } intersect ." "{ 2 3 }" }
+} ;
+
+HELP: union
+{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" sequence } }
+{ $description "Outputs a sequence consisting of elements present in " { $snippet "seq1" } " and " { $snippet "seq2" } " which does not contain duplicate values." }
+{ $examples
+    { $example "USING: sets prettyprint ;" "{ 1 2 3 } { 2 3 4 } union ." "V{ 1 2 3 4 }" }
+} ;
+
+{ diff intersect union } related-words
diff --git a/core/sets/sets-tests.factor b/core/sets/sets-tests.factor
new file mode 100644 (file)
index 0000000..4f8c8cd
--- /dev/null
@@ -0,0 +1,17 @@
+USING: kernel sets tools.test ;
+IN: sets.tests
+
+[ f ] [ { 0 1 1 2 3 5 } all-unique? ] unit-test
+[ t ] [ { 0 1 2 3 4 5 } all-unique? ] unit-test
+
+[ V{ 1 2 3 } ] [ { 1 2 2 3 3 } prune ] unit-test
+[ V{ 3 2 1 } ] [ { 3 3 2 2 1 } prune ] unit-test
+
+[ { } ] [ { } { } intersect  ] unit-test
+[ { 2 3 } ] [ { 1 2 3 } { 2 3 4 } intersect ] unit-test
+
+[ { } ] [ { } { } diff ] unit-test
+[ { 4 } ] [ { 1 2 3 } { 2 3 4 } diff ] unit-test
+
+[ V{ } ] [ { } { } union ] unit-test
+[ V{ 1 2 3 4 } ] [ { 1 2 3 } { 2 3 4 } union ] unit-test
diff --git a/core/sets/sets.factor b/core/sets/sets.factor
new file mode 100644 (file)
index 0000000..31c39c6
--- /dev/null
@@ -0,0 +1,31 @@
+! Copyright (C) 2008 Slava Pestov, Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs hashtables kernel sequences vectors ;
+IN: sets
+
+: (prune) ( elt hash vec -- )
+    3dup drop key?
+    [ [ drop dupd set-at ] [ nip push ] [ ] 3tri ] unless
+    3drop ; inline
+
+: prune ( seq -- newseq )
+    [ ] [ length <hashtable> ] [ length <vector> ] tri
+    [ [ (prune) ] 2curry each ] keep ;
+
+: unique ( seq -- assoc )
+    [ dup ] H{ } map>assoc ;
+
+: (all-unique?) ( elt hash -- ? )
+    2dup key? [ 2drop f ] [ dupd set-at t ] if ;
+
+: all-unique? ( seq -- ? )
+    dup length <hashtable> [ (all-unique?) ] curry all? ;
+
+: intersect ( seq1 seq2 -- newseq )
+    unique [ key? ] curry subset ;
+
+: diff ( seq1 seq2 -- newseq )
+    swap unique [ key? not ] curry subset ;
+
+: union ( seq1 seq2 -- newseq )
+    append prune ;
diff --git a/core/sets/summary.txt b/core/sets/summary.txt
new file mode 100644 (file)
index 0000000..f987cc2
--- /dev/null
@@ -0,0 +1 @@
+Set-theoretic operations on sequences
diff --git a/core/sets/tags.txt b/core/sets/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index b385fbf369522c65a2e37a126be1b7669452f156..5703b631f4376567f54cdd78835928521d0dc46e 100755 (executable)
@@ -69,7 +69,7 @@ M: pathname forget*
     pathname-string forget-source ;
 
 : rollback-source-file ( file -- )
-    dup source-file-definitions new-definitions get [ union ] 2map
+    dup source-file-definitions new-definitions get [ assoc-union ] 2map
     swap set-source-file-definitions ;
 
 SYMBOL: file
index 260a08c0447090236c46dd17493e11c1801ef50b..f840ca15adfb8e778095106c828744105c5e01d8 100755 (executable)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2005, 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math namespaces strings arrays vectors sequences ;
+USING: kernel math namespaces strings arrays vectors sequences
+sets ;
 IN: splitting
 
 TUPLE: groups seq n sliced? ;
@@ -8,7 +9,7 @@ TUPLE: groups seq n sliced? ;
 : check-groups 0 <= [ "Invalid group count" throw ] when ;
 
 : <groups> ( seq n -- groups )
-    dup check-groups f groups construct-boa ; inline
+    dup check-groups f groups boa ; inline
 
 : <sliced-groups> ( seq n -- groups )
     <groups> t over set-groups-sliced? ;
@@ -69,7 +70,7 @@ INSTANCE: groups sequence
 : split ( seq separators -- pieces ) [ split, ] { } make ;
 
 : string-lines ( str -- seq )
-    dup "\r\n" seq-intersect empty? [
+    dup "\r\n" intersect empty? [
         1array
     ] [
         "\n" split [
index c971287ef69a6bb671df06f9a49a2254b110a279..961c8cdf6eb4730bb008a947ac7b2444dcad7ffc 100755 (executable)
@@ -1,5 +1,6 @@
-USING: continuations kernel math namespaces strings sbufs
-tools.test sequences vectors arrays ;
+USING: continuations kernel math namespaces strings
+strings.private sbufs tools.test sequences vectors arrays memory
+prettyprint io.streams.null ;
 IN: strings.tests
 
 [ CHAR: b ] [ 1 >bignum "abc" nth ] unit-test
@@ -90,3 +91,28 @@ unit-test
     "\udeadbe" clone
     CHAR: \u123456 over clone set-first
 ] unit-test
+
+! Regressions
+[ ] [
+    [
+        4 [
+            100 [ drop "obdurak" clone ] map
+            gc
+            dup [
+                1234 0 rot set-string-nth
+            ] each
+            1000 [
+                1000 f <array> drop
+            ] times
+            .
+        ] times
+    ] with-null-stream
+] unit-test
+
+[ t ] [
+    10000 [
+        drop
+        300 100 CHAR: \u123456
+        [ <string> clone resize-string first ] keep =
+    ] all?
+] unit-test
index bb3c94ce97824bcb236d6c84cce40c9823376543..14847372778a8ea83026dfe29a31972d6b36563a 100755 (executable)
@@ -46,6 +46,6 @@ M: string resize resize-string ;
 
 : >string ( seq -- str ) "" clone-like ;
 
-M: string new drop 0 <string> ;
+M: string new-sequence drop 0 <string> ;
 
 INSTANCE: string sequence
index 61e77ae9a5d3e426280b40ca8dafc2dffe105f93..c2eb411f0a727657098acff3f4861cb8d3ad61c9 100755 (executable)
@@ -573,21 +573,21 @@ HELP: ERROR:
         ""
         "TUPLE: invalid-values x y ;"
         ": invalid-values ( x y -- * )"
-        "    \\ invalid-values construct-boa throw ;"
+        "    \\ invalid-values boa throw ;"
     }
 } ;
 
 HELP: C:
 { $syntax "C: constructor class" }
 { $values { "constructor" "a new word to define" } { "class" tuple-class } }
-{ $description "Define a constructor word for a tuple class which simply performs BOA (by order of arguments) construction using " { $link construct-boa } "." }
+{ $description "Define a constructor word for a tuple class which simply performs BOA (by order of arguments) construction using " { $link boa } "." }
 { $examples
     "Suppose the following tuple has been defined:"
     { $code "TUPLE: color red green blue ;" }
     "The following two lines are equivalent:"
     { $code
         "C: <color> color"
-        ": <color> color construct-boa ;"
+        ": <color> color boa ;"
     }
     "In both cases, a word " { $snippet "<color>" } " is defined, which reads three values from the stack and creates a " { $snippet "color" } " instance having these values in the " { $snippet "red" } ", " { $snippet "green" } " and " { $snippet "blue" } " slots, respectively."
 } ;
index 005672c1c62e46239d32bfb224decb33b8e01531..eaf5ffea051bd2fe3953cc91b4a0ae0ddb8a6d1f 100755 (executable)
@@ -61,7 +61,7 @@ IN: bootstrap.syntax
         scan {
             { [ dup length 1 = ] [ first ] }
             { [ "\\" ?head ] [ next-escape drop ] }
-            { [ t ] [ name>char-hook get call ] }
+            [ name>char-hook get call ]
         } cond parsed
     ] define-syntax
 
@@ -166,7 +166,7 @@ IN: bootstrap.syntax
     "C:" [
         CREATE-WORD
         scan-word dup check-tuple
-        [ construct-boa ] curry define-inline
+        [ boa ] curry define-inline
     ] define-syntax
 
     "ERROR:" [
index df112bd78674d19dec1d6e2dca3ebeec4805db12..5aac0a8e8ca2cfd5a9b254ba63551b67082b045f 100755 (executable)
@@ -7,9 +7,7 @@ ABOUT: "system"
 ARTICLE: "system" "System interface"
 { $subsection "cpu" }
 { $subsection "os" }
-"Reading environment variables:"
-{ $subsection os-env }
-{ $subsection os-envs }
+{ $subsection "environment-variables" }
 "Getting the path to the Factor VM and image:"
 { $subsection vm }
 { $subsection image }
@@ -19,7 +17,16 @@ ARTICLE: "system" "System interface"
 { $subsection exit }
 { $see-also "io.files" "io.mmap" "io.monitors" "network-streams" "io.launcher" } ;
 
-ARTICLE: "cpu" "Processor Detection"
+ARTICLE: "environment-variables" "Environment variables"
+"Reading environment variables:"
+{ $subsection os-env }
+{ $subsection os-envs }
+"Writing environment variables:"
+{ $subsection set-os-env }
+{ $subsection unset-os-env }
+{ $subsection set-os-envs } ;
+
+ARTICLE: "cpu" "Processor detection"
 "Processor detection:"
 { $subsection cpu }
 "Supported processors:"
@@ -30,7 +37,7 @@ ARTICLE: "cpu" "Processor Detection"
 "Processor families:"
 { $subsection x86 } ;
 
-ARTICLE: "os" "Operating System Detection"
+ARTICLE: "os" "Operating system detection"
 "Operating system detection:"
 { $subsection os }
 "Supported operating systems:"
@@ -93,12 +100,28 @@ HELP: os-envs
 HELP: set-os-envs
 { $values { "assoc" "an association mapping strings to strings" } }
 { $description "Replaces the current set of environment variables." }
+{ $notes
+    "Names and values of environment variables are operating system-specific. Windows NT allows values up to 32766 characters in length."
+}
+{ $errors "Windows CE has no concept of environment variables, so this word throws an error there." } ;
+
+HELP: set-os-env ( value key -- )
+{ $values { "value" string } { "key" string } }
+{ $description "Set an environment variable." }
+{ $notes
+    "Names and values of environment variables are operating system-specific."
+}
+{ $errors "Windows CE has no concept of environment variables, so this word throws an error there." } ;
+
+HELP: unset-os-env ( key -- )
+{ $values { "key" string } }
+{ $description "Unset an environment variable." }
 { $notes
     "Names and values of environment variables are operating system-specific."
 }
 { $errors "Windows CE has no concept of environment variables, so this word throws an error there." } ;
 
-{ os-env os-envs set-os-envs } related-words
+{ os-env os-envs set-os-env unset-os-env set-os-envs } related-words
 
 HELP: image
 { $values { "path" "a pathname string" } }
index 14e34ccb1787c9c9c0cb805355af449582eca3cb..c731a1472559c0e837dc27054747ec76aced68e6 100755 (executable)
@@ -1,4 +1,5 @@
-USING: math tools.test system prettyprint namespaces kernel ;
+USING: math tools.test system prettyprint namespaces kernel
+strings sequences ;
 IN: system.tests
 
 os wince? [
@@ -12,3 +13,15 @@ os unix? [
     [ ] [ "envs" get set-os-envs ] unit-test
     [ t ] [ os-envs "envs" get = ] unit-test
 ] when
+
+[ ] [ "factor-test-key-1" unset-os-env ] unit-test
+[ ] [ "ps3" "factor-test-key-1" set-os-env ] unit-test
+[ "ps3" ] [ "factor-test-key-1" os-env ] unit-test
+[ ] [ "factor-test-key-1" unset-os-env ] unit-test
+[ f ] [ "factor-test-key-1" os-env ] unit-test
+
+[ ] [
+    32766 CHAR: a <string> "factor-test-key-long" set-os-env
+] unit-test
+[ 32766 ] [ "factor-test-key-long" os-env length ] unit-test
+[ ] [ "factor-test-key-long" unset-os-env ] unit-test
index d7d7988893e06df8bc443488014fc8334eba7cf1..f99191b91ffac7b08ceb66150f218ed4cab94b39 100755 (executable)
@@ -4,7 +4,7 @@
 IN: threads
 USING: arrays hashtables heaps kernel kernel.private math
 namespaces sequences vectors continuations continuations.private
-dlists assocs system combinators init boxes ;
+dlists assocs system combinators init boxes accessors ;
 
 SYMBOL: initial-thread
 
@@ -18,11 +18,10 @@ mailbox variables sleep-entry ;
 
 ! Thread-local storage
 : tnamespace ( -- assoc )
-    self dup thread-variables
-    [ ] [ H{ } clone dup rot set-thread-variables ] ?if ;
+    self variables>> [ H{ } clone dup self (>>variables) ] unless* ;
 
 : tget ( key -- value )
-    self thread-variables at ;
+    self variables>> at ;
 
 : tset ( value key -- )
     tnamespace set-at ;
@@ -35,7 +34,7 @@ mailbox variables sleep-entry ;
 : thread ( id -- thread ) threads at ;
 
 : thread-registered? ( thread -- ? )
-    thread-id threads key? ;
+    id>> threads key? ;
 
 : check-unregistered
     dup thread-registered?
@@ -48,59 +47,61 @@ mailbox variables sleep-entry ;
 <PRIVATE
 
 : register-thread ( thread -- )
-    check-unregistered dup thread-id threads set-at ;
+    check-unregistered dup id>> threads set-at ;
 
 : unregister-thread ( thread -- )
-    check-registered thread-id threads delete-at ;
+    check-registered id>> threads delete-at ;
 
 : set-self ( thread -- ) 40 setenv ; inline
 
 PRIVATE>
 
+: new-thread ( quot name class -- thread )
+    new
+        swap >>name
+        swap >>quot
+        \ thread counter >>id
+        <box> >>continuation
+        [ ] >>exit-handler ; inline
+
 : <thread> ( quot name -- thread )
-    \ thread counter <box> [ ] {
-        set-thread-quot
-        set-thread-name
-        set-thread-id
-        set-thread-continuation
-        set-thread-exit-handler
-    } \ thread construct ;
+    \ thread new-thread ;
 
 : run-queue 42 getenv ;
 
 : sleep-queue 43 getenv ;
 
 : resume ( thread -- )
-    f over set-thread-state
+    f >>state
     check-registered run-queue push-front ;
 
 : resume-now ( thread -- )
-    f over set-thread-state
+    f >>state
     check-registered run-queue push-back ;
 
 : resume-with ( obj thread -- )
-    f over set-thread-state
+    f >>state
     check-registered 2array run-queue push-front ;
 
 : sleep-time ( -- ms/f )
     {
         { [ run-queue dlist-empty? not ] [ 0 ] }
         { [ sleep-queue heap-empty? ] [ f ] }
-        { [ t ] [ sleep-queue heap-peek nip millis [-] ] }
+        [ sleep-queue heap-peek nip millis [-] ]
     } cond ;
 
 <PRIVATE
 
 : schedule-sleep ( thread ms -- )
     >r check-registered dup r> sleep-queue heap-push*
-    swap set-thread-sleep-entry ;
+    >>sleep-entry drop ;
 
 : expire-sleep? ( heap -- ? )
     dup heap-empty?
     [ drop f ] [ heap-peek nip millis <= ] if ;
 
 : expire-sleep ( thread -- )
-    f over set-thread-sleep-entry resume ;
+    f >>sleep-entry resume ;
 
 : expire-sleep-loop ( -- )
     sleep-queue
@@ -123,21 +124,21 @@ PRIVATE>
     ] [
         pop-back
         dup array? [ first2 ] [ f swap ] if dup set-self
-        f over set-thread-state
-        thread-continuation box>
+        f >>state
+        continuation>> box>
         continue-with
     ] if ;
 
 PRIVATE>
 
 : stop ( -- )
-    self dup thread-exit-handler call
+    self dup exit-handler>> call
     unregister-thread next ;
 
 : suspend ( quot state -- obj )
     [
-        self thread-continuation >box
-        self set-thread-state
+        self continuation>> >box
+        self (>>state)
         self swap call next
     ] callcc1 2nip ; inline
 
@@ -157,9 +158,9 @@ M: real sleep
     millis + >integer sleep-until ;
 
 : interrupt ( thread -- )
-    dup thread-state [
-        dup thread-sleep-entry [ sleep-queue heap-delete ] when*
-        f over set-thread-sleep-entry
+    dup state>> [
+        dup sleep-entry>> [ sleep-queue heap-delete ] when*
+        f >>sleep-entry
         dup resume
     ] when drop ;
 
@@ -171,7 +172,7 @@ M: real sleep
             V{ } set-catchstack
             { } set-retainstack
             >r { } set-datastack r>
-            thread-quot [ call stop ] call-clear
+            quot>> [ call stop ] call-clear
         ] 1 (throw)
     ] "spawn" suspend 2drop ;
 
@@ -196,8 +197,8 @@ GENERIC: error-in-thread ( error thread -- )
     <min-heap> 43 setenv
     initial-thread global
     [ drop f "Initial" <thread> ] cache
-    <box> over set-thread-continuation
-    f over set-thread-state
+    <box> >>continuation
+    f >>state
     dup register-thread
     set-self ;
 
index 18aa0f3fa776f60e003b430339432e040a0abe15..8f642657712b93200a29ac53d1e948960564999c 100755 (executable)
@@ -94,6 +94,6 @@ IN: vectors.tests
     100 >array dup >vector <reversed> >array >r reverse r> =
 ] unit-test
 
-[ fixnum ] [ 1 >bignum V{ } new length class ] unit-test
+[ fixnum ] [ 1 >bignum V{ } new-sequence length class ] unit-test
 
 [ fixnum ] [ 1 >bignum [ ] V{ } map-as length class ] unit-test
index 1820c62ff45ecab41ecd28bdb64f33b4a6b6234b..4a6b41f863a74566b3f5c41d248afa09b5afda28 100755 (executable)
@@ -6,7 +6,7 @@ IN: vectors
 <PRIVATE
 
 : array>vector ( array length -- vector )
-    vector construct-boa ; inline
+    vector boa ; inline
 
 PRIVATE>
 
@@ -19,7 +19,7 @@ M: vector like
         dup array? [ dup length array>vector ] [ >vector ] if
     ] unless ;
 
-M: vector new drop [ f <array> ] keep >fixnum array>vector ;
+M: vector new-sequence drop [ f <array> ] keep >fixnum array>vector ;
 
 M: vector equal?
     over vector? [ sequence= ] [ 2drop f ] if ;
index 1191594fe55aa1c0552d844561bf43402f7a0436..45b0d6b0191f4c69b6b6a9eac184f12ba5c998c1 100755 (executable)
@@ -110,6 +110,8 @@ IN: vocabs.loader.tests
     ] with-compilation-unit
 ] unit-test
 
+[ ] [ "vocabs.loader.test.b" changed-vocab ] unit-test
+
 [ ] [ "vocabs.loader.test.b" refresh ] unit-test
 
 [ 3 ] [ "count-me" get-global ] unit-test
index 8ef5f6f508ae014de81aaccde78fc73479747c95..24a00189e4b021e2a537951e133f51437bf9c358 100755 (executable)
@@ -88,7 +88,7 @@ SYMBOL: load-vocab-hook ! ( name -- )
 TUPLE: vocab-link name ;
 
 : <vocab-link> ( name -- vocab-link )
-    vocab-link construct-boa ;
+    vocab-link boa ;
 
 M: vocab-link hashcode*
     vocab-link-name hashcode* ;
index a715aab64f7ee4430503dd519667645ad47d020d..f259378f7e72ef24cc4894e4f53a102ead1b8a5a 100755 (executable)
@@ -284,7 +284,7 @@ HELP: <word>
 
 HELP: gensym
 { $values { "word" word } }
-{ $description "Creates an uninterned word that is not equal to any other word in the system. Gensyms have an automatically-generated name based on a prefix and an incrementing counter." }
+{ $description "Creates an uninterned word that is not equal to any other word in the system." }
 { $examples { $unchecked-example "gensym ." "G:260561" } }
 { $notes "Gensyms are often used as placeholder values that have no meaning of their own but must be unique. For example, the compiler uses gensyms to label sections of code." } ;
 
index 7794a7f41f11ed07e3724804b290e8f881e15645..3466544eef0f407afd9b0b84855693b01cf07686 100755 (executable)
@@ -2,8 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays definitions graphs assocs kernel kernel.private
 slots.private math namespaces sequences strings vectors sbufs
-quotations assocs hashtables sorting math.parser words.private
-vocabs combinators ;
+quotations assocs hashtables sorting words.private vocabs ;
 IN: words
 
 : word ( -- word ) \ word get-global ;
@@ -66,11 +65,15 @@ SYMBOL: bootstrapping?
 GENERIC: crossref? ( word -- ? )
 
 M: word crossref?
-    {
-        { [ dup "forgotten" word-prop ] [ f ] }
-        { [ dup word-vocabulary ] [ t ] }
-        { [ t ] [ f ] }
-    } cond nip ;
+    dup "forgotten" word-prop [
+        drop f
+    ] [
+        word-vocabulary >boolean
+    ] if ;
+
+GENERIC: compiled-crossref? ( word -- ? )
+
+M: word compiled-crossref? crossref? ;
 
 GENERIC# (quot-uses) 1 ( obj assoc -- )
 
@@ -98,7 +101,7 @@ SYMBOL: compiled-crossref
 compiled-crossref global [ H{ } assoc-like ] change-at
 
 : compiled-xref ( word dependencies -- )
-    [ drop crossref? ] assoc-subset
+    [ drop compiled-crossref? ] assoc-subset
     2dup "compiled-uses" set-word-prop
     compiled-crossref get add-vertex* ;
 
@@ -191,7 +194,7 @@ M: word subwords drop f ;
     { "methods" "combination" "default-method" } reset-props ;
 
 : gensym ( -- word )
-    "G:" \ gensym counter number>string append f <word> ;
+    "( gensym )" f <word> ;
 
 : define-temp ( quot -- word )
     gensym dup rot define ;
index adf79c84c9f9dcb15f9892d02941e45076082e3f..bd1f02c44c58653abd0bacfff9720e6070a15a2d 100755 (executable)
@@ -21,7 +21,7 @@ SYMBOL: alarm-thread
     pick callable? [ "Not a quotation" throw ] unless ; inline
 
 : <alarm> ( quot time frequency -- alarm )
-    check-alarm <box> alarm construct-boa ;
+    check-alarm <box> alarm boa ;
 
 : register-alarm ( alarm -- )
     dup dup alarm-time alarms get-global heap-push*
diff --git a/extra/arrays/lib/summary.txt b/extra/arrays/lib/summary.txt
new file mode 100644 (file)
index 0000000..5ecd994
--- /dev/null
@@ -0,0 +1 @@
+Non-core array words
diff --git a/extra/arrays/lib/tags.txt b/extra/arrays/lib/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 8954ffd8ccd1cf1459963dd7a45b718503aa6532..32e3602f8fa9936d166d3816d7f408239ae677cc 100644 (file)
@@ -48,7 +48,7 @@ SYMBOL: elements
 
 TUPLE: element syntax id tag tagclass encoding contentlength newobj objtype ;
 
-: <element> element construct-empty ;
+: <element> element new ;
 
 : set-id ( -- boolean )
     read1 dup elements get set-element-id ;
@@ -172,7 +172,7 @@ SYMBOL: tagnum
 
 TUPLE: tag value ;
 
-: <tag> ( -- <tag> ) 4 tag construct-boa ;
+: <tag> ( -- <tag> ) 4 tag boa ;
 
 : with-ber ( quot -- )
     [
index f81f70a613f86c147d9c034d87ee5335a7172e3c..3317348f45e1c9eb2ada10d26d5164d3446fdd5d 100644 (file)
@@ -68,7 +68,7 @@ M: x30 g ;
     "benchmark.dispatch1" words [ tuple-class? ] subset ;
 
 : a-bunch-of-objects ( -- seq )
-    my-classes [ construct-empty ] map ;
+    my-classes [ new ] map ;
 
 : dispatch-benchmark ( -- )
     1000000 a-bunch-of-objects
index 34df715f894dfb3873f03e644daf0ac2d3578dfa..a2f096695b32fcad0211ef91cb09b114fa01ccdd 100755 (executable)
@@ -68,7 +68,7 @@ INSTANCE: x30 g
     "benchmark.dispatch5" words [ tuple-class? ] subset ;\r
 \r
 : a-bunch-of-objects ( -- seq )\r
-    my-classes [ construct-empty ] map ;\r
+    my-classes [ new ] map ;\r
 \r
 : dispatch-benchmark ( -- )\r
     1000000 a-bunch-of-objects\r
index 25f543212f18a68534776161ae5b14de331d5074..fd7bb6e80295171e31bd74205aaa343ffa652f69 100644 (file)
@@ -5,6 +5,6 @@ TUPLE: hello n ;
 
 : foo 0 100000000 [ over hello-n + ] times ;
 
-: typecheck-main 0 hello construct-boa foo 2drop ;
+: typecheck-main 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 0fc1debb670dc35d4e5203f26b161d9dc140a30c..0dfcc17c66491fb63c6c65747192306ec2c76f59 100644 (file)
@@ -7,6 +7,6 @@ TUPLE: hello n ;
 
 : foo 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello construct-boa foo 2drop ;
+: typecheck-main 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 9a58e0a79587fbb63d7576d72c2e4b58351d6656..3ca6a9f9e7b55136b1faea7d55678dc2981773d6 100644 (file)
@@ -7,6 +7,6 @@ TUPLE: hello n ;
 
 : foo 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello construct-boa foo 2drop ;
+: typecheck-main 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index eb211e97e72c396e8588b62b3a083bdb65bb5a8f..cc3310fef6c2b35e70a4106c7be0a2b0d1ecc6c3 100644 (file)
@@ -7,6 +7,6 @@ TUPLE: hello n ;
 
 : foo 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello construct-boa foo 2drop ;
+: typecheck-main 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 114809377b71f74877991179653f74f9d33df82a..fca0568adf6c7ff251c1ca844121a0d418a8f05f 100644 (file)
@@ -24,7 +24,7 @@ TUPLE: check< number bound ;
 M: check< summary drop "Number exceeds upper bound" ;
 
 : check< ( num cmp -- num )
-    2dup < [ drop ] [ \ check< construct-boa throw ] if ;
+    2dup < [ drop ] [ \ check< boa throw ] if ;
 
 : ?check ( length -- )
     safe-bitfields? get [ 2^ , \ check< , ] [ drop ] if ;
index fa0c54d0c62809eea5dedc408994f76b2c205a10..5f5e11d913485307d1e13c3566d646aadc96d365 100755 (executable)
@@ -9,6 +9,7 @@ namespaces random ;
     { [ os unix? ] [ "random.unix" require ] }
 } cond
 
-! [ [ 32 random-bits ] with-secure-random <mersenne-twister> random-generator set-global ]
-[ millis <mersenne-twister> random-generator set-global ]
-"generator.random" add-init-hook
+[
+    [ 32 random-bits ] with-system-random
+    <mersenne-twister> random-generator set-global
+] "generator.random" add-init-hook
diff --git a/extra/bubble-chamber/bubble-chamber-docs.factor b/extra/bubble-chamber/bubble-chamber-docs.factor
new file mode 100644 (file)
index 0000000..47331ef
--- /dev/null
@@ -0,0 +1,102 @@
+
+USING: help.syntax help.markup ;
+
+USING: bubble-chamber.particle.muon
+       bubble-chamber.particle.quark
+       bubble-chamber.particle.hadron
+       bubble-chamber.particle.axion ;
+
+IN: bubble-chamber
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: muon
+
+  { $class-description
+    "The muon is a colorful particle with an entangled friend."
+    "It draws both itself and its horizontally symmetric partner."
+    "A high range of speed and almost no speed decay allow the"
+    "muon to reach the extents of the window, often forming rings"
+    "where theta has decayed but speed remains stable. The result"
+    "is color almost everywhere in the general direction of collision,"
+    "stabilized into fuzzy rings." } ;
+
+HELP: quark
+
+  { $class-description
+    "The quark draws as a translucent black. Their large numbers"
+    "create fields of blackness overwritten only by the glowing shadows of "
+    "Hadrons. "
+    "quarks are allowed to accelerate away with speed decay values above 1.0. "
+    "Each quark has an entangled friend. Both particles are drawn identically,"
+    "mirrored along the y-axis." } ;
+
+HELP: hadron
+
+  { $class-description
+    "Hadrons collide from totally random directions. "
+    "Those hadrons that do not exit the drawing area, "
+    "tend to stabilize into perfect circular orbits. "
+    "Each hadron draws with a slight glowing emboss. "
+    "The hadron itself is not drawn." } ;
+
+HELP: axion
+
+  { $class-description
+    "The axion particle draws a bold black path. Axions exist "
+    "in a slightly higher dimension and as such are drawn with "
+    "elevated embossed shadows. Axions are quick to stabilize "
+    "and fall into single pixel orbits axions automatically "
+    "recollide themselves after stabilizing." } ;
+
+{ muon quark hadron axion } related-words
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "bubble-chamber" "Bubble Chamber"
+
+  { $subsection "bubble-chamber-introduction" }
+  { $subsection "bubble-chamber-particles" }
+  { $subsection "bubble-chamber-author" }
+  { $subsection "bubble-chamber-running" } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "bubble-chamber-introduction" "Introduction"
+
+"The Bubble Chamber is a generative painting system of imaginary "
+"colliding particles. A single super-massive collision produces a "
+"discrete universe of four particle types. Particles draw their "
+"positions over time as pixel exposures. " ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "bubble-chamber-particles" "Particles"
+
+"Four types of particles exist. The behavior and graphic appearance of "
+"each particle type is unique."
+
+  { $subsection muon }
+  { $subsection quark }
+  { $subsection hadron }
+  { $subsection axion } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "bubble-chamber-author" "Author"
+
+  "Bubble Chamber was created by Jared Tarbell. "
+  "It was originally implemented in Processing. "
+  "It was ported to Factor by Eduardo Cavazos. "
+  "The original work is on display here: "
+  { $url
+  "http://www.complexification.net/gallery/machines/bubblechamber/" } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "bubble-chamber-running" "How to use"
+
+  "After you run the vocabulary, a window will appear. Click the "
+  "mouse in a random area to fire 11 particles of each type. "
+  "Another way to fire particles is to press the "
+  "spacebar. This fires all the particles." ;
\ No newline at end of file
diff --git a/extra/bubble-chamber/bubble-chamber.factor b/extra/bubble-chamber/bubble-chamber.factor
new file mode 100644 (file)
index 0000000..4b0db46
--- /dev/null
@@ -0,0 +1,88 @@
+
+USING: kernel namespaces sequences random math math.constants math.libm vars
+       ui
+       processing
+       processing.gadget
+       bubble-chamber.common
+       bubble-chamber.particle
+       bubble-chamber.particle.muon
+       bubble-chamber.particle.quark
+       bubble-chamber.particle.hadron
+       bubble-chamber.particle.axion ;
+
+IN: bubble-chamber
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VARS: particles muons quarks hadrons axions ;
+
+VAR: boom
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: collide-all ( -- )
+
+  2 pi * 1random >collision-theta
+
+  particles> [ collide ] each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: collide-one ( -- )
+
+  dim 2 / mouse-x - dim 2 / mouse-y - fatan2 >collision-theta
+
+  hadrons> random collide
+  quarks>  random collide
+  muons>   random collide ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: mouse-pressed ( -- )
+  boom on
+  1 background ! kludge
+  11 [ drop collide-one ] each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: key-released ( -- )
+  key " " =
+    [
+      boom on
+      1 background
+      collide-all
+    ]
+  when ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: bubble-chamber ( -- )
+
+  1000 1000 size*
+
+  [
+    1 background
+    no-stroke
+  
+    1789 [ drop <muon>   ] map >muons
+    1300 [ drop <quark>  ] map >quarks
+    1000 [ drop <hadron> ] map >hadrons
+    111  [ drop <axion>  ] map >axions
+
+    muons> quarks> hadrons> axions> 3append append >particles
+
+    collide-one
+  ] setup
+
+  [
+    boom>
+      [ particles> [ move ] each ]
+    when
+  ] draw
+
+  [ mouse-pressed ] button-down
+  [ key-released  ] key-up ;
+
+: go ( -- ) [ bubble-chamber run ] with-ui ;
+
+MAIN: go
\ No newline at end of file
diff --git a/extra/bubble-chamber/common/common.factor b/extra/bubble-chamber/common/common.factor
new file mode 100644 (file)
index 0000000..c9ce687
--- /dev/null
@@ -0,0 +1,12 @@
+
+USING: kernel math accessors combinators.cleave vars ;
+
+IN: bubble-chamber.common
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: collision-theta
+
+: dim ( -- dim ) 1000 ;
+
+: center ( -- point ) dim 2 / dup {2} ; foldable
diff --git a/extra/bubble-chamber/particle/axion/axion.factor b/extra/bubble-chamber/particle/axion/axion.factor
new file mode 100644 (file)
index 0000000..5486589
--- /dev/null
@@ -0,0 +1,67 @@
+
+USING: kernel sequences random accessors multi-methods
+       math math.constants math.ranges math.points combinators.cleave
+       processing bubble-chamber.common bubble-chamber.particle ;
+
+IN: bubble-chamber.particle.axion
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: axion < particle ;
+
+: <axion> ( -- axion ) axion new initialize-particle ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: collide { axion }
+
+  center              >>pos
+  2 pi *      1random >>theta
+  1.0   6.0   2random >>speed
+  0.998 1.000 2random >>speed-d
+  0                   >>theta-d
+  0                   >>theta-dd
+
+  [ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] [ ] while
+
+  drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: dy>alpha ( dy -- alpha ) neg 6 * 30 + 255.0 / ;
+
+: axion-white ( dy -- dy ) dup 1 swap dy>alpha {2} stroke ;
+: axion-black ( dy -- dy ) dup 0 swap dy>alpha {2} stroke ;
+
+: axion-point- ( particle dy -- particle ) >r dup pos>> r> v-y point ;
+: axion-point+ ( particle dy -- particle ) >r dup pos>> r> v+y point ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: move { axion }
+
+  { 0.06 0.59 } stroke
+  dup pos>>  point
+
+  1 4 [a,b] [ axion-white axion-point- ] each
+  1 4 [a,b] [ axion-black axion-point+ ] each
+
+  dup vel>> move-by
+
+  turn
+
+  step-theta
+  step-theta-d
+  step-speed-mul
+
+  [ ] [ speed-d>> 0.9999 * ] bi >>speed-d
+
+  1000 random 996 >
+    [
+      dup speed>>   neg     >>speed
+      dup speed-d>> neg 2 + >>speed-d
+
+      100 random 30 > [ collide ] [ drop ] if
+    ]
+    [ drop ]
+  if ;
diff --git a/extra/bubble-chamber/particle/hadron/hadron.factor b/extra/bubble-chamber/particle/hadron/hadron.factor
new file mode 100644 (file)
index 0000000..9eecf2d
--- /dev/null
@@ -0,0 +1,60 @@
+
+USING: kernel random math math.constants math.points accessors multi-methods
+       processing
+       processing.color
+       bubble-chamber.common
+       bubble-chamber.particle ;
+
+IN: bubble-chamber.particle.hadron
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: hadron < particle ;
+
+: <hadron> ( -- hadron ) hadron new initialize-particle ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: collide { hadron }
+
+  center              >>pos
+  2 pi *      1random >>theta
+  0.5   3.5   2random >>speed
+  0.996 1.001 2random >>speed-d
+  0                   >>theta-d
+  0                   >>theta-dd
+
+  [ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] [ ] while
+
+  0 1 0 <rgb> >>myc
+
+  drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: move { hadron }
+
+  { 1 0.11 } stroke
+  dup pos>> 1 v-y point
+  
+  { 0 0.11 } stroke
+  dup pos>> 1 v+y point
+
+  dup vel>> move-by
+
+  turn
+
+  step-theta
+  step-theta-d
+  step-speed-mul
+
+  1000 random 997 >
+    [
+      1.0     >>speed-d
+      0.00001 >>theta-dd
+
+      100 random 70 > [ dup collide ] when
+    ]
+  when
+
+  out-of-bounds? [ collide ] [ drop ] if ;
diff --git a/extra/bubble-chamber/particle/muon/colors/colors.factor b/extra/bubble-chamber/particle/muon/colors/colors.factor
new file mode 100644 (file)
index 0000000..ab72f65
--- /dev/null
@@ -0,0 +1,53 @@
+
+USING: kernel sequences math math.constants accessors
+       processing
+       processing.color ;
+
+IN: bubble-chamber.particle.muon.colors
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: good-colors ( -- seq )
+  {
+    T{ rgba f 0.23 0.14 0.17 1 }
+    T{ rgba f 0.23 0.14 0.15 1 }
+    T{ rgba f 0.21 0.14 0.15 1 }
+    T{ rgba f 0.51 0.39 0.33 1 }
+    T{ rgba f 0.49 0.33 0.20 1 }
+    T{ rgba f 0.55 0.45 0.32 1 }
+    T{ rgba f 0.69 0.63 0.51 1 }
+    T{ rgba f 0.64 0.39 0.18 1 }
+    T{ rgba f 0.73 0.42 0.20 1 }
+    T{ rgba f 0.71 0.45 0.29 1 }
+    T{ rgba f 0.79 0.45 0.22 1 }
+    T{ rgba f 0.82 0.56 0.34 1 }
+    T{ rgba f 0.88 0.72 0.49 1 }
+    T{ rgba f 0.85 0.69 0.40 1 }
+    T{ rgba f 0.96 0.92 0.75 1 }
+    T{ rgba f 0.99 0.98 0.87 1 }
+    T{ rgba f 0.85 0.82 0.69 1 }
+    T{ rgba f 0.99 0.98 0.87 1 }
+    T{ rgba f 0.82 0.82 0.79 1 }
+    T{ rgba f 0.65 0.69 0.67 1 }
+    T{ rgba f 0.53 0.60 0.55 1 }
+    T{ rgba f 0.57 0.53 0.68 1 }
+    T{ rgba f 0.47 0.42 0.56 1 }
+  } ;
+
+: anti-colors ( -- seq ) good-colors <reversed> ; 
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: color-fraction ( particle -- particle fraction ) dup theta>> pi + 2 pi * / ;
+
+: set-good-color ( particle -- particle )
+  color-fraction dup 0 1 between?
+    [ good-colors at-fraction-of >>myc ]
+    [ drop ]
+  if ;
+
+: set-anti-color ( particle -- particle )
+  color-fraction dup 0 1 between?
+    [ anti-colors at-fraction-of >>mya ]
+    [ drop ]
+  if ;
diff --git a/extra/bubble-chamber/particle/muon/muon.factor b/extra/bubble-chamber/particle/muon/muon.factor
new file mode 100644 (file)
index 0000000..a61526f
--- /dev/null
@@ -0,0 +1,62 @@
+
+USING: kernel arrays sequences random
+       math
+       math.ranges
+       math.functions
+       math.vectors
+       multi-methods accessors
+       combinators.cleave
+       processing
+       bubble-chamber.common
+       bubble-chamber.particle
+       bubble-chamber.particle.muon.colors ;
+
+IN: bubble-chamber.particle.muon
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: muon < particle ;
+
+: <muon> ( -- muon ) muon new initialize-particle ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: collide { muon }
+
+  center               >>pos
+  2 32 [a,b] random    >>speed
+  0.0001 0.001 2random >>speed-d
+
+  collision-theta>  -0.1 0.1 2random + >>theta
+  0                                    >>theta-d
+  0                                    >>theta-dd
+
+  [ 0.001 theta-dd-small? ] [ -0.1 0.1 random-theta-dd ] [ ] while
+
+  set-good-color
+  set-anti-color
+
+  drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: move { muon }
+
+  dup myc>> 0.16 >>alpha stroke
+  dup pos>> point
+
+  dup mya>> 0.16 >>alpha stroke
+  dup pos>> first2 >r dim swap - r> 2array point
+
+  dup
+    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
+  move-by
+
+  step-theta
+  step-theta-d
+  step-speed-sub
+
+  out-of-bounds? [ collide ] [ drop ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
diff --git a/extra/bubble-chamber/particle/particle.factor b/extra/bubble-chamber/particle/particle.factor
new file mode 100644 (file)
index 0000000..755a414
--- /dev/null
@@ -0,0 +1,68 @@
+
+USING: kernel sequences combinators
+       math math.vectors math.functions multi-methods
+       accessors combinators.cleave processing processing.color
+       bubble-chamber.common ;
+
+IN: bubble-chamber.particle
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: collide ( particle -- )
+GENERIC: move    ( particle -- )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: particle pos vel speed speed-d theta theta-d theta-dd myc mya ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: initialize-particle ( particle -- particle )
+
+  0 0 {2} >>pos
+  0 0 {2} >>vel
+
+  0 >>speed
+  0 >>speed-d
+  0 >>theta
+  0 >>theta-d
+  0 >>theta-dd
+
+  0 0 0 1 <rgba> >>myc
+  0 0 0 1 <rgba> >>mya ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: move-by ( obj delta -- obj ) over pos>> v+ >>pos ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: theta-dd-small? ( par limit -- par ? ) >r dup theta-dd>> abs r> < ;
+
+: random-theta-dd  ( par a b -- par ) 2random >>theta-dd ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: turn ( particle -- particle )
+  dup
+    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
+  >>vel ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: step-theta     ( p -- p ) [ ] [ theta>>   ] [ theta-d>>  ] tri + >>theta   ;
+: step-theta-d   ( p -- p ) [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d ;
+: step-speed-sub ( p -- p ) [ ] [ speed>>   ] [ speed-d>>  ] tri - >>speed   ;
+: step-speed-mul ( p -- p ) [ ] [ speed>>   ] [ speed-d>>  ] tri * >>speed   ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: x ( particle -- x ) pos>> first  ;
+: y ( particle -- x ) pos>> second ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: out-of-bounds? ( particle -- particle ? )
+  dup
+  { [ x dim neg < ] [ x dim 2 * > ] [ y dim neg < ] [ y dim 2 * > ] } cleave
+  or or or ;
diff --git a/extra/bubble-chamber/particle/quark/quark.factor b/extra/bubble-chamber/particle/quark/quark.factor
new file mode 100644 (file)
index 0000000..595c3b5
--- /dev/null
@@ -0,0 +1,53 @@
+
+USING: kernel arrays sequences random math accessors multi-methods
+       processing
+       bubble-chamber.common
+       bubble-chamber.particle ;
+
+IN: bubble-chamber.particle.quark
+
+TUPLE: quark < particle ;
+
+: <quark> ( -- quark ) quark new initialize-particle ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: collide { quark }
+
+  center                     >>pos
+  collision-theta> -0.11 0.11 2random +  >>theta
+  0.5 3.0 2random                        >>speed
+
+  0.996 1.001 2random                    >>speed-d
+  0                                      >>theta-d
+  0                                      >>theta-dd
+
+  [ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] [ ] while
+
+  drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: move { quark }
+
+  dup myc>> 0.13 >>alpha stroke
+  dup pos>>              point
+
+  dup pos>> first2 >r dim swap - r> 2array point
+
+  [ ] [ vel>> ] bi move-by
+
+  turn
+
+  step-theta
+  step-theta-d
+  step-speed-mul
+
+  1000 random 997 >
+    [
+      dup speed>> neg    >>speed
+      2 over speed-d>> - >>speed-d
+    ]
+  when
+
+  out-of-bounds? [ collide ] [ drop ] if ;
diff --git a/extra/builder/build/build.factor b/extra/builder/build/build.factor
new file mode 100644 (file)
index 0000000..e9f5898
--- /dev/null
@@ -0,0 +1,46 @@
+
+USING: io.files io.launcher io.encodings.utf8 prettyprint
+       builder.util builder.common builder.child builder.release
+       builder.report builder.email builder.cleanup ;
+
+IN: builder.build
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: create-build-dir ( -- )
+  datestamp >stamp
+  build-dir make-directory ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: enter-build-dir  ( -- ) build-dir set-current-directory ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: clone-builds-factor ( -- )
+  { "git" "clone" builds/factor } to-strings try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: record-id ( -- )
+  "factor"
+    [ git-id "../git-id" utf8 [ . ] with-file-writer ]
+  with-directory ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: build ( -- )
+  reset-status
+  create-build-dir
+  enter-build-dir
+  clone-builds-factor
+  record-id
+  build-child
+  release
+  report
+  email-report
+  cleanup ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+MAIN: build
\ No newline at end of file
index 0e3a794e246e2719e92e2976ccc58f8a0a585987..29daa8160bfacb4701bffb496afc052a2567a081 100644 (file)
 
-USING: kernel namespaces sequences splitting system combinators continuations
-       parser io io.files io.launcher io.sockets prettyprint threads
-       bootstrap.image benchmark vars bake smtp builder.util accessors
-       debugger io.encodings.utf8
-       calendar
-       tools.test
+USING: kernel debugger io.files threads calendar 
        builder.common
-       builder.benchmark
-       builder.release ;
+       builder.updates
+       builder.build ;
 
 IN: builder
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: cd ( path -- ) set-current-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: builds/factor ( -- path ) builds "factor" append-path ;
-: build-dir     ( -- path ) builds stamp>   append-path ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: prepare-build-machine ( -- )
-  builds make-directory
-  builds
-    [
-      { "git" "clone" "git://factorcode.org/git/factor.git" } try-process
-    ]
-  with-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: builds-check ( -- ) builds exists? not [ prepare-build-machine ] when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: git-clone ( -- desc ) { "git" "clone" "../factor" } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: enter-build-dir ( -- )
-  datestamp >stamp
-  builds cd
-  stamp> make-directory
-  stamp> cd ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: git-id ( -- id )
-  { "git" "show" } utf8 <process-stream>
-  [ readln ] with-stream " " split second ;
-
-: record-git-id ( -- ) git-id "../git-id" utf8 [ . ] with-file-writer ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: gnu-make ( -- string )
-  os { freebsd openbsd netbsd } member?
-    [ "gmake" ]
-    [ "make"  ]
-  if ;
-
-: do-make-clean ( -- ) { gnu-make "clean" } to-strings try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-vm ( -- desc )
-  <process>
-    { gnu-make } to-strings >>command
-    "../compile-log"        >>stdout
-    +stdout+                >>stderr ;
-
-: do-make-vm ( -- )
-  make-vm [ "vm compile error" print "../compile-log" cat ] run-or-bail ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: copy-image ( -- )
-  builds/factor my-boot-image-name append-path ".." copy-file-into
-  builds/factor my-boot-image-name append-path "."  copy-file-into ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: bootstrap-cmd ( -- cmd )
-  { "./factor" { "-i=" my-boot-image-name } "-no-user-init" } to-strings ;
-
-: bootstrap ( -- desc )
-  <process>
-    bootstrap-cmd >>command
-    +closed+      >>stdin
-    "../boot-log" >>stdout
-    +stdout+      >>stderr
-    60 minutes    >>timeout ;
-
-: do-bootstrap ( -- )
-  bootstrap [ "Bootstrap error" print "../boot-log" cat ] run-or-bail ;
-
-: builder-test-cmd ( -- cmd )
-  { "./factor" "-run=builder.test" } to-strings ;
-
-: builder-test ( -- desc )
-  <process>
-    builder-test-cmd >>command
-    +closed+         >>stdin
-    "../test-log"    >>stdout
-    +stdout+         >>stderr
-    240 minutes      >>timeout ;
-
-: do-builder-test ( -- )
-  builder-test [ "Test error" print "../test-log" 100 cat-n ] run-or-bail ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: build-status
-
-: (build) ( -- )
-
-  builds-check  
-
-  build-status off
-
-  enter-build-dir
-
-  "report" utf8
-    [
-      "Build machine:   " write host-name             print
-      "CPU:             " write cpu                   .
-      "OS:              " write os                    .
-      "Build directory: " write current-directory get print
-
-      git-clone [ "git clone failed" print ] run-or-bail
-
-      "factor"
-        [
-          record-git-id
-          do-make-clean
-          do-make-vm
-          copy-image
-          do-bootstrap
-          do-builder-test
-        ]
-      with-directory
-
-      "test-log" delete-file
-
-      "git id:          " write "git-id" eval-file print nl
-
-      "Boot time: " write "boot-time" eval-file milli-seconds>time print
-      "Load time: " write "load-time" eval-file milli-seconds>time print
-      "Test time: " write "test-time" eval-file milli-seconds>time print nl
-
-      "Did not pass load-everything: " print "load-everything-vocabs" cat
-      
-      "Did not pass test-all: "        print "test-all-vocabs"        cat
-                                             "test-failures"          cat
-      
-      "help-lint results:"             print "help-lint"              cat
-
-      "Benchmarks: " print "benchmarks" eval-file benchmarks.
-
-      nl
-
-      show-benchmark-deltas
-
-      "benchmarks" ".." copy-file-into
-
-      maybe-release
-    ]
-  with-file-writer
-
-  build-status on ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: builder-from
-
-SYMBOL: builder-recipients
-
-: tag-subject ( str -- str ) { "builder@" host-name* ": " , } bake to-string ;
-
-: subject ( -- str ) build-status get [ "report" ] [ "error" ] if tag-subject ;
-
-: send-builder-email ( -- )
-  <email>
-    builder-from get        >>from
-    builder-recipients get  >>to
-    subject                 >>subject
-    "./report" file>string >>body
-  send-email ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: compress-image ( -- ) { "bzip2" my-boot-image-name } to-strings try-process ;
-
-! : build ( -- )
-!   [ (build) ] try
-!   builds cd stamp> cd
-!   [ send-builder-email ] try
-!   { "rm" "-rf" "factor" } [ ] run-or-bail
-!   [ compress-image ] try ;
-
-: build ( -- )
-  [
-    (build)
-    build-dir
-      [
-        { "rm" "-rf" "factor" } try-process
-        compress-image
-      ]
-    with-directory
-  ]
-  try
-  send-builder-email ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USE: bootstrap.image.download
-
-: git-pull ( -- desc )
-  {
-    "git"
-    "pull"
-    "--no-summary"
-    "git://factorcode.org/git/factor.git"
-    "master"
-  } ;
-
-: updates-available? ( -- ? )
-  git-id
-  git-pull try-process
-  git-id
-  = not ;
-
-: new-image-available? ( -- ? )
-  my-boot-image-name need-new-image?
-    [ download-my-image t ]
-    [ f ]
-  if ;
-
 : build-loop ( -- )
   builds-check
   [
-    builds/factor
-      [
-        updates-available? new-image-available? or
-          [ build ]
-        when
-      ]
-    with-directory
+    builds/factor set-current-directory
+    new-code-available? [ build ] when
   ]
   try
   5 minutes sleep
   build-loop ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-MAIN: build-loop
+MAIN: build-loop
\ No newline at end of file
diff --git a/extra/builder/child/child.factor b/extra/builder/child/child.factor
new file mode 100644 (file)
index 0000000..0f701df
--- /dev/null
@@ -0,0 +1,68 @@
+
+USING: namespaces debugger io.files io.launcher accessors bootstrap.image
+       calendar builder.util builder.common ;
+
+IN: builder.child
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-clean ( -- ) { gnu-make "clean" } to-strings try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-vm ( -- )
+  <process>
+    gnu-make         >>command
+    "../compile-log" >>stdout
+    +stdout+         >>stderr
+  try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: builds-factor-image ( -- img ) builds/factor my-boot-image-name append-path ;
+
+: copy-image ( -- )
+  builds-factor-image ".." copy-file-into
+  builds-factor-image "."  copy-file-into ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: boot-cmd ( -- cmd )
+  { "./factor" { "-i=" my-boot-image-name } "-no-user-init" } to-strings ;
+
+: boot ( -- )
+  <process>
+    boot-cmd      >>command
+    +closed+      >>stdin
+    "../boot-log" >>stdout
+    +stdout+      >>stderr
+    60 minutes    >>timeout
+  try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: test-cmd ( -- cmd ) { "./factor" "-run=builder.test" } ;
+
+: test ( -- )
+  <process>
+    test-cmd      >>command
+    +closed+      >>stdin
+    "../test-log" >>stdout
+    +stdout+      >>stderr
+    240 minutes   >>timeout
+  try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: (build-child) ( -- )
+  make-clean
+  make-vm      status-vm   on
+  copy-image
+  boot         status-boot on
+  test         status-test on
+               status      on ;
+
+: build-child ( -- )
+  "factor" set-current-directory
+    [ (build-child) ] try
+  ".." set-current-directory ;
\ No newline at end of file
diff --git a/extra/builder/cleanup/cleanup.factor b/extra/builder/cleanup/cleanup.factor
new file mode 100644 (file)
index 0000000..327b90e
--- /dev/null
@@ -0,0 +1,24 @@
+
+USING: kernel namespaces io.files io.launcher bootstrap.image
+       builder.util builder.common ;
+
+IN: builder.cleanup
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: builder-debug
+
+: compress-image ( -- ) { "bzip2" my-boot-image-name } to-strings try-process ;
+
+: delete-child-factor ( -- )
+  build-dir [ { "rm" "-rf" "factor" } try-process ] with-directory ;
+
+: cleanup ( -- )
+  builder-debug get f =
+    [
+      "test-log" delete-file
+      delete-child-factor
+      compress-image
+    ]
+  when ;
+
index 6ebe1d625a983d8a7b9c65c4a980f6fb6d1ae134..e3c207eaaaf1dfa81014fddcffac3f6c56270e32 100644 (file)
@@ -1,5 +1,7 @@
 
-USING: kernel namespaces io.files sequences vars ;
+USING: kernel namespaces sequences splitting
+       io io.files io.launcher io.encodings.utf8 prettyprint
+       vars builder.util ;
 
 IN: builder.common
 
@@ -16,3 +18,47 @@ SYMBOL: builds-dir
 
 VAR: stamp
 
+: builds/factor ( -- path ) builds "factor" append-path ;
+: build-dir     ( -- path ) builds stamp>   append-path ;
+
+: create-build-dir ( -- )
+  datestamp >stamp
+  build-dir make-directory ;
+  
+: enter-build-dir  ( -- ) build-dir set-current-directory ;
+
+: clone-builds-factor ( -- )
+  { "git" "clone" builds/factor } to-strings try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: prepare-build-machine ( -- )
+  builds make-directory
+  builds
+    [ { "git" "clone" "git://factorcode.org/git/factor.git" } try-process ]
+  with-directory ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: builds-check ( -- ) builds exists? not [ prepare-build-machine ] when ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: status-vm
+SYMBOL: status-boot
+SYMBOL: status-test
+SYMBOL: status-build
+SYMBOL: status-release
+SYMBOL: status
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: reset-status ( -- )
+  { status-vm status-boot status-test status-build status-release status }
+    [ off ]
+  each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: upload-to-factorcode
+
diff --git a/extra/builder/email/email.factor b/extra/builder/email/email.factor
new file mode 100644 (file)
index 0000000..eed48cb
--- /dev/null
@@ -0,0 +1,22 @@
+
+USING: kernel namespaces accessors smtp builder.util builder.common ;
+
+IN: builder.email
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: builder-from
+SYMBOL: builder-recipients
+
+: subject-status ( -- str ) status get [ "report" ] [ "error" ] if ;
+
+: subject ( -- str ) { "builder@" host-name* ": " subject-status } to-string ;
+
+: email-report ( -- )
+  <email>
+    builder-from get       >>from
+    builder-recipients get >>to
+    subject                >>subject
+    "report" file>string   >>body
+  send-email ;
+
diff --git a/extra/builder/release/archive/archive.factor b/extra/builder/release/archive/archive.factor
new file mode 100644 (file)
index 0000000..9b239da
--- /dev/null
@@ -0,0 +1,58 @@
+
+USING: kernel combinators system sequences io.files io.launcher prettyprint
+       builder.util
+       builder.common ;
+
+IN: builder.release.archive
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: base-name ( -- string )
+  { "factor" [ os unparse ] cpu- stamp> } to-strings "-" join ;
+
+: extension ( -- extension )
+  {
+    { [ os winnt?  ] [ ".zip"    ] }  
+    { [ os macosx? ] [ ".dmg"    ] }
+    { [ os unix?   ] [ ".tar.gz" ] }
+  }
+  cond ;
+
+: archive-name ( -- string ) base-name extension append ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: windows-archive-cmd ( -- cmd ) { "zip" "-r" archive-name "factor" } ;
+
+: macosx-archive-cmd ( -- cmd )
+  { "hdiutil" "create"
+              "-srcfolder" "factor"
+              "-fs" "HFS+"
+              "-volname" "factor"
+              archive-name } ;
+
+: unix-archive-cmd ( -- cmd ) { "tar" "-cvzf" archive-name "factor" } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: archive-cmd ( -- cmd )
+  {
+    { [ os windows? ] [ windows-archive-cmd ] }
+    { [ os macosx?  ] [ macosx-archive-cmd  ] }
+    { [ os unix?    ] [ unix-archive-cmd    ] }
+  }
+  cond ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-archive ( -- ) archive-cmd to-strings try-process ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: releases ( -- path )
+  builds "releases" append-path
+  dup exists? not
+    [ dup make-directory ]
+  when ;
+
+: save-archive ( -- ) archive-name releases move-file-into ;
\ No newline at end of file
diff --git a/extra/builder/release/branch/branch.factor b/extra/builder/release/branch/branch.factor
new file mode 100644 (file)
index 0000000..6218a2e
--- /dev/null
@@ -0,0 +1,40 @@
+
+USING: kernel system namespaces sequences prettyprint io.files io.launcher
+       bootstrap.image
+       builder.util
+       builder.common ;
+
+IN: builder.release.branch
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: branch-name ( -- string ) "clean-" platform append ;
+
+: refspec ( -- string ) "master:" branch-name append ;
+
+: push-to-clean-branch ( -- )
+  { "git" "push" "factorcode.org:/git/factor.git" refspec }
+  to-strings
+  try-process ;
+
+: upload-clean-image ( -- )
+  {
+    "scp"
+    my-boot-image-name
+    "factorcode.org:/var/www/factorcode.org/newsite/images/clean"
+  }
+  to-strings
+  try-process ;
+
+: (update-clean-branch) ( -- )
+  "factor"
+    [
+      push-to-clean-branch
+      upload-clean-image
+    ]
+  with-directory ;
+
+: update-clean-branch ( -- )
+  upload-to-factorcode get
+    [ (update-clean-branch) ]
+  when ;
index 9b449a51c538f7d834b8da0c56d8000eae67cb00..8f4c0e30f537430a93dcc75597c335afd12e4058 100644 (file)
 
-USING: kernel system namespaces sequences splitting combinators
-       io io.files io.launcher prettyprint
-       bake combinators.cleave builder.common builder.util ;
+USING: kernel debugger system namespaces sequences splitting combinators
+       io io.files io.launcher prettyprint bootstrap.image
+       bake combinators.cleave
+       builder.util
+       builder.common
+       builder.release.branch
+       builder.release.tidy
+       builder.release.archive
+       builder.release.upload ;
 
 IN: builder.release
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: releases ( -- path )
-  builds "releases" append-path
-  dup exists? not
-    [ dup make-directory ]
-  when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: common-files ( -- seq )
-  {
-    "boot.x86.32.image"
-    "boot.x86.64.image"
-    "boot.macosx-ppc.image"
-    "boot.linux-ppc.image"
-    "vm"
-    "temp"
-    "logs"
-    ".git"
-    ".gitignore"
-    "Makefile"
-    "unmaintained"
-    "build-support"
-  } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: cpu- ( -- cpu ) cpu unparse "." split "-" join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: base-name ( -- string )
-  { "factor" [ os unparse ] cpu- stamp> } to-strings "-" join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: extension ( -- extension )
-  {
-    { [ os winnt?  ] [ ".zip"    ] }  
-    { [ os macosx? ] [ ".dmg"    ] }
-    { [ os unix?   ] [ ".tar.gz" ] }
-  }
-  cond ;
-
-: archive-name ( -- string ) base-name extension append ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: windows-archive-cmd ( -- cmd ) { "zip" "-r" archive-name "factor" } ;
-
-: macosx-archive-cmd ( -- cmd )
-  { "hdiutil" "create"
-              "-srcfolder" "factor"
-              "-fs" "HFS+"
-              "-volname" "factor"
-              archive-name } ;
-
-: unix-archive-cmd ( -- cmd ) { "tar" "-cvzf" archive-name "factor" } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: archive-cmd ( -- cmd )
-  {
-    { [ os windows? ] [ windows-archive-cmd ] }
-    { [ os macosx?  ] [ macosx-archive-cmd  ] }
-    { [ os unix?    ] [ unix-archive-cmd    ] }
-  }
-  cond ;
-
-: make-archive ( -- ) archive-cmd to-strings try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: remove-common-files ( -- )
-  { "rm" "-rf" common-files } to-strings try-process ;
-
-: remove-factor-app ( -- )
-  os macosx? not [ { "rm" "-rf" "Factor.app" } try-process ] when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: upload-to-factorcode
-
-: platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ;
-
-: remote-location ( -- dest )
-  "factorcode.org:/var/www/factorcode.org/newsite/downloads"
-  platform
-  append-path ;
-    
-: upload ( -- )
-  { "scp" archive-name remote-location } to-strings
-  [ "Error uploading binary to factorcode" print ]
-  run-or-bail ;
-
-: maybe-upload ( -- )
-  upload-to-factorcode get
-    [ upload ]
-  when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! : release ( -- )
-!   "factor"
-!     [
-!       remove-factor-app
-!       remove-common-files
-!     ]
-!   with-directory
-!   make-archive
-!   archive-name releases move-file-into ;
-
-: release ( -- )
-  "factor"
-    [
-      remove-factor-app
-      remove-common-files
-    ]
-  with-directory
+: (release) ( -- )
+  update-clean-branch
+  tidy
   make-archive
-  maybe-upload
-  archive-name releases move-file-into ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  upload
+  save-archive
+  status-release on ;
 
-: release? ( -- ? )
-  {
-    "./load-everything-vocabs"
-    "./test-all-vocabs"
-  }
-    [ eval-file empty? ]
-  all? ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: clean-build? ( -- ? )
+  { "load-everything-vocabs" "test-all-vocabs" } [ eval-file empty? ] all? ;
 
-: maybe-release ( -- ) release? [ release ] when ;
\ No newline at end of file
+: release ( -- ) [ clean-build? [ (release) ] when ] try ;
\ No newline at end of file
diff --git a/extra/builder/release/tidy/tidy.factor b/extra/builder/release/tidy/tidy.factor
new file mode 100644 (file)
index 0000000..f8f27e7
--- /dev/null
@@ -0,0 +1,29 @@
+
+USING: kernel system io.files io.launcher builder.util ;
+
+IN: builder.release.tidy
+
+: common-files ( -- seq )
+  {
+    "boot.x86.32.image"
+    "boot.x86.64.image"
+    "boot.macosx-ppc.image"
+    "boot.linux-ppc.image"
+    "vm"
+    "temp"
+    "logs"
+    ".git"
+    ".gitignore"
+    "Makefile"
+    "unmaintained"
+    "build-support"
+  } ;
+
+: remove-common-files ( -- )
+  { "rm" "-rf" common-files } to-strings try-process ;
+
+: remove-factor-app ( -- )
+  os macosx? not [ { "rm" "-rf" "Factor.app" } try-process ] when ;
+
+: tidy ( -- )
+  "factor" [ remove-factor-app remove-common-files ] with-directory ;
diff --git a/extra/builder/release/upload/upload.factor b/extra/builder/release/upload/upload.factor
new file mode 100644 (file)
index 0000000..38f6dcb
--- /dev/null
@@ -0,0 +1,24 @@
+
+USING: kernel namespaces io io.files
+       builder.util
+       builder.common
+       builder.release.archive ;
+
+IN: builder.release.upload
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: remote-location ( -- dest )
+  "factorcode.org:/var/www/factorcode.org/newsite/downloads"
+  platform
+  append-path ;
+
+: (upload) ( -- )
+  { "scp" archive-name remote-location } to-strings
+  [ "Error uploading binary to factorcode" print ]
+  run-or-bail ;
+
+: upload ( -- )
+  upload-to-factorcode get
+    [ (upload) ]
+  when ;
diff --git a/extra/builder/report/report.factor b/extra/builder/report/report.factor
new file mode 100644 (file)
index 0000000..101d259
--- /dev/null
@@ -0,0 +1,35 @@
+
+USING: kernel namespaces debugger system io io.files io.sockets
+       io.encodings.utf8 prettyprint benchmark
+       builder.util builder.common ;
+
+IN: builder.report
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: (report) ( -- )
+
+  "Build machine:   " write host-name             print
+  "CPU:             " write cpu                   .
+  "OS:              " write os                    .
+  "Build directory: " write build-dir             print
+  "git id:          " write "git-id" eval-file    print nl
+
+  status-vm   get f = [ "compile-log" cat    "vm compile error" throw ] when
+  status-boot get f = [ "boot-log"    cat    "Boot error"       throw ] when
+  status-test get f = [ "test-log" 100 cat-n "Test error"       throw ] when
+
+  "Boot time: " write "boot-time" eval-file milli-seconds>time print
+  "Load time: " write "load-time" eval-file milli-seconds>time print
+  "Test time: " write "test-time" eval-file milli-seconds>time print nl
+
+  "Did not pass load-everything: " print "load-everything-vocabs" cat
+      
+  "Did not pass test-all: "        print "test-all-vocabs"        cat
+                                         "test-failures"          cat
+      
+  "help-lint results:"             print "help-lint"              cat
+
+  "Benchmarks: " print "benchmarks" eval-file benchmarks. ;
+
+: report ( -- ) "report" utf8 [ [ (report) ] try ] with-file-writer ;
\ No newline at end of file
index d5c3e9cd941cd54d241349360e406e7425386f1c..957af28dc14f7a5f443221c1e1a2bc5f68c63ff2 100644 (file)
@@ -1,16 +1,4 @@
 
-! USING: kernel namespaces sequences assocs continuations
-!        vocabs vocabs.loader
-!        io
-!        io.files
-!        prettyprint
-!        tools.vocabs
-!        tools.test
-!        io.encodings.utf8
-!        combinators.cleave
-!        help.lint
-!        bootstrap.stage2 benchmark builder.util ;
-
 USING: kernel namespaces assocs
        io.files io.encodings.utf8 prettyprint 
        help.lint
diff --git a/extra/builder/updates/updates.factor b/extra/builder/updates/updates.factor
new file mode 100644 (file)
index 0000000..a818455
--- /dev/null
@@ -0,0 +1,31 @@
+
+USING: kernel io.launcher bootstrap.image bootstrap.image.download
+       builder.util builder.common ;
+
+IN: builder.updates
+
+: git-pull-cmd ( -- cmd )
+  {
+    "git"
+    "pull"
+    "--no-summary"
+    "git://factorcode.org/git/factor.git"
+    "master"
+  } ;
+
+: updates-available? ( -- ? )
+  git-id
+  git-pull-cmd try-process
+  git-id
+  = not ;
+
+: new-image-available? ( -- ? )
+  my-boot-image-name need-new-image?
+    [ download-my-image t ]
+    [ f ]
+  if ;
+
+: new-code-available? ( -- ? )
+  updates-available?
+  new-image-available?
+  or ;
\ No newline at end of file
index 92b9af41ef284fcd572295fff1869eb362156cc9..3b0834b19056556137265a969d6d7184b9a2f1c7 100644 (file)
@@ -2,6 +2,7 @@
 USING: kernel words namespaces classes parser continuations
        io io.files io.launcher io.sockets
        math math.parser
+       system
        combinators sequences splitting quotations arrays strings tools.time
        sequences.deep accessors assocs.lib
        io.encodings.utf8
@@ -24,11 +25,11 @@ DEFER: to-strings
 : to-string ( obj -- str )
   dup class
     {
-      { string    [ ] }
-      { quotation [ call ] }
-      { word      [ execute ] }
-      { fixnum    [ number>string ] }
-      { array     [ to-strings concat ] }
+      { string    [ ] }
+      { quotation [ call ] }
+      { word      [ execute ] }
+      { fixnum    [ number>string ] }
+      { array     [ to-strings concat ] }
     }
   case ;
 
@@ -40,21 +41,6 @@ DEFER: to-strings
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-! TUPLE: process* arguments stdin stdout stderr timeout ;
-
-! : <process*> process* construct-empty ;
-
-! : >desc ( process* -- desc )
-!   H{ } clone
-!     over arguments>> [ +arguments+ swap put-at ] when*
-!     over stdin>>     [ +stdin+     swap put-at ] when*
-!     over stdout>>    [ +stdout+    swap put-at ] when*
-!     over stderr>>    [ +stderr+    swap put-at ] when*
-!     over timeout>>   [ +timeout+   swap put-at ] when*
-!   nip ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
 : host-name* ( -- name ) host-name "." split first ;
 
 : datestamp ( -- string )
@@ -109,4 +95,17 @@ USE: prettyprint
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: failsafe ( quot -- ) [ drop ] recover ;
+: cpu- ( -- cpu ) cpu unparse "." split "-" join ;
+
+: platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: gnu-make ( -- string )
+  os { freebsd openbsd netbsd } member? [ "gmake" ] [ "make" ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: git-id ( -- id )
+  { "git" "show" } utf8 <process-stream> [ readln ] with-stream
+  " " split second ;
index 2cb0df5ca11d6c5eaa0aae17fa9a4395c5811b9f..897a30c417841d4d4fff90b3f0a395ccb8961caa 100755 (executable)
@@ -13,7 +13,7 @@ IN: bunny.model
         numbers {
             { [ dup length 5 = ] [ 3 head pick push ] }
             { [ dup first 3 = ] [ 1 tail over push ] }
-            { [ t ] [ drop ] }
+            [ drop ]
         } cond (parse-model)
     ] when* ;
 
@@ -61,7 +61,7 @@ TUPLE: bunny-buffers array element-array nv ni ;
 
 : <bunny-dlist> ( model -- geom )
     GL_COMPILE [ first3 draw-triangles ] make-dlist
-    bunny-dlist construct-boa ;
+    bunny-dlist boa ;
 
 : <bunny-buffers> ( model -- geom )
     {
@@ -76,7 +76,7 @@ TUPLE: bunny-buffers array element-array nv ni ;
         ]
         [ first length 3 * ]
         [ third length 3 * ]
-    } cleave bunny-buffers construct-boa ;
+    } cleave bunny-buffers boa ;
 
 GENERIC: bunny-geom ( geom -- )
 GENERIC: draw-bunny ( geom draw -- )
index f9908e4581fe6136a8d50411ad8da4e2814efb9e..1bbad298358fd478df9291d01ac66499462b003f 100755 (executable)
@@ -10,17 +10,17 @@ TUPLE: png-gadget png ;
 
 ERROR: cairo-error string ;
 
-: check-zero
+: check-zero ( n -- n )
     dup zero? [
         "PNG dimension is 0" cairo-error
     ] when ;
 
 : cairo-png-error ( n -- )
     {
-        { [ dup CAIRO_STATUS_NO_MEMORY = ] [ "Cairo: no memory" cairo-error ] }
-        { [ dup CAIRO_STATUS_FILE_NOT_FOUND = ] [ "Cairo: file not found" cairo-error ] }
-        { [ dup CAIRO_STATUS_READ_ERROR = ] [ "Cairo: read error" cairo-error ] }
-        { [ t ] [ drop ] }
+        { CAIRO_STATUS_NO_MEMORY [ "Cairo: no memory" cairo-error ] }
+        { CAIRO_STATUS_FILE_NOT_FOUND [ "Cairo: file not found" cairo-error ] }
+        { CAIRO_STATUS_READ_ERROR [ "Cairo: read error" cairo-error ] }
+        [ drop ]
     } cond ;
 
 : <png> ( path -- png )
@@ -29,7 +29,7 @@ ERROR: cairo-error string ;
     dup cairo_surface_status cairo-png-error
     dup [ cairo_image_surface_get_width check-zero ]
     [ cairo_image_surface_get_height check-zero ] [ ] tri
-    cairo-surface>array png construct-boa ;
+    cairo-surface>array png boa ;
 
 : write-png ( png path -- )
     >r png-surface r>
diff --git a/extra/calendar/windows/tags.txt b/extra/calendar/windows/tags.txt
new file mode 100644 (file)
index 0000000..8e1a559
--- /dev/null
@@ -0,0 +1 @@
+windows
index 2986422155b6bf812f0880ce53a3a6ad890768eb..b621d3bde3609440c228248a3be7fcefc6c04d11 100755 (executable)
@@ -5,12 +5,11 @@ IN: calendar.windows
 M: windows gmt-offset ( -- hours minutes seconds )
     "TIME_ZONE_INFORMATION" <c-object>
     dup GetTimeZoneInformation {
-        { [ dup TIME_ZONE_ID_INVALID = ] [ win32-error-string throw ] }
-        { [ dup [ TIME_ZONE_ID_UNKNOWN = ] [ TIME_ZONE_ID_STANDARD = ] bi or ] [
-            drop TIME_ZONE_INFORMATION-Bias ] }
-        { [ dup TIME_ZONE_ID_DAYLIGHT = ] [
-            drop
+        { TIME_ZONE_ID_INVALID [ win32-error-string throw ] }
+        { TIME_ZONE_ID_UNKNOWN [ TIME_ZONE_INFORMATION-Bias ] }
+        { TIME_ZONE_ID_STANDARD [ TIME_ZONE_INFORMATION-Bias ] }
+        { TIME_ZONE_ID_DAYLIGHT [
             [ TIME_ZONE_INFORMATION-Bias ]
             [ TIME_ZONE_INFORMATION-DaylightBias ] bi +
         ] }
-    } cond neg 60 /mod 0 ;
+    } case neg 60 /mod 0 ;
index 8fe36ab45414834abd2ea162dcbd655a713c0ffe..ea54766ad4e744c5a307acff806a60641b10cc1c 100755 (executable)
@@ -9,7 +9,7 @@ IN: channels
 TUPLE: channel receivers senders ;
 
 : <channel> ( -- channel )
-    V{ } clone V{ } clone channel construct-boa ;
+    V{ } clone V{ } clone channel boa ;
 
 GENERIC: to ( value channel -- )
 GENERIC: from ( channel -- value )
index 08deb004e885753f539807f89e6eb7d60f394c3d..77dfb557668a12f15bc5790d844508305fc5000a 100755 (executable)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2005, 2006 Alex Chapman, Daniel Ehrenberg
 ! See http;//factorcode.org/license.txt for BSD license
-USING: kernel sequences math sequences.private strings ;
+USING: kernel sequences math sequences.private strings
+accessors ;
 IN: circular
 
 ! a circular sequence wraps another sequence, but begins at an
@@ -8,30 +9,30 @@ IN: circular
 TUPLE: circular seq start ;
 
 : <circular> ( seq -- circular )
-    0 circular construct-boa ;
+    0 circular boa ;
 
 : circular-wrap ( n circular -- n circular )
-    [ circular-start + ] keep
-    [ circular-seq length rem ] keep ; inline
+    [ start>> + ] keep
+    [ seq>> length rem ] keep ; inline
 
-M: circular length circular-seq length ;
+M: circular length seq>> length ;
 
-M: circular virtual@ circular-wrap circular-seq ;
+M: circular virtual@ circular-wrap seq>> ;
 
 M: circular nth virtual@ nth ;
 
 M: circular set-nth virtual@ set-nth ;
 
+M: circular virtual-seq seq>> ;
+
 : change-circular-start ( n circular -- )
     #! change start to (start + n) mod length
-    circular-wrap set-circular-start ;
+    circular-wrap (>>start) ;
 
 : push-circular ( elt circular -- )
-    [ set-first ] keep 1 swap change-circular-start ;
+    [ set-first ] [ 1 swap change-circular-start ] bi ;
 
 : <circular-string> ( n -- circular )
     0 <string> <circular> ;
 
-M: circular virtual-seq circular-seq ;
-
 INSTANCE: circular virtual-sequence
index 20431da07b2251c59652e6ae304059ae70ac8388..34dd181d3b59c3b01e5d979b496484a59ce12bfa 100644 (file)
@@ -7,7 +7,7 @@ HELP: >tuple<
 { $example
     "USING: kernel prettyprint classes.tuple.lib ;"
     "TUPLE: foo a b c ;"
-    "1 2 3 \\ foo construct-boa \\ foo >tuple< .s"
+    "1 2 3 \\ foo boa \\ foo >tuple< .s"
     "1\n2\n3"
 }
 { $notes "Words using " { $snippet ">tuple<" } " may be compiled." }
@@ -19,7 +19,7 @@ HELP: >tuple*<
 { $example
     "USING: kernel prettyprint classes.tuple.lib ;"
     "TUPLE: foo a bb* ccc dddd* ;"
-    "1 2 3 4 \\ foo construct-boa \\ foo >tuple*< .s"
+    "1 2 3 4 \\ foo boa \\ foo >tuple*< .s"
     "2\n4"
 }
 { $notes "Words using " { $snippet ">tuple*<" } " may be compiled." }
index 328f83d714faf934b71e654b1762cf8e6bc282aa..7f7f24ab56e0553b03f812f4abb4ecd23fb172a8 100644 (file)
@@ -3,6 +3,6 @@ IN: classes.tuple.lib.tests
 
 TUPLE: foo a b* c d* e f* ;
 
-[ 1 2 3 4 5 6 ] [ 1 2 3 4 5 6 \ foo construct-boa \ foo >tuple< ] unit-test
-[ 2 4 6 ] [ 1 2 3 4 5 6 \ foo construct-boa \ foo >tuple*< ] unit-test
+[ 1 2 3 4 5 6 ] [ 1 2 3 4 5 6 \ foo boa \ foo >tuple< ] unit-test
+[ 2 4 6 ] [ 1 2 3 4 5 6 \ foo boa \ foo >tuple*< ] unit-test
 
index 0cf020a0872d4adfbfbe1130fd1fb488ffb741c0..2ae17a1604d719cb66a440a5170a10f25311e8f6 100755 (executable)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2006, 2007 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien io kernel namespaces core-foundation cocoa.messages
-cocoa cocoa.classes cocoa.runtime sequences threads
-debugger init inspector kernel.private ;
+USING: alien io kernel namespaces core-foundation
+core-foundation.run-loop cocoa.messages cocoa cocoa.classes
+cocoa.runtime sequences threads debugger init inspector
+kernel.private ;
 IN: cocoa.application
 
 : <NSString> ( str -- alien ) <CFString> -> autorelease ;
@@ -21,8 +22,6 @@ IN: cocoa.application
 : with-cocoa ( quot -- )
     [ NSApp drop call ] with-autorelease-pool ;
 
-: CFRunLoopDefaultMode "kCFRunLoopDefaultMode" <NSString> ;
-
 : next-event ( app -- event )
     0 f CFRunLoopDefaultMode 1
     -> nextEventMatchingMask:untilDate:inMode:dequeue: ;
@@ -50,7 +49,7 @@ IN: cocoa.application
 TUPLE: objc-error alien reason ;
 
 : objc-error ( alien -- * )
-    dup -> reason CF>string \ objc-error construct-boa throw ;
+    dup -> reason CF>string \ objc-error boa throw ;
 
 M: objc-error summary ( error -- )
     drop "Objective C exception" ;
index 480e19b00583ba940ab16b9387aff335b911611e..ca9509c3ec917bd8ee16939af932d04c2073ce9c 100755 (executable)
@@ -43,7 +43,7 @@ super-message-senders global [ H{ } assoc-like ] change-at
 
 TUPLE: selector name object ;
 
-MEMO: <selector> ( name -- sel ) f \ selector construct-boa ;
+MEMO: <selector> ( name -- sel ) f \ selector boa ;
 
 : selector ( selector -- alien )
     dup selector-object expired? [
@@ -139,7 +139,7 @@ H{
     { "NSRect" "{_NSRect=ffff}" }
     { "NSSize" "{_NSSize=ff}" }
     { "NSRange" "{_NSRange=II}" }
-} union alien>objc-types set-global
+} assoc-union alien>objc-types set-global
 
 : objc-struct-type ( i string -- ctype )
     2dup CHAR: = -rot index* swap subseq
@@ -154,7 +154,7 @@ H{
         { [ dup CHAR: ^ = ] [ 3drop "void*" ] }
         { [ dup CHAR: { = ] [ drop objc-struct-type ] }
         { [ dup CHAR: [ = ] [ 3drop "void*" ] }
-        { [ t ] [ 2nip 1string objc>alien-types get at ] }
+        [ 2nip 1string objc>alien-types get at ]
     } cond ;
 
 : parse-objc-type ( string -- ctype ) 0 swap (parse-objc-type) ;
index deb03f72e2cfc7ea953ee6c21a8a3bb9f80db8ab..84b41a91ff6ae3006c23ecd70b61907f5add5f0a 100755 (executable)
@@ -137,7 +137,7 @@ MACRO: map-exec-with ( words -- )
     [ 1quotation ] map [ map-call-with ] curry ;
 
 MACRO: construct-slots ( assoc tuple-class -- tuple ) 
-    [ construct-empty ] curry swap [
+    [ new ] curry swap [
         [ dip ] curry swap 1quotation [ keep ] curry compose
     ] { } assoc>map concat compose ;
 
index 0f18fcf4319402eb5d6e05c0d55e3dfb51fb0b8c..731a740983efe97ecd0dc4c0258d11da48f051e5 100755 (executable)
@@ -1,6 +1,6 @@
 IN: concurrency.combinators.tests\r
 USING: concurrency.combinators tools.test random kernel math \r
-concurrency.mailboxes threads sequences ;\r
+concurrency.mailboxes threads sequences accessors ;\r
 \r
 [ [ drop ] parallel-each ] must-infer\r
 [ [ ] parallel-map ] must-infer\r
@@ -11,7 +11,7 @@ concurrency.mailboxes threads sequences ;
 [ { 1 4 9 } ] [ { 1 2 3 } [ 1000 random sleep sq ] parallel-map ] unit-test\r
 \r
 [ { 1 2 3 } [ dup 2 mod 0 = [ "Even" throw ] when ] parallel-map ]\r
-[ delegate "Even" = ] must-fail-with\r
+[ error>> "Even" = ] must-fail-with\r
 \r
 [ V{ 0 3 6 9 } ]\r
 [ 10 [ 3 mod zero? ] parallel-subset ] unit-test\r
index b1fa137bc4ea61aea6501322c79eba8408db26bb..6a75f7206c8cf183ad7cc69f489db2608c2ecd26 100755 (executable)
@@ -15,7 +15,7 @@ TUPLE: count-down n promise ;
 \r
 : <count-down> ( n -- count-down )\r
     dup 0 < [ "Invalid count for count down" throw ] when\r
-    <promise> \ count-down construct-boa\r
+    <promise> \ count-down boa\r
     dup count-down-check ;\r
 \r
 : count-down ( count-down -- )\r
index 0a631d1c7b0423d9a15a36bfcab29dc333217197..d9d6809602f04cf403995c184d97164f1ad8ac01 100755 (executable)
@@ -9,7 +9,7 @@ IN: concurrency.exchangers
 TUPLE: exchanger thread object ;\r
 \r
 : <exchanger> ( -- exchanger )\r
-    <box> <box> exchanger construct-boa ;\r
+    <box> <box> exchanger boa ;\r
 \r
 : exchange ( obj exchanger -- newobj )\r
     dup exchanger-thread box-full? [\r
index d598bf0b592ed52b79ce430cf9a7af1f1bf8e596..b3c76a7a01694bd7a6ee4ac6989194c1e7109a99 100755 (executable)
@@ -5,7 +5,7 @@ IN: concurrency.flags
 
 TUPLE: flag value? thread ;
 
-: <flag> ( -- flag ) f <box> flag construct-boa ;
+: <flag> ( -- flag ) f <box> flag boa ;
 
 : raise-flag ( flag -- )
     dup flag-value? [
index 43f22c00dab822dbf522a5d359590fb2a8a2af79..b5ea247420ec515e11129e00d62268dd24200fe9 100755 (executable)
@@ -8,10 +8,10 @@ IN: concurrency.locks
 TUPLE: lock threads owner reentrant? ;\r
 \r
 : <lock> ( -- lock )\r
-    <dlist> f f lock construct-boa ;\r
+    <dlist> f f lock boa ;\r
 \r
 : <reentrant-lock> ( -- lock )\r
-    <dlist> f t lock construct-boa ;\r
+    <dlist> f t lock boa ;\r
 \r
 <PRIVATE\r
 \r
@@ -51,7 +51,7 @@ PRIVATE>
 TUPLE: rw-lock readers writers reader# writer ;\r
 \r
 : <rw-lock> ( -- lock )\r
-    <dlist> <dlist> 0 f rw-lock construct-boa ;\r
+    <dlist> <dlist> 0 f rw-lock boa ;\r
 \r
 <PRIVATE\r
 \r
index 50694776c515b02e2b58719f1d52bcd7f3c33dec..a9b86e3bcdef714046410bfcc82568cf9c89826f 100755 (executable)
@@ -57,7 +57,7 @@ HELP: mailbox-get?
 \r
 \r
 ARTICLE: "concurrency.mailboxes" "Mailboxes"\r
-"A " { $emphasis "mailbox" } " is a first-in-first-out queue where the operation of removing an element blocks if the queue is empty, instead of throwing an error."\r
+"A " { $emphasis "mailbox" } " is a first-in-first-out queue where the operation of removing an element blocks if the queue is empty, instead of throwing an error. Mailboxes are implemented in the " { $vocab-link "concurrency.mailboxes" } " vocabulary."\r
 { $subsection mailbox }\r
 { $subsection <mailbox> }\r
 "Removing the first element:"\r
@@ -73,3 +73,5 @@ ARTICLE: "concurrency.mailboxes" "Mailboxes"
 "Testing if a mailbox is empty:"\r
 { $subsection mailbox-empty? }\r
 { $subsection while-mailbox-empty } ;\r
+\r
+ABOUT: "concurrency.mailboxes"\r
index 2cb12bcabaf47fc7155876c3338b451cdaf432de..7fe09cdcf5b849f9c28f6466e47bc52753adc624 100755 (executable)
@@ -1,6 +1,7 @@
 IN: concurrency.mailboxes.tests\r
-USING: concurrency.mailboxes vectors sequences threads\r
-tools.test math kernel strings ;\r
+USING: concurrency.mailboxes concurrency.count-downs vectors\r
+sequences threads tools.test math kernel strings namespaces\r
+continuations calendar ;\r
 \r
 [ V{ 1 2 3 } ] [\r
     0 <vector>\r
@@ -38,3 +39,37 @@ tools.test math kernel strings ;
     "junk2" over mailbox-put\r
     mailbox-get\r
 ] unit-test\r
+\r
+<mailbox> "m" set\r
+\r
+1 <count-down> "c" set\r
+1 <count-down> "d" set\r
+\r
+[\r
+    "c" get await\r
+    [ "m" get mailbox-get drop ]\r
+    [ drop "d" get count-down ] recover\r
+] "Mailbox close test" spawn drop\r
+\r
+[ ] [ "c" get count-down ] unit-test\r
+[ ] [ "m" get dispose ] unit-test\r
+[ ] [ "d" get 5 seconds await-timeout ] unit-test\r
+\r
+[ ] [ "m" get dispose ] unit-test\r
+\r
+<mailbox> "m" set\r
+\r
+1 <count-down> "c" set\r
+1 <count-down> "d" set\r
+\r
+[\r
+    "c" get await\r
+    "m" get wait-for-close\r
+    "d" get count-down\r
+] "Mailbox close test" spawn drop\r
+\r
+[ ] [ "c" get count-down ] unit-test\r
+[ ] [ "m" get dispose ] unit-test\r
+[ ] [ "d" get 5 seconds await-timeout ] unit-test\r
+\r
+[ ] [ "m" get dispose ] unit-test\r
index 7b6405679f52242e9ec0f9939990c63c1b1a88a5..ac0319770817a0fc3814e110d29c804744609f82 100755 (executable)
@@ -3,41 +3,50 @@
 IN: concurrency.mailboxes\r
 USING: dlists threads sequences continuations\r
 namespaces random math quotations words kernel arrays assocs\r
-init system concurrency.conditions ;\r
+init system concurrency.conditions accessors ;\r
 \r
-TUPLE: mailbox threads data ;\r
+TUPLE: mailbox threads data closed ;\r
+\r
+: check-closed ( mailbox -- )\r
+    closed>> [ "Mailbox closed" throw ] when ; inline\r
+\r
+M: mailbox dispose\r
+    t >>closed threads>> notify-all ;\r
 \r
 : <mailbox> ( -- mailbox )\r
-    <dlist> <dlist> mailbox construct-boa ;\r
+    <dlist> <dlist> f mailbox boa ;\r
 \r
 : mailbox-empty? ( mailbox -- bool )\r
-    mailbox-data dlist-empty? ;\r
+    data>> dlist-empty? ;\r
 \r
 : mailbox-put ( obj mailbox -- )\r
-    [ mailbox-data push-front ] keep\r
-    mailbox-threads notify-all yield ;\r
+    [ data>> push-front ]\r
+    [ threads>> notify-all ] bi yield ;\r
+\r
+: wait-for-mailbox ( mailbox timeout -- )\r
+    >r threads>> r> "mailbox" wait ;\r
 \r
 : block-unless-pred ( mailbox timeout pred -- )\r
-    pick mailbox-data over dlist-contains? [\r
+    pick check-closed\r
+    pick data>> over dlist-contains? [\r
         3drop\r
     ] [\r
-        >r over mailbox-threads over "mailbox" wait r>\r
-        block-unless-pred\r
+        >r 2dup wait-for-mailbox r> block-unless-pred\r
     ] if ; inline\r
 \r
 : block-if-empty ( mailbox timeout -- mailbox )\r
+    over check-closed\r
     over mailbox-empty? [\r
-        over mailbox-threads over "mailbox" wait\r
-        block-if-empty\r
+        2dup wait-for-mailbox block-if-empty\r
     ] [\r
         drop\r
     ] if ;\r
 \r
 : mailbox-peek ( mailbox -- obj )\r
-    mailbox-data peek-back ;\r
+    data>> peek-back ;\r
 \r
 : mailbox-get-timeout ( mailbox timeout -- obj )\r
-    block-if-empty mailbox-data pop-back ;\r
+    block-if-empty data>> pop-back ;\r
 \r
 : mailbox-get ( mailbox -- obj )\r
     f mailbox-get-timeout ;\r
@@ -45,7 +54,7 @@ TUPLE: mailbox threads data ;
 : mailbox-get-all-timeout ( mailbox timeout -- array )\r
     block-if-empty\r
     [ dup mailbox-empty? ]\r
-    [ dup mailbox-data pop-back ]\r
+    [ dup data>> pop-back ]\r
     [ ] unfold nip ;\r
 \r
 : mailbox-get-all ( mailbox -- array )\r
@@ -60,28 +69,31 @@ TUPLE: mailbox threads data ;
 \r
 : mailbox-get-timeout? ( mailbox timeout pred -- obj )\r
     3dup block-unless-pred\r
-    nip >r mailbox-data r> delete-node-if ; inline\r
+    nip >r data>> r> delete-node-if ; inline\r
 \r
 : mailbox-get? ( mailbox pred -- obj )\r
     f swap mailbox-get-timeout? ; inline\r
 \r
-TUPLE: linked-error thread ;\r
+: wait-for-close-timeout ( mailbox timeout -- )\r
+    over closed>>\r
+    [ 2drop ] [ 2dup wait-for-mailbox wait-for-close-timeout ] if ;\r
+\r
+: wait-for-close ( mailbox -- )\r
+    f wait-for-close-timeout ;\r
+\r
+TUPLE: linked-error error thread ;\r
 \r
-: <linked-error> ( error thread -- linked )\r
-    { set-delegate set-linked-error-thread }\r
-    linked-error construct ;\r
+C: <linked-error> linked-error\r
 \r
 : ?linked dup linked-error? [ rethrow ] when ;\r
 \r
-TUPLE: linked-thread supervisor ;\r
+TUPLE: linked-thread < thread supervisor ;\r
 \r
 M: linked-thread error-in-thread\r
-    [ <linked-error> ] keep\r
-    linked-thread-supervisor mailbox-put ;\r
+    [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;\r
 \r
 : <linked-thread> ( quot name mailbox -- thread' )\r
-    >r <thread> linked-thread construct-delegate r>\r
-    over set-linked-thread-supervisor ;\r
+    >r linked-thread new-thread r> >>supervisor ;\r
 \r
 : spawn-linked-to ( quot name mailbox -- thread )\r
     <linked-thread> [ (spawn) ] keep ;\r
index e7aa5d1a7e496be1154bd7faaa2f21c45a0ad9cd..1219982f510b129567f95af4d1c6de5b4186c5cc 100755 (executable)
@@ -32,7 +32,7 @@ HELP: spawn-linked
 { $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" } 
 { $see-also spawn } ;
 
-ARTICLE: { "concurrency" "messaging" } "Mailboxes"
+ARTICLE: { "concurrency" "messaging" } "Sending and receiving messages"
 "Each thread has an associated mailbox. Other threads can place items on this queue by sending the thread a message. A thread can check its mailbox for messages, blocking if none are pending, and thread them as they are queued."
 $nl
 "The messages that are sent from thread to thread are any Factor value. Factor tuples are ideal for this sort of thing as you can send a tuple to a thread and the generic word dispatch mechanism can be used to perform actions depending on what the type of the tuple is."
@@ -43,7 +43,8 @@ $nl
 { $subsection receive }
 { $subsection receive-timeout }
 { $subsection receive-if }
-{ $subsection receive-if-timeout } ;
+{ $subsection receive-if-timeout }
+{ $see-also "concurrency.mailboxes" } ;
 
 ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends"
 "The " { $link send } " word sends a message asynchronously, and the sending thread continues immediately. It is also possible to send a message to a thread and block until a response is received:"
index 6de381b166108ba775169f25dea7b7be1ea86769..00184bac05413a334ab240f780815bfc30f2dd93 100755 (executable)
@@ -3,7 +3,8 @@
 !
 USING: kernel threads vectors arrays sequences
 namespaces tools.test continuations dlists strings math words
-match quotations concurrency.messaging concurrency.mailboxes ;
+match quotations concurrency.messaging concurrency.mailboxes
+concurrency.count-downs accessors ;
 IN: concurrency.messaging.tests
 
 [ ] [ my-mailbox mailbox-data dlist-delete-all ] unit-test
@@ -29,7 +30,7 @@ IN: concurrency.messaging.tests
         "crash" throw
     ] "Linked test" spawn-linked drop
     receive
-] [ delegate "crash" = ] must-fail-with
+] [ error>> "crash" = ] must-fail-with
 
 MATCH-VARS: ?from ?to ?value ;
 SYMBOL: increment
@@ -52,4 +53,15 @@ SYMBOL: exit
     [ value , self , ] { } make "counter" get send
     receive
     exit "counter" get send
-] unit-test
\ No newline at end of file
+] unit-test
+
+! Not yet
+
+! 1 <count-down> "c" set
+
+! [
+!     "c" get count-down
+!     receive drop
+! ] "Bad synchronous send" spawn "t" set
+
+! [ 3 "t" get send-synchronous ] must-fail
\ No newline at end of file
index 2cd83d43f55e24e73ef3a25762b18039aa3f7efc..66c5e421fab01cf54ba2b85c6ce9ebcf077fa3be 100755 (executable)
@@ -40,12 +40,12 @@ M: thread send ( message thread -- )
 TUPLE: synchronous data sender tag ;\r
 \r
 : <synchronous> ( data -- sync )\r
-    self 256 random-bits synchronous construct-boa ;\r
+    self 256 random-bits synchronous boa ;\r
 \r
 TUPLE: reply data tag ;\r
 \r
 : <reply> ( data synchronous -- reply )\r
-    synchronous-tag \ reply construct-boa ;\r
+    synchronous-tag \ reply boa ;\r
 \r
 : synchronous-reply? ( response synchronous -- ? )\r
     over reply?\r
index b7ccff7fa7ffb777de3c1f7fb15e06e1dddf823a..b432d63bfca5c1033005105f5528b8ff8b98d615 100755 (executable)
@@ -6,7 +6,7 @@ IN: concurrency.promises
 TUPLE: promise mailbox ;\r
 \r
 : <promise> ( -- promise )\r
-    <mailbox> promise construct-boa ;\r
+    <mailbox> promise boa ;\r
 \r
 : promise-fulfilled? ( promise -- ? )\r
     promise-mailbox mailbox-empty? not ;\r
index 031614ea951e914557eef8e43274f4e1b72a567d..8b88c540bc629dd414f22c03d8afc70da71dc354 100755 (executable)
@@ -8,7 +8,7 @@ TUPLE: semaphore count threads ;
 \r
 : <semaphore> ( n -- semaphore )\r
     dup 0 < [ "Cannot have semaphore with negative count" throw ] when\r
-    <dlist> semaphore construct-boa ;\r
+    <dlist> semaphore boa ;\r
 \r
 : wait-to-acquire ( semaphore timeout -- )\r
     >r semaphore-threads r> "semaphore" wait ;\r
index d0da724cc6d6df72877b43e2f10776969a2f8539..868e9681696344c79e6e2ded3d6c753fcee913a1 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.files io.launcher io.styles io hashtables kernel
-sequences sequences.lib assocs system sorting math.parser ;
+sequences sequences.lib assocs system sorting math.parser
+sets ;
 IN: contributors
 
 : changelog ( -- authors )
index 73b8fce22907924bf49ad8a6c9d336ec712c9f4b..77ad30ad8ff4acdbc4793d1795f8183c569e3f9b 100644 (file)
@@ -9,9 +9,9 @@ TYPEDEF: void* CFBundleRef
 TYPEDEF: void* CFStringRef
 TYPEDEF: void* CFURLRef
 TYPEDEF: void* CFUUIDRef
-TYPEDEF: void* CFRunLoopRef
 TYPEDEF: bool Boolean
 TYPEDEF: int CFIndex
+TYPEDEF: int SInt32
 TYPEDEF: double CFTimeInterval
 TYPEDEF: double CFAbsoluteTime
 
@@ -85,5 +85,3 @@ FUNCTION: void CFRelease ( void* cf ) ;
     ] [
         "Cannot load bundled named " prepend throw
     ] ?if ;
-
-FUNCTION: CFRunLoopRef CFRunLoopGetMain ( ) ;
index 55f2462061c8bd7dec4f5a3cbaeb52ace8b5ba97..3c9dbdbef021928e24871ecd6a6d481b07e06de9 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.syntax kernel math sequences
-namespaces assocs init continuations core-foundation ;
+namespaces assocs init accessors continuations combinators
+core-foundation core-foundation.run-loop ;
 IN: core-foundation.fsevents
 
 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
@@ -151,12 +152,9 @@ SYMBOL: event-stream-callbacks
 
 [
     event-stream-callbacks global
-    [ [ drop expired? not ] assoc-subset ] change-at
-    1 \ event-stream-counter set-global
+    [ [ drop expired? not ] assoc-subset H{ } assoc-like ] change-at
 ] "core-foundation" add-init-hook
 
-event-stream-callbacks global [ H{ } assoc-like ] change-at
-
 : add-event-source-callback ( quot -- id )
     event-stream-counter <alien>
     [ event-stream-callbacks get set-at ] keep ;
@@ -184,11 +182,11 @@ event-stream-callbacks global [ H{ } assoc-like ] change-at
     }
     "cdecl" [
         [ >event-triple ] 3curry map
-        swap event-stream-callbacks get at call
-        drop
+        swap event-stream-callbacks get at
+        dup [ call drop ] [ 3drop ] if
     ] alien-callback ;
 
-TUPLE: event-stream info handle ;
+TUPLE: event-stream info handle closed ;
 
 : <event-stream> ( quot paths latency flags -- event-stream )
     >r >r >r
@@ -196,9 +194,15 @@ TUPLE: event-stream info handle ;
     >r master-event-source-callback r>
     r> r> r> <FSEventStream>
     dup enable-event-stream
-    event-stream construct-boa ;
+    f event-stream boa ;
 
 M: event-stream dispose
-    dup event-stream-info remove-event-source-callback
-    event-stream-handle dup disable-event-stream
-    FSEventStreamRelease ;
+    dup closed>> [ drop ] [
+        t >>closed
+        {
+            [ info>> remove-event-source-callback ]
+            [ handle>> disable-event-stream ]
+            [ handle>> FSEventStreamInvalidate ]
+            [ handle>> FSEventStreamRelease ]
+        } cleave
+    ] if ;
diff --git a/extra/core-foundation/run-loop/run-loop.factor b/extra/core-foundation/run-loop/run-loop.factor
new file mode 100644 (file)
index 0000000..7594766
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax kernel threads init namespaces alien
+core-foundation ;
+IN: core-foundation.run-loop
+
+: kCFRunLoopRunFinished 1 ; inline
+: kCFRunLoopRunStopped 2 ; inline
+: kCFRunLoopRunTimedOut 3 ; inline
+: kCFRunLoopRunHandledSource 4 ; inline
+
+TYPEDEF: void* CFRunLoopRef
+
+FUNCTION: CFRunLoopRef CFRunLoopGetMain ( ) ;
+
+FUNCTION: SInt32 CFRunLoopRunInMode (
+   CFStringRef mode,
+   CFTimeInterval seconds,
+   Boolean returnAfterSourceHandled
+) ;
+
+: CFRunLoopDefaultMode ( -- alien )
+    #! Ugly, but we don't have static NSStrings
+    \ CFRunLoopDefaultMode get-global dup expired? [
+        drop
+        "kCFRunLoopDefaultMode" <CFString>
+        dup \ CFRunLoopDefaultMode set-global
+    ] when ;
+
+: run-loop-thread ( -- )
+    CFRunLoopDefaultMode 0 f CFRunLoopRunInMode
+    kCFRunLoopRunHandledSource = [ 1000 sleep ] unless
+    run-loop-thread ;
+
+: start-run-loop-thread ( -- )
+    [ run-loop-thread t ] "CFRunLoop dispatcher" spawn-server drop ;
+
+[ start-run-loop-thread ] "core-foundation.run-loop" add-init-hook
index 36c786e41adc9ae4b2be2fb62a91028b25421c66..3fad3adbaade1e5ac4884367f816676925f17ea6 100644 (file)
@@ -8,7 +8,7 @@ SYMBOL: current-coro
 TUPLE: coroutine resumecc exitcc ;
 
 : cocreate ( quot -- co )
-  coroutine construct-empty
+  coroutine new
   dup current-coro associate
   [ swapd , , \ bind , 
     "Coroutine has terminated illegally." , \ throw ,
index d4574119b2a9f8b649a47e2ca25f3ff76c90471e..ecc998e99ca563f0ffe7c4029e2bc23a5d908f63 100755 (executable)
@@ -425,7 +425,7 @@ M: cpu reset ( cpu -- )
   [ HEX: 10 swap set-cpu-last-interrupt ] keep
   0 swap set-cpu-cycles ;
 
-: <cpu> ( -- cpu ) cpu construct-empty dup reset ;
+: <cpu> ( -- cpu ) cpu new dup reset ;
 
 : (load-rom) ( n ram -- )
   read1 [ ! n ram ch
diff --git a/extra/crypto/test/blum-blum-shub.factor b/extra/crypto/test/blum-blum-shub.factor
deleted file mode 100644 (file)
index b1b6034..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: kernel math test namespaces crypto crypto-internals ;
-
-[ 6 ] [ 5 T{ bbs f 590695557939 811977232793 } random-bbs-bits* ] unit-test
-[ 792723710536787233474130382522 ] [ 100 T{ bbs f 200352954495 846054538649 } [ random-bbs-bits* drop ] 2keep random-bbs-bits* ] unit-test
-
index 1a1a18c942b18d1541f83ed4df91222dd703d3b9..baf4e9db5acb7afdb654b1fb830f50ca1d3c4ca0 100755 (executable)
@@ -12,7 +12,7 @@ TUPLE: db
     delete-statements ;
 
 : construct-db ( class -- obj )
-    construct-empty
+    new
         H{ } clone >>insert-statements
         H{ } clone >>update-statements
         H{ } clone >>delete-statements ;
@@ -52,7 +52,7 @@ TUPLE: throwable-statement < statement ;
 TUPLE: result-set sql in-params out-params handle n max ;
 
 : construct-statement ( sql in out class -- statement )
-    construct-empty
+    new
         swap >>out-params
         swap >>in-params
         swap >>sql ;
@@ -96,7 +96,7 @@ M: nonthrowable-statement execute-statement ( statement -- )
     0 >>n drop ;
 
 : construct-result-set ( query handle class -- result-set )
-    construct-empty
+    new
         swap >>handle
         >r [ sql>> ] [ in-params>> ] [ out-params>> ] tri r>
         swap >>out-params
index 59d1b6ff3d1ac5330062eceef208bca7b469b3b4..ca912f200d65611d1871c592edfb43837f75a299 100644 (file)
@@ -18,16 +18,16 @@ TUPLE: mysql-result-set ;
 : mysql-error ( mysql -- )
     [ mysql_error throw ] when* ;
 
-: mysql-connect ( mysql-connection -- )
-    new-mysql over set-mysql-db-handle
-    dup {
-        mysql-db-handle
-        mysql-db-host
-        mysql-db-user
-        mysql-db-password
-        mysql-db-db
-        mysql-db-port
-    } get-slots f 0 mysql_real_connect mysql-error ;
+: mysql-connect ( mysql-connection -- )
+    new-mysql over set-mysql-db-handle
+    dup {
+        mysql-db-handle
+        mysql-db-host
+        mysql-db-user
+        mysql-db-password
+        mysql-db-db
+        mysql-db-port
+    } get-slots f 0 mysql_real_connect mysql-error ;
 
 ! =========================================================
 ! Low level mysql utility definitions
index dc7225514e1a08b5f1a172730b7ef940191d9121..f8700debaa7e24e6219e9e18ab55fab0f19a721b 100755 (executable)
@@ -9,7 +9,7 @@ TUPLE: mysql-statement ;
 TUPLE: mysql-result-set ;
 
 M: mysql-db db-open ( mysql-db -- )
-    drop ;
+    ;
 
 M: mysql-db dispose ( mysql-db -- )
     mysql-db-handle mysql_close ;
index 7f428bb6b65861932a21364a3dd5fb81d84fdce3..ee5ba622e526dd7d6590bfcb94af4dec14fbf4da 100755 (executable)
@@ -6,8 +6,7 @@ IN: db.postgresql.ffi
 
 << "postgresql" {
     { [ os winnt? ]  [ "libpq.dll" ] }
-    { [ os macosx? ] [ "/opt/local/lib/postgresql83/libpq.dylib" ] }
-    ! { [ os macosx? ] [ "libpq.dylib" ] }
+    { [ os macosx? ] [ "libpq.dylib" ] }
     { [ os unix?  ]  [ "libpq.so" ] }
 } cond "cdecl" add-library >>
 
index c490ace77091ea6d83a1cb19129c374e1b800e8a..488026fcc7c989402ac9f0cc3a60da642bed63ec 100644 (file)
@@ -38,5 +38,3 @@ TUPLE: person name age ;
         { offset 40 }
         { limit 20 }
     } ;
-
-
index 99dde992808fb7df45541cee32f56741caa7b661..26e8429efdbb90def0395abc71d461b2318747a5 100755 (executable)
@@ -55,7 +55,7 @@ TUPLE: no-sql-match ;
         { [ dup number? ] [ number>string sql% ] }
         { [ dup symbol? ] [ unparse sql% ] }
         { [ dup word? ] [ unparse sql% ] }
-        { [ t ] [ T{ no-sql-match } throw ] }
+        [ T{ no-sql-match } throw ]
     } cond ;
 
 : parse-sql ( obj -- sql in-spec out-spec in out )
index f81d7de4b820a2ee358e189055c919cff1909821..e66accd7e90f08369402b67066af85daf0d97660 100755 (executable)
@@ -20,7 +20,7 @@ IN: db.sqlite.lib
     {
         { [ dup SQLITE_OK = ] [ drop ] }
         { [ dup SQLITE_ERROR = ] [ sqlite-statement-error ] }
-        { [ t ] [ sqlite-error ] }
+        [ sqlite-error ]
     } cond ;
 
 : sqlite-open ( filename -- db )
index 7fc059c9b31ba38dafdf59f54e410abb93c3c960..311f18daa924461ef1fdd177aef7b0b3366f629a 100755 (executable)
@@ -40,7 +40,7 @@ HOOK: <select-by-slots-statement> db ( tuple class -- tuple )
 HOOK: insert-tuple* db ( tuple statement -- )
 
 : resulting-tuple ( row out-params -- tuple )
-    dup first sql-spec-class construct-empty [
+    dup first sql-spec-class new [
         [
             >r sql-spec-slot-name r> set-slot-named
         ] curry 2each
index f8e238b7db2c0e9da7ec5feb870c5e3608313600..506d7175b651d9b5e54d3b3e475943126d1582a0 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
 USING: parser generic kernel classes words slots assocs sequences arrays
-vectors definitions prettyprint combinators.lib math ;
+vectors definitions prettyprint combinators.lib math sets ;
 IN: delegate
 
 ! Protocols
@@ -23,7 +23,7 @@ IN: delegate
 
 : forget-old-definitions ( protocol new-wordlist -- )
     >r users-and-words r>
-    seq-diff forget-all-methods ;
+    diff forget-all-methods ;
 
 : define-protocol ( protocol wordlist -- )
     ! 2dup forget-old-definitions
index 736645890e40dc09e6ff805b1245cd83095e20a6..f1ad068fe22efbdf06f070764ff536be7c036a4c 100755 (executable)
@@ -5,7 +5,7 @@ io definitions kernel continuations ;
 IN: delegate.protocols
 
 PROTOCOL: sequence-protocol
-    clone clone-like like new new-resizable nth nth-unsafe
+    clone clone-like like new-sequence new-resizable nth nth-unsafe
     set-nth set-nth-unsafe length set-length lengthen ;
 
 PROTOCOL: assoc-protocol
index 147e1836881585f978b55a6b3a0b9b60005c3374..59c325c4904f138229e40c74860f29c26a29ad3b 100755 (executable)
@@ -3,7 +3,7 @@ IN: destructors.tests
 
 TUPLE: dummy-obj destroyed? ;
 
-: <dummy-obj> dummy-obj construct-empty ;
+: <dummy-obj> dummy-obj new ;
 
 TUPLE: dummy-destructor obj ;
 
index 1b98d2ee0d88561ff39026402643622d8258c4ef..87b574078691ec16b612223e52a10e33bf14b2a5 100755 (executable)
@@ -18,7 +18,7 @@ M: destructor dispose
     ] if ;
 
 : <destructor> ( obj -- newobj )
-    f destructor construct-boa ;
+    f destructor boa ;
 
 : add-error-destructor ( obj -- )
     <destructor> error-destructors get push ;
index 1776c916ada5ce4a2ee17d52896a34e0df8d296f..7d56c960344edab28c71cfeb0dca88195bfbf06a 100755 (executable)
@@ -7,10 +7,10 @@ TUPLE: digraph ;
 TUPLE: vertex value edges ;
 
 : <digraph> ( -- digraph )
-    digraph construct-empty H{ } clone over set-delegate ;
+    digraph new H{ } clone over set-delegate ;
 
 : <vertex> ( value -- vertex )
-    V{ } clone vertex construct-boa ;
+    V{ } clone vertex boa ;
 
 : add-vertex ( key value digraph -- )
     >r <vertex> swap r> set-at ;
diff --git a/extra/digraphs/tags.txt b/extra/digraphs/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/extra/disjoint-set/authors.txt b/extra/disjoint-set/authors.txt
new file mode 100644 (file)
index 0000000..16e1588
--- /dev/null
@@ -0,0 +1 @@
+Eric Mertens
diff --git a/extra/disjoint-set/disjoint-set.factor b/extra/disjoint-set/disjoint-set.factor
new file mode 100644 (file)
index 0000000..6f3b1e6
--- /dev/null
@@ -0,0 +1,72 @@
+USING: accessors arrays hints kernel locals math sequences ;
+
+IN: disjoint-set
+
+<PRIVATE
+
+TUPLE: disjoint-set parents ranks counts ;
+
+: count ( a disjoint-set -- n )
+    counts>> nth ; inline
+
+: add-count ( p a disjoint-set -- )
+    [ count [ + ] curry ] keep counts>> swap change-nth ; inline
+
+: parent ( a disjoint-set -- p )
+    parents>> nth ; inline
+
+: set-parent ( p a disjoint-set -- )
+    parents>> set-nth ; inline
+
+: link-sets ( p a disjoint-set -- )
+    [ set-parent ]
+    [ add-count ] 3bi ; inline
+
+: rank ( a disjoint-set -- r )
+    ranks>> nth ; inline
+
+: inc-rank ( a disjoint-set -- )
+    ranks>> [ 1+ ] change-nth ; inline
+
+: representative? ( a disjoint-set -- ? )
+    dupd parent = ; inline
+
+: representative ( a disjoint-set -- p )
+    2dup representative? [ drop ] [
+        [ [ parent ] keep representative dup ] 2keep set-parent
+    ] if ;
+
+: representatives ( a b disjoint-set -- r r )
+    [ representative ] curry bi@ ; inline
+
+: ranks ( a b disjoint-set -- r r )
+    [ rank ] curry bi@ ; inline
+
+:: branch ( a b neg zero pos -- )
+    a b = zero [ a b < neg pos if ] if ; inline
+
+PRIVATE>
+
+: <disjoint-set> ( n -- disjoint-set )
+    [ >array ]
+    [ 0 <array> ]
+    [ 1 <array> ] tri
+    disjoint-set boa ;
+
+: equiv-set-size ( a disjoint-set -- n )
+    [ representative ] keep count ;
+
+: equiv? ( a b disjoint-set -- ? )
+    representatives = ; inline
+
+:: equate ( a b disjoint-set -- )
+    a b disjoint-set representatives
+    2dup = [ 2drop ] [
+        2dup disjoint-set ranks
+        [ swap ] [ over disjoint-set inc-rank ] [ ] branch
+        disjoint-set link-sets
+    ] if ;
+
+HINTS: equate disjoint-set ;
+HINTS: representative disjoint-set ;
+HINTS: equiv-set-size disjoint-set ;
diff --git a/extra/disjoint-set/summary.txt b/extra/disjoint-set/summary.txt
new file mode 100644 (file)
index 0000000..ec7ec73
--- /dev/null
@@ -0,0 +1 @@
+An efficient implementation of the disjoint-set data structure
diff --git a/extra/disjoint-set/tags.txt b/extra/disjoint-set/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 14f0dc41acd066e659f6bb75be97acab1d2c43db..4fa4ed3c09d3b571fcd90f073d2f8da62845089d 100755 (executable)
@@ -151,14 +151,14 @@ TUPLE: char-elt ;
     -rot {
         { [ over { 0 0 } = ] [ drop ] }
         { [ over second zero? ] [ >r first 1- r> line-end ] }
-        { [ t ] [ pick call ] }
+        [ pick call ]
     } cond nip ; inline
 
 : (next-char) ( loc document quot -- loc )
     -rot {
         { [ 2dup doc-end = ] [ drop ] }
         { [ 2dup line-end? ] [ drop first 1+ 0 2array ] }
-        { [ t ] [ pick call ] }
+        [ pick call ]
     } cond nip ; inline
 
 M: char-elt prev-elt
@@ -184,8 +184,7 @@ M: one-char-elt next-elt 2drop ;
     [ >r blank? r> xor ] curry ; inline
 
 : (prev-word) ( ? col str -- col )
-    rot break-detector find-last*
-    drop [ 1+ ] [ 0 ] if* ;
+    rot break-detector find-last* drop ?1+ ;
 
 : (next-word) ( ? col str -- col )
     [ rot break-detector find* drop ] keep
index 16de8f5eee5784d0509e3256a05d5406e2cb76d7..a15a12830cb84eeae84594094c95b42e32a91e8f 100755 (executable)
@@ -21,7 +21,7 @@ SYMBOL: edit-hook
     [ [ "Load " prepend ] keep ] { } map>assoc ;
 
 : no-edit-hook ( -- )
-    \ no-edit-hook construct-empty
+    \ no-edit-hook new
     editor-restarts throw-restarts
     require ;
 
index 142fc5de6c2e6050d5cbd01362b2179d3ab0e35e..f876c9569b6a226b9731b8b27a586276996b8e4a 100755 (executable)
@@ -6,6 +6,8 @@ io.streams.string html peg.parsers html.elements sequences.deep
 unicode.categories ;
 IN: farkup
 
+<PRIVATE
+
 : delimiters ( -- string )
     "*_^~%[-=|\\\n" ; inline
 
@@ -144,6 +146,8 @@ MEMO: paragraph ( -- parser )
         [ "<p>" swap "</p>" 3array ] unless
     ] action ;
 
+PRIVATE>
+
 PEG: parse-farkup ( -- parser )
     [
         list , table , h1 , h2 , h3 , h4 , code , paragraph , 2nl , nl ,
index d983bd271564dc979217e83e56eb4067a58e3003..6c20aac7f2dcd08232592525f62ca1bd91bbe726 100755 (executable)
@@ -22,11 +22,11 @@ DEFER: (fry)
         drop 1quotation
     ] [
         unclip {
-            { , [ [ curry ] ((fry)) ] }
-            { @ [ [ compose ] ((fry)) ] }
+            { , [ [ curry ] ((fry)) ] }
+            { @ [ [ compose ] ((fry)) ] }
 
             ! to avoid confusion, remove if fry goes core
-            { namespaces:, [ [ curry ] ((fry)) ] }
+            { namespaces:, [ [ curry ] ((fry)) ] }
 
             [ swap >r suffix r> (fry) ]
         } case
index fb2abf1c3df4d397a5d18fb1b9b82a2f130b3e2b..a3a5075820f54c1dfe5ac015f0d9a1ab3b2c3fb2 100644 (file)
@@ -7,7 +7,7 @@ IN: gap-buffer.cursortree
 TUPLE: cursortree cursors ;
 
 : <cursortree> ( seq -- cursortree )
-    <gb> cursortree construct-empty tuck set-delegate <avl>
+    <gb> cursortree new tuck set-delegate <avl>
     over set-cursortree-cursors ;
 
 GENERIC: cursortree-gb ( cursortree -- gb )
@@ -38,16 +38,16 @@ M: left-cursor set-cursor-pos ( n cursor -- ) >r 1- r> [ cursor-tree position>in
 M: right-cursor set-cursor-pos ( n cursor -- ) [ cursor-tree position>index ] keep set-cursor-index ;
 
 : <cursor> ( cursortree -- cursor )
-    cursor construct-empty tuck set-cursor-tree ;
+    cursor new tuck set-cursor-tree ;
 
 : make-cursor ( cursortree pos cursor -- cursor )
     >r swap <cursor> r> tuck set-delegate tuck set-cursor-pos ;
 
 : <left-cursor> ( cursortree pos -- left-cursor )
-    left-cursor construct-empty make-cursor ;
+    left-cursor new make-cursor ;
 
 : <right-cursor> ( cursortree pos -- right-cursor )
-    right-cursor construct-empty make-cursor ;
+    right-cursor new make-cursor ;
 
 : cursors ( cursortree -- seq )
     cursortree-cursors values concat ;
index 3d78204d3fa842be5f32a37013b3a045d3bd47f0..d3b946afe9ba6368a9b254adb4007cef02c2fd1e 100644 (file)
@@ -27,7 +27,7 @@ M: gb set-gb-seq ( seq gb -- ) set-delegate ;
     tuck gb-expand-factor * ceiling >fixnum swap gb-min-size max ;
 
 : <gb> ( seq -- gb )
-    gb construct-empty
+    gb new
     5 over set-gb-min-size
     1.5 over set-gb-expand-factor
     [ >r length r> set-gb-gap-start ] 2keep
index 57de004d919144e5f59c89b14fbc2e246d732ec2..fd3a2d285ada1995d8d0a244ffb5254cceafc7b6 100644 (file)
@@ -1 +1,2 @@
+collections
 collections sequences
index 53aab483a1a54f24f205025683d0b768ac1cd938..cc345c7537893237ffb2572bfe8773405974fa9d 100755 (executable)
@@ -14,7 +14,7 @@ IN: hardware-info
     { [ os windows? ] [ "hardware-info.windows" ] }
     { [ os linux? ] [ "hardware-info.linux" ] }
     { [ os macosx? ] [ "hardware-info.macosx" ] }
-    { [ t ] [ f ] }
+    [ f ]
 } cond [ require ] when* >>
 
 : hardware-report. ( -- )
diff --git a/extra/hardware-info/windows/tags.txt b/extra/hardware-info/windows/tags.txt
new file mode 100644 (file)
index 0000000..8e1a559
--- /dev/null
@@ -0,0 +1 @@
+windows
index 075ce2d0e8dbff8437414c70d7229ef76c2ccf0f..9b21bf7fff552f76ceb591ae7d49a732b82f0a71 100755 (executable)
@@ -199,7 +199,7 @@ 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
-    "\"mydata.dat\" dup file-info file-info-length ["
+    "\"mydata.dat\" dup file-info size>> ["
     "    4 <sliced-groups> [ reverse-here ] change-each"
     "] with-mapped-file"
 }
@@ -224,7 +224,7 @@ $nl
     ":errors - print 2 compiler errors."
     ":warnings - print 50 compiler warnings."
 }
-"These warnings arise from the compiler's stack effect checker. Warnings are non-fatal conditions -- not all code has a static stack effect, so you try to minimize warnings but understand that in many cases they cannot be eliminated. Errors indicate programming mistakes, such as erronous stack effect declarations."
+"These warnings arise from the compiler's stack effect checker. Warnings are non-fatal conditions -- not all code has a static stack effect, so you try to minimize warnings but understand that in many cases they cannot be eliminated. Errors indicate programming mistakes, such as erroneous stack effect declarations."
 { $references
     "To learn more about the compiler and static stack effect inference, read these articles:"
     "compiler"
@@ -259,7 +259,7 @@ $nl
 { $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" } "."
 $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 supresses 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. The " { $snippet "-script" } " switch suppresses compiler messages, and exits Factor when the script finishes."
 { $references
     { }
     "cli"
@@ -273,7 +273,7 @@ $nl
 $nl
 "Keep the following guidelines in mind to avoid losing your sense of balance:"
 { $list
-    "SImplify, simplify, simplify. Break your program up into small words which operate on a few values at a time. Most word definitions should fit on a single line; very rarely should they exceed two or three lines."
+    "Simplify, simplify, simplify. Break your program up into small words which operate on a few values at a time. Most word definitions should fit on a single line; very rarely should they exceed two or three lines."
     "In addition to keeping your words short, keep them meaningful. Give them good names, and make sure each word only does one thing. Try documenting your words; if the documentation for a word is unclear or complex, chances are the word definition is too. Don't be afraid to refactor your code."
     "If your code looks repetitive, factor it some more."
     "If after factoring, your code still looks repetitive, introduce combinators."
@@ -285,7 +285,7 @@ $nl
     "Every time you define a word which simply manipulates sequences, hashtables or objects in an abstract way which is not related to your program domain, check the library to see if you can reuse an existing definition."
     { "Learn to use the " { $link "inference" } " tool." }
     { "Write unit tests. Factor provides good support for unit testing; see " { $link "tools.test" } ". Once your program has a good test suite you can refactor with confidence and catch regressions early." }
-    "Don't write Factor as if it were C. Imperitive programming and indexed loops are almost always not the most idiomatic solution."
+    "Don't write Factor as if it were C. Imperative programming and indexed loops are almost always not the most idiomatic solution."
     { "Use sequences, assocs and objects to group related data. Object allocation is very cheap. Don't be afraid to create tuples, pairs and triples. Don't be afraid of operations which allocate new objects either, such as " { $link append } "." }
     { "If you find yourself writing a loop with a sequence and an index, there's almost always a better way. Learn the " { $link "sequences-combinators" } " by heart." }
     { "If you find yourself writing a heavily nested loop which performs several steps on each iteration, there is almost always a better way. Break the problem down into a series of passes over the data instead, gradually transforming it into the desired result with a series of simple loops. Factor the loops out and reuse them. If you're working on anything math-related, learn " { $link "math-vectors" } " by heart." }
@@ -312,7 +312,7 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid"
     $nl
     "Unit tests for the " { $vocab-link "inference" } " vocabulary can be used to ensure that any methods your vocabulary defines on core generic words have static stack effects:"
     { $code "\"inference\" test" }
-    "In general, you should strive to write code with inferrable stack effects, even for sections of a program which are not performance sensitive; the " { $link infer. } " tool together with the optimizing compiler's error reporting can catch many bugs ahead of time." }
+    "In general, you should strive to write code with inferable stack effects, even for sections of a program which are not performance sensitive; the " { $link infer. } " tool together with the optimizing compiler's error reporting can catch many bugs ahead of time." }
     { "Be careful when calling words which access variables from a " { $link make-assoc } " which constructs an assoc with arbitrary keys, since those keys might shadow variables." }
     { "If " { $link run-file } " throws a stack depth assertion, it means that the top-level form in the file left behind values on the stack. The stack depth is compared before and after loading a source file, since this type of situation is almost always an error. If you have a legitimate need to load a source file which returns data in some manner, define a word in the source file which produces this data on the stack and call the word after loading the file." }
 } ;
index acdbca82eebfc68c25a57fa5e650693d6e253551..4e6bfe48881153f52d84b860c438700af278b261 100755 (executable)
@@ -3,7 +3,7 @@ namespaces words sequences classes assocs vocabs kernel arrays
 prettyprint.backend kernel.private io generic math system
 strings sbufs vectors byte-arrays bit-arrays float-arrays
 quotations io.streams.byte-array io.encodings.string
-classes.builtin ;
+classes.builtin parser ;
 IN: help.handbook
 
 ARTICLE: "conventions" "Conventions"
@@ -25,6 +25,7 @@ $nl
     { { $snippet { $emphasis "foo" } "?" } "outputs a boolean" { { $link empty? } } }
     { { $snippet "?" { $emphasis "foo" } } { "conditionally performs " { $snippet { $emphasis "foo" } } } { { $links ?nth } } }
     { { $snippet "<" { $emphasis "foo" } ">" } { "creates a new " { $snippet "foo" } } { { $link <array> } } }
+    { { $snippet "new-" { $emphasis "foo" } } { "creates a new " { $snippet "foo" } ", taking some kind of parameter from the stack which determines the type of the object to be created" } { { $link new-sequence } ", " { $link new-lexer } ", " { $link new } } }
     { { $snippet { $emphasis "foo" } "*" } { "alternative form of " { $snippet "foo" } ", or a generic word called by " { $snippet "foo" } } { { $links at* pprint* } } }
     { { $snippet "(" { $emphasis "foo" } ")" } { "implementation detail word used by " { $snippet "foo" } } { { $link (clone) } } }
     { { $snippet "set-" { $emphasis "foo" } } { "sets " { $snippet "foo" } " to a new value" } { $links set-length } }
index 4e8424f7a3340f6ce6f143050ec92821b29849fa..aa2704a799fc1b17831a99a8487e8e793d1c29c5 100755 (executable)
@@ -139,7 +139,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
     {
         { [ dup empty? ] [ (:help-none) ] }
         { [ dup length 1 = ] [ first help ] }
-        { [ t ] [ (:help-multi) ] }
+        [ (:help-multi) ]
     } cond (:help-debugger) ;
 
 : remove-article ( name -- )
index 01e08473c6957e7c518bb3d7dd98f1ca95f83ced..28af93f295c170d81da3eecf2b79a80ac402b392 100755 (executable)
@@ -5,7 +5,7 @@ words strings classes tools.vocabs namespaces io
 io.streams.string prettyprint definitions arrays vectors
 combinators splitting debugger hashtables sorting effects vocabs
 vocabs.loader assocs editors continuations classes.predicate
-macros combinators.lib sequences.lib math ;
+macros combinators.lib sequences.lib math sets ;
 IN: help.lint
 
 : check-example ( element -- )
index b963a19f29abf9d9f9057ceb5758aac6f808637e..2e2b34ebfdfd7133c64da72c2d24a630ea6f3eef 100755 (executable)
@@ -79,7 +79,7 @@ M: f print-element drop ;
     [ strong-style get print-element* ] ($heading) ;
 
 : ($code-style) ( presentation -- hash )
-    presented associate code-style get union ;
+    presented associate code-style get assoc-union ;
 
 : ($code) ( presentation quot -- )
     [
index c12c392eb327073ae2ddc7eef44bae580cae961a..afdae38c5a285a956aab5d47d93e8b8190ad837f 100755 (executable)
@@ -14,7 +14,7 @@ INSTANCE: word topic
 GENERIC: >link ( obj -- obj )
 M: link >link ;
 M: vocab-spec >link ;
-M: object >link link construct-boa ;
+M: object >link link boa ;
 
 PREDICATE: word-link < link link-name word? ;
 
@@ -40,13 +40,13 @@ GENERIC: set-article-parent ( parent topic -- )
 TUPLE: article title content loc ;
 
 : <article> ( title content -- article )
-    f \ article construct-boa ;
+    f \ article boa ;
 
 M: article article-name article-title ;
 
 TUPLE: no-article name ;
 
-: no-article ( name -- * ) \ no-article construct-boa throw ;
+: no-article ( name -- * ) \ no-article boa throw ;
 
 M: no-article summary
     drop "Help article does not exist" ;
index 2994e2d792730ce085f18a4f3cc01ac1638d1f4d..ce320ca75b447c4c66c84fece801070a9e279cd5 100644 (file)
@@ -3,7 +3,9 @@ namespaces tools.test xml.writer sbufs sequences html.private ;
 IN: html.tests
 
 : make-html-string
-    [ with-html-stream ] with-string-writer ;
+    [ with-html-stream ] with-string-writer ; inline
+
+[ [ ] make-html-string ] must-infer
 
 [ ] [
     512 <sbuf> <html-stream> drop
@@ -32,7 +34,7 @@ M: funky browser-link-href
 
 [ "<a href='http://www.funky-town.com/austin'>&lt;</a>" ] [
     [
-        "<" "austin" funky construct-boa write-object
+        "<" "austin" funky boa write-object
     ] make-html-string
 ] unit-test
 
index 06199373328514c21387f73b7c9129e3025ecf74..5c82b7f0384c1688ffabd5f3240f1bf54a240260 100755 (executable)
@@ -32,7 +32,7 @@ TUPLE: html-stream last-div? ;
 TUPLE: html-sub-stream style stream ;
 
 : (html-sub-stream) ( style stream -- stream )
-    html-sub-stream construct-boa
+    html-sub-stream boa
     512 <sbuf> <html-stream> over set-delegate ;
 
 : <html-sub-stream> ( style stream class -- stream )
@@ -194,7 +194,7 @@ M: html-stream stream-nl ( stream -- )
 
 ! Utilities
 : with-html-stream ( quot -- )
-    stdio get <html-stream> swap with-stream* ;
+    stdio get <html-stream> swap with-stream* ; inline
 
 : xhtml-preamble
     "<?xml version=\"1.0\"?>" write-html
index 5ed9ab84c1d43d1bba9db0b4982fc000f62ae73d..3078cf23a52fb3134c41b8fb37dbbaf2675ff95f 100644 (file)
@@ -92,7 +92,7 @@ M: printer print-tag ( tag -- )
             [ print-closing-named-tag ] }
         { [ dup tag-name string? ]
             [ print-opening-named-tag ] }
-        { [ t ] [ <unknown-tag-error> throw ] }
+        [ <unknown-tag-error> throw ]
     } cond ;
 
 SYMBOL: tablestack
index 2e7370bc395b14200c9fafbf675411a94322cb9a..d1ffce721d9854026bdba407dda9ff57ad21e782 100755 (executable)
@@ -1,5 +1,6 @@
 USING: http tools.test multiline tuple-syntax
-io.streams.string kernel arrays splitting sequences     ;
+io.streams.string kernel arrays splitting sequences
+assocs io.sockets ;
 IN: http.tests
 
 [ "hello%20world" ] [ "hello world" url-encode ] unit-test
@@ -136,10 +137,12 @@ io.encodings.ascii ;
 [ ] [
     [
         <dispatcher>
-        <action>
-            [ stop-server "text/html" <content> [ "Goodbye" write ] >>body ] >>display
-        "quit" add-responder
-        "extra/http/test" resource-path <static> >>default
+            <action>
+                [ stop-server "text/html" <content> [ "Goodbye" write ] >>body ] >>display
+            "quit" add-responder
+            <dispatcher>
+                "extra/http/test" resource-path <static> >>default
+            "nested" add-responder
         main-responder set
 
         [ 1237 httpd ] "HTTPD test" spawn drop
@@ -148,7 +151,17 @@ io.encodings.ascii ;
 
 [ t ] [
     "extra/http/test/foo.html" resource-path ascii file-contents
-    "http://localhost:1237/foo.html" http-get =
+    "http://localhost:1237/nested/foo.html" http-get =
+] unit-test
+
+! Try with a slightly malformed request
+[ t ] [
+    "localhost" 1237 <inet> ascii <client> [
+        "GET nested HTTP/1.0\r\n" write flush
+        "\r\n" write flush
+        readln drop
+        read-header USE: prettyprint
+    ] with-stream dup . "location" swap at "/" head?
 ] unit-test
 
 [ "Goodbye" ] [
index 6ff4829b486cc6e36d003dd628242b4426c08dc4..e792802b5abaa1eb645ab2a69ad236fc79d0186f 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: fry hashtables io io.streams.string kernel math
+USING: fry hashtables io io.streams.string kernel math sets
 namespaces math.parser assocs sequences strings splitting ascii
 io.encodings.utf8 io.encodings.string namespaces unicode.case
 combinators vectors sorting accessors calendar
@@ -94,7 +94,7 @@ IN: http
 
 : check-header-string ( str -- str )
     #! http://en.wikipedia.org/wiki/HTTP_Header_Injection
-    dup "\r\n" seq-intersect empty?
+    dup "\r\n" intersect empty?
     [ "Header injection attack" throw ] unless ;
 
 : write-header ( assoc -- )
@@ -122,7 +122,7 @@ IN: http
 TUPLE: cookie name value path domain expires http-only ;
 
 : <cookie> ( value name -- cookie )
-    cookie construct-empty
+    cookie new
     swap >>name swap >>value ;
 
 : parse-cookies ( string -- seq )
@@ -145,10 +145,10 @@ TUPLE: cookie name value path domain expires http-only ;
 
 : (unparse-cookie) ( key value -- )
     {
-        { [ dup f eq? ] [ 2drop ] }
-        { [ dup t eq? ] [ drop , ] }
-        { [ t ] [ "=" swap 3append , ] }
-    } cond ;
+        { f [ drop ] }
+        { t [ , ] }
+        [ "=" swap 3append , ]
+    } case ;
 
 : unparse-cookie ( cookie -- strings )
     [
@@ -176,7 +176,7 @@ post-data-type
 cookies ;
 
 : <request>
-    request construct-empty
+    request new
         "1.1" >>version
         http-port >>port
         H{ } clone >>header
@@ -346,7 +346,7 @@ cookies
 body ;
 
 : <response>
-    response construct-empty
+    response new
     "1.1" >>version
     H{ } clone >>header
     "close" "connection" set-header
@@ -399,7 +399,7 @@ body ;
         { [ dup not ] [ drop ] }
         { [ dup string? ] [ write ] }
         { [ dup callable? ] [ call ] }
-        { [ t ] [ stdio get stream-copy ] }
+        [ stdio get stream-copy ]
     } cond ;
 
 M: response write-response ( respose -- )
@@ -434,7 +434,7 @@ message
 body ;
 
 : <raw-response> ( -- response )
-    raw-response construct-empty
+    raw-response new
     "1.1" >>version ;
 
 M: raw-response write-response ( respose -- )
index fcafa57ff6257b1839f5f04d30c2ea2c80122bda..2b2aaea6a8adbd4208d0954afa8e361a791df727 100755 (executable)
@@ -12,7 +12,7 @@ SYMBOL: params
 TUPLE: action init display submit get-params post-params ;\r
 \r
 : <action>\r
-    action construct-empty\r
+    action new\r
         [ ] >>init\r
         [ <400> ] >>display\r
         [ <400> ] >>submit ;\r
@@ -40,7 +40,7 @@ TUPLE: action init display submit get-params post-params ;
 M: action call-responder ( path action -- response )\r
     '[\r
         , ,\r
-        [ +append-path associate request-params union params set ]\r
+        [ +append-path associate request-params assoc-union params set ]\r
         [ action set ] bi*\r
         request get method>> {\r
             { "GET" [ handle-get ] }\r
index 89984b0e8473d0e40b39f14229aa996d10db4b55..4f04a1ff9b853e50b9dae245a7d4527e70b545c8 100755 (executable)
@@ -1,20 +1,29 @@
 ! Copyright (c) 2008 Slava Pestov\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors quotations assocs kernel splitting\r
-base64 html.elements io combinators http.server\r
-http.server.auth.providers http.server.auth.providers.null\r
-http.server.actions http.server.components http.server.sessions\r
-http.server.templating.fhtml http.server.validators\r
-http.server.auth http sequences io.files namespaces hashtables\r
+base64 io combinators sequences io.files namespaces hashtables\r
 fry io.sockets arrays threads locals qualified continuations\r
-destructors ;\r
+destructors\r
+\r
+html.elements\r
+http\r
+http.server\r
+http.server.auth\r
+http.server.auth.providers\r
+http.server.auth.providers.null\r
+http.server.actions\r
+http.server.components\r
+http.server.forms\r
+http.server.sessions\r
+http.server.templating.fhtml\r
+http.server.validators ;\r
 IN: http.server.auth.login\r
 QUALIFIED: smtp\r
 \r
 SYMBOL: post-login-url\r
 SYMBOL: login-failed?\r
 \r
-TUPLE: login users ;\r
+TUPLE: login < dispatcher users ;\r
 \r
 : users login get users>> ;\r
 \r
@@ -130,7 +139,7 @@ SYMBOL: user-exists?
 \r
                 successful-login\r
 \r
-                login get responder>> init-user-profile\r
+                login get default>> responder>> init-user-profile\r
             ] >>submit\r
     ] ;\r
 \r
@@ -178,7 +187,7 @@ SYMBOL: previous-page
                     "password" value uid users check-login\r
                     [ login-failed? on validation-failed ] unless\r
 \r
-                    "new-password" value set-password\r
+                    "new-password" value >>password\r
                 ] unless\r
 \r
                 "realname" value >>realname\r
@@ -269,7 +278,8 @@ SYMBOL: lost-password-from
 : <recover-form-3>\r
     "new-password" <form>\r
         "resource:extra/http/server/auth/login/recover-3.fhtml" >>edit-template\r
-        "username" <username> <hidden>\r
+        "username" <username>\r
+            hidden >>renderer\r
             t >>required\r
             add-field\r
         "new-password" <password>\r
@@ -278,7 +288,8 @@ SYMBOL: lost-password-from
         "verify-password" <password>\r
             t >>required\r
             add-field\r
-        "ticket" <string> <hidden>\r
+        "ticket" <string>\r
+            hidden >>renderer\r
             t >>required\r
             add-field ;\r
 \r
@@ -342,22 +353,22 @@ C: <protected> protected
     "login" f <permanent-redirect> ;\r
 \r
 M: protected call-responder ( path responder -- response )\r
-    logged-in-user sget [\r
-        dup save-user-after\r
+    logged-in-user sget dup [\r
+        save-user-after\r
         request get request-url previous-page sset\r
         responder>> call-responder\r
     ] [\r
-        2drop\r
+        3drop\r
         request get method>> { "GET" "HEAD" } member?\r
         [ show-login-page ] [ <400> ] if\r
     ] if ;\r
 \r
 M: login call-responder ( path responder -- response )\r
     dup login set\r
-    delegate call-responder ;\r
+    call-next-method ;\r
 \r
 : <login> ( responder -- auth )\r
-    login <webapp>\r
+    login new-dispatcher\r
         swap <protected> >>default\r
         <login-action> "login" add-responder\r
         <logout-action> "logout" add-responder\r
index f99e4d3d2ec329ee8850f0c12bffac0d284e11ef..a8f17d6f5dbce8cd3f0ec92005d69e2ccf5b94c0 100755 (executable)
@@ -26,7 +26,7 @@ namespaces accessors kernel ;
 \r
 [ t ] [ "user" get >boolean ] unit-test\r
 \r
-[ ] [ "user" get "fdasf" set-password drop ] unit-test\r
+[ ] [ "user" get "fdasf" >>password drop ] unit-test\r
 \r
 [ t ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test\r
 \r
index 18ec8da62a375e046efa07755b5202f369e37a8a..54f96480bca68961127685a8f4d9ddf1a6f20b48 100755 (executable)
@@ -7,7 +7,7 @@ http.server.auth.providers ;
 TUPLE: users-in-memory assoc ;\r
 \r
 : <users-in-memory> ( -- provider )\r
-    H{ } clone users-in-memory construct-boa ;\r
+    H{ } clone users-in-memory boa ;\r
 \r
 M: users-in-memory get-user ( username provider -- user/f )\r
     assoc>> at ;\r
index 340e1bb35d1a0bb0f0c7bb36a2eeb8c158ac0781..6daddac30463653a9168afebcffc529328234ed3 100755 (executable)
@@ -31,7 +31,7 @@ users-in-db "provider" set
 \r
     [ t ] [ "user" get >boolean ] unit-test\r
 \r
-    [ ] [ "user" get "fdasf" set-password drop ] unit-test\r
+    [ ] [ "user" get "fdasf" >>password drop ] unit-test\r
 \r
     [ ] [ "user" get "provider" get update-user ] unit-test\r
 \r
index eda3babf0f8d3e82807d24df9498490ee0c67155..a867b2381e563e39093f56c4f59d59ac41b4f167 100755 (executable)
@@ -6,7 +6,7 @@ IN: http.server.auth.providers
 \r
 TUPLE: user username realname password email ticket profile ;\r
 \r
-: <user> user construct-empty H{ } clone >>profile ;\r
+: <user> user new H{ } clone >>profile ;\r
 \r
 GENERIC: get-user ( username provider -- user/f )\r
 \r
@@ -17,8 +17,6 @@ GENERIC: new-user ( user provider -- user/f )
 : check-login ( password username provider -- user/f )\r
     get-user dup [ [ password>> = ] keep and ] [ 2drop f ] if ;\r
 \r
-: set-password ( user password -- user ) >>password ;\r
-\r
 ! Password recovery support\r
 \r
 :: issue-ticket ( email username provider -- user/f )\r
index e1b737a9c67162ace49f072d6ea3109d9c4221f2..42213d015f4f796205c55e2b9078bfc46e990f87 100755 (executable)
@@ -14,7 +14,7 @@ TUPLE: callback-responder responder callbacks ;
     #! A continuation responder is a special type of session\r
     #! manager. However it works entirely differently from\r
     #! the URL and cookie session managers.\r
-    H{ } clone callback-responder construct-boa ;\r
+    H{ } clone callback-responder boa ;\r
 \r
 TUPLE: callback cont quot expires alarm responder ;\r
 \r
@@ -32,7 +32,7 @@ TUPLE: callback cont quot expires alarm responder ;
     ] when drop ;\r
 \r
 : <callback> ( cont quot expires? -- callback )\r
-    f callback-responder get callback construct-boa\r
+    f callback-responder get callback boa\r
     dup touch-callback ;\r
 \r
 : invoke-callback ( callback -- response )\r
index d372865b7e95d1d1f47aae29176a2e630330280c..f1c43fe8ae58a5207edf1594266f3f6263b0d551 100755 (executable)
@@ -1,7 +1,10 @@
 IN: http.server.components.tests\r
-USING: http.server.components http.server.validators\r
-namespaces tools.test kernel accessors\r
-tuple-syntax mirrors http.server.actions ;\r
+USING: http.server.components http.server.forms\r
+http.server.validators namespaces tools.test kernel accessors\r
+tuple-syntax mirrors http.server.actions\r
+io.streams.string io.streams.null ;\r
+\r
+\ render-edit must-infer\r
 \r
 validation-failed? off\r
 \r
@@ -42,7 +45,7 @@ validation-failed? off
 \r
 TUPLE: test-tuple text number more-text ;\r
 \r
-: <test-tuple> test-tuple construct-empty ;\r
+: <test-tuple> test-tuple new ;\r
 \r
 : <test-form> ( -- form )\r
     "test" <form>\r
@@ -99,11 +102,31 @@ TUPLE: test-tuple text number more-text ;
         "123" "n" get validate value>>\r
     ] unit-test\r
     \r
-    [ ] [ "n" get t >>integer drop ] unit-test\r
+    [ ] [ "i" <integer> "i" set ] unit-test\r
 \r
     [ 3 ] [\r
-        "3" "n" get validate\r
+        "3" "i" get validate\r
+    ] unit-test\r
+    \r
+    [ t ] [\r
+        "3.9" "i" get validate validation-error?\r
     ] unit-test\r
+\r
+    H{ } clone values set\r
+\r
+    [ ] [ 3 "i" set-value ] unit-test\r
+\r
+    [ "3" ] [ [ "i" get render-view ] with-string-writer ] unit-test\r
+\r
+    [ ] [ [ "i" get render-edit ] with-null-stream ] unit-test\r
+\r
+    [ ] [ "t" <text> "t" set ] unit-test\r
+\r
+    [ ] [ "hello world" "t" set-value ] unit-test\r
+\r
+    [ ] [ [ "t" get render-edit ] with-null-stream ] unit-test\r
 ] with-scope\r
 \r
 [ t ] [ "wake up sheeple" dup "n" <text> validate = ] unit-test\r
+\r
+[ ] [ "password" <password> "p" set ] unit-test\r
index bd95bf4407ea2ba9582099a09c3a7f186a78a8a3..1e5e33c4a02ea296dcd93ae87f2a1852a3305632 100755 (executable)
@@ -2,23 +2,47 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: html.elements http.server.validators accessors namespaces
 kernel io math.parser assocs classes words classes.tuple arrays
-sequences io.files http.server.templating.fhtml
-http.server.actions splitting mirrors hashtables fry
+sequences splitting mirrors hashtables fry combinators
 continuations math ;
 IN: http.server.components
 
+! Renderer protocol
+GENERIC: render-view* ( value renderer -- )
+GENERIC: render-edit* ( value id renderer -- )
+
+TUPLE: field type ;
+
+C: <field> field
+
+M: field render-view* drop write ;
+
+M: field render-edit*
+    <input type>> =type [ =id ] [ =name ] bi =value input/> ;
+
+: render-error ( message -- )
+    <span "error" =class span> write </span> ;
+
+TUPLE: hidden < field ;
+
+: hidden ( -- renderer ) T{ hidden f "hidden" } ; inline
+
+M: hidden render-view* 2drop ;
+
+! Component protocol
 SYMBOL: components
 
-TUPLE: component id required default ;
+TUPLE: component id required default renderer ;
 
 : component ( name -- component )
     dup components get at
     [ ] [ "No such component: " prepend throw ] ?if ;
 
+GENERIC: init ( component -- component )
+
+M: component init ;
+
 GENERIC: validate* ( value component -- result )
-GENERIC: render-view* ( value component -- )
-GENERIC: render-edit* ( value component -- )
-GENERIC: render-error* ( reason value component -- )
+GENERIC: component-string ( value component -- string )
 
 SYMBOL: values
 
@@ -26,216 +50,175 @@ SYMBOL: values
 
 : set-value values get set-at ;
 
-: validate ( value component -- result )
-    '[
-        ,
-        over empty? [
-            [ default>> [ v-default ] when* ]
-            [ required>> [ v-required ] when ]
-            bi
-        ] [ validate* ] if
-    ] with-validator ;
+: blank-values H{ } clone values set ;
 
-: render-view ( component -- )
-    [ id>> value ] [ render-view* ] bi ;
+: from-tuple <mirror> values set ;
 
-: render-error ( error -- )
-    <span "error" =class span> write </span> ;
+: values-tuple values get mirror-object ;
 
-: render-edit ( component -- )
-    dup id>> value dup validation-error? [
-        [ reason>> ] [ value>> ] bi rot render-error*
-    ] [
-        swap [ default>> or ] keep render-edit*
-    ] if ;
-
-: <component> ( id class -- component )
-    \ component construct-empty
-    swap construct-delegate
-    swap >>id ; inline
-
-! Forms
-TUPLE: form view-template edit-template components ;
-
-: <form> ( id -- form )
-    form <component>
-        V{ } clone >>components ;
-
-: add-field ( form component -- form )
-    dup id>> pick components>> set-at ;
-
-: with-form ( form quot -- )
-    >r components>> components r> with-variable ; inline
-
-: set-defaults ( form -- )
-    [
-        components get [
-            swap values get [
-                swap default>> or
-            ] change-at
-        ] assoc-each
-    ] with-form ;
-
-: view-form ( form -- )
-    dup view-template>> '[ , run-template ] with-form ;
-
-: edit-form ( form -- )
-    dup edit-template>> '[ , run-template ] with-form ;
-
-: validate-param ( id component -- )
-    [ [ params get at ] [ validate ] bi* ]
-    [ drop set-value ] 2bi ;
-
-: (validate-form) ( form -- error? )
-    [
-        validation-failed? off
-        components get [ validate-param ] assoc-each
-        validation-failed? get
-    ] with-form ;
-
-: validate-form ( form -- )
-    (validate-form) [ validation-failed ] when ;
+: render-view ( component -- )
+    [ id>> value ] [ component-string ] [ renderer>> ] tri
+    render-view* ;
 
-: blank-values H{ } clone values set ;
+<PRIVATE
 
-: from-tuple <mirror> values set ;
+: render-edit-string ( string component -- )
+    [ id>> ] [ renderer>> ] bi render-edit* ;
 
-: values-tuple values get mirror-object ;
+: render-edit-error ( component -- )
+    [ id>> value ] keep
+    [ [ value>> ] dip render-edit-string ]
+    [ drop reason>> render-error ] 2bi ;
 
-! ! !
-! Canned components: for simple applications and prototyping
-! ! !
+: value-or-default ( component -- value )
+    [ id>> value ] [ default>> ] bi or ;
 
-: render-input ( value component type -- )
-    <input
-    =type
-    id>> [ =id ] [ =name ] bi
-    =value
-    input/> ;
+: render-edit-value ( component -- )
+    [ value-or-default ]
+    [ component-string ]
+    [ render-edit-string ]
+    tri ;
 
-! Hidden fields
-TUPLE: hidden ;
+PRIVATE>
 
-: <hidden> ( component -- component )
-    hidden construct-delegate ;
+: render-edit ( component -- )
+    dup id>> value validation-error?
+    [ render-edit-error ] [ render-edit-value ] if ;
 
-M: hidden render-view*
-    2drop ;
+: validate ( value component -- result )
+    '[
+        ,
+        over empty? [
+            [ default>> [ v-default ] when* ]
+            [ required>> [ v-required ] when ]
+            bi
+        ] [ validate* ] if
+    ] with-validator ;
 
-M: hidden render-edit*
-    >r dup number? [ number>string ] when r>
-    "hidden" render-input ;
+: new-component ( id class renderer -- component )
+    swap new
+        swap >>renderer
+        swap >>id
+        init ; inline
 
 ! String input fields
-TUPLE: string min-length max-length ;
-
-: <string> ( id -- component ) string <component> ;
+TUPLE: string < component one-line min-length max-length ;
 
-M: string validate*
-    [ v-one-line ] [
-        [ min-length>> [ v-min-length ] when* ]
-        [ max-length>> [ v-max-length ] when* ]
-        bi
-    ] bi* ;
+: new-string ( id class -- component )
+    "text" <field> new-component
+        t >>one-line ; inline
 
-M: string render-view*
-    drop write ;
+: <string> ( id -- component )
+    string new-string ;
 
-M: string render-edit*
-    "text" render-input ;
+M: string validate*
+    [   one-line>> [ v-one-line   ] when  ]
+    [ min-length>> [ v-min-length ] when* ]
+    [ max-length>> [ v-max-length ] when* ]
+    tri ;
 
-M: string render-error*
-    "text" render-input render-error ;
+M: string component-string
+    drop ;
 
 ! Username fields
-TUPLE: username ;
+TUPLE: username < string ;
+
+M: username init
+    2 >>min-length
+    20 >>max-length ;
 
 : <username> ( id -- component )
-    <string> username construct-delegate
-        2 >>min-length
-        20 >>max-length ;
+    username new-string ;
 
 M: username validate*
-    delegate validate* v-one-word ;
+    call-next-method v-one-word ;
 
 ! E-mail fields
-TUPLE: email ;
+TUPLE: email < string ;
 
 : <email> ( id -- component )
-    <string> email construct-delegate
+    email new-string
         5 >>min-length
         60 >>max-length ;
 
 M: email validate*
-    delegate validate* dup empty? [ v-email ] unless ;
+    call-next-method dup empty? [ v-email ] unless ;
+
+! Don't send passwords back to the user
+TUPLE: password-renderer < field ;
+
+: password-renderer T{ password-renderer f "password" } ;
+
+: blank-password >r >r drop "" r> r> ;
+
+M: password-renderer render-edit*
+    blank-password call-next-method ;
 
 ! Password fields
-TUPLE: password ;
+TUPLE: password < string ;
+
+M: password init
+    6 >>min-length
+    60 >>max-length ;
 
 : <password> ( id -- component )
-    <string> password construct-delegate
-        6 >>min-length
-        60 >>max-length ;
+    password new-string
+        password-renderer >>renderer ;
 
 M: password validate*
-    delegate validate* v-one-word ;
-
-M: password render-edit*
-    >r drop f r> "password" render-input ;
-
-M: password render-error*
-    render-edit* render-error ;
+    call-next-method v-one-word ;
 
 ! Number fields
-TUPLE: number min-value max-value integer ;
+TUPLE: number < string min-value max-value ;
 
-: <number> ( id -- component ) number <component> ;
+: <number> ( id -- component )
+    number new-string ;
 
 M: number validate*
     [ v-number ] [
-        [ integer>> [ v-integer ] when ]
         [ min-value>> [ v-min-value ] when* ]
         [ max-value>> [ v-max-value ] when* ]
-        tri
+        bi
     ] bi* ;
 
-M: number render-view*
-    drop number>string write ;
+M: number component-string
+    drop dup [ number>string ] when ;
 
-M: number render-edit*
-    >r number>string r> "text" render-input ;
+! Integer fields
+TUPLE: integer < number ;
 
-M: number render-error*
-    "text" render-input render-error ;
+: <integer> ( id -- component )
+    integer new-string ;
 
-! Text areas
-TUPLE: text ;
+M: integer validate*
+    call-next-method v-integer ;
 
-: <text> ( id -- component ) text <component> ;
+! Simple captchas
+TUPLE: captcha < string ;
 
-M: text validate* drop ;
+: <captcha> ( id -- component )
+    captcha new-string ;
 
-M: text render-view*
-    drop write ;
+M: captcha validate*
+    drop v-captcha ;
 
-: render-textarea
-    <textarea
-        id>> [ =id ] [ =name ] bi
-    textarea>
-        write
-    </textarea> ;
+! Text areas
+TUPLE: textarea-renderer ;
 
-M: text render-edit*
-    render-textarea ;
+: textarea-renderer T{ textarea-renderer } ;
 
-M: text render-error*
-    render-textarea render-error ;
+M: textarea-renderer render-view*
+    drop write ;
 
-! Simple captchas
-TUPLE: captcha ;
+M: textarea-renderer render-edit*
+    drop <textarea [ =id ] [ =name ] bi textarea> write </textarea> ;
 
-: <captcha> ( id -- component )
-    <string> captcha construct-delegate ;
+TUPLE: text < string ;
 
-M: captcha validate*
-    drop v-captcha ;
+: new-text ( id class -- component )
+    new-string
+        f >>one-line
+        textarea-renderer >>renderer ;
+
+: <text> ( id -- component )
+    text new-text ;
index 09c8471905ee55d01024c0215055f194429e4c0d..65e159513d544a1f5ae76229bced4b47b92f3edc 100755 (executable)
@@ -1,13 +1,16 @@
 ! Copyright (C) 2008 Slava Pestov\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: splitting http.server.components kernel io sequences\r
-farkup ;\r
+USING: splitting kernel io sequences farkup accessors\r
+http.server.components ;\r
 IN: http.server.components.farkup\r
 \r
-TUPLE: farkup ;\r
+TUPLE: farkup-renderer < textarea-renderer ;\r
 \r
-: <farkup> ( id -- component )\r
-    <text> farkup construct-delegate ;\r
+: farkup-renderer T{ farkup-renderer } ;\r
 \r
-M: farkup render-view*\r
+M: farkup-renderer render-view*\r
     drop string-lines "\n" join convert-farkup write ;\r
+\r
+: <farkup> ( id -- component )\r
+    <text>\r
+        farkup-renderer >>renderer ;\r
index 4893977f7603e6fd8b05875d127c9f2574984c52..eb8ff943c7fcbc3eb19b2425a104f8e1dceab45e 100755 (executable)
@@ -1,9 +1,13 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
+USING: kernel namespaces db.tuples math.parser
+accessors fry locals hashtables
+http.server
+http.server.actions
+http.server.components
+http.server.forms
+http.server.validators ;
 IN: http.server.crud
-USING: kernel namespaces db.tuples math.parser http.server
-http.server.actions http.server.components
-http.server.validators accessors fry locals hashtables ;
 
 :: <view-action> ( form ctor -- action )
     <action>
index a0d732c1efb54cdc42213f6ef6ad17061b5350e9..a8b929bc98c8671aadcc412c132400fd25aeb974 100755 (executable)
@@ -9,8 +9,8 @@ TUPLE: db-persistence responder db params ;
 C: <db-persistence> db-persistence\r
 \r
 : connect-db ( db-persistence -- )\r
-    [ db>> ] [ params>> ] bi make-db\r
-    [ db set ] [ db-open ] [ add-always-destructor ] tri ;\r
+    [ db>> ] [ params>> ] bi make-db db-open\r
+    [ db set ] [ add-always-destructor ] bi ;\r
 \r
 M: db-persistence call-responder\r
     [ connect-db ] [ responder>> call-responder ] bi ;\r
diff --git a/extra/http/server/forms/forms.factor b/extra/http/server/forms/forms.factor
new file mode 100644 (file)
index 0000000..cf8fd4c
--- /dev/null
@@ -0,0 +1,48 @@
+USING: kernel accessors assocs namespaces io.files fry
+http.server.actions
+http.server.components
+http.server.validators
+http.server.templating.fhtml ;
+IN: http.server.forms
+
+TUPLE: form < component view-template edit-template components ;
+
+M: form init V{ } clone >>components ;
+
+: <form> ( id -- form )
+    form f new-component ;
+
+: add-field ( form component -- form )
+    dup id>> pick components>> set-at ;
+
+: with-form ( form quot -- )
+    >r components>> components r> with-variable ; inline
+
+: set-defaults ( form -- )
+    [
+        components get [
+            swap values get [
+                swap default>> or
+            ] change-at
+        ] assoc-each
+    ] with-form ;
+
+: view-form ( form -- )
+    dup view-template>> '[ , run-template ] with-form ;
+
+: edit-form ( form -- )
+    dup edit-template>> '[ , run-template ] with-form ;
+
+: validate-param ( id component -- )
+    [ [ params get at ] [ validate ] bi* ]
+    [ drop set-value ] 2bi ;
+
+: (validate-form) ( form -- error? )
+    [
+        validation-failed? off
+        components get [ validate-param ] assoc-each
+        validation-failed? get
+    ] with-form ;
+
+: validate-form ( form -- )
+    (validate-form) [ validation-failed ] when ;
index 2cc0f80f030e43d24d62c04ea340dc96aaf103f6..db03645a24f78b3fb0c7bb903c0f5cc120493b92 100755 (executable)
@@ -89,7 +89,7 @@ SYMBOL: form-hook
     {
         { [ over "http://" head? ] [ link>string ] }
         { [ over "/" head? ] [ absolute-redirect ] }
-        { [ t ] [ relative-redirect ] }
+        [ relative-redirect ]
     } cond ;
 
 : <redirect> ( to query code message -- response )
@@ -105,8 +105,13 @@ SYMBOL: form-hook
 
 TUPLE: dispatcher default responders ;
 
+: new-dispatcher ( class -- dispatcher )
+    new
+        404-responder get >>default
+        H{ } clone >>responders ; inline
+
 : <dispatcher> ( -- dispatcher )
-    404-responder get H{ } clone dispatcher construct-boa ;
+    dispatcher new-dispatcher ;
 
 : split-path ( path -- rest first )
     [ CHAR: / = ] left-trim "/" split1 swap ;
@@ -125,13 +130,10 @@ M: dispatcher call-responder ( path dispatcher -- response )
         2drop redirect-with-/
     ] if ;
 
-: <webapp> ( class -- dispatcher )
-    <dispatcher> swap construct-delegate ; inline
-
 TUPLE: vhost-dispatcher default responders ;
 
 : <vhost-dispatcher> ( -- dispatcher )
-    404-responder get H{ } clone vhost-dispatcher construct-boa ;
+    404-responder get H{ } clone vhost-dispatcher boa ;
 
 : find-vhost ( dispatcher -- responder )
     request get host>> over responders>> at*
index a3d06e8f18357b88ec0fbdc0c003cf9105cc7f54..9e4f5385831cd6f10898232e6555e9d923b5e69e 100755 (executable)
@@ -17,9 +17,10 @@ M: object init-session* drop ;
 
 TUPLE: session-manager responder sessions ;
 
-: <session-manager> ( responder class -- responder' )
-    >r <sessions-in-memory> session-manager construct-boa
-    r> construct-delegate ; inline
+: new-session-manager ( responder class -- responder' )
+    new
+        <sessions-in-memory> >>sessions
+        swap >>responder ; inline
 
 SYMBOLS: session session-id session-changed? ;
 
@@ -64,18 +65,18 @@ M: session-saver dispose
     [ [ session-id set ] [ session set ] bi* ] 2bi
     [ session-manager set ] [ responder>> call-responder ] bi ;
 
-TUPLE: null-sessions ;
+TUPLE: null-sessions < session-manager ;
 
 : <null-sessions>
-    null-sessions <session-manager> ;
+    null-sessions new-session-manager ;
 
 M: null-sessions call-responder ( path responder -- response )
     H{ } clone f call-responder/session ;
 
-TUPLE: url-sessions ;
+TUPLE: url-sessions < session-manager ;
 
 : <url-sessions> ( responder -- responder' )
-    url-sessions <session-manager> ;
+    url-sessions new-session-manager ;
 
 : session-id-key "factorsessid" ;
 
@@ -84,7 +85,7 @@ TUPLE: url-sessions ;
     [ drop ] [ get-session ] 2bi ;
 
 : add-session-id ( query -- query' )
-    session-id get [ session-id-key associate union ] when* ;
+    session-id get [ session-id-key associate assoc-union ] when* ;
 
 : session-form-field ( -- )
     <input
@@ -107,10 +108,10 @@ M: url-sessions call-responder ( path responder -- response )
         2drop nip new-url-session
     ] if ;
 
-TUPLE: cookie-sessions ;
+TUPLE: cookie-sessions < session-manager ;
 
 : <cookie-sessions> ( responder -- responder' )
-    cookie-sessions <session-manager> ;
+    cookie-sessions new-session-manager ;
 
 : current-cookie-session ( responder -- id namespace/f )
     request get session-id-key get-cookie dup
index 4bdc52b86e710c2281be542466a229a22aaddf9c..6e4a84d646344deec56bfc3cbb6ceb734b44d47b 100755 (executable)
@@ -7,7 +7,7 @@ IN: http.server.sessions.storage.assoc
 TUPLE: sessions-in-memory sessions alarms ;\r
 \r
 : <sessions-in-memory> ( -- storage )\r
-    H{ } clone H{ } clone sessions-in-memory construct-boa ;\r
+    H{ } clone H{ } clone sessions-in-memory boa ;\r
 \r
 : cancel-session-timeout ( id storage -- )\r
     alarms>> at [ cancel-alarm ] when* ;\r
index e573b22ba157b41867a115d61f1d1a7dc66e7a89..0245db15b0c4a051bd4e23d41c0c87fb20cdb46a 100755 (executable)
@@ -18,7 +18,7 @@ session "SESSIONS"
 : init-sessions-table session ensure-table ;
 
 : <session> ( id -- session )
-    session construct-empty
+    session new
         swap dup [ string>number ] when >>id ;
 
 M: sessions-in-db get-session ( id storage -- namespace/f )
index 905c7320ca7096aa7901e2d2de0a781633cb79a2..2d4a97c3c062276a74befd917d41e3612e12a3c5 100755 (executable)
@@ -10,7 +10,7 @@ IN: http.server.static
 TUPLE: file-responder root hook special ;\r
 \r
 : file-http-date ( filename -- string )\r
-    file-info file-info-modified timestamp>http-string ;\r
+    file-info modified>> timestamp>http-string ;\r
 \r
 : last-modified-matches? ( filename -- ? )\r
     file-http-date dup [\r
@@ -21,13 +21,13 @@ TUPLE: file-responder root hook special ;
     304 "Not modified" <trivial-response> ;\r
 \r
 : <file-responder> ( root hook -- responder )\r
-    H{ } clone file-responder construct-boa ;\r
+    H{ } clone file-responder boa ;\r
 \r
 : <static> ( root -- responder )\r
     [\r
         <content>\r
         swap\r
-        [ file-info file-info-size "content-length" set-header ]\r
+        [ file-info size>> "content-length" set-header ]\r
         [ file-http-date "last-modified" set-header ]\r
         [ '[ , binary <file-reader> stdio get stream-copy ] >>body ]\r
         tri\r
index f3d9d54a25e91acd34884f66c0c424a99e8acd08..4a3bf38e23e4d5b7fdcefbd923b287fd51bbbcc3 100755 (executable)
@@ -1,50 +1,47 @@
 ! Copyright (C) 2005 Alex Chapman
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations sequences kernel parser namespaces io
 io.files io.streams.string html html.elements source-files
 debugger combinators math quotations generic strings splitting
 accessors http.server.static http.server assocs
-io.encodings.utf8 fry ;
+io.encodings.utf8 fry accessors ;
 
 IN: http.server.templating.fhtml
 
 : templating-vocab ( -- vocab-name ) "http.server.templating.fhtml" ;
 
-! See apps/http-server/test/ or libs/furnace/ for template usage
-! examples
-
 ! We use a custom lexer so that %> ends a token even if not
 ! followed by whitespace
-TUPLE: template-lexer ;
+TUPLE: template-lexer < lexer ;
 
 : <template-lexer> ( lines -- lexer )
-    <lexer> template-lexer construct-delegate ;
+    template-lexer new-lexer ;
 
 M: template-lexer skip-word
     [
         {
             { [ 2dup nth CHAR: " = ] [ drop 1+ ] }
             { [ 2dup swap tail-slice "%>" head? ] [ drop 2 + ] }
-            { [ t ] [ f skip ] }
+            [ f skip ]
         } cond
     ] change-lexer-column ;
 
 DEFER: <% delimiter
 
 : check-<% ( lexer -- col )
-    "<%" over lexer-line-text rot lexer-column start* ;
+    "<%" over line-text>> rot column>> start* ;
 
 : found-<% ( accum lexer col -- accum )
     [
-        over lexer-line-text
-        >r >r lexer-column r> r> subseq parsed
+        over line-text>>
+        >r >r column>> r> r> subseq parsed
         \ write-html parsed
-    ] 2keep 2 + swap set-lexer-column ;
+    ] 2keep 2 + >>column drop ;
 
 : still-looking ( accum lexer -- accum )
     [
-        dup lexer-line-text swap lexer-column tail
+        [ line-text>> ] [ column>> ] bi tail
         parsed \ print-html parsed
     ] keep next-line ;
 
index 32a1125809ae71f43b06cecf3f6a430c74d29887..5be064c5ce716fbc1b82ce4d3c4c308b40aa581b 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel continuations sequences math namespaces
+USING: kernel continuations sequences math namespaces sets
 math.parser assocs regexp fry unicode.categories sequences ;
 IN: http.server.validators
 
@@ -70,7 +70,7 @@ C: <validation-error> validation-error
     dup empty? [ "must remain blank" throw ] unless ;
 
 : v-one-line ( str -- str )
-    dup "\r\n" seq-intersect empty?
+    dup "\r\n" intersect empty?
     [ "must be a single line" throw ] unless ;
 
 : v-one-word ( str -- str )
index 31e7c5f78a67fbb5d0055bd39b2e7e251103b667..0df41cf53ffe2930dba7729dd4742d8db321b282 100644 (file)
@@ -1,5 +1,5 @@
 USING: inverse tools.test arrays math kernel sequences
-math.functions math.constants ;
+math.functions math.constants continuations ;
 IN: inverse-tests
 
 [ 2 ] [ { 3 2 } [ 3 swap 2array ] undo ] unit-test
@@ -51,7 +51,7 @@ C: <nil> nil
     {
         { [ <cons> ] [ list-sum + ] }
         { [ <nil> ] [ 0 ] }
-        { [ ] [ "Malformed list" throw ] }
+        [ "Malformed list" throw ]
     } switch ;
 
 [ 10 ] [ 1 2 3 4 <nil> <cons> <cons> <cons> <cons> list-sum ] unit-test
@@ -59,8 +59,9 @@ C: <nil> nil
 [ 1 2 ] [ 1 2 <cons> [ <cons> ] undo ] unit-test
 [ t ] [ 1 2 <cons> [ <cons> ] matches? ] unit-test
 [ f ] [ 1 2 <cons> [ <foo> ] matches? ] unit-test
+[ "Malformed list" ] [ [ f list-sum ] [ ] recover ] unit-test
 
-: empty-cons ( -- cons ) cons construct-empty ;
+: empty-cons ( -- cons ) cons new ;
 : cons* ( cdr car -- cons ) { set-cons-cdr set-cons-car } cons construct ;
 
 [ ] [ T{ cons f f f } [ empty-cons ] undo ] unit-test
@@ -68,3 +69,4 @@ C: <nil> nil
 
 [ t ] [ pi [ pi ] matches? ] unit-test
 [ 0.0 ] [ 0.0 pi + [ pi + ] undo ] unit-test
+[ ] [ 3 [ _ ] undo ] unit-test
index 1b7badd94a9a2d16a5da4b94caf502cf8c9aab2a..7a2856e311993580ee7881597b735fad3173661e 100755 (executable)
@@ -6,7 +6,7 @@ mirrors combinators.lib ;
 IN: inverse
 
 TUPLE: fail ;
-: fail ( -- * ) \ fail construct-empty throw ;
+: fail ( -- * ) \ fail new throw ;
 M: fail summary drop "Unification failed" ;
 
 : assure ( ? -- ) [ fail ] unless ;
@@ -26,7 +26,7 @@ M: fail summary drop "Unification failed" ;
     "pop-inverse" set-word-prop ;
 
 TUPLE: no-inverse word ;
-: no-inverse ( word -- * ) \ no-inverse construct-empty throw ;
+: no-inverse ( word -- * ) \ no-inverse new throw ;
 M: no-inverse summary
     drop "The word cannot be used in pattern matching" ;
 
@@ -60,11 +60,13 @@ PREDICATE: math-inverse < word "math-inverse" word-prop ;
 PREDICATE: pop-inverse < word "pop-length" word-prop ;
 UNION: explicit-inverse normal-inverse math-inverse pop-inverse ;
 
-: enough? ( stack quot -- ? )
-    [ >r length r> 1quotation infer effect-in >= ] [ 3drop f ]
-    recover ;
+: enough? ( stack word -- ? )
+    dup deferred? [ 2drop f ] [
+        [ >r length r> 1quotation infer effect-in >= ]
+        [ 3drop f ] recover
+    ] if ;
 
-: fold-word ( stack quot -- stack )
+: fold-word ( stack word -- stack )
     2dup enough?
     [ 1quotation with-datastack ] [ >r % r> , { } ] if ;
 
@@ -72,10 +74,10 @@ UNION: explicit-inverse normal-inverse math-inverse pop-inverse ;
     [ { } swap [ fold-word ] each % ] [ ] make ; 
 
 : flattenable? ( object -- ? )
-    [ [ word? ] [ primitive? not ] and? ] [
+    { [ word? ] [ primitive? not ] [
         { "inverse" "math-inverse" "pop-inverse" }
         [ word-prop ] with contains? not
-    ] and? ; 
+    ] } <-&& ; 
 
 : (flatten) ( quot -- )
     [ dup flattenable? [ word-def (flatten) ] [ , ] if ] each ;
@@ -159,7 +161,7 @@ MACRO: undo ( quot -- ) [undo] ;
     2curry
 ] define-pop-inverse
 
-: _ f ;
+DEFER: _
 \ _ [ drop ] define-inverse
 
 : both ( object object -- object )
@@ -193,6 +195,10 @@ MACRO: undo ( quot -- ) [undo] ;
 \ first3 [ 3array ] define-inverse
 \ first4 [ 4array ] define-inverse
 
+\ prefix [ unclip ] define-inverse
+\ unclip [ prefix ] define-inverse
+\ suffix [ dup 1 head* swap peek ] define-inverse
+
 ! Constructor inverse
 : deconstruct-pred ( class -- quot )
     "predicate" word-prop [ dupd call assure ] curry ;
@@ -208,14 +214,14 @@ MACRO: undo ( quot -- ) [undo] ;
 : boa-inverse ( class -- quot )
     [ deconstruct-pred ] keep slot-readers compose ;
 
-\ construct-boa 1 [ ?wrapped boa-inverse ] define-pop-inverse
+\ boa 1 [ ?wrapped boa-inverse ] define-pop-inverse
 
 : empty-inverse ( class -- quot )
     deconstruct-pred
     [ tuple>array 1 tail [ ] contains? [ fail ] when ]
     compose ;
 
-\ construct-empty 1 [ ?wrapped empty-inverse ] define-pop-inverse
+\ new 1 [ ?wrapped empty-inverse ] define-pop-inverse
 
 : writer>reader ( word -- word' )
     [ "writing" word-prop "slots" word-prop ] keep
@@ -249,13 +255,14 @@ MACRO: undo ( quot -- ) [undo] ;
 MACRO: matches? ( quot -- ? ) [matches?] ;
 
 TUPLE: no-match ;
-: no-match ( -- * ) \ no-match construct-empty throw ;
+: no-match ( -- * ) \ no-match new throw ;
 M: no-match summary drop "Fall through in switch" ;
 
 : recover-chain ( seq -- quot )
     [ no-match ] [ swap \ recover-fail 3array >quotation ] reduce ;
 
 : [switch]  ( quot-alist -- quot )
+    [ dup quotation? [ [ ] swap 2array ] when ] map
     reverse [ >r [undo] r> compose ] { } assoc>map
     recover-chain ;
 
index 8b00e59d23cbe03426b81d1af63ba2823b74ae69..a9014755446ab9cd6828b82835decee50295eb36 100755 (executable)
@@ -9,7 +9,7 @@ accessors ;
 TUPLE: buffer size ptr fill pos ;
 
 : <buffer> ( n -- buffer )
-    dup malloc 0 0 buffer construct-boa ;
+    dup malloc 0 0 buffer boa ;
 
 : buffer-free ( buffer -- )
     dup buffer-ptr free  f swap set-buffer-ptr ;
index e8dadc13f7b15e3f459f358b94b97ed358bb41e5..33d629b10541f4b507d208c75cd71300beaf89fe 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.syntax help.markup io.encodings.8-bit.private ;
+USING: help.syntax help.markup io.encodings.8-bit.private
+strings ;
 IN: io.encodings.8-bit
 
 ARTICLE: "io.encodings.8-bit" "8-bit encodings"
@@ -34,8 +35,8 @@ HELP: 8-bit
 { $class-description "Describes an 8-bit encoding, including its name (a symbol) and a table used for encoding and decoding." } ;
 
 HELP: define-8-bit-encoding
-{ $values { "name" "a string" } { "path" "a path" } }
-{ $description "Creates a new encoding with the given name, using the resource file at the path to tell how to encode and decode octets. The resource file should be in a similar format to those at " { $url "ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/" } } ;
+{ $values { "name" string } { "stream" "an input stream" } }
+{ $description "Creates a new encoding. The stream should be in a similar format to those at " { $url "ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/" } } ;
 
 HELP: latin1
 { $description "This is the ISO-8859-1 encoding, also called Latin-1: Western European. It is an 8-bit superset of ASCII which is the default for a mimetype starting with 'text' and provides the characters necessary for most western European languages." } 
index 259173fec4ea8d1285b6531ebf468980b2d190b1..dc6e52d67efacc252038f1ecf169bac36ec21040 100755 (executable)
@@ -29,9 +29,10 @@ IN: io.encodings.8-bit
     { "mac-roman" "ROMAN" }
 } ;
 
-: full-path ( file-name -- path )
+: encoding-file ( file-name -- stream )
     "extra/io/encodings/8-bit/" ".TXT"
-    swapd 3append resource-path ;
+    swapd 3append resource-path
+    ascii <file-reader> ;
 
 : tail-if ( seq n -- newseq )
     2dup swap length <= [ tail ] [ drop ] if ;
@@ -48,8 +49,8 @@ IN: io.encodings.8-bit
 : ch>byte ( assoc -- newassoc )
     [ swap ] assoc-map >hashtable ;
 
-: parse-file ( file-name -- byte>ch ch>byte )
-    ascii file-lines process-contents
+: parse-file ( path -- byte>ch ch>byte )
+    lines process-contents
     [ byte>ch ] [ ch>byte ] bi ;
 
 TUPLE: 8-bit name decode encode ;
@@ -69,15 +70,15 @@ M: 8-bit decode-char
     decode>> decode-8-bit ;
 
 : make-8-bit ( word byte>ch ch>byte -- )
-    [ 8-bit construct-boa ] 2curry dupd curry define ;
+    [ 8-bit boa ] 2curry dupd curry define ;
 
-: define-8-bit-encoding ( name path -- )
+: define-8-bit-encoding ( name stream -- )
     >r in get create r> parse-file make-8-bit ;
 
 PRIVATE>
 
 [
     "io.encodings.8-bit" in [
-        mappings [ full-path define-8-bit-encoding ] assoc-each
+        mappings [ encoding-file define-8-bit-encoding ] assoc-each
     ] with-variable
 ] with-compilation-unit
index 89c10d89cc75572e17ff5ab14839166ea5f4e0e1..21eb231075cff024253d5cd22ffb0f6d24e5e6cb 100644 (file)
@@ -7,7 +7,7 @@ TUPLE: strict code ;
 C: strict strict
 
 TUPLE: decode-error ;
-: decode-error ( -- * ) \ decode-error construct-empty throw ;
+: decode-error ( -- * ) \ decode-error new throw ;
 M: decode-error summary
     drop "Error in decoding input stream" ;
 
index 0f6ca3a2c91f171cee5338ca5ffabb30043a39ba..4446b82f208f2ffd91ebc0dacc7287b9234c71b2 100755 (executable)
@@ -129,9 +129,6 @@ HELP: <process>
 { $values { "process" process } }
 { $description "Creates a new, empty process. It must be filled in before being passed to " { $link run-process } "." } ;
 
-HELP: process-stream
-{ $class-description "A bidirectional stream for interacting with a running process. Instances are created by calling " { $link <process-stream> } ". The " { $link process-stream-process } " slot holds a " { $link process } " instance." } ;
-
 HELP: <process-stream>
 { $values
   { "desc" "a launch descriptor" }
@@ -144,7 +141,7 @@ HELP: with-process-stream
   { "desc" "a launch descriptor" }
   { "quot" quotation }
   { "status" "an exit code" } }
-{ $description "Calls " { $snippet "quot" } " in a dynamic scope where " { $link stdio } " is rebound to a " { $link process-stream } ". After the quotation returns, waits for the process to end and outputs the exit code." } ;
+{ $description "Calls " { $snippet "quot" } " in a dynamic scope where " { $link stdio } " is rebound to a process stream. After the quotation returns, waits for the process to end and outputs the exit code." } ;
 
 HELP: wait-for-process
 { $values { "process" process } { "status" integer } }
index fa4bdcaaea8df5171830f229bab12df158cdf14e..9b480d0cc2974e1d4bc9987de6051c752d71ef7e 100755 (executable)
@@ -41,7 +41,7 @@ SYMBOL: +highest-priority+
 SYMBOL: +realtime-priority+
 
 : <process> ( -- process )
-    process construct-empty
+    process new
     H{ } clone >>environment
     +append-environment+ >>environment-mode ;
 
@@ -85,8 +85,8 @@ M: process hashcode* process-handle hashcode* ;
 : get-environment ( process -- env )
     dup environment>>
     swap environment-mode>> {
-        { +prepend-environment+ [ os-envs union ] }
-        { +append-environment+ [ os-envs swap union ] }
+        { +prepend-environment+ [ os-envs assoc-union ] }
+        { +append-environment+ [ os-envs swap assoc-union ] }
         { +replace-environment+ [ ] }
     } case ;
 
@@ -130,7 +130,7 @@ HOOK: run-process* io-backend ( process -- handle )
 TUPLE: process-failed code ;
 
 : process-failed ( code -- * )
-    \ process-failed construct-boa throw ;
+    \ process-failed boa throw ;
 
 : try-process ( desc -- )
     run-process wait-for-process dup zero?
@@ -150,18 +150,18 @@ M: process timed-out kill-process ;
 
 HOOK: (process-stream) io-backend ( process -- handle in out )
 
-TUPLE: process-stream process ;
+: <process-stream*> ( desc encoding -- stream process )
+    >r >process dup dup (process-stream) <reader&writer>
+    r> <encoder-duplex> -roll
+    process-started ;
 
 : <process-stream> ( desc encoding -- stream )
-    >r >process dup dup (process-stream)
-    >r >r process-started process-stream construct-boa
-    r> r> <reader&writer> r> <encoder-duplex>
-    over set-delegate ;
+    <process-stream*> drop ; inline
 
 : with-process-stream ( desc quot -- status )
-    swap <process-stream>
+    swap <process-stream*> >r
     [ swap with-stream ] keep
-    process>> wait-for-process ; inline
+    r> wait-for-process ; inline
 
 : notify-exit ( process status -- )
     >>status
index b17d7aeab932a25db6aaa3d988e9848136c74472..a00f7cd92b38248bc8e734e51986d8b97036dea9 100755 (executable)
@@ -1,10 +1,10 @@
 USING: io io.mmap io.files kernel tools.test continuations
-sequences io.encodings.ascii ;
+sequences io.encodings.ascii accessors ;
 IN: io.mmap.tests
 
 [ "mmap-test-file.txt" resource-path delete-file ] ignore-errors
 [ ] [ "12345" "mmap-test-file.txt" resource-path ascii set-file-contents ] unit-test
-[ ] [ "mmap-test-file.txt" resource-path dup file-info file-info-size [ CHAR: 2 0 pick set-nth drop ] with-mapped-file ] unit-test
-[ 5 ] [ "mmap-test-file.txt" resource-path dup file-info file-info-size [ length ] with-mapped-file ] unit-test
+[ ] [ "mmap-test-file.txt" resource-path dup file-info size>> [ CHAR: 2 0 pick set-nth drop ] with-mapped-file ] unit-test
+[ 5 ] [ "mmap-test-file.txt" resource-path dup file-info size>> [ length ] with-mapped-file ] unit-test
 [ "22345" ] [ "mmap-test-file.txt" resource-path ascii file-contents ] unit-test
 [ "mmap-test-file.txt" resource-path delete-file ] ignore-errors
index 76a354b0bd8926bf57524e50e983842bba0aac25..cd6a06a8e97002adf527e2183203e50c99fc651c 100755 (executable)
 IN: io.monitors\r
-USING: help.markup help.syntax continuations ;\r
+USING: help.markup help.syntax continuations\r
+concurrency.mailboxes quotations ;\r
+\r
+HELP: with-monitors\r
+{ $values { "quot" quotation } }\r
+{ $description "Calls a quotation in a new dynamic scope where file system monitor operations can be performed." }\r
+{ $errors "Throws an error if the platform does not support file system change monitors." } ;\r
 \r
 HELP: <monitor>\r
 { $values { "path" "a pathname string" } { "recursive?" "a boolean" } { "monitor" "a new monitor" } }\r
-{ $description "Opens a file system change monitor which listens for changes on " { $snippet "path" } ". The boolean indicates whether changes in subdirectories should be reported."\r
-$nl\r
-"Not all operating systems support recursive monitors; if recursive monitoring is not available, an error is thrown and the caller must implement alternative logic for monitoring subdirectories." } ;\r
+{ $contract "Opens a file system change monitor which listens for changes on " { $snippet "path" } ". The boolean indicates whether changes in subdirectories should be reported." }\r
+{ $errors "Throws an error if the pathname does not exist, if a monitor could not be created or if the platform does not support monitors." } ;\r
+\r
+HELP: (monitor)\r
+{ $values { "path" "a pathname string" } { "recursive?" "a boolean" } { "mailbox" mailbox } { "monitor" "a new monitor" } }\r
+{ $contract "Opens a file system change monitor which listens for changes on " { $snippet "path" } " and posts notifications to " { $snippet "mailbox" } " as triples with shape " { $snippet "{ path changed monitor } " } ". The boolean indicates whether changes in subdirectories should be reported." }\r
+{ $errors "Throws an error if the pathname does not exist, if a monitor could not be created or if the platform does not support monitors." } ;\r
 \r
 HELP: next-change\r
 { $values { "monitor" "a monitor" } { "path" "a pathname string" } { "changed" "a change descriptor" } }\r
-{ $description "Waits for file system changes and outputs the pathname of the first changed file. The change descriptor is aq sequence of symbols documented in " { $link "io.monitors.descriptors" } "." } ;\r
+{ $contract "Waits for file system changes and outputs the pathname of the first changed file. The change descriptor is a sequence of symbols documented in " { $link "io.monitors.descriptors" } "." }\r
+{ $errors "Throws an error if the monitor is closed from another thread." } ;\r
 \r
 HELP: with-monitor\r
 { $values { "path" "a pathname string" } { "recursive?" "a boolean" } { "quot" "a quotation with stack effect " { $snippet "( monitor -- )" } } }\r
-{ $description "Opens a file system change monitor and passes it to the quotation. Closes the monitor after the quotation returns or throws an error." } ;\r
+{ $description "Opens a file system change monitor and passes it to the quotation. Closes the monitor after the quotation returns or throws an error." }\r
+{ $errors "Throws an error if the pathname does not exist, if a monitor could not be created or if the platform does not support monitors." } ;\r
 \r
 HELP: +add-file+\r
-{ $description "Indicates that the file has been added to the directory." } ;\r
+{ $description "Indicates that a file has been added to its parent directory." } ;\r
 \r
 HELP: +remove-file+\r
-{ $description "Indicates that the file has been removed from the directory." } ;\r
+{ $description "Indicates that a file has been removed from its parent directory." } ;\r
 \r
 HELP: +modify-file+\r
-{ $description "Indicates that the file contents have changed." } ;\r
+{ $description "Indicates that a file's contents have changed." } ;\r
+\r
+HELP: +rename-file-old+\r
+{ $description "Indicates that a file has been renamed, and this is the old name." } ;\r
+\r
+HELP: +rename-file-new+\r
+{ $description "Indicates that a file has been renamed, and this is the new name." } ;\r
 \r
 HELP: +rename-file+\r
-{ $description "Indicates that file has been renamed." } ;\r
+{ $description "Indicates that file has been renamed." } ;\r
 \r
 ARTICLE: "io.monitors.descriptors" "File system change descriptors"\r
 "Change descriptors output by " { $link next-change } ":"\r
 { $subsection +add-file+ }\r
 { $subsection +remove-file+ }\r
 { $subsection +modify-file+ }\r
-{ $subsection +rename-file+ }\r
-{ $subsection +add-file+ } ;\r
+{ $subsection +rename-file-old+ }\r
+{ $subsection +rename-file-new+ }\r
+{ $subsection +rename-file+ } ;\r
+\r
+ARTICLE: "io.monitors.platforms" "Monitors on different platforms"\r
+"Whether the " { $snippet "path" } " output value of " { $link next-change } " contains an absolute path or a path relative to the path given to " { $link <monitor> } " is platform-specific. User code should not assume either case."\r
+{ $heading "Mac OS X" }\r
+"Factor uses " { $snippet "FSEventStream" } "s to implement monitors on Mac OS X. This requires Mac OS X 10.5 or later."\r
+$nl\r
+{ $snippet "FSEventStream" } "s always monitor directory hierarchies recursively, and the " { $snippet "recursive?" } " parameter to " { $link <monitor> } " has no effect."\r
+$nl\r
+"The " { $snippet "changed" } " output value of the " { $link next-change } " word always outputs " { $link +modify-file+ } " and the " { $snippet "path" } " output value is always the directory containing the file that changed. Unlike other platforms, fine-grained information is not available."\r
+{ $heading "Windows" }\r
+"Factor uses " { $snippet "ReadDirectoryChanges" } " to implement monitors on Windows."\r
+$nl\r
+"Both recursive and non-recursive monitors are directly supported by the operating system."\r
+{ $heading "Linux" }\r
+"Factor uses " { $snippet "inotify" } " to implement monitors on Linux. This requires Linux kernel version 2.6.16 or later."\r
+$nl\r
+"Factor simulates recursive monitors by creating a hierarchy of monitors for every subdirectory, since " { $snippet "inotify" } " can only monitor a single directory. This is transparent to user code."\r
+$nl\r
+"Inside a single " { $link with-monitors } " scope, only one monitor may be created for any given directory."\r
+{ $heading "BSD" }\r
+"Factor uses " { $snippet "kqueue" } " to implement monitors on BSD."\r
+$nl\r
+"The " { $snippet "kqueue" } " system is limited to monitoring individual files and directories. Monitoring a directory only notifies of files being added and removed to the directory itself, not of changes to file contents."\r
+{ $heading "Windows CE" }\r
+"Windows CE does not support monitors." ;\r
 \r
 ARTICLE: "io.monitors" "File system change monitors"\r
 "File system change monitors listen for changes to file names, attributes and contents under a specified directory. They can optionally be recursive, in which case subdirectories are also monitored."\r
 $nl\r
+"Monitoring operations must be wrapped in a combinator:"\r
+{ $subsection with-monitors }\r
 "Creating a file system change monitor and listening for changes:"\r
 { $subsection <monitor> }\r
 { $subsection next-change }\r
+"An alternative programming style is where instead of having a thread listen for changes on a monitor, change notifications are posted to a mailbox:"\r
+{ $subsection (monitor) }\r
 { $subsection "io.monitors.descriptors" }\r
-"Monitors are closed by calling " { $link dispose } " or " { $link with-disposal } "."\r
-$nl\r
-"A utility combinator which opens a monitor and cleans it up after:"\r
+{ $subsection "io.monitors.platforms" } \r
+"Monitors are closed by calling " { $link dispose } " or " { $link with-disposal } ". An easy way to pair construction with disposal is to use a combinator:"\r
 { $subsection with-monitor }\r
-"An example which watches the Factor directory for changes:"\r
+"Monitors support the " { $link "io.timeouts" } "."\r
+$nl\r
+"An example which watches a directory for changes:"\r
 { $code\r
     "USE: io.monitors"\r
     ": watch-loop ( monitor -- )"\r
     "    dup next-change . . nl nl flush watch-loop ;"\r
     ""\r
-    "\"\" resource-path f [ watch-loop ] with-monitor"\r
+    ": watch-directory ( path -- )"\r
+    "    [ t [ watch-loop ] with-monitor ] with-monitors"\r
 } ;\r
 \r
 ABOUT: "io.monitors"\r
diff --git a/extra/io/monitors/monitors-tests.factor b/extra/io/monitors/monitors-tests.factor
new file mode 100644 (file)
index 0000000..6407108
--- /dev/null
@@ -0,0 +1,91 @@
+IN: io.monitors.tests
+USING: io.monitors tools.test io.files system sequences
+continuations namespaces concurrency.count-downs kernel io
+threads calendar prettyprint ;
+
+os { winnt linux macosx } member? [
+    [
+        [ "monitor-test" temp-file delete-tree ] ignore-errors
+
+        [ ] [ "monitor-test" temp-file make-directory ] unit-test
+
+        [ ] [ "monitor-test" temp-file t <monitor> "m" set ] unit-test
+
+        [ ] [ "monitor-test/a1" temp-file make-directory ] unit-test
+
+        [ ] [ "monitor-test/a2" temp-file make-directory ] unit-test
+
+        [ ] [ "monitor-test/a1" temp-file "monitor-test/a2" temp-file move-file-into ] unit-test
+
+        [ t ] [ "monitor-test/a2/a1" temp-file exists? ] unit-test
+
+        [ ] [ "monitor-test/a2/a1/a3.txt" temp-file touch-file ] unit-test
+
+        [ t ] [ "monitor-test/a2/a1/a3.txt" temp-file exists? ] unit-test
+
+        [ ] [ "monitor-test/a2/a1/a4.txt" temp-file touch-file ] unit-test
+        [ ] [ "monitor-test/a2/a1/a5.txt" temp-file touch-file ] unit-test
+        [ ] [ "monitor-test/a2/a1/a4.txt" temp-file delete-file ] unit-test
+        [ ] [ "monitor-test/a2/a1/a5.txt" temp-file "monitor-test/a2/a1/a4.txt" temp-file move-file ] unit-test
+
+        [ t ] [ "monitor-test/a2/a1/a4.txt" temp-file exists? ] unit-test
+
+        [ ] [ "m" get dispose ] unit-test
+    ] with-monitors
+
+    
+    [
+        [ "monitor-test" temp-file delete-tree ] ignore-errors
+        
+        [ ] [ "monitor-test/xyz" temp-file make-directories ] unit-test
+        
+        [ ] [ "monitor-test" temp-file t <monitor> "m" set ] unit-test
+        
+        [ ] [ 1 <count-down> "b" set ] unit-test
+        
+        [ ] [ 1 <count-down> "c1" set ] unit-test
+        
+        [ ] [ 1 <count-down> "c2" set ] unit-test
+        
+        [ ] [
+            [
+                "b" get count-down
+
+                [
+                    "m" get next-change drop
+                    dup print flush
+                    dup parent-directory
+                    [ right-trim-separators "xyz" tail? ] either? not
+                ] [ ] [ ] while
+
+                "c1" get count-down
+                
+                [
+                    "m" get next-change drop
+                    dup print flush
+                    dup parent-directory
+                    [ right-trim-separators "yxy" tail? ] either? not
+                ] [ ] [ ] while
+
+                "c2" get count-down
+            ] "Monitor test thread" spawn drop
+        ] unit-test
+        
+        [ ] [ "b" get await ] unit-test
+        
+        [ ] [ "monitor-test/xyz/test.txt" temp-file touch-file ] unit-test
+
+        [ ] [ "c1" get 1 minutes await-timeout ] unit-test
+        
+        [ ] [ "monitor-test/subdir/blah/yxy" temp-file make-directories ] unit-test
+
+        [ ] [ "monitor-test/subdir/blah/yxy/test.txt" temp-file touch-file ] unit-test
+
+        [ ] [ "c2" get 1 minutes await-timeout ] unit-test
+
+        ! Dispose twice
+        [ ] [ "m" get dispose ] unit-test
+
+        [ ] [ "m" get dispose ] unit-test
+    ] with-monitors
+] when
index 1678c2de41a82356e7ebbb21a2e23e36b04d34d4..863c8fc95cfb5bb7634803b2b6979344c8e1d4c3 100755 (executable)
@@ -1,83 +1,55 @@
-! Copyright (C) 2008 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: io.backend kernel continuations namespaces sequences\r
-assocs hashtables sorting arrays threads boxes io.timeouts ;\r
-IN: io.monitors\r
-\r
-<PRIVATE\r
-\r
-TUPLE: monitor queue closed? ;\r
-\r
-: check-monitor ( monitor -- )\r
-    monitor-closed? [ "Monitor closed" throw ] when ;\r
-\r
-: (monitor) ( delegate -- monitor )\r
-    H{ } clone {\r
-        set-delegate\r
-        set-monitor-queue\r
-    } monitor construct ;\r
-\r
-GENERIC: fill-queue ( monitor -- )\r
-\r
-: changed-file ( changed path -- )\r
-    namespace [ append ] change-at ;\r
-\r
-: dequeue-change ( assoc -- path changes )\r
-    delete-any prune natural-sort >array ;\r
-\r
-M: monitor dispose\r
-    dup check-monitor\r
-    t over set-monitor-closed?\r
-    delegate dispose ;\r
-\r
-! Simple monitor; used on Linux and Mac OS X. On Windows,\r
-! monitors are full-fledged ports.\r
-TUPLE: simple-monitor handle callback timeout ;\r
-\r
-M: simple-monitor timeout simple-monitor-timeout ;\r
-\r
-M: simple-monitor set-timeout set-simple-monitor-timeout ;\r
-\r
-: <simple-monitor> ( handle -- simple-monitor )\r
-    f (monitor) <box> {\r
-        set-simple-monitor-handle\r
-        set-delegate\r
-        set-simple-monitor-callback\r
-    } simple-monitor construct ;\r
-\r
-: construct-simple-monitor ( handle class -- simple-monitor )\r
-    >r <simple-monitor> r> construct-delegate ; inline\r
-\r
-: notify-callback ( simple-monitor -- )\r
-    simple-monitor-callback [ resume ] if-box? ;\r
-\r
-M: simple-monitor timed-out\r
-    notify-callback ;\r
-\r
-M: simple-monitor fill-queue ( monitor -- )\r
-    [\r
-        [ swap simple-monitor-callback >box ]\r
-        "monitor" suspend drop\r
-    ] with-timeout\r
-    check-monitor ;\r
-\r
-M: simple-monitor dispose ( monitor -- )\r
-    dup delegate dispose notify-callback ;\r
-\r
-PRIVATE>\r
-\r
-HOOK: <monitor> io-backend ( path recursive? -- monitor )\r
-\r
-: next-change ( monitor -- path changed )\r
-    dup check-monitor\r
-    dup monitor-queue dup assoc-empty? [\r
-        drop dup fill-queue next-change\r
-    ] [ nip dequeue-change ] if ;\r
-\r
-SYMBOL: +add-file+\r
-SYMBOL: +remove-file+\r
-SYMBOL: +modify-file+\r
-SYMBOL: +rename-file+\r
-\r
-: with-monitor ( path recursive? quot -- )\r
-    >r <monitor> r> with-disposal ; inline\r
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.backend kernel continuations namespaces sequences
+assocs hashtables sorting arrays threads boxes io.timeouts
+accessors concurrency.mailboxes ;
+IN: io.monitors
+
+HOOK: init-monitors io-backend ( -- )
+
+M: object init-monitors ;
+
+HOOK: dispose-monitors io-backend ( -- )
+
+M: object dispose-monitors ;
+
+: with-monitors ( quot -- )
+    [
+        init-monitors
+        [ dispose-monitors ] [ ] cleanup
+    ] with-scope ; inline
+
+TUPLE: monitor < identity-tuple path queue timeout ;
+
+M: monitor hashcode* path>> hashcode* ;
+
+M: monitor timeout timeout>> ;
+
+M: monitor set-timeout (>>timeout) ;
+
+: new-monitor ( path mailbox class -- monitor )
+    new
+        swap >>queue
+        swap >>path ; inline
+
+: queue-change ( path changes monitor -- )
+    3dup and and
+    [ [ 3array ] keep queue>> mailbox-put ] [ 3drop ] if ;
+
+HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor )
+
+: <monitor> ( path recursive? -- monitor )
+    <mailbox> (monitor) ;
+
+: next-change ( monitor -- path changed )
+    [ queue>> ] [ timeout ] bi mailbox-get-timeout first2 ;
+
+SYMBOL: +add-file+
+SYMBOL: +remove-file+
+SYMBOL: +modify-file+
+SYMBOL: +rename-file-old+
+SYMBOL: +rename-file-new+
+SYMBOL: +rename-file+
+
+: with-monitor ( path recursive? quot -- )
+    >r <monitor> r> with-disposal ; inline
diff --git a/extra/io/monitors/recursive/recursive-tests.factor b/extra/io/monitors/recursive/recursive-tests.factor
new file mode 100644 (file)
index 0000000..44baadf
--- /dev/null
@@ -0,0 +1,59 @@
+USING: accessors math kernel namespaces continuations
+io.files io.monitors io.monitors.recursive io.backend
+concurrency.mailboxes
+tools.test ;
+IN: io.monitors.recursive.tests
+
+\ pump-thread must-infer
+
+SINGLETON: mock-io-backend
+
+TUPLE: counter i ;
+
+SYMBOL: dummy-monitor-created
+SYMBOL: dummy-monitor-disposed
+
+TUPLE: dummy-monitor < monitor ;
+
+M: dummy-monitor dispose
+    drop dummy-monitor-disposed get [ 1+ ] change-i drop ;
+
+M: mock-io-backend (monitor)
+    nip
+    over exists? [
+        dummy-monitor new-monitor
+        dummy-monitor-created get [ 1+ ] change-i drop
+    ] [
+        "Does not exist" throw
+    ] if ;
+
+M: mock-io-backend link-info
+    global [ link-info ] bind ;
+
+[ ] [ 0 counter boa dummy-monitor-created set ] unit-test
+[ ] [ 0 counter boa dummy-monitor-disposed set ] unit-test
+
+[ ] [
+    mock-io-backend io-backend [
+        "" resource-path <mailbox> <recursive-monitor> dispose
+    ] with-variable
+] unit-test
+
+[ t ] [ dummy-monitor-created get i>> 0 > ] unit-test
+
+[ t ] [ dummy-monitor-created get i>> dummy-monitor-disposed get i>> = ] unit-test
+
+[ "doesnotexist" temp-file delete-tree ] ignore-errors
+
+[
+    mock-io-backend io-backend [
+        "doesnotexist" temp-file <mailbox> <recursive-monitor> dispose
+    ] with-variable
+] must-fail
+
+[ ] [
+    mock-io-backend io-backend [
+        "" resource-path <mailbox> <recursive-monitor>
+        [ dispose ] [ dispose ] bi
+    ] with-variable
+] unit-test
diff --git a/extra/io/monitors/recursive/recursive.factor b/extra/io/monitors/recursive/recursive.factor
new file mode 100644 (file)
index 0000000..1b18015
--- /dev/null
@@ -0,0 +1,105 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors sequences assocs arrays continuations combinators kernel
+threads concurrency.messaging concurrency.mailboxes
+concurrency.promises
+io.files io.monitors ;
+IN: io.monitors.recursive
+
+! Simulate recursive monitors on platforms that don't have them
+
+TUPLE: recursive-monitor < monitor children thread ready ;
+
+DEFER: add-child-monitor
+
+: qualify-path ( path -- path' )
+    monitor tget path>> prepend-path ;
+
+: add-child-monitors ( path -- )
+    #! We yield since this directory scan might take a while.
+    [
+        directory* [ first add-child-monitor yield ] each
+    ] curry ignore-errors ;
+
+: add-child-monitor ( path -- )
+    qualify-path dup link-info type>> +directory+ eq? [
+        [ add-child-monitors ]
+        [
+            [ f my-mailbox (monitor) ] keep
+            monitor tget children>> set-at
+        ] bi
+    ] [ drop ] if ;
+
+USE: io
+USE: prettyprint
+
+: remove-child-monitor ( monitor -- )
+    monitor tget children>> delete-at*
+    [ dispose ] [ drop ] if ;
+
+M: recursive-monitor dispose
+    dup queue>> closed>> [
+        drop
+    ] [
+        [ "stop" swap thread>> send-synchronous drop ]
+        [ queue>> dispose ] bi
+    ] if ;
+
+: stop-pump ( -- )
+    monitor tget children>> [ nip dispose ] assoc-each ;
+
+: pump-step ( msg -- )
+    first3 path>> swap >r prepend-path r> monitor tget 3array
+    monitor tget queue>>
+    mailbox-put ;
+
+: child-added ( path monitor -- )
+    path>> prepend-path add-child-monitor ;
+
+: child-removed ( path monitor -- )
+    path>> prepend-path remove-child-monitor ;
+
+: update-hierarchy ( msg -- )
+    first3 swap [
+        {
+            { +add-file+ [ child-added ] }
+            { +remove-file+ [ child-removed ] }
+            { +rename-file-old+ [ child-removed ] }
+            { +rename-file-new+ [ child-added ] }
+            [ 3drop ]
+        } case
+    ] with with each ;
+
+: pump-loop ( -- )
+    receive dup synchronous? [
+        >r stop-pump t r> reply-synchronous
+    ] [
+        [ [ update-hierarchy ] curry ignore-errors ] [ pump-step ] bi
+        pump-loop
+    ] if ;
+
+: monitor-ready ( error/t -- )
+    monitor tget ready>> fulfill ;
+
+: pump-thread ( monitor -- )
+    monitor tset
+    [ "" add-child-monitor t monitor-ready ]
+    [ [ self <linked-error> monitor-ready ] keep rethrow ]
+    recover
+    pump-loop ;
+
+: start-pump-thread ( monitor -- )
+    dup [ pump-thread ] curry
+    "Recursive monitor pump" spawn
+    >>thread drop ;
+
+: wait-for-ready ( monitor -- )
+    ready>> ?promise ?linked drop ;
+
+: <recursive-monitor> ( path mailbox -- monitor )
+    >r (normalize-path) r>
+    recursive-monitor new-monitor
+        H{ } clone >>children
+        <promise> >>ready
+    dup start-pump-thread
+    dup wait-for-ready ;
index ee9978f2c89a7bc8a106c79a30acd8eb028bdb8a..bd2be34c9dc3d3aab0c7a0417d6a8c25220b31ca 100755 (executable)
@@ -1,5 +1,5 @@
 USING: io io.buffers io.backend help.markup help.syntax kernel
-byte-arrays sbufs words continuations byte-vectors ;
+byte-arrays sbufs words continuations byte-vectors classes ;
 IN: io.nonblocking
 
 ARTICLE: "io.nonblocking" "Non-blocking I/O implementation"
@@ -36,10 +36,10 @@ HELP: port
 $nl
 "Ports have the following slots:"
 { $list
-    { { $link port-handle } " - a native handle identifying the underlying native resource used by the port" }
-    { { $link port-error } " - the most recent I/O error, if any. This error is thrown to the waiting thread when " { $link pending-error } " is called by stream operations" }
-    { { $link port-type } " - a symbol identifying the port's intended purpose" }
-    { { $link port-eof? } " - a flag indicating if the port has reached the end of file while reading" }
+    { { $snippet "handle" } " - a native handle identifying the underlying native resource used by the port" }
+    { { $snippet "error" } " - the most recent I/O error, if any. This error is thrown to the waiting thread when " { $link pending-error } " is called by stream operations" }
+    { { $snippet "type" } " - a symbol identifying the port's intended purpose" }
+    { { $snippet "eof" } " - a flag indicating if the port has reached the end of file while reading" }
 } } ;
 
 HELP: input-port
@@ -53,12 +53,12 @@ HELP: init-handle
 { $contract "Prepares a native handle for use by the port; called by " { $link <port> } "." } ;
 
 HELP: <port>
-{ $values { "handle" "a native handle identifying an I/O resource" } { "buffer" "a " { $link buffer } " or " { $link f } } { "type" symbol } { "port" "a new " { $link port } } }
-{ $description "Creates a new " { $link port } " using the specified native handle and I/O buffer." }
+{ $values { "handle" "a native handle identifying an I/O resource" } { "class" class } { "port" "a new " { $link port } } }
+{ $description "Creates a new " { $link port } " with no buffer." }
 $low-level-note ;
 
 HELP: <buffered-port>
-{ $values { "handle" "a native handle identifying an I/O resource" } { "type" symbol } { "port" "a new " { $link port } } }
+{ $values { "handle" "a native handle identifying an I/O resource" } { "class" class } { "port" "a new " { $link port } } }
 { $description "Creates a new " { $link port } " using the specified native handle and a default-sized I/O buffer." } 
 $low-level-note ;
 
@@ -93,5 +93,5 @@ HELP: unless-eof
 { $description "If the port has reached end of file, outputs " { $link f } ", otherwise applies the quotation to the port." } ;
 
 HELP: can-write?
-{ $values { "len" "a positive integer" } { "writer" output-port } { "?" "a boolean" } }
+{ $values { "len" "a positive integer" } { "buffer" buffer } { "?" "a boolean" } }
 { $description "Tests if the port's output buffer can accomodate " { $snippet "len" } " bytes. If the buffer is empty, this always outputs " { $link t } ", since in that case the buffer will be grown automatically." } ;
index 85319ad8ef155726dec78c1fccc453e21341975e..0bf7a6ccec7495dfc49dfb938ef5acea316ec012 100755 (executable)
@@ -1,46 +1,39 @@
 ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman
 ! See http://factorcode.org/license.txt for BSD license.
-IN: io.nonblocking
 USING: math kernel io sequences io.buffers io.timeouts generic
 byte-vectors system io.streams.duplex io.encodings
 io.backend continuations debugger classes byte-arrays namespaces
-splitting dlists assocs io.encodings.binary ;
+splitting dlists assocs io.encodings.binary inspector accessors ;
+IN: io.nonblocking
 
 SYMBOL: default-buffer-size
 64 1024 * default-buffer-size set-global
 
-! Common delegate of native stream readers and writers
-TUPLE: port
-handle
-error
-timeout
-type eof? ;
-
-M: port timeout port-timeout ;
-
-M: port set-timeout set-port-timeout ;
+TUPLE: port handle buffer error timeout closed eof ;
 
-SYMBOL: closed
+M: port timeout timeout>> ;
 
-PREDICATE: input-port < port port-type input-port eq? ;
-PREDICATE: output-port < port port-type output-port eq? ;
+M: port set-timeout (>>timeout) ;
 
 GENERIC: init-handle ( handle -- )
+
 GENERIC: close-handle ( handle -- )
 
-: <port> ( handle buffer type -- port )
-    pick init-handle {
-        set-port-handle
-        set-delegate
-        set-port-type
-    } port construct ;
+: <port> ( handle class -- port )
+    new
+        swap dup init-handle >>handle ; inline
+
+: <buffered-port> ( handle class -- port )
+    <port>
+        default-buffer-size get <buffer> >>buffer ; inline
 
-: <buffered-port> ( handle type -- port )
-    default-buffer-size get <buffer> swap <port> ;
+TUPLE: input-port < port ;
 
 : <reader> ( handle -- input-port )
     input-port <buffered-port> ;
 
+TUPLE: output-port < port ;
+
 : <writer> ( handle -- output-port )
     output-port <buffered-port> ;
 
@@ -48,7 +41,15 @@ GENERIC: close-handle ( handle -- )
     swap <reader> [ swap <writer> ] [ ] [ dispose drop ] cleanup ;
 
 : pending-error ( port -- )
-    dup port-error f rot set-port-error [ throw ] when* ;
+    [ f ] change-error drop [ throw ] when* ;
+
+ERROR: port-closed-error port ;
+
+M: port-closed-error summary
+    drop "Port has been closed" ;
+
+: check-closed ( port -- port )
+    dup closed>> [ port-closed-error ] when ;
 
 HOOK: cancel-io io-backend ( port -- )
 
@@ -59,21 +60,22 @@ M: port timed-out cancel-io ;
 GENERIC: (wait-to-read) ( port -- )
 
 : wait-to-read ( count port -- )
-    tuck buffer-length > [ (wait-to-read) ] [ drop ] if ;
+    tuck buffer>> buffer-length > [ (wait-to-read) ] [ drop ] if ;
 
 : wait-to-read1 ( port -- )
     1 swap wait-to-read ;
 
 : unless-eof ( port quot -- value )
-    >r dup buffer-empty? over port-eof? and
-    [ f swap set-port-eof? f ] r> if ; inline
+    >r dup buffer>> buffer-empty? over eof>> and
+    [ f >>eof drop f ] r> if ; inline
 
 M: input-port stream-read1
-    dup wait-to-read1 [ buffer-pop ] unless-eof ;
+    check-closed
+    dup wait-to-read1 [ buffer>> buffer-pop ] unless-eof ;
 
 : read-step ( count port -- byte-array/f )
     [ wait-to-read ] 2keep
-    [ dupd buffer-read ] unless-eof nip ;
+    [ dupd buffer>> buffer-read ] unless-eof nip ;
 
 : read-loop ( count port accum -- )
     pick over length - dup 0 > [
@@ -87,6 +89,7 @@ M: input-port stream-read1
     ] if ;
 
 M: input-port stream-read
+    check-closed
     >r 0 max >fixnum r>
     2dup read-step dup [
         pick over length > [
@@ -94,72 +97,75 @@ M: input-port stream-read
             [ push-all ] keep
             [ read-loop ] keep
             B{ } like
-        ] [
-            2nip
-        ] if
-    ] [
-        2nip
-    ] if ;
+        ] [ 2nip ] if
+    ] [ 2nip ] if ;
 
 M: input-port stream-read-partial ( max stream -- byte-array/f )
+    check-closed
     >r 0 max >fixnum r> read-step ;
 
-: can-write? ( len writer -- ? )
+: can-write? ( len buffer -- ? )
     [ buffer-fill + ] keep buffer-capacity <= ;
 
 : wait-to-write ( len port -- )
-    tuck can-write? [ drop ] [ stream-flush ] if ;
+    tuck buffer>> can-write? [ drop ] [ stream-flush ] if ;
 
 M: output-port stream-write1
-    1 over wait-to-write byte>buffer ;
+    check-closed
+    1 over wait-to-write
+    buffer>> byte>buffer ;
 
 M: output-port stream-write
-    over length over buffer-size > [
-        [ buffer-size <groups> ] keep
-        [ stream-write ] curry each
+    check-closed
+    over length over buffer>> buffer-size > [
+        [ buffer>> buffer-size <groups> ]
+        [ [ stream-write ] curry ] bi
+        each
     ] [
-        over length over wait-to-write >buffer
+        [ >r length r> wait-to-write ]
+        [ buffer>> >buffer ] 2bi
     ] if ;
 
 GENERIC: port-flush ( port -- )
 
 M: output-port stream-flush ( port -- )
-    dup port-flush pending-error ;
+    check-closed
+    [ port-flush ] [ pending-error ] bi ;
+
+GENERIC: close-port ( port -- )
+
+M: output-port close-port
+    [ port-flush ] [ call-next-method ] bi ;
 
-: close-port ( port type -- )
-    output-port eq? [ dup port-flush ] when
+M: port close-port
     dup cancel-io
-    dup port-handle close-handle
-    dup delegate [ buffer-free ] when*
-    f swap set-delegate ;
+    dup handle>> close-handle
+    [ [ buffer-free ] when* f ] change-buffer drop ;
 
 M: port dispose
-    dup port-type closed eq?
-    [ drop ]
-    [ dup port-type >r closed over set-port-type r> close-port ]
-    if ;
+    dup closed>> [ drop ] [ t >>closed close-port ] if ;
 
-TUPLE: server-port addr client client-addr encoding ;
+TUPLE: server-port < port addr client client-addr encoding ;
 
 : <server-port> ( handle addr encoding -- server )
-    rot server-port <port>
-    { set-server-port-addr set-server-port-encoding set-delegate }
-    server-port construct ;
+    rot server-port <port>
+        swap >>encoding
+        swap >>addr ;
 
-: check-server-port ( port -- )
-    port-type server-port assert= ;
+: check-server-port ( port -- port )
+    dup server-port? [ "Not a server port" throw ] unless ; inline
 
-TUPLE: datagram-port addr packet packet-addr ;
+TUPLE: datagram-port < port addr packet packet-addr ;
 
 : <datagram-port> ( handle addr -- datagram )
-    >r f datagram-port <port> r>
-    { set-delegate set-datagram-port-addr }
-    datagram-port construct ;
+    swap datagram-port <port>
+        swap >>addr ;
 
-: check-datagram-port ( port -- )
-    port-type datagram-port assert= ;
+: check-datagram-port ( port -- port )
+    check-closed
+    dup datagram-port? [ "Not a datagram port" throw ] unless ; inline
 
-: check-datagram-send ( packet addrspec port -- )
-    dup check-datagram-port
-    datagram-port-addr [ class ] bi@ assert=
-    class byte-array assert= ;
+: check-datagram-send ( packet addrspec port -- packet addrspec port )
+    check-datagram-port
+    2dup addr>> [ class ] bi@ assert=
+    pick class byte-array assert= ;
index dad1087022b30afbde42554c668119223953eb90..171f8122c532a2ee83a75536d020398384c89da5 100755 (executable)
@@ -14,7 +14,7 @@ TUPLE: directory-iterator path bfs queue ;
     ] curry each ;
 
 : <directory-iterator> ( path bfs? -- iterator )
-    <dlist> directory-iterator construct-boa
+    <dlist> directory-iterator boa
     dup path>> over push-directory ;
 
 : next-file ( iter -- file/f )
index 0b7e62690803041518dade0e586c489b1cffcc84..1d5ed16dc58596af8d4e412cc3b5838f806bbde7 100755 (executable)
@@ -12,17 +12,17 @@ SYMBOL: servers
 
 LOG: accepted-connection NOTICE
 
-: with-client ( client quot -- )
+: with-client ( client addrspec quot -- )
     [
-        over client-stream-addr accepted-connection
+        swap accepted-connection
         with-stream*
-    ] curry with-disposal ; inline
+    ] 2curry with-disposal ; inline
 
 \ with-client DEBUG add-error-logging
 
 : accept-loop ( server quot -- )
     [
-        >r accept r> [ with-client ] 2curry "Client" spawn drop
+        >r accept r> [ with-client ] 3curry "Client" spawn drop
     ] 2keep accept-loop ; inline
 
 : server-loop ( addrspec encoding quot -- )
index 5b0790ca2dd95b883101eac29765c8ac9331dc65..498430fdbc84108db12459fed0c91b9be0182f17 100755 (executable)
@@ -90,7 +90,7 @@ M: inet6 parse-sockaddr
         { [ dup AF_INET = ] [ T{ inet4 } ] }
         { [ dup AF_INET6 = ] [ T{ inet6 } ] }
         { [ dup AF_UNIX = ] [ T{ local } ] }
-        { [ t ] [ f ] }
+        [ f ]
     } cond nip ;
 
 M: f parse-sockaddr nip ;
index fa38ec90eee1a057811e0c72057506d95505ce82..ad78b4631cac2472f3b5dacb9d204575f5b98ecc 100755 (executable)
@@ -17,8 +17,6 @@ ARTICLE: "network-connection" "Connection-oriented networking"
 "Connection-oriented network servers are implemented by first opening a server socket, then waiting for connections:"
 { $subsection <server> }
 { $subsection accept }
-"The stream returned by " { $link accept } " holds the address specifier of the remote client:"
-{ $subsection client-stream-addr }
 "Server sockets are closed by calling " { $link dispose } "."
 $nl
 "Address specifiers have the following interpretation with connection-oriented networking words:"
@@ -118,10 +116,8 @@ HELP: <server>
 { $errors "Throws an error if the address is already in use, or if it if the system forbids access." } ;
 
 HELP: accept
-{ $values { "server" "a handle" } { "client" "a bidirectional stream" } }
-{ $description "Waits for a connection to a server socket created by " { $link <server> } ", and outputs a bidirectional stream when the connection has been established. The encoding of this stream is the one that was passed to the server constructor."
-$nl
-"The returned client stream responds to the " { $link client-stream-addr } " word with the address of the incoming connection." }
+{ $values { "server" "a handle" } { "client" "a bidirectional stream" } { "addrspec" "an address specifier" } }
+{ $description "Waits for a connection to a server socket created by " { $link <server> } ", and outputs a bidirectional stream when the connection has been established. The encoding of this stream is the one that was passed to the server constructor." }
 { $errors "Throws an error if the server socket is closed or otherwise is unavailable." } ;
 
 HELP: <datagram>
index 17799227b8eadba4f8a830a749902a04265cc25c..859dcb4cdc69a31f53f389112e32e553272df0b4 100755 (executable)
@@ -1,13 +1,13 @@
 ! Copyright (C) 2007, 2008 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: generic kernel io.backend namespaces continuations
-sequences arrays io.encodings io.nonblocking ;
+sequences arrays io.encodings io.nonblocking accessors ;
 IN: io.sockets
 
 TUPLE: local path ;
 
 : <local> ( path -- addrspec )
-    normalize-path local construct-boa ;
+    normalize-path local boa ;
 
 TUPLE: inet4 host port ;
 
@@ -21,20 +21,14 @@ TUPLE: inet host port ;
 
 C: <inet> inet
 
-TUPLE: client-stream addr ;
+HOOK: ((client)) io-backend ( addrspec -- client-in client-out )
 
-: <client-stream> ( addrspec delegate -- stream )
-    { set-client-stream-addr set-delegate }
-    client-stream construct ;
-
-HOOK: (client) io-backend ( addrspec -- client-in client-out )
-
-GENERIC: client* ( addrspec -- client-in client-out )
-M: array client* [ (client) 2array ] attempt-all first2 ;
-M: object client* (client) ;
+GENERIC: (client) ( addrspec -- client-in client-out )
+M: array (client) [ ((client)) 2array ] attempt-all first2 ;
+M: object (client) ((client)) ;
 
 : <client> ( addrspec encoding -- stream )
-    >r client* r> <encoder-duplex> ;
+    >r (client) r> <encoder-duplex> ;
 
 HOOK: (server) io-backend ( addrspec -- handle )
 
@@ -43,10 +37,9 @@ HOOK: (server) io-backend ( addrspec -- handle )
 
 HOOK: (accept) io-backend ( server -- addrspec handle )
 
-: accept ( server -- client )
-    [ (accept) dup <reader&writer> ] keep
-    server-port-encoding <encoder-duplex>
-    <client-stream> ;
+: accept ( server -- client addrspec )
+    [ (accept) dup <reader&writer> ] [ encoding>> ] bi
+    <encoder-duplex> swap ;
 
 HOOK: <datagram> io-backend ( addrspec -- datagram )
 
@@ -58,7 +51,8 @@ HOOK: resolve-host io-backend ( host serv passive? -- seq )
 
 HOOK: host-name io-backend ( -- string )
 
-M: inet client*
-    dup inet-host swap inet-port f resolve-host
-    dup empty? [ "Host name lookup failed" throw ] when
-    client* ;
+M: inet (client)
+    [ host>> ] [ port>> ] bi f resolve-host
+    [ empty? [ "Host name lookup failed" throw ] when ]
+    [ (client) ]
+    bi ;
index df7e1389cc539b5fb701163dae57b2e2900de8e5..64104083bedc78e50886ee5b240a165944a904eb 100755 (executable)
@@ -18,13 +18,13 @@ HELP: with-timeout
 { $description "Applies the quotation to the object. If the object's timeout expires before the quotation returns, " { $link timed-out } " is called on the object." } ;\r
 \r
 ARTICLE: "io.timeouts" "I/O timeout protocol"\r
-"Streams and processes support optional timeouts, which impose an upper bound on the length of time for which an operation on these objects can block. Timeouts are used in network servers to prevent malicious clients from holding onto connections forever, and to ensure that runaway processes get killed."\r
+"Streams, processes and monitors support optional timeouts, which impose an upper bound on the length of time for which an operation on these objects can block. Timeouts are used in network servers to prevent malicious clients from holding onto connections forever, and to ensure that runaway processes get killed."\r
 { $subsection timeout }\r
 { $subsection set-timeout }\r
 "The I/O timeout protocol can be implemented by any class wishing to support timeouts on blocking operations."\r
 { $subsection timed-out }\r
 "A combinator to be used in operations which can time out:"\r
 { $subsection with-timeout }\r
-{ $see-also "stream-protocol" "io.launcher" } ;\r
+{ $see-also "stream-protocol" "io.launcher" "io.monitors" } ;\r
 \r
 ABOUT: "io.timeouts"\r
old mode 100755 (executable)
new mode 100644 (file)
index 865490b..ba4e587
@@ -14,18 +14,13 @@ TUPLE: io-task port callbacks ;
 : io-task-fd port>> handle>> ;
 
 : <io-task> ( port continuation/f class -- task )
-    >r [ 1vector ] [ V{ } clone ] if* io-task construct-boa
-    r> construct-delegate ; inline
+    new
+        swap [ 1vector ] [ V{ } clone ] if* >>callbacks
+        swap >>port ; inline
 
-TUPLE: input-task ;
+TUPLE: input-task < io-task ;
 
-: <input-task> ( port continuation class -- task )
-    >r input-task <io-task> r> construct-delegate ; inline
-
-TUPLE: output-task ;
-
-: <output-task> ( port continuation class -- task )
-    >r output-task <io-task> r> construct-delegate ; inline
+TUPLE: output-task < io-task ;
 
 GENERIC: do-io-task ( task -- ? )
 GENERIC: io-task-container ( mx task -- hashtable )
@@ -37,9 +32,10 @@ M: input-task io-task-container drop reads>> ;
 
 M: output-task io-task-container drop writes>> ;
 
-: <mx> ( -- mx ) f H{ } clone H{ } clone mx construct-boa ;
-
-: construct-mx ( class -- obj ) <mx> swap construct-delegate ;
+: new-mx ( class -- obj )
+    new
+        H{ } clone >>reads
+        H{ } clone >>writes ; inline
 
 GENERIC: register-io-task ( task mx -- )
 GENERIC: unregister-io-task ( task mx -- )
@@ -123,16 +119,18 @@ M: unix cancel-io ( port -- )
 
 ! Readers
 : reader-eof ( reader -- )
-    dup buffer-empty? [ t >>eof? ] when drop ;
+    dup buffer>> buffer-empty? [ t >>eof ] when drop ;
 
 : (refill) ( port -- n )
-    [ handle>> ] [ buffer-end ] [ buffer-capacity ] tri read ;
+    [ handle>> ]
+    [ buffer>> buffer-end ]
+    [ buffer>> buffer-capacity ] tri read ;
 
 : refill ( port -- ? )
     #! Return f if there is a recoverable error
-    dup buffer-empty? [
+    dup buffer>> buffer-empty? [
         dup (refill)  dup 0 >= [
-            swap n>buffer t
+            swap buffer>> n>buffer t
         ] [
             drop defer-error
         ] if
@@ -140,10 +138,10 @@ M: unix cancel-io ( port -- )
         drop t
     ] if ;
 
-TUPLE: read-task ;
+TUPLE: read-task < input-task ;
 
 : <read-task> ( port continuation -- task )
-    read-task <input-task> ;
+    read-task <io-task> ;
 
 M: read-task do-io-task
     io-task-port dup refill
@@ -155,28 +153,33 @@ M: input-port (wait-to-read)
 
 ! Writers
 : write-step ( port -- ? )
-    dup [ handle>> ] [ buffer@ ] [ buffer-length ] tri write
-    dup 0 >= [ swap buffer-consume f ] [ drop defer-error ] if ;
+    dup
+    [ handle>> ]
+    [ buffer>> buffer@ ]
+    [ buffer>> buffer-length ] tri
+    write dup 0 >=
+    [ swap buffer>> buffer-consume f ]
+    [ drop defer-error ] if ;
 
-TUPLE: write-task ;
+TUPLE: write-task < output-task ;
 
 : <write-task> ( port continuation -- task )
-    write-task <output-task> ;
+    write-task <io-task> ;
 
 M: write-task do-io-task
-    io-task-port dup [ buffer-empty? ] [ port-error ] bi or
-    [ 0 swap buffer-reset t ] [ write-step ] if ;
+    io-task-port dup [ buffer>> buffer-empty? ] [ port-error ] bi or
+    [ 0 swap buffer>> buffer-reset t ] [ write-step ] if ;
 
 : add-write-io-task ( port continuation -- )
-    over port-handle mx get-global mx-writes at*
+    over handle>> mx get-global writes>> at*
     [ io-task-callbacks push drop ]
     [ drop <write-task> add-io-task ] if ;
 
 : (wait-to-write) ( port -- )
     [ add-write-io-task ] with-port-continuation drop ;
 
-M: port port-flush ( port -- )
-    dup buffer-empty? [ drop ] [ (wait-to-write) ] if ;
+M: output-port port-flush ( port -- )
+    dup buffer>> buffer-empty? [ drop ] [ (wait-to-write) ] if ;
 
 M: unix io-multiplex ( ms/f -- )
     mx get-global wait-for-events ;
@@ -187,13 +190,12 @@ M: unix (init-stdio) ( -- )
     2 <writer> ;
 
 ! mx io-task for embedding an fd-based mx inside another mx
-TUPLE: mx-port mx ;
+TUPLE: mx-port < port mx ;
 
 : <mx-port> ( mx -- port )
-    dup fd>> f mx-port <port>
-    { set-mx-port-mx set-delegate } mx-port construct ;
+    dup fd>> mx-port <port> swap >>mx ;
 
-TUPLE: mx-task ;
+TUPLE: mx-task < io-task ;
 
 : <mx-task> ( port -- task )
     f mx-task <io-task> ;
@@ -203,3 +205,6 @@ M: mx-task do-io-task
 
 : multiplexer-error ( n -- )
     0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ;
+
+: ?flag ( n mask symbol -- n )
+    pick rot bitand 0 > [ , ] [ drop ] if ;
index 12a64a41f90b7e2acc73101478a58abeaba30e5b..d74c355642c530b92ea4649a96c22145368297f3 100755 (executable)
@@ -1,8 +1,18 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 IN: io.unix.bsd
-USING: io.backend io.unix.backend io.unix.select
-namespaces system ;
+USING: namespaces system kernel accessors assocs continuations
+unix
+io.backend io.unix.backend io.unix.select io.unix.kqueue io.monitors ;
 
 M: bsd init-io ( -- )
-    <select-mx> mx set-global ;
+    <select-mx> mx set-global
+    <kqueue-mx> kqueue-mx set-global
+    kqueue-mx get-global <mx-port> <mx-task>
+    dup io-task-fd
+    [ mx get-global reads>> set-at ]
+    [ mx get-global writes>> set-at ] 2bi ;
+
+M: bsd (monitor) ( path recursive? mailbox -- )
+    swap [ "Recursive kqueue monitors not supported" throw ] when
+    <vnode-monitor> ;
index 1459549f9ec39881eb994eda3894d0312406f55b..db1e7086e05b08752d1132b0717b75d10948789a 100644 (file)
@@ -5,7 +5,7 @@ bit-arrays sequences assocs unix unix.linux.epoll math
 namespaces structs ;
 IN: io.unix.epoll
 
-TUPLE: epoll-mx events ;
+TUPLE: epoll-mx < mx events ;
 
 : max-events ( -- n )
     #! We read up to 256 events at a time. This is an arbitrary
@@ -13,7 +13,7 @@ TUPLE: epoll-mx events ;
     256 ; inline
 
 : <epoll-mx> ( -- mx )
-    epoll-mx construct-mx
+    epoll-mx new-mx
     max-events epoll_create dup io-error over set-mx-fd
     max-events "epoll-event" <c-array> over set-epoll-mx-events ;
 
@@ -33,12 +33,10 @@ M: output-task io-task-events drop EPOLLOUT ;
     epoll_ctl io-error ;
 
 M: epoll-mx register-io-task ( task mx -- )
-    2dup EPOLL_CTL_ADD do-epoll-ctl 
-    delegate register-io-task ;
+    [ EPOLL_CTL_ADD do-epoll-ctl ] [ call-next-method ] 2bi ;
 
 M: epoll-mx unregister-io-task ( task mx -- )
-    2dup delegate unregister-io-task
-    EPOLL_CTL_DEL do-epoll-ctl ;
+    [ call-next-method ] [ EPOLL_CTL_DEL do-epoll-ctl ] 2bi ;
 
 : wait-event ( mx timeout -- n )
     >r { mx-fd epoll-mx-events } get-slots max-events
index 39c18b460121976d702ab4f31591edd15d445a29..a09ebb46c9f09967c89fda16cf50d1616103ff3a 100755 (executable)
@@ -72,20 +72,20 @@ M: unix delete-directory ( path -- )
 M: unix copy-file ( from to -- )
     [ normalize-path ] bi@
     [ (copy-file) ]
-    [ swap file-info file-info-permissions chmod io-error ]
+    [ swap file-info permissions>> chmod io-error ]
     2bi ;
 
 : stat>type ( stat -- type )
-    stat-st_mode {
-        { [ dup S_ISREG  ] [ +regular-file+     ] }
-        { [ dup S_ISDIR  ] [ +directory+        ] }
-        { [ dup S_ISCHR  ] [ +character-device+ ] }
-        { [ dup S_ISBLK  ] [ +block-device+     ] }
-        { [ dup S_ISFIFO ] [ +fifo+             ] }
-        { [ dup S_ISLNK  ] [ +symbolic-link+    ] }
-        { [ dup S_ISSOCK ] [ +socket+           ] }
-        { [ t            ] [ +unknown+          ] }
-    } cond nip ;
+    stat-st_mode S_IFMT bitand {
+        { S_IFREG [ +regular-file+ ] }
+        { S_IFDIR [ +directory+ ] }
+        { S_IFCHR [ +character-device+ ] }
+        { S_IFBLK [ +block-device+ ] }
+        { S_IFIFO [ +fifo+ ] }
+        { S_IFLNK [ +symbolic-link+ ] }
+        { S_IFSOCK [ +socket+ ] }
+        [ drop +unknown+ ]
+    } case ;
 
 : stat>file-info ( stat -- info )
     {
@@ -94,7 +94,7 @@ M: unix copy-file ( from to -- )
         [ stat-st_mode ]
         [ stat-st_mtim timespec-sec seconds unix-1970 time+ ]
     } cleave
-    \ file-info construct-boa ;
+    \ file-info boa ;
 
 M: unix file-info ( path -- info )
     normalize-path stat* stat>file-info ;
old mode 100755 (executable)
new mode 100644 (file)
index 97b186e..8e8fb0e
@@ -1,12 +1,14 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types kernel io.nonblocking io.unix.backend
-sequences assocs unix unix.time unix.kqueue unix.process math namespaces
-combinators threads vectors io.launcher
-io.unix.launcher ;
+USING: alien.c-types kernel math math.bitfields namespaces
+locals accessors combinators threads vectors hashtables
+sequences assocs continuations sets
+unix unix.time unix.kqueue unix.process
+io.nonblocking io.unix.backend io.launcher io.unix.launcher
+io.monitors ;
 IN: io.unix.kqueue
 
-TUPLE: kqueue-mx events ;
+TUPLE: kqueue-mx < mx events monitors ;
 
 : max-events ( -- n )
     #! We read up to 256 events at a time. This is an arbitrary
@@ -14,9 +16,10 @@ TUPLE: kqueue-mx events ;
     256 ; inline
 
 : <kqueue-mx> ( -- mx )
-    kqueue-mx construct-mx
-    kqueue dup io-error over set-mx-fd
-    max-events "kevent" <c-array> over set-kqueue-mx-events ;
+    kqueue-mx new-mx
+        H{ } clone >>monitors
+        kqueue dup io-error >>fd
+        max-events "kevent" <c-array> >>events ;
 
 GENERIC: io-task-filter ( task -- n )
 
@@ -24,52 +27,78 @@ 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 )
     "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 ;
 
 : register-kevent ( kevent mx -- )
-    mx-fd swap 1 f 0 f kevent
+    fd>> swap 1 f 0 f kevent
     0 < [ err_no ESRCH = [ (io-error) ] unless ] when ;
 
 M: kqueue-mx register-io-task ( task mx -- )
-    over EV_ADD make-kevent over register-kevent
-    delegate register-io-task ;
+    [ >r EV_ADD make-kevent r> register-kevent ]
+    [ call-next-method ]
+    2bi ;
 
 M: kqueue-mx unregister-io-task ( task mx -- )
-    2dup delegate unregister-io-task
-    swap EV_DELETE make-kevent swap register-kevent ;
+    [ call-next-method ]
+    [ >r EV_DELETE make-kevent r> register-kevent ]
+    2bi ;
 
 : wait-kevent ( mx timespec -- n )
-    >r dup mx-fd f 0 roll kqueue-mx-events max-events r> kevent
+    >r [ fd>> f 0 ] keep events>> max-events r> kevent
     dup multiplexer-error ;
 
-: kevent-read-task ( mx fd -- )
-    over mx-reads at handle-io-task ;
+:: kevent-read-task ( mx fd kevent -- )
+    mx fd mx reads>> at handle-io-task ;
 
-: kevent-write-task ( mx fd -- )
-    over mx-reads at handle-io-task ;
+:: kevent-write-task ( mx fd kevent -- )
+    mx fd mx writes>> at handle-io-task ;
 
-: kevent-proc-task ( pid -- )
-    dup wait-for-pid swap find-process
+:: kevent-proc-task ( mx pid kevent -- )
+    pid wait-for-pid
+    pid find-process
     dup [ swap notify-exit ] [ 2drop ] if ;
 
+: parse-action ( mask -- changed )
+    [
+        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 ;
+
+:: kevent-vnode-task ( mx kevent fd -- )
+    ""
+    kevent kevent-fflags parse-action
+    fd mx monitors>> at queue-change ;
+
 : handle-kevent ( mx kevent -- )
-    dup kevent-ident swap kevent-filter {
+    [ ] [ 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 drop ] }
+        { [ dup EVFILT_PROC = ] [ drop kevent-proc-task ] }
+        { [ dup EVFILT_VNODE = ] [ drop kevent-vnode-task ] }
     } cond ;
 
 : handle-kevents ( mx n -- )
-    [ over kqueue-mx-events kevent-nth handle-kevent ] with each ;
+    [ over events>> kevent-nth handle-kevent ] with each ;
 
 M: kqueue-mx wait-for-events ( ms mx -- )
     swap dup [ make-timespec ] when
     dupd wait-kevent handle-kevents ;
 
+! Procs
 : make-proc-kevent ( pid -- kevent )
     "kevent" <c-object>
     tuck set-kevent-ident
@@ -77,5 +106,44 @@ M: kqueue-mx wait-for-events ( ms mx -- )
     EVFILT_PROC over set-kevent-filter
     NOTE_EXIT over set-kevent-fflags ;
 
-: add-pid-task ( pid mx -- )
+: 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 82852f63110aaa5df1f5f5d76fcf4fd4c69b369a..2c1e6261c045301224a8aa24ab86d1f5dfcfde74 100755 (executable)
@@ -55,7 +55,7 @@ USE: unix
         { [ pick string? ] [ redirect-file ] }
         { [ pick +closed+ eq? ] [ redirect-closed ] }
         { [ pick +inherit+ eq? ] [ redirect-closed ] }
-        { [ t ] [ redirect-stream ] }
+        [ redirect-stream ]
     } cond ;
 
 : ?closed dup +closed+ eq? [ drop "/dev/null" ] when ;
index 30c61f6d21327d15af1134a0dc2ce41618341df8..e75f4c5f6b9b3a08ba2285a1a20902b367daadeb 100755 (executable)
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel io.backend io.monitors io.monitors.private
-io.files io.buffers io.nonblocking io.timeouts io.unix.backend
-io.unix.select io.unix.launcher unix.linux.inotify assocs
-namespaces threads continuations init math alien.c-types alien
-vocabs.loader accessors system ;
+USING: kernel io.backend io.monitors io.unix.backend
+io.unix.select io.unix.linux.monitors system namespaces ;
 IN: io.unix.linux
 
-TUPLE: linux-monitor ;
-
-: <linux-monitor> ( wd -- monitor )
-    linux-monitor construct-simple-monitor ;
-
-TUPLE: inotify watches ;
-
-: watches ( -- assoc ) inotify get-global watches>> ;
-
-: wd>monitor ( wd -- monitor ) watches at ;
-
-: <inotify> ( -- port/f )
-    H{ } clone
-    inotify_init dup 0 < [ 2drop f ] [
-        inotify <buffered-port>
-        { set-inotify-watches set-delegate } inotify construct
-    ] if ;
-
-: inotify-fd inotify get-global handle>> ;
-
-: (add-watch) ( path mask -- wd )
-    inotify-fd -rot inotify_add_watch dup io-error ;
-
-: check-existing ( wd -- )
-    watches key? [
-        "Cannot open multiple monitors for the same file" throw
-    ] when ;
-
-: add-watch ( path mask -- monitor )
-    (add-watch) dup check-existing
-    [ <linux-monitor> dup ] keep watches set-at ;
-
-: remove-watch ( monitor -- )
-    dup simple-monitor-handle watches delete-at
-    simple-monitor-handle inotify-fd swap inotify_rm_watch io-error ;
-
-: check-inotify
-    inotify get [
-        "inotify is not supported by this Linux release" throw
-    ] unless ;
-
-M: linux <monitor> ( path recursive? -- monitor )
-    check-inotify
-    drop IN_CHANGE_EVENTS add-watch ;
-
-M: linux-monitor dispose ( monitor -- )
-    dup delegate dispose remove-watch ;
-
-: ?flag ( n mask symbol -- n )
-    pick rot bitand 0 > [ , ] [ drop ] if ;
-
-: parse-action ( mask -- changed )
-    [
-        IN_CREATE +add-file+ ?flag
-        IN_DELETE +remove-file+ ?flag
-        IN_DELETE_SELF +remove-file+ ?flag
-        IN_MODIFY +modify-file+ ?flag
-        IN_ATTRIB +modify-file+ ?flag
-        IN_MOVED_FROM +rename-file+ ?flag
-        IN_MOVED_TO +rename-file+ ?flag
-        IN_MOVE_SELF +rename-file+ ?flag
-        drop
-    ] { } make ;
-
-: parse-file-notify ( buffer -- changed path )
-    { inotify-event-name inotify-event-mask } get-slots
-    parse-action swap alien>char-string ;
-
-: events-exhausted? ( i buffer -- ? )
-    fill>> >= ;
-
-: inotify-event@ ( i buffer -- alien )
-    ptr>> <displaced-alien> ;
-
-: next-event ( i buffer -- i buffer )
-    2dup inotify-event@
-    inotify-event-len "inotify-event" heap-size +
-    swap >r + r> ;
-
-: parse-file-notifications ( i buffer -- )
-    2dup events-exhausted? [ 2drop ] [
-        2dup inotify-event@ dup inotify-event-wd wd>monitor [
-            monitor-queue [
-                parse-file-notify changed-file
-            ] bind
-        ] keep notify-callback
-        next-event parse-file-notifications
-    ] if ;
-
-: read-notifications ( port -- )
-    dup refill drop
-    0 over parse-file-notifications
-    0 swap buffer-reset ;
-
-TUPLE: inotify-task ;
-
-: <inotify-task> ( port -- task )
-    f inotify-task <input-task> ;
-
-: init-inotify ( mx -- )
-    <inotify> dup [
-        dup inotify set-global
-        <inotify-task> swap register-io-task
-    ] [
-        2drop
-    ] if ;
-
-M: inotify-task do-io-task ( task -- )
-    io-task-port read-notifications f ;
-
 M: linux init-io ( -- )
-    <select-mx>
-    [ mx set-global ]
-    [ init-inotify ] bi ;
+    <select-mx> mx set-global ;
 
 linux set-io-backend
diff --git a/extra/io/unix/linux/monitors/monitors.factor b/extra/io/unix/linux/monitors/monitors.factor
new file mode 100644 (file)
index 0000000..58c1f01
--- /dev/null
@@ -0,0 +1,126 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel io.backend io.monitors io.monitors.recursive
+io.files io.buffers io.monitors io.nonblocking io.timeouts
+io.unix.backend io.unix.select unix.linux.inotify assocs
+namespaces threads continuations init math math.bitfields sets
+alien.c-types alien vocabs.loader accessors system hashtables ;
+IN: io.unix.linux.monitors
+
+TUPLE: linux-monitor < monitor wd ;
+
+: <linux-monitor> ( wd path mailbox -- monitor )
+    linux-monitor new-monitor
+        swap >>wd ;
+
+SYMBOL: watches
+
+SYMBOL: inotify
+
+: wd>monitor ( wd -- monitor ) watches get at ;
+
+: <inotify> ( -- port/f )
+    inotify_init dup 0 < [ drop f ] [ <reader> ] if ;
+
+: inotify-fd inotify get handle>> ;
+
+: check-existing ( wd -- )
+    watches get key? [
+        "Cannot open multiple monitors for the same file" throw
+    ] when ;
+
+: (add-watch) ( path mask -- wd )
+    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>
+    <linux-monitor> [ ] [ ] [ wd>> ] tri watches get set-at ;
+
+: check-inotify
+    inotify get [
+        "Calling <monitor> outside with-monitors" throw
+    ] unless ;
+
+M: linux (monitor) ( path recursive? mailbox -- monitor )
+    swap [
+        <recursive-monitor>
+    ] [
+        check-inotify
+        IN_CHANGE_EVENTS swap add-watch
+    ] if ;
+
+M: linux-monitor dispose ( monitor -- )
+    [ wd>> watches get delete-at ]
+    [ wd>> inotify-fd swap inotify_rm_watch io-error ] bi ;
+
+: ignore-flags? ( mask -- ? )
+    {
+        IN_DELETE_SELF
+        IN_MOVE_SELF
+        IN_UNMOUNT
+        IN_Q_OVERFLOW
+        IN_IGNORED
+    } flags bitand 0 > ;
+
+: parse-action ( mask -- changed )
+    [
+        IN_CREATE +add-file+ ?flag
+        IN_DELETE +remove-file+ ?flag
+        IN_MODIFY +modify-file+ ?flag
+        IN_ATTRIB +modify-file+ ?flag
+        IN_MOVED_FROM +rename-file-old+ ?flag
+        IN_MOVED_TO +rename-file-new+ ?flag
+        drop
+    ] { } make prune ;
+
+: parse-file-notify ( buffer -- path changed )
+    dup inotify-event-mask ignore-flags? [
+        drop f f
+    ] [
+        [ inotify-event-name alien>char-string ]
+        [ inotify-event-mask parse-action ] bi
+    ] if ;
+
+: events-exhausted? ( i buffer -- ? )
+    fill>> >= ;
+
+: inotify-event@ ( i buffer -- alien )
+    ptr>> <displaced-alien> ;
+
+: next-event ( i buffer -- i buffer )
+    2dup inotify-event@
+    inotify-event-len "inotify-event" heap-size +
+    swap >r + r> ;
+
+: 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
+        next-event parse-file-notifications
+    ] if ;
+
+: inotify-read-loop ( port -- )
+    dup wait-to-read1
+    0 over buffer>> parse-file-notifications
+    0 over buffer>> buffer-reset
+    inotify-read-loop ;
+
+: inotify-read-thread ( port -- )
+    [ inotify-read-loop ] curry ignore-errors ;
+
+M: linux init-monitors
+    H{ } clone watches set
+    <inotify> [
+        [ inotify set ]
+        [
+            [ inotify-read-thread ] curry
+            "Linux monitor thread" spawn drop
+        ] bi
+    ] [
+        "Linux kernel version is too old" throw
+    ] if* ;
+
+M: linux dispose-monitors
+    inotify get dispose ;
index c1c73ea0185eef0223c016820b9e789a01c9176f..0a0aec6ab66b2f8290ae63971e7755cb2c4777f4 100644 (file)
@@ -1,23 +1,23 @@
-USING: io.unix.bsd io.backend io.monitors io.monitors.private
-continuations kernel core-foundation.fsevents sequences
-namespaces arrays system ;
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.unix.bsd io.backend io.monitors core-foundation.fsevents
+continuations kernel sequences namespaces arrays system locals
+accessors ;
 IN: io.unix.macosx
 
-macosx set-io-backend
-
-TUPLE: macosx-monitor ;
+TUPLE: macosx-monitor < monitor handle ;
 
 : enqueue-notifications ( triples monitor -- )
-    tuck monitor-queue
-    [ [ first { +modify-file+ } swap changed-file ] each ] bind
-    notify-callback ;
+    [
+        >r first { +modify-file+ } r> queue-change
+    ] curry each ;
 
-M: macosx <monitor>
-    drop
-    f macosx-monitor construct-simple-monitor
+M:: macosx (monitor) ( path recursive? mailbox -- monitor )
+    path mailbox macosx-monitor new-monitor
     dup [ enqueue-notifications ] curry
-    rot 1array 0 0 <event-stream>
-    over set-simple-monitor-handle ;
+    path 1array 0 0 <event-stream> >>handle ;
 
 M: macosx-monitor dispose
-    dup simple-monitor-handle dispose delegate dispose ;
+    handle>> dispose ;
+
+macosx set-io-backend
index f042366b135e876d29fd38e46eb171a34adcaf25..2815a49cd39770394f56edc25850f1b6e1b61757 100755 (executable)
@@ -13,7 +13,7 @@ IN: io.unix.mmap
 M: unix <mapped-file> ( path length -- obj )
     swap >r
     dup PROT_READ PROT_WRITE bitor MAP_FILE MAP_SHARED bitor
-    r> mmap-open f mapped-file construct-boa ;
+    r> mmap-open f mapped-file boa ;
 
 M: unix close-mapped-file ( mmap -- )
     [ mapped-file-address ] keep
index aceee0f31114e48e21bbbac4d9a8a0ffe9d12bf2..9413556d4f2480b5fe48853865e5ea9a8b27353f 100755 (executable)
@@ -5,7 +5,7 @@ bit-arrays sequences assocs unix math namespaces structs
 accessors ;
 IN: io.unix.select
 
-TUPLE: select-mx read-fdset write-fdset ;
+TUPLE: select-mx < mx read-fdset write-fdset ;
 
 ! Factor's bit-arrays are an array of bytes, OS X expects
 ! FD_SET to be an array of cells, so we have to account for
@@ -14,9 +14,9 @@ TUPLE: select-mx read-fdset write-fdset ;
     little-endian? [ BIN: 11000 bitxor ] unless ; inline
 
 : <select-mx> ( -- mx )
-    select-mx construct-mx
-    FD_SETSIZE 8 * <bit-array> >>read-fdset
-    FD_SETSIZE 8 * <bit-array> >>write-fdset ;
+    select-mx new-mx
+        FD_SETSIZE 8 * <bit-array> >>read-fdset
+        FD_SETSIZE 8 * <bit-array> >>write-fdset ;
 
 : clear-nth ( n seq -- ? )
     [ nth ] [ f -rot set-nth ] 2bi ;
@@ -29,7 +29,6 @@ TUPLE: select-mx read-fdset write-fdset ;
     [ handle-fd ] 2curry assoc-each ;
 
 : init-fdset ( tasks fdset -- )
-    ! dup clear-bits
     [ >r drop t swap munge r> set-nth ] curry assoc-each ;
 
 : read-fdset/tasks
@@ -45,9 +44,9 @@ TUPLE: select-mx read-fdset write-fdset ;
     [ reads>> max-fd ] [ writes>> max-fd ] bi max 1+ ;
 
 : init-fdsets ( mx -- nfds read write except )
-    [ num-fds ] keep
-    [ read-fdset/tasks tuck init-fdset ] keep
-    write-fdset/tasks tuck init-fdset
+    [ num-fds ]
+    [ read-fdset/tasks tuck init-fdset ]
+    [ write-fdset/tasks tuck init-fdset ] tri
     f ;
 
 M: select-mx wait-for-events ( ms mx -- )
index a54205a8789469a8c1d9ff459ea1ec8b0385c05d..cecc70fb0825a7d65b90f6214febcfff6958d609 100755 (executable)
@@ -7,7 +7,7 @@ USING: alien alien.c-types generic io kernel math namespaces
 io.nonblocking parser threads unix sequences
 byte-arrays io.sockets io.binary io.unix.backend
 io.streams.duplex io.sockets.impl math.parser continuations libc
-combinators io.backend io.files io.files.private system ;
+combinators io.backend io.files io.files.private system accessors ;
 IN: io.unix.sockets
 
 : pending-init-error ( port -- )
@@ -30,10 +30,10 @@ M: unix addrinfo-error ( n -- )
 : init-client-socket ( fd -- )
     SOL_SOCKET SO_OOBINLINE sockopt ;
 
-TUPLE: connect-task ;
+TUPLE: connect-task < output-task ;
 
 : <connect-task> ( port continuation -- task )
-    connect-task <output-task> ;
+    connect-task <io-task> ;
 
 M: connect-task do-io-task
     io-task-port dup port-handle f 0 write
@@ -42,7 +42,7 @@ M: connect-task do-io-task
 : wait-to-connect ( port -- )
     [ <connect-task> add-io-task ] with-port-continuation drop ;
 
-M: unix (client) ( addrspec -- client-in client-out )
+M: unix ((client)) ( addrspec -- client-in client-out )
     dup make-sockaddr/size >r >r
     protocol-family SOCK_STREAM socket-fd
     dup r> r> connect
@@ -61,10 +61,10 @@ USE: unix
 : init-server-socket ( fd -- )
     SOL_SOCKET SO_REUSEADDR sockopt ;
 
-TUPLE: accept-task ;
+TUPLE: accept-task < input-task ;
 
 : <accept-task> ( port continuation  -- task )
-    accept-task <input-task> ;
+    accept-task <io-task> ;
 
 : accept-sockaddr ( port -- fd sockaddr )
     dup port-handle swap server-port-addr sockaddr-type
@@ -97,11 +97,10 @@ M: unix (server) ( addrspec -- handle )
 
 M: unix (accept) ( server -- addrspec handle )
     #! Wait for a client connection.
-    dup check-server-port
-    dup wait-to-accept
-    dup pending-error
-    dup server-port-client-addr
-    swap server-port-client ;
+    check-server-port
+    [ wait-to-accept ]
+    [ pending-error ]
+    [ [ client-addr>> ] [ client>> ] bi ] tri ;
 
 ! Datagram sockets - UDP and Unix domain
 M: unix <datagram>
@@ -128,10 +127,10 @@ packet-size <byte-array> receive-buffer set-global
         rot head
     ] if ;
 
-TUPLE: receive-task ;
+TUPLE: receive-task < input-task ;
 
 : <receive-task> ( stream continuation  -- task )
-    receive-task <input-task> ;
+    receive-task <io-task> ;
 
 M: receive-task do-io-task
     io-task-port
@@ -148,19 +147,18 @@ M: receive-task do-io-task
     [ <receive-task> add-io-task ] with-port-continuation drop ;
 
 M: unix receive ( datagram -- packet addrspec )
-    dup check-datagram-port
-    dup wait-receive
-    dup pending-error
-    dup datagram-port-packet
-    swap datagram-port-packet-addr ;
+    check-datagram-port
+    [ wait-receive ]
+    [ pending-error ]
+    [ [ packet>> ] [ packet-addr>> ] bi ] tri ;
 
 : do-send ( socket data sockaddr len -- n )
     >r >r dup length 0 r> r> sendto ;
 
-TUPLE: send-task packet sockaddr len ;
+TUPLE: send-task < output-task packet sockaddr len ;
 
 : <send-task> ( packet sockaddr len stream continuation -- task )
-    send-task <output-task> [
+    send-task <io-task> [
         {
             set-send-task-packet
             set-send-task-sockaddr
@@ -180,7 +178,7 @@ M: send-task do-io-task
     2drop 2drop ;
 
 M: unix send ( packet addrspec datagram -- )
-    3dup check-datagram-send
+    check-datagram-send
     [ >r make-sockaddr/size r> wait-send ] keep
     pending-error ;
 
index c8ed4fc41c41afc8620ee00fe80e6554989dea1f..ff315bc5299e7433f864e2f7dc237e0293491358 100755 (executable)
@@ -11,7 +11,7 @@ IN: io.unix.tests
 
     socket-server <local>
     ascii <server> [
-        accept [
+        accept drop [
             "Hello world" print flush
             readln "XYZ" = "FOO" "BAR" ? print flush
         ] with-stream
index 8bfbff2ba05338281dda6f3efb973a81d732d755..8a15a57f8370c5ef3644ecdb50bdb1ec8b182014 100755 (executable)
@@ -48,7 +48,7 @@ SYMBOLS: +read-only+ +hidden+ +system+
         [ WIN32_FIND_DATA-ftLastWriteTime FILETIME>timestamp ]
         ! [ WIN32_FIND_DATA-ftLastAccessTime FILETIME>timestamp ]
     } cleave
-    \ file-info construct-boa ;
+    \ file-info boa ;
 
 : find-first-file-stat ( path -- WIN32_FIND_DATA )
     "WIN32_FIND_DATA" <c-object> [
@@ -69,7 +69,7 @@ SYMBOLS: +read-only+ +hidden+ +system+
         [ BY_HANDLE_FILE_INFORMATION-ftLastWriteTime FILETIME>timestamp ]
         ! [ BY_HANDLE_FILE_INFORMATION-ftLastAccessTime FILETIME>timestamp ]
     } cleave
-    \ file-info construct-boa ;
+    \ file-info boa ;
 
 : get-file-information ( handle -- BY_HANDLE_FILE_INFORMATION )
     [
index 04e149d26124c8a2c58facaefb42af85c10aaca1..670ea18f5eb3b61800f7139d747eaa9fadbff883 100755 (executable)
@@ -23,7 +23,7 @@ TUPLE: CreateProcess-args
        stdout-pipe stdin-pipe ;
 
 : default-CreateProcess-args ( -- obj )
-    CreateProcess-args construct-empty
+    CreateProcess-args new
     "STARTUPINFO" <c-object>
     "STARTUPINFO" heap-size over set-STARTUPINFO-cb >>lpStartupInfo
     "PROCESS_INFORMATION" <c-object> >>lpProcessInformation
index 8d3690bbb586e675876874bf1ea0a22cc451f539..0164ed16976aad4565923e301c7df22245cd426f 100755 (executable)
@@ -78,7 +78,7 @@ M: windows <mapped-file> ( path length -- mmap )
         PAGE_READWRITE SEC_COMMIT bitor
         FILE_MAP_ALL_ACCESS mmap-open
         -rot 2array
-        f \ mapped-file construct-boa
+        f \ mapped-file boa
     ] with-destructors ;
 
 M: windows close-mapped-file ( mapped-file -- )
index 822973b85bf14cf5a7d088dbed88f2f0f6d66b33..fe7f1ecc61b6a28e7fafc5746bb54d7ca138e601 100755 (executable)
@@ -3,7 +3,7 @@ continuations destructors io io.backend io.nonblocking
 io.windows libc kernel math namespaces sequences
 threads classes.tuple.lib windows windows.errors
 windows.kernel32 strings splitting io.files qualified ascii
-combinators.lib system ;
+combinators.lib system accessors ;
 QUALIFIED: windows.winsock
 IN: io.windows.nt.backend
 
@@ -38,15 +38,15 @@ M: winnt add-completion ( handle -- )
     zero? [
         GetLastError {
             { [ dup expected-io-error? ] [ 2drop t ] }
-            { [ dup eof? ] [ drop t swap set-port-eof? f ] }
-            { [ t ] [ (win32-error-string) throw ] }
+            { [ dup eof? ] [ drop t >>eof drop f ] }
+            [ (win32-error-string) throw ]
         } cond
     ] [
         drop t
     ] if ;
 
 : get-overlapped-result ( overlapped port -- bytes-transferred )
-    dup port-handle win32-file-handle rot 0 <uint>
+    dup handle>> handle>> rot 0 <uint>
     [ 0 GetOverlappedResult overlapped-error? drop ] keep *uint ;
 
 : save-callback ( overlapped port -- )
@@ -75,11 +75,11 @@ M: winnt add-completion ( handle -- )
         ] [
             dup eof? [
                 drop lookup-callback
-                dup io-callback-port t swap set-port-eof?
+                dup port>> t >>eof drop
             ] [
                 (win32-error-string) swap lookup-callback
-                [ io-callback-port set-port-error ] keep
-            ] if io-callback-thread resume f
+                [ port>> set-port-error ] keep
+            ] if thread>> resume f
         ] if
     ] [
         lookup-callback
@@ -90,7 +90,7 @@ M: winnt add-completion ( handle -- )
     handle-overlapped [ 0 drain-overlapped ] unless ;
 
 M: winnt cancel-io
-    port-handle win32-file-handle CancelIo drop ;
+    handle>> handle>> CancelIo drop ;
 
 M: winnt io-multiplex ( ms -- )
     drain-overlapped ;
index 3232ab6ff355de1fac8e79e544bec5502d62ce33..eec473e8403f32c7618e7bc5106446feb6433037 100755 (executable)
@@ -3,7 +3,7 @@ io.timeouts io.nonblocking io.windows io.windows.nt.backend
 kernel libc math threads windows windows.kernel32 system
 alien.c-types alien.arrays sequences combinators combinators.lib
 sequences.lib ascii splitting alien strings assocs namespaces
-io.files.private ;
+io.files.private accessors ;
 IN: io.windows.nt.files
 
 M: winnt cwd
@@ -25,7 +25,7 @@ M: winnt root-directory? ( path -- ? )
           { [ dup length 2 = ] [ dup second CHAR: : = ] } && nip ] [
             t
         ] }
-        { [ t ] [ f ] }
+        [ f ]
     } cond nip ;
 
 ERROR: not-absolute-path ;
@@ -64,7 +64,7 @@ M: winnt FileArgs-overlapped ( port -- overlapped )
     dup pending-error
     tuck get-overlapped-result
     dup pick update-file-ptr
-    swap buffer-consume ;
+    swap buffer>> buffer-consume ;
 
 : (flush-output) ( port -- )
     dup make-FileArgs
@@ -73,7 +73,7 @@ M: winnt FileArgs-overlapped ( port -- overlapped )
         >r FileArgs-lpOverlapped r>
         [ save-callback ] 2keep
         [ finish-flush ] keep
-        dup buffer-empty? [ drop ] [ (flush-output) ] if
+        dup buffer>> buffer-empty? [ drop ] [ (flush-output) ] if
     ] [
         2drop
     ] if ;
@@ -82,14 +82,14 @@ M: winnt FileArgs-overlapped ( port -- overlapped )
     [ [ (flush-output) ] with-timeout ] with-destructors ;
 
 M: port port-flush
-    dup buffer-empty? [ dup flush-output ] unless drop ;
+    dup buffer>> buffer-empty? [ dup flush-output ] unless drop ;
 
 : finish-read ( overlapped port -- )
     dup pending-error
     tuck get-overlapped-result dup zero? [
-        drop t swap set-port-eof?
+        drop t >>eof drop
     ] [
-        dup pick n>buffer
+        dup pick buffer>> n>buffer
         swap update-file-ptr
     ] if ;
 
index 97de248d241705c82535965bd7f124b22f5a320d..f57902608f5acad544f01dace0370b495ce5265c 100755 (executable)
@@ -55,7 +55,7 @@ IN: io.windows.nt.launcher
         { [ pick +inherit+ eq? ] [ redirect-inherit ] }
         { [ pick +closed+ eq? ] [ redirect-closed ] }
         { [ pick string? ] [ redirect-file ] }
-        { [ t ] [ redirect-stream ] }
+        [ redirect-stream ]
     } cond ;
 
 : default-stdout ( args -- handle )
diff --git a/extra/io/windows/nt/monitors/monitors-tests.factor b/extra/io/windows/nt/monitors/monitors-tests.factor
new file mode 100755 (executable)
index 0000000..ef36bae
--- /dev/null
@@ -0,0 +1,4 @@
+IN: io.windows.nt.monitors.tests\r
+USING: io.windows.nt.monitors tools.test ;\r
+\r
+\ fill-queue-thread must-infer\r
index 164b529b617ea16205946657af3e196257d07940..4c2277acb98ecd4690df487768531782e4bc240d 100755 (executable)
@@ -1,14 +1,16 @@
 ! Copyright (C) 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types destructors io.windows
-io.windows.nt.backend kernel math windows windows.kernel32
-windows.types libc assocs alien namespaces continuations
-io.monitors io.monitors.private io.nonblocking io.buffers
-io.files io.timeouts io sequences hashtables sorting arrays
-combinators math.bitfields strings system ;
+USING: alien alien.c-types libc destructors locals
+kernel math assocs namespaces continuations sequences hashtables
+sorting arrays combinators math.bitfields strings system
+accessors threads
+io.backend io.windows io.windows.nt.backend io.monitors
+io.nonblocking io.buffers io.files io.timeouts io
+windows windows.kernel32 windows.types ;
 IN: io.windows.nt.monitors
 
 : open-directory ( path -- handle )
+    normalize-path
     FILE_LIST_DIRECTORY
     share-mode
     f
@@ -21,67 +23,88 @@ IN: io.windows.nt.monitors
     dup add-completion
     f <win32-file> ;
 
-TUPLE: win32-monitor path recursive? ;
+TUPLE: win32-monitor-port < input-port recursive ;
 
-: <win32-monitor> ( path recursive? port -- monitor )
-    (monitor) {
-        set-win32-monitor-path
-        set-win32-monitor-recursive?
-        set-delegate
-    } win32-monitor construct ;
+TUPLE: win32-monitor < monitor port ;
 
-M: winnt <monitor> ( path recursive? -- monitor )
-    [
-        over open-directory win32-monitor <buffered-port>
-        <win32-monitor>
-    ] with-destructors ;
-
-: begin-reading-changes ( monitor -- overlapped )
-    dup port-handle win32-file-handle
-    over buffer-ptr
-    pick buffer-size
-    roll win32-monitor-recursive? 1 0 ?
+: begin-reading-changes ( port -- overlapped )
+    {
+        [ handle>> handle>> ]
+        [ buffer>> ptr>> ]
+        [ buffer>> size>> ]
+        [ recursive>> 1 0 ? ]
+    } cleave
     FILE_NOTIFY_CHANGE_ALL
     0 <uint>
     (make-overlapped)
     [ f ReadDirectoryChangesW win32-error=0/f ] keep ;
 
-: read-changes ( monitor -- bytes )
+: read-changes ( port -- bytes )
     [
-        [
-            dup begin-reading-changes
-            swap [ save-callback ] 2keep
-            dup check-monitor ! we may have closed it...
-            get-overlapped-result
-        ] with-timeout
+        dup begin-reading-changes
+        swap [ save-callback ] 2keep
+        check-closed ! we may have closed it...
+        dup eof>> [ "EOF??" throw ] when
+        get-overlapped-result
     ] with-destructors ;
 
 : parse-action ( action -- changed )
     {
-        { [ dup FILE_ACTION_ADDED = ] [ +add-file+ ] }
-        { [ dup FILE_ACTION_REMOVED = ] [ +remove-file+ ] }
-        { [ dup FILE_ACTION_MODIFIED = ] [ +modify-file+ ] }
-        { [ dup FILE_ACTION_RENAMED_OLD_NAME = ] [ +rename-file+ ] }
-        { [ dup FILE_ACTION_RENAMED_NEW_NAME = ] [ +rename-file+ ] }
-        { [ t ] [ +modify-file+ ] }
-    } cond nip ;
+        { FILE_ACTION_ADDED [ +add-file+ ] }
+        { FILE_ACTION_REMOVED [ +remove-file+ ] }
+        { FILE_ACTION_MODIFIED [ +modify-file+ ] }
+        { FILE_ACTION_RENAMED_OLD_NAME [ +rename-file+ ] }
+        { FILE_ACTION_RENAMED_NEW_NAME [ +rename-file+ ] }
+        [ drop +modify-file+ ]
+    } case 1array ;
 
 : memory>u16-string ( alien len -- string )
     [ memory>byte-array ] keep 2/ c-ushort-array> >string ;
 
-: parse-file-notify ( buffer -- changed path )
-    {
-        FILE_NOTIFY_INFORMATION-FileName
-        FILE_NOTIFY_INFORMATION-FileNameLength
-        FILE_NOTIFY_INFORMATION-Action
-    } get-slots parse-action 1array -rot memory>u16-string ;
-
-: (changed-files) ( buffer -- )
-    dup parse-file-notify changed-file
-    dup FILE_NOTIFY_INFORMATION-NextEntryOffset dup zero?
-    [ 2drop ] [ swap <displaced-alien> (changed-files) ] if ;
-
-M: win32-monitor fill-queue ( monitor -- )
-    dup buffer-ptr over read-changes
-    [ zero? [ drop ] [ (changed-files) ] if ] H{ } make-assoc
-    swap set-monitor-queue ;
+: parse-notify-record ( buffer -- path changed )
+    [
+        [ FILE_NOTIFY_INFORMATION-FileName ]
+        [ FILE_NOTIFY_INFORMATION-FileNameLength ]
+        bi memory>u16-string
+    ]
+    [ FILE_NOTIFY_INFORMATION-Action parse-action ] bi ;
+
+: (file-notify-records) ( buffer -- buffer )
+    dup ,
+    dup FILE_NOTIFY_INFORMATION-NextEntryOffset zero? [
+        [ FILE_NOTIFY_INFORMATION-NextEntryOffset ] keep <displaced-alien>
+        (file-notify-records)
+    ] unless ;
+
+: file-notify-records ( buffer -- seq )
+    [ (file-notify-records) drop ] { } make ;
+
+: parse-notify-records ( monitor buffer -- )
+    file-notify-records
+    [ parse-notify-record rot queue-change ] with each ;
+
+: fill-queue ( monitor -- )
+    dup port>> check-closed
+    [ buffer>> ptr>> ] [ read-changes zero? ] bi
+    [ 2dup parse-notify-records ] unless
+    2drop ;
+
+: (fill-queue-thread) ( monitor -- )
+    dup fill-queue (fill-queue-thread) ;
+
+: fill-queue-thread ( monitor -- )
+    [ dup fill-queue (fill-queue-thread) ]
+    [ dup port-closed-error? [ 2drop ] [ rethrow ] if ] recover ;
+
+M:: winnt (monitor) ( path recursive? mailbox -- monitor )
+    [
+        path mailbox win32-monitor new-monitor
+            path open-directory \ win32-monitor-port <buffered-port>
+                recursive? >>recursive
+            >>port
+        dup [ fill-queue-thread ] curry
+        "Windows monitor thread" spawn drop
+    ] with-destructors ;
+
+M: win32-monitor dispose
+    port>> dispose ;
index f2aca0470d3acb5bda478759cf55d03059839e5b..b164d5872b048eeb2276b223f6f0f87075889c35 100755 (executable)
@@ -37,7 +37,7 @@ TUPLE: pipe in out ;
     [
         >r over >r create-named-pipe dup close-later
         r> r> open-other-end dup close-later
-        pipe construct-boa
+        pipe boa
     ] with-destructors ;
 
 : close-pipe ( pipe -- )
index 36acaac992a481af0b6be909b107ac34db9ae8fa..79e767177dee7916d0e71d3684cd60e05a55a644 100755 (executable)
@@ -2,7 +2,7 @@ USING: alien alien.accessors alien.c-types byte-arrays
 continuations destructors io.nonblocking io.timeouts io.sockets
 io.sockets.impl io namespaces io.streams.duplex io.windows
 io.windows.nt.backend windows.winsock kernel libc math sequences
-threads classes.tuple.lib system ;
+threads classes.tuple.lib system accessors ;
 IN: io.windows.nt.sockets
 
 : malloc-int ( object -- object )
@@ -50,9 +50,9 @@ TUPLE: ConnectEx-args port
     2dup save-callback
     get-overlapped-result drop ;
 
-M: winnt (client) ( addrspec -- client-in client-out )
+M: winnt ((client)) ( addrspec -- client-in client-out )
     [
-        \ ConnectEx-args construct-empty
+        \ ConnectEx-args new
         over make-sockaddr/size pick init-connect
         over tcp-socket over set-ConnectEx-args-s*
         dup ConnectEx-args-s* add-completion
@@ -122,8 +122,8 @@ TUPLE: AcceptEx-args port
 M: winnt (accept) ( server -- addrspec handle )
     [
         [
-            dup check-server-port
-            \ AcceptEx-args construct-empty
+            check-server-port
+            \ AcceptEx-args new
             [ init-accept ] keep
             [ ((accept)) ] keep
             [ accept-continuation ] keep
@@ -159,7 +159,7 @@ TUPLE: WSARecvFrom-args port
 : init-WSARecvFrom ( datagram WSARecvFrom -- )
     [ set-WSARecvFrom-args-port ] 2keep
     [
-        >r delegate port-handle delegate win32-file-handle r>
+        >r handle>> handle>> r>
         set-WSARecvFrom-args-s*
     ] 2keep [
         >r datagram-port-addr sockaddr-type heap-size r>
@@ -192,8 +192,8 @@ TUPLE: WSARecvFrom-args port
 
 M: winnt receive ( datagram -- packet addrspec )
     [
-        dup check-datagram-port
-        \ WSARecvFrom-args construct-empty
+        check-datagram-port
+        \ WSARecvFrom-args new
         [ init-WSARecvFrom ] keep
         [ call-WSARecvFrom ] keep
         [ WSARecvFrom-continuation ] keep
@@ -244,8 +244,8 @@ USE: io.sockets
 
 M: winnt send ( packet addrspec datagram -- )
     [
-        3dup check-datagram-send
-        \ WSASendTo-args construct-empty
+        check-datagram-send
+        \ WSASendTo-args new
         [ init-WSASendTo ] keep
         [ call-WSASendTo ] keep
         [ WSASendTo-continuation ] keep
diff --git a/extra/io/windows/tags.txt b/extra/io/windows/tags.txt
new file mode 100644 (file)
index 0000000..8e1a559
--- /dev/null
@@ -0,0 +1 @@
+windows
index 3e0f4e9e8655cd9f22864b4b8174c5920d8b9f00..772ad9124f519888185f1aa44b024f2d1ac6e3d4 100755 (executable)
@@ -5,7 +5,7 @@ io.buffers io.files io.nonblocking io.sockets io.binary
 io.sockets.impl windows.errors strings io.streams.duplex
 kernel math namespaces sequences windows windows.kernel32
 windows.shell32 windows.types windows.winsock splitting
-continuations math.bitfields system ;
+continuations math.bitfields system accessors ;
 IN: io.windows
 
 M: windows destruct-handle CloseHandle drop ;
@@ -92,7 +92,7 @@ M: win32-file close-handle ( handle -- )
     ] when drop ;
 
 : open-append ( path -- handle length )
-    [ dup file-info file-info-size ] [ drop 0 ] recover
+    [ dup file-info size>> ] [ drop 0 ] recover
     >r (open-append) r> 2dup set-file-pointer ;
 
 TUPLE: FileArgs
@@ -103,9 +103,9 @@ C: <FileArgs> FileArgs
 
 : make-FileArgs ( port -- <FileArgs> )
     [ port-handle win32-file-handle ] keep
-    [ delegate ] keep
+    [ buffer>> ] keep
     [
-        buffer-length
+        buffer>> buffer-length
         "DWORD" <c-object>
     ] keep FileArgs-overlapped <FileArgs> ;
 
@@ -152,11 +152,10 @@ M: windows delete-directory ( path -- )
 
 HOOK: WSASocket-flags io-backend ( -- DWORD )
 
-TUPLE: win32-socket ;
+TUPLE: win32-socket < win32-file ;
 
 : <win32-socket> ( handle -- win32-socket )
-    f <win32-file>
-    \ win32-socket construct-delegate ;
+    f win32-file boa ;
 
 : open-socket ( family type -- socket )
     0 f 0 WSASocket-flags WSASocket dup socket-error ;
index 8a39846fc4553f0b73f3f8bd00205cb1e32ddaee..4dda206c7b9864481e3c26deaecacc1ea43d0cc4 100755 (executable)
 ! Copyright (C) 2007 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays calendar io io.sockets kernel match namespaces
-sequences splitting strings continuations threads ascii
-io.encodings.utf8 ;
+USING: arrays calendar combinators channels concurrency.messaging fry io
+       io.encodings.8-bit io.sockets kernel math namespaces sequences
+       sequences.lib splitting strings threads
+       continuations classes.tuple ascii accessors ;
 IN: irc
 
+! utils
+: split-at-first ( seq separators -- before after )
+    dupd '[ , member? ] find
+        [ cut 1 tail ]
+        [ swap ]
+    if ;
+
+: spawn-server-linked ( quot name -- thread )
+    >r '[ , [ ] [ ] while ] r>
+    spawn-linked ;
+! ---
+
+! Default irc port
+: irc-port 6667 ;
+
+! Message used when the client isn't running anymore
+SINGLETON: irc-end
+
 ! "setup" objects
-TUPLE: profile server port nickname password default-channels ;
-C: <profile> profile
+TUPLE: irc-profile server port nickname password default-channels  ;
+C: <irc-profile> irc-profile
 
-TUPLE: channel-profile name password auto-rejoin ;
-C: <channel-profile> channel-profile
+TUPLE: irc-channel-profile name password auto-rejoin ;
+C: <irc-channel-profile> irc-channel-profile
 
 ! "live" objects
-TUPLE: irc-client profile nick stream stream-process controller-process ;
-C: <irc-client> irc-client
-
 TUPLE: nick name channels log ;
 C: <nick> nick
 
-TUPLE: channel name topic members log attributes ;
-C: <channel> channel
+TUPLE: irc-client profile nick stream stream-channel controller-channel
+       listeners is-running ;
+: <irc-client> ( profile -- irc-client )
+    f V{ } clone V{ } clone <nick>
+    f <channel> <channel> V{ } clone f irc-client boa ;
+
+USE: prettyprint
+TUPLE: irc-listener channel ;
+! FIXME: spawn-server-linked con manejo de excepciones, mandar un mensaje final (ya se maneja esto al recibir mensajes del channel? )
+! tener la opción de dejar de correr un client??
+: <irc-listener> ( quot -- irc-listener )
+    <channel> irc-listener boa swap
+    [
+        [ channel>> '[ , from ] ]
+        [ '[ , curry f spawn drop ] ]
+        bi* compose "irc-listener" spawn-server-linked drop
+    ] [ drop ] 2bi ;
+
+! TUPLE: irc-channel name topic members log attributes ;
+! C: <irc-channel> irc-channel
 
 ! the delegate of all irc messages
-TUPLE: irc-message timestamp ;
+TUPLE: irc-message line prefix command parameters trailing timestamp ;
 C: <irc-message> irc-message
 
 ! "irc message" objects
-TUPLE: logged-in name text ;
+TUPLE: logged-in < irc-message name ;
 C: <logged-in> logged-in
 
-TUPLE: ping name ;
+TUPLE: ping < irc-message ;
 C: <ping> ping
 
-TUPLE: join name channel ;
-C: <join> join
+TUPLE: join_ < irc-message ;
+C: <join> join_
 
-TUPLE: part name channel text ;
+TUPLE: part < irc-message name channel ;
 C: <part> part
 
-TUPLE: quit text ;
+TUPLE: quit ;
 C: <quit> quit
 
-TUPLE: privmsg name text ;
+TUPLE: privmsg < irc-message name ;
 C: <privmsg> privmsg
 
-TUPLE: kick channel er ee text ;
+TUPLE: kick < irc-message channel who ;
 C: <kick> kick
 
-TUPLE: roomlist channel names ;
+TUPLE: roomlist < irc-message channel names ;
 C: <roomlist> roomlist
 
-TUPLE: nick-in-use name ;
+TUPLE: nick-in-use < irc-message name ;
 C: <nick-in-use> nick-in-use
 
-TUPLE: notice type text ;
+TUPLE: notice < irc-message type ;
 C: <notice> notice
 
-TUPLE: mode name channel mode text ;
+TUPLE: mode < irc-message name channel mode ;
 C: <mode> mode
-! TUPLE: members
 
-TUPLE: unhandled text ;
+TUPLE: unhandled < irc-message ;
 C: <unhandled> unhandled
 
-! "control message" objects
-TUPLE: command sender ;
-TUPLE: service predicate quot enabled? ;
-TUPLE: chat-command from to text ;
-TUPLE: join-command channel password ;
-TUPLE: part-command channel text ;
-
 SYMBOL: irc-client
-: irc-stream> ( -- stream ) irc-client get irc-client-stream ;
-: trim-: ( seq -- seq ) [ CHAR: : = ] left-trim ;
+: irc-client> ( -- irc-client ) irc-client get ;
+: irc-stream> ( -- stream ) irc-client> stream>> ;
+
+: remove-heading-: ( seq -- seq ) dup ":" head? [ 1 tail ] when ;
+
 : parse-name ( string -- string )
-    trim-: "!" split first ;
-: irc-split ( string -- seq )
-    1 swap [ [ CHAR: : = ] find* ] keep
-    swap [ swap cut trim-: ] [ nip f ] if >r [ blank? ] trim trim-:
-    " " split r> [ 1array append ] when* ;
+    remove-heading-: "!" split-at-first drop ;
+
+: sender>> ( obj -- string )
+    prefix>> parse-name ;
+
+: split-prefix ( string -- string/f string )
+    dup ":" head?
+        [ remove-heading-: " " split1 ]
+        [ f swap ]
+    if ;
+
+: split-trailing ( string -- string string/f )
+    ":" split1 ;
+
+: string>irc-message ( string -- object )
+    dup split-prefix split-trailing
+    [ [ blank? ] trim " " split unclip swap ] dip
+    now <irc-message> ;
+
 : me? ( name -- ? )
-    irc-client get irc-client-nick nick-name = ;
+    irc-client> nick>> name>> = ;
 
 : irc-write ( s -- )
     irc-stream> stream-write ;
@@ -89,123 +132,155 @@ SYMBOL: irc-client
 : irc-print ( s -- )
     irc-stream> [ stream-print ] keep stream-flush ;
 
-: nick ( nick -- )
+! Irc commands    
+
+: NICK ( nick -- )
     "NICK " irc-write irc-print ;
 
-: login ( nick -- )
-    dup nick
+: LOGIN ( nick -- )
+    dup NICK
     "USER " irc-write irc-write
     " hostname servername :irc.factor" irc-print ;
 
-: connect* ( server port -- )
-    <inet> utf8 <client> irc-client get set-irc-client-stream ;
-
-: connect ( server -- ) 6667 connect* ;
+: CONNECT ( server port -- stream )
+    <inet> latin1 <client> ;
 
-: join ( channel password -- )
+: JOIN ( channel password -- )
     "JOIN " irc-write
-    [ >r " :" r> 3append ] when* irc-print ;
+    [ " :" swap 3append ] when* irc-print ;
 
-: part ( channel text -- )
-    >r "PART " irc-write irc-write r>
+: PART ( channel text -- )
+    [ "PART " irc-write irc-write ] dip
     " :" irc-write irc-print ;
 
-: say ( line nick -- )
-    "PRIVMSG " irc-write irc-write " :" irc-write irc-print ;
+: KICK ( channel who -- )
+    [ "KICK " irc-write irc-write ] dip
+    " " irc-write irc-print ;
+    
+: PRIVMSG ( nick line -- )
+    [ "PRIVMSG " irc-write irc-write ] dip
+    " :" irc-write irc-print ;
+
+: SAY ( nick line -- )
+    PRIVMSG ;
 
-: quit ( text -- )
+: ACTION ( nick line -- )
+    [ 1 , "ACTION " % % 1 , ] "" make PRIVMSG ;
+
+: QUIT ( text -- )
     "QUIT :" irc-write irc-print ;
 
+: join-channel ( channel-profile -- )
+    [ name>> ] keep password>> JOIN ;
 
+: irc-connect ( irc-client -- )
+    [ profile>> [ server>> ] keep port>> CONNECT ] keep
+    swap >>stream t >>is-running drop ;
+    
 GENERIC: handle-irc ( obj -- )
 
 M: object handle-irc ( obj -- )
-    "Unhandled irc object" print drop ;
+    drop ;
 
 M: logged-in handle-irc ( obj -- )
-    logged-in-name irc-client get [ irc-client-nick set-nick-name ] keep
-    
-    irc-client-profile profile-default-channels
-    [
-        [ channel-profile-name ] keep
-        channel-profile-password join
-    ] each ;
+    name>>
+    irc-client> [ nick>> swap >>name drop ] keep 
+    profile>> default-channels>> [ join-channel ] each ;
 
 M: ping handle-irc ( obj -- )
     "PONG " irc-write
-    ping-name irc-print ;
+    trailing>> irc-print ;
 
 M: nick-in-use handle-irc ( obj -- )
-    nick-in-use-name "_" append nick ;
-
-: delegate-timestamp ( obj -- obj )
-    now <irc-message> over set-delegate ;
-
-MATCH-VARS: ?name ?name2 ?channel ?text ?mode ;
-SYMBOL: line
-: match-irc ( string -- )
-    dup line set
-    dup print flush
-    irc-split
-    {
-        { { "PING" ?name }
-          [ ?name <ping> ] }
-        { { ?name "001" ?name2 ?text }
-          [ ?name2 ?text <logged-in> ] }
-        { { ?name "433" _ ?name2 "Nickname is already in use." }
-          [ ?name2 <nick-in-use> ] }
-
-        { { ?name "JOIN" ?channel }
-          [ ?name ?channel <join> ] }
-        { { ?name "PART" ?channel ?text }
-          [ ?name ?channel ?text <part> ] }
-        { { ?name "PRIVMSG" ?channel ?text }
-          [ ?name ?channel ?text <privmsg> ] }
-        { { ?name "QUIT" ?text }
-          [ ?name ?text <quit> ] }
-
-        { { "NOTICE" ?name ?text }
-          [ ?name ?text <notice> ] }
-        { { ?name "MODE" ?channel ?mode ?text }
-          [ ?name ?channel ?mode ?text <mode> ] }
-        { { ?name "KICK" ?channel ?name2 ?text }
-          [  ?channel ?name ?name2 ?text <kick> ] }
-
-        ! { { ?name "353" ?name2 _ ?channel ?text }
-         ! [ ?text ?channel ?name2 make-member-list ] }
-        { _ [ line get <unhandled> ] }
-    } match-cond
-    delegate-timestamp handle-irc flush ;
-
-: irc-loop ( -- )
-    irc-stream> stream-readln
-    [ match-irc irc-loop ] when* ;
-
+    name>> "_" append NICK ;
+
+: parse-irc-line ( string -- message )
+    string>irc-message
+    dup command>> {
+        { "PING" [ \ ping ] }
+        { "NOTICE" [ \ notice ] }
+        { "001" [ \ logged-in ] }
+        { "433" [ \ nick-in-use ] }
+        { "JOIN" [ \ join_ ] }
+        { "PART" [ \ part ] }
+        { "PRIVMSG" [ \ privmsg ] }
+        { "QUIT" [ \ quit ] }
+        { "MODE" [ \ mode ] }
+        { "KICK" [ \ kick ] }
+        [ drop \ unhandled ]
+    } case
+    [ [ tuple-slots ] [ parameters>> ] bi append ] dip prefix >tuple ;
+
+! Reader
+: handle-reader-message ( irc-client irc-message -- )
+    dup handle-irc swap stream-channel>> to ;
+
+: reader-loop ( irc-client -- )
+    dup stream>> stream-readln [
+        dup print parse-irc-line handle-reader-message
+    ] [
+        f >>is-running
+        dup stream>> dispose
+        irc-end over controller-channel>> to
+        stream-channel>> irc-end swap to
+    ] if* ;
+
+! Controller commands
+GENERIC: handle-command ( obj -- )
+
+M: object handle-command ( obj -- )
+    . ;
+
+TUPLE: send-message to text ;
+C: <send-message> send-message
+M: send-message handle-command ( obj -- )
+    dup to>> swap text>> SAY ;
+
+TUPLE: send-action to text ;
+C: <send-action> send-action
+M: send-action handle-command ( obj -- )
+    dup to>> swap text>> ACTION ;
+
+TUPLE: send-quit text ;
+C: <send-quit> send-quit
+M: send-quit handle-command ( obj -- )
+    text>> QUIT ;
+
+: irc-listen ( irc-client quot -- )
+    [ listeners>> ] [ <irc-listener> ] bi* swap push ;
+
+! Controller loop
+: controller-loop ( irc-client -- )
+    controller-channel>> from handle-command ;
+
+! Multiplexer
+: multiplex-message ( irc-client message -- )
+    swap listeners>> [ channel>> ] map
+    [ '[ , , to ] "message" spawn drop ] each-with ;
+
+: multiplexer-loop ( irc-client -- )
+    dup stream-channel>> from multiplex-message ;
+
+! process looping and starting
+: (spawn-irc-loop) ( irc-client quot name -- )
+    [ over >r curry r> '[ @ , is-running>> ] ] dip
+    spawn-server-linked drop ;
+
+: spawn-irc-loop ( irc-client quot name -- )
+    '[ , , , [ (spawn-irc-loop) receive ] [ print ] recover ]
+    f spawn drop ;
+
+: spawn-irc ( irc-client -- )
+    [ [ reader-loop ] "reader-loop" spawn-irc-loop ]
+    [ [ controller-loop ] "controller-loop" spawn-irc-loop ]
+    [ [ multiplexer-loop ] "multiplexer-loop" spawn-irc-loop ]
+    tri ;
+    
 : do-irc ( irc-client -- )
-    dup irc-client set
-    dup irc-client-profile profile-server
-    over irc-client-profile profile-port connect*
-    dup irc-client-profile profile-nickname login
-    [ irc-loop ] [ irc-stream> dispose ] [ ] cleanup ;
-
-: with-infinite-loop ( quot timeout -- quot timeout )
-    "looping" print flush
-    over [ drop ] recover dup sleep with-infinite-loop ;
-
-: start-irc ( irc-client -- )
-    ! [ [ do-irc ] curry 3000 with-infinite-loop ] with-scope ;
-    [ do-irc ] curry 3000 with-infinite-loop ;
-
-
-! For testing
-: make-factorbot
-    "irc.freenode.org" 6667 "factorbot" f
-    [
-        "#concatenative-flood" f f <channel-profile> ,
-    ] { } make <profile>
-    f V{ } clone V{ } clone <nick>
-    f f f <irc-client> ;
-
-: test-factorbot
-    make-factorbot start-irc ;
-
+    irc-client [
+        irc-client>
+        [ irc-connect ]
+        [ profile>> nickname>> LOGIN ]
+        [ spawn-irc ]
+        tri
+    ] with-variable ;
\ No newline at end of file
index f82ee91d22dc2271fe81db0edde21c949c8b607a..3842816f0e43cda2f502f2e5fa03ab2e8804c4c3 100644 (file)
@@ -8,7 +8,7 @@ TUPLE: jamshred tunnel players running ;
 
 : <jamshred> ( -- jamshred )
     <random-tunnel> "Player 1" <player> 2dup swap play-in-tunnel 1array f
-    jamshred construct-boa ;
+    jamshred boa ;
 
 : jamshred-player ( jamshred -- player )
     ! TODO: support more than one player
index bcf4597307c328b6616723080776743eab12e1bf..11a89b314f25def2b9ad7fa9d6b93766e6484f5b 100644 (file)
@@ -11,7 +11,7 @@ IN: jamshred.oint
 TUPLE: oint location forward up left ;
 
 : <oint> ( location forward up left -- oint )
-    oint construct-boa ;
+    oint boa ;
 
 ! : x-rotation ( theta -- matrix )
 !     #! construct this matrix:
index 6cc433903e807737d5ac5ee443d78f9f5018f34f..17843ef9c2b925156e557c4333d4a5ed023d6828 100644 (file)
@@ -7,7 +7,7 @@ IN: jamshred.player
 TUPLE: player name tunnel nearest-segment ;
 
 : <player> ( name -- player )
-    f f player construct-boa
+    f f player boa
     F{ 0 0 5 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } <oint> over set-delegate ;
 
 : turn-player ( player x-radians y-radians -- )
index 7be406d37ae298cea3dbeb36282d0ea5e08e26a1..d5ee7f3ebc40f625bd9387b563108e0e8973f0a4 100755 (executable)
@@ -9,7 +9,7 @@ IN: jamshred.tunnel
 TUPLE: segment number color radius ;
 
 : <segment> ( number color radius location forward up left -- segment )
-    <oint> >r segment construct-boa r> over set-delegate ;
+    <oint> >r segment boa r> over set-delegate ;
 
 : segment-vertex ( theta segment -- vertex )
      tuck 2dup oint-up swap sin v*n
index add37173b753a043aee9d1e5e0cee917f8640540..b079cec42c69f8ee97f208c1a6df2a592477a273 100755 (executable)
@@ -3,7 +3,7 @@
 USING: arrays assocs hashtables assocs io kernel math
 math.vectors math.matrices math.matrices.elimination namespaces
 parser prettyprint sequences words combinators math.parser
-splitting sorting shuffle symbols ;
+splitting sorting shuffle symbols sets ;
 IN: koszul
 
 ! Utilities
@@ -15,7 +15,7 @@ IN: koszul
         { [ dup number? ] [ { } associate ] }
         { [ dup array? ] [ 1 swap associate ] }
         { [ dup hashtable? ] [ ] }
-        { [ t ] [ 1array >alt ] }
+        [ 1array >alt ]
     } cond ;
 
 : canonicalize
@@ -31,10 +31,10 @@ SYMBOL: terms
 ! Printing elements
 : num-alt. ( n -- str )
     {
-        { [ dup 1 = ] [ drop " + " ] }
-        { [ dup -1 = ] [ drop " - " ] }
-        { [ t ] [ number>string " + " prepend ] }
-    } cond ;
+        { 1 [ " + " ] }
+        { -1 [ " - " ] }
+        [ number>string " + " prepend ]
+    } case ;
 
 : (alt.) ( basis n -- str )
     over empty? [
index d13848498fe1e9a359d9018699c65f7920af2d21..b87a1e5f2e5176fe66ae63a94af261ca1d5972dd 100644 (file)
@@ -52,7 +52,7 @@ M: cons nil? ( cons -- bool )
 TUPLE: lazy-cons car cdr ;
 
 : lazy-cons ( car cdr -- promise )
-    [ promise ] bi@ \ lazy-cons construct-boa
+    [ promise ] bi@ \ lazy-cons boa
     T{ promise f f t f } clone
     [ set-promise-value ] keep ;
 
@@ -103,7 +103,7 @@ TUPLE: memoized-cons original car cdr nil? ;
 
 : <memoized-cons> ( cons -- memoized-cons )
   not-memoized not-memoized not-memoized
-  memoized-cons construct-boa ;
+  memoized-cons boa ;
 
 M: memoized-cons car ( memoized-cons -- car )
   dup memoized-cons-car not-memoized? [
@@ -321,7 +321,7 @@ M: sequence-cons nil? ( sequence-cons -- bool )
   {
     { [ dup sequence? ] [ 0 swap seq>list ] }
     { [ dup list?     ] [ ] }
-    { [ t ] [ "Could not convert object to a list" throw ] }
+    [ "Could not convert object to a list" throw ]
   } cond ;
 
 TUPLE: lazy-concat car cdr ;
diff --git a/extra/lint/authors.txt b/extra/lint/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/lint/lint-tests.factor b/extra/lint/lint-tests.factor
deleted file mode 100644 (file)
index 9a39980..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-USING: io lint kernel math tools.test ;
-IN: lint.tests
-
-! Don't write code like this
-: lint1
-    [ "hi" print ] [ ] if ; ! when
-
-[ { [ [ ] if ] } ] [ \ lint1 lint ] unit-test
-
-: lint2
-    1 + ; ! 1+
-[ { [ 1 + ] } ] [ \ lint2 lint ] unit-test
-
-: lint3
-    dup -rot ; ! tuck
-
-[ { [ dup -rot ] } ] [ \ lint3 lint ] unit-test
-
diff --git a/extra/lint/lint.factor b/extra/lint/lint.factor
deleted file mode 100644 (file)
index dcf52f7..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-! Copyright (C) 2007 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.accessors arrays assocs combinators.lib io kernel
-macros math namespaces prettyprint quotations sequences
-vectors vocabs words html.elements slots.private tar ;
-IN: lint
-
-SYMBOL: def-hash
-SYMBOL: def-hash-keys
-
-: set-hash-vector ( val key hash -- )
-    2dup at -rot >r >r ?push r> r> set-at ;
-
-: add-word-def ( word quot -- )
-    dup callable? [
-        def-hash get-global set-hash-vector
-    ] [
-        2drop
-    ] if ;
-
-: more-defs
-    {
-        { [ swap >r swap r> ] -rot }
-        { [ swap swapd ] -rot }
-        { [ >r swap r> swap ] rot }
-        { [ swapd swap ] rot }
-        { [ dup swap ] over }
-        { [ dup -rot ] tuck }
-        { [ >r swap r> ] swapd }
-        { [ nip nip ] 2nip }
-        { [ drop drop ] 2drop }
-        { [ drop drop drop ] 3drop }
-        { [ 0 = ] zero? }
-        { [ pop drop ] pop* }
-        { [ [ ] if ] when }
-    } [ first2 swap add-word-def ] each ;
-
-: accessor-words ( -- seq )
-{
-    alien-signed-1 alien-signed-2 alien-signed-4 alien-signed-8
-    alien-unsigned-1 alien-unsigned-2 alien-unsigned-4 alien-unsigned-8
-    <displaced-alien> alien-unsigned-cell set-alien-signed-cell
-    set-alien-unsigned-1 set-alien-signed-1 set-alien-unsigned-2
-    set-alien-signed-2 set-alien-unsigned-4 set-alien-signed-4
-    set-alien-unsigned-8 set-alien-signed-8
-    alien-cell alien-signed-cell set-alien-cell set-alien-unsigned-cell
-    set-alien-float alien-float
-} ;
-
-: trivial-defs
-    {
-        [ get ] [ t ] [ { } ] [ . ] [ drop f ]
-        [ drop ] [ f ] [ first ] [ second ] [ third ] [ fourth ]
-        [ ">" write-html ] [ <unimplemented-typeflag> throw ]
-        [ "/>" write-html ]
-    } ;
-
-H{ } clone def-hash set-global
-all-words [ dup word-def add-word-def ] each
-more-defs
-
-! Remove empty word defs
-def-hash get-global [
-    drop empty? not
-] assoc-subset
-
-! Remove constants [ 1 ]
-[
-    drop dup length 1 = swap first number? and not
-] assoc-subset
-
-! Remove set-alien-cell, etc.
-[
-    drop [ accessor-words swap seq-diff ] keep [ length ] bi@ =
-] assoc-subset
-
-! Remove trivial defs
-[
-    drop trivial-defs member? not
-] assoc-subset
-
-! Remove n m shift defs
-[
-    drop dup length 3 = [
-        dup first2 [ number? ] both?
-        swap third \ shift = and not
-    ] [ drop t ] if
-] assoc-subset 
-
-! Remove [ n slot ]
-[
-    drop dup length 2 = [
-        first2 \ slot = swap number? and not
-    ] [ drop t ] if
-] assoc-subset def-hash set-global
-
-: find-duplicates
-    def-hash get-global [
-        nip length 1 >
-    ] assoc-subset ;
-
-def-hash get-global keys def-hash-keys set-global
-
-GENERIC: lint ( obj -- seq )
-
-M: object lint ( obj -- seq )
-    drop f ;
-
-: subseq/member? ( subseq/member seq -- ? )
-    { [ 2dup start ] [ 2dup member? ] } || 2nip ;
-
-M: callable lint ( quot -- seq )
-    def-hash-keys get [
-        swap subseq/member?
-    ] with subset ;
-
-M: word lint ( word -- seq )
-    word-def dup callable? [ lint ] [ drop f ] if ;
-
-: word-path. ( word -- )
-    [ word-vocabulary ":" ] keep unparse 3append write nl ;
-
-: (lint.) ( pair -- )
-    first2 >r word-path. r> [
-        bl bl bl bl
-        dup .
-        "-----------------------------------" print
-        def-hash get at [ bl bl bl bl word-path. ] each
-        nl
-    ] each nl nl ;
-
-: lint. ( alist -- )
-    [ (lint.) ] each ;
-    
-
-GENERIC: run-lint ( obj -- obj )
-
-: (trim-self)
-    def-hash get-global at* [
-        dupd remove empty? not
-    ] [
-        drop f
-    ] if ;
-
-: trim-self ( seq -- newseq )
-    [ [ (trim-self) ] subset ] assoc-map ;
-
-: filter-symbols ( alist -- alist )
-    [
-        nip first dup def-hash get at
-        [ first ] bi@ literalize = not
-    ] assoc-subset ;
-
-M: sequence run-lint ( seq -- seq )
-    [
-        global [ dup . flush ] bind
-        dup lint
-    ] { } map>assoc
-    trim-self
-    [ second empty? not ] subset
-    filter-symbols ;
-
-M: word run-lint ( word -- seq )
-    1array run-lint ;
-
-: lint-all ( -- seq )
-    all-words run-lint dup lint. ;
-
-: lint-vocab ( vocab -- seq )
-    words run-lint dup lint. ;
-
-: lint-word ( word -- seq )
-    1array run-lint dup lint. ;
diff --git a/extra/lint/summary.txt b/extra/lint/summary.txt
deleted file mode 100755 (executable)
index 943869d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Finds potential mistakes in code
index a961dec3bde2916a710120bdd68a0c460ec172bd..2b0c61cc8951d17f828fdb8162cc910ffcd87b53 100755 (executable)
@@ -3,7 +3,7 @@
 USING: kernel namespaces sequences sequences.private assocs math
 inference.transforms parser words quotations debugger macros
 arrays macros splitting combinators prettyprint.backend
-definitions prettyprint hashtables prettyprint.sections
+definitions prettyprint hashtables prettyprint.sections sets
 sequences.private effects generic compiler.units accessors ;
 IN: locals
 
@@ -140,7 +140,7 @@ M: object free-vars drop { } ;
 M: quotation free-vars { } [ add-if-free ] reduce ;
 
 M: lambda free-vars
-    dup vars>> swap body>> free-vars seq-diff ;
+    dup vars>> swap body>> free-vars diff ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! lambda-rewrite
index 015861501ecdfd18345479eeb4f75db5b14012ff..c6b073e50199d2215bc20e779f63b8819acd194a 100755 (executable)
@@ -66,7 +66,7 @@ MEMO: 'log-line' ( -- parser )
             parse-log-line {\r
                 { [ dup malformed? ] [ malformed-line ] }\r
                 { [ dup multiline? ] [ add-multiline ] }\r
-                { [ t ] [ , ] }\r
+                [ , ]\r
             } cond\r
         ] each\r
     ] { } make ;\r
index bed6a2fec33345e244b94e014f78f07dc7147f1b..c6aee034cc75f99b9727a940302ac129ccfee3a1 100755 (executable)
@@ -40,10 +40,10 @@ SYMBOL: log-files
     rot [ empty? not ] subset {\r
         { [ dup empty? ] [ 3drop ] }\r
         { [ dup length 1 = ] [ first -rot f (write-message) ] }\r
-        { [ t ] [\r
+        [\r
             [ first -rot f (write-message) ] 3keep\r
             1 tail -rot [ t (write-message) ] 2curry each\r
-        ] }\r
+        ]\r
     } cond ;\r
 \r
 : (log-message) ( msg -- )\r
index 93ecb60f1ca250251718f139e5ee9f8d6337fe2a..cfd00d9795e4ba623270aa6b5fa3ac5d5832e44c 100644 (file)
@@ -1 +1 @@
-Utility for defining compiler transforms, and short-circuiting boolean operators
+Utility for defining compiler transforms
index 825d58c7c2c2d43e29c369d6574f168c1a3a221e..e559ebc60d3e78eda47d94a297b0ddf17a90d65a 100755 (executable)
@@ -58,7 +58,7 @@ MACRO: match-cond ( assoc -- )
         { [ dup match-var? ] [ get ] }
         { [ dup sequence? ] [ [ replace-patterns ] map ] }
         { [ dup tuple? ] [ tuple>array replace-patterns >tuple ] }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : match-replace ( object pattern1 pattern2 -- result )
index 5b805fa260bbfa8de398d79ff53f61c244791c13..40de92e3b1d322866b2bfa86f31f9ebb463fd4f7 100644 (file)
@@ -22,7 +22,7 @@ TUPLE: erato limit bits latest ;
   [ [ indices ] keep erato-bits [ f -rot set-nth ] curry each ] [ 2drop ] if ;
 
 : <erato> ( n -- erato )
-  dup ind 1+ <bit-array> 1 over set-bits erato construct-boa ;
+  dup ind 1+ <bit-array> 1 over set-bits erato boa ;
 
 : next-prime ( erato -- prime/f )
   [ erato-latest 2 + ] keep [ set-erato-latest ] 2keep
index 77c7d9247dda521e994a4ac7ef3747dcb6f936ea..b3cfba8650ff810b6863fd803a120897fbf0cc3a 100755 (executable)
@@ -99,7 +99,7 @@ M: real absq sq ;
         { [ pick fp-nan? pick fp-nan? or ] [ 3drop f ] }
         { [ dup zero? ] [ drop number= ] }
         { [ dup 0 < ] [ ~rel ] }
-        { [ t ] [ ~abs ] }
+        [ ~abs ]
     } cond ;
 
 : power-of-2? ( n -- ? )
index ea7f02829dc7c85ee9110fd0c09c8b0afeaaf352..7835277b9b2fde1110f13f3082dc3315f0064b5e 100755 (executable)
@@ -1,6 +1,6 @@
 USING: combinators combinators.lib io locals kernel math
 math.functions math.ranges namespaces random sequences
-hashtables ;
+hashtables sets ;
 IN: math.miller-rabin
 
 SYMBOL: a
@@ -55,7 +55,7 @@ TUPLE: miller-rabin-bounds ;
         { [ dup 1 <= ] [ 3drop f ] }
         { [ dup 2 = ] [ 3drop t ] }
         { [ dup even? ] [ 3drop f ] }
-        { [ t ] [ [ drop trials set t (miller-rabin) ] with-scope ] }
+        [ [ drop trials set t (miller-rabin) ] with-scope ]
     } cond ;
 
 : miller-rabin ( n -- ? ) 10 miller-rabin* ;
index eeb1b66a89f2f03e62470bfa4d85f3e88bd2b1b5..edad69fffc650b94a12a5af5c1842640cc08e894 100644 (file)
@@ -38,9 +38,8 @@ PRIVATE>
     { [ dup 2 < ] [ drop { } ] }
     { [ dup 1000003 < ]
       [ primes-under-million [ [ <=> ] binsearch 1+ 0 swap ] keep <slice> ] }
-    { [ t ]
-      [ primes-under-million 1000003 lprimes-from
-        rot [ <= ] curry lwhile list>array append ] }
+    [ primes-under-million 1000003 lprimes-from
+        rot [ <= ] curry lwhile list>array append ]
   } cond ; foldable
 
 : primes-between ( low high -- seq )
index 9215fc3acd5d53b529e5f1c35c21886a49f80af5..81b7f634276fbaf8b89448884dfea37dfa03a8c4 100755 (executable)
@@ -6,7 +6,7 @@ TUPLE: range from length step ;
 : <range> ( a b step -- range )
     >r over - r>
     [ / 1+ 0 max >integer ] keep
-    range construct-boa ;
+    range boa ;
 
 M: range length ( seq -- n )
     range-length ;
index bd02c2f70843fe2e8807cc7940e1d1459e2560a2..7964f8929e21dfbfed66191b735492069d284d09 100755 (executable)
@@ -4,7 +4,7 @@ tools.test ;
 
 TUPLE: model-tester hit? ;
 
-: <model-tester> model-tester construct-empty ;
+: <model-tester> model-tester new ;
 
 M: model-tester model-changed nip t swap set-model-tester-hit? ;
 
index ffb9b1127ae2c9f6a424044f67555b1202637387..58335de3d11371abfd7e3db471261c82d0071b73 100755 (executable)
@@ -8,7 +8,7 @@ TUPLE: model < identity-tuple
 value connections dependencies ref locked? ;
 
 : <model> ( value -- model )
-    V{ } clone V{ } clone 0 f model construct-boa ;
+    V{ } clone V{ } clone 0 f model boa ;
 
 M: model hashcode* drop model hashcode* ;
 
diff --git a/extra/morse/tags.txt b/extra/morse/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
diff --git a/extra/multi-methods/multi-methods-tests.factor b/extra/multi-methods/multi-methods-tests.factor
deleted file mode 100755 (executable)
index 8910e64..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-IN: multi-methods.tests
-USING: multi-methods tools.test kernel math arrays sequences
-prettyprint strings classes hashtables assocs namespaces
-debugger continuations ;
-
-[ { 1 2 3 4 5 6 } ] [
-    { 6 4 5 1 3 2 } [ <=> ] topological-sort
-] unit-test
-
-[ -1 ] [
-    { fixnum array } { number sequence } classes<
-] unit-test
-
-[ 0 ] [
-    { number sequence } { number sequence } classes<
-] unit-test
-
-[ 1 ] [
-    { object object } { number sequence } classes<
-] unit-test
-
-[
-    {
-        { { object integer } [ 1 ] }
-        { { object object } [ 2 ] }
-        { { POSTPONE: f POSTPONE: f } [ 3 ] }
-    }
-] [
-    {
-        { { integer } [ 1 ] }
-        { { } [ 2 ] }
-        { { f f } [ 3 ] }
-    } congruify-methods
-] unit-test
-
-GENERIC: first-test
-
-[ t ] [ \ first-test generic? ] unit-test
-
-MIXIN: thing
-
-TUPLE: paper ;    INSTANCE: paper thing
-TUPLE: scissors ; INSTANCE: scissors thing
-TUPLE: rock ;     INSTANCE: rock thing
-
-GENERIC: beats?
-
-METHOD: beats? { paper scissors } t ;
-METHOD: beats? { scissors rock } t ;
-METHOD: beats? { rock paper } t ;
-METHOD: beats? { thing thing } f ;
-
-: play ( obj1 obj2 -- ? ) beats? 2nip ;
-
-[ { } 3 play ] must-fail
-[ t ] [ error get no-method? ] unit-test
-[ ] [ error get error. ] unit-test
-[ t ] [ T{ paper } T{ scissors } play ] unit-test
-[ f ] [ T{ scissors } T{ paper } play ] unit-test
-
-[ t ] [ { beats? paper scissors } method-spec? ] unit-test
-[ ] [ { beats? paper scissors } see ] unit-test
-
-GENERIC: legacy-test
-
-M: integer legacy-test sq ;
-M: string legacy-test " hey" append ;
-
-[ 25 ] [ 5 legacy-test ] unit-test
-[ "hello hey" ] [ "hello" legacy-test ] unit-test
-
-SYMBOL: some-var
-
-HOOK: hook-test some-var
-
-[ t ] [ \ hook-test hook-generic? ] unit-test
-
-METHOD: hook-test { array array } reverse ;
-METHOD: hook-test { array } class ;
-METHOD: hook-test { hashtable number } assoc-size ;
-
-{ 1 2 3 } some-var set
-[ { f t t } ] [ { t t f } hook-test ] unit-test
-[ fixnum ] [ 3 hook-test ] unit-test
-5.0 some-var set
-[ 0 ] [ H{ } hook-test ] unit-test
-
-MIXIN: busted
-
-TUPLE: busted-1 ;
-TUPLE: busted-2 ; INSTANCE: busted-2 busted
-TUPLE: busted-3 ;
-
-GENERIC: busted-sort
-
-METHOD: busted-sort { busted-1 busted-2 } ;
-METHOD: busted-sort { busted-2 busted-3 } ;
-METHOD: busted-sort { busted busted } ;
index 115432b14d6719d84cf4a07bb7fa77ebaa18efe0..dd6fc7dfff6014c43d473894f141130c7bf2fd25 100755 (executable)
@@ -3,13 +3,74 @@
 USING: kernel math sequences vectors classes classes.algebra
 combinators arrays words assocs parser namespaces definitions
 prettyprint prettyprint.backend quotations arrays.lib
-debugger io compiler.units kernel.private effects ;
+debugger io compiler.units kernel.private effects accessors
+hashtables sorting shuffle ;
 IN: multi-methods
 
-GENERIC: generic-prologue ( combination -- quot )
+! PART I: Converting hook specializers
+: canonicalize-specializer-0 ( specializer -- specializer' )
+    [ \ f or ] map ;
 
-GENERIC: method-prologue ( combination -- quot )
+SYMBOL: args
 
+SYMBOL: hooks
+
+SYMBOL: total
+
+: canonicalize-specializer-1 ( specializer -- specializer' )
+    [
+        [ class? ] subset
+        [ length <reversed> [ 1+ neg ] map ] keep zip
+        [ length args [ max ] change ] keep
+    ]
+    [
+        [ pair? ] subset
+        [ keys [ hooks get push-new ] each ] keep
+    ] bi append ;
+
+: canonicalize-specializer-2 ( specializer -- specializer' )
+    [
+        >r
+        {
+            { [ dup integer? ] [ ] }
+            { [ dup word? ] [ hooks get index ] }
+        } cond args get + r>
+    ] assoc-map ;
+
+: canonicalize-specializer-3 ( specializer -- specializer' )
+    >r total get object <array> dup <enum> r> update ;
+
+: canonicalize-specializers ( methods -- methods' hooks )
+    [
+        [ >r canonicalize-specializer-0 r> ] assoc-map
+
+        0 args set
+        V{ } clone hooks set
+
+        [ >r canonicalize-specializer-1 r> ] assoc-map
+
+        hooks [ natural-sort ] change
+
+        [ >r canonicalize-specializer-2 r> ] assoc-map
+
+        args get hooks get length + total set
+
+        [ >r canonicalize-specializer-3 r> ] assoc-map
+
+        hooks get
+    ] with-scope ;
+
+: drop-n-quot ( n -- quot ) \ drop <repetition> >quotation ;
+
+: prepare-method ( method n -- quot )
+    [ 1quotation ] [ drop-n-quot ] bi* prepend ;
+
+: prepare-methods ( methods -- methods' prologue )
+    canonicalize-specializers
+    [ length [ prepare-method ] curry assoc-map ] keep
+    [ [ get ] curry ] map concat [ ] like ;
+
+! Part II: Topologically sorting specializers
 : maximal-element ( seq quot -- n elt )
     dupd [
         swapd [ call 0 < ] 2curry subset empty?
@@ -28,10 +89,14 @@ GENERIC: method-prologue ( combination -- quot )
             { [ 2dup [ class< ] 2keep swap class< and ] [ 0 ] }
             { [ 2dup class< ] [ -1 ] }
             { [ 2dup swap class< ] [ 1 ] }
-            { [ t ] [ 0 ] }
+            [ 0 ]
         } cond 2nip
     ] 2map [ zero? not ] find nip 0 or ;
 
+: sort-methods ( alist -- alist' )
+    [ [ first ] bi@ classes< ] topological-sort ;
+
+! PART III: Creating dispatch quotation
 : picker ( n -- quot )
     {
         { 0 [ [ dup ] ] }
@@ -52,209 +117,164 @@ GENERIC: method-prologue ( combination -- quot )
         unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
     ] if ;
 
+: argument-count ( methods -- n )
+    keys 0 [ length max ] reduce ;
+
+ERROR: no-method arguments generic ;
+
+: make-default-method ( methods generic -- quot )
+    >r argument-count r> [ >r narray r> no-method ] 2curry ;
+
+: multi-dispatch-quot ( methods generic -- quot )
+    [ make-default-method ]
+    [ drop [ >r multi-predicate r> ] assoc-map reverse ]
+    2bi alist>quot ;
+
+! Generic words
+PREDICATE: generic < word
+    "multi-methods" word-prop >boolean ;
+
 : methods ( word -- alist )
     "multi-methods" word-prop >alist ;
 
-: make-method-def ( quot classes generic -- quot )
+: make-generic ( generic -- quot )
     [
-        swap [ declare ] curry %
-        "multi-combination" word-prop method-prologue %
-        %
+        [ methods prepare-methods % sort-methods ] keep
+        multi-dispatch-quot %
     ] [ ] make ;
 
-TUPLE: method word def classes generic loc ;
+: update-generic ( word -- )
+    dup make-generic define ;
 
+! Methods
 PREDICATE: method-body < word
-    "multi-method" word-prop >boolean ;
+    "multi-method-generic" word-prop >boolean ;
 
 M: method-body stack-effect
-    "multi-method" word-prop method-generic stack-effect ;
+    "multi-method-generic" word-prop stack-effect ;
 
 M: method-body crossref?
     drop t ;
 
-: method-word-name ( classes generic -- string )
+: method-word-name ( specializer generic -- string )
+    [ word-name % "-" % unparse % ] "" make ;
+
+: method-word-props ( specializer generic -- assoc )
     [
-        word-name %
-        "-(" % [ "," % ] [ word-name % ] interleave ")" %
-    ] "" make ;
-
-: <method-word> ( quot classes generic -- word )
-    #! We xref here because the "multi-method" word-prop isn't
-    #! set yet so crossref? yields f.
-    [ make-method-def ] 2keep
+        "multi-method-generic" set
+        "multi-method-specializer" set
+    ] H{ } make-assoc ;
+
+: <method> ( specializer generic -- word )
+    [ method-word-props ] 2keep
     method-word-name f <word>
-    dup rot define
-    dup xref ;
+    [ set-word-props ] keep ;
 
-: <method> ( quot classes generic -- method )
-    [ <method-word> ] 3keep f \ method construct-boa
-    dup method-word over "multi-method" set-word-prop ;
+: with-methods ( word quot -- )
+    over >r >r "multi-methods" word-prop
+    r> call r> update-generic ; inline
 
-TUPLE: no-method arguments generic ;
+: reveal-method ( method classes generic -- )
+    [ set-at ] with-methods ;
 
-: no-method ( argument-count generic -- * )
-    >r narray r> \ no-method construct-boa throw ; inline
+: method ( classes word -- method )
+    "multi-methods" word-prop at ;
 
-: argument-count ( methods -- n )
-    dup assoc-empty? [ drop 0 ] [
-        keys [ length ] map supremum
+: create-method ( classes generic -- method )
+    2dup method dup [
+        2nip
+    ] [
+        drop [ <method> dup ] 2keep reveal-method
     ] if ;
 
-: multi-dispatch-quot ( methods generic -- quot )
-    >r [
-        [
-            >r multi-predicate r> method-word 1quotation
-        ] assoc-map
-    ] keep argument-count
-    r> [ no-method ] 2curry
-    swap reverse alist>quot ;
-
-: congruify-methods ( alist -- alist' )
-    dup argument-count [
-        swap >r object pad-left [ \ f or ] map r>
-    ] curry assoc-map ;
-
-: sorted-methods ( alist -- alist' )
-    [ [ first ] bi@ classes< ] topological-sort ;
-
 : niceify-method [ dup \ f eq? [ drop f ] when ] map ;
 
 M: no-method error.
     "Type check error" print
     nl
-    "Generic word " write dup no-method-generic pprint
+    "Generic word " write dup generic>> pprint
     " does not have a method applicable to inputs:" print
-    dup no-method-arguments short.
+    dup arguments>> short.
     nl
     "Inputs have signature:" print
-    dup no-method-arguments [ class ] map niceify-method .
+    dup arguments>> [ class ] map niceify-method .
     nl
-    "Defined methods in topological order: " print
-    no-method-generic
-    methods congruify-methods sorted-methods keys
-    [ niceify-method ] map stack. ;
-
-TUPLE: standard-combination ;
-
-M: standard-combination method-prologue drop [ ] ;
-
-M: standard-combination generic-prologue drop [ ] ;
+    "Available methods: " print
+    generic>> methods canonicalize-specializers drop sort-methods
+    keys [ niceify-method ] map stack. ;
 
-: make-generic ( generic -- quot )
-    dup "multi-combination" word-prop generic-prologue swap
-    [ methods congruify-methods sorted-methods ] keep
-    multi-dispatch-quot append ;
-
-TUPLE: hook-combination var ;
-
-M: hook-combination method-prologue
-    drop [ drop ] ;
-
-M: hook-combination generic-prologue
-    hook-combination-var [ get ] curry ;
+: forget-method ( specializer generic -- )
+    [ delete-at ] with-methods ;
 
-: update-generic ( word -- )
-    dup make-generic define ;
+: method>spec ( method -- spec )
+    [ "multi-method-specializer" word-prop ]
+    [ "multi-method-generic" word-prop ] bi prefix ;
 
-: define-generic ( word combination -- )
-    over "multi-combination" word-prop over = [
-        2drop
+: define-generic ( word -- )
+    dup "multi-methods" word-prop [
+        drop
     ] [
-        dupd "multi-combination" set-word-prop
-        dup H{ } clone "multi-methods" set-word-prop
-        update-generic
+        [ H{ } clone "multi-methods" set-word-prop ]
+        [ update-generic ]
+        bi
     ] if ;
 
-: define-standard-generic ( word -- )
-    T{ standard-combination } define-generic ;
-
+! Syntax
 : GENERIC:
-    CREATE define-standard-generic ; parsing
-
-: define-hook-generic ( word var -- )
-    hook-combination construct-boa define-generic ;
-
-: HOOK:
-    CREATE scan-word define-hook-generic ; parsing
+    CREATE define-generic ; parsing
 
-: method ( classes word -- method )
-    "multi-methods" word-prop at ;
-
-: with-methods ( word quot -- )
-    over >r >r "multi-methods" word-prop
-    r> call r> update-generic ; inline
+: parse-method ( -- quot classes generic )
+    parse-definition [ 2 tail ] [ second ] [ first ] tri ;
 
-: define-method ( quot classes generic -- )
-    >r [ bootstrap-word ] map r>
-    [ <method> ] 2keep
-    [ set-at ] with-methods ;
+: create-method-in ( specializer generic -- method )
+    create-method dup save-location f set-word ;
 
-: forget-method ( classes generic -- )
-    [ delete-at ] with-methods ;
+: CREATE-METHOD
+    scan-word scan-object swap create-method-in ;
 
-: method>spec ( method -- spec )
-    dup method-classes swap method-generic prefix ;
+: (METHOD:) CREATE-METHOD parse-definition ;
 
-: parse-method ( -- quot classes generic )
-    parse-definition dup 2 tail over second rot first ;
-
-: METHOD:
-    location
-    >r parse-method [ define-method ] 2keep prefix r>
-    remember-definition ; parsing
+: METHOD: (METHOD:) define ; parsing
 
 ! For compatibility
 : M:
-    scan-word 1array scan-word parse-definition
-    -rot define-method ; parsing
+    scan-word 1array scan-word create-method-in
+    parse-definition
+    define ; parsing
 
 ! Definition protocol. We qualify core generics here
 USE: qualified
 QUALIFIED: syntax
 
-PREDICATE: generic < word
-    "multi-combination" word-prop >boolean ;
-
-PREDICATE: standard-generic < word
-    "multi-combination" word-prop standard-combination? ;
-
-PREDICATE: hook-generic < word
-    "multi-combination" word-prop hook-combination? ;
-
-syntax:M: standard-generic definer drop \ GENERIC: f ;
+syntax:M: generic definer drop \ GENERIC: f ;
 
-syntax:M: standard-generic definition drop f ;
-
-syntax:M: hook-generic definer drop \ HOOK: f ;
-
-syntax:M: hook-generic definition drop f ;
-
-syntax:M: hook-generic synopsis*
-    dup definer.
-    dup seeing-word
-    dup pprint-word
-    dup "multi-combination" word-prop
-    hook-combination-var pprint-word stack-effect. ;
+syntax:M: generic definition drop f ;
 
 PREDICATE: method-spec < array
     unclip generic? >r [ class? ] all? r> and ;
 
 syntax:M: method-spec where
-    dup unclip method [ method-loc ] [ second where ] ?if ;
+    dup unclip method [ ] [ first ] ?if where ;
 
 syntax:M: method-spec set-where
-    unclip method set-method-loc ;
+    unclip method set-where ;
 
 syntax:M: method-spec definer
-    drop \ METHOD: \ ; ;
+    unclip method definer ;
 
 syntax:M: method-spec definition
-    unclip method dup [ method-def ] when ;
+    unclip method definition ;
 
 syntax:M: method-spec synopsis*
-    dup definer.
-    unclip pprint* pprint* ;
+    unclip method synopsis* ;
 
 syntax:M: method-spec forget*
-    unclip forget-method ;
+    unclip method forget* ;
+
+syntax:M: method-body definer
+    drop \ METHOD: \ ; ;
+
+syntax:M: method-body synopsis*
+    dup definer.
+    [ "multi-method-generic" word-prop pprint-word ]
+    [ "multi-method-specializer" word-prop pprint* ] bi ;
diff --git a/extra/multi-methods/tests/canonicalize.factor b/extra/multi-methods/tests/canonicalize.factor
new file mode 100644 (file)
index 0000000..d5baf49
--- /dev/null
@@ -0,0 +1,66 @@
+IN: multi-methods.tests
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings ;
+
+[ { POSTPONE: f integer } ] [ { f integer } canonicalize-specializer-0 ] unit-test
+
+: setup-canon-test
+    0 args set
+    V{ } clone hooks set ;
+
+: canon-test-1
+    { integer { cpu x86 } sequence } canonicalize-specializer-1 ;
+
+[ { { -2 integer } { -1 sequence } { cpu x86 } } ] [
+    [
+        setup-canon-test
+        canon-test-1
+    ] with-scope
+] unit-test
+
+[ { { 0 integer } { 1 sequence } { 2 x86 } } ] [
+    [
+        setup-canon-test
+        canon-test-1
+        canonicalize-specializer-2
+    ] with-scope
+] unit-test
+
+[ { integer sequence x86 } ] [
+    [
+        setup-canon-test
+        canon-test-1
+        canonicalize-specializer-2
+        args get hooks get length + total set
+        canonicalize-specializer-3
+    ] with-scope
+] unit-test
+
+: example-1
+    {
+        { { { cpu x86 } { os linux } } "a" }
+        { { { cpu ppc } } "b" }
+        { { string { os windows } } "c" }
+    } ;
+
+[
+    {
+        { { object x86 linux } "a"  }
+        { { object ppc object } "b" }
+        { { string object windows } "c" }
+    }
+    V{ cpu os }
+] [
+    example-1 canonicalize-specializers
+] unit-test
+
+[
+    {
+        { { object x86 linux } [ drop drop "a" ] }
+        { { object ppc object } [ drop drop "b" ] }
+        { { string object windows } [ drop drop "c" ] }
+    }
+    [ \ cpu get \ os get ]
+] [
+    example-1 prepare-methods
+] unit-test
diff --git a/extra/multi-methods/tests/definitions.factor b/extra/multi-methods/tests/definitions.factor
new file mode 100644 (file)
index 0000000..c112a67
--- /dev/null
@@ -0,0 +1,32 @@
+IN: multi-methods.tests
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings words compiler.units quotations ;
+
+\ GENERIC: must-infer
+\ create-method-in must-infer
+
+DEFER: fake
+\ fake H{ } clone "multi-methods" set-word-prop
+
+[ "fake-{ }" ] [ { } \ fake method-word-name ] unit-test
+
+[ H{ { "multi-method-generic" fake } { "multi-method-specializer" { } } } ]
+[ { } \ fake method-word-props ] unit-test
+
+[ t ] [ { } \ fake <method> method-body? ] unit-test
+
+[
+    [ { } [ ] ] [ \ fake methods prepare-methods >r sort-methods r> ] unit-test
+
+    [ t ] [ { } \ fake multi-dispatch-quot callable? ] unit-test
+
+    [ t ] [ \ fake make-generic quotation? ] unit-test
+
+    [ ] [ \ fake update-generic ] unit-test
+
+    DEFER: testing
+
+    [ ] [ \ testing define-generic ] unit-test
+
+    [ t ] [ \ testing generic? ] unit-test
+] with-compilation-unit
diff --git a/extra/multi-methods/tests/legacy.factor b/extra/multi-methods/tests/legacy.factor
new file mode 100644 (file)
index 0000000..f4bd0a0
--- /dev/null
@@ -0,0 +1,10 @@
+IN: multi-methods.tests
+USING: math strings sequences tools.test ;
+
+GENERIC: legacy-test
+
+M: integer legacy-test sq ;
+M: string legacy-test " hey" append ;
+
+[ 25 ] [ 5 legacy-test ] unit-test
+[ "hello hey" ] [ "hello" legacy-test ] unit-test
diff --git a/extra/multi-methods/tests/syntax.factor b/extra/multi-methods/tests/syntax.factor
new file mode 100644 (file)
index 0000000..597a1ce
--- /dev/null
@@ -0,0 +1,64 @@
+IN: multi-methods.tests
+USING: multi-methods tools.test math sequences namespaces system
+kernel strings definitions prettyprint debugger arrays
+hashtables continuations classes assocs accessors ;
+
+GENERIC: first-test
+
+[ t ] [ \ first-test generic? ] unit-test
+
+MIXIN: thing
+
+SINGLETON: paper    INSTANCE: paper thing
+SINGLETON: scissors INSTANCE: scissors thing
+SINGLETON: rock     INSTANCE: rock thing
+
+GENERIC: beats?
+
+METHOD: beats? { paper scissors } t ;
+METHOD: beats? { scissors rock } t ;
+METHOD: beats? { rock paper } t ;
+METHOD: beats? { thing thing } f ;
+
+: play ( obj1 obj2 -- ? ) beats? 2nip ;
+
+[ { } 3 play ] must-fail
+[ t ] [ error get no-method? ] unit-test
+[ ] [ error get error. ] unit-test
+[ { { } 3 } ] [ error get arguments>> ] unit-test
+[ t ] [ paper scissors play ] unit-test
+[ f ] [ scissors paper play ] unit-test
+
+[ t ] [ { beats? paper scissors } method-spec? ] unit-test
+[ ] [ { beats? paper scissors } see ] unit-test
+
+SYMBOL: some-var
+
+GENERIC: hook-test
+
+METHOD: hook-test { array { some-var array } } reverse ;
+METHOD: hook-test { { some-var array } } class ;
+METHOD: hook-test { hashtable { some-var number } } assoc-size ;
+
+{ 1 2 3 } some-var set
+[ { f t t } ] [ { t t f } hook-test ] unit-test
+[ fixnum ] [ 3 hook-test ] unit-test
+5.0 some-var set
+[ 0 ] [ H{ } hook-test ] unit-test
+
+"error" some-var set
+[ H{ } hook-test ] must-fail
+[ t ] [ error get no-method? ] unit-test
+[ { H{ } "error" } ] [ error get arguments>> ] unit-test
+
+MIXIN: busted
+
+TUPLE: busted-1 ;
+TUPLE: busted-2 ; INSTANCE: busted-2 busted
+TUPLE: busted-3 ;
+
+GENERIC: busted-sort
+
+METHOD: busted-sort { busted-1 busted-2 } ;
+METHOD: busted-sort { busted-2 busted-3 } ;
+METHOD: busted-sort { busted busted } ;
diff --git a/extra/multi-methods/tests/topological-sort.factor b/extra/multi-methods/tests/topological-sort.factor
new file mode 100644 (file)
index 0000000..ed8bece
--- /dev/null
@@ -0,0 +1,18 @@
+IN: multi-methods.tests
+USING: kernel multi-methods tools.test math arrays sequences ;
+
+[ { 1 2 3 4 5 6 } ] [
+    { 6 4 5 1 3 2 } [ <=> ] topological-sort
+] unit-test
+
+[ -1 ] [
+    { fixnum array } { number sequence } classes<
+] unit-test
+
+[ 0 ] [
+    { number sequence } { number sequence } classes<
+] unit-test
+
+[ 1 ] [
+    { object object } { number sequence } classes<
+] unit-test
index b123fef2a3b8e3a99f23704eee3d21bac1ffcfe4..6a191f0e07ab35132f252c5f5672efcc083e839a 100644 (file)
 
 USING: kernel sequences assocs qualified circular ;
 
+USING: math multi-methods ;
+
 QUALIFIED: sequences
+QUALIFIED: assocs
 QUALIFIED: circular
 
 IN: newfx
 
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! Now, we can see a new world coming into view.
 ! A world in which there is the very real prospect of a new world order.
 !
 !    - George Herbert Walker Bush
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: at ( col key -- val )
+GENERIC: of ( key col -- val )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: grab ( col key -- col val )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: is ( col key val -- col )
+GENERIC: as ( col val key -- col )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: is-of ( key val col -- col )
+GENERIC: as-of ( val key col -- col )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: mutate-at ( col key val -- )
+GENERIC: mutate-as ( col val key -- )
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: at-mutate ( key val col -- )
+GENERIC: as-mutate ( val key col -- )
 
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! sequence
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: nth-at ( seq i -- val ) swap nth ;
-: nth-of ( i seq -- val )      nth ;
+METHOD: at { sequence number  } swap nth ;
+METHOD: of { number  sequence }      nth ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: nth-is ( seq   i val -- seq ) swap pick set-nth ;
-: is-nth ( seq val   i -- seq )      pick set-nth ;
+METHOD: grab { sequence number } dupd swap nth ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: nth-is-of (   i val seq -- seq ) dup >r swapd set-nth r> ;
-: is-nth-of ( val   i seq -- seq ) dup >r       set-nth r> ;
+METHOD: is { sequence number object  } swap pick set-nth ;
+METHOD: as { sequence object  number }      pick set-nth ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: mutate-nth    ( seq i val -- ) swap rot set-nth ;
-: mutate-nth-at ( seq val i -- )      rot set-nth ;
+METHOD: is-of { number object  sequence } dup >r swapd set-nth r> ;
+METHOD: as-of { object  number sequence } dup >r       set-nth r> ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: mutate-at { sequence number object  } swap rot set-nth ;
+METHOD: mutate-as { sequence object  number }      rot set-nth ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: mutate-nth-of    (   i val seq -- ) swapd set-nth ;
-: mutate-nth-at-of ( val   i seq -- )       set-nth ;
+METHOD: at-mutate { number object  sequence } swapd set-nth ;
+METHOD: as-mutate { object  number sequence }       set-nth ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: at-key ( tbl key -- val ) swap at ;
-: key-of ( key tbl -- val )      at ;
 
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! assoc
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: key-is ( tbl key val -- tbl ) swap pick set-at ;
-: is-key ( tbl val key -- tbl )      pick set-at ;
+METHOD: at { assoc object } swap assocs:at ;
+METHOD: of { object assoc }      assocs:at ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: mutate-key    ( tbl key val -- ) swap rot set-at ;
-: mutate-at-key ( tbl val key -- )      rot set-at ;
+METHOD: grab { assoc object } dupd swap assocs:at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: is { assoc object object } swap pick set-at ;
+METHOD: as { assoc object object }      pick set-at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: is-of { object object assoc } dup >r swapd set-at r> ;
+METHOD: as-of { object object assoc } dup >r       set-at r> ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+METHOD: mutate-at { assoc object object } swap rot set-at ;
+METHOD: mutate-as { assoc object object }      rot set-at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: mutate-key-of    ( key val tbl -- ) swapd set-at ;
-: mutate-at-key-of ( val key tbl -- )       set-at ;
+METHOD: at-mutate { object object assoc } swapd set-at ;
+METHOD: as-mutate { object object assoc }       set-at ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
index ca97eab3bc8b455696e18e681f57f9f758c3663c..59f5095aad5fe1e13c3cdee328db5e6bc9904a44 100644 (file)
-! Copyright (C) 2007 Chris Double.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: kernel alien alien.syntax combinators alien.c-types\r
-       strings sequences namespaces words math threads ;\r
-IN: odbc\r
-\r
-"odbc" "odbc32.dll" "stdcall" add-library\r
-\r
-LIBRARY: odbc\r
-\r
-TYPEDEF: void* usb_dev_handle*\r
-TYPEDEF: short SQLRETURN\r
-TYPEDEF: short SQLSMALLINT\r
-TYPEDEF: short* SQLSMALLINT*\r
-TYPEDEF: ushort SQLUSMALLINT\r
-TYPEDEF: uint* SQLUINTEGER*\r
-TYPEDEF: int SQLINTEGER\r
-TYPEDEF: char SQLCHAR\r
-TYPEDEF: char* SQLCHAR*\r
-TYPEDEF: void* SQLHANDLE\r
-TYPEDEF: void* SQLHANDLE*\r
-TYPEDEF: void* SQLHENV\r
-TYPEDEF: void* SQLHDBC\r
-TYPEDEF: void* SQLHSTMT\r
-TYPEDEF: void* SQLHWND\r
-TYPEDEF: void* SQLPOINTER\r
-\r
-: SQL-HANDLE-ENV  ( -- number ) 1 ; inline\r
-: SQL-HANDLE-DBC  ( -- number ) 2 ; inline\r
-: SQL-HANDLE-STMT ( -- number ) 3 ; inline\r
-: SQL-HANDLE-DESC ( -- number ) 4 ; inline\r
-\r
-: SQL-NULL-HANDLE ( -- alien ) f ; inline\r
-\r
-: SQL-ATTR-ODBC-VERSION ( -- number ) 200 ; inline\r
-\r
-: SQL-OV-ODBC2 ( -- number ) 2 <alien> ; inline\r
-: SQL-OV-ODBC3 ( -- number ) 3 <alien> ; inline\r
-\r
-: SQL-SUCCESS ( -- number ) 0 ; inline\r
-: SQL-SUCCESS-WITH-INFO ( -- number ) 1 ; inline\r
-: SQL-NO-DATA-FOUND ( -- number ) 100 ; inline\r
-\r
-: SQL-DRIVER-NOPROMPT ( -- number ) 0 ; inline\r
-: SQL-DRIVER-PROMPT ( -- number ) 2 ; inline\r
-\r
-: SQL-C-DEFAULT ( -- number ) 99 ; inline\r
-\r
-SYMBOL: SQL-CHAR\r
-SYMBOL: SQL-VARCHAR\r
-SYMBOL: SQL-LONGVARCHAR\r
-SYMBOL: SQL-WCHAR\r
-SYMBOL: SQL-WCHARVAR\r
-SYMBOL: SQL-WLONGCHARVAR\r
-SYMBOL: SQL-DECIMAL\r
-SYMBOL: SQL-SMALLINT\r
-SYMBOL: SQL-NUMERIC\r
-SYMBOL: SQL-INTEGER\r
-SYMBOL: SQL-REAL\r
-SYMBOL: SQL-FLOAT\r
-SYMBOL: SQL-DOUBLE\r
-SYMBOL: SQL-BIT\r
-SYMBOL: SQL-TINYINT\r
-SYMBOL: SQL-BIGINT\r
-SYMBOL: SQL-BINARY\r
-SYMBOL: SQL-VARBINARY\r
-SYMBOL: SQL-LONGVARBINARY\r
-SYMBOL: SQL-TYPE-DATE\r
-SYMBOL: SQL-TYPE-TIME\r
-SYMBOL: SQL-TYPE-TIMESTAMP\r
-SYMBOL: SQL-TYPE-UTCDATETIME\r
-SYMBOL: SQL-TYPE-UTCTIME\r
-SYMBOL: SQL-INTERVAL-MONTH\r
-SYMBOL: SQL-INTERVAL-YEAR\r
-SYMBOL: SQL-INTERVAL-YEAR-TO-MONTH\r
-SYMBOL: SQL-INTERVAL-DAY\r
-SYMBOL: SQL-INTERVAL-HOUR\r
-SYMBOL: SQL-INTERVAL-MINUTE\r
-SYMBOL: SQL-INTERVAL-SECOND\r
-SYMBOL: SQL-INTERVAL-DAY-TO-HOUR\r
-SYMBOL: SQL-INTERVAL-DAY-TO-MINUTE\r
-SYMBOL: SQL-INTERVAL-DAY-TO-SECOND\r
-SYMBOL: SQL-INTERVAL-HOUR-TO-MINUTE\r
-SYMBOL: SQL-INTERVAL-HOUR-TO-SECOND\r
-SYMBOL: SQL-INTERVAL-MINUTE-TO-SECOND\r
-SYMBOL: SQL-GUID\r
-SYMBOL: SQL-TYPE-UNKNOWN\r
-\r
-: convert-sql-type ( number -- symbol )\r
-  {\r
-    { [ dup 1 = ] [ drop SQL-CHAR ] }\r
-    { [ dup 12 = ] [ drop SQL-VARCHAR ] }\r
-    { [ dup -1 = ] [ drop SQL-LONGVARCHAR ] }\r
-    { [ dup -8 = ] [ drop SQL-WCHAR ] }\r
-    { [ dup -9 = ] [ drop SQL-WCHARVAR ] }\r
-    { [ dup -10 = ] [ drop SQL-WLONGCHARVAR ] }\r
-    { [ dup 3 = ] [ drop SQL-DECIMAL ] }\r
-    { [ dup 5 = ] [ drop SQL-SMALLINT ] }\r
-    { [ dup 2 = ] [ drop SQL-NUMERIC ] }\r
-    { [ dup 4 = ] [ drop SQL-INTEGER ] }\r
-    { [ dup 7 = ] [ drop SQL-REAL ] }\r
-    { [ dup 6 = ] [ drop SQL-FLOAT ] }\r
-    { [ dup 8 = ] [ drop SQL-DOUBLE ] }\r
-    { [ dup -7 = ] [ drop SQL-BIT ] }\r
-    { [ dup -6 = ] [ drop SQL-TINYINT ] }\r
-    { [ dup -5 = ] [ drop SQL-BIGINT ] }\r
-    { [ dup -2 = ] [ drop SQL-BINARY ] }\r
-    { [ dup -3 = ] [ drop SQL-VARBINARY ] }   \r
-    { [ dup -4 = ] [ drop SQL-LONGVARBINARY ] }\r
-    { [ dup 91 = ] [ drop SQL-TYPE-DATE ] }\r
-    { [ dup 92 = ] [ drop SQL-TYPE-TIME ] }\r
-    { [ dup 93 = ] [ drop SQL-TYPE-TIMESTAMP ] }\r
-    { [ t ] [ drop SQL-TYPE-UNKNOWN ] }\r
-  } cond ;\r
-\r
-: succeeded? ( n -- bool )\r
-  #! Did the call succeed (SQL-SUCCESS or SQL-SUCCESS-WITH-INFO)\r
-  {\r
-    { [ dup SQL-SUCCESS = ] [ drop t ] }\r
-    { [ dup SQL-SUCCESS-WITH-INFO = ] [ drop t ] }\r
-    { [ t ] [ drop f ] }\r
-  } cond ;  \r
-\r
-FUNCTION: SQLRETURN SQLAllocHandle ( SQLSMALLINT handleType, SQLHANDLE inputHandle, SQLHANDLE* outputHandlePtr ) ;\r
-FUNCTION: SQLRETURN SQLSetEnvAttr ( SQLHENV environmentHandle, SQLINTEGER attribute, SQLPOINTER valuePtr, SQLINTEGER stringLength ) ;\r
-FUNCTION: SQLRETURN SQLDriverConnect ( SQLHDBC connectionHandle, SQLHWND windowHandle, SQLCHAR* inConnectionString, SQLSMALLINT stringLength, SQLCHAR* outConnectionString, SQLSMALLINT bufferLength, SQLSMALLINT* stringLength2Ptr, SQLUSMALLINT driverCompletion ) ; \r
-FUNCTION: SQLRETURN SQLDisconnect ( SQLHDBC connectionHandle ) ;\r
-FUNCTION: SQLRETURN SQLPrepare ( SQLHSTMT statementHandle, SQLCHAR* statementText, SQLINTEGER length ) ;\r
-FUNCTION: SQLRETURN SQLExecute ( SQLHSTMT statementHandle ) ;\r
-FUNCTION: SQLRETURN SQLFreeHandle ( SQLSMALLINT handleType, SQLHANDLE handle ) ;\r
-FUNCTION: SQLRETURN SQLFetch ( SQLHSTMT statementHandle ) ;\r
-FUNCTION: SQLRETURN SQLNumResultCols ( SQLHSTMT statementHandle, SQLSMALLINT* columnCountPtr ) ;\r
-FUNCTION: SQLRETURN SQLDescribeCol ( SQLHSTMT statementHandle, SQLSMALLINT columnNumber, SQLCHAR* columnName, SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr, SQLUINTEGER* columnSizePtr, SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr ) ;\r
-FUNCTION: SQLRETURN SQLGetData ( SQLHSTMT statementHandle, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValuePtr, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_indPtr ) ;\r
-\r
-: alloc-handle ( type parent -- handle )\r
-  f <void*> [ SQLAllocHandle ] keep swap succeeded? [\r
-    *void*\r
-  ] [\r
-    drop f\r
-  ] if ;\r
-\r
-: alloc-env-handle ( -- handle )\r
-  SQL-HANDLE-ENV SQL-NULL-HANDLE alloc-handle ;\r
-\r
-: alloc-dbc-handle ( env -- handle )\r
-  SQL-HANDLE-DBC swap alloc-handle ;\r
-\r
-: alloc-stmt-handle ( dbc -- handle )\r
-  SQL-HANDLE-STMT swap alloc-handle ;\r
-\r
-: temp-string ( length -- byte-array length )\r
-  [ CHAR: \space  <string> string>char-alien ] keep ;\r
-\r
-: odbc-init ( -- env )\r
-  alloc-env-handle\r
-  [ \r
-    SQL-ATTR-ODBC-VERSION SQL-OV-ODBC3 0 SQLSetEnvAttr \r
-    succeeded? [ "odbc-init failed" throw ] unless\r
-  ] keep ;\r
-\r
-: odbc-connect ( env dsn -- dbc )\r
-   >r alloc-dbc-handle dup r> \r
-   f swap dup length 1024 temp-string 0 <short> SQL-DRIVER-NOPROMPT \r
-   SQLDriverConnect succeeded? [ "odbc-connect failed" throw ] unless ;\r
-\r
-: odbc-disconnect ( dbc -- )\r
-  SQLDisconnect succeeded? [ "odbc-disconnect failed" throw ] unless ;     \r
-\r
-: odbc-prepare ( dbc string -- statement )\r
-  >r alloc-stmt-handle dup r> dup length SQLPrepare succeeded? [ "odbc-prepare failed" throw ] unless ;\r
-\r
-: odbc-free-statement ( statement -- )\r
-  SQL-HANDLE-STMT swap SQLFreeHandle succeeded? [ "odbc-free-statement failed" throw ] unless ;\r
-\r
-: odbc-execute ( statement --  )\r
-  SQLExecute succeeded? [ "odbc-execute failed" throw ] unless ;\r
-\r
-: odbc-next-row ( statement -- bool )\r
-  SQLFetch succeeded? ;\r
-\r
-: odbc-number-of-columns ( statement -- number )\r
-  0 <short> [ SQLNumResultCols succeeded? ] keep swap [\r
-    *short\r
-  ] [\r
-    drop f\r
-  ] if ;\r
-\r
-TUPLE: column nullable digits size type name number ;\r
-\r
-C: <column> column\r
-\r
-: odbc-describe-column ( statement n -- column )\r
-  dup >r\r
-  1024 CHAR: \space <string> string>char-alien dup >r\r
-  1024 \r
-  0 <short>\r
-  0 <short> dup >r\r
-  0 <uint> dup >r\r
-  0 <short> dup >r\r
-  0 <short> dup >r\r
-  SQLDescribeCol succeeded? [\r
-    r> *short \r
-    r> *short \r
-    r> *uint \r
-    r> *short convert-sql-type \r
-    r> alien>char-string \r
-    r> <column> \r
-  ] [\r
-    r> drop r> drop r> drop r> drop r> drop r> drop\r
-    "odbc-describe-column failed" throw\r
-  ] if ;\r
-\r
-: dereference-type-pointer ( byte-array column -- object )\r
-  column-type {\r
-    { [ dup SQL-CHAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-VARCHAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-LONGVARCHAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-WCHAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-WCHARVAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-WLONGCHARVAR = ] [ drop alien>char-string ] }\r
-    { [ dup SQL-SMALLINT = ] [ drop *short ] }\r
-    { [ dup SQL-INTEGER = ] [ drop *long ] }\r
-    { [ dup SQL-REAL = ] [ drop *float ] }\r
-    { [ dup SQL-FLOAT = ] [ drop *double ] }\r
-    { [ dup SQL-DOUBLE = ] [ drop *double ] }\r
-    { [ dup SQL-TINYINT = ] [ drop *char  ] }\r
-    { [ dup SQL-BIGINT = ] [ drop *longlong ] }\r
-    { [ t ] [ nip [ "Unknown SQL Type: " % word-name % ] "" make ] }    \r
-  } cond ;\r
-\r
-TUPLE: field value column ;\r
-\r
-C: <field> field\r
-\r
-: odbc-get-field ( statement column -- field )\r
-  dup column? [ dupd odbc-describe-column ] unless dup >r column-number\r
-  SQL-C-DEFAULT\r
-  8192 CHAR: \space <string> string>char-alien dup >r\r
-  8192 \r
-  f SQLGetData succeeded? [\r
-    r> r> [ dereference-type-pointer ] keep <field>\r
-  ] [\r
-    r> drop r> [ \r
-      "SQLGetData Failed for Column: " % \r
-      dup column-name % \r
-      " of type: " % dup column-type word-name %\r
-    ] "" make swap <field>\r
-  ] if ;\r
-\r
-: odbc-get-row-fields ( statement -- seq )\r
-  [\r
-    dup odbc-number-of-columns [\r
-      1+ odbc-get-field field-value ,\r
-    ] with each \r
-  ] { } make ;\r
-\r
-: (odbc-get-all-rows) ( statement -- )\r
-  dup odbc-next-row [ dup odbc-get-row-fields , yield (odbc-get-all-rows) ] [ drop ] if ; \r
-    \r
-: odbc-get-all-rows ( statement -- seq )\r
-  [ (odbc-get-all-rows) ] { } make ;\r
-  \r
-: odbc-query ( string dsn -- result )\r
-  odbc-init swap odbc-connect [\r
-    swap odbc-prepare\r
-    dup odbc-execute\r
-    dup odbc-get-all-rows\r
-    swap odbc-free-statement\r
-  ] keep odbc-disconnect ;
\ No newline at end of file
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel alien alien.syntax combinators alien.c-types
+       strings sequences namespaces words math threads ;
+IN: odbc
+
+"odbc" "odbc32.dll" "stdcall" add-library
+
+LIBRARY: odbc
+
+TYPEDEF: void* usb_dev_handle*
+TYPEDEF: short SQLRETURN
+TYPEDEF: short SQLSMALLINT
+TYPEDEF: short* SQLSMALLINT*
+TYPEDEF: ushort SQLUSMALLINT
+TYPEDEF: uint* SQLUINTEGER*
+TYPEDEF: int SQLINTEGER
+TYPEDEF: char SQLCHAR
+TYPEDEF: char* SQLCHAR*
+TYPEDEF: void* SQLHANDLE
+TYPEDEF: void* SQLHANDLE*
+TYPEDEF: void* SQLHENV
+TYPEDEF: void* SQLHDBC
+TYPEDEF: void* SQLHSTMT
+TYPEDEF: void* SQLHWND
+TYPEDEF: void* SQLPOINTER
+
+: SQL-HANDLE-ENV  ( -- number ) 1 ; inline
+: SQL-HANDLE-DBC  ( -- number ) 2 ; inline
+: SQL-HANDLE-STMT ( -- number ) 3 ; inline
+: SQL-HANDLE-DESC ( -- number ) 4 ; inline
+
+: SQL-NULL-HANDLE ( -- alien ) f ; inline
+
+: SQL-ATTR-ODBC-VERSION ( -- number ) 200 ; inline
+
+: SQL-OV-ODBC2 ( -- number ) 2 <alien> ; inline
+: SQL-OV-ODBC3 ( -- number ) 3 <alien> ; inline
+
+: SQL-SUCCESS ( -- number ) 0 ; inline
+: SQL-SUCCESS-WITH-INFO ( -- number ) 1 ; inline
+: SQL-NO-DATA-FOUND ( -- number ) 100 ; inline
+
+: SQL-DRIVER-NOPROMPT ( -- number ) 0 ; inline
+: SQL-DRIVER-PROMPT ( -- number ) 2 ; inline
+
+: SQL-C-DEFAULT ( -- number ) 99 ; inline
+
+SYMBOL: SQL-CHAR
+SYMBOL: SQL-VARCHAR
+SYMBOL: SQL-LONGVARCHAR
+SYMBOL: SQL-WCHAR
+SYMBOL: SQL-WCHARVAR
+SYMBOL: SQL-WLONGCHARVAR
+SYMBOL: SQL-DECIMAL
+SYMBOL: SQL-SMALLINT
+SYMBOL: SQL-NUMERIC
+SYMBOL: SQL-INTEGER
+SYMBOL: SQL-REAL
+SYMBOL: SQL-FLOAT
+SYMBOL: SQL-DOUBLE
+SYMBOL: SQL-BIT
+SYMBOL: SQL-TINYINT
+SYMBOL: SQL-BIGINT
+SYMBOL: SQL-BINARY
+SYMBOL: SQL-VARBINARY
+SYMBOL: SQL-LONGVARBINARY
+SYMBOL: SQL-TYPE-DATE
+SYMBOL: SQL-TYPE-TIME
+SYMBOL: SQL-TYPE-TIMESTAMP
+SYMBOL: SQL-TYPE-UTCDATETIME
+SYMBOL: SQL-TYPE-UTCTIME
+SYMBOL: SQL-INTERVAL-MONTH
+SYMBOL: SQL-INTERVAL-YEAR
+SYMBOL: SQL-INTERVAL-YEAR-TO-MONTH
+SYMBOL: SQL-INTERVAL-DAY
+SYMBOL: SQL-INTERVAL-HOUR
+SYMBOL: SQL-INTERVAL-MINUTE
+SYMBOL: SQL-INTERVAL-SECOND
+SYMBOL: SQL-INTERVAL-DAY-TO-HOUR
+SYMBOL: SQL-INTERVAL-DAY-TO-MINUTE
+SYMBOL: SQL-INTERVAL-DAY-TO-SECOND
+SYMBOL: SQL-INTERVAL-HOUR-TO-MINUTE
+SYMBOL: SQL-INTERVAL-HOUR-TO-SECOND
+SYMBOL: SQL-INTERVAL-MINUTE-TO-SECOND
+SYMBOL: SQL-GUID
+SYMBOL: SQL-TYPE-UNKNOWN
+
+: convert-sql-type ( number -- symbol )
+  {
+    { 1 [ SQL-CHAR ] }
+    { 12  [ SQL-VARCHAR ] }
+    { -1  [ SQL-LONGVARCHAR ] }
+    { -8  [ SQL-WCHAR ] }
+    { -9  [ SQL-WCHARVAR ] }
+    { -10 [ SQL-WLONGCHARVAR ] }
+    { 3 [ SQL-DECIMAL ] }
+    { 5 [ SQL-SMALLINT ] }
+    { 2 [ SQL-NUMERIC ] }
+    { 4 [ SQL-INTEGER ] }
+    { 7 [ SQL-REAL ] }
+    { 6 [ SQL-FLOAT ] }
+    { 8 [ SQL-DOUBLE ] }
+    { -7 [ SQL-BIT ] }
+    { -6 [ SQL-TINYINT ] }
+    { -5 [ SQL-BIGINT ] }
+    { -2 [ SQL-BINARY ] }
+    { -3 [ SQL-VARBINARY ] }
+    { -4 [ SQL-LONGVARBINARY ] }
+    { 91 [ SQL-TYPE-DATE ] }
+    { 92 [ SQL-TYPE-TIME ] }
+    { 93 [ SQL-TYPE-TIMESTAMP ] }
+    [ drop SQL-TYPE-UNKNOWN ]
+  } case ;
+
+: succeeded? ( n -- bool )
+  #! Did the call succeed (SQL-SUCCESS or SQL-SUCCESS-WITH-INFO)
+  {
+    { SQL-SUCCESS [ t ] }
+    { SQL-SUCCESS-WITH-INFO [ t ] }
+    [ drop f ]
+  } case ;
+
+FUNCTION: SQLRETURN SQLAllocHandle ( SQLSMALLINT handleType, SQLHANDLE inputHandle, SQLHANDLE* outputHandlePtr ) ;
+FUNCTION: SQLRETURN SQLSetEnvAttr ( SQLHENV environmentHandle, SQLINTEGER attribute, SQLPOINTER valuePtr, SQLINTEGER stringLength ) ;
+FUNCTION: SQLRETURN SQLDriverConnect ( SQLHDBC connectionHandle, SQLHWND windowHandle, SQLCHAR* inConnectionString, SQLSMALLINT stringLength, SQLCHAR* outConnectionString, SQLSMALLINT bufferLength, SQLSMALLINT* stringLength2Ptr, SQLUSMALLINT driverCompletion ) ;
+FUNCTION: SQLRETURN SQLDisconnect ( SQLHDBC connectionHandle ) ;
+FUNCTION: SQLRETURN SQLPrepare ( SQLHSTMT statementHandle, SQLCHAR* statementText, SQLINTEGER length ) ;
+FUNCTION: SQLRETURN SQLExecute ( SQLHSTMT statementHandle ) ;
+FUNCTION: SQLRETURN SQLFreeHandle ( SQLSMALLINT handleType, SQLHANDLE handle ) ;
+FUNCTION: SQLRETURN SQLFetch ( SQLHSTMT statementHandle ) ;
+FUNCTION: SQLRETURN SQLNumResultCols ( SQLHSTMT statementHandle, SQLSMALLINT* columnCountPtr ) ;
+FUNCTION: SQLRETURN SQLDescribeCol ( SQLHSTMT statementHandle, SQLSMALLINT columnNumber, SQLCHAR* columnName, SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr, SQLUINTEGER* columnSizePtr, SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr ) ;
+FUNCTION: SQLRETURN SQLGetData ( SQLHSTMT statementHandle, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValuePtr, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_indPtr ) ;
+
+: alloc-handle ( type parent -- handle )
+  f <void*> [ SQLAllocHandle ] keep swap succeeded? [
+    *void*
+  ] [
+    drop f
+  ] if ;
+
+: alloc-env-handle ( -- handle )
+  SQL-HANDLE-ENV SQL-NULL-HANDLE alloc-handle ;
+
+: alloc-dbc-handle ( env -- handle )
+  SQL-HANDLE-DBC swap alloc-handle ;
+
+: alloc-stmt-handle ( dbc -- handle )
+  SQL-HANDLE-STMT swap alloc-handle ;
+
+: temp-string ( length -- byte-array length )
+  [ CHAR: \space  <string> string>char-alien ] keep ;
+
+: odbc-init ( -- env )
+  alloc-env-handle
+  [
+    SQL-ATTR-ODBC-VERSION SQL-OV-ODBC3 0 SQLSetEnvAttr
+    succeeded? [ "odbc-init failed" throw ] unless
+  ] keep ;
+
+: odbc-connect ( env dsn -- dbc )
+   >r alloc-dbc-handle dup r>
+   f swap dup length 1024 temp-string 0 <short> SQL-DRIVER-NOPROMPT
+   SQLDriverConnect succeeded? [ "odbc-connect failed" throw ] unless ;
+
+: odbc-disconnect ( dbc -- )
+  SQLDisconnect succeeded? [ "odbc-disconnect failed" throw ] unless ;
+
+: odbc-prepare ( dbc string -- statement )
+  >r alloc-stmt-handle dup r> dup length SQLPrepare succeeded? [ "odbc-prepare failed" throw ] unless ;
+
+: odbc-free-statement ( statement -- )
+  SQL-HANDLE-STMT swap SQLFreeHandle succeeded? [ "odbc-free-statement failed" throw ] unless ;
+
+: odbc-execute ( statement --  )
+  SQLExecute succeeded? [ "odbc-execute failed" throw ] unless ;
+
+: odbc-next-row ( statement -- bool )
+  SQLFetch succeeded? ;
+
+: odbc-number-of-columns ( statement -- number )
+  0 <short> [ SQLNumResultCols succeeded? ] keep swap [
+    *short
+  ] [
+    drop f
+  ] if ;
+
+TUPLE: column nullable digits size type name number ;
+
+C: <column> column
+
+: odbc-describe-column ( statement n -- column )
+  dup >r
+  1024 CHAR: \space <string> string>char-alien dup >r
+  1024
+  0 <short>
+  0 <short> dup >r
+  0 <uint> dup >r
+  0 <short> dup >r
+  0 <short> dup >r
+  SQLDescribeCol succeeded? [
+    r> *short
+    r> *short
+    r> *uint
+    r> *short convert-sql-type
+    r> alien>char-string
+    r> <column>
+  ] [
+    r> drop r> drop r> drop r> drop r> drop r> drop
+    "odbc-describe-column failed" throw
+  ] if ;
+
+: dereference-type-pointer ( byte-array column -- object )
+  column-type {
+    { SQL-CHAR [ alien>char-string ] }
+    { SQL-VARCHAR [ alien>char-string ] }
+    { SQL-LONGVARCHAR [ alien>char-string ] }
+    { SQL-WCHAR [ alien>char-string ] }
+    { SQL-WCHARVAR [ alien>char-string ] }
+    { SQL-WLONGCHARVAR [ alien>char-string ] }
+    { SQL-SMALLINT [ *short ] }
+    { SQL-INTEGER [ *long ] }
+    { SQL-REAL [ *float ] }
+    { SQL-FLOAT [ *double ] }
+    { SQL-DOUBLE [ *double ] }
+    { SQL-TINYINT [ *char  ] }
+    { SQL-BIGINT [ *longlong ] }
+    [ nip [ "Unknown SQL Type: " % word-name % ] "" make ]
+  } case ;
+
+TUPLE: field value column ;
+
+C: <field> field
+
+: odbc-get-field ( statement column -- field )
+  dup column? [ dupd odbc-describe-column ] unless dup >r column-number
+  SQL-C-DEFAULT
+  8192 CHAR: \space <string> string>char-alien dup >r
+  8192
+  f SQLGetData succeeded? [
+    r> r> [ dereference-type-pointer ] keep <field>
+  ] [
+    r> drop r> [
+      "SQLGetData Failed for Column: " %
+      dup column-name %
+      " of type: " % dup column-type word-name %
+    ] "" make swap <field>
+  ] if ;
+
+: odbc-get-row-fields ( statement -- seq )
+  [
+    dup odbc-number-of-columns [
+      1+ odbc-get-field field-value ,
+    ] with each
+  ] { } make ;
+
+: (odbc-get-all-rows) ( statement -- )
+  dup odbc-next-row [ dup odbc-get-row-fields , yield (odbc-get-all-rows) ] [ drop ] if ;
+
+: odbc-get-all-rows ( statement -- seq )
+  [ (odbc-get-all-rows) ] { } make ;
+
+: odbc-query ( string dsn -- result )
+  odbc-init swap odbc-connect [
+    swap odbc-prepare
+    dup odbc-execute
+    dup odbc-get-all-rows
+    swap odbc-free-statement
+  ] keep odbc-disconnect ;
index 2a685eccd1cd3a836f6094d6b76fab5a13b5b84b..d4ad11311fa2264f08bcfaee8c723da9234d884f 100755 (executable)
@@ -179,7 +179,7 @@ HINTS: yuv>rgb byte-array byte-array ;
     num-audio-buffers-processed {\r
         { [ over player-buffers length 1 = over zero? and ] [ drop append-new-audio-buffer t ] }\r
         { [ over player-buffers length 2 = over zero? and ] [ yield drop f ] }\r
-        { [ t ] [ fill-processed-audio-buffer t ] }\r
+        [ fill-processed-audio-buffer t ]\r
     } cond ;\r
 \r
 : start-audio ( player -- player bool )\r
@@ -284,7 +284,7 @@ HINTS: yuv>rgb byte-array byte-array ;
         decode-packet {\r
             { [ is-vorbis-packet? ] [ handle-initial-vorbis-header ] }\r
             { [ is-theora-packet? ] [ handle-initial-theora-header ] }\r
-            { [ t ]                 [ handle-initial-unknown-header ] }\r
+            [ handle-initial-unknown-header ]\r
         } cond t\r
     ] [\r
         f\r
index d27df4965db5bde233a99dd3a27b8f51f7a06294..6802d1537840edff93def27370d224a2ff12180c 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces sequences splitting opengl.gl
-continuations math.parser math arrays ;
+continuations math.parser math arrays sets ;
 IN: opengl.capabilities
 
 : (require-gl) ( thing require-quot make-error-quot -- )
@@ -15,7 +15,7 @@ IN: opengl.capabilities
 : has-gl-extensions? ( extensions -- ? )
     gl-extensions swap [ over member? ] all? nip ;
 : (make-gl-extensions-error) ( required-extensions -- )
-    gl-extensions swap seq-diff
+    gl-extensions swap diff
     "Required OpenGL extensions not supported:\n" %
     [ "    " % % "\n" % ] each ;
 : require-gl-extensions ( extensions -- )
index b8ac396c2f126355a52834ba15003f7b9442be22..739ad203a19825f39c951d14c4a447e67f7e0300 100644 (file)
@@ -1,15 +1,15 @@
 USING: alien alien.syntax combinators kernel parser sequences
 system words namespaces hashtables init math arrays assocs
 continuations ;
+IN: opengl.gl.extensions
 
 ERROR: unknown-gl-platform ;
 << {
     { [ os windows? ] [ "opengl.gl.windows" ] }
     { [ os macosx? ]  [ "opengl.gl.macosx" ] }
     { [ os unix? ] [ "opengl.gl.unix" ] }
-    { [ t ] [ unknown-gl-platform ] }
+    [ unknown-gl-platform ]
 } cond use+ >>
-IN: opengl.gl.extensions
 
 SYMBOL: +gl-function-number-counter+
 SYMBOL: +gl-function-pointers+
diff --git a/extra/opengl/gl/windows/tags.txt b/extra/opengl/gl/windows/tags.txt
new file mode 100644 (file)
index 0000000..8e1a559
--- /dev/null
@@ -0,0 +1 @@
+windows
index 36d24e13002210cec85eff3152a967f64aa1b41b..ab9ae38ac1ab7a284b3260b2124af6b8514af874 100755 (executable)
@@ -159,7 +159,7 @@ MACRO: set-draw-buffers ( buffers -- )
 TUPLE: sprite loc dim dim2 dlist texture ;
 
 : <sprite> ( loc dim dim2 -- sprite )
-    f f sprite construct-boa ;
+    f f sprite boa ;
 
 : sprite-size2 sprite-dim2 first2 ;
 
index 1f5453798d283441c5741a65817c5622857abc85..3ae0c94b126a9c3d02a6bd38a9c6aa5e4c14739b 100755 (executable)
@@ -19,7 +19,7 @@ M: comment pprint*
     swap comment-node present-text ;
 
 : comment, ( ? node text -- )
-    rot [ \ comment construct-boa , ] [ 2drop ] if ;
+    rot [ \ comment boa , ] [ 2drop ] if ;
 
 : values% ( prefix values -- )
     swap [
@@ -149,7 +149,7 @@ SYMBOL: node-count
                     { [ dup "intrinsics" word-prop over "if-intrinsics" word-prop or ] [ intrinsics-called ] }
                     { [ dup generic? ] [ generics-called ] }
                     { [ dup method-body? ] [ methods-called ] }
-                    { [ t ] [ words-called ] }
+                    [ words-called ]
                 } cond 1 -rot get at+
             ] [
                 drop
index a30ce648542d6bc95c7b21518bffcaf02f9c3c72..44b746f8ce792f78c86e7f5dd5bded43e0d3194c 100644 (file)
@@ -35,20 +35,20 @@ C: <connection> connection
 
 : check-result ( result -- )
     {
-        { [ dup OCI_SUCCESS = ] [ drop ] }
-        { [ dup OCI_ERROR = ] [ err get get-oci-error ] }
-        { [ dup OCI_INVALID_HANDLE = ] [ "invalid handle" throw ] }
-        { [ t ] [ "operation failed" throw ] }
-    } cond ;
+        { OCI_SUCCESS [ ] }
+        { OCI_ERROR [ err get get-oci-error ] }
+        { OCI_INVALID_HANDLE [ "invalid handle" throw ] }
+        [ "operation failed" throw ]
+    } case ;
 
 : check-status ( status -- bool )
     {
-        { [ dup OCI_SUCCESS = ] [ drop t ] }
-        { [ dup OCI_ERROR = ] [ err get get-oci-error ] }
-        { [ dup OCI_INVALID_HANDLE = ] [ "invalid handle" throw ] }
-        { [ dup OCI_NO_DATA = ] [ drop f ] }
-        { [ t ] [ "operation failed" throw ] }
-    } cond ;
+        { OCI_SUCCESS [ t ] }
+        { OCI_ERROR [ err get get-oci-error ] }
+        { OCI_INVALID_HANDLE [ "invalid handle" throw ] }
+        { OCI_NO_DATA [ f ] }
+        [ "operation failed" throw ]
+    } case ;
 
 ! =========================================================
 ! Initialization and handle-allocation routines
@@ -153,19 +153,19 @@ C: <connection> connection
     >r stm get err get r> dup length swap malloc-char-string swap
     OCI_NTV_SYNTAX OCI_DEFAULT OCIStmtPrepare check-result ;
 
-: calculate-size ( type -- size object )
+: calculate-size ( type -- size )
     {
-        { [ dup SQLT_INT = ] [ "int" heap-size ] }
-        { [ dup SQLT_FLT = ] [ "float" heap-size ] }
-        { [ dup SQLT_CHR = ] [ "char" heap-size ] }
-        { [ dup SQLT_NUM = ] [ "int" heap-size 10 * ] }
-        { [ dup SQLT_STR = ] [ 64 ] }
-        { [ dup SQLT_ODT = ] [ 256 ] }
-    } cond ;
+        { SQLT_INT [ "int" heap-size ] }
+        { SQLT_FLT [ "float" heap-size ] }
+        { SQLT_CHR [ "char" heap-size ] }
+        { SQLT_NUM [ "int" heap-size 10 * ] }
+        { SQLT_STR [ 64 ] }
+        { SQLT_ODT [ 256 ] }
+    } case ;
 
 : define-by-position ( position type -- )
     >r >r stm get f <void*> err get
-    r> r> calculate-size swap >r [ "char" malloc-array dup buf set ] keep 1+
+    r> r> dup calculate-size >r [ "char" malloc-array dup buf set ] keep 1+
     r> f f f OCI_DEFAULT OCIDefineByPos check-result ;
 
 : execute-statement ( -- bool )
index d8fccfb8f9f5b5050d276997187b07564f290956..40620295c6d344b3c86d0108636ee880aef68794 100755 (executable)
@@ -113,7 +113,7 @@ M: fail-parser parse ( input parser -- list )
 TUPLE: ensure-parser test ;
 
 : ensure ( parser -- ensure )
-    ensure-parser construct-boa ;
+    ensure-parser boa ;
 
 M: ensure-parser parse ( input parser -- list )
     2dup ensure-parser-test parse nil?
@@ -122,7 +122,7 @@ M: ensure-parser parse ( input parser -- list )
 TUPLE: ensure-not-parser test ;
 
 : ensure-not ( parser -- ensure )
-    ensure-not-parser construct-boa ;
+    ensure-not-parser boa ;
 
 M: ensure-not-parser parse ( input parser -- list )
     2dup ensure-not-parser-test parse nil?
@@ -135,10 +135,10 @@ TUPLE: and-parser parsers ;
         >r and-parser-parsers r> suffix
     ] [
         2array
-    ] if and-parser construct-boa ;
+    ] if and-parser boa ;
 
 : <and-parser> ( parsers -- parser )
-    dup length 1 = [ first ] [ and-parser construct-boa ] if ;
+    dup length 1 = [ first ] [ and-parser boa ] if ;
 
 : and-parser-parse ( list p1  -- list )
     swap [
@@ -161,7 +161,7 @@ M: and-parser parse ( input parser -- list )
 TUPLE: or-parser parsers ;
 
 : <or-parser> ( parsers -- parser )
-    dup length 1 = [ first ] [ or-parser construct-boa ] if ;
+    dup length 1 = [ first ] [ or-parser boa ] if ;
 
 : <|> ( parser1 parser2 -- parser )
     2array <or-parser> ;
@@ -265,7 +265,7 @@ LAZY: <?> ( parser -- parser )
 TUPLE: only-first-parser p1 ;
 
 LAZY: only-first ( parser -- parser )
-    only-first-parser construct-boa ;
+    only-first-parser boa ;
 
 M: only-first-parser parse ( input parser -- list )
     #! Transform a parser into a parser that only yields
index 0879ecda49f93acf9a2454245643925c95a1acdc..0292a88ad9e24d11614eeb7e5529364139139d45 100644 (file)
@@ -295,3 +295,5 @@ main = Primary
 { V{ V{ V{ "x" "[" "i" "]" } "[" "j" "]" } "." "y" } } [
   "x[i][j].y" primary parse-result-ast
 ] unit-test
+
+'ebnf' compile must-infer
index e5787e6cf88af1d0f09abd975cb0f0c2d3cf66ab..8bf0475da54d4b3098040e0eed905fa4d6f6b388 100644 (file)
@@ -318,11 +318,11 @@ M: object build-locals ( code ast -- )
    \r
 M: ebnf-action (transform) ( ast -- parser )\r
   [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals \r
-  string-lines [ parse-lines ] with-compilation-unit action ;\r
+  string-lines parse-lines action ;\r
 \r
 M: ebnf-semantic (transform) ( ast -- parser )\r
   [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals \r
-  string-lines [ parse-lines ] with-compilation-unit semantic ;\r
+  string-lines parse-lines semantic ;\r
 \r
 M: ebnf-var (transform) ( ast -- parser )\r
   parser>> (transform) ;\r
@@ -361,7 +361,11 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   [ compiled-parse ] curry [ with-scope ] curry ;\r
 \r
 : replace-escapes ( string -- string )\r
-  "\\t" token [ drop "\t" ] action  "\\n" token [ drop "\n" ] action 2choice replace ;\r
+  [\r
+    "\\t" token [ drop "\t" ] action ,\r
+    "\\n" token [ drop "\n" ] action ,\r
+    "\\r" token [ drop "\r" ] action ,\r
+  ] choice* replace ;\r
 \r
 : [EBNF "EBNF]" parse-multiline-string replace-escapes ebnf>quot nip parsed ; parsing\r
 \r
index 3bbb61b8466e63bb9b41488ecb847fc5b9b99c12..da7f678f2d76e13f85731c23529597e0bd547556 100755 (executable)
@@ -20,7 +20,7 @@ M: just-parser (compile) ( parser -- quot )
   just-parser-p1 compiled-parser just-pattern curry ;
 
 MEMO: just ( parser -- parser )
-  just-parser construct-boa init-parser ;
+  just-parser boa init-parser ;
 
 : 1token ( ch -- parser ) 1string token ;
 
index 3b1d408ae2cb9cb134272c27d0236f8acff66919..858d062c68380d02b1f8f4c48f82a3ddb19a52b3 100755 (executable)
@@ -21,7 +21,7 @@ C: <parser> parser
 SYMBOL: ignore 
 
 : <parse-result> ( remaining ast -- parse-result )
-  parse-result construct-boa ;
+  parse-result boa ;
 
 SYMBOL: packrat
 SYMBOL: pos
@@ -30,6 +30,9 @@ SYMBOL: fail
 SYMBOL: lrstack
 SYMBOL: heads
 
+: failed? ( obj -- ? )
+  fail = ;
+
 : delegates ( -- cache )
   \ delegates get-global [ H{ } clone dup \ delegates set-global ] unless* ;
 
@@ -66,21 +69,18 @@ C: <head> peg-head
   #! that maps the position to the parser result.
   id>> packrat get [ drop H{ } clone ] cache ;
 
+: process-rule-result ( p result -- result )
+  [
+    nip [ ast>> ] [ remaining>> ] bi input-from pos set    
+  ] [ 
+    pos set fail
+  ] if* ; 
+
 : eval-rule ( rule -- ast )
   #! Evaluate a rule, return an ast resulting from it.
   #! Return fail if the rule failed. The rule has
   #! stack effect ( input -- parse-result )
-  pos get swap 
-  execute 
-!  drop f f <parse-result>
-  [
-    nip
-    [ ast>> ] [ remaining>> ] bi
-    input-from pos set    
-  ] [ 
-    pos set   
-    fail
-  ] if* ; inline
+  pos get swap execute process-rule-result ; inline
 
 : memo ( pos rule -- memo-entry )
   #! Return the result from the memo cache. 
@@ -90,23 +90,31 @@ C: <head> peg-head
   #! Store an entry in the cache
   rule-parser input-cache set-at ;
 
-:: (grow-lr) ( r p m h -- )
-  p pos set
-  h involved-set>> clone h (>>eval-set)
-  r eval-rule
-  dup fail = pos get m pos>> <= or [
-    drop
+: update-m ( ast m -- )
+  swap >>ans pos get >>pos drop ;
+
+: stop-growth? ( ast m -- ? )
+  [ failed? pos get ] dip 
+  pos>> <= or ;
+
+: setup-growth ( h p -- )
+  pos set dup involved-set>> clone >>eval-set drop ;
+
+: (grow-lr) ( h p r m -- )
+  >r >r [ setup-growth ] 2keep r> r>
+  >r dup eval-rule r> swap
+  dup pick stop-growth? [
+    4drop drop
   ] [
-    m (>>ans)
-    pos get m (>>pos)
-    r p m h (grow-lr)
+    over update-m
+    (grow-lr)
   ] if ; inline
  
-:: grow-lr ( r p m h -- ast )
-  h p heads get set-at
-  r p m h (grow-lr) 
-  p heads get delete-at
-  m pos>> pos set m ans>>
+: grow-lr ( h p r m -- ast )
+  >r >r [ heads get set-at ] 2keep r> r>
+  pick over >r >r (grow-lr) r> r>
+  swap heads get delete-at
+  dup pos>> pos set ans>>
   ; inline
 
 :: (setup-lr) ( r l s -- )
@@ -128,10 +136,10 @@ C: <head> peg-head
         |
     h rule>> r eq? [
       m ans>> seed>> m (>>ans)
-      m ans>> fail = [
+      m ans>> failed? [
         fail
       ] [
-        r p m h grow-lr
+        h p r m grow-lr
       ] if
     ] [
       m ans>> seed>>
@@ -150,8 +158,7 @@ C: <head> peg-head
         r h eval-set>> member? [
           h [ r swap remove ] change-eval-set drop
           r eval-rule
-          m (>>ans)
-          pos get m (>>pos)
+          m update-m
           m
         ] [ 
           m
@@ -207,20 +214,18 @@ C: <head> peg-head
 
 GENERIC: (compile) ( parser -- quot )
 
+: execute-parser ( word -- result )
+  pos get apply-rule dup failed? [ 
+    drop f 
+  ] [
+    input-slice swap <parse-result>
+  ] if ; inline
 
-:: parser-body ( parser -- quot )
+: parser-body ( parser -- quot )
   #! Return the body of the word that is the compiled version
   #! of the parser.
-  [let* | rule [ gensym dup parser (compile) 0 1 <effect> define-declared dup parser "peg" set-word-prop ] 
-        |
-    [
-      rule pos get apply-rule dup fail = [ 
-        drop f 
-      ] [
-        input-slice swap <parse-result>
-      ] if
-    ] 
-  ] ;
+  gensym 2dup swap (compile) 0 1 <effect> define-declared swap dupd "peg" set-word-prop
+  [ execute-parser ] curry ;
 
 : compiled-parser ( parser -- word )
   #! Look to see if the given parser has been compiled.
@@ -235,8 +240,21 @@ GENERIC: (compile) ( parser -- quot )
     gensym tuck >>compiled 2dup parser-body 0 1 <effect> define-declared dupd "peg" set-word-prop
   ] if* ;
 
+SYMBOL: delayed
+
+: fixup-delayed ( -- )
+  #! Work through all delayed parsers and recompile their
+  #! words to have the correct bodies.
+  delayed get [
+    call compiled-parser 1quotation 0 1 <effect> define-declared
+  ] assoc-each ;
+
 : compile ( parser -- word )
-  [ compiled-parser ] with-compilation-unit ;
+  [
+    H{ } clone delayed [ 
+      compiled-parser fixup-delayed 
+    ] with-variable
+  ] with-compilation-unit ;
 
 : compiled-parse ( state word -- result )
   swap [ execute ] with-packrat ; inline 
@@ -446,7 +464,7 @@ M: delay-parser (compile) ( parser -- quot )
   #! For efficiency we memoize the quotation.
   #! This way it is run only once and the 
   #! parser constructed once at run time.
-  quot>> '[ @ compile ] { } { "word" } <effect> memoize-quot '[ @ execute ] ; 
+  quot>> gensym [ delayed get set-at ] keep 1quotation ; 
 
 TUPLE: box-parser quot ;
 
@@ -463,16 +481,16 @@ M: box-parser (compile) ( parser -- quot )
 PRIVATE>
 
 : token ( string -- parser )
-  token-parser construct-boa init-parser ;      
+  token-parser boa init-parser ;      
 
 : satisfy ( quot -- parser )
-  satisfy-parser construct-boa init-parser ;
+  satisfy-parser boa init-parser ;
 
 : range ( min max -- parser )
-  range-parser construct-boa init-parser ;
+  range-parser boa init-parser ;
 
 : seq ( seq -- parser )
-  seq-parser construct-boa init-parser ;
+  seq-parser boa init-parser ;
 
 : 2seq ( parser1 parser2 -- parser )
   2array seq ;
@@ -487,7 +505,7 @@ PRIVATE>
   { } make seq ; inline 
 
 : choice ( seq -- parser )
-  choice-parser construct-boa init-parser ;
+  choice-parser boa init-parser ;
 
 : 2choice ( parser1 parser2 -- parser )
   2array choice ;
@@ -502,34 +520,34 @@ PRIVATE>
   { } make choice ; inline 
 
 : repeat0 ( parser -- parser )
-  repeat0-parser construct-boa init-parser ;
+  repeat0-parser boa init-parser ;
 
 : repeat1 ( parser -- parser )
-  repeat1-parser construct-boa init-parser ;
+  repeat1-parser boa init-parser ;
 
 : optional ( parser -- parser )
-  optional-parser construct-boa init-parser ;
+  optional-parser boa init-parser ;
 
 : semantic ( parser quot -- parser )
-  semantic-parser construct-boa init-parser ;
+  semantic-parser boa init-parser ;
 
 : ensure ( parser -- parser )
-  ensure-parser construct-boa init-parser ;
+  ensure-parser boa init-parser ;
 
 : ensure-not ( parser -- parser )
-  ensure-not-parser construct-boa init-parser ;
+  ensure-not-parser boa init-parser ;
 
 : action ( parser quot -- parser )
-  action-parser construct-boa init-parser ;
+  action-parser boa init-parser ;
 
 : sp ( parser -- parser )
-  sp-parser construct-boa init-parser ;
+  sp-parser boa init-parser ;
 
 : hide ( parser -- parser )
   [ drop ignore ] action ;
 
 : delay ( quot -- parser )
-  delay-parser construct-boa init-parser ;
+  delay-parser boa init-parser ;
 
 : box ( quot -- parser )
   #! because a box has its quotation run at compile time
@@ -543,7 +561,7 @@ PRIVATE>
   #! parse. The action adds an indirection with a parser type
   #! that gets memoized and fixes this. Need to rethink how
   #! to fix boxes so this isn't needed...
-  box-parser construct-boa next-id f <parser> over set-delegate [ ] action ;
+  box-parser boa next-id f <parser> over set-delegate [ ] action ;
 
 : PEG:
   (:) [
index fec3163e2f484077f60715bb35894191460ad557..81820e0152801d685c89bbe8353f5468049c113e 100644 (file)
@@ -60,7 +60,7 @@ USING: kernel math parser sequences combinators splitting ;
         { [ 1 over consonant-end? not ] [ drop f ] }
         { [ 2 over consonant-end? ] [ drop f ] }
         { [ 3 over consonant-end? not ] [ drop f ] }
-        { [ t ] [ "wxy" last-is? not ] }
+        [ "wxy" last-is? not ]
     } cond ;
 
 : r ( str oldsuffix newsuffix -- str )
@@ -75,7 +75,7 @@ USING: kernel math parser sequences combinators splitting ;
             { [ "ies" ?tail ] [ "i" append ] }
             { [ dup "ss" tail? ] [ ] }
             { [ "s" ?tail ] [ ] }
-            { [ t ] [ ] }
+            [ ]
         } cond
     ] when ;
 
@@ -114,11 +114,11 @@ USING: kernel math parser sequences combinators splitting ;
                 {
                     { [ "ed" ?tail ] [ -ed ] }
                     { [ "ing" ?tail ] [ -ing ] }
-                    { [ t ] [ f ] }
+                    [ f ]
                 } cond
             ] [ -ed/ing ]
         }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : step1c ( str -- newstr )
@@ -149,7 +149,7 @@ USING: kernel math parser sequences combinators splitting ;
         { [ "iviti"   ?tail ] [ "iviti"   "ive"  r ] }
         { [ "biliti"  ?tail ] [ "biliti"  "ble"  r ] }
         { [ "logi"    ?tail ] [ "logi"    "log"  r ] }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : step3 ( str -- newstr )
@@ -161,7 +161,7 @@ USING: kernel math parser sequences combinators splitting ;
         { [ "ical"  ?tail ] [ "ical"  "ic" r ] }
         { [ "ful"   ?tail ] [ "ful"   ""   r ] }
         { [ "ness"  ?tail ] [ "ness"  ""   r ] }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : -ion ( str -- newstr )
@@ -192,7 +192,7 @@ USING: kernel math parser sequences combinators splitting ;
         { [ "ous"   ?tail ] [ ] }
         { [ "ive"   ?tail ] [ ] }
         { [ "ize"   ?tail ] [ ] }
-        { [ t ] [ ] }
+        [ ]
     } cond dup consonant-seq 1 > [ nip ] [ drop ] if ;
 
 : remove-e? ( str -- ? )
@@ -210,7 +210,7 @@ USING: kernel math parser sequences combinators splitting ;
         { [ dup peek CHAR: l = not ] [ ] }
         { [ dup length 1- over double-consonant? not ] [ ] }
         { [ dup consonant-seq 1 > ] [ butlast ] }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : step5 ( str -- newstr ) remove-e ll->l ;
index 8b78c43f00de59d6bee18a6a03c26ffafd9c3f1a..bac3f8ac6d19b9793047ff567d39bade985b9242 100644 (file)
@@ -18,7 +18,7 @@ TUPLE: processing-gadget button-down button-up key-down key-up ;
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : <processing-gadget> ( -- gadget )
-  processing-gadget construct-empty
+  processing-gadget new
     <frame-buffer> set-gadget-delegate ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/extra/processing/gallery/bubble-chamber/bubble-chamber-docs.factor b/extra/processing/gallery/bubble-chamber/bubble-chamber-docs.factor
deleted file mode 100644 (file)
index 21a845e..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-
-USING: help.syntax help.markup ;
-
-IN: processing.gallery.bubble-chamber
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-HELP: muon
-
-  { $class-description
-    "The muon is a colorful particle with an entangled friend."
-    "It draws both itself and its horizontally symmetric partner."
-    "A high range of speed and almost no speed decay allow the"
-    "muon to reach the extents of the window, often forming rings"
-    "where theta has decayed but speed remains stable. The result"
-    "is color almost everywhere in the general direction of collision,"
-    "stabilized into fuzzy rings." } ;
-
-HELP: quark
-
-  { $class-description
-    "The quark draws as a translucent black. Their large numbers"
-    "create fields of blackness overwritten only by the glowing shadows of "
-    "Hadrons. "
-    "quarks are allowed to accelerate away with speed decay values above 1.0. "
-    "Each quark has an entangled friend. Both particles are drawn identically,"
-    "mirrored along the y-axis." } ;
-
-HELP: hadron
-
-  { $class-description
-    "Hadrons collide from totally random directions. "
-    "Those hadrons that do not exit the drawing area, "
-    "tend to stabilize into perfect circular orbits. "
-    "Each hadron draws with a slight glowing emboss. "
-    "The hadron itself is not drawn." } ;
-
-HELP: axion
-
-  { $class-description
-    "The axion particle draws a bold black path. Axions exist "
-    "in a slightly higher dimension and as such are drawn with "
-    "elevated embossed shadows. Axions are quick to stabilize "
-    "and fall into single pixel orbits axions automatically "
-    "recollide themselves after stabilizing." } ;
-
-{ muon quark hadron axion } related-words
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ARTICLE: "bubble-chamber" "Bubble Chamber"
-
-  { $subsection "bubble-chamber-introduction" }
-  { $subsection "bubble-chamber-particles" }
-  { $subsection "bubble-chamber-author" }
-  { $subsection "bubble-chamber-running" } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ARTICLE: "bubble-chamber-introduction" "Introduction"
-
-"The Bubble Chamber is a generative painting system of imaginary "
-"colliding particles. A single super-massive collision produces a "
-"discrete universe of four particle types. Particles draw their "
-"positions over time as pixel exposures. " ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ARTICLE: "bubble-chamber-particles" "Particles"
-
-"Four types of particles exist. The behavior and graphic appearance of "
-"each particle type is unique."
-
-  { $subsection muon }
-  { $subsection quark }
-  { $subsection hadron }
-  { $subsection axion } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ARTICLE: "bubble-chamber-author" "Author"
-
-  "Bubble Chamber was created by Jared Tarbell. "
-  "It was originally implemented in Processing. "
-  "It was ported to Factor by Eduardo Cavazos. "
-  "The original work is on display here: "
-  { $url
-  "http://www.complexification.net/gallery/machines/bubblechamber/" } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ARTICLE: "bubble-chamber-running" "How to use"
-
-  "After you run the vocabulary, a window will appear. Click the "
-  "mouse in a random area to fire 11 particles of each type. "
-  "Another way to fire particles is to press the "
-  "spacebar. This fires all the particles." ;
\ No newline at end of file
diff --git a/extra/processing/gallery/bubble-chamber/bubble-chamber.factor b/extra/processing/gallery/bubble-chamber/bubble-chamber.factor
deleted file mode 100644 (file)
index 2efa04e..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-
-USING: kernel namespaces sequences combinators arrays threads
-
-       math
-       math.libm
-       math.vectors
-       math.ranges
-       math.constants
-       math.functions
-       math.points
-
-       ui
-       ui.gadgets
-
-       random accessors multi-methods
-       combinators.cleave       
-       vars locals
-
-       newfx
-
-       processing
-       processing.gadget
-       processing.color ;
-
-IN: processing.gallery.bubble-chamber
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: move-by ( obj delta -- obj ) over pos>> v+ >>pos ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: dim ( -- dim ) 1000 ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: collision-theta
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: boom
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VARS: particles muons quarks hadrons axions ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: good-colors ( -- seq )
-  {
-    T{ rgba f 0.23 0.14 0.17 1 }
-    T{ rgba f 0.23 0.14 0.15 1 }
-    T{ rgba f 0.21 0.14 0.15 1 }
-    T{ rgba f 0.51 0.39 0.33 1 }
-    T{ rgba f 0.49 0.33 0.20 1 }
-    T{ rgba f 0.55 0.45 0.32 1 }
-    T{ rgba f 0.69 0.63 0.51 1 }
-    T{ rgba f 0.64 0.39 0.18 1 }
-    T{ rgba f 0.73 0.42 0.20 1 }
-    T{ rgba f 0.71 0.45 0.29 1 }
-    T{ rgba f 0.79 0.45 0.22 1 }
-    T{ rgba f 0.82 0.56 0.34 1 }
-    T{ rgba f 0.88 0.72 0.49 1 }
-    T{ rgba f 0.85 0.69 0.40 1 }
-    T{ rgba f 0.96 0.92 0.75 1 }
-    T{ rgba f 0.99 0.98 0.87 1 }
-    T{ rgba f 0.85 0.82 0.69 1 }
-    T{ rgba f 0.99 0.98 0.87 1 }
-    T{ rgba f 0.82 0.82 0.79 1 }
-    T{ rgba f 0.65 0.69 0.67 1 }
-    T{ rgba f 0.53 0.60 0.55 1 }
-    T{ rgba f 0.57 0.53 0.68 1 }
-    T{ rgba f 0.47 0.42 0.56 1 }
-  } ;
-
-: good-color ( i -- color ) good-colors nth-of ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: x ( particle -- x ) pos>> first  ;
-: y ( particle -- x ) pos>> second ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: out-of-bounds? ( particle -- particle ? )
-  dup
-  { [ x dim neg < ] [ x dim 2 * > ] [ y dim neg < ] [ y dim 2 * > ] } cleave
-  or or or ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: particle pos vel speed speed-d theta theta-d theta-dd myc mya ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: initialize-particle ( particle -- particle )
-
-  0 0 {2} >>pos
-  0 0 {2} >>vel
-
-  0 >>speed
-  0 >>speed-d
-  0 >>theta
-  0 >>theta-d
-  0 >>theta-dd
-
-  0 0 0 1 <rgba> >>myc
-  0 0 0 1 <rgba> >>mya ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-GENERIC: collide ( particle -- )
-GENERIC: move    ( particle -- )
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: muon < particle ;
-
-: <muon> ( -- muon ) muon construct-empty initialize-particle ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: collide { muon }
-
-  dim 2 / dup 2array     >>pos
-  2 32 [a,b] random      >>speed
-  0.0001 0.001 2random   >>speed-d
-
-  collision-theta>  -0.1 0.1 2random + >>theta
-  0                                    >>theta-d
-  0                                    >>theta-dd
-
-  [ dup theta-dd>> abs 0.001 < ]
-    [ -0.1 0.1 2random >>theta-dd ]
-    [ ]
-  while
-
-  dup theta>> pi         +
-  2 pi *                 /
-  good-colors length 1 - *
-  [ ] [ good-colors length >= ] [ 0 < ] tri or
-    [ drop ]
-    [
-      [ good-color >>myc ]
-      [ good-colors length swap - 1 - good-color >>mya ]
-      bi
-    ]
-  if
-
-  drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: move { muon }
-
-  dup myc>> 0.16 >>alpha stroke
-  dup pos>> point
-
-  dup mya>> 0.16 >>alpha stroke
-  dup pos>> first2 >r dim swap - r> 2array point
-
-  dup
-    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
-  move-by
-
-  [ ] [ theta>>   ] [ theta-d>>  ] tri + >>theta
-  [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d
-  [ ] [ speed>>   ] [ speed-d>>  ] tri - >>speed
-
-  out-of-bounds?
-    [ collide ]
-    [ drop    ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: quark < particle ;
-
-: <quark> ( -- quark ) quark construct-empty initialize-particle ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: collide { quark }
-
-  dim 2 / dup 2array                     >>pos
-  collision-theta> -0.11 0.11 2random +  >>theta
-  0.5 3.0 2random                        >>speed
-
-  0.996 1.001 2random                    >>speed-d
-  0                                      >>theta-d
-  0                                      >>theta-dd
-
-  [ dup theta-dd>> abs 0.00001 < ]
-    [ -0.001 0.001 2random >>theta-dd ]
-    [ ]
-  while
-
-  drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: move { quark }
-
-  dup myc>> 0.13 >>alpha stroke
-  dup pos>>              point
-
-  dup pos>> first2 >r dim swap - r> 2array point
-
-  [ ] [ vel>> ] bi move-by
-
-  dup
-    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
-  >>vel
-
-  [ ] [ theta>>   ] [ theta-d>>  ] tri + >>theta
-  [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d
-  [ ] [ speed>>   ] [ speed-d>>  ] tri * >>speed
-
-  ! 1000 random 997 >
-  3/1000 chance
-    [
-      dup speed>> neg    >>speed
-      2 over speed-d>> - >>speed-d
-    ]
-  when
-
-  out-of-bounds?
-    [ collide ]
-    [ drop    ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: hadron < particle ;
-
-: <hadron> ( -- hadron ) hadron construct-empty initialize-particle ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: collide { hadron }
-
-  dim 2 / dup 2array >>pos
-  2 pi *  1random    >>theta
-  0.5 3.5 2random    >>speed
-
-  0.996 1.001 2random >>speed-d
-  0                   >>theta-d
-  0                   >>theta-dd
-
-  [ dup theta-dd>> abs 0.00001 < ]
-    [ -0.001 0.001 2random >>theta-dd ]
-    [ ]
-  while
-
-  0 1 0 <rgb> >>myc
-
-  drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: move { hadron }
-
-  { 1 0.11 } stroke
-  dup pos>> 1 v-y point
-  
-  { 0 0.11 } stroke
-  dup pos>> 1 v+y point
-
-  dup vel>> move-by
-
-  dup
-    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
-  >>vel
-
-  [ ] [ theta>>   ] [ theta-d>>  ] tri + >>theta
-  [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d
-  [ ] [ speed>>   ] [ speed-d>>  ] tri * >>speed
-
-  ! 1000 random 997 >
-  3/1000 chance
-    [
-      1.0     >>speed-d
-      0.00001 >>theta-dd
-
-      ! 100 random 70 >
-      30/100 chance
-        [
-          dim 2 / dup 2array >>pos
-          dup collide
-        ]
-      when
-    ]
-  when
-
-  out-of-bounds?
-    [ collide ]
-    [ drop ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: axion < particle ;
-
-: <axion> ( -- axion ) axion construct-empty initialize-particle ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: collide { axion }
-
-  dim 2 / dup 2array >>pos
-  2 pi * 1random     >>theta
-  1.0 6.0 2random    >>speed
-
-  0.998 1.000 2random >>speed-d
-  0                   >>theta-d
-  0                   >>theta-dd
-
-  [ dup theta-dd>> abs 0.00001 < ]
-    [ -0.001 0.001 2random >>theta-dd ]
-    [ ]
-  while
-
-  drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-METHOD: move { axion }
-
-  { 0.06 0.59 } stroke
-  dup pos>>  point
-
-  1 4 [a,b]
-    [| dy |
-      1 30 dy 6 * - 255.0 / 2array stroke
-      dup pos>> 0 dy neg 2array v+ point
-    ] with-locals
-  each
-
-  1 4 [a,b]
-    [| dy |
-      0 30 dy 6 * - 255.0 / 2array stroke
-      dup pos>> dy v+y point
-    ] with-locals
-  each
-
-  dup vel>> move-by
-
-  dup
-    [ speed>> ] [ theta>> { sin cos } <arr> ] bi n*v
-  >>vel
-
-  [ ] [ theta>>   ] [ theta-d>>  ] tri + >>theta
-  [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d
-  [ ] [ speed>>   ] [ speed-d>>  ] tri * >>speed
-
-  [ ] [ speed-d>> 0.9999 * ] bi >>speed-d
-
-  ! 1000 random 996 >
-  4/1000 chance
-    [
-      dup speed>> neg       >>speed
-      dup speed-d>> neg 2 + >>speed-d
-
-      ! 100 random 30 >
-      70/100 chance
-        [
-          dim 2 / dup 2array >>pos
-          collide
-        ]
-        [ drop ]
-      if
-    ]
-    [ drop ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! : draw ( -- )
-
-!   boom>
-!     [ particles> [ move ] each ]
-!   when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: collide-all ( -- )
-
-  2 pi * 1random >collision-theta
-
-  particles> [ collide ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: collide-one ( -- )
-
-  dim 2 / mouse-x - dim 2 / mouse-y - fatan2 >collision-theta
-
-  hadrons> random collide
-  quarks>  random collide
-  muons>   random collide ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: mouse-pressed ( -- )
-  boom on
-  1 background ! kludge
-  11 [ drop collide-one ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: key-released ( -- )
-  key " " =
-    [
-      boom on
-      1 background
-      collide-all
-    ]
-  when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: bubble-chamber ( -- )
-
-  1000 1000 size*
-
-  [
-    1 background
-    no-stroke
-  
-    1789 [ drop <muon>   ] map >muons
-    1300 [ drop <quark>  ] map >quarks
-    1000 [ drop <hadron> ] map >hadrons
-    111  [ drop <axion>  ] map >axions
-
-    muons> quarks> hadrons> axions> 3append append >particles
-
-    collide-one
-  ] setup
-
-  [
-    boom>
-      [ particles> [ move ] each ]
-    when
-  ] draw
-
-  [ mouse-pressed ] button-down
-  [ key-released  ] key-up
-
-  ;
-
-: go ( -- ) [ bubble-chamber run ] with-ui ;
-
-MAIN: go
\ No newline at end of file
index 02a8325663eb77cfde4db56b06f84390482a2480..e089b15e7e4f32fa7f8133b521938de850613cab 100644 (file)
@@ -8,7 +8,7 @@ USING: kernel namespaces threads combinators sequences arrays
        combinators
        combinators.lib
        combinators.cleave
-       rewrite-closures fry accessors
+       rewrite-closures fry accessors newfx
        processing.color
        processing.gadget ;
        
@@ -28,6 +28,14 @@ IN: processing
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+! : at-fraction ( seq fraction -- val ) over length 1- * nth-at ;
+
+: at-fraction ( seq fraction -- val ) over length 1- * at ;
+
+: at-fraction-of ( fraction seq -- val ) swap at-fraction ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
 VAR: fill-color
 VAR: stroke-color
 
@@ -282,7 +290,7 @@ VAR: frame-rate-value
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-VAR: slate
+VAR: slate
 
 VAR: loop-flag
 
index 828c0c3fd88dfdc9277012353bd53c978e092635..b2146b4aeab2af090e5972d7eef6a925d81410e5 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Aaron Schaefer, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: hashtables kernel math math.ranges project-euler.common sequences
-    sorting ;
+    sorting sets ;
 IN: project-euler.004
 
 ! http://projecteuler.net/index.php?section=problems&id=4
index 526bb4c4464e716afb6023c7c285529354071914..1dd7878a3b84fac50f43b4ad68c2893258331cff 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: hashtables kernel math math.ranges project-euler.common sequences
-    sorting ;
+    sorting sets ;
 IN: project-euler.023
 
 ! http://projecteuler.net/index.php?section=problems&id=23
@@ -51,7 +51,7 @@ IN: project-euler.023
 PRIVATE>
 
 : euler023 ( -- answer )
-    20161 abundants-upto possible-sums source-023 seq-diff sum ;
+    20161 abundants-upto possible-sums source-023 diff sum ;
 
 ! TODO: solution is still too slow, although it takes under 1 minute
 
index 459a3a4bd6c3a305b04d0bcdb6bee9917c260a5f..9cfe0aacffc510dddc235ff8d828d23a38f22e66 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: hashtables kernel math.functions math.ranges project-euler.common
-    sequences ;
+    sequences sets ;
 IN: project-euler.029
 
 ! http://projecteuler.net/index.php?section=problems&id=29
index 0981c68e1c1522ebbd01a2115492893add6d21c9..7b24004df66cdc942986b978e126b4dffa114b67 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.lib hashtables kernel math math.combinatorics math.functions
-    math.parser math.ranges project-euler.common sequences ;
+    math.parser math.ranges project-euler.common sequences sets ;
 IN: project-euler.032
 
 ! http://projecteuler.net/index.php?section=problems&id=32
index 9873abf05ca727127cc3630c28dd4dc4ed7e7fd4..c362e1e1a59cd393127b3fca9336e02b8aed6d27 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.combinatorics math.parser math.primes
-    project-euler.common sequences sequences.lib ;
+    project-euler.common sequences sequences.lib sets ;
 IN: project-euler.035
 
 ! http://projecteuler.net/index.php?section=problems&id=35
@@ -28,7 +28,7 @@ IN: project-euler.035
 
 : possible? ( seq -- ? )
     dup length 1 > [
-        dup { 0 2 4 5 6 8 } swap seq-diff =
+        dup { 0 2 4 5 6 8 } swap diff =
     ] [
         drop t
     ] if ;
index cf09277f31ba09c0314b2fe0dd1b4baf05a41f54..0d1eb00bfa38656d4a5357bb72ab2d82b90fe209 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.lib hashtables kernel math math.combinatorics math.parser
-    math.ranges project-euler.common sequences sequences.lib sorting ;
+    math.ranges project-euler.common sequences sequences.lib sorting sets ;
 IN: project-euler.043
 
 ! http://projecteuler.net/index.php?section=problems&id=43
@@ -79,7 +79,7 @@ PRIVATE>
     [ unclip 1 head prefix concat ] map [ all-unique? ] subset ;
 
 : add-missing-digit ( seq -- seq )
-    dup natural-sort 10 seq-diff first prefix ;
+    dup natural-sort 10 diff first prefix ;
 
 : interesting-pandigitals ( -- seq )
     17 candidates { 13 11 7 5 3 2 } [
index 1c20d1ab34b15dd67690e7793d89f893464860f5..bb95ab9024d689010bb48a8068fa6a704d80c22a 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays ascii assocs hashtables io.encodings.ascii io.files kernel math
     math.parser namespaces sequences sequences.lib sequences.private sorting
-    splitting strings ;
+    splitting strings sets ;
 IN: project-euler.059
 
 ! http://projecteuler.net/index.php?section=problems&id=59
index b4cbd6dbcbcf45d7580307579e33358a6468fb6c..452a64af44af269d7b490cc951ec6ac4a717fbc5 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs hashtables io.files kernel math math.parser namespaces
-io.encodings.ascii sequences ;
+io.encodings.ascii sequences sets ;
 IN: project-euler.079
 
 ! http://projecteuler.net/index.php?section=problems&id=79
@@ -35,7 +35,7 @@ IN: project-euler.079
     ] { } make ;
 
 : find-source ( seq -- elt )
-    dup values swap keys [ prune ] bi@ seq-diff
+    dup values swap keys [ prune ] bi@ diff
     dup empty? [ "Topological sort failed" throw ] [ first ] if ;
 
 : remove-source ( seq elt -- seq )
@@ -52,7 +52,7 @@ PRIVATE>
 
 : topological-sort ( seq -- seq )
     [ [ (topological-sort) ] { } make ] keep
-    concat prune dupd seq-diff append ;
+    concat prune dupd diff append ;
 
 : euler079 ( -- answer )
     source-079 >edges topological-sort 10 digits>integer ;
@@ -60,7 +60,7 @@ PRIVATE>
 ! [ euler079 ] 100 ave-time
 ! 2 ms run / 0 ms GC ave time - 100 trials
 
-! TODO: prune and seq-diff are relatively slow; topological sort could be
+! TODO: prune and diff are relatively slow; topological sort could be
 ! cleaned up and generalized much better, but it works for this problem
 
 MAIN: euler079
index 90655149dc48b2e0dc1075f37ca4d0abb7b0b691..4387662c90f033f0d63a51a6e682554b865982e6 100644 (file)
@@ -30,7 +30,7 @@ MEMO: fn ( n -- x )
     {
         { [ dup 2 < ]  [ drop 1 ] }
         { [ dup odd? ] [ 2/ fn ] }
-        { [ t ]        [ 2/ [ fn ] [ 1- fn + ] bi + ] }
+        [ 2/ [ fn ] [ 1- fn ] bi + ]
     } cond ;
 
 : euler169 ( -- result )
index e6b4acc8c080f2a476318542dbb7f1fd153eeffd..853bf9a10f1b7c28841ee68da0ea9579cd52b3cb 100644 (file)
@@ -44,7 +44,7 @@ IN: project-euler.175
     {
         { [ dup integer? ] [ 1- 0 add-bits ] }
         { [ dup 1 < ] [ 1 over - / dupd compute 1 1 add-bits ] }
-        { [ t ] [ [ 1 mod compute ] 2keep >integer 0 add-bits ] }
+        [ [ 1 mod compute ] 2keep >integer 0 add-bits ]
     } cond ;
 
 PRIVATE>
diff --git a/extra/project-euler/186/186.factor b/extra/project-euler/186/186.factor
new file mode 100644 (file)
index 0000000..acec27c
--- /dev/null
@@ -0,0 +1,35 @@
+USING: circular disjoint-set kernel math math.ranges
+       sequences sequences.lib ;
+IN: project-euler.186
+
+: (generator) ( k -- n )
+    dup sq 300007 * 200003 - * 100003 + 1000000 rem ;
+
+: <generator> ( -- lag )
+    55 [1,b] [ (generator) ] map <circular> ;
+
+: advance ( lag -- )
+    [ { 0 31 } nths sum 1000000 rem ] keep push-circular ;
+
+: next ( lag -- n )
+    [ first ] [ advance ] bi ;
+
+: 2unless? ( x y ?quot quot -- )
+    >r 2keep rot [ 2drop ] r> if ; inline
+
+: (p186) ( generator counter unionfind -- counter )
+    524287 over equiv-set-size 990000 <
+    [
+        pick [ next ] [ next ] bi
+        [ = ] [
+            pick equate
+            [ 1+ ] dip
+        ] 2unless? (p186)
+    ] [
+        drop nip
+    ] if ;
+
+: euler186 ( -- n )
+    <generator> 0 1000000 <disjoint-set> (p186) ;
+
+MAIN: euler186
index 4eec9c9a080a88d0973d39308897a1447f03225e..d280bffce6277dc99b9063797c919f64017cb8c2 100644 (file)
@@ -1 +1,2 @@
 Aaron Schaefer
+Eric Mertens
index 469f6a91ed68890866cf614d325d54984440d73e..2126f0c05dcde20f4a9e08647f1d300b4a77a510 100755 (executable)
@@ -11,7 +11,7 @@ IN: promises
 TUPLE: promise quot forced? value ;
 
 : promise ( quot -- promise )
-  f f \ promise construct-boa ;
+  f f \ promise boa ;
 
 : promise-with ( value quot -- promise )
   curry promise ;
index 36a503bec4e22d0b1960571124bc7077a832882c..d336d31114a0f5d0c0b4a685f2248f020e2a5614 100755 (executable)
@@ -6,3 +6,29 @@ HELP: QUALIFIED:
 { $description "Similar to " { $link POSTPONE: USE: } " but loads vocabulary with prefix." }
 { $examples { $code
     "QUALIFIED: math\n1 2 math:+ ! ==> 3" } } ;
+
+HELP: QUALIFIED-WITH:
+{ $syntax "QUALIFIED-WITH: vocab prefix" }
+{ $description "Works like " { $link POSTPONE: QUALIFIED: } " but uses the specified prefix." }
+{ $examples { $code
+    "QUALIFIED-WITH: math m\n1 2 m:+ ! ==> 3" } } ;
+
+HELP: FROM:
+{ $syntax "FROM: vocab => words ... ;" }
+{ $description "Imports the specified words from vocab." }
+{ $examples { $code
+    "FROM: math.parser => bin> hex> ; ! imports only bin> and hex>" } } ;
+
+HELP: EXCLUDE:
+{ $syntax "EXCLUDE: vocab => words ... ;" }
+{ $description "Imports everything from vocab excluding the specified words" }
+{ $examples { $code
+    "EXCLUDE: math.parser => bin> hex> ; ! imports everythin but bin> and hex>" } } ;
+
+HELP: RENAME:
+{ $syntax "RENAME: word vocab => newname " }
+{ $description "Imports word from vocab, but renamed to newname." }
+{ $examples { $code
+    "RENAME: + math => -"
+    "2 3 - ! => 5" } } ;
+
index d1bd569a394f24fd5f801c901e2072a4d65f14ae..8f67ddf7309dfa3d78fac6ca7f6d06223a1de5d5 100644 (file)
@@ -3,6 +3,22 @@ IN: foo
 : x 1 ;
 IN: bar
 : x 2 ;
+IN: baz
+: x 3 ;
+
 QUALIFIED: foo
 QUALIFIED: bar
-[ 1 2 2 ] [ foo:x bar:x x ] unit-test
+[ 1 2 3 ] [ foo:x bar:x x ] unit-test
+
+QUALIFIED-WITH: bar p
+[ 2 ] [ p:x ] unit-test
+
+RENAME: x baz => y
+[ 3 ] [ y ] unit-test
+
+FROM: baz => x ;
+[ 3 ] [ x ] unit-test
+
+EXCLUDE: bar => x ;
+[ 3 ] [ x ] unit-test
+
index 69e4c09b6e11c992e5767299739e13df057d5b2c..730388ade0264867e7d843831c86d5693854af04 100644 (file)
@@ -1,13 +1,43 @@
-USING: kernel sequences assocs parser vocabs namespaces
-vocabs.loader ;
+USING: kernel sequences assocs hashtables parser vocabs words namespaces
+vocabs.loader debugger sets ;
 IN: qualified
 
-: define-qualified ( vocab-name -- )
-    dup require
-    dup vocab-words swap CHAR: : suffix
+: define-qualified ( vocab-name prefix-name -- )
+    [ load-vocab vocab-words ] [ CHAR: : suffix ] bi*
     [ -rot >r append r> ] curry assoc-map
     use get push ;
 
-
 : QUALIFIED:
-    scan define-qualified ; parsing
+    #! Syntax: QUALIFIED: vocab
+    scan dup define-qualified ; parsing
+
+: QUALIFIED-WITH:
+    #! Syntax: QUALIFIED-WITH: vocab prefix
+    scan scan define-qualified ; parsing
+
+: expect=> scan "=>" assert= ;
+
+: partial-vocab ( words name -- assoc )
+    dupd [
+        lookup [ "No such word: " swap append throw ] unless*
+    ] curry map zip ;
+
+: partial-vocab-ignoring ( words name -- assoc )
+    [ vocab-words keys diff ] keep partial-vocab ;
+
+: EXCLUDE:
+    #! Syntax: EXCLUDE: vocab => words ... ;
+    scan expect=>
+    ";" parse-tokens swap partial-vocab-ignoring use get push ; parsing
+
+: FROM:
+    #! Syntax: FROM: vocab => words... ;
+    scan expect=>
+    ";" parse-tokens swap partial-vocab use get push ; parsing
+
+: RENAME:
+    #! Syntax: RENAME: word vocab => newname
+    scan scan lookup [ "No such word" throw ] unless*
+    expect=>
+    scan associate use get push ; parsing
+
diff --git a/extra/random-tester/authors.txt b/extra/random-tester/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/random-tester/databank/authors.txt b/extra/random-tester/databank/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/random-tester/databank/databank.factor b/extra/random-tester/databank/databank.factor
deleted file mode 100644 (file)
index 45ee779..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-USING: kernel math.constants ;
-IN: random-tester.databank
-
-: databank ( -- array )
-    {
-        ! V{ } H{ } V{ 3 } { 3 } { } "" "asdf"
-        pi 1/0. -1/0. 0/0. [ ]
-        f t "" 0 0.0 3.14 2 -3 -7 20 3/4 -3/4 1.2/3 3.5
-        C{ 2 2 } C{ 1/0. 1/0. }
-    } ;
-
diff --git a/extra/random-tester/random-tester.factor b/extra/random-tester/random-tester.factor
deleted file mode 100755 (executable)
index 7fb1714..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-USING: compiler continuations io kernel math namespaces
-prettyprint quotations random sequences vectors
-compiler.units ;
-USING: random-tester.databank random-tester.safe-words ;
-IN: random-tester
-
-SYMBOL: errored
-SYMBOL: before
-SYMBOL: after
-SYMBOL: quot
-TUPLE: random-tester-error ;
-
-: setup-test ( #data #code -- data... quot )
-    #! Variable stack effect
-    >r [ databank random ] times r>
-    [ drop \ safe-words get random ] map >quotation ;
-
-: test-compiler ! ( data... quot -- ... )
-    errored off
-    dup quot set
-    datastack 1 head* before set
-    [ call ] [ drop ] recover
-    datastack after set
-    clear
-    before get [ ] each
-    quot get [ compile-call ] [ errored on ] recover ;
-
-: do-test ! ( data... quot -- )
-    .s flush test-compiler
-    errored get [
-        datastack after get 2dup = [
-            2drop
-        ] [
-            [ . ] each
-            "--" print
-            [ . ] each
-            quot get .
-            random-tester-error construct-empty throw
-        ] if
-    ] unless clear ;
-
-: random-test1 ( #data #code -- )
-    setup-test do-test ;
-
-: random-test2 ( -- )
-    3 2 setup-test do-test ;
diff --git a/extra/random-tester/random/authors.txt b/extra/random-tester/random/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/random-tester/random/random.factor b/extra/random-tester/random/random.factor
deleted file mode 100755 (executable)
index 11f2e60..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-USING: kernel math sequences namespaces hashtables words
-arrays parser compiler syntax io prettyprint optimizer
-random math.constants math.functions layouts random-tester.utils ;
-IN: random-tester
-
-! Tweak me
-: max-length 15 ; inline
-: max-value 1000000000 ; inline
-
-! varying bit-length random number
-: random-bits ( n -- int )
-    random 2 swap ^ random ;
-
-: random-seq ( -- seq )
-    { [ ] { } V{ } "" } random
-    [ max-length random [ max-value random , ] times ] swap make ;
-
-: random-string
-    [ max-length random [ max-value random , ] times ] "" make ;
-
-: special-integers ( -- seq ) \ special-integers get ;
-[ { -1 0 1 } % most-negative-fixnum , most-positive-fixnum , first-bignum , ] 
-{ } make \ special-integers set-global
-: special-floats ( -- seq ) \ special-floats get ;
-[ { 0.0 -0.0 } % e , pi , 1./0. , -1./0. , 0./0. , epsilon , epsilon neg , ]
-{ } make \ special-floats set-global
-: special-complexes ( -- seq ) \ special-complexes get ;
-[ 
-    { -1 0 1 C{ 0 1 } C{ 0 -1 } } %
-    e , e neg , pi , pi neg ,
-    0 pi rect> , 0 pi neg rect> , pi neg 0 rect> , pi pi rect> ,
-    pi pi neg rect> , pi neg pi rect> , pi neg pi neg rect> ,
-    e neg e neg rect> , e e rect> ,
-] { } make \ special-complexes set-global
-
-: random-fixnum ( -- fixnum )
-    most-positive-fixnum random 1+ 50% [ neg 1- ] when >fixnum ;
-
-: random-bignum ( -- bignum )
-     400 random-bits first-bignum + 50% [ neg ] when ;
-    
-: random-integer ( -- n )
-    50% [
-        random-fixnum
-    ] [
-        50% [ random-bignum ] [ special-integers get random ] if
-    ] if ;
-
-: random-positive-integer ( -- int )
-    random-integer dup 0 < [
-            neg
-        ] [
-            dup 0 = [ 1 + ] when
-    ] if ;
-
-: random-ratio ( -- ratio )
-    1000000000 dup [ random ] bi@ 1+ / 50% [ neg ] when dup [ drop random-ratio ] unless 10% [ drop 0 ] when ;
-
-: random-float ( -- float )
-    50% [ random-ratio ] [ special-floats get random ] if
-    50%
-    [ .0000000000000000001 /f ] [ 50% [ .00000000000000001 * ] when ] if
-    >float ;
-
-: random-number ( -- number )
-    {
-        [ random-integer ]
-        [ random-ratio ]
-        [ random-float ]
-    } do-one ;
-
-: random-complex ( -- C )
-    random-number random-number rect> ;
-
diff --git a/extra/random-tester/safe-words/authors.txt b/extra/random-tester/safe-words/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/random-tester/safe-words/safe-words.factor b/extra/random-tester/safe-words/safe-words.factor
deleted file mode 100755 (executable)
index 5ca2c79..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-USING: kernel namespaces sequences sorting vocabs ;
-USING: arrays assocs generic hashtables  math math.intervals math.parser math.functions refs shuffle vectors words ;
-IN: random-tester.safe-words
-
-: ?-words
-    {
-        delegate
-
-        /f
-
-        bits>float bits>double
-        float>bits double>bits
-
-        >bignum >boolean >fixnum >float
-
-        array? integer? complex? value-ref? ref? key-ref?
-        interval? number?
-        wrapper? tuple?
-        [-1,1]? between? bignum? both? either? eq? equal? even? fixnum? float? fp-nan? hashtable? interval-contains? interval-subset? interval? key-ref? key? number? odd? pair? power-of-2? ratio? rational? real? subassoc? zero? assoc? curry? vector? callstack? ! clear 3.14 [ <vector> assoc? ] compile-1
-        2^ not
-        ! arrays
-        resize-array <array>
-        ! assocs
-        (assoc-stack)
-        new-assoc
-        assoc-like
-        <hashtable>
-        all-integers? (all-integers?) ! hangs?
-        assoc-push-if
-
-        (clone) assoc-clone-like ! SYMBOL: foo foo dup (clone) =
-    } ;
-
-: bignum-words
-    {
-        next-power-of-2 (next-power-of-2)
-        times
-        hashcode hashcode*
-    } ;
-
-: initialization-words
-    {
-        init-namespaces
-    } ;
-
-: stack-words
-    {
-        dup
-        drop 2drop 3drop
-        roll -roll 2swap
-
-        >r r>
-    } ;
-
-: stateful-words
-    {
-        counter
-        gensym
-    } ;
-
-: foo-words
-    {
-        set-retainstack
-        retainstack callstack
-        datastack
-        callstack>array
-    } ;
-
-: exit-words
-    {
-        call-clear die
-    } ;
-
-: bad-words ( -- array )
-    [
-        ?-words %
-        bignum-words %
-        initialization-words %
-        stack-words %
-        stateful-words %
-        exit-words %
-        foo-words %
-    ] { } make ;
-
-: safe-words ( -- array )
-    bad-words {
-        "alists" "arrays" "assocs" ! "bit-arrays" "byte-arrays"
-        ! "classes" "combinators" "compiler" "continuations"
-        ! "core-foundation" "definitions" "documents"
-        ! "float-arrays" "generic" "graphs" "growable"
-        "hashtables"  ! io.*
-        "kernel" "math" 
-        "math.bitfields" "math.complex" "math.constants" "math.floats"
-        "math.functions" "math.integers" "math.intervals" "math.libm"
-        "math.parser" "math.ratios" "math.vectors"
-        ! "namespaces" "quotations" "sbufs"
-        ! "queues" "strings" "sequences"
-        "vectors"
-        ! "words"
-    } [ words ] map concat seq-diff natural-sort ;
-    
-safe-words \ safe-words set-global
-
-! foo dup (clone) = .
-! foo dup clone = .
-! f [ byte-array>bignum assoc-clone-like ] compile-1
-! 2 3.14 [ construct-empty number= ] compile-1
-! 3.14 [ <vector> assoc? ] compile-1
-! -3 [ ] 2 [ byte-array>bignum denominator ] compile-1
-
diff --git a/extra/random-tester/utils/authors.txt b/extra/random-tester/utils/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/random-tester/utils/utils.factor b/extra/random-tester/utils/utils.factor
deleted file mode 100644 (file)
index a025bbf..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-USING: arrays assocs combinators.lib continuations kernel
-math math.functions memoize namespaces quotations random sequences
-sequences.private shuffle ;
-IN: random-tester.utils
-
-: %chance ( n -- ? )
-    100 random > ;
-
-: 10% ( -- ? ) 10 %chance ;
-: 20% ( -- ? ) 20 %chance ;
-: 30% ( -- ? ) 30 %chance ;
-: 40% ( -- ? ) 40 %chance ;
-: 50% ( -- ? ) 50 %chance ;
-: 60% ( -- ? ) 60 %chance ;
-: 70% ( -- ? ) 70 %chance ;
-: 80% ( -- ? ) 80 %chance ;
-: 90% ( -- ? ) 90 %chance ;
-
-: call-if ( quot ? -- ) swap when ; inline
-
-: with-10% ( quot -- ) 10% call-if ; inline
-: with-20% ( quot -- ) 20% call-if ; inline
-: with-30% ( quot -- ) 30% call-if ; inline
-: with-40% ( quot -- ) 40% call-if ; inline
-: with-50% ( quot -- ) 50% call-if ; inline
-: with-60% ( quot -- ) 60% call-if ; inline
-: with-70% ( quot -- ) 70% call-if ; inline
-: with-80% ( quot -- ) 80% call-if ; inline
-: with-90% ( quot -- ) 90% call-if ; inline
-
-: random-key keys random ;
-: random-value [ random-key ] keep at ;
-
-: do-one ( seq -- ) random call ; inline
diff --git a/extra/random/blum-blum-shub/blum-blum-shub-tests.factor b/extra/random/blum-blum-shub/blum-blum-shub-tests.factor
new file mode 100644 (file)
index 0000000..a92f256
--- /dev/null
@@ -0,0 +1,28 @@
+USING: kernel math tools.test namespaces random
+random.blum-blum-shub ;
+IN: blum-blum-shub.tests
+
+[ 887708070 ] [
+    T{ blum-blum-shub f 590695557939 811977232793 } random-32*
+] unit-test
+
+
+[ 887708070 ] [
+    T{ blum-blum-shub f 590695557939 811977232793 } [
+        32 random-bits
+    ] with-random
+] unit-test
+
+[ 5726770047455156646 ] [
+    T{ blum-blum-shub f 590695557939 811977232793 } [
+        64 random-bits
+    ] with-random
+] unit-test
+
+[ 3716213681 ]
+[
+    100 T{ blum-blum-shub f 200352954495 846054538649 } tuck [
+        random-32* drop
+    ] curry times
+    random-32*
+] unit-test
index 017ef402c016a5ef12f31d3060299573499bddcf..db8fe540e590f6354a747d422d0864412f62c74d 100755 (executable)
@@ -3,34 +3,26 @@ math.miller-rabin combinators.lib
 math.functions accessors random ;
 IN: random.blum-blum-shub
 
-! TODO: take (log log M) bits instead of 1 bit
-! Blum Blum Shub, M = pq
+! Blum Blum Shub, n = pq, x_i+1 = x_i ^ 2 mod n
+! return low bit of x+1
 TUPLE: blum-blum-shub x n ;
 
-C: <blum-blum-shub> blum-blum-shub
+<PRIVATE
 
 : generate-bbs-primes ( numbits -- p q )
-    #! two primes congruent to 3 (mod 4)
     [ [ random-prime ] curry [ 4 mod 3 = ] generate ] dup bi ;
 
-IN: crypto
 : <blum-blum-shub> ( numbits -- blum-blum-shub )
-    #! returns a Blum-Blum-Shub tuple
     generate-bbs-primes *
     [ find-relative-prime ] keep
-    blum-blum-shub construct-boa ;
-
-! 256 make-bbs blum-blum-shub set-global
+    blum-blum-shub boa ;
 
 : next-bbs-bit ( bbs -- bit )
-    #! x = x^2 mod n, return low bit of calculated x
-    [ [ x>> 2 ] [ n>> ] bi ^mod ]
-    [ [ >>x ] keep x>> 1 bitand ] bi ;
+    [ [ x>> 2 ] [ n>> ] bi ^mod ] keep
+    over >>x drop 1 bitand ;
 
-IN: crypto
-! : random ( n -- n )
-    ! ! #! Cryptographically secure random number using Blum-Blum-Shub 256
-    ! [ log2 1+ random-bits ] keep dupd >= [ -1 shift ] when ;
+PRIVATE>
 
 M: blum-blum-shub random-32* ( bbs -- r )
-    ;
+    0 32 rot
+    [ next-bbs-bit swap 1 shift bitor ] curry times ;
index 46f2088440ac01fae7c8953716df5e9488b82fb2..01e79abff2d96f514938aff8d3721a02f11c3410 100755 (executable)
@@ -58,7 +58,7 @@ TUPLE: mersenne-twister seq i ;
 PRIVATE>
 
 : <mersenne-twister> ( seed -- obj )
-    init-mt-seq 0 mersenne-twister construct-boa
+    init-mt-seq 0 mersenne-twister boa
     dup mt-generate ;
 
 M: mersenne-twister seed-random ( mt seed -- )
index b1c57ede6008238932bde07c8aff91ad1818eb3d..b4b6ad9aff242d7d12a046d1c839a58e61fbd55a 100755 (executable)
@@ -5,7 +5,7 @@ io.backend io.binary combinators system vocabs.loader
 inspector ;
 IN: random
 
-SYMBOL: insecure-random-generator
+SYMBOL: system-random-generator
 SYMBOL: secure-random-generator
 SYMBOL: random-generator
 
@@ -48,5 +48,8 @@ M: f random-32* ( obj -- * ) no-random-number-generator ;
 : with-random ( tuple quot -- )
     random-generator swap with-variable ; inline
 
+: with-system-random ( quot -- )
+    system-random-generator get swap with-random ; inline
+
 : with-secure-random ( quot -- )
-    >r secure-random-generator get r> with-random ; inline
+    secure-random-generator get swap with-random ; inline
index 6a72baa21be81dac54559bc6f16068143cfe8c71..6016a6e9cbecaa4066fd2e1aa2a5858098fce061 100644 (file)
@@ -18,11 +18,11 @@ M: unix-random random-bytes* ( n tuple -- byte-array )
 os openbsd? [
     [
         "/dev/srandom" <unix-random> secure-random-generator set-global
-        "/dev/prandom" <unix-random> insecure-random-generator set-global
+        "/dev/arandom" <unix-random> system-random-generator set-global
     ] "random.unix" add-init-hook
 ] [
     [
         "/dev/random" <unix-random> secure-random-generator set-global
-        "/dev/urandom" <unix-random> insecure-random-generator set-global
+        "/dev/urandom" <unix-random> system-random-generator set-global
     ] "random.unix" add-init-hook
 ] if
diff --git a/extra/random/windows/tags.txt b/extra/random/windows/tags.txt
new file mode 100644 (file)
index 0000000..8e1a559
--- /dev/null
@@ -0,0 +1 @@
+windows
index 65426d4277eddde6490d4c2fe1ac87e00e3719f3..6f47d3e6bfdd861922dcab208ea71c6d53feff6e 100644 (file)
@@ -44,7 +44,7 @@ M: windows-rng random-bytes* ( n tuple -- bytes )
 
 [
     MS_DEF_PROV
-    PROV_RSA_FULL <windows-rng> insecure-random-generator set-global
+    PROV_RSA_FULL <windows-rng> system-random-generator set-global
 
     MS_STRONG_PROV
     PROV_RSA_FULL <windows-rng> secure-random-generator set-global
index b0cd61bd8f60b94fe3a26ecf6f0249068ee3d422..6b344ad140450802d30744f394a87162378a532a 100755 (executable)
@@ -269,7 +269,7 @@ TUPLE: regexp source parser ignore-case? ;
         ignore-case? [
             dup 'regexp' just parse-1
         ] with-variable
-    ] keep regexp construct-boa ;
+    ] keep regexp boa ;
 
 : do-ignore-case ( string regexp -- string regexp )
     dup regexp-ignore-case? [ >r >upper r> ] when ;
index 6921d1223ab162d03985ec8fb1b010dad095f4f5..c3b7311714eaa33079ff9d79543610d5e87b8c9c 100755 (executable)
@@ -113,7 +113,7 @@ M: array noise [ noise ] map vsum ;
     noise first2 {\r
         { [ over 4 <= ] [ >r drop 0 r> ] }\r
         { [ over 15 >= ] [ >r 2 * r> ] }\r
-        { [ t ] [ ] }\r
+        [ ]\r
     } cond\r
     {\r
         ! short words are easier to read\r
@@ -123,7 +123,7 @@ M: array noise [ noise ] map vsum ;
         { [ dup 25 >= ] [ >r 2 * r> 20 max ] }\r
         { [ dup 20 >= ] [ >r 5/3 * r> ] }\r
         { [ dup 15 >= ] [ >r 3/2 * r> ] }\r
-        { [ t ] [ ] }\r
+        [ ]\r
     } cond noise-factor ;\r
 \r
 GENERIC: word-noise-factor ( word -- factor )\r
index a3e61dd8892eb1f8a768074c6e8a35993c606981..07e43cea8effec3b56133ea88bcb45899877b08d 100644 (file)
@@ -19,7 +19,7 @@ TUPLE: roman-range-error n ;
     dup 1 3999 between? [
         drop
     ] [
-        roman-range-error construct-boa throw
+        roman-range-error boa throw
     ] if ;
 
 : roman<= ( ch1 ch2 -- ? )
index bf5105f334647ad6b48d4ced966532bcb59cd767..6663381522aeb2fbcde56cd4f2b526184c1cd0f7 100644 (file)
@@ -9,7 +9,7 @@ IN: rot13
     {
         { [ dup letter? ] [ CHAR: a rotate ] }
         { [ dup LETTER? ] [ CHAR: A rotate ] }
-        { [ t ] [ ] }
+        [ ]
     } cond ;
 
 : rot13 ( string -- string ) [ rot-letter ] map ;
index 2ac667a94c8922bb6aa21002aca8cb5895d32513..dad1dd39194567e1095b91575d81e0fc3afc7828 100755 (executable)
@@ -31,7 +31,7 @@ TUPLE: arc id subject object relation ;
     arc construct-empty swap >>relation swap >>object swap >>subject ;
 
 : <id-arc> ( id -- arc )
-    arc construct-empty swap >>id ;
+    arc new swap >>id ;
 
 : delete-arc ( arc -- ) delete-tuple ;
 
index 0221d9b99ab9807e07a6ee483be451cbb97aa2bd..15983329d6d5fcec9cf73045e0c830396dc2c42a 100755 (executable)
@@ -227,8 +227,8 @@ PRIVATE>
 : ?nth* ( n seq -- elt/f ? )
     2dup bounds-check? [ nth-unsafe t ] [ 2drop f f ] if ; flushable
 
-: nths ( indices seq -- seq' )
-    [ swap nth ] with map ;
+: nths ( seq indices -- seq' )
+    swap [ nth ] curry map ;
 
 : replace ( str oldseq newseq -- str' )
     zip >hashtable substitute ;
diff --git a/extra/sequences/lib/summary.txt b/extra/sequences/lib/summary.txt
new file mode 100644 (file)
index 0000000..e389b41
--- /dev/null
@@ -0,0 +1 @@
+Non-core sequence words
index 5919fb0701f6497e7b83640c4127885f63976483..b22bf2683c78031486ff306cbe58165b6b21b08d 100755 (executable)
@@ -17,6 +17,6 @@ PRIVATE>
 
 : map-next ( seq quot -- newseq )
     ! quot: next-elt elt -- newelt
-    over dup length swap new >r
+    over dup length swap new-sequence >r
     iterate-seq [ (map-next) ] 2curry
     r> [ collect ] keep ; inline
diff --git a/extra/sequences/next/summary.txt b/extra/sequences/next/summary.txt
new file mode 100644 (file)
index 0000000..fe5bd31
--- /dev/null
@@ -0,0 +1 @@
+Iteration with access to next element
index 7a2fbfae9e6c4a93d650a585e095d39362d00d69..bb69a8a41ccd9ba1264e77b3686199e9df4e83e2 100755 (executable)
@@ -65,7 +65,7 @@ GENERIC: (serialize) ( obj -- )
     read1 {
         { [ dup HEX: ff = ] [ drop deserialize-cell read be> ] }
         { [ dup HEX: 80 >= ] [ HEX: 80 bitxor ] }
-        { [ t ] [ read be> ] }
+        [ read be> ]
     } cond ;
 
 : serialize-shared ( obj quot -- )
@@ -183,7 +183,7 @@ M: word (serialize) ( obj -- )
     {
         { [ dup t eq? ] [ serialize-true ] }
         { [ dup word-vocabulary not ] [ serialize-gensym ] }
-        { [ t ] [ serialize-word ] }
+        [ serialize-word ]
     } cond ;
 
 M: wrapper (serialize) ( obj -- )
@@ -246,7 +246,7 @@ SYMBOL: deserialized
     (deserialize) <wrapper> ;
 
 :: (deserialize-seq) ( exemplar quot -- seq )
-    deserialize-cell exemplar new
+    deserialize-cell exemplar new-sequence
     [ intern-object ]
     [ dup [ drop quot call ] change-each ] bi ; inline
 
@@ -277,7 +277,7 @@ SYMBOL: deserialized
 : deserialize-tuple ( -- array )
     #! Ugly because we have to intern the tuple before reading
     #! slots
-    (deserialize) construct-empty
+    (deserialize) new
     [ intern-object ]
     [
         [ (deserialize) ]
index 14957ceca2e4fe8589dfe6bc851c996a9b9a0bf3..737a887f9fa868d12adb66e8767cc4fc2dc84414 100755 (executable)
@@ -56,15 +56,15 @@ SYMBOL: data-mode
             "220 OK\r\n" write flush t
           ] }
         { [ data-mode get ] [ dup global [ print ] bind t ] }
-        { [ 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 [
+        accept drop [
             1 minutes stdio get set-timeout
             "220 hello\r\n" write flush
             process
index ee2b021329f20e393da26a90b8469f48958a3327..d565117e5fdffe66b477a23b5ce4f15567a4e44e 100755 (executable)
@@ -4,7 +4,7 @@
 USING: namespaces io io.timeouts kernel logging io.sockets
 sequences combinators sequences.lib splitting assocs strings
 math.parser random system calendar io.encodings.ascii
-calendar.format accessors ;
+calendar.format accessors sets ;
 IN: smtp
 
 SYMBOL: smtp-domain
@@ -32,7 +32,7 @@ LOG: log-smtp-connection NOTICE ( addrspec -- )
 
 : validate-address ( string -- string' )
     #! Make sure we send funky stuff to the server by accident.
-    dup "\r\n>" seq-intersect empty?
+    dup "\r\n>" intersect empty?
     [ "Bad e-mail address: " prepend throw ] unless ;
 
 : mail-from ( fromaddr -- )
@@ -70,7 +70,7 @@ LOG: smtp-response DEBUG
         { [ dup "50" head? ] [ smtp-response "syntax error" throw ] }
         { [ dup "53" head? ] [ smtp-response "invalid authentication data" throw ] }
         { [ dup "55" head? ] [ smtp-response "fatal error" throw ] }
-        { [ t ] [ "unknown error" throw ] }
+        [ "unknown error" throw ]
     } cond ;
 
 : multiline? ( response -- boolean )
@@ -90,7 +90,7 @@ LOG: smtp-response DEBUG
 : get-ok ( -- ) receive-response check-response ;
 
 : validate-header ( string -- string' )
-    dup "\r\n" seq-intersect empty?
+    dup "\r\n" intersect empty?
     [ "Invalid header string: " prepend throw ] unless ;
 
 : write-header ( key value -- )
@@ -149,7 +149,7 @@ M: email clone
     message-id "Message-Id" set-header ;
 
 : <email> ( -- email )
-    email construct-empty
+    email new
     H{ } clone >>headers ;
 
 : send-email ( email -- )
index d66ffdc66e075d95739160857d73fa32d4c0e2e0..200257b31c53ef442a1aa502be553ca3191288e4 100755 (executable)
@@ -306,7 +306,7 @@ M: invaders-gadget draw-gadget* ( gadget -- )
     { [ dup 184 238 within pick 0 223 within and ] [ 2drop green ] }
     { [ dup 240 247 within pick 16 133 within and ] [ 2drop green ] }
     { [ dup 247 215 - 247 184 - within pick 0 223 within and ] [ 2drop red ] }
-    { [ t ] [ 2drop white ] }
+    [ 2drop white ]
   } cond ;
 
 : plot-bitmap-bits ( bitmap point byte bit -- )
index 489b7aaeb47ad438aac8dee4d13d2b3392e1d88a..3f1d91d84cff6066a0df901b6dccd9909aba3946 100755 (executable)
@@ -12,7 +12,7 @@ IN: state-machine
 TUPLE: state place data ;
 
 TUPLE: missing-state ;
-: missing-state \ missing-state construct-empty throw ;
+: missing-state \ missing-state new throw ;
 M: missing-state error.
     drop "Missing state" print ;
 
index 3f51a52e1b4c1f0e5f8231e93c634db42fded83d..6a3bf1d5528873cfdcfb2f5218e5c53497bce0be 100644 (file)
@@ -23,7 +23,7 @@ C: <spot> spot
 ! * Errors\r
 TUPLE: parsing-error line column ;\r
 : <parsing-error> ( -- parsing-error )\r
-    get-line get-column parsing-error construct-boa ;\r
+    get-line get-column parsing-error boa ;\r
 \r
 : construct-parsing-error ( ... slots class -- error )\r
     construct <parsing-error> over set-delegate ; inline\r
@@ -97,7 +97,7 @@ SYMBOL: prolog-data
     #! advance spot to after the substring.\r
     [ [\r
         dup slip swap dup [ get-char , ] unless\r
-    ] skip-until ] "" make nip ;\r
+    ] skip-until ] "" make nip ; inline\r
 \r
 : rest ( -- string )\r
     [ f ] take-until ;\r
index 764c4d92f0271f0d3e1ffa0b25026fddee79347e..b0ba85c97f55dea438a78ea3d4445947e298a720 100644 (file)
@@ -32,7 +32,7 @@ DEFER: search
         { [ 3dup nip row-contains? ] [ 3drop ] }
         { [ 3dup drop col-contains? ] [ 3drop ] }
         { [ 3dup box-contains? ] [ 3drop ] }
-        { [ t ] [ assume ] }
+        [ assume ]
     } cond ;
 
 : solve ( x y -- ) 9 [ 1+ 2over attempt ] each 2drop ;
@@ -62,7 +62,7 @@ DEFER: search
         { [ over 9 = ] [ >r drop 0 r> 1+ search ] }
         { [ over 0 = over 9 = and ] [ 2drop solution. ] }
         { [ 2dup board> ] [ >r 1+ r> search ] }
-        { [ t ] [ solve ] }
+        [ solve ]
     } cond ;
 
 : sudoku ( board -- )
index 99af06b80ff5a42a2567c6f15c049b19b90a51fd..9b3d2ae79f4cea7174848176588b6ca9374d8e98 100755 (executable)
@@ -1,7 +1,7 @@
 USING: combinators io io.files io.streams.duplex
 io.streams.string kernel math math.parser continuations
 namespaces pack prettyprint sequences strings system
-hexdump io.encodings.binary ;
+hexdump io.encodings.binary inspector accessors ;
 IN: tar
 
 : zero-checksum 256 ;
@@ -9,7 +9,7 @@ IN: tar
 TUPLE: tar-header name mode uid gid size mtime checksum typeflag
 linkname magic version uname gname devmajor devminor prefix ;
 
-: <tar-header> ( -- obj ) tar-header construct-empty ;
+: <tar-header> ( -- obj ) tar-header new ;
 
 : tar-trim ( seq -- newseq )
     [ "\0 " member? ] trim ;
@@ -68,98 +68,78 @@ SYMBOL: filename
 : parse-tar-header ( seq -- obj )
     [ header-checksum ] keep over zero-checksum = [
         2drop
-        \ tar-header construct-empty
+        \ tar-header new
         0 over set-tar-header-size
         0 over set-tar-header-checksum
     ] [
         [ read-tar-header ] with-string-reader
         [ tar-header-checksum = [
-                \ checksum-error construct-empty throw
+                \ checksum-error new throw
             ] unless
         ] keep
     ] if ;
 
-TUPLE: unknown-typeflag str ;
-: <unknown-typeflag> ( ch -- obj )
-    1string \ unknown-typeflag construct-boa ;
-
-TUPLE: unimplemented-typeflag header ;
-: <unimplemented-typeflag> ( header -- obj )
-    global [ "Unimplemented typeflag: " print dup . flush ] bind
-    tar-header-typeflag
-    1string \ unimplemented-typeflag construct-boa ;
+ERROR: unknown-typeflag ch ;
+M: unknown-typeflag summary ( obj -- str )
+    ch>> 1string
+    "Unknown typeflag: " prepend ;
 
 : tar-append-path ( path -- newpath )
     base-dir get prepend-path ;
 
 ! Normal file
 : typeflag-0
-  tar-header-name tar-append-path binary <file-writer>
+  name>> tar-append-path binary <file-writer>
   [ read-data-blocks ] keep dispose ;
 
 ! Hard link
-: typeflag-1 ( header -- )
-   <unimplemented-typeflag> throw ;
+: typeflag-1 ( header -- ) unknown-typeflag ;
 
 ! Symlink
-: typeflag-2 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-2 ( header -- ) unknown-typeflag ;
 
 ! character special
-: typeflag-3 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-3 ( header -- ) unknown-typeflag ;
 
 ! Block special
-: typeflag-4 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-4 ( header -- ) unknown-typeflag ;
 
 ! Directory
 : typeflag-5 ( header -- )
     tar-header-name tar-append-path make-directories ;
 
 ! FIFO
-: typeflag-6 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-6 ( header -- ) unknown-typeflag ;
 
 ! Contiguous file
-: typeflag-7 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-7 ( header -- ) unknown-typeflag ;
 
 ! Global extended header
-: typeflag-8 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-8 ( header -- ) unknown-typeflag ;
 
 ! Extended header
-: typeflag-9 ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-9 ( header -- ) unknown-typeflag ;
 
 ! Global POSIX header
-: typeflag-g ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-g ( header -- ) unknown-typeflag ;
 
 ! Extended POSIX header
-: typeflag-x ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-x ( header -- ) unknown-typeflag ;
 
 ! Solaris access control list
-: typeflag-A ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-A ( header -- ) unknown-typeflag ;
 
 ! GNU dumpdir
-: typeflag-D ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-D ( header -- ) unknown-typeflag ;
 
 ! Solaris extended attribute file
-: typeflag-E ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-E ( header -- ) unknown-typeflag ;
 
 ! Inode metadata
-: typeflag-I ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-I ( header -- ) unknown-typeflag ;
 
 ! Long link name
-: typeflag-K ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-K ( header -- ) unknown-typeflag ;
 
 ! Long file name
 : typeflag-L ( header -- )
@@ -169,24 +149,19 @@ TUPLE: unimplemented-typeflag header ;
     filename get tar-append-path make-directories ;
 
 ! Multi volume continuation entry
-: typeflag-M ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-M ( header -- ) unknown-typeflag ;
 
 ! GNU long file name
-: typeflag-N ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-N ( header -- ) unknown-typeflag ;
 
 ! Sparse file
-: typeflag-S ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-S ( header -- ) unknown-typeflag ;
 
 ! Volume header
-: typeflag-V ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-V ( header -- ) unknown-typeflag ;
 
 ! Vendor extended header type
-: typeflag-X ( header -- )
-    <unimplemented-typeflag> throw ;
+: typeflag-X ( header -- ) unknown-typeflag ;
 
 : (parse-tar) ( -- )
     512 read 
@@ -218,7 +193,7 @@ TUPLE: unimplemented-typeflag header ;
             { CHAR: S [ typeflag-S ] }
             { CHAR: V [ typeflag-V ] }
             { CHAR: X [ typeflag-X ] }
-            [ <unknown-typeflag> throw ]
+            [ unknown-typeflag ]
         } case
         ! dup tar-header-size zero? [
             ! out-stream get [ dispose ] when
@@ -237,7 +212,7 @@ TUPLE: unimplemented-typeflag header ;
 
 : parse-tar ( path -- obj )
     binary [
-        "tar-test" resource-path base-dir set
+        "resource:tar-test" base-dir set
         global [ nl nl nl "Starting to parse .tar..." print flush ] bind
         global [ "Expanding to: " write base-dir get . flush ] bind
         (parse-tar)
diff --git a/extra/taxes/tags.txt b/extra/taxes/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
index d557feabfa3ff5edd2bc08e4445144c89c1d4564..f1f3868ec8cb9025bad59016c6d1383f2b5aac89 100644 (file)
@@ -45,7 +45,7 @@ GENERIC: withholding ( salary w4 collector -- x )
 TUPLE: tax-table single married ;
 
 : <tax-table> ( single married class -- obj )
-    >r tax-table construct-boa r> construct-delegate ;
+    >r tax-table boa r> construct-delegate ;
 
 : tax-bracket-range dup second swap first - ;
 
index 93bbebf34fe01b1bd2db140f0002550fc0a02d06..532978e35964e349f6944412a5012cade0fa9376 100644 (file)
@@ -9,7 +9,7 @@ TUPLE: board width height rows ;
     [ drop f <array> ] with map ;
 
 : <board> ( width height -- board )
-    2dup make-rows board construct-boa ;
+    2dup make-rows board boa ;
 
 #! A block is simply an array of form { x y } where { 0 0 } is the top-left of
 #! the tetris board, and { 9 19 } is the bottom right on a 10x20 board.
index 16bde2100f059fe693eee31bf653e0a98ab7784a..b9c37c065661ad65c10d4b360886809109078851 100755 (executable)
@@ -35,7 +35,7 @@ unicode.categories ;
         { [ 2dup length 1- number= ] [ 2drop 4 ] }
         { [ 2dup >r 1- r> nth Letter? not ] [ 2drop 10 ] }
         { [ 2dup >r 1+ r> nth Letter? not ] [ 2drop 4 ] }
-        { [ t ] [ 2drop 1 ] }
+        [ 2drop 1 ]
     } cond ;
 
 : score ( full fuzzy -- n )
index e11d16c4ecb29c20a4c54c92e1d269095a4eeb95..b8386542488b6f459e253410de9c999faa85c226 100755 (executable)
@@ -22,9 +22,8 @@ IN: tools.deploy.backend
         +stdout+ >>stderr
         +closed+ >>stdin
         +low-priority+ >>priority
-    utf8 <process-stream>
-    dup copy-lines
-    process>> wait-for-process zero? [
+    utf8 <process-stream*>
+    >r copy-lines r> wait-for-process zero? [
         "Deployment failed" throw
     ] unless ;
 
index 7ebedf7ca14f130a96714b41033a812c9abceeea..589d6c613b54218f33396ef0552c1805569031c2 100755 (executable)
@@ -65,7 +65,7 @@ SYMBOL: deploy-image
         { deploy-c-types?           f }
         ! default value for deploy.macosx
         { "stop-after-last-window?" t }
-    } union ;
+    } assoc-union ;
 
 : deploy-config-path ( vocab -- string )
     vocab-dir "deploy.factor" append-path ;
@@ -73,7 +73,7 @@ SYMBOL: deploy-image
 : deploy-config ( vocab -- assoc )
     dup default-config swap
     dup deploy-config-path vocab-file-contents
-    parse-fresh dup empty? [ drop ] [ first union ] if ;
+    parse-fresh dup empty? [ drop ] [ first assoc-union ] if ;
 
 : set-deploy-config ( assoc vocab -- )
     >r unparse-use string-lines r>
index 99e533f1c1c5e47b4e5f46505d5f95d740885dca..37689f749f30ea2c2a3d8c2c64aacacc420ce96c 100755 (executable)
@@ -1,7 +1,7 @@
 IN: tools.deploy.tests\r
 USING: tools.test system io.files kernel tools.deploy.config\r
 tools.deploy.backend math sequences io.launcher arrays\r
-namespaces continuations layouts ;\r
+namespaces continuations layouts accessors ;\r
 \r
 : shake-and-bake ( vocab -- )\r
     [ "test.image" temp-file delete-file ] ignore-errors\r
@@ -12,7 +12,7 @@ namespaces continuations layouts ;
     ] with-directory ;\r
 \r
 : small-enough? ( n -- ? )\r
-    >r "test.image" temp-file file-info file-info-size r> <= ;\r
+    >r "test.image" temp-file file-info size>> r> <= ;\r
 \r
 [ ] [ "hello-world" shake-and-bake ] unit-test\r
 \r
index 72e1c33a26e88aef7cfdeab966216b997aaa5f3a..82e2652c0198b66a0ff87273278bf455a8e8b9c4 100755 (executable)
@@ -3,7 +3,7 @@
 USING: qualified io.streams.c init fry namespaces assocs kernel
 parser tools.deploy.config vocabs sequences words words.private
 memory kernel.private continuations io prettyprint
-vocabs.loader debugger system strings ;
+vocabs.loader debugger system strings sets ;
 QUALIFIED: bootstrap.stage2
 QUALIFIED: classes
 QUALIFIED: command-line
@@ -104,7 +104,7 @@ IN: tools.deploy.shaker
     set-global ;
 
 : strip-vocab-globals ( except names -- words )
-    [ child-vocabs [ words ] map concat ] map concat seq-diff ;
+    [ child-vocabs [ words ] map concat ] map concat diff ;
 
 : stripped-globals ( -- seq )
     [
index de8f8740f06f4e8b4798fbd3d76bff72762da31f..038bfde70d6dab9f738bb7185a67b5011cf11c80 100755 (executable)
@@ -9,14 +9,14 @@ global [
     [ "MiniFactor.nib" load-nib ] cocoa-init-hook set-global
 
     ! Only keeps those methods that we actually call
-    sent-messages get super-sent-messages get union
-    objc-methods [ intersect ] change
+    sent-messages get super-sent-messages get assoc-union
+    objc-methods [ assoc-intersect ] change
 
     sent-messages get
     super-sent-messages get
     [ keys [ objc-methods get at dup ] H{ } map>assoc ] bi@
-    super-message-senders [ intersect ] change
-    message-senders [ intersect ] change
+    super-message-senders [ assoc-intersect ] change
+    message-senders [ assoc-intersect ] change
 
     sent-messages off
     super-sent-messages off
index ef1aab0d0e80e39c69ee151fac63f9fc11f1f70d..6eee6b97667765ea71321b89a9e71390a45ad973 100644 (file)
@@ -1 +1,2 @@
+windows
 tools
index 552247e2c430484a36cd2d3ab0f3f613b487a73a..060377d1272a10ae3692c0420895cd074347c976 100755 (executable)
@@ -22,7 +22,7 @@ heaps.private system math math.parser ;
 : threads. ( -- )\r
     standard-table-style [\r
         [\r
-            { "ID" "Name" "Waiting on" "Remaining sleep" }\r
+            { "ID:" "Name:" "Waiting on:" "Remaining sleep:" }\r
             [ [ write ] with-cell ] each\r
         ] with-row\r
 \r
index 6ecb0bc5ad67d1fa7ee761bbbc485456f6e625da..db1edbeb61bea21d4d706c7dc1eb02a56c1e9196 100755 (executable)
@@ -10,7 +10,7 @@ IN: tools.vocabs.browser
     {
         { [ dup not ] [ drop "" ] }
         { [ dup vocab-main ] [ drop "[Runnable]" ] }
-        { [ t ] [ drop "[Loaded]" ] }
+        [ drop "[Loaded]" ]
     } cond ;
 
 : write-status ( vocab -- )
diff --git a/extra/tools/vocabs/monitor/monitor-tests.factor b/extra/tools/vocabs/monitor/monitor-tests.factor
new file mode 100644 (file)
index 0000000..f1eece9
--- /dev/null
@@ -0,0 +1,6 @@
+USING: tools.test tools.vocabs.monitor io.files ;
+IN: tools.vocabs.monitor.tests
+
+[ "kernel" ] [ "core/kernel/kernel.factor" path>vocab ] unit-test
+[ "kernel" ] [ "core/kernel/" path>vocab ] unit-test
+[ "kernel" ] [ "core/kernel/" resource-path path>vocab ] unit-test
index 071f1796769988e8d4f051afcf09f4af1e75c3fe..ab5e8c66b7ed8752d7a7453700e839f594b502c8 100755 (executable)
@@ -1,24 +1,53 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: threads io.files io.monitors init kernel\r
-vocabs.loader tools.vocabs namespaces continuations ;\r
+vocabs vocabs.loader tools.vocabs namespaces continuations\r
+sequences splitting assocs command-line ;\r
 IN: tools.vocabs.monitor\r
 \r
-! Use file system change monitoring to flush the tags/authors\r
-! cache\r
-SYMBOL: vocab-monitor\r
+: vocab-dir>vocab-name ( path -- vocab )\r
+    left-trim-separators right-trim-separators\r
+    { { CHAR: / CHAR: . } { CHAR: \\ CHAR: . } } substitute ;\r
+\r
+: path>vocab-name ( path -- vocab )\r
+    dup ".factor" tail? [ parent-directory ] when ;\r
+\r
+: chop-vocab-root ( path -- path' )\r
+    "resource:" prepend-path (normalize-path)\r
+    dup vocab-roots get\r
+    [ (normalize-path) ] map\r
+    [ head? ] with find nip\r
+    ?head drop ;\r
+\r
+: path>vocab ( path -- vocab )\r
+    chop-vocab-root path>vocab-name vocab-dir>vocab-name ;\r
+\r
+: monitor-loop ( monitor -- )\r
+    #! On OS X, monitors give us the full path, so we chop it\r
+    #! off if its there.\r
+    dup next-change drop path>vocab changed-vocab\r
+    reset-cache\r
+    monitor-loop ;\r
 \r
 : monitor-thread ( -- )\r
-    vocab-monitor get-global\r
-    next-change 2drop\r
-    t sources-changed? set-global reset-cache ;\r
+    [\r
+        [\r
+            "" resource-path t <monitor>\r
+            \r
+            H{ } clone changed-vocabs set-global\r
+            vocabs [ changed-vocab ] each\r
+            \r
+            monitor-loop\r
+        ] with-monitors\r
+    ] ignore-errors ;\r
 \r
-: start-monitor-thread\r
+: start-monitor-thread ( -- )\r
     #! Silently ignore errors during monitor creation since\r
     #! monitors are not supported on all platforms.\r
-    [\r
-        "" resource-path t <monitor> vocab-monitor set-global\r
-        [ monitor-thread t ] "Vocabulary monitor" spawn-server drop\r
-    ] ignore-errors ;\r
+    [ monitor-thread ] "Vocabulary monitor" spawn drop ;\r
 \r
-[ start-monitor-thread ] "tools.vocabs.monitor" add-init-hook\r
+[\r
+    "-no-monitors" cli-args member? [\r
+        start-monitor-thread\r
+    ] unless\r
+] "tools.vocabs.monitor" add-init-hook\r
diff --git a/extra/tools/vocabs/vocabs-tests.factor b/extra/tools/vocabs/vocabs-tests.factor
new file mode 100644 (file)
index 0000000..04e628d
--- /dev/null
@@ -0,0 +1,9 @@
+IN: tools.vocabs.tests
+USING: tools.test tools.vocabs namespaces continuations ;
+
+[ ] [
+    changed-vocabs get-global
+    f changed-vocabs set-global
+    [ t ] [ "kernel" changed-vocab? ] unit-test
+    [ "kernel" changed-vocab ] [ changed-vocabs set-global ] [ ] cleanup
+] unit-test
index 2f941ad2ce5a043168d09cfab217a5c1fa4c19bb..40e79ee01473852a79ebb005da716c076260bdeb 100755 (executable)
@@ -3,7 +3,8 @@
 USING: io.files kernel io.encodings.utf8 vocabs.loader vocabs\r
 sequences namespaces math.parser arrays hashtables assocs\r
 memoize inspector sorting splitting combinators source-files\r
-io debugger continuations compiler.errors init io.crc32 ;\r
+io debugger continuations compiler.errors init io.crc32 \r
+sets ;\r
 IN: tools.vocabs\r
 \r
 : vocab-tests-file ( vocab -- path )\r
@@ -21,55 +22,25 @@ IN: tools.vocabs
 \r
 : vocab-tests ( vocab -- tests )\r
     [\r
-        dup vocab-tests-file [ , ] when*\r
-        vocab-tests-dir [ % ] when*\r
+        [ vocab-tests-file [ , ] when* ]\r
+        [ vocab-tests-dir [ % ] when* ] bi\r
     ] { } make ;\r
 \r
 : vocab-files ( vocab -- seq )\r
     [\r
-        dup vocab-source-path [ , ] when*\r
-        dup vocab-docs-path [ , ] when*\r
-        vocab-tests %\r
+        [ vocab-source-path [ , ] when* ]\r
+        [ vocab-docs-path [ , ] when* ]\r
+        [ vocab-tests % ] tri\r
     ] { } make ;\r
 \r
-: source-modified? ( path -- ? )\r
-    dup source-files get at [\r
-        dup source-file-path\r
-        dup exists? [\r
-            utf8 file-lines lines-crc32\r
-            swap source-file-checksum = not\r
-        ] [\r
-            2drop f\r
-        ] if\r
-    ] [\r
-        exists?\r
-    ] ?if ;\r
-\r
-: modified ( seq quot -- seq )\r
-    [ dup ] swap compose { } map>assoc\r
-    [ nip ] assoc-subset\r
-    [ nip source-modified? ] assoc-subset keys ; inline\r
-\r
-: modified-sources ( vocabs -- seq )\r
-    [ vocab-source-path ] modified ;\r
-\r
-: modified-docs ( vocabs -- seq )\r
-    [ vocab-docs-path ] modified ;\r
-\r
-: to-refresh ( prefix -- modified-sources modified-docs )\r
-    child-vocabs\r
-    dup modified-sources swap modified-docs ;\r
-\r
 : vocab-heading. ( vocab -- )\r
     nl\r
     "==== " write\r
-    dup vocab-name swap vocab write-object ":" print\r
+    [ vocab-name ] [ vocab write-object ] bi ":" print\r
     nl ;\r
 \r
 : load-error. ( triple -- )\r
-    dup first vocab-heading.\r
-    dup second print-error\r
-    drop ;\r
+    [ first vocab-heading. ] [ second print-error ] bi ;\r
 \r
 : load-failures. ( failures -- )\r
     [ load-error. nl ] each ;\r
@@ -88,31 +59,101 @@ SYMBOL: failures
         failures get\r
     ] with-compiler-errors ;\r
 \r
-: do-refresh ( modified-sources modified-docs -- )\r
-    2dup\r
-    [ f swap set-vocab-docs-loaded? ] each\r
-    [ f swap set-vocab-source-loaded? ] each\r
-    append prune require-all load-failures. ;\r
+: source-modified? ( path -- ? )\r
+    dup source-files get at [\r
+        dup source-file-path\r
+        dup exists? [\r
+            utf8 file-lines lines-crc32\r
+            swap source-file-checksum = not\r
+        ] [\r
+            2drop f\r
+        ] if\r
+    ] [\r
+        exists?\r
+    ] ?if ;\r
 \r
-: refresh ( prefix -- ) to-refresh do-refresh ;\r
+SYMBOL: changed-vocabs\r
+\r
+[ f changed-vocabs set-global ] "tools.vocabs" add-init-hook\r
 \r
-SYMBOL: sources-changed?\r
+: changed-vocab ( vocab -- )\r
+    dup vocab changed-vocabs get and\r
+    [ dup changed-vocabs get set-at ] [ drop ] if ;\r
 \r
-[ t sources-changed? set-global ] "tools.vocabs" add-init-hook\r
+: unchanged-vocab ( vocab -- )\r
+    changed-vocabs get delete-at ;\r
 \r
-: refresh-all ( -- )\r
-    "" refresh f sources-changed? set-global ;\r
+: unchanged-vocabs ( vocabs -- )\r
+    [ unchanged-vocab ] each ;\r
+\r
+: changed-vocab? ( vocab -- ? )\r
+    changed-vocabs get dup [ key? ] [ 2drop t ] if ;\r
+\r
+: filter-changed ( vocabs -- vocabs' )\r
+    [ changed-vocab? ] subset ;\r
+\r
+SYMBOL: modified-sources\r
+SYMBOL: modified-docs\r
+\r
+: (to-refresh) ( vocab variable loaded? path -- )\r
+    dup [\r
+        swap [\r
+            pick changed-vocab? [\r
+                source-modified? [ get push ] [ 2drop ] if\r
+            ] [ 3drop ] if\r
+        ] [ drop get push ] if\r
+    ] [ 2drop 2drop ] if ;\r
+\r
+: to-refresh ( prefix -- modified-sources modified-docs unchanged )\r
+    [\r
+        V{ } clone modified-sources set\r
+        V{ } clone modified-docs set\r
+\r
+        child-vocabs [\r
+            [\r
+                [\r
+                    [ modified-sources ]\r
+                    [ vocab-source-loaded? ]\r
+                    [ vocab-source-path ]\r
+                    tri (to-refresh)\r
+                ] [\r
+                    [ modified-docs ]\r
+                    [ vocab-docs-loaded? ]\r
+                    [ vocab-docs-path ]\r
+                    tri (to-refresh)\r
+                ] bi\r
+            ] each\r
+\r
+            modified-sources get\r
+            modified-docs get\r
+        ]\r
+        [ modified-sources get modified-docs get append swap diff ] bi\r
+    ] with-scope ;\r
+\r
+: do-refresh ( modified-sources modified-docs unchanged -- )\r
+    unchanged-vocabs\r
+    [\r
+        [ [ f swap set-vocab-source-loaded? ] each ]\r
+        [ [ f swap set-vocab-docs-loaded? ] each ] bi*\r
+    ]\r
+    [\r
+        append prune\r
+        [ unchanged-vocabs ]\r
+        [ require-all load-failures. ] bi\r
+    ] 2bi ;\r
+\r
+: refresh ( prefix -- ) to-refresh do-refresh ;\r
 \r
-MEMO: (vocab-file-contents) ( path -- lines )\r
-    dup exists? [ utf8 file-lines ] [ drop f ] if ;\r
+: refresh-all ( -- ) "" refresh ;\r
 \r
-: vocab-file-contents ( vocab name -- seq )\r
-    vocab-append-path dup [ (vocab-file-contents) ] when ;\r
+MEMO: vocab-file-contents ( vocab name -- seq )\r
+    vocab-append-path dup\r
+    [ dup exists? [ utf8 file-lines ] [ drop f ] if ] when ;\r
 \r
 : set-vocab-file-contents ( seq vocab name -- )\r
     dupd vocab-append-path [\r
         utf8 set-file-lines\r
-        \ (vocab-file-contents) reset-memoized\r
+        \ vocab-file-contents reset-memoized\r
     ] [\r
         "The " swap vocab-name\r
         " vocabulary was not loaded from the file system"\r
@@ -215,7 +256,7 @@ MEMO: all-vocabs-seq ( -- seq )
         { [ ".test" ?tail ] [ t ] }\r
         { [ "raptor" ?head ] [ t ] }\r
         { [ dup "tools.deploy.app" = ] [ t ] }\r
-        { [ t ] [ f ] }\r
+        [ f ]\r
     } cond nip ;\r
 \r
 : filter-dangerous ( seq -- seq' )\r
@@ -261,7 +302,7 @@ MEMO: all-authors ( -- seq )
 \r
 : reset-cache ( -- )\r
     root-cache get-global clear-assoc\r
-    \ (vocab-file-contents) reset-memoized\r
+    \ vocab-file-contents reset-memoized\r
     \ all-vocabs-seq reset-memoized\r
     \ all-authors reset-memoized\r
     \ all-tags reset-memoized ;\r
index 4d1a4da6b13194870856240ac82a156db2f06863..8a5ab42767d3df122eeed021c52992fa4920821e 100755 (executable)
@@ -72,8 +72,9 @@ M: object add-breakpoint ;
     {
         { [ dup "step-into" word-prop ] [ "step-into" word-prop call ] }
         { [ dup standard-generic? ] [ effective-method (step-into-execute) ] }
+        { [ dup hook-generic? ] [ effective-method (step-into-execute) ] }
         { [ dup primitive? ] [ execute break ] }
-        { [ t ] [ word-def (step-into-quot) ] }
+        [ word-def (step-into-quot) ]
     } cond ;
 
 \ (step-into-execute) t "step-into?" set-word-prop
@@ -153,7 +154,7 @@ SYMBOL: +stopped+
                 { [ dup quotation? ] [ add-breakpoint , \ break , ] }
                 { [ dup array? ] [ add-breakpoint , \ break , ] }
                 { [ dup word? ] [ literalize , \ (step-into-execute) , ] }
-                { [ t ] [ , \ break , ] }
+                [ , \ break , ]
             } cond %
         ] [ ] make
     ] change-frame ;
index 81628684bc0349fd8f7514ea741f324f9e747cd3..5c88187c6c1d2cba2ea977eb4cc5e62e49631520 100755 (executable)
@@ -14,7 +14,7 @@ INSTANCE: avl tree-mixin
 TUPLE: avl-node balance ;
 
 : <avl-node> ( key value -- node )
-    swap <node> 0 avl-node construct-boa tuck set-delegate ;
+    swap <node> 0 avl-node boa tuck set-delegate ;
 
 : change-balance ( node amount -- )
     over avl-node-balance + swap set-avl-node-balance ;
@@ -29,7 +29,7 @@ TUPLE: avl-node balance ;
     avl-node-balance {
         { [ dup zero? ] [ 2drop 0 0 ] }
         { [ over = ] [ neg 0 ] }
-        { [ t ] [ 0 swap ] }
+        [ 0 swap ]
     } cond ;
 
 : double-rotate ( node -- node )
@@ -89,7 +89,7 @@ M: avl set-at ( value key node -- node )
     current-side get over avl-node-balance {
         { [ dup zero? ] [ drop neg over set-avl-node-balance f ] }
         { [ dupd = ] [ drop 0 over set-avl-node-balance t ] }
-        { [ t ] [ dupd neg change-balance rebalance-delete ] }
+        [ dupd neg change-balance rebalance-delete ]
     } cond ;
 
 : avl-replace-with-extremity ( to-replace node -- node shorter? )
diff --git a/extra/trees/avl/tags.txt b/extra/trees/avl/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 7746db85d3a402f8a6b0fbccbd65d13f069a5a93..4b82f86a57b9fd7d7c36c39e99da2ba48e660d62 100644 (file)
@@ -107,7 +107,7 @@ DEFER: (splay)
     2dup get-splay [ 2nip set-node-value ] [
        drop dup inc-count
        2dup splay-split rot
-       >r >r swapd r> node construct-boa r> set-tree-root
+       >r >r swapd r> node boa r> set-tree-root
     ] if ;
 
 : new-root ( value key tree -- )
index e70c874e98c157c8c741946f26f1eeada25f76ea..46391bbd283ef9435bcafc35c03502ea47a2aee5 100644 (file)
@@ -1 +1 @@
-Splay Trees
+Splay trees
index e59bbab1ed69aa5694e1cad1df54b0ee97f65e94..07497b209870ddc41496733ad0f4ac3006b91c33 100755 (executable)
@@ -10,10 +10,10 @@ MIXIN: tree-mixin
 TUPLE: tree root count ;
 
 : <tree> ( -- tree )
-    f 0 tree construct-boa ;
+    f 0 tree boa ;
 
 : construct-tree ( class -- tree )
-    construct-empty <tree> over set-delegate ; inline
+    new <tree> over set-delegate ; inline
 
 INSTANCE: tree tree-mixin
 
@@ -21,7 +21,7 @@ INSTANCE: tree-mixin assoc
 
 TUPLE: node key value left right ;
 : <node> ( key value -- node )
-    f f node construct-boa ;
+    f f node boa ;
 
 SYMBOL: current-side
 
@@ -112,7 +112,7 @@ M: tree set-at ( value key tree -- )
           [ 2drop t ] }
         { [ >r 2nip r> [ tree-call ] 2keep rot ]
           [ drop [ node-key ] keep node-value t ] }
-        { [ t ] [ >r node-right r> find-node ] }
+        [ >r node-right r> find-node ]
     } cond ; inline
 
 M: tree-mixin assoc-find ( tree quot -- key value ? )
index b9593af23918db273b529355092bf8db36db2cbe..680610fbced9cab07946c846a5a69a2a101ac0b7 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: tuple-array example ;
     swap tuple>array length over length - ;
 
 : <tuple-array> ( length example -- tuple-array )
-    prepare-example [ rot * { } new ] keep
+    prepare-example [ rot * { } new-sequence ] keep
     <sliced-groups> tuple-array construct-delegate
     [ set-tuple-array-example ] keep ;
 
@@ -29,7 +29,7 @@ M: tuple-array set-nth ( elt n seq -- )
     tuck >r >r tuple-array-example deconstruct r> r>
     delegate set-nth ;
 
-M: tuple-array new tuple-array-example >tuple <tuple-array> ;
+M: tuple-array new-sequence tuple-array-example >tuple <tuple-array> ;
 
 : >tuple-array ( seq -- tuple-array/seq )
     dup empty? [
index 2419b8febb8e70a1d55644e67e41a596b62fa371..219df5197cfda5fc181ed85d8fbdad5f2b1cc84b 100755 (executable)
@@ -15,4 +15,4 @@ IN: tuple-syntax
     [ scan-object pick rot set-slot parse-slots ] when* ;
 
 : TUPLE{
-    scan-word construct-empty parse-slots parsed ; parsing
+    scan-word new parse-slots parsed ; parsing
index b9a932306aad7c09c6a97aaac0a810069274fdcc..24f93b56fc3db71d445dc0f4e3045cd874db9b7d 100644 (file)
@@ -8,7 +8,7 @@ IN: turtle
 TUPLE: turtle ;
 
 : <turtle> ( -- turtle )
-turtle construct-empty
+turtle new
 { 0 0 0 } clone <pos>
 3 identity-matrix <ori>
 rot
index fa6cc75ba6da3a58e040a247963388f35b98995d..ab6cc35d8ca1d97f31d184c164ecde164f42cc7d 100644 (file)
@@ -5,7 +5,7 @@ IN: ui.clipboards
 
 ! Two text transfer buffers
 TUPLE: clipboard contents ;
-: <clipboard> "" clipboard construct-boa ;
+: <clipboard> "" clipboard boa ;
 
 GENERIC: paste-clipboard ( gadget clipboard -- )
 
index 5b975f40de7076ac783cc32b63671f90a65af9b7..ab0c3015251ad5cc1ff602da257031e79efdbdb1 100755 (executable)
@@ -1,10 +1,10 @@
-! Copyright (C) 2006, 2007 Slava Pestov
+! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien arrays assocs cocoa kernel math cocoa.messages
 cocoa.subclassing cocoa.classes cocoa.views cocoa.application
 cocoa.pasteboard cocoa.types cocoa.windows sequences ui
 ui.gadgets ui.gadgets.worlds ui.gestures core-foundation
-threads ;
+threads combinators ;
 IN: ui.cocoa.views
 
 : send-mouse-moved ( view event -- )
@@ -211,6 +211,40 @@ CLASS: {
     [ [ nip T{ select-all-action } send-action$ ] ui-try ]
 }
 
+! Multi-touch gestures: this is undocumented.
+! http://cocoadex.com/2008/02/nsevent-modifications-swipe-ro.html
+{ "magnifyWithEvent:" "void" { "id" "SEL" "id" }
+    [
+        nip
+        dup -> deltaZ sgn {
+            {  1 [ T{ zoom-in-action } send-action$ ] }
+            { -1 [ T{ zoom-out-action } send-action$ ] }
+            {  0 [ 2drop ] }
+        } case
+    ]
+}
+
+{ "swipeWithEvent:" "void" { "id" "SEL" "id" }
+    [
+        nip
+        dup -> deltaX sgn {
+            {  1 [ T{ left-action } send-action$ ] }
+            { -1 [ T{ right-action } send-action$ ] }
+            {  0
+                [
+                    dup -> deltaY sgn {
+                        {  1 [ T{ up-action } send-action$ ] }
+                        { -1 [ T{ down-action } send-action$ ] }
+                        {  0 [ 2drop ] }
+                    } case
+                ]
+            }
+        } case
+    ]
+}
+
+! "rotateWithEvent:" "void" { "id" "SEL" "id" }}
+
 { "acceptsFirstResponder" "bool" { "id" "SEL" }
     [ 2drop 1 ]
 }
index f73276bbe6de5dfba6c79403a3a076e94e614270..90eb6254cd57bce74153f77935716a0dfd12a8dc 100755 (executable)
@@ -66,7 +66,7 @@ M: word command-description ( word -- str )
     H{ { +nullary+ f } { +listener+ f } { +description+ f } } ;
 
 : define-command ( word hash -- )
-    default-flags swap union >r word-props r> update ;
+    default-flags swap assoc-union >r word-props r> update ;
 
 : command-quot ( target command -- quot )
     dup 1quotation swap +nullary+ word-prop
index 6b548aaf68982f37ea5adc59214a1511050decb9..91d20e9c9992f83aa6c380608d75d49dafc9ad3e 100644 (file)
@@ -7,7 +7,7 @@ IN: ui.gadgets.borders
 TUPLE: border size fill ;
 
 : <border> ( child gap -- border )
-    dup 2array { 0 0 } border construct-boa
+    dup 2array { 0 0 } border boa
     <gadget> over set-delegate
     tuck add-gadget ;
 
index 7e649b7ff7969e6088bb427720b5a17435f772b9..9910082ebfd89ca57690b5d46690621f0dab70a8 100755 (executable)
@@ -40,7 +40,7 @@ button H{
 } set-gestures
 
 : <button> ( gadget quot -- button )
-    button construct-empty
+    button new
     [ set-button-quot ] keep
     [ set-gadget-delegate ] keep ;
 
@@ -55,7 +55,7 @@ C: <button-paint> button-paint
         { [ dup button-pressed? ] [ drop button-paint-pressed ] }
         { [ dup button-selected? ] [ drop button-paint-selected ] }
         { [ dup button-rollover? ] [ drop button-paint-rollover ] }
-        { [ t ] [ drop button-paint-plain ] }
+        [ drop button-paint-plain ]
     } cond ;
 
 M: button-paint draw-interior
@@ -93,7 +93,7 @@ repeat-button H{
 : <repeat-button> ( label quot -- button )
     #! Button that calls the quotation every 100ms as long as
     #! the mouse is held down.
-    repeat-button construct-empty
+    repeat-button new
     [ >r <bevel-button> r> set-gadget-delegate ] keep ;
 
 TUPLE: checkmark-paint color ;
index 4487f4d506e020177ad46405405b53a1a35b4592..28fefbe1ae77c9ec5ebdb9477042c3e672e1a401 100644 (file)
@@ -22,7 +22,7 @@ TUPLE: frame ;
 : @bottom-right 2 2 ;
 
 : <frame> ( -- frame )
-    frame construct-empty
+    frame new
     <frame-grid> <grid> over set-gadget-delegate ;
 
 : (fill-center) ( vec n -- )
index 0a44e5e2678ba8df8633cddb6743275682c4e5b5..dbe06ec8cdeba061241e404dfd876880e6f94b74 100755 (executable)
@@ -1,6 +1,6 @@
 IN: ui.gadgets.tests
 USING: ui.gadgets ui.gadgets.packs ui.gadgets.worlds tools.test
-namespaces models kernel dlists math
+namespaces models kernel dlists math sets
 math.parser ui sequences hashtables assocs io arrays
 prettyprint io.streams.string ;
 
@@ -114,7 +114,7 @@ C: <fooey> fooey
 TUPLE: mock-gadget graft-called ungraft-called ;
 
 : <mock-gadget>
-    0 0 mock-gadget construct-boa <gadget> over set-delegate ;
+    0 0 mock-gadget boa <gadget> over set-delegate ;
 
 M: mock-gadget graft*
     dup mock-gadget-graft-called 1+
index 3ad76b0a16901924653cb22708cc283919d11aaf..15c174d52e8837083281e61eaf3cd53f69ed82d5 100755 (executable)
@@ -111,7 +111,7 @@ M: gadget children-on nip gadget-children ;
 : fast-children-on ( rect axis children -- from to )
     3dup
     >r >r dup rect-loc swap rect-dim v+
-    r> r> (fast-children-on) [ 1+ ] [ 0 ] if*
+    r> r> (fast-children-on) ?1+
     >r
     >r >r rect-loc
     r> r> (fast-children-on) 0 or
@@ -378,7 +378,7 @@ SYMBOL: in-layout?
     {
         { [ 2dup eq? ] [ 2drop t ] }
         { [ dup not ] [ 2drop f ] }
-        { [ t ] [ gadget-parent child? ] }
+        [ gadget-parent child? ]
     } cond ;
 
 GENERIC: focusable-child* ( gadget -- child/t )
index d3f4339a87d0bacbdc9d782fd9796f82edb52f8c..111a78b215c6a49931fcfc2a71f2207c1b7f901b 100755 (executable)
@@ -11,7 +11,7 @@ IN: ui.gadgets.labelled
 TUPLE: labelled-gadget content ;
 
 : <labelled-gadget> ( gadget title -- newgadget )
-    labelled-gadget construct-empty
+    labelled-gadget new
     [
         <label> dup reverse-video-theme f track,
         g-> set-labelled-gadget-content 1 track,
@@ -50,7 +50,7 @@ TUPLE: closable-gadget content ;
     [ [ closable-gadget? ] is? ] find-parent ;
 
 : <closable-gadget> ( gadget title quot -- gadget )
-    closable-gadget construct-empty
+    closable-gadget new
     [
         <title-bar> @top frame,
         g-> set-closable-gadget-content @center frame,
index fedacbd2afe7706914619bf971fcb89e1c005dd5..bff0ca10adb6ef8a63fe4fa879338371f78021a2 100755 (executable)
@@ -46,7 +46,7 @@ M: pane gadget-selection
     selection-color swap set-pane-selection-color ;
 
 : <pane> ( -- pane )
-    pane construct-empty
+    pane new
     <pile> over set-delegate
     <shelf> over set-pane-prototype
     <pile> <incremental> over add-output
@@ -88,7 +88,7 @@ C: <pane-stream> pane-stream
     dup gadget-children {
         { [ dup empty? ] [ 2drop "" <label> ] }
         { [ dup length 1 = ] [ nip first ] }
-        { [ t ] [ drop ] }
+        [ drop ]
     } cond ;
 
 : smash-pane ( pane -- gadget ) pane-output smash-line ;
index 82ddeba3c0fcdbeecd3212c8877557fab93c6670..78e4deda533f6fce7802881cc90ec3b1e194fb27 100644 (file)
@@ -25,7 +25,7 @@ TUPLE: presentation object hook ;
     dup presentation-object over show-summary button-update ;
 
 : <presentation> ( label object -- button )
-    presentation construct-empty
+    presentation new
     [ drop ] over set-presentation-hook
     [ set-presentation-object ] keep
     swap [ invoke-primary ] <roll-button>
index d4a189589438e520b91bc81f138ca04505af5a1e..396a494ef3a4dd6bde55a94c4884497412c9e81e 100755 (executable)
@@ -119,7 +119,7 @@ scroller H{
         { [ dup t eq? ] [ drop (scroll>bottom) ] }
         { [ dup rect? ] [ swap (scroll>rect) ] }
         { [ dup ] [ swap (scroll>gadget) ] }
-        { [ t ] [ drop dup scroller-value swap scroll ] }
+        [ drop dup scroller-value swap scroll ]
     } cond ;
 
 M: scroller layout*
index 173c5c9cac52c71db0267e129ffd2fc46aff0ad4..d9afce15a7442c9b8f4ffb26dcd6d8eb9b49778f 100755 (executable)
@@ -69,7 +69,7 @@ M: value-ref finish-editing
 } define-command
 
 : <slot-editor> ( ref -- gadget )
-    slot-editor construct-empty
+    slot-editor new
     [ set-slot-editor-ref ] keep
     [
         toolbar,
@@ -118,7 +118,7 @@ TUPLE: editable-slot printer ref ;
 } set-gestures
 
 : <editable-slot> ( gadget ref -- editable-slot )
-    editable-slot construct-empty
+    editable-slot new
     { 1 0 } <track> over set-gadget-delegate
     [ drop <gadget> ] over set-editable-slot-printer
     [ set-editable-slot-ref ] keep
index e52eff453aea0688ebd65496d6e182018308bcfc..f68a70c2bd5c312d0efde2d9fe31b83a575accb8 100755 (executable)
@@ -3,7 +3,7 @@
 USING: arrays assocs kernel math models namespaces
 sequences words strings system hashtables math.parser
 math.vectors classes.tuple classes ui.gadgets boxes
-calendar alarms symbols combinators ;
+calendar alarms symbols combinators sets ;
 IN: ui.gestures
 
 : set-gestures ( class hash -- ) "gestures" set-word-prop ;
@@ -39,11 +39,19 @@ TUPLE: lose-focus ;         C: <lose-focus> lose-focus
 TUPLE: gain-focus ;         C: <gain-focus> gain-focus
 
 ! Higher-level actions
-TUPLE: cut-action ;        C: <cut-action> cut-action
-TUPLE: copy-action ;       C: <copy-action> copy-action
-TUPLE: paste-action ;      C: <paste-action> paste-action
-TUPLE: delete-action ;     C: <delete-action> delete-action
-TUPLE: select-all-action ; C: <select-all-action> select-all-action
+TUPLE: cut-action ;         C: <cut-action> cut-action
+TUPLE: copy-action ;        C: <copy-action> copy-action
+TUPLE: paste-action ;       C: <paste-action> paste-action
+TUPLE: delete-action ;      C: <delete-action> delete-action
+TUPLE: select-all-action ;  C: <select-all-action> select-all-action
+
+TUPLE: left-action ;        C: <left-action> left-action
+TUPLE: right-action ;       C: <right-action> right-action
+TUPLE: up-action ;          C: <up-action> up-action
+TUPLE: down-action ;        C: <down-action> down-action
+
+TUPLE: zoom-in-action ;  C: <zoom-in-action> zoom-in-action
+TUPLE: zoom-out-action ; C: <zoom-out-action> zoom-out-action
 
 : generalize-gesture ( gesture -- newgesture )
     tuple>array 1 head* >tuple ;
@@ -54,7 +62,7 @@ SYMBOLS: C+ A+ M+ S+ ;
 TUPLE: key-down mods sym ;
 
 : <key-gesture> ( mods sym action? class -- mods' sym' )
-    >r [ S+ rot remove swap ] unless r> construct-boa ; inline
+    >r [ S+ rot remove swap ] unless r> boa ; inline
 
 : <key-down> ( mods sym action? -- key-down )
     key-down <key-gesture> ;
@@ -191,7 +199,7 @@ SYMBOL: drag-timer
         { [ multi-click-button?   not ] [ f ] }
         { [ multi-click-position? not ] [ f ] }
         { [ multi-click-position? not ] [ f ] }
-        { [ t ] [ t ] }
+        [ t ]
     } cond nip ;
 
 : update-click# ( button -- )
@@ -273,4 +281,16 @@ M: button-down gesture>string
         button-down-# [ " " % # ] when*
     ] "" make ;
 
+M: left-action gesture>string drop "Swipe left" ;
+
+M: right-action gesture>string drop "Swipe right" ;
+
+M: up-action gesture>string drop "Swipe up" ;
+
+M: down-action gesture>string drop "Swipe down" ;
+
+M: zoom-in-action gesture>string drop "Zoom in" ;
+
+M: zoom-out-action gesture>string drop "Zoom out (pinch)" ;
+
 M: object gesture>string drop f ;
index 1e3d08f164e48fe4cfa9de0985613aa6b84794fd..1072340cced626617acef707ac43751db3272182 100755 (executable)
@@ -5,7 +5,7 @@ io.streams.string math help help.markup ;
 
 : my-pprint pprint ;
 
-[ drop t ] \ my-pprint [ ] [ ] f operation construct-boa "op" set
+[ drop t ] \ my-pprint [ ] [ ] f operation boa "op" set
 
 [ [ 3 my-pprint ] ] [
     3 "op" get operation-command command-quot
@@ -13,7 +13,7 @@ io.streams.string math help help.markup ;
 
 [ "3" ] [ [ 3 "op" get invoke-command ] with-string-writer ] unit-test
 
-[ drop t ] \ my-pprint [ ] [ editor-string ] f operation construct-boa
+[ drop t ] \ my-pprint [ ] [ editor-string ] f operation boa
 "op" set
 
 [ "\"4\"" ] [
index a9009e386e7568ba4f9e4c266d5c6eab09a69887..26200ea96fcd007b13f7a2a270d5a71ffd293c51 100755 (executable)
@@ -54,7 +54,7 @@ SYMBOL: operations
     H{ { +keyboard+ f } { +primary+ f } { +secondary+ f } } ;
 
 : define-operation ( pred command flags -- )
-    default-flags swap union
+    default-flags swap assoc-union
     dupd define-command <operation>
     operations get push ;
 
index 152b1bff44535abdc7cd2af3956a6a22ded59a0e..cacd0a8d3ac89e6d086db3441a74d2a267faceba 100644 (file)
@@ -80,7 +80,7 @@ DEFER: draw-gadget
     {
         { [ dup gadget-visible? not ] [ drop ] }
         { [ dup gadget-clipped? not ] [ (draw-gadget) ] }
-        { [ t ] [ [ (draw-gadget) ] with-clipping ] }
+        [ [ (draw-gadget) ] with-clipping ]
     } cond ;
 
 ! Pen paint properties
index 693c161367cb9daa631611ab004400c81e26b8e7..b8a6f7ec2c94074a97f6057e036d46f3f6714f37 100755 (executable)
@@ -21,7 +21,7 @@ TUPLE: browser-gadget pane history ;
     swap set-browser-gadget-history ;
 
 : <browser-gadget> ( -- gadget )
-    browser-gadget construct-empty
+    browser-gadget new
     dup init-history [
         toolbar,
         g <help-pane> g-> set-browser-gadget-pane
@@ -76,3 +76,8 @@ browser-gadget "toolbar" f {
     { T{ key-down f { A+ } "v" } com-vocabularies }
     { T{ key-down f f "F1" } browser-help }
 } define-command-map
+
+browser-gadget "multi-touch" f {
+    { T{ left-action } com-back }
+    { T{ right-action } com-forward }
+} define-command-map
index a7c173799a63be8ba0d48d0e4156d5992e183bcf..8cb581b1c22b8468fa9aec8b81cdd8f9adf8d346 100644 (file)
@@ -21,7 +21,7 @@ TUPLE: debugger restarts ;
     ] make-filled-pile ;
 
 : <debugger> ( error restarts restart-hook -- gadget )
-    debugger construct-empty
+    debugger new
     [
         toolbar,
         <restart-list> g-> set-debugger-restarts
index 522c26e92eb579fcc6ac62643eac343bd32ca3d8..d01f7ab1398fe1a8683842cab7c7937615328d3c 100755 (executable)
@@ -104,7 +104,7 @@ deploy-gadget "toolbar" f {
     g <toolbar> { 10 10 } over set-pack-gap gadget, ;
 
 : <deploy-gadget> ( vocab -- gadget )
-    f deploy-gadget construct-boa [
+    f deploy-gadget boa [
         dup <deploy-settings>
         g-> set-deploy-gadget-settings gadget,
         buttons,
index 70a01c7c12bfdcc5613405f08c21a8707cc1ad6c..e4079a331edc0ffe095b75fadecf385d23c931d6 100644 (file)
@@ -14,7 +14,7 @@ TUPLE: inspector-gadget object pane ;
     ] with-pane ;
 
 : <inspector-gadget> ( -- gadget )
-    inspector-gadget construct-empty
+    inspector-gadget new
     [
         toolbar,
         <pane> g-> set-inspector-gadget-pane <scroller> 1 track,
@@ -43,5 +43,9 @@ inspector-gadget "toolbar" f {
     { T{ key-down f f "F1" } inspector-help }
 } define-command-map
 
+inspector-gadget "multi-touch" f {
+    { T{ left-action } &back }
+} define-command-map
+
 M: inspector-gadget tool-scroller
     inspector-gadget-pane find-scroller ;
index fe0a6542177994c847b5cb85d87b36762c8c9d41..99c005451db6f2614fd19e11cb864ddefa73a197 100755 (executable)
@@ -1,4 +1,29 @@
 IN: ui.tools.interactor.tests
-USING: ui.tools.interactor tools.test ;
+USING: ui.tools.interactor ui.gadgets.panes namespaces
+ui.gadgets.editors concurrency.promises threads listener
+tools.test kernel calendar parser ;
 
-\ <interactor> must-infer
+[
+    \ <interactor> must-infer
+
+    [ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test
+
+    [ ] [ "[ 1 2 3" "interactor" get set-editor-string ] unit-test
+
+    [ ] [ <promise> "promise" set ] unit-test
+
+    [
+        "interactor" get stream-read-quot "promise" get fulfill
+    ] "Interactor test" spawn drop
+
+    ! This should not throw an exception
+    [ ] [ "interactor" get evaluate-input ] unit-test
+
+    [ ] [ [ "interactor" get interactor-busy? ] [ yield ] [ ] while ] unit-test
+
+    [ ] [ "[ 1 2 3 ]" "interactor" get set-editor-string ] unit-test
+
+    [ ] [ "interactor" get evaluate-input ] unit-test
+
+    [ [ [ 1 2 3 ] ] ] [ "promise" get 5 seconds ?promise-timeout ] unit-test
+] with-interactive-vocabs
index 8232094e769a6bed7a3ee256cd5d753e00b2da1e..3837ce2de164f73575c62f0da2f5cfbd0d7c769c 100755 (executable)
@@ -138,24 +138,26 @@ M: interactor stream-read-partial
         drop parse-lines-interactive
     ] [
         2nip
-        dup delegate unexpected-eof? [ drop f ] when
+        dup parse-error? [
+            dup error>> unexpected-eof? [ drop f ] when
+        ] when
     ] recover ;
 
 : handle-interactive ( lines interactor -- quot/f ? )
     tuck try-parse {
         { [ dup quotation? ] [ nip t ] }
         { [ dup not ] [ drop "\n" swap user-input f f ] }
-        { [ t ] [ handle-parse-error f f ] }
+        [ handle-parse-error f f ]
     } cond ;
 
 M: interactor stream-read-quot
     [ interactor-yield ] keep {
         { [ over not ] [ drop ] }
         { [ over callable? ] [ drop ] }
-        { [ t ] [
+        [
             [ handle-interactive ] keep swap
             [ interactor-finish ] [ nip stream-read-quot ] if
-        ] }
+        ]
     } cond ;
 
 M: interactor pref-dim*
index 91f7b0ec5dba9e183ab68ff396fcd51f736d527f..6c2a5e317d67dc19425a4804baaeb7563dffa08f 100755 (executable)
@@ -28,7 +28,7 @@ TUPLE: input-scroller ;
 
 : <input-scroller> ( interactor -- scroller )
     <scroller>
-    input-scroller construct-empty
+    input-scroller new
     [ set-gadget-delegate ] keep ;
 
 M: input-scroller pref-dim*
@@ -119,7 +119,7 @@ M: tuple-dispatch-engine-word word-completion-string
     {
         { [ dup not ] [ 2drop ] }
         { [ 2dup memq? ] [ 2drop ] }
-        { [ t ] [ push ] }
+        [ push ]
     } cond ;
 
 : insert-word ( word -- )
@@ -136,7 +136,7 @@ M: tuple-dispatch-engine-word word-completion-string
 TUPLE: stack-display ;
 
 : <stack-display> ( -- gadget )
-    stack-display construct-empty
+    stack-display new
     g workspace-listener swap [
         dup <toolbar> f track,
         listener-gadget-stack [ stack. ]
@@ -178,7 +178,7 @@ M: stack-display tool-scroller
     f <model> swap set-listener-gadget-stack ;
 
 : <listener-gadget> ( -- gadget )
-    listener-gadget construct-empty dup init-listener
+    listener-gadget new dup init-listener
     [ listener-output, listener-input, ] { 0 1 } build-track ;
 
 : listener-help "ui-listener" help-window ;
index cceebbec8b41ab7db05e0f06fdf116dc7f8f6e1b..8b8d2c07a3d314b9c53e146558789abac584d4ec 100755 (executable)
@@ -8,7 +8,7 @@ IN: ui.tools.profiler
 TUPLE: profiler-gadget pane ;
 
 : <profiler-gadget> ( -- gadget )
-    profiler-gadget construct-empty
+    profiler-gadget new
     [
         toolbar,
         <pane> g-> set-profiler-gadget-pane
index 23697bbf3facb299834b30afcfdf713a2bb4f6bc..b18c0c1ad689af4cdace8cbf6a1dbad25817e579 100755 (executable)
@@ -57,7 +57,7 @@ search-field H{
     swap <list> ;
 
 : <live-search> ( string seq limited? presenter -- gadget )
-    live-search construct-empty
+    live-search new
     [
         <search-field> g-> set-live-search-field f track,
         <search-list> g-> set-live-search-list
index 57ad16bf70dcdde67589ba8ea0ad47ff9d2de4e6..4a8e1ddf4a01be34c929414ed7de5d7a3420afdb 100755 (executable)
@@ -2,8 +2,9 @@ USING: editors help.markup help.syntax inspector io listener
 parser prettyprint tools.profiler tools.walker ui.commands
 ui.gadgets.editors ui.gadgets.panes ui.gadgets.presentations
 ui.gadgets.slots ui.operations ui.tools.browser
-ui.tools.interactor ui.tools.listener ui.tools.operations
-ui.tools.profiler ui.tools.walker ui.tools.workspace vocabs ;
+ui.tools.interactor ui.tools.inspector ui.tools.listener
+ui.tools.operations ui.tools.profiler ui.tools.walker
+ui.tools.workspace vocabs ;
 IN: ui.tools
 
 ARTICLE: "ui-presentations" "Presentations in the UI"
@@ -46,12 +47,14 @@ $nl
 $nl
 "The slot editor has a toolbar containing various commands."
 { $command-map slot-editor "toolbar" }
+{ $command-map inspector-gadget "multi-touch" }
 "The following commands are also available."
 { $command-map source-editor "word" } ;
 
 ARTICLE: "ui-browser" "UI browser"
 "The browser is used to display Factor code, documentation, and vocabularies."
 { $command-map browser-gadget "toolbar" }
+{ $command-map browser-gadget "multi-touch" }
 "Browsers are instances of " { $link browser-gadget } "." ;
 
 ARTICLE: "ui-profiler" "UI profiler" 
@@ -110,6 +113,7 @@ ARTICLE: "ui-workspace-keys" "UI keyboard shortcuts"
 { $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 } "." ;
 
index d71b6574910721850c16dba3b08ec1614e6ffc02..494e9d67370af23fa086bc45f802eb9d12528122 100755 (executable)
@@ -70,6 +70,11 @@ workspace "tool-switching" f {
     { T{ key-down f { A+ } "4" } com-profiler }
 } define-command-map
 
+workspace "multi-touch" f {
+    { T{ zoom-out-action } com-listener }
+    { T{ up-action } refresh-all }
+} define-command-map
+
 \ workspace-window
 H{ { +nullary+ t } } define-command
 
index 3c3ff9da44120ea5abcd1681d5496b37c69232c5..d32d110871a8f281eb10b9edd58c026e68b37562 100755 (executable)
@@ -43,7 +43,7 @@ TUPLE: variables-gadget ;
 
 : <variables-gadget> ( model -- gadget )
     <namestack-display> <scroller>
-    variables-gadget construct-empty
+    variables-gadget new
     [ set-gadget-delegate ] keep ;
 
 M: variables-gadget pref-dim* drop { 400 400 } ;
index dbd2ce15ac2299aecc6bc4c4055e83779ca43a56..edf4a5bb869d74ffc83957df2444d6acb437c782 100755 (executable)
@@ -56,7 +56,7 @@ M: walker-gadget focusable-child*
     [ walker-state-string ] curry <filter> <label-control> ;
 
 : <walker-gadget> ( status continuation thread -- gadget )
-    over <traceback-gadget> f walker-gadget construct-boa [
+    over <traceback-gadget> f walker-gadget boa [
         toolbar,
         g walker-gadget-status self <thread-status> f track,
         g walker-gadget-traceback 1 track,
@@ -81,7 +81,7 @@ walker-gadget "toolbar" f {
     {
         { [ dup walker-gadget? not ] [ 2drop f ] }
         { [ dup walker-gadget-closing? ] [ 2drop f ] }
-        { [ t ] [ walker-gadget-thread eq? ] }
+        [ walker-gadget-thread eq? ]
     } cond ;
 
 : find-walker-window ( thread -- world/f )
index 72f1404ee5698b8208c1deec09b5b8827e7e39b8..e3aff92109a87c967bd7e5a9ef404455d1003a2f 100644 (file)
@@ -9,7 +9,7 @@ TUPLE: node value children ;
 : traverse-step ( path gadget -- path' gadget' )
     >r unclip r> gadget-children ?nth ;
 
-: make-node ( quot -- ) { } make node construct-boa , ; inline
+: make-node ( quot -- ) { } make node boa , ; inline
 
 : traverse-to-path ( topath gadget -- )
     dup not [
@@ -70,7 +70,7 @@ DEFER: (gadget-subtree)
         { [ pick empty? ] [ rot drop traverse-to-path ] }
         { [ over empty? ] [ nip traverse-from-path ] }
         { [ pick first pick first = ] [ traverse-child ] }
-        { [ t ] [ traverse-middle ] }
+        [ traverse-middle ]
     } cond ;
 
 : gadget-subtree ( frompath topath gadget -- seq )
index 6286297f68060069f1bb3adc3b6480139426998c..946fe283aa6ef2cb244062842bcd9677ec459661 100755 (executable)
@@ -4,7 +4,7 @@ USING: arrays assocs io kernel math models namespaces
 prettyprint dlists sequences threads sequences words
 debugger ui.gadgets ui.gadgets.worlds ui.gadgets.tracks
 ui.gestures ui.backend ui.render continuations init combinators
-hashtables concurrency.flags ;
+hashtables concurrency.flags sets ;
 IN: ui
 
 ! Assoc mapping aliens to gadgets
index e0c9f24122d4e3b7ce297e684a439126d3410e7e..6229fc9a6555973b07c8f002c9b4590d41ceb938 100755 (executable)
@@ -7,7 +7,7 @@ vectors words windows.kernel32 windows.gdi32 windows.user32
 windows.opengl32 windows.messages windows.types windows.nt
 windows threads libc combinators continuations command-line
 shuffle opengl ui.render unicode.case ascii math.bitfields
-locals symbols ;
+locals symbols accessors ;
 IN: ui.windows
 
 SINGLETON: windows-ui-backend
@@ -203,8 +203,18 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
     wParam keystroke>gesture <key-up>
     hWnd window-focus send-gesture drop ;
 
+: set-window-active ( hwnd uMsg wParam lParam ? -- n )
+    >r 4dup r> 2nip nip
+    swap window set-world-active? DefWindowProc ;
+
 : handle-wm-syscommand ( hWnd uMsg wParam lParam -- n )
-    dup alpha? [ 4drop 0 ] [ DefWindowProc ] if ;
+    {
+        { [ over SC_MINIMIZE = ] [ f set-window-active ] }
+        { [ over SC_RESTORE = ] [ t set-window-active ] }
+        { [ over SC_MAXIMIZE = ] [ t set-window-active ] }
+        { [ dup alpha? ] [ 4drop 0 ] }
+        { [ t ] [ DefWindowProc ] }
+    } cond ;
 
 : cleanup-window ( handle -- )
     dup win-title [ free ] when*
@@ -381,11 +391,11 @@ SYMBOL: trace-messages?
         { [ windows get empty? ] [ drop ] }
         { [ dup peek-message? ] [ ui-wait event-loop ] }
         { [ dup MSG-message WM_QUIT = ] [ drop ] }
-        { [ t ] [
+        [
             dup TranslateMessage drop
             dup DispatchMessage drop
             event-loop
-        ] }
+        ]
     } cond ;
 
 : register-wndclassex ( -- class )
index 3ad10a6991b0bbdb033b7ff3c3313a5651af1581..c04427185390bed4441730d029297eb76f9f1afa 100755 (executable)
@@ -133,7 +133,7 @@ M: world selection-notify-event
     {
         { [ dup XA_PRIMARY = ] [ drop selection get ] }
         { [ dup XA_CLIPBOARD = ] [ drop clipboard get ] }
-        { [ t ] [ drop <clipboard> ] }
+        [ drop <clipboard> ]
     } cond ;
 
 : encode-clipboard ( string type -- bytes )
@@ -156,7 +156,7 @@ M: world selection-request-event
         { [ dup supported-type? ] [ drop dup set-selection-prop send-notify-success ] }
         { [ dup "TARGETS" x-atom = ] [ drop dup set-targets-prop send-notify-success ] }
         { [ dup "TIMESTAMP" x-atom = ] [ drop dup set-timestamp-prop send-notify-success ] }
-        { [ t ] [ drop send-notify-failure ] }
+        [ drop send-notify-failure ]
     } cond ;
 
 M: x11-ui-backend (close-window) ( handle -- )
index 7bb5776e786847745e8a4051cd8f30d3e7ae22b9..ee3c8729c4bb1171f93ca7e0993ffef5359399b2 100644 (file)
@@ -21,7 +21,7 @@ CATEGORY: grapheme-control Zl Zp Cc Cf ;
     } case ;
 
 : trim-blank ( str -- newstr )
-    dup [ blank? not ] find-last 1+* head ;
+    [ blank? ] right-trim ;
 
 : process-other-extend ( lines -- set )
     [ "#" split1 drop ";" split1 drop trim-blank ] map
@@ -43,7 +43,7 @@ CATEGORY: (extend) Me Mn ;
         { [ dup jamo? ] [ jamo-class ] }
         { [ dup grapheme-control? ] [ control-class ] }
         { [ extend? ] [ Extend ] }
-        { [ t ] [ Any ] }
+        [ Any ]
     } cond ;
 
 : init-grapheme-table ( -- table )
@@ -110,8 +110,7 @@ VALUE: grapheme-table
 
 : last-grapheme ( str -- i )
     unclip-last-slice grapheme-class swap
-    [ grapheme-class dup rot grapheme-break? ] find-last-index
-    nip -1 or 1+ ;
+    [ grapheme-class dup rot grapheme-break? ] find-last-index ?1+ nip ;
 
 [
     other-extend-lines process-other-extend \ other-extend set-value
index 06d22f0f6326790829773e4f1c2b6128db71d4d2..d0506a6a46f42295bb5d1a336822d9ba58de0aa9 100755 (executable)
@@ -51,7 +51,7 @@ SYMBOL: locale ! Just casing locale, or overall?
             drop dot-over =
             dup CHAR: i HEX: 131 ? ,
         ] }
-        { [ t ] [ , drop f ] }
+        [ , drop f ]
     } cond ;
 
 : turk>lower ( string -- lower-i )
index ba9c0370cce4e1f4a5d871dbf894cd175dc907c1..58d836464c6963666162067509c2d1c2916ba8f5 100755 (executable)
@@ -12,9 +12,6 @@ IN: unicode.data
 >>
 
 ! Convenience functions
-: 1+* ( n/f _ -- n+1 )
-    drop [ 1+ ] [ 0 ] if* ;
-
 : ?between? ( n/f from to -- ? )
     pick [ between? ] [ 3drop f ] if ;
 
@@ -138,7 +135,7 @@ load-data
 dup process-names \ name-map set-value
 13 over process-data \ simple-lower set-value
 12 over process-data tuck \ simple-upper set-value
-14 over process-data swapd union \ simple-title set-value
+14 over process-data swapd assoc-union \ simple-title set-value
 dup process-combining \ class-map set-value
 dup process-canonical \ canonical-map set-value
     \ combine-map set-value
index 951430b2b5c246d4e58e6b52649f08a5681ac25f..34c329b55cc9b24f1c05c305e16cdd4a92f24603 100644 (file)
@@ -67,7 +67,7 @@ IN: unicode.normalize
     0 reorder-loop ;
 
 : reorder-back ( string i -- )
-    over [ non-starter? not ] find-last* 1+* reorder-next 2drop ;
+    over [ non-starter? not ] find-last* drop ?1+ reorder-next 2drop ;
 
 : decompose ( string quot -- decomposed )
     ! When there are 8 and 32-bit strings, this'll be
index cf53ceaee3dde0bb4208c8bb7ab5a89cf770ab78..32baf9e7ed3e27612c3e33752dd354672abe8aaa 100755 (executable)
@@ -1,6 +1,6 @@
 USING: arrays io kernel math namespaces splitting prettyprint
 sequences sorting vectors words inverse inspector shuffle
-math.functions ;
+math.functions sets ;
 IN: units
 
 TUPLE: dimensioned value top bot ;
@@ -8,7 +8,7 @@ TUPLE: dimensioned value top bot ;
 TUPLE: dimensions-not-equal ;
 
 : dimensions-not-equal ( -- * )
-    \ dimensions-not-equal construct-empty throw ;
+    \ dimensions-not-equal new throw ;
 
 M: dimensions-not-equal summary drop "Dimensions do not match" ;
 
@@ -19,13 +19,13 @@ M: dimensions-not-equal summary drop "Dimensions do not match" ;
     [ remove-one ] curry bi@ ;
 
 : symbolic-reduce ( seq seq -- seq seq )
-    2dup seq-intersect dup empty?
+    2dup intersect dup empty?
     [ drop ] [ first 2remove-one symbolic-reduce ] if ;
 
 : <dimensioned> ( n top bot -- obj )
     symbolic-reduce
     [ natural-sort ] bi@
-    dimensioned construct-boa ;
+    dimensioned boa ;
 
 : >dimensioned< ( d -- n top bot )
     { dimensioned-value dimensioned-top dimensioned-bot }
index 342047d9aff7defe329b00e649e230729362e0cb..cb1c93987888ef86fb8be22d9141fb890a219c1c 100644 (file)
@@ -10,23 +10,13 @@ IN: unix.stat
 
 : S_IFMT   OCT: 170000 ; ! These bits determine file type.
 
-: S_IFDIR  OCT:  40000 ;    ! Directory.
-: S_IFCHR  OCT:  20000 ;    ! Character device.
-: S_IFBLK  OCT:  60000 ;    ! Block device.
-: S_IFREG  OCT: 100000 ;    ! Regular file.
-: S_IFIFO  OCT: 010000 ;    ! FIFO.
-: S_IFLNK  OCT: 120000 ;    ! Symbolic link.
-: S_IFSOCK OCT: 140000 ;    ! Socket.
-
-: S_ISTYPE ( mode mask -- val ) >r S_IFMT bitand r> = ;
-
-: S_ISREG  ( mode -- value ) S_IFREG S_ISTYPE ;
-: S_ISDIR  ( mode -- value ) S_IFDIR S_ISTYPE ;
-: S_ISCHR  ( mode -- value ) S_IFCHR S_ISTYPE ;
-: S_ISBLK  ( mode -- value ) S_IFBLK S_ISTYPE ;
-: S_ISFIFO ( mode -- value ) S_IFIFO S_ISTYPE ;
-: S_ISLNK  ( mode -- value ) S_IFLNK S_ISTYPE ;
-: S_ISSOCK ( mode -- value ) S_IFSOCK S_ISTYPE ;
+: S_IFDIR  OCT:  40000 ; inline   ! Directory.
+: S_IFCHR  OCT:  20000 ; inline   ! Character device.
+: S_IFBLK  OCT:  60000 ; inline   ! Block device.
+: S_IFREG  OCT: 100000 ; inline   ! Regular file.
+: S_IFIFO  OCT: 010000 ; inline   ! FIFO.
+: S_IFLNK  OCT: 120000 ; inline   ! Symbolic link.
+: S_IFSOCK OCT: 140000 ; inline   ! Socket.
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! File Access Permissions
index 28091d3d9db64feb7d578fe7fb12084d2f23915c..0d2f164c8de520244ae0fbcc039a208cec3a8acc 100644 (file)
@@ -61,6 +61,133 @@ LIBRARY: advapi32
 : CRYPT_MACHINE_KEYSET HEX: 20 ; inline
 : CRYPT_SILENT         HEX: 40 ; inline
 
+C-STRUCT: ACL
+    { "BYTE" "AclRevision" }
+    { "BYTE" "Sbz1" }
+    { "WORD" "AclSize" }
+    { "WORD" "AceCount" }
+    { "WORD" "Sbz2" } ;
+
+TYPEDEF: ACL* PACL
+
+: ACCESS_ALLOWED_ACE_TYPE 0 ; inline
+: ACCESS_DENIED_ACE_TYPE 1 ; inline
+: SYSTEM_AUDIT_ACE_TYPE 2 ; inline
+: SYSTEM_ALARM_ACE_TYPE 3 ; inline
+
+: OBJECT_INHERIT_ACE HEX: 1 ; inline
+: CONTAINER_INHERIT_ACE HEX: 2 ; inline
+: NO_PROPAGATE_INHERIT_ACE HEX: 4 ; inline
+: INHERIT_ONLY_ACE HEX: 8 ; inline
+: VALID_INHERIT_FLAGS HEX: f ; inline
+
+C-STRUCT: ACE_HEADER
+    { "BYTE" "AceType" }
+    { "BYTE" "AceFlags" }
+    { "WORD" "AceSize" } ;
+
+TYPEDEF: ACE_HEADER* PACE_HEADER
+
+C-STRUCT: ACCESS_ALLOWED_ACE
+    { "ACE_HEADER" "Header" }
+    { "DWORD" "Mask" }
+    { "DWORD" "SidStart" } ;
+
+TYPEDEF: ACCESS_ALLOWED_ACE* PACCESS_ALLOWED_ACE
+
+C-STRUCT: ACCESS_DENIED_ACE
+    { "ACE_HEADER" "Header" }
+    { "DWORD" "Mask" }
+    { "DWORD" "SidStart" } ;
+TYPEDEF: ACCESS_DENIED_ACE* PACCESS_DENIED_ACE
+
+
+C-STRUCT: SYSTEM_AUDIT_ACE
+    { "ACE_HEADER" "Header" }
+    { "DWORD" "Mask" }
+    { "DWORD" "SidStart" } ;
+
+TYPEDEF: SYSTEM_AUDIT_ACE* PSYSTEM_AUDIT_ACE
+
+C-STRUCT: SYSTEM_ALARM_ACE
+    { "ACE_HEADER" "Header" }
+    { "DWORD" "Mask" }
+    { "DWORD" "SidStart" } ;
+
+TYPEDEF: SYSTEM_ALARM_ACE* PSYSTEM_ALARM_ACE
+
+C-STRUCT: ACCESS_ALLOWED_CALLBACK_ACE
+    { "ACE_HEADER" "Header" }
+    { "DWORD" "Mask" }
+    { "DWORD" "SidStart" } ;
+
+TYPEDEF: ACCESS_ALLOWED_CALLBACK_ACE* PACCESS_ALLOWED_CALLBACK_ACE
+
+
+! typedef enum _TOKEN_INFORMATION_CLASS {
+: TokenUser 1 ; inline
+: TokenGroups 2 ; inline
+: TokenPrivileges 3 ; inline
+: TokenOwner 4 ; inline
+: TokenPrimaryGroup 5 ; inline
+: TokenDefaultDacl 6 ; inline
+: TokenSource 7 ; inline
+: TokenType 8 ; inline
+: TokenImpersonationLevel 9 ; inline
+: TokenStatistics 10 ; inline
+: TokenRestrictedSids 11 ; inline
+: TokenSessionId 12 ; inline
+: TokenGroupsAndPrivileges 13 ; inline
+: TokenSessionReference 14 ; inline
+: TokenSandBoxInert 15 ; inline
+! } TOKEN_INFORMATION_CLASS;
+
+: DELETE                     HEX: 00010000 ; inline
+: READ_CONTROL               HEX: 00020000 ; inline
+: WRITE_DAC                  HEX: 00040000 ; inline
+: WRITE_OWNER                HEX: 00080000 ; inline
+: SYNCHRONIZE                HEX: 00100000 ; inline
+: STANDARD_RIGHTS_REQUIRED   HEX: 000f0000 ; inline
+
+: STANDARD_RIGHTS_READ       READ_CONTROL ; inline
+: STANDARD_RIGHTS_WRITE      READ_CONTROL ; inline
+: STANDARD_RIGHTS_EXECUTE    READ_CONTROL ; inline
+
+: TOKEN_TOKEN_ADJUST_DEFAULT   HEX: 0080 ; inline
+: TOKEN_ADJUST_GROUPS          HEX: 0040 ; inline
+: TOKEN_ADJUST_PRIVILEGES      HEX: 0020 ; inline
+: TOKEN_ADJUST_SESSIONID       HEX: 0100 ; inline
+: TOKEN_ASSIGN_PRIMARY         HEX: 0001 ; inline
+: TOKEN_DUPLICATE              HEX: 0002 ; inline
+: TOKEN_EXECUTE                STANDARD_RIGHTS_EXECUTE ; inline
+: TOKEN_IMPERSONATE            HEX: 0004 ; inline
+: TOKEN_QUERY                  HEX: 0008 ; inline
+: TOKEN_QUERY_SOURCE           HEX: 0010 ; inline
+: TOKEN_ADJUST_DEFAULT         HEX: 0080 ; inline
+: TOKEN_READ STANDARD_RIGHTS_READ TOKEN_QUERY bitor ;
+
+: TOKEN_WRITE
+    {
+        STANDARD_RIGHTS_WRITE
+        TOKEN_ADJUST_PRIVILEGES
+        TOKEN_ADJUST_GROUPS
+        TOKEN_ADJUST_DEFAULT
+    } flags ; foldable
+
+: TOKEN_ALL_ACCESS
+    {
+        STANDARD_RIGHTS_REQUIRED
+        TOKEN_ASSIGN_PRIMARY
+        TOKEN_DUPLICATE
+        TOKEN_IMPERSONATE
+        TOKEN_QUERY
+        TOKEN_QUERY_SOURCE
+        TOKEN_ADJUST_PRIVILEGES
+        TOKEN_ADJUST_GROUPS
+        TOKEN_ADJUST_SESSIONID
+        TOKEN_ADJUST_DEFAULT
+    } flags ; foldable
+
 
 ! : I_ScGetCurrentGroupStateW ;
 ! : A_SHAFinal ;
@@ -85,7 +212,7 @@ LIBRARY: advapi32
 ! : AddAccessDeniedAce ;
 ! : AddAccessDeniedAceEx ;
 ! : AddAccessDeniedObjectAce ;
-! : AddAce ;
+FUNCTION: BOOL AddAce ( PACL pAcl, DWORD dwAceRevision, DWORD dwStartingAceIndex, LPVOID pAceList, DWORD nAceListLength ) ;
 ! : AddAuditAccessAce ;
 ! : AddAuditAccessAceEx ;
 ! : AddAuditAccessObjectAce ;
@@ -382,7 +509,7 @@ FUNCTION: BOOL GetUserNameW ( LPCTSTR lpBuffer, LPDWORD lpnSize ) ;
 ! : ImpersonateLoggedOnUser ;
 ! : ImpersonateNamedPipeClient ;
 ! : ImpersonateSelf ;
-! : InitializeAcl ;
+FUNCTION: BOOL InitializeAcl ( PACL pAcl, DWORD nAclLength, DWORD dwAclRevision ) ;
 ! : InitializeSecurityDescriptor ;
 ! : InitializeSid ;
 ! : InitiateSystemShutdownA ;
@@ -508,70 +635,6 @@ FUNCTION: BOOL LookupPrivilegeValueW ( LPCTSTR lpSystemName,
 ! : OpenEventLogA ;
 ! : OpenEventLogW ;
 
-! typedef enum _TOKEN_INFORMATION_CLASS {
-: TokenUser 1 ;
-: TokenGroups 2 ;
-: TokenPrivileges 3 ;
-: TokenOwner 4 ;
-: TokenPrimaryGroup 5 ;
-: TokenDefaultDacl 6 ;
-: TokenSource 7 ;
-: TokenType 8 ;
-: TokenImpersonationLevel 9 ;
-: TokenStatistics 10 ;
-: TokenRestrictedSids 11 ;
-: TokenSessionId 12 ;
-: TokenGroupsAndPrivileges 13 ;
-: TokenSessionReference 14 ;
-: TokenSandBoxInert 15 ;
-! } TOKEN_INFORMATION_CLASS;
-
-: DELETE                     HEX: 00010000 ; inline
-: READ_CONTROL               HEX: 00020000 ; inline
-: WRITE_DAC                  HEX: 00040000 ; inline
-: WRITE_OWNER                HEX: 00080000 ; inline
-: SYNCHRONIZE                HEX: 00100000 ; inline
-: STANDARD_RIGHTS_REQUIRED   HEX: 000f0000 ; inline
-
-: STANDARD_RIGHTS_READ       READ_CONTROL ; inline
-: STANDARD_RIGHTS_WRITE      READ_CONTROL ; inline
-: STANDARD_RIGHTS_EXECUTE    READ_CONTROL ; inline
-
-: TOKEN_TOKEN_ADJUST_DEFAULT   HEX: 0080 ; inline
-: TOKEN_ADJUST_GROUPS          HEX: 0040 ; inline
-: TOKEN_ADJUST_PRIVILEGES      HEX: 0020 ; inline
-: TOKEN_ADJUST_SESSIONID       HEX: 0100 ; inline
-: TOKEN_ASSIGN_PRIMARY         HEX: 0001 ; inline
-: TOKEN_DUPLICATE              HEX: 0002 ; inline
-: TOKEN_EXECUTE                STANDARD_RIGHTS_EXECUTE ; inline
-: TOKEN_IMPERSONATE            HEX: 0004 ; inline
-: TOKEN_QUERY                  HEX: 0008 ; inline
-: TOKEN_QUERY_SOURCE           HEX: 0010 ; inline
-: TOKEN_ADJUST_DEFAULT         HEX: 0080 ; inline
-: TOKEN_READ STANDARD_RIGHTS_READ TOKEN_QUERY bitor ;
-
-: TOKEN_WRITE
-    {
-        STANDARD_RIGHTS_WRITE
-        TOKEN_ADJUST_PRIVILEGES
-        TOKEN_ADJUST_GROUPS
-        TOKEN_ADJUST_DEFAULT
-    } flags ; foldable
-
-: TOKEN_ALL_ACCESS
-    {
-        STANDARD_RIGHTS_REQUIRED
-        TOKEN_ASSIGN_PRIMARY
-        TOKEN_DUPLICATE
-        TOKEN_IMPERSONATE
-        TOKEN_QUERY
-        TOKEN_QUERY_SOURCE
-        TOKEN_ADJUST_PRIVILEGES
-        TOKEN_ADJUST_GROUPS
-        TOKEN_ADJUST_SESSIONID
-        TOKEN_ADJUST_DEFAULT
-    } flags ; foldable
-
 FUNCTION: BOOL OpenProcessToken ( HANDLE ProcessHandle,
                                   DWORD DesiredAccess,
                                   PHANDLE TokenHandle ) ;
index 733071d19735c6c84d309d93087355e1382b9536..3b0db96d6394857bf654b484c62c0e7bba31f8a7 100644 (file)
@@ -1001,3 +1001,25 @@ windows-messages set-global
 : LM_GETIDEALHEIGHT WM_USER  HEX: 0301 +  ; inline
 : LM_SETITEM WM_USER  HEX: 0302 + ; inline
 : LM_GETITEM WM_USER  HEX: 0303 + ; inline
+
+
+: WA_INACTIVE 0 ; inline
+: WA_ACTIVE 1 ; inline
+: WA_CLICKACTIVE 2 ; inline
+
+: SC_SIZE         HEX: f000 ; inline
+: SC_MOVE         HEX: f010 ; inline
+: SC_MINIMIZE     HEX: f020 ; inline
+: SC_MAXIMIZE     HEX: f030 ; inline
+: SC_NEXTWINDOW   HEX: f040 ; inline
+: SC_PREVWINDOW   HEX: f050 ; inline
+: SC_CLOSE        HEX: f060 ; inline
+: SC_VSCROLL      HEX: f070 ; inline
+: SC_HSCROLL      HEX: f080 ; inline
+: SC_MOUSEMENU    HEX: f090 ; inline
+: SC_KEYMENU      HEX: f100 ; inline
+: SC_ARRANGE      HEX: f110 ; inline
+: SC_RESTORE      HEX: f120 ; inline
+: SC_TASKLIST     HEX: f130 ; inline
+: SC_SCREENSAVE   HEX: f140 ; inline
+: SC_HOTKEY       HEX: f150 ; inline
index bb863cf9a0b54c7c5bfff3a2b9c46f577012fa25..5aebfa6848a97be5cafbd7214dd00eb67b3dcd3c 100644 (file)
@@ -1 +1,2 @@
+windows
 bindings
index 0313776a20aeb3565189d1cd091bb43a3004d0ec..a63a3903a11b41afe24cf084174a1df666ced5b6 100755 (executable)
@@ -15,7 +15,7 @@ IN: x11.clipboard
 TUPLE: x-clipboard atom contents ;
 
 : <x-clipboard> ( atom -- clipboard )
-    "" x-clipboard construct-boa ;
+    "" x-clipboard boa ;
 
 : selection-property ( -- n )
     "org.factorcode.Factor.SELECTION" x-atom ;
index f40392891c5b8bb885d1af1a582614e2202624a1..e7a5645f81371bc3da58826d38a5b32fa7b2963c 100644 (file)
@@ -52,22 +52,22 @@ GENERIC: client-event ( event window -- )
 
 : handle-event ( event window -- )
     over XAnyEvent-type {
-        { [ dup Expose = ] [ drop expose-event ] }
-        { [ dup ConfigureNotify = ] [ drop configure-event ] }
-        { [ dup ButtonPress = ] [ drop button-down-event$ ] }
-        { [ dup ButtonRelease = ] [ drop button-up-event$ ] }
-        { [ dup EnterNotify = ] [ drop enter-event ] }
-        { [ dup LeaveNotify = ] [ drop leave-event ] }
-        { [ dup MotionNotify = ] [ drop motion-event ] }
-        { [ dup KeyPress = ] [ drop key-down-event ] }
-        { [ dup KeyRelease = ] [ drop key-up-event ] }
-        { [ dup FocusIn = ] [ drop focus-in-event ] }
-        { [ dup FocusOut = ] [ drop focus-out-event ] }
-        { [ dup SelectionNotify = ] [ drop selection-notify-event ] }
-        { [ dup SelectionRequest = ] [ drop selection-request-event ] }
-        { [ dup ClientMessage = ] [ drop client-event ] }
-        { [ t ] [ 3drop ] }
-    } cond ;
+        { Expose [ expose-event ] }
+        { ConfigureNotify [ configure-event ] }
+        { ButtonPress [ button-down-event$ ] }
+        { ButtonRelease [ button-up-event$ ] }
+        { EnterNotify [ enter-event ] }
+        { LeaveNotify [ leave-event ] }
+        { MotionNotify [ motion-event ] }
+        { KeyPress [ key-down-event ] }
+        { KeyRelease [ key-up-event ] }
+        { FocusIn [ focus-in-event ] }
+        { FocusOut [ focus-out-event ] }
+        { SelectionNotify [ selection-notify-event ] }
+        { SelectionRequest [ selection-request-event ] }
+        { ClientMessage [ client-event ] }
+        [ 3drop ]
+    } case ;
 
 : configured-loc ( event -- dim )
     dup XConfigureEvent-x swap XConfigureEvent-y 2array ;
index 1194ff4df14c8a35767f2cf322d2e35e529a7bbc..d50cfa0d1e9ac8eb940f3a543ccf90d294239b0f 100755 (executable)
@@ -92,7 +92,7 @@ M: rpc-fault send-rpc
 TUPLE: server-error tag message ;
 
 : server-error ( tag message -- * )
-    \ server-error construct-boa throw ;
+    \ server-error boa throw ;
 
 M: server-error error.
     "Error in XML supplied to server" print
@@ -111,7 +111,7 @@ TAG: boolean xml>item
     dup children>string {
         { [ dup "1" = ] [ 2drop t ] }
         { [ "0" = ] [ drop f ] }
-        { [ t ] [ "Bad boolean" server-error ] }
+        [ "Bad boolean" server-error ]
     } cond ;
 
 : unstruct-member ( tag -- )
index a7c8bf7b738189a9524ff68f53e9caefb4335aad..da2e4ccb328e8fc0932adb0c6ddbe32e40151f0a 100755 (executable)
@@ -62,7 +62,7 @@ M: attrs set-at
     ] if* ;
 
 M: attrs assoc-size attrs-alist length ;
-M: attrs new-assoc drop V{ } new <attrs> ;
+M: attrs new-assoc drop V{ } new-sequence <attrs> ;
 M: attrs >alist attrs-alist ;
 
 : >attrs ( assoc -- attrs )
index 98146136e6d9e3e1099c2eccadf6c522a346e8d1..72ab7b1340ec0c411dd1216112994d8781061fa0 100644 (file)
@@ -6,6 +6,8 @@ USING: kernel xml tools.test io namespaces sequences xml.errors xml.entities
     continuations assocs sequences.deep ;
 
 ! This is insufficient
+\ read-xml must-infer
+
 SYMBOL: xml-file
 [ ] [ "extra/xml/tests/test.xml" resource-path
     [ file>xml ] with-html-entities xml-file set ] unit-test
index b2b7d78b3e353557b7ab8fbf8f74745a64bcbcd9..5ba151c2138518c452e74df51404cb7dfe19ed0c 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2006 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: xml.errors xml.data xml.utilities xml.char-classes
+USING: xml.errors xml.data xml.utilities xml.char-classes sets
 xml.entities kernel state-parser kernel namespaces strings math
 math.parser sequences assocs arrays splitting combinators unicode.case ;
 IN: xml.tokenize
@@ -86,7 +86,7 @@ SYMBOL: ns-stack
         { [ dup not ] [ 2drop ] }
         { [ 2dup = ] [ 2drop next ] }
         { [ dup CHAR: & = ] [ drop parse-entity (parse-char) ] }
-        { [ t ] [ , next (parse-char) ] }
+        [ , next (parse-char) ]
     } cond ;
 
 : parse-char ( ch -- string )
@@ -162,7 +162,7 @@ SYMBOL: ns-stack
         T{ name f "" "version" f }
         T{ name f "" "encoding" f }
         T{ name f "" "standalone" f }
-    } swap seq-diff
+    } swap diff
     dup empty? [ drop ] [ <extra-attrs> throw ] if ; 
 
 : good-version ( version -- version )
@@ -194,9 +194,9 @@ SYMBOL: ns-stack
     {
         { [ get-char dup CHAR: ! = ] [ drop next direct ] }
         { [ CHAR: ? = ] [ next instruct ] } 
-        { [ t ] [
+        [
             start-tag [ dup add-ns pop-ns <closer> ]
             [ middle-tag end-tag ] if
             CHAR: > expect
-        ] }
+        ]
     } cond ;
index b397e3c7b157f0fddf4ea7048254de24985c9af6..ed0773bd6fb3823b51e0141b5f8bff25cd0189f5 100755 (executable)
@@ -17,7 +17,7 @@ M: process-missing error.
 : run-process ( tag word -- )
     2dup "xtable" word-prop
     >r dup name-tag r> at* [ 2nip call ] [
-        drop \ process-missing construct-boa throw
+        drop \ process-missing boa throw
     ] if ;
 
 : PROCESS:
index 28b8f260685d8c6cd6b651d939b52041ec666336..27880da07f533b7c6d8c512d78f4ff1586735c65 100644 (file)
@@ -29,9 +29,7 @@ SYMBOL: indenter
     xml-pprint? get [ -1 indentation +@ ] when ;\r
 \r
 : trim-whitespace ( string -- no-whitespace )\r
-    [ [ blank? not ] find drop 0 or ] keep\r
-    [ [ blank? not ] find-last drop [ 1+ ] [ 0 ] if* ] keep\r
-    subseq ;\r
+    [ blank? ] trim ;\r
 \r
 : ?filter-children ( children -- no-whitespace )\r
     xml-pprint? get [\r
index 822b290f88438951af6c6fac33707a8e8b476c94..62f0f6ede32104942a572f6a3144f64402d07628 100755 (executable)
@@ -9,7 +9,7 @@ TUPLE: mode file file-name-glob first-line-glob ;
 
 TAG: MODE
     "NAME" over at >r
-    mode construct-empty {
+    mode new {
         { "FILE" f set-mode-file }
         { "FILE_NAME_GLOB" f set-mode-file-name-glob }
         { "FIRST_LINE_GLOB" f set-mode-first-line-glob }
index 4e97e597b28a14cebf466e3c45ad9aa652d84d7a..a6ef34a1f911fb9867dbe293bbf927eccc263a77 100644 (file)
@@ -1,5 +1,5 @@
 USING: kernel strings assocs sequences hashtables sorting
-       unicode.case unicode.categories ;
+       unicode.case unicode.categories sets ;
 IN: xmode.keyword-map
 
 ! Based on org.gjt.sp.jedit.syntax.KeywordMap
index 096b83e22effb3797a0092f51ce1b2f0902251a5..68b2c85a7db0207e704d0f7ecb42b52e97993406 100755 (executable)
@@ -71,7 +71,7 @@ TAGS>
     ] keep ;
 
 : merge-rule-set-props ( props rule-set -- )
-    [ rule-set-props union ] keep set-rule-set-props ;
+    [ rule-set-props assoc-union ] keep set-rule-set-props ;
 
 ! Top-level entry points
 : parse-mode-tag ( tag -- rule-sets )
index 8c74d616568e747d6bc83d0dbe23207690a900e0..df5580fc68466054536db189a978a439517411b4 100755 (executable)
@@ -33,7 +33,7 @@ finalized?
     } set-slots ;
 
 : <rule-set> ( -- ruleset )
-    rule-set construct-empty dup init-rule-set ;
+    rule-set new dup init-rule-set ;
 
 MEMO: standard-rule-set ( id -- ruleset )
     <rule-set> [ set-rule-set-default ] keep ;
@@ -73,7 +73,7 @@ chars
 ;
 
 : construct-rule ( class -- rule )
-    >r rule construct-empty r> construct-delegate ; inline
+    >r rule new r> construct-delegate ; inline
 
 TUPLE: seq-rule ;
 
index eb30ad59f7cf620863ec5521cf0c9e4c26c5f0e9..57a8a5ac16753d6a000e4a79900c68a46194f6e0 100755 (executable)
@@ -12,7 +12,7 @@ vectors sequences io.files prettyprint assocs unicode.case ;
 
 TUPLE: company employees type ;
 
-: <company> V{ } clone f company construct-boa ;
+: <company> V{ } clone f company boa ;
 
 : add-employee company-employees push ;
 
@@ -21,7 +21,7 @@ TUPLE: company employees type ;
 TUPLE: employee name description ;
 
 TAG: employee
-    employee construct-empty
+    employee new
     { { "name" f set-employee-name } { f set-employee-description } }
     init-from-tag swap add-employee ;
 
diff --git a/unmaintained/lint/authors.txt b/unmaintained/lint/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/lint/lint-tests.factor b/unmaintained/lint/lint-tests.factor
new file mode 100644 (file)
index 0000000..9a39980
--- /dev/null
@@ -0,0 +1,18 @@
+USING: io lint kernel math tools.test ;
+IN: lint.tests
+
+! Don't write code like this
+: lint1
+    [ "hi" print ] [ ] if ; ! when
+
+[ { [ [ ] if ] } ] [ \ lint1 lint ] unit-test
+
+: lint2
+    1 + ; ! 1+
+[ { [ 1 + ] } ] [ \ lint2 lint ] unit-test
+
+: lint3
+    dup -rot ; ! tuck
+
+[ { [ dup -rot ] } ] [ \ lint3 lint ] unit-test
+
diff --git a/unmaintained/lint/lint.factor b/unmaintained/lint/lint.factor
new file mode 100644 (file)
index 0000000..dcf52f7
--- /dev/null
@@ -0,0 +1,173 @@
+! Copyright (C) 2007 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.accessors arrays assocs combinators.lib io kernel
+macros math namespaces prettyprint quotations sequences
+vectors vocabs words html.elements slots.private tar ;
+IN: lint
+
+SYMBOL: def-hash
+SYMBOL: def-hash-keys
+
+: set-hash-vector ( val key hash -- )
+    2dup at -rot >r >r ?push r> r> set-at ;
+
+: add-word-def ( word quot -- )
+    dup callable? [
+        def-hash get-global set-hash-vector
+    ] [
+        2drop
+    ] if ;
+
+: more-defs
+    {
+        { [ swap >r swap r> ] -rot }
+        { [ swap swapd ] -rot }
+        { [ >r swap r> swap ] rot }
+        { [ swapd swap ] rot }
+        { [ dup swap ] over }
+        { [ dup -rot ] tuck }
+        { [ >r swap r> ] swapd }
+        { [ nip nip ] 2nip }
+        { [ drop drop ] 2drop }
+        { [ drop drop drop ] 3drop }
+        { [ 0 = ] zero? }
+        { [ pop drop ] pop* }
+        { [ [ ] if ] when }
+    } [ first2 swap add-word-def ] each ;
+
+: accessor-words ( -- seq )
+{
+    alien-signed-1 alien-signed-2 alien-signed-4 alien-signed-8
+    alien-unsigned-1 alien-unsigned-2 alien-unsigned-4 alien-unsigned-8
+    <displaced-alien> alien-unsigned-cell set-alien-signed-cell
+    set-alien-unsigned-1 set-alien-signed-1 set-alien-unsigned-2
+    set-alien-signed-2 set-alien-unsigned-4 set-alien-signed-4
+    set-alien-unsigned-8 set-alien-signed-8
+    alien-cell alien-signed-cell set-alien-cell set-alien-unsigned-cell
+    set-alien-float alien-float
+} ;
+
+: trivial-defs
+    {
+        [ get ] [ t ] [ { } ] [ . ] [ drop f ]
+        [ drop ] [ f ] [ first ] [ second ] [ third ] [ fourth ]
+        [ ">" write-html ] [ <unimplemented-typeflag> throw ]
+        [ "/>" write-html ]
+    } ;
+
+H{ } clone def-hash set-global
+all-words [ dup word-def add-word-def ] each
+more-defs
+
+! Remove empty word defs
+def-hash get-global [
+    drop empty? not
+] assoc-subset
+
+! Remove constants [ 1 ]
+[
+    drop dup length 1 = swap first number? and not
+] assoc-subset
+
+! Remove set-alien-cell, etc.
+[
+    drop [ accessor-words swap seq-diff ] keep [ length ] bi@ =
+] assoc-subset
+
+! Remove trivial defs
+[
+    drop trivial-defs member? not
+] assoc-subset
+
+! Remove n m shift defs
+[
+    drop dup length 3 = [
+        dup first2 [ number? ] both?
+        swap third \ shift = and not
+    ] [ drop t ] if
+] assoc-subset 
+
+! Remove [ n slot ]
+[
+    drop dup length 2 = [
+        first2 \ slot = swap number? and not
+    ] [ drop t ] if
+] assoc-subset def-hash set-global
+
+: find-duplicates
+    def-hash get-global [
+        nip length 1 >
+    ] assoc-subset ;
+
+def-hash get-global keys def-hash-keys set-global
+
+GENERIC: lint ( obj -- seq )
+
+M: object lint ( obj -- seq )
+    drop f ;
+
+: subseq/member? ( subseq/member seq -- ? )
+    { [ 2dup start ] [ 2dup member? ] } || 2nip ;
+
+M: callable lint ( quot -- seq )
+    def-hash-keys get [
+        swap subseq/member?
+    ] with subset ;
+
+M: word lint ( word -- seq )
+    word-def dup callable? [ lint ] [ drop f ] if ;
+
+: word-path. ( word -- )
+    [ word-vocabulary ":" ] keep unparse 3append write nl ;
+
+: (lint.) ( pair -- )
+    first2 >r word-path. r> [
+        bl bl bl bl
+        dup .
+        "-----------------------------------" print
+        def-hash get at [ bl bl bl bl word-path. ] each
+        nl
+    ] each nl nl ;
+
+: lint. ( alist -- )
+    [ (lint.) ] each ;
+    
+
+GENERIC: run-lint ( obj -- obj )
+
+: (trim-self)
+    def-hash get-global at* [
+        dupd remove empty? not
+    ] [
+        drop f
+    ] if ;
+
+: trim-self ( seq -- newseq )
+    [ [ (trim-self) ] subset ] assoc-map ;
+
+: filter-symbols ( alist -- alist )
+    [
+        nip first dup def-hash get at
+        [ first ] bi@ literalize = not
+    ] assoc-subset ;
+
+M: sequence run-lint ( seq -- seq )
+    [
+        global [ dup . flush ] bind
+        dup lint
+    ] { } map>assoc
+    trim-self
+    [ second empty? not ] subset
+    filter-symbols ;
+
+M: word run-lint ( word -- seq )
+    1array run-lint ;
+
+: lint-all ( -- seq )
+    all-words run-lint dup lint. ;
+
+: lint-vocab ( vocab -- seq )
+    words run-lint dup lint. ;
+
+: lint-word ( word -- seq )
+    1array run-lint dup lint. ;
diff --git a/unmaintained/lint/summary.txt b/unmaintained/lint/summary.txt
new file mode 100755 (executable)
index 0000000..943869d
--- /dev/null
@@ -0,0 +1 @@
+Finds potential mistakes in code
diff --git a/unmaintained/random-tester/authors.txt b/unmaintained/random-tester/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/random-tester/databank/authors.txt b/unmaintained/random-tester/databank/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/random-tester/databank/databank.factor b/unmaintained/random-tester/databank/databank.factor
new file mode 100644 (file)
index 0000000..45ee779
--- /dev/null
@@ -0,0 +1,11 @@
+USING: kernel math.constants ;
+IN: random-tester.databank
+
+: databank ( -- array )
+    {
+        ! V{ } H{ } V{ 3 } { 3 } { } "" "asdf"
+        pi 1/0. -1/0. 0/0. [ ]
+        f t "" 0 0.0 3.14 2 -3 -7 20 3/4 -3/4 1.2/3 3.5
+        C{ 2 2 } C{ 1/0. 1/0. }
+    } ;
+
diff --git a/unmaintained/random-tester/random-tester.factor b/unmaintained/random-tester/random-tester.factor
new file mode 100755 (executable)
index 0000000..7fb1714
--- /dev/null
@@ -0,0 +1,46 @@
+USING: compiler continuations io kernel math namespaces
+prettyprint quotations random sequences vectors
+compiler.units ;
+USING: random-tester.databank random-tester.safe-words ;
+IN: random-tester
+
+SYMBOL: errored
+SYMBOL: before
+SYMBOL: after
+SYMBOL: quot
+TUPLE: random-tester-error ;
+
+: setup-test ( #data #code -- data... quot )
+    #! Variable stack effect
+    >r [ databank random ] times r>
+    [ drop \ safe-words get random ] map >quotation ;
+
+: test-compiler ! ( data... quot -- ... )
+    errored off
+    dup quot set
+    datastack 1 head* before set
+    [ call ] [ drop ] recover
+    datastack after set
+    clear
+    before get [ ] each
+    quot get [ compile-call ] [ errored on ] recover ;
+
+: do-test ! ( data... quot -- )
+    .s flush test-compiler
+    errored get [
+        datastack after get 2dup = [
+            2drop
+        ] [
+            [ . ] each
+            "--" print
+            [ . ] each
+            quot get .
+            random-tester-error construct-empty throw
+        ] if
+    ] unless clear ;
+
+: random-test1 ( #data #code -- )
+    setup-test do-test ;
+
+: random-test2 ( -- )
+    3 2 setup-test do-test ;
diff --git a/unmaintained/random-tester/random/authors.txt b/unmaintained/random-tester/random/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/random-tester/random/random.factor b/unmaintained/random-tester/random/random.factor
new file mode 100755 (executable)
index 0000000..11f2e60
--- /dev/null
@@ -0,0 +1,74 @@
+USING: kernel math sequences namespaces hashtables words
+arrays parser compiler syntax io prettyprint optimizer
+random math.constants math.functions layouts random-tester.utils ;
+IN: random-tester
+
+! Tweak me
+: max-length 15 ; inline
+: max-value 1000000000 ; inline
+
+! varying bit-length random number
+: random-bits ( n -- int )
+    random 2 swap ^ random ;
+
+: random-seq ( -- seq )
+    { [ ] { } V{ } "" } random
+    [ max-length random [ max-value random , ] times ] swap make ;
+
+: random-string
+    [ max-length random [ max-value random , ] times ] "" make ;
+
+: special-integers ( -- seq ) \ special-integers get ;
+[ { -1 0 1 } % most-negative-fixnum , most-positive-fixnum , first-bignum , ] 
+{ } make \ special-integers set-global
+: special-floats ( -- seq ) \ special-floats get ;
+[ { 0.0 -0.0 } % e , pi , 1./0. , -1./0. , 0./0. , epsilon , epsilon neg , ]
+{ } make \ special-floats set-global
+: special-complexes ( -- seq ) \ special-complexes get ;
+[ 
+    { -1 0 1 C{ 0 1 } C{ 0 -1 } } %
+    e , e neg , pi , pi neg ,
+    0 pi rect> , 0 pi neg rect> , pi neg 0 rect> , pi pi rect> ,
+    pi pi neg rect> , pi neg pi rect> , pi neg pi neg rect> ,
+    e neg e neg rect> , e e rect> ,
+] { } make \ special-complexes set-global
+
+: random-fixnum ( -- fixnum )
+    most-positive-fixnum random 1+ 50% [ neg 1- ] when >fixnum ;
+
+: random-bignum ( -- bignum )
+     400 random-bits first-bignum + 50% [ neg ] when ;
+    
+: random-integer ( -- n )
+    50% [
+        random-fixnum
+    ] [
+        50% [ random-bignum ] [ special-integers get random ] if
+    ] if ;
+
+: random-positive-integer ( -- int )
+    random-integer dup 0 < [
+            neg
+        ] [
+            dup 0 = [ 1 + ] when
+    ] if ;
+
+: random-ratio ( -- ratio )
+    1000000000 dup [ random ] bi@ 1+ / 50% [ neg ] when dup [ drop random-ratio ] unless 10% [ drop 0 ] when ;
+
+: random-float ( -- float )
+    50% [ random-ratio ] [ special-floats get random ] if
+    50%
+    [ .0000000000000000001 /f ] [ 50% [ .00000000000000001 * ] when ] if
+    >float ;
+
+: random-number ( -- number )
+    {
+        [ random-integer ]
+        [ random-ratio ]
+        [ random-float ]
+    } do-one ;
+
+: random-complex ( -- C )
+    random-number random-number rect> ;
+
diff --git a/unmaintained/random-tester/safe-words/authors.txt b/unmaintained/random-tester/safe-words/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/random-tester/safe-words/safe-words.factor b/unmaintained/random-tester/safe-words/safe-words.factor
new file mode 100755 (executable)
index 0000000..5ca2c79
--- /dev/null
@@ -0,0 +1,110 @@
+USING: kernel namespaces sequences sorting vocabs ;
+USING: arrays assocs generic hashtables  math math.intervals math.parser math.functions refs shuffle vectors words ;
+IN: random-tester.safe-words
+
+: ?-words
+    {
+        delegate
+
+        /f
+
+        bits>float bits>double
+        float>bits double>bits
+
+        >bignum >boolean >fixnum >float
+
+        array? integer? complex? value-ref? ref? key-ref?
+        interval? number?
+        wrapper? tuple?
+        [-1,1]? between? bignum? both? either? eq? equal? even? fixnum? float? fp-nan? hashtable? interval-contains? interval-subset? interval? key-ref? key? number? odd? pair? power-of-2? ratio? rational? real? subassoc? zero? assoc? curry? vector? callstack? ! clear 3.14 [ <vector> assoc? ] compile-1
+        2^ not
+        ! arrays
+        resize-array <array>
+        ! assocs
+        (assoc-stack)
+        new-assoc
+        assoc-like
+        <hashtable>
+        all-integers? (all-integers?) ! hangs?
+        assoc-push-if
+
+        (clone) assoc-clone-like ! SYMBOL: foo foo dup (clone) =
+    } ;
+
+: bignum-words
+    {
+        next-power-of-2 (next-power-of-2)
+        times
+        hashcode hashcode*
+    } ;
+
+: initialization-words
+    {
+        init-namespaces
+    } ;
+
+: stack-words
+    {
+        dup
+        drop 2drop 3drop
+        roll -roll 2swap
+
+        >r r>
+    } ;
+
+: stateful-words
+    {
+        counter
+        gensym
+    } ;
+
+: foo-words
+    {
+        set-retainstack
+        retainstack callstack
+        datastack
+        callstack>array
+    } ;
+
+: exit-words
+    {
+        call-clear die
+    } ;
+
+: bad-words ( -- array )
+    [
+        ?-words %
+        bignum-words %
+        initialization-words %
+        stack-words %
+        stateful-words %
+        exit-words %
+        foo-words %
+    ] { } make ;
+
+: safe-words ( -- array )
+    bad-words {
+        "alists" "arrays" "assocs" ! "bit-arrays" "byte-arrays"
+        ! "classes" "combinators" "compiler" "continuations"
+        ! "core-foundation" "definitions" "documents"
+        ! "float-arrays" "generic" "graphs" "growable"
+        "hashtables"  ! io.*
+        "kernel" "math" 
+        "math.bitfields" "math.complex" "math.constants" "math.floats"
+        "math.functions" "math.integers" "math.intervals" "math.libm"
+        "math.parser" "math.ratios" "math.vectors"
+        ! "namespaces" "quotations" "sbufs"
+        ! "queues" "strings" "sequences"
+        "vectors"
+        ! "words"
+    } [ words ] map concat seq-diff natural-sort ;
+    
+safe-words \ safe-words set-global
+
+! foo dup (clone) = .
+! foo dup clone = .
+! f [ byte-array>bignum assoc-clone-like ] compile-1
+! 2 3.14 [ construct-empty number= ] compile-1
+! 3.14 [ <vector> assoc? ] compile-1
+! -3 [ ] 2 [ byte-array>bignum denominator ] compile-1
+
diff --git a/unmaintained/random-tester/utils/authors.txt b/unmaintained/random-tester/utils/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/unmaintained/random-tester/utils/utils.factor b/unmaintained/random-tester/utils/utils.factor
new file mode 100644 (file)
index 0000000..a025bbf
--- /dev/null
@@ -0,0 +1,34 @@
+USING: arrays assocs combinators.lib continuations kernel
+math math.functions memoize namespaces quotations random sequences
+sequences.private shuffle ;
+IN: random-tester.utils
+
+: %chance ( n -- ? )
+    100 random > ;
+
+: 10% ( -- ? ) 10 %chance ;
+: 20% ( -- ? ) 20 %chance ;
+: 30% ( -- ? ) 30 %chance ;
+: 40% ( -- ? ) 40 %chance ;
+: 50% ( -- ? ) 50 %chance ;
+: 60% ( -- ? ) 60 %chance ;
+: 70% ( -- ? ) 70 %chance ;
+: 80% ( -- ? ) 80 %chance ;
+: 90% ( -- ? ) 90 %chance ;
+
+: call-if ( quot ? -- ) swap when ; inline
+
+: with-10% ( quot -- ) 10% call-if ; inline
+: with-20% ( quot -- ) 20% call-if ; inline
+: with-30% ( quot -- ) 30% call-if ; inline
+: with-40% ( quot -- ) 40% call-if ; inline
+: with-50% ( quot -- ) 50% call-if ; inline
+: with-60% ( quot -- ) 60% call-if ; inline
+: with-70% ( quot -- ) 70% call-if ; inline
+: with-80% ( quot -- ) 80% call-if ; inline
+: with-90% ( quot -- ) 90% call-if ; inline
+
+: random-key keys random ;
+: random-value [ random-key ] keep at ;
+
+: do-one ( seq -- ) random call ; inline
index 390a719c77723dd2e37d3b397bd248c9fb3f322c..e7b19e96e10c7d92835f677f7ab11f6c16523b2c 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef DEBUG
-    CFLAGS += -fomit-frame-pointer
-#endif
+CFLAGS += -fomit-frame-pointer
 
 EXE_SUFFIX =
 DLL_PREFIX = lib
index d3b8b6e39eb2143d657265a1940753b09617b0ac..2490ed88057f8c9b342984197cb37638e3e68ee8 100755 (executable)
@@ -315,7 +315,7 @@ INLINE void* allot_object(CELL type, CELL a)
 {
        CELL *object;
 
-       if(nursery->size - ALLOT_BUFFER_ZONE > a)
+       if(HAVE_NURSERY_P && nursery->size - ALLOT_BUFFER_ZONE > a)
        {
                /* If there is insufficient room, collect the nursery */
                if(nursery->here + ALLOT_BUFFER_ZONE + a > nursery->end)
index 86f0509e38d2da1c5bee8eca66d22e4408712c7b..eb28af53e47e4c024217f51b6f489f5fb2a15253 100644 (file)
@@ -1,4 +1,12 @@
+#include <ucontext.h>
+
 #define FRAME_RETURN_ADDRESS(frame) *((XT *)(frame_successor(frame) + 1) + 1)
 
+INLINE void *ucontext_stack_pointer(void *uap)
+{
+        ucontext_t *ucontext = (ucontext_t *)uap;
+        return (void *)ucontext->uc_mcontext.uc_regs->gregs[PT_R1];
+}
+
 #define UAP_PROGRAM_COUNTER(ucontext) \
        (((ucontext_t *)(ucontext))->uc_mcontext.uc_regs->gregs[PT_NIP])
index 4c350877524a5f49ad8713b5a69bf3454de657dd..701bb8da0161fbdfebb3a3797a9a235438ea4fd0 100644 (file)
@@ -15,4 +15,10 @@ DLLEXPORT void c_to_factor_toplevel(CELL quot);
 #ifndef environ
        extern char ***_NSGetEnviron(void);
        #define environ (*_NSGetEnviron())
-#endif
\ No newline at end of file
+#endif
+
+INLINE void *ucontext_stack_pointer(void *uap)
+{
+       ucontext_t *ucontext = (ucontext_t *)uap;
+       return ucontext->uc_stack.ss_sp;
+}
diff --git a/vm/os-unix-ucontext.h b/vm/os-unix-ucontext.h
deleted file mode 100644 (file)
index 9ed0620..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <ucontext.h>
-
-INLINE void *ucontext_stack_pointer(void *uap)
-{
-       ucontext_t *ucontext = (ucontext_t *)uap;
-       return ucontext->uc_stack.ss_sp;
-}
index 74320288aa60c82b9382a3ff5537c3420185aa8b..6363ce68a9224ac76fa598e3e5423b98f3bbc5de 100755 (executable)
@@ -85,6 +85,16 @@ DEFINE_PRIMITIVE(read_dir)
        dpush(result);
 }
 
+DEFINE_PRIMITIVE(os_env)
+{
+       char *name = unbox_char_string();
+       char *value = getenv(name);
+       if(value == NULL)
+               dpush(F);
+       else
+               box_char_string(value);
+}
+
 DEFINE_PRIMITIVE(os_envs)
 {
        GROWABLE_ARRAY(result);
@@ -103,6 +113,21 @@ DEFINE_PRIMITIVE(os_envs)
        dpush(result);
 }
 
+DEFINE_PRIMITIVE(set_os_env)
+{
+       char *key = unbox_char_string();
+       REGISTER_C_STRING(key);
+       char *value = unbox_char_string();
+       UNREGISTER_C_STRING(key);
+       setenv(key, value, 1);
+}
+
+DEFINE_PRIMITIVE(unset_os_env)
+{
+       char *key = unbox_char_string();
+       unsetenv(key);
+}
+
 DEFINE_PRIMITIVE(set_os_envs)
 {
        F_ARRAY *array = untag_array(dpop());
index 664df9e774d38b9119b2745ef0e27cff1b1eb9cd..59c14d98f5a47f6c821921f819298f54a9525604 100755 (executable)
@@ -215,6 +215,36 @@ void sleep_millis(DWORD msec)
        Sleep(msec);
 }
 
+DEFINE_PRIMITIVE(os_env)
+{
+       F_CHAR *key = unbox_u16_string();
+       F_CHAR *value = safe_malloc(MAX_UNICODE_PATH * 2);
+       int ret;
+       ret = GetEnvironmentVariable(key, value, MAX_UNICODE_PATH * 2);
+       if(ret == 0)
+               dpush(F);
+       else
+               dpush(tag_object(from_u16_string(value)));
+       free(value);
+}
+
+DEFINE_PRIMITIVE(set_os_env)
+{
+       F_CHAR *key = unbox_u16_string();
+       REGISTER_C_STRING(key);
+       F_CHAR *value = unbox_u16_string();
+       UNREGISTER_C_STRING(key);
+       if(!SetEnvironmentVariable(key, value))
+               general_error(ERROR_IO, tag_object(get_error_message()), F, NULL);
+}
+
+DEFINE_PRIMITIVE(unset_os_env)
+{
+       if(!SetEnvironmentVariable(unbox_u16_string(), NULL)
+               && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
+               general_error(ERROR_IO, tag_object(get_error_message()), F, NULL);
+}
+
 DEFINE_PRIMITIVE(set_os_envs)
 {
        not_implemented_error();
index a8c8ba756f028ea0b21e9fcb1b61a34e053a217b..2f97cb9d1d383ac6a4ceaa896e93a0cf412e50fd 100644 (file)
@@ -27,7 +27,6 @@
        #include "os-unix.h"
 
        #ifdef __APPLE__
-               #include "os-unix-ucontext.h"
                #include "os-macosx.h"
                #include "mach_signal.h"
                
@@ -84,7 +83,6 @@
                        #if defined(FACTOR_X86)
                                #include "os-linux-x86.32.h"
                        #elif defined(FACTOR_PPC)
-                               #include "os-unix-ucontext.h"
                                #include "os-linux-ppc.h"
                        #elif defined(FACTOR_ARM)
                                #include "os-linux-arm.h"
index 533fcebc9a0c283df5723967ec51107bc0694f72..2906a154a25704214a629601566121f89734eb9f 100755 (executable)
@@ -182,6 +182,8 @@ void *primitives[] = {
        primitive_set_innermost_stack_frame_quot,
        primitive_call_clear,
        primitive_os_envs,
+       primitive_set_os_env,
+       primitive_unset_os_env,
        primitive_set_os_envs,
        primitive_resize_byte_array,
        primitive_resize_bit_array,
index 282be0a447b069f51e2ac89c76fa6e41b1a41d64..ae0c91d9e610f827e7d918a5afbb59e7968c94dd 100755 (executable)
--- a/vm/run.c
+++ b/vm/run.c
@@ -280,16 +280,6 @@ DEFINE_PRIMITIVE(exit)
        exit(to_fixnum(dpop()));
 }
 
-DEFINE_PRIMITIVE(os_env)
-{
-       char *name = unbox_char_string();
-       char *value = getenv(name);
-       if(value == NULL)
-               dpush(F);
-       else
-               box_char_string(value);
-}
-
 DEFINE_PRIMITIVE(eq)
 {
        CELL lhs = dpop();
index c112c5f587788d797c194af5910f71dbdb63dc8f..e2afb08525c70c202f924d1ace89c62d36bd81c0 100755 (executable)
--- a/vm/run.h
+++ b/vm/run.h
@@ -249,6 +249,8 @@ DECLARE_PRIMITIVE(setenv);
 DECLARE_PRIMITIVE(exit);
 DECLARE_PRIMITIVE(os_env);
 DECLARE_PRIMITIVE(os_envs);
+DECLARE_PRIMITIVE(set_os_env);
+DECLARE_PRIMITIVE(unset_os_env);
 DECLARE_PRIMITIVE(set_os_envs);
 DECLARE_PRIMITIVE(eq);
 DECLARE_PRIMITIVE(millis);
index f88c3ef3cb6d8cde568cd016e5eb093b84f5a1e4..d9fd152c970802c5af2c4aa1b618bdb62e8d5a24 100755 (executable)
@@ -50,6 +50,7 @@ F_WORD *allot_word(CELL vocab, CELL name)
        word->counter = tag_fixnum(0);
        word->compiledp = F;
        word->profiling = NULL;
+       word->code = NULL;
 
        REGISTER_UNTAGGED(word);
        default_word_code(word,true);
@@ -108,8 +109,11 @@ F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill)
                memset((void*)AREF(array,0),'\0',capacity * CELLS);
        else
        {
+               /* No need for write barrier here. Either the object is in
+               the nursery, or it was allocated directly in tenured space
+               and the write barrier is already hit for us in that case. */
                for(i = 0; i < capacity; i++)
-                       set_array_nth(array,i,fill);
+                       put(AREF(array,i),fill);
        }
        return array;
 }
@@ -181,7 +185,7 @@ F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill)
        memcpy(new_array + 1,array + 1,to_copy * CELLS);
 
        for(i = to_copy; i < capacity; i++)
-               set_array_nth(new_array,i,fill);
+               put(AREF(new_array,i),fill);
 
        return new_array;
 }
@@ -222,6 +226,8 @@ F_ARRAY *growable_append(F_ARRAY *result, F_ARRAY *elts, CELL *result_count)
 
        UNREGISTER_UNTAGGED(elts);
 
+       write_barrier((CELL)result);
+
        memcpy((void*)AREF(result,*result_count),(void*)AREF(elts,0),elts_size * CELLS);
 
        *result_count += elts_size;
@@ -467,6 +473,8 @@ void set_string_nth(F_STRING* string, CELL index, CELL value)
                                untag_fixnum_fast(string->length)
                                * sizeof(u16));
                        UNREGISTER_UNTAGGED(string);
+
+                       write_barrier((CELL)string);
                        string->aux = tag_object(aux);
                }
        }
@@ -549,10 +557,11 @@ F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill)
                REGISTER_UNTAGGED(string);
                REGISTER_UNTAGGED(new_string);
                F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16));
-               new_string->aux = tag_object(new_aux);
                UNREGISTER_UNTAGGED(new_string);
                UNREGISTER_UNTAGGED(string);
 
+               new_string->aux = tag_object(new_aux);
+
                F_BYTE_ARRAY *aux = untag_object(string->aux);
                memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16));
        }