]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'autouse-existing-usings' of git@github.com:seckar/factor into cleaner...
authorNicholas Seckar <nseckar@gmail.com>
Sun, 19 Apr 2009 21:31:44 +0000 (14:31 -0700)
committerNicholas Seckar <nseckar@gmail.com>
Sun, 19 Apr 2009 21:31:44 +0000 (14:31 -0700)
433 files changed:
.gitignore
basis/alien/libraries/libraries-docs.factor
basis/alien/parser/parser.factor
basis/alien/syntax/syntax.factor
basis/bootstrap/finish-bootstrap.factor
basis/bootstrap/stage2.factor
basis/bootstrap/tools/tools.factor
basis/compiler/codegen/codegen.factor
basis/compiler/compiler-docs.factor
basis/compiler/compiler.factor
basis/compiler/errors/authors.txt [new file with mode: 0755]
basis/compiler/errors/errors-docs.factor [new file with mode: 0644]
basis/compiler/errors/errors.factor [new file with mode: 0644]
basis/compiler/errors/summary.txt [new file with mode: 0755]
basis/compiler/tests/folding.factor
basis/compiler/tests/redefine1.factor
basis/compiler/tests/redefine10.factor
basis/compiler/tests/redefine11.factor
basis/compiler/tests/redefine12.factor
basis/compiler/tests/redefine2.factor
basis/compiler/tests/redefine3.factor
basis/compiler/tests/redefine4.factor
basis/compiler/tests/redefine5.factor
basis/compiler/tests/redefine6.factor
basis/compiler/tests/redefine7.factor
basis/compiler/tests/redefine8.factor
basis/compiler/tests/redefine9.factor
basis/compiler/tests/simple.factor
basis/compiler/tree/builder/builder.factor
basis/compiler/tree/cleanup/cleanup-tests.factor
basis/compiler/tree/normalization/normalization-tests.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/recursive/recursive-tests.factor
basis/concurrency/exchangers/exchangers-tests.factor
basis/concurrency/flags/flags-tests.factor
basis/concurrency/promises/promises-docs.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/x86/bootstrap.factor
basis/debugger/debugger.factor
basis/delegate/delegate-tests.factor
basis/editors/editors-docs.factor
basis/editors/editors.factor
basis/editors/gedit/authors.txt [new file with mode: 0644]
basis/editors/gedit/gedit.factor [new file with mode: 0644]
basis/editors/gedit/summary.txt [new file with mode: 0644]
basis/editors/gedit/tags.txt [new file with mode: 0644]
basis/eval/eval-docs.factor
basis/eval/eval-tests.factor
basis/eval/eval.factor
basis/fry/fry-tests.factor
basis/furnace/sessions/sessions-tests.factor
basis/generalizations/generalizations-docs.factor
basis/generalizations/generalizations.factor
basis/hash2/hash2-tests.factor
basis/hash2/hash2.factor
basis/heaps/heaps-tests.factor
basis/help/cookbook/cookbook.factor
basis/help/crossref/crossref-tests.factor
basis/help/definitions/definitions-tests.factor
basis/help/handbook/handbook.factor
basis/help/home/home-docs.factor
basis/help/lint/checks/authors.txt [new file with mode: 0644]
basis/help/lint/checks/checks.factor [new file with mode: 0644]
basis/help/lint/lint-docs.factor
basis/help/lint/lint.factor
basis/help/syntax/syntax-tests.factor
basis/help/topics/topics-tests.factor
basis/help/tutorial/tutorial.factor
basis/http/client/client.factor
basis/io/crlf/crlf-tests.factor [new file with mode: 0644]
basis/io/crlf/crlf.factor
basis/io/launcher/launcher-docs.factor
basis/io/launcher/unix/parser/parser-tests.factor
basis/io/launcher/unix/parser/parser.factor
basis/io/launcher/windows/nt/nt-tests.factor
basis/io/sockets/sockets.factor
basis/io/styles/styles-docs.factor
basis/io/styles/styles.factor
basis/listener/listener-docs.factor
basis/listener/listener-tests.factor
basis/listener/listener.factor
basis/lists/lists.factor
basis/locals/locals-tests.factor
basis/macros/macros-tests.factor
basis/match/match.factor
basis/math/intervals/intervals-tests.factor
basis/math/matrices/authors.txt [new file with mode: 0644]
basis/math/matrices/elimination/authors.txt [new file with mode: 0644]
basis/math/matrices/elimination/elimination-tests.factor [new file with mode: 0644]
basis/math/matrices/elimination/elimination.factor [new file with mode: 0755]
basis/math/matrices/elimination/summary.txt [new file with mode: 0644]
basis/math/matrices/matrices-tests.factor [new file with mode: 0644]
basis/math/matrices/matrices.factor [new file with mode: 0755]
basis/math/matrices/summary.txt [new file with mode: 0644]
basis/memoize/memoize-tests.factor
basis/memoize/memoize.factor
basis/mime/multipart/multipart.factor
basis/mirrors/mirrors-tests.factor
basis/models/arrow/smart/authors.txt [new file with mode: 0644]
basis/models/arrow/smart/smart-docs.factor
basis/models/arrow/smart/smart-tests.factor [new file with mode: 0644]
basis/models/arrow/smart/smart.factor [new file with mode: 0644]
basis/models/search/search.factor
basis/models/sort/sort.factor
basis/opengl/textures/textures.factor
basis/peg/ebnf/ebnf-tests.factor
basis/persistent/deques/deques.factor
basis/persistent/hashtables/hashtables-tests.factor
basis/prettyprint/prettyprint-tests.factor
basis/random/mersenne-twister/mersenne-twister-tests.factor
basis/refs/authors.txt
basis/refs/refs-docs.factor
basis/refs/refs-tests.factor
basis/refs/refs.factor
basis/regexp/parser/parser-tests.factor
basis/regexp/regexp-tests.factor
basis/smtp/authors.txt
basis/smtp/server/server.factor
basis/smtp/smtp-docs.factor
basis/smtp/smtp-tests.factor
basis/smtp/smtp.factor
basis/sorting/slots/slots-docs.factor
basis/sorting/slots/slots-tests.factor
basis/sorting/slots/slots.factor
basis/stack-checker/errors/errors.factor
basis/stack-checker/errors/prettyprint/prettyprint.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/stack-checker-tests.factor
basis/stack-checker/transforms/transforms-tests.factor
basis/stack-checker/transforms/transforms.factor
basis/threads/threads-tests.factor
basis/tools/annotations/annotations-tests.factor
basis/tools/annotations/annotations.factor
basis/tools/completion/completion.factor
basis/tools/continuations/authors.txt [new file with mode: 0644]
basis/tools/continuations/continuations.factor [new file with mode: 0644]
basis/tools/deploy/shaker/shaker.factor
basis/tools/deploy/test/11/11.factor
basis/tools/deploy/test/7/7.factor
basis/tools/errors/authors.txt [new file with mode: 0644]
basis/tools/errors/errors-docs.factor [new file with mode: 0644]
basis/tools/errors/errors.factor [new file with mode: 0644]
basis/tools/files/files.factor
basis/tools/profiler/profiler.factor
basis/tools/scaffold/scaffold.factor
basis/tools/test/test-docs.factor
basis/tools/test/test.factor
basis/tools/trace/authors.txt [new file with mode: 0644]
basis/tools/trace/trace-tests.factor [new file with mode: 0644]
basis/tools/trace/trace.factor [new file with mode: 0644]
basis/tools/vocabs/vocabs.factor
basis/tools/walker/debug/debug.factor
basis/tools/walker/walker-tests.factor
basis/tools/walker/walker.factor
basis/ui/backend/cocoa/tools/tools.factor
basis/ui/backend/x11/x11.factor
basis/ui/baseline-alignment/baseline-alignment.factor
basis/ui/gadgets/gadgets.factor
basis/ui/gadgets/icons/icons.factor
basis/ui/gadgets/packs/packs-tests.factor
basis/ui/gadgets/packs/packs.factor
basis/ui/gadgets/panes/panes-tests.factor
basis/ui/gadgets/paragraphs/paragraphs-tests.factor
basis/ui/gadgets/presentations/presentations.factor
basis/ui/gadgets/search-tables/search-tables.factor
basis/ui/gadgets/slots/slots.factor
basis/ui/gadgets/tables/tables.factor
basis/ui/operations/operations-docs.factor
basis/ui/text/text-docs.factor
basis/ui/tools/browser/browser.factor
basis/ui/tools/browser/popups/popups.factor
basis/ui/tools/debugger/debugger.factor
basis/ui/tools/error-list/authors.txt [new file with mode: 0644]
basis/ui/tools/error-list/error-list-docs.factor [new file with mode: 0644]
basis/ui/tools/error-list/error-list.factor [new file with mode: 0644]
basis/ui/tools/error-list/icons/compiler-error.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/compiler-warning.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/help-lint-error.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/linkage-error.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/note.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/source-file.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/syntax-error.tiff [new file with mode: 0644]
basis/ui/tools/error-list/icons/unit-test-error.tiff [new file with mode: 0644]
basis/ui/tools/inspector/inspector-docs.factor
basis/ui/tools/listener/listener-docs.factor
basis/ui/tools/listener/listener.factor
basis/ui/tools/operations/operations.factor
basis/ui/tools/profiler/profiler-tests.factor [new file with mode: 0644]
basis/ui/tools/profiler/profiler.factor
basis/ui/tools/tools-docs.factor
basis/ui/tools/tools.factor
basis/ui/tools/walker/walker-docs.factor
basis/urls/encoding/encoding-docs.factor
basis/urls/encoding/encoding.factor
basis/windows/advapi32/advapi32.factor
basis/windows/dinput/constants/constants-tests.factor [new file with mode: 0644]
basis/windows/dinput/constants/constants.factor
basis/windows/gdi32/gdi32.factor
basis/windows/gdi32/tags.txt
basis/windows/kernel32/kernel32.factor
basis/windows/user32/user32.factor
basis/windows/usp10/tags.txt [new file with mode: 0644]
basis/x11/authors.txt [new file with mode: 0644]
basis/x11/clipboard/clipboard.factor
basis/x11/events/events.factor
basis/x11/glx/glx.factor
basis/x11/io/authors.txt [new file with mode: 0644]
basis/x11/io/io.factor [new file with mode: 0644]
basis/x11/io/unix/authors.txt [new file with mode: 0644]
basis/x11/io/unix/tags.txt [new file with mode: 0644]
basis/x11/io/unix/unix.factor [new file with mode: 0644]
basis/x11/syntax/authors.txt [new file with mode: 0644]
basis/x11/syntax/syntax.factor [new file with mode: 0644]
basis/x11/windows/windows.factor
basis/x11/x11.factor [new file with mode: 0644]
basis/x11/xim/xim.factor
basis/x11/xlib/xlib.factor
build-support/factor.sh
core/alien/alien-docs.factor
core/bootstrap/syntax-docs.factor [new file with mode: 0644]
core/classes/classes-tests.factor
core/classes/mixin/mixin-tests.factor
core/classes/tuple/parser/parser-tests.factor
core/classes/tuple/tuple-tests.factor
core/classes/union/union-tests.factor
core/combinators/combinators-tests.factor
core/combinators/combinators.factor
core/compiler/errors/authors.txt [deleted file]
core/compiler/errors/errors-docs.factor [deleted file]
core/compiler/errors/errors.factor [deleted file]
core/compiler/errors/summary.txt [deleted file]
core/compiler/units/units-tests.factor
core/compiler/units/units.factor
core/continuations/continuations-docs.factor
core/continuations/continuations-tests.factor
core/continuations/continuations.factor
core/generic/generic-tests.factor
core/generic/generic.factor
core/generic/standard/engines/tuple/tuple.factor
core/generic/standard/standard-tests.factor
core/kernel/kernel-tests.factor
core/memory/memory-tests.factor
core/parser/parser-tests.factor
core/parser/parser.factor
core/quotations/quotations-docs.factor
core/sequences/sequences.factor
core/slots/slots-tests.factor
core/slots/slots.factor
core/source-files/errors/authors.txt [new file with mode: 0644]
core/source-files/errors/errors-tests.factor [new file with mode: 0644]
core/source-files/errors/errors.factor [new file with mode: 0644]
core/source-files/source-files.factor
core/vocabs/loader/loader-tests.factor
core/vocabs/loader/loader.factor
core/words/alias/alias-tests.factor
core/words/constant/constant-docs.factor [new file with mode: 0644]
core/words/words-docs.factor
core/words/words-tests.factor
extra/4DNav/4DNav.factor
extra/4DNav/file-chooser/file-chooser.factor
extra/advice/advice-docs.factor [deleted file]
extra/advice/advice-tests.factor [deleted file]
extra/advice/advice.factor [deleted file]
extra/advice/authors.txt [deleted file]
extra/advice/summary.txt [deleted file]
extra/advice/tags.txt [deleted file]
extra/bank/bank.factor
extra/benchmark/base64/base64.factor
extra/benchmark/benchmark.factor
extra/benchmark/beust1/beust1.factor
extra/benchmark/beust2/beust2.factor
extra/benchmark/fib6/fib6.factor
extra/benchmark/md5/md5.factor
extra/benchmark/random/random.factor
extra/benchmark/sha1/sha1.factor
extra/benchmark/sum-file/sum-file.factor
extra/coroutines/coroutines.factor
extra/couchdb/authors.txt [new file with mode: 0644]
extra/couchdb/couchdb-tests.factor [new file with mode: 0644]
extra/couchdb/couchdb.factor [new file with mode: 0644]
extra/dns/util/util.factor
extra/fuel/eval/eval.factor
extra/fuel/fuel.factor
extra/fuel/pprint/pprint.factor
extra/graph-theory/authors.txt [deleted file]
extra/graph-theory/graph-theory-docs.factor [deleted file]
extra/graph-theory/graph-theory.factor [deleted file]
extra/graph-theory/reversals/reversals.factor [deleted file]
extra/graph-theory/sparse/sparse.factor [deleted file]
extra/graph-theory/summary.txt [deleted file]
extra/graph-theory/tags.txt [deleted file]
extra/images/viewer/viewer.factor
extra/infix/infix.factor
extra/irc/messages/messages-tests.factor
extra/jamshred/authors.txt [new file with mode: 0644]
extra/jamshred/deploy.factor [new file with mode: 0644]
extra/jamshred/game/authors.txt [new file with mode: 0644]
extra/jamshred/game/game.factor [new file with mode: 0644]
extra/jamshred/gl/authors.txt [new file with mode: 0644]
extra/jamshred/gl/gl.factor [new file with mode: 0644]
extra/jamshred/jamshred.factor [new file with mode: 0644]
extra/jamshred/log/log.factor [new file with mode: 0644]
extra/jamshred/oint/authors.txt [new file with mode: 0644]
extra/jamshred/oint/oint-tests.factor [new file with mode: 0644]
extra/jamshred/oint/oint.factor [new file with mode: 0644]
extra/jamshred/player/authors.txt [new file with mode: 0644]
extra/jamshred/player/player.factor [new file with mode: 0644]
extra/jamshred/sound/sound.factor [new file with mode: 0644]
extra/jamshred/summary.txt [new file with mode: 0644]
extra/jamshred/tags.txt [new file with mode: 0644]
extra/jamshred/tunnel/authors.txt [new file with mode: 0644]
extra/jamshred/tunnel/tunnel-tests.factor [new file with mode: 0644]
extra/jamshred/tunnel/tunnel.factor [new file with mode: 0644]
extra/key-caps/key-caps.factor
extra/koszul/koszul.factor
extra/lint/lint-tests.factor
extra/mason/build/build-tests.factor
extra/mason/build/build.factor
extra/mason/child/child-tests.factor
extra/mason/child/child.factor
extra/mason/cleanup/cleanup.factor
extra/mason/common/common.factor
extra/mason/config/config.factor
extra/mason/email/email-tests.factor
extra/mason/email/email.factor
extra/mason/help/help.factor
extra/mason/mason.factor
extra/mason/notify/authors.txt [new file with mode: 0644]
extra/mason/notify/notify.factor [new file with mode: 0644]
extra/mason/release/archive/archive.factor
extra/mason/release/release.factor
extra/mason/release/upload/upload.factor
extra/mason/report/report-tests.factor
extra/mason/report/report.factor
extra/mason/test/test.factor
extra/mason/twitter/authors.txt [new file with mode: 0644]
extra/mason/twitter/twitter.factor [new file with mode: 0644]
extra/math/binpack/binpack.factor
extra/math/function-tools/function-tools.factor
extra/math/matrices/authors.txt [deleted file]
extra/math/matrices/elimination/authors.txt [deleted file]
extra/math/matrices/elimination/elimination-tests.factor [deleted file]
extra/math/matrices/elimination/elimination.factor [deleted file]
extra/math/matrices/elimination/summary.txt [deleted file]
extra/math/matrices/matrices-tests.factor [deleted file]
extra/math/matrices/matrices.factor [deleted file]
extra/math/matrices/summary.txt [deleted file]
extra/math/numerical-integration/numerical-integration.factor
extra/morse/authors.txt [new file with mode: 0644]
extra/morse/morse-docs.factor [new file with mode: 0644]
extra/morse/morse-tests.factor [new file with mode: 0644]
extra/morse/morse.factor [new file with mode: 0644]
extra/morse/summary.txt [new file with mode: 0644]
extra/morse/tags.txt [new file with mode: 0644]
extra/openal/authors.txt [new file with mode: 0644]
extra/openal/backend/authors.txt [new file with mode: 0755]
extra/openal/backend/backend.factor [new file with mode: 0644]
extra/openal/example/authors.txt [new file with mode: 0755]
extra/openal/example/example.factor [new file with mode: 0644]
extra/openal/macosx/authors.txt [new file with mode: 0755]
extra/openal/macosx/macosx.factor [new file with mode: 0644]
extra/openal/macosx/tags.txt [new file with mode: 0644]
extra/openal/openal.factor [new file with mode: 0644]
extra/openal/other/authors.txt [new file with mode: 0755]
extra/openal/other/other.factor [new file with mode: 0644]
extra/openal/summary.txt [new file with mode: 0644]
extra/openal/tags.txt [new file with mode: 0644]
extra/parser-combinators/parser-combinators.factor
extra/partial-continuations/partial-continuations-tests.factor
extra/partial-continuations/partial-continuations.factor
extra/peg-lexer/peg-lexer.factor
extra/project-euler/011/011.factor
extra/project-euler/018/018.factor
extra/project-euler/032/032.factor
extra/project-euler/150/150.factor
extra/shell/shell.factor
extra/synth/authors.txt [new file with mode: 0644]
extra/synth/buffers/authors.txt [new file with mode: 0644]
extra/synth/buffers/buffers.factor [new file with mode: 0644]
extra/synth/example/authors.txt [new file with mode: 0644]
extra/synth/example/example.factor [new file with mode: 0644]
extra/synth/summary.txt [new file with mode: 0644]
extra/synth/synth.factor [new file with mode: 0644]
extra/tar/tar.factor
extra/ui/gadgets/lists/lists.factor
extra/update/util/util.factor
extra/webapps/counter/counter.factor
extra/webapps/site-watcher/site-watcher.factor
extra/webapps/site-watcher/spidering/spidering.factor
extra/wordtimer/wordtimer.factor
unmaintained/advice/advice-docs.factor [new file with mode: 0644]
unmaintained/advice/advice-tests.factor [new file with mode: 0644]
unmaintained/advice/advice.factor [new file with mode: 0644]
unmaintained/advice/authors.txt [new file with mode: 0644]
unmaintained/advice/summary.txt [new file with mode: 0644]
unmaintained/advice/tags.txt [new file with mode: 0644]
unmaintained/graph-theory/authors.txt [new file with mode: 0644]
unmaintained/graph-theory/graph-theory-docs.factor [new file with mode: 0644]
unmaintained/graph-theory/graph-theory.factor [new file with mode: 0644]
unmaintained/graph-theory/reversals/reversals.factor [new file with mode: 0644]
unmaintained/graph-theory/sparse/sparse.factor [new file with mode: 0644]
unmaintained/graph-theory/summary.txt [new file with mode: 0644]
unmaintained/graph-theory/tags.txt [new file with mode: 0644]
unmaintained/morse/authors.txt [deleted file]
unmaintained/morse/morse-docs.factor [deleted file]
unmaintained/morse/morse-tests.factor [deleted file]
unmaintained/morse/morse.factor [deleted file]
unmaintained/morse/summary.txt [deleted file]
unmaintained/morse/tags.txt [deleted file]
unmaintained/openal/authors.txt [deleted file]
unmaintained/openal/backend/authors.txt [deleted file]
unmaintained/openal/backend/backend.factor [deleted file]
unmaintained/openal/example/authors.txt [deleted file]
unmaintained/openal/example/example.factor [deleted file]
unmaintained/openal/macosx/authors.txt [deleted file]
unmaintained/openal/macosx/macosx.factor [deleted file]
unmaintained/openal/macosx/tags.txt [deleted file]
unmaintained/openal/openal.factor [deleted file]
unmaintained/openal/other/authors.txt [deleted file]
unmaintained/openal/other/other.factor [deleted file]
unmaintained/openal/summary.txt [deleted file]
unmaintained/openal/tags.txt [deleted file]
unmaintained/synth/authors.txt [deleted file]
unmaintained/synth/buffers/authors.txt [deleted file]
unmaintained/synth/buffers/buffers.factor [deleted file]
unmaintained/synth/example/authors.txt [deleted file]
unmaintained/synth/example/example.factor [deleted file]
unmaintained/synth/summary.txt [deleted file]
unmaintained/synth/synth.factor [deleted file]
vm/data_gc.c
vm/data_gc.h
vm/image.c

index 22dda8efb4b7d80d0abffccb5a77eeb385b6d221..b52c593b49078de911f8f400b84b53e698515c93 100644 (file)
@@ -25,3 +25,5 @@ build-support/wordsize
 .#*
 *.swo
 checksums.txt
+*.so
+a.out
index 3b9c56c8fb1a74162f1bafbcd0c86da3082cc529..c555061e586cb82f130bfb66409243a179a2808f 100644 (file)
@@ -58,3 +58,10 @@ $nl
     "} cond >>"
 }
 "Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
+
+ARTICLE: "loading-libs" "Loading native libraries"
+"Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
+{ $subsection add-library }
+"Once a library has been defined, you can try loading it to see if the path name is correct:"
+{ $subsection load-library }
+"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again." ;
index 193893fabc29d2ac9386f7a7afcbf706d9654e3c..df1dd15bfb7ad62ed10ca1f704092babc5717fef 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types arrays assocs effects grouping kernel
-parser sequences splitting words fry locals ;
+parser sequences splitting words fry locals lexer namespaces ;
 IN: alien.parser
 
 : parse-arglist ( parameters return -- types effect )
@@ -12,8 +12,15 @@ IN: alien.parser
 : function-quot ( return library function types -- quot )
     '[ _ _ _ _ alien-invoke ] ;
 
-:: define-function ( return library function parameters -- )
+:: make-function ( return library function parameters -- word quot effect )
     function create-in dup reset-generic
     return library function
-    parameters return parse-arglist [ function-quot ] dip
-    define-declared ;
+    parameters return parse-arglist [ function-quot ] dip ;
+
+: (FUNCTION:) ( -- word quot effect )
+    scan "c-library" get scan ";" parse-tokens
+    [ "()" subseq? not ] filter
+    make-function ;
+
+: define-function ( return library function parameters -- )
+    make-function define-declared ;
index 6a1bf7f635ff9bc502b163713b9d12e99dd3369b..0cc6d51446bdb82b4abff11912ecd56acc1b1c7a 100644 (file)
@@ -16,9 +16,7 @@ SYNTAX: BAD-ALIEN <bad-alien> parsed ;
 SYNTAX: LIBRARY: scan "c-library" set ;
 
 SYNTAX: FUNCTION:
-    scan "c-library" get scan ";" parse-tokens
-    [ "()" subseq? not ] filter
-    define-function ;
+    (FUNCTION:) define-declared ;
 
 SYNTAX: TYPEDEF:
     scan scan typedef ;
index 36f6291bc6f7bb31ca9617184182ad7a11c00919..ab08aa87a9b02fa170d8cebe5f386a7cbaff74bd 100644 (file)
@@ -8,7 +8,7 @@ namespaces eval kernel vocabs.loader io ;
         (command-line) parse-command-line
         load-vocab-roots
         run-user-init
-        "e" get [ eval ] when*
+        "e" get [ eval( -- ) ] when*
         ignore-cli-args? not script get and
         [ run-script ] [ "run" get run ] if*
         output-stream get [ stream-flush ] when*
index 12741f2170fba9dbb826481b26664cabdfc58b11..d6c1876d6a6e9149aa76137b1945cbd1b83d985e 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors init namespaces words words.symbol io
 kernel.private math memory continuations kernel io.files
 io.pathnames io.backend system parser vocabs sequences
 vocabs.loader combinators splitting source-files strings
-definitions assocs compiler.errors compiler.units math.parser
+definitions assocs compiler.units math.parser
 generic sets command-line ;
 IN: bootstrap.stage2
 
@@ -81,14 +81,11 @@ SYMBOL: bootstrap-time
         "none" require
     ] if
 
-    [
-        load-components
+    load-components
 
-        millis over - core-bootstrap-time set-global
+    millis over - core-bootstrap-time set-global
 
-        run-bootstrap-init
-    ] with-compiler-errors
-    :errors
+    run-bootstrap-init
 
     f error set-global
     f error-continuation set-global
index b0afe4a1d9bd0bf01545988b0bdc777a352d61ff..cb0792ee1e2ddaf0a21cf98b433e1365a4038af9 100644 (file)
@@ -6,6 +6,7 @@ IN: bootstrap.tools
     "bootstrap.image"
     "tools.annotations"
     "tools.crossref"
+    "tools.errors"
     "tools.deploy"
     "tools.disassembler"
     "tools.memory"
index 65e70bd04228565aa3ae2c39e3c74e5f4d0c56d1..a220de476a8ada60287d61d43d5a3082e172604e 100755 (executable)
@@ -5,6 +5,7 @@ kernel kernel.private layouts assocs words summary arrays
 combinators classes.algebra alien alien.c-types alien.structs
 alien.strings alien.arrays alien.complex sets libc alien.libraries
 continuations.private fry cpu.architecture
+source-files.errors
 compiler.errors
 compiler.alien
 compiler.cfg
@@ -379,8 +380,7 @@ TUPLE: no-such-library name ;
 M: no-such-library summary
     drop "Library not found" ;
 
-M: no-such-library compiler-error-type
-    drop +linkage+ ;
+M: no-such-library error-type drop +linkage-error+ ;
 
 : no-such-library ( name -- )
     \ no-such-library boa
@@ -391,8 +391,7 @@ TUPLE: no-such-symbol name ;
 M: no-such-symbol summary
     drop "Symbol not found" ;
 
-M: no-such-symbol compiler-error-type
-    drop +linkage+ ;
+M: no-such-symbol error-type drop +linkage-error+ ;
 
 : no-such-symbol ( name -- )
     \ no-such-symbol boa
index f19225a45c60d8ef1c0c2e2446c4662441eaa5bf..f92f0015d3c573f786db8c30de023b088cc80451 100644 (file)
@@ -1,5 +1,7 @@
-USING: help.markup help.syntax words io parser
-assocs words.private sequences compiler.units quotations ;
+USING: assocs compiler.cfg.builder compiler.cfg.optimizer
+compiler.errors compiler.tree.builder compiler.tree.optimizer
+compiler.units help.markup help.syntax io parser quotations
+sequences words words.private ;
 IN: compiler
 
 HELP: enable-compiler
@@ -18,6 +20,24 @@ ARTICLE: "compiler-usage" "Calling the optimizing compiler"
 { $subsection compile-call }
 "Higher-level words can be found in " { $link "compilation-units" } "." ;
 
+ARTICLE: "compiler-impl" "Compiler implementation"
+"The " { $vocab-link "compiler" } "vocabulary, in addition to providing the user-visible words of the compiler, implements the main compilation loop."
+$nl
+"Words are added to the " { $link compile-queue } " variable as needed and compiled."
+{ $subsection compile-queue }
+"Once compiled, a word is added to the assoc stored in the " { $link compiled } " variable. When compilation is complete, this assoc is passed to " { $link modify-code-heap } "."
+$nl
+"The " { $link (compile) } " word performs the actual task of compiling an individual word. The process proceeds as follows:"
+{ $list
+  { "The " { $link frontend } " word calls " { $link build-tree-from-word } ". If this fails, the error is passed to " { $link fail } ". The logic for ignoring compile warnings generated for inline words and macros is located here. If the error is not ignorable, it is added to the global " { $link compiler-errors } " assoc (see " { $link "compiler-errors" } ")." }
+  { "If the word contains a breakpoint, compilation ends here. Otherwise, all remaining steps execute until machine code is generated. Any further errors thrown by the compiler are not reported as compile errors, but instead are ordinary exceptions. This is because they indicate bugs in the compiler, not errors in user code." }
+  { "The " { $link frontend } " word then calls " { $link optimize-tree } ". This produces the final optimized tree IR, and this stage of the compiler is complete." }
+  { "The " { $link backend } " word calls " { $link build-cfg } " followed by " { $link optimize-cfg } " and a few other stages. Finally, it calls " { $link save-asm } ", and adds any uncompiled words called by this word to the compilation queue with " { $link maybe-compile } "." }
+}
+"If compilation fails, the word is stored in the " { $link compiled } " assoc with a value of " { $link f } ". This causes the VM to compile the word with the non-optimizing compiler."
+$nl
+"Calling " { $link modify-code-heap } " is handled not by the " { $vocab-link "compiler" } " vocabulary, but rather " { $vocab-link "compiler.units" } ". The optimizing compiler merely provides an implementation of the " { $link recompile } " generic word." ;
+
 ARTICLE: "compiler" "Optimizing compiler"
 "Factor includes two compilers which work behind the scenes. Words are always compiled, and the compilers do not have to be invoked explicitly. For the most part, compilation is fully transparent. However, there are a few things worth knowing about the compilation process."
 $nl
@@ -31,7 +51,8 @@ $nl
 "The optimizing compiler also trades off compile time for performance of generated code, so loading certain vocabularies might take a while. Saving the image after loading vocabularies can save you a lot of time that you would spend waiting for the same code to load in every coding session; see " { $link "images" } " for information."
 { $subsection "compiler-errors" }
 { $subsection "hints" }
-{ $subsection "compiler-usage" } ;
+{ $subsection "compiler-usage" }
+{ $subsection "compiler-impl" } ;
 
 ABOUT: "compiler"
 
index 04c1a9c55fb9a69033e871f7b818a79ac4337641..e5d88af14a92b68cb00d06d6f895f37114735ed9 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel namespaces arrays sequences io words fry
 continuations vocabs assocs dlists definitions math graphs generic
-combinators deques search-deques macros io stack-checker
+combinators deques search-deques macros io source-files.errors stack-checker
 stack-checker.state stack-checker.inlining combinators.short-circuit
 compiler.errors compiler.units compiler.tree.builder
 compiler.tree.optimizer compiler.cfg.builder compiler.cfg.optimizer
@@ -53,22 +53,30 @@ SYMBOLS: +optimized+ +unoptimized+ ;
     f swap compiler-error ;
 
 : ignore-error? ( word error -- ? )
-    [ [ inline? ] [ macro? ] bi or ]
-    [ compiler-error-type +warning+ eq? ] bi* and ;
-
-: fail ( word error -- * )
-    [ 2dup ignore-error? [ 2drop ] [ swap compiler-error ] if ]
     [
-        drop
-        [ compiled-unxref ]
-        [ f swap compiled get set-at ]
-        [ +unoptimized+ save-compiled-status ]
-        tri
-    ] 2bi
+        {
+            [ inline? ]
+            [ macro? ]
+            [ "transform-quot" word-prop ]
+            [ "no-compile" word-prop ]
+            [ "special" word-prop ]
+        } 1||
+    ] [ error-type +compiler-warning+ eq? ] bi* and ;
+
+: (fail) ( word -- * )
+    [ compiled-unxref ]
+    [ f swap compiled get set-at ]
+    [ +unoptimized+ save-compiled-status ]
+    tri
     return ;
 
+: fail ( word error -- * )
+    [ 2dup ignore-error? [ drop f ] when swap compiler-error ] [ drop (fail) ] 2bi ;
+
 : frontend ( word -- nodes )
-    [ build-tree-from-word ] [ fail ] recover optimize-tree ;
+    dup contains-breakpoints? [ (fail) ] [
+        [ build-tree-from-word ] [ fail ] recover optimize-tree
+    ] if ;
 
 ! Only switch this off for debugging.
 SYMBOL: compile-dependencies?
@@ -122,6 +130,8 @@ t compile-dependencies? set-global
 : compile-call ( quot -- )
     [ dup infer define-temp ] with-compilation-unit execute ;
 
+\ compile-call t "no-compile" set-word-prop
+
 SINGLETON: optimizing-compiler
 
 M: optimizing-compiler recompile ( words -- alist )
diff --git a/basis/compiler/errors/authors.txt b/basis/compiler/errors/authors.txt
new file mode 100755 (executable)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/compiler/errors/errors-docs.factor b/basis/compiler/errors/errors-docs.factor
new file mode 100644 (file)
index 0000000..6dbe519
--- /dev/null
@@ -0,0 +1,5 @@
+IN: compiler.errors
+USING: help.markup help.syntax vocabs.loader words io
+quotations words.symbol ;
+
+ABOUT: "compiler-errors"
diff --git a/basis/compiler/errors/errors.factor b/basis/compiler/errors/errors.factor
new file mode 100644 (file)
index 0000000..22ae8d9
--- /dev/null
@@ -0,0 +1,54 @@
+! Copyright (C) 2007, 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors source-files.errors kernel namespaces assocs ;
+IN: compiler.errors
+
+TUPLE: compiler-error < source-file-error ;
+
+M: compiler-error error-type error>> error-type ;
+
+SYMBOL: compiler-errors
+
+compiler-errors [ H{ } clone ] initialize
+
+SYMBOLS: +compiler-error+ +compiler-warning+ +linkage-error+ ;
+
+: errors-of-type ( type -- assoc )
+    compiler-errors get-global
+    swap [ [ nip error-type ] dip eq? ] curry
+    assoc-filter ;
+
+T{ error-type
+   { type +compiler-error+ }
+   { word ":errors" }
+   { plural "compiler errors" }
+   { icon "vocab:ui/tools/error-list/icons/compiler-error.tiff" }
+   { quot [ +compiler-error+ errors-of-type values ] }
+   { forget-quot [ compiler-errors get delete-at ] }
+} define-error-type
+
+T{ error-type
+   { type +compiler-warning+ }
+   { word ":warnings" }
+   { plural "compiler warnings" }
+   { icon "vocab:ui/tools/error-list/icons/compiler-warning.tiff" }
+   { quot [ +compiler-warning+ errors-of-type values ] }
+   { forget-quot [ compiler-errors get delete-at ] }
+} define-error-type
+
+T{ error-type
+   { type +linkage-error+ }
+   { word ":linkage" }
+   { plural "linkage errors" }
+   { icon "vocab:ui/tools/error-list/icons/linkage-error.tiff" }
+   { quot [ +linkage-error+ errors-of-type values ] }
+   { forget-quot [ compiler-errors get delete-at ] }
+   { fatal? f }
+} define-error-type
+
+: <compiler-error> ( error word -- compiler-error )
+    \ compiler-error <definition-error> ;
+
+: compiler-error ( error word -- )
+    compiler-errors get-global pick
+    [ [ [ <compiler-error> ] keep ] dip set-at ] [ delete-at drop ] if ;
diff --git a/basis/compiler/errors/summary.txt b/basis/compiler/errors/summary.txt
new file mode 100755 (executable)
index 0000000..01d106b
--- /dev/null
@@ -0,0 +1 @@
+Compiler warning and error reporting
index d6868fd034e24df3b9ba37e6432fc13bd211710e..fe2f801de23bfe65b346b9d9416074e3ff5ff5f2 100644 (file)
@@ -12,7 +12,7 @@ IN: compiler.tests
     IN: compiler.tests.folding
     GENERIC: foldable-generic ( a -- b ) foldable
     M: integer foldable-generic f <array> ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -20,7 +20,7 @@ IN: compiler.tests
     USING: math arrays ;
     IN: compiler.tests.folding
     : fold-test ( -- x ) 10 foldable-generic ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ t ] [
index 0875967bd2652a09903bb6e98ebebaa659fba379..8145ad628b0eb793597360546a89e61583855a0e 100644 (file)
@@ -11,7 +11,7 @@ M: integer method-redefine-generic-1 3 + ;
 
 [ 6 ] [ method-redefine-test-1 ] unit-test
 
-[ ] [ "IN: compiler.tests USE: math M: fixnum method-redefine-generic-1 4 + ;" eval ] unit-test
+[ ] [ "IN: compiler.tests USE: math M: fixnum method-redefine-generic-1 4 + ;" eval( -- ) ] unit-test
 
 [ 7 ] [ method-redefine-test-1 ] unit-test
 
@@ -27,7 +27,7 @@ M: integer method-redefine-generic-2 3 + ;
 
 [ 6 ] [ method-redefine-test-2 ] unit-test
 
-[ ] [ "IN: compiler.tests USE: kernel USE: math M: fixnum method-redefine-generic-2 4 + ; USE: strings M: string method-redefine-generic-2 drop f ;" eval ] unit-test
+[ ] [ "IN: compiler.tests USE: kernel USE: math M: fixnum method-redefine-generic-2 4 + ; USE: strings M: string method-redefine-generic-2 drop f ;" eval( -- ) ] unit-test
 
 [ 7 ] [ method-redefine-test-2 ] unit-test
 
@@ -43,10 +43,10 @@ M: integer method-redefine-generic-2 3 + ;
 
 [ t ] [ \ hey optimized>> ] unit-test
 [ t ] [ \ there optimized>> ] unit-test
-[ ] [ "IN: compiler.tests : hey ( -- ) 3 ;" eval ] unit-test
+[ ] [ "IN: compiler.tests : hey ( -- ) 3 ;" eval( -- ) ] unit-test
 [ f ] [ \ hey optimized>> ] unit-test
 [ f ] [ \ there optimized>> ] unit-test
-[ ] [ "IN: compiler.tests : hey ( -- ) ;" eval ] unit-test
+[ ] [ "IN: compiler.tests : hey ( -- ) ;" eval( -- ) ] unit-test
 [ t ] [ \ there optimized>> ] unit-test
 
 : good ( -- ) ;
@@ -59,7 +59,7 @@ M: integer method-redefine-generic-2 3 + ;
 
 [ f ] [ \ good compiled-usage assoc-empty? ] unit-test
 
-[ ] [ "IN: compiler.tests : good ( -- ) 3 ;" eval ] unit-test
+[ ] [ "IN: compiler.tests : good ( -- ) 3 ;" eval( -- ) ] unit-test
 
 [ f ] [ \ good optimized>> ] unit-test
 [ f ] [ \ bad optimized>> ] unit-test
@@ -67,7 +67,7 @@ M: integer method-redefine-generic-2 3 + ;
 
 [ t ] [ \ good compiled-usage assoc-empty? ] unit-test
 
-[ ] [ "IN: compiler.tests : good ( -- ) ;" eval ] unit-test
+[ ] [ "IN: compiler.tests : good ( -- ) ;" eval( -- ) ] unit-test
 
 [ t ] [ \ good optimized>> ] unit-test
 [ t ] [ \ bad optimized>> ] unit-test
index 8a6fb8a313e93a8c6ba82f7aee305462b0a563a5..faae7b8ed1e7c9ba6e9ad5b1b07d40e26dc7860d 100644 (file)
@@ -13,7 +13,7 @@ IN: compiler.tests
     MIXIN: my-mixin
     INSTANCE: fixnum my-mixin
     : my-inline ( a -- b ) dup my-mixin instance? [ 1 + ] when ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -21,7 +21,7 @@ IN: compiler.tests
     USE: math
     IN: compiler.tests.redefine10
     INSTANCE: float my-mixin
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ 2.0 ] [
index 18b1a3a43070188f06ec68cc1255d9ae8d54cb5d..57f9f9caf071dd4ac94f1d595577d7b04ff5fc84 100644 (file)
@@ -17,7 +17,7 @@ IN: compiler.tests
     M: my-mixin my-generic drop 0 ;
     M: object my-generic drop 1 ;
     : my-inline ( -- b ) { } my-generic ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
index 87dc4596e909ec209b20400efa95145eb5e7225c..ccf6c88e70f8d90a3cbd8a94bea1332f55028b98 100644 (file)
@@ -15,6 +15,6 @@ M: object g drop t ;
 
 TUPLE: jeah ;
 
-[ ] [ "USE: kernel IN: compiler.tests.redefine12 M: jeah g drop f ;" eval ] unit-test
+[ ] [ "USE: kernel IN: compiler.tests.redefine12 M: jeah g drop f ;" eval( -- ) ] unit-test
 
 [ f ] [ T{ jeah } h ] unit-test
index 5a28b282618dc83f9e91301fc85e6dd1b18e9eb0..6a7b7a6941e78b9e7e5c12d7c1c7ec6207cfa60d 100644 (file)
@@ -5,7 +5,7 @@ arrays words assocs eval words.symbol ;
 
 DEFER: redefine2-test
 
-[ ] [ "USE: sequences USE: kernel IN: compiler.tests TUPLE: redefine2-test ; M: redefine2-test nth 2drop 3 ; INSTANCE: redefine2-test sequence" eval ] unit-test
+[ ] [ "USE: sequences USE: kernel IN: compiler.tests TUPLE: redefine2-test ; M: redefine2-test nth 2drop 3 ; INSTANCE: redefine2-test sequence" eval( -- ) ] unit-test
 
 [ t ] [ \ redefine2-test symbol? ] unit-test
 
index b25b5a1a5e2dabc37744a10a01fb3ed22f057984..87ab100879b681994e0ebad1ae06ca132480cb08 100644 (file)
@@ -18,7 +18,7 @@ M: empty-mixin sheeple drop "wake up" ;
 [ t ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
 [ f ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
 
-[ ] [ "IN: compiler.tests USE: arrays INSTANCE: array empty-mixin" eval ] unit-test
+[ ] [ "IN: compiler.tests USE: arrays INSTANCE: array empty-mixin" eval( -- ) ] unit-test
 
 [ "wake up" ] [ sheeple-test ] unit-test
 [ f ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
index 2f21777801b44fd30e816a95bb7d39bd815cab8e..88b40f0c5a36a1c44aa9d206ba8523d3beaba3e8 100644 (file)
@@ -7,6 +7,6 @@ USING: io.streams.string kernel tools.test eval ;
 
 [ "" ] [ [ declaration-test ] with-string-writer ] unit-test
 
-[ ] [ "IN: compiler.tests USE: io : declaration-test-1 ( -- a ) \"X\" write f ;" eval ] unit-test
+[ ] [ "IN: compiler.tests USE: io : declaration-test-1 ( -- a ) \"X\" write f ;" eval( -- ) ] unit-test
 
 [ "X" ] [ [ declaration-test ] with-string-writer ] unit-test
index ac1619b8576e784abb816405be2d1e759c2de299..c390f9a1ecaddfecf4dc7c96ba74b4735183bf88 100644 (file)
@@ -14,7 +14,7 @@ IN: compiler.tests
     GENERIC: my-generic ( a -- b )
     M: object my-generic [ <=> ] sort ;
     : my-inline ( a -- b ) my-generic ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -23,7 +23,7 @@ IN: compiler.tests
     IN: compiler.tests.redefine5
     TUPLE: my-tuple ;
     M: my-tuple my-generic drop 0 ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ 0 ] [
index 73225c55b80e8f93a9280a6e90dc230c34184034..7f1be973e7aab7025f1c6a01aacf3bbde901b4f3 100644 (file)
@@ -14,7 +14,7 @@ IN: compiler.tests
     MIXIN: my-mixin
     M: my-mixin my-generic drop 0 ;
     : my-inline ( a -- b ) { my-mixin } declare my-generic ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -24,7 +24,7 @@ IN: compiler.tests
     TUPLE: my-tuple ;
     M: my-tuple my-generic drop 1 ;
     INSTANCE: my-tuple my-mixin
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ 1 ] [
index 164a2e383107968dcf552564cb0bd4a808051fa0..d6dfdf20fd30d79403fa45bca8aae8fd7b91d998 100644 (file)
@@ -13,7 +13,7 @@ IN: compiler.tests
     MIXIN: my-mixin
     INSTANCE: fixnum my-mixin
     : my-inline ( a -- b ) dup my-mixin? [ 1 + ] when ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -21,7 +21,7 @@ IN: compiler.tests
     USE: math
     IN: compiler.tests.redefine7
     INSTANCE: float my-mixin
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ 2.0 ] [
index c8b3377632a0025fe6627233a3b22c858c02c222..3499c5070a0a97578ae7c03aa176a8a401799796 100644 (file)
@@ -16,7 +16,7 @@ IN: compiler.tests
     ! We add the bogus quotation here to hinder inlining
     ! since otherwise we cannot trigger this bug.
     M: my-mixin my-generic 1 + [ [ <=> ] sort ] drop ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -24,7 +24,7 @@ IN: compiler.tests
     USE: math
     IN: compiler.tests.redefine8
     INSTANCE: float my-mixin
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ 2.0 ] [
index 7b0f8a2e9c04d542d4d2f080a525c301df9ffbd9..25ed5f15db2e28e4aaae556916d658ce4ecbcb8d 100644 (file)
@@ -16,7 +16,7 @@ IN: compiler.tests
     ! We add the bogus quotation here to hinder inlining
     ! since otherwise we cannot trigger this bug.
     M: my-mixin my-generic 1 + [ [ <=> ] sort ] drop ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [ ] [
@@ -25,7 +25,7 @@ IN: compiler.tests
     IN: compiler.tests.redefine9
     TUPLE: my-tuple ;
     INSTANCE: my-tuple my-mixin
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 [
index d53b864b06c7dc8e9ee5b275552160e756854d49..769182a8b16986b4d04110e8a3a648d4ecd28874 100644 (file)
@@ -237,6 +237,6 @@ M: f single-combination-test-2 single-combination-test-4 ;
 10 [
     [ "compiler.tests.foo" forget-vocab ] with-compilation-unit
     [ t ] [
-        "USING: prettyprint words accessors ; IN: compiler.tests.foo : (recursive) ( -- ) (recursive) (recursive) ; inline recursive : recursive ( -- ) (recursive) ; \\ (recursive) optimized>>" eval
+        "USING: prettyprint words accessors ; IN: compiler.tests.foo : (recursive) ( -- ) (recursive) (recursive) ; inline recursive : recursive ( -- ) (recursive) ; \\ (recursive) optimized>>" eval( -- obj )
     ] unit-test
 ] times
index 4cb7650b1de1721d6472408a80ac84c0e9e100a6..fe9c2a26a4e732a060119cb8a6bbe82f1174d7cf 100644 (file)
@@ -42,8 +42,10 @@ IN: compiler.tree.builder
 : check-cannot-infer ( word -- )
     dup "cannot-infer" word-prop [ cannot-infer-effect ] [ drop ] if ;
 
+TUPLE: do-not-compile word ;
+
 : check-no-compile ( word -- )
-    dup "no-compile" word-prop [ cannot-infer-effect ] [ drop ] if ;
+    dup "no-compile" word-prop [ do-not-compile inference-warning ] [ drop ] if ;
 
 : build-tree-from-word ( word -- nodes )
     [
@@ -56,3 +58,6 @@ IN: compiler.tree.builder
             } cleave
         ] maybe-cannot-infer
     ] with-tree-builder ;
+
+: contains-breakpoints? ( word -- ? )
+    def>> [ word? ] filter [ "break?" word-prop ] any? ;
index 7de092d84aac6608b50e6b0a61f2318deb392f7b..c596be263ae3a858037a816710e3187842caedc5 100755 (executable)
@@ -197,7 +197,7 @@ M: fixnum annotate-entry-test-1 drop ;
         [ dup annotate-entry-test-1 1+ ] dip (annotate-entry-test-2)
     ] if ; inline recursive
 
-: annotate-entry-test-2 ( from to -- ) 0 -rot (annotate-entry-test-2) ; inline
+: annotate-entry-test-2 ( from to -- obj ) 0 -rot (annotate-entry-test-2) ; inline
 
 [ f ] [
     [ { bignum } declare annotate-entry-test-2 ]
@@ -302,7 +302,7 @@ cell-bits 32 = [
 ] unit-test
 
 [ t ] [
-    [ 1000 [ 1+ ] map ] { 1+ fixnum+ } inlined?
+    [ 1000 iota [ 1+ ] map ] { 1+ fixnum+ } inlined?
 ] unit-test
 
 : rec ( a -- b )
@@ -519,4 +519,4 @@ cell-bits 32 = [
 [ t ] [
     [ { integer integer } declare + drop ]
     { + +-integer-integer } inlined?
-] unit-test
\ No newline at end of file
+] unit-test
index 5ac3c57abed18f0948335c50cfbaea511d430f7e..680ae0b1709f0a28abe2696ad810a8b2afab1bf7 100644 (file)
@@ -17,13 +17,13 @@ sequences accessors tools.test kernel math ;
 
 [ 2 ] [ [ 3 [ drop ] [ 2drop 3 ] if ] build-tree count-introductions ] unit-test
 
-: foo ( -- ) swap ; inline recursive
+: foo ( quot: ( -- ) -- ) call ; inline recursive
 
 : recursive-inputs ( nodes -- n )
     [ #recursive? ] find nip child>> first in-d>> length ;
 
-[ 0 2 ] [
-    [ foo ] build-tree
+[ 1 3 ] [
+    [ [ swap ] foo ] build-tree
     [ recursive-inputs ]
     [ analyze-recursive normalize recursive-inputs ] bi
 ] unit-test
@@ -34,18 +34,18 @@ sequences accessors tools.test kernel math ;
 [ ] [ [ [ 1 ] [ 2 ] if + * ] test-normalization ] unit-test
 
 DEFER: bbb
-: aaa ( x -- ) dup [ dup [ bbb ] dip aaa ] [ drop ] if ; inline recursive
-: bbb ( x -- ) [ drop 0 ] dip aaa ; inline recursive
+: aaa ( obj x -- obj ) dup [ dup [ bbb ] dip aaa ] [ drop ] if ; inline recursive
+: bbb ( obj x -- obj ) [ drop 0 ] dip aaa ; inline recursive
 
 [ ] [ [ bbb ] test-normalization ] unit-test
 
-: ccc ( -- ) ccc drop 1 ; inline recursive
+: ccc ( obj -- 1 ) ccc drop 1 ; inline recursive
 
 [ ] [ [ ccc ] test-normalization ] unit-test
 
 DEFER: eee
-: ddd ( -- ) eee ; inline recursive
-: eee ( -- ) swap ddd ; inline recursive
+: ddd ( a b -- a b ) eee ; inline recursive
+: eee ( a b -- a b ) swap ddd ; inline recursive
 
 [ ] [ [ eee ] test-normalization ] unit-test
 
index f18cfcd3a3aad1e48c56ddd3d12a4c0cf5798fb5..0815351057616bf5dae89d5c581f978e0a2764b8 100755 (executable)
@@ -148,7 +148,11 @@ DEFER: (flat-length)
     ] sum-outputs ;
 
 : should-inline? ( #call word -- ? )
-    dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ;
+    {
+        { [ dup contains-breakpoints? ] [ 2drop f ] }
+        { [ dup "inline" word-prop ] [ 2drop t ] }
+        [ inlining-rank 5 >= ]
+    } cond ;
 
 SYMBOL: history
 
index 5dd647ae8915c62f5d6d2d8685c4a1076318149c..5b9b49811f6ae4e2ec2065f960524686fc22fabc 100644 (file)
@@ -680,11 +680,11 @@ TUPLE: littledan-2 { from read-only } { to read-only } ;
 : (littledan-3-test) ( x -- )
     length 1+ f <array> (littledan-3-test) ; inline recursive
 
-: littledan-3-test ( -- )
+: littledan-3-test ( -- )
     0 f <array> (littledan-3-test) ; inline
 
 [ ] [ [ littledan-3-test ] final-classes drop ] unit-test
 
 [ V{ 0 } ] [ [ { } length ] final-literals ] unit-test
 
-[ V{ 1 } ] [ [ { } length 1+ f <array> length ] final-literals ] unit-test
\ No newline at end of file
+[ V{ 1 } ] [ [ { } length 1+ f <array> length ] final-literals ] unit-test
index d548d58bc6f9e8d19615fccb9841bd7873fbe7d9..971675d3671e2a21e68cd7774d29a449b2e7b877 100644 (file)
@@ -57,7 +57,7 @@ compiler.tree.combinators ;
     \ (each-integer) label-is-loop?
 ] unit-test
 
-: loop-test-2 ( a -- )
+: loop-test-2 ( a b -- a' )
     dup [ 1+ loop-test-2 1- ] [ drop ] if ; inline recursive
 
 [ t ] [
index 569b1a72c2cf3fee247f1e489dfaa1594e853a54..3b5b014fe3854a83b681a39a61ea55c13f208e3c 100644 (file)
@@ -3,7 +3,7 @@ USING: sequences tools.test concurrency.exchangers
 concurrency.count-downs concurrency.promises locals kernel\r
 threads ;\r
 \r
-:: exchanger-test ( -- )\r
+:: exchanger-test ( -- string )\r
     [let |\r
         ex [ <exchanger> ]\r
         c [ 2 <count-down> ]\r
index a66629331652532fed94f07fdbd0fb24496deed3..05ff74b03f27236dcf436e2e74aef8688ba07aa3 100644 (file)
@@ -11,7 +11,7 @@ kernel threads locals accessors calendar ;
 \r
 [ f ] [ flag-test-1 ] unit-test\r
 \r
-:: flag-test-2 ( -- )\r
+:: flag-test-2 ( -- )\r
     [let | f [ <flag> ] |\r
         [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
         f lower-flag\r
index 8e160842a93d5f7abb0c907a70723f6bc8d32ff3..69f12d87397aac4d192bc3311e7dc888e991e3e8 100644 (file)
@@ -7,6 +7,10 @@ IN: concurrency.promises
 HELP: promise\r
 { $class-description "The class of write-once promises." } ;\r
 \r
+HELP: <promise>\r
+{ $values { "promise" promise } }\r
+{ $description "Creates a new promise which may be fulfilled by calling " { $link fulfill } "." } ;\r
+\r
 HELP: promise-fulfilled?\r
 { $values { "promise" promise } { "?" "a boolean" } }\r
 { $description "Tests if " { $link fulfill } " has previously been called on the promise, in which case " { $link ?promise } " will return immediately without blocking." } ;\r
index ec7bf8f34185a1cba1b73692a624b7b4e76cdb77..1431d471c161b4496c8ea064aac2966de4953f22 100644 (file)
@@ -310,7 +310,7 @@ CONSTANT: rs-reg 30
     4 ds-reg 0 LWZ\r
     5 ds-reg -4 LWZU\r
     5 0 4 CMP\r
-    2 swap execute ! magic number\r
+    2 swap execute( offset -- ) ! magic number\r
     \ f tag-number 3 LI\r
     3 ds-reg 0 STW ;\r
 \r
@@ -341,7 +341,7 @@ CONSTANT: rs-reg 30
 : jit-math ( insn -- )\r
     3 ds-reg 0 LWZ\r
     4 ds-reg -4 LWZU\r
-    [ 5 3 4 ] dip execute\r
+    [ 5 3 4 ] dip execute( dst src1 src2 -- )\r
     5 ds-reg 0 STW ;\r
 \r
 [ \ ADD jit-math ] f f f \ fixnum+fast define-sub-primitive\r
index f5829d76ea267edf32f21c9090574df1b5ac2ca9..b63d31364b915ca8146bd8b9894a0f04b4632f8e 100644 (file)
@@ -334,7 +334,7 @@ big-endian off
     ! compare with second value
     ds-reg [] temp0 CMP
     ! move t if true
-    [ temp1 temp3 ] dip execute
+    [ temp1 temp3 ] dip execute( dst src -- )
     ! store
     ds-reg [] temp1 MOV ;
 
@@ -355,7 +355,7 @@ big-endian off
     ! pop stack
     ds-reg bootstrap-cell SUB
     ! compute result
-    [ ds-reg [] temp0 ] dip execute ;
+    [ ds-reg [] temp0 ] dip execute( dst src -- ) ;
 
 [ \ ADD jit-math ] f f f \ fixnum+fast define-sub-primitive
 
index efd35ab2803055b47556bbf552bc73c1e7d991c9..49ec534e8fa59c9bc0f27219235a8e9934394628 100644 (file)
@@ -8,8 +8,9 @@ classes.mixin classes.tuple continuations continuations.private
 combinators generic.math classes.builtin classes compiler.units
 generic.standard vocabs init kernel.private io.encodings
 accessors math.order destructors source-files parser
-classes.tuple.parser effects.parser lexer compiler.errors
-generic.parser strings.parser vocabs.loader vocabs.parser ;
+classes.tuple.parser effects.parser lexer
+generic.parser strings.parser vocabs.loader vocabs.parser see
+source-files.errors ;
 IN: debugger
 
 GENERIC: error. ( error -- )
@@ -213,14 +214,13 @@ M: condition error-help error>> error-help ;
 
 M: assert summary drop "Assertion failed" ;
 
-M: assert error.
-    "Assertion failed" print
+M: assert-sequence summary drop "Assertion failed" ;
+
+M: assert-sequence error.
     standard-table-style [
-        15 length-limit set
-        5 line-limit set
-        [ expect>> [ [ "Expect:" write ] with-cell pprint-cell ] with-row ]
-        [ got>> [ [ "Got:" write ] with-cell pprint-cell ] with-row ] bi
-    ] tabular-output nl ;
+        [ "=== Expected:" print expected>> stack. ]
+        [ "=== Got:" print got>> stack. ] bi
+    ] tabular-output ;
 
 M: immutable summary drop "Sequence is immutable" ;
 
@@ -268,20 +268,6 @@ M: duplicate-slot-names summary
 M: invalid-slot-name summary
     drop "Invalid slot name" ;
 
-: file. ( file -- ) path>> <pathname> . ;
-
-M: source-file-error error.
-    [ file>> file. ] [ error>> error. ] bi ;
-
-M: source-file-error summary
-    error>> summary ;
-
-M: source-file-error compute-restarts
-    error>> compute-restarts ;
-
-M: source-file-error error-help
-    error>> error-help ;
-
 M: not-in-a-method-error summary
     drop "call-next-method can only be called in a method definition" ;
 
@@ -309,12 +295,6 @@ M: lexer-error compute-restarts
 M: lexer-error error-help
     error>> error-help ;
 
-M: object compiler-error. ( error word -- )
-    nl
-    "While compiling " write pprint ": " print
-    nl
-    print-error ;
-
 M: bad-effect summary
     drop "Bad stack effect declaration" ;
 
index cf822b40a351f25e2a92c7893b6342b3546369aa..f6a40d8dc82a0d35068e3c7fd759ac66f4d9c711 100644 (file)
@@ -35,7 +35,7 @@ M: hello bing hello-test ;
 [ 3 ] [ 1 0 <hello> 2 whoa ] unit-test
 [ 3 ] [ 1 0 <hello> f <goodbye> 2 whoa ] unit-test
 
-[ ] [ 3 [ "USING: accessors delegate ; IN: delegate.tests CONSULT: baz goodbye these>> ;" eval ] times ] unit-test
+[ ] [ 3 [ "USING: accessors delegate ; IN: delegate.tests CONSULT: baz goodbye these>> ;" eval( -- ) ] times ] unit-test
 [ H{ { goodbye T{ consultation f baz goodbye [ these>> ] } } } ] [ baz protocol-consult ] unit-test
 [ H{ } ] [ bee protocol-consult ] unit-test
 
@@ -63,22 +63,22 @@ CONSULT: beta hey value>> 1- ;
 [ 0 ] [ 1 <hey> three ] unit-test
 [ { hey } ] [ alpha protocol-users ] unit-test
 [ { hey } ] [ beta protocol-users ] unit-test
-[ ] [ "USE: delegate IN: delegate.tests PROTOCOL: alpha one ;" eval ] unit-test
+[ ] [ "USE: delegate IN: delegate.tests PROTOCOL: alpha one ;" eval( -- ) ] unit-test
 [ f ] [ hey \ two method ] unit-test
 [ f ] [ hey \ four method ] unit-test
-[ ] [ "USE: delegate IN: delegate.tests PROTOCOL: beta two three four ;" eval ] unit-test
+[ ] [ "USE: delegate IN: delegate.tests PROTOCOL: beta two three four ;" eval( -- ) ] unit-test
 [ { hey } ] [ alpha protocol-users ] unit-test
 [ { hey } ] [ beta protocol-users ] unit-test
 [ 2 ] [ 1 <hey> one ] unit-test
 [ 0 ] [ 1 <hey> two ] unit-test
 [ 0 ] [ 1 <hey> three ] unit-test
 [ 0 ] [ 1 <hey> four ] unit-test
-[ ] [ "USING: math accessors delegate ; IN: delegate.tests CONSULT: beta hey value>> 2 - ;" eval ] unit-test
+[ ] [ "USING: math accessors delegate ; IN: delegate.tests CONSULT: beta hey value>> 2 - ;" eval( -- ) ] unit-test
 [ 2 ] [ 1 <hey> one ] unit-test
 [ -1 ] [ 1 <hey> two ] unit-test
 [ -1 ] [ 1 <hey> three ] unit-test
 [ -1 ] [ 1 <hey> four ] unit-test
-[ ] [ "IN: delegate.tests FORGET: alpha" eval ] unit-test
+[ ] [ "IN: delegate.tests FORGET: alpha" eval( -- ) ] unit-test
 [ f ] [ hey \ one method ] unit-test
 
 TUPLE: slot-protocol-test-1 a b ;
@@ -196,4 +196,4 @@ DEFER: seq-delegate
     seq-delegate
     sequence-protocol \ protocol-consult word-prop
     key?
-] unit-test
\ No newline at end of file
+] unit-test
index e3961aef80dbab80e76181fe54fdf46f3b73e02e..30611ca699297f0b3b7e736653fb3cd10506adad 100644 (file)
@@ -1,4 +1,5 @@
-USING: help.markup help.syntax parser source-files vocabs.loader ;
+USING: help.markup help.syntax parser source-files
+source-files.errors vocabs.loader ;
 IN: editors
 
 ARTICLE: "editor" "Editor integration"
@@ -13,6 +14,9 @@ ARTICLE: "editor" "Editor integration"
 
 ABOUT: "editor"
 
+HELP: edit-hook
+{ $var-description "A quotation with stack effect " { $snippet "( file line -- )" } ". If not set, the " { $link edit } " word throws a condition with restarts for loading one of the sub-vocabularies of the " { $vocab-link "editors" } " vocabulary." } ;
+
 HELP: edit
 { $values { "defspec" "a definition specifier" } }
 { $description "Opens the source file containing the definition using the current " { $link edit-hook } ". See " { $link "editor" } "." }
index 0003b508fb2c6903aad9e5532e3a2777d1d98bab..6088400bd8e41d422675d403fa3c61477b103d16 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser lexer kernel namespaces sequences definitions
-io.files io.backend io.pathnames io summary continuations
-tools.crossref tools.vocabs prettyprint source-files assocs
+USING: parser lexer kernel namespaces sequences definitions io.files
+io.backend io.pathnames io summary continuations tools.crossref
+tools.vocabs prettyprint source-files source-files.errors assocs
 vocabs vocabs.loader splitting accessors debugger prettyprint
 help.topics ;
 IN: editors
@@ -57,7 +57,7 @@ M: lexer-error error-line
     [ error>> error-line ] [ line>> ] bi or ;
 
 M: source-file-error error-file
-    [ error>> error-file ] [ file>> path>> ] bi or ;
+    [ error>> error-file ] [ file>> ] bi or ;
 
 M: source-file-error error-line
     error>> error-line ;
@@ -81,6 +81,9 @@ M: object error-line
 : :edit ( -- )
     error get (:edit) ;
 
+: edit-error ( error -- )
+    [ file>> ] [ line#>> ] bi 2dup and [ edit-location ] [ 2drop ] if ;
+
 : edit-each ( seq -- )
     [
         [ "Editing " write . ]
diff --git a/basis/editors/gedit/authors.txt b/basis/editors/gedit/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/editors/gedit/gedit.factor b/basis/editors/gedit/gedit.factor
new file mode 100644 (file)
index 0000000..97ea0e1
--- /dev/null
@@ -0,0 +1,17 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: editors io.launcher kernel make math.parser namespaces
+sequences ;
+IN: editors.gedit
+
+: gedit-path ( -- path )
+    \ gedit-path get-global [
+        "gedit"
+    ] unless* ;
+
+: gedit ( file line -- )
+    [
+        gedit-path , number>string "+" prepend , ,
+    ] { } make run-detached drop ;
+
+[ gedit ] edit-hook set-global
diff --git a/basis/editors/gedit/summary.txt b/basis/editors/gedit/summary.txt
new file mode 100644 (file)
index 0000000..ebb7189
--- /dev/null
@@ -0,0 +1 @@
+gedit integration
diff --git a/basis/editors/gedit/tags.txt b/basis/editors/gedit/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index b53c3bae6bb040eda37fe7e186129594d642d1ee..b30c6d9cb93d83840535892dcff3fcbd06d9b134 100644 (file)
@@ -1,18 +1,23 @@
 IN: eval
-USING: help.markup help.syntax strings io ;
+USING: help.markup help.syntax strings io effects ;
 
 HELP: eval
-{ $values { "str" string } }
-{ $description "Parses Factor source code from a string, and calls the resulting quotation." }
+{ $values { "str" string } { "effect" effect } }
+{ $description "Parses Factor source code from a string, and calls the resulting quotation, which must have the given stack effect." }
+{ $errors "Throws an error if the input is malformed, or if the evaluation itself throws an error." } ;
+
+HELP: eval(
+{ $syntax "eval( inputs -- outputs )" }
+{ $description "Parses Factor source code from the string at the top of the stack, and calls the resulting quotation, which must have the given stack effect." }
 { $errors "Throws an error if the input is malformed, or if the evaluation itself throws an error." } ;
 
 HELP: eval>string
 { $values { "str" string } { "output" string } }
-{ $description "Evaluates the Factor code in " { $snippet "str" } " with " { $link output-stream } " rebound to a string output stream, then outputs the resulting string." } ;
+{ $description "Evaluates the Factor code in " { $snippet "str" } " with " { $link output-stream } " rebound to a string output stream, then outputs the resulting string. The code in the string must not take or leave any values on the stack." } ;
 
 ARTICLE: "eval" "Evaluating strings at runtime"
 "The " { $vocab-link "eval" } " vocabulary implements support for evaluating strings at runtime."
-{ $subsection eval }
+{ $subsection POSTPONE: eval( }
 { $subsection eval>string } ;
 
 ABOUT: "eval"
index 675921944ab75a62552fdcefe9ce0c828da29396..d27e66119346609f0fc9ef1a4d83488c2ed52967 100644 (file)
@@ -1,4 +1,6 @@
 IN: eval.tests
 USING: eval tools.test ;
 
+[ 4 ] [ "USE: math 2 2 +" eval( -- result ) ] unit-test
+[ "USE: math 2 2 +" eval( -- ) ] must-fail
 [ "4\n" ] [ "USING: math prettyprint ; 2 2 + ." eval>string ] unit-test
index 3672337a584d0f17f8860a816246f6ef87d93348..4c5b9e8cf9a72c0fb56860cd7cb01b22ef92a8a1 100644 (file)
@@ -1,23 +1,25 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: splitting parser compiler.units kernel namespaces
-debugger io.streams.string fry ;
+debugger io.streams.string fry combinators effects.parser ;
 IN: eval
 
 : parse-string ( str -- quot )
     [ string-lines parse-lines ] with-compilation-unit ;
 
-: (eval) ( str -- )
-    parse-string call ;
+: (eval) ( str effect -- )
+    [ parse-string ] dip call-effect ; inline
 
-: eval ( str -- )
-    [ (eval) ] with-file-vocabs ;
+: eval ( str effect -- )
+    [ (eval) ] with-file-vocabs ; inline
+
+SYNTAX: eval( \ eval parse-call( ;
 
 : (eval>string) ( str -- output )
     [
         "quiet" on
         parser-notes off
-        '[ _ (eval) ] try
+        '[ _ (( -- )) (eval) ] try
     ] with-string-writer ;
 
 : eval>string ( str -- output )
index d240e6f23374f769c15e3256843b24bc416d7420..88ecae66addbb2dc29f8c7bed661c822dea6f44d 100644 (file)
@@ -56,7 +56,7 @@ sequences eval accessors ;
     3 '[ [ [ _ 1array ] call 1array ] call 1array ] call
 ] unit-test
 
-[ "USING: fry locals.backend ; f '[ load-local _ ]" eval ]
+[ "USING: fry locals.backend ; f '[ load-local _ ]" eval( -- quot ) ]
 [ error>> >r/r>-in-fry-error? ] must-fail-with
 
 [ { { "a" 1 } { "b" 2 } { "c" 3 } { "d" 4 } } ] [
index b325c778cfa2ae8f8aac7d8adcde459e5fd2ec88..99855c76fa8fc09a05841a2343381233f1de03bf 100644 (file)
@@ -22,7 +22,7 @@ M: foo call-responder*
     "x" [ 1+ ] schange\r
     "x" sget number>string "text/html" <content> ;\r
 \r
-: url-responder-mock-test ( -- )\r
+: url-responder-mock-test ( -- string )\r
     [\r
         <request>\r
             "GET" >>method\r
@@ -34,7 +34,7 @@ M: foo call-responder*
         [ write-response-body drop ] with-string-writer\r
     ] with-destructors ;\r
 \r
-: sessions-mock-test ( -- )\r
+: sessions-mock-test ( -- string )\r
     [\r
         <request>\r
             "GET" >>method\r
index 2088e468c64593800b8d869e335f6b618ceb6bfa..36715111940242937ab1e43d6976993a4151f139 100644 (file)
@@ -272,8 +272,8 @@ HELP: nweave
 \r
 HELP: n*quot\r
 { $values\r
-     { "n" integer } { "seq" sequence }\r
-     { "seq'" sequence }\r
+     { "n" integer } { "quot" quotation }\r
+     { "quot'" quotation }\r
 }\r
 { $examples\r
     { $example "USING: generalizations prettyprint math ;"\r
index 0aa042d4f2e7056159d3d1775c8fd31853fc5808..edee44acc67c96511e3eddde255c1a431145f4e6 100644 (file)
@@ -7,7 +7,7 @@ IN: generalizations
 
 <<
 
-: n*quot ( n seq -- seq' ) <repetition> concat >quotation ;
+: n*quot ( n quot -- quot' ) <repetition> concat >quotation ;
 
 : repeat ( n obj quot -- ) swapd times ; inline
 
@@ -94,4 +94,4 @@ MACRO: nweave ( n -- )
 : nappend-as ( n exemplar -- seq )
     [ narray concat ] dip like ; inline
 
-: nappend ( n -- seq ) narray concat ; inline
\ No newline at end of file
+: nappend ( n -- seq ) narray concat ; inline
index 6f97c7c3d5412fd65606f39540a6edef2d9b5253..682680bc508e97667a1a172b03047d51fae2b21a 100644 (file)
@@ -4,11 +4,11 @@ IN: hash2.tests
 [ t ] [ 1 2 { 1 2 } 2= ] unit-test
 [ f ] [ 1 3 { 1 2 } 2= ] unit-test
 
-: sample-hash ( -- )
+: sample-hash ( -- hash )
     5 <hash2>
-    dup 2 3 "foo" roll set-hash2
-    dup 4 2 "bar" roll set-hash2
-    dup 4 7 "other" roll set-hash2 ;
+    [ [ 2 3 "foo" ] dip set-hash2 ] keep
+    [ [ 4 2 "bar" ] dip set-hash2 ] keep
+    [ [ 4 7 "other" ] dip set-hash2 ] keep ;
 
 [ "foo" ] [ 2 3 sample-hash hash2 ] unit-test
 [ "bar" ] [ 4 2 sample-hash hash2 ] unit-test
index ffe6926130bc6dbfba7817b77217a3e55cf57868..aadc0d45a2299dee35d782f3820d9f41a3918d97 100644 (file)
@@ -1,4 +1,6 @@
-USING: kernel sequences arrays math vectors ;
+! Copyright (C) 2007 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences arrays math vectors locals ;
 IN: hash2
 
 ! Little ad-hoc datastructure used to map two numbers
@@ -22,8 +24,8 @@ IN: hash2
 : assoc2 ( a b alist -- value )
     (assoc2) dup [ third ] when ; inline
 
-: set-assoc2 ( value a b alist -- alist )
-    [ rot 3array ] dip ?push ; inline
+:: set-assoc2 ( value a b alist -- alist )
+    { a b value } alist ?push ; inline
 
 : hash2@ ( a b hash2 -- a b bucket hash2 )
     [ 2dup hashcode2 ] dip [ length mod ] keep ; inline
@@ -31,8 +33,8 @@ IN: hash2
 : hash2 ( a b hash2 -- value/f )
     hash2@ nth dup [ assoc2 ] [ 3drop f ] if ;
 
-: set-hash2 ( a b value hash2 -- )
-    [ -rot ] dip hash2@ [ set-assoc2 ] change-nth ;
+:: set-hash2 ( a b value hash2 -- )
+    value a b hash2 hash2@ [ set-assoc2 ] change-nth ;
 
 : alist>hash2 ( alist size -- hash2 )
     <hash2> [ over [ first3 ] dip set-hash2 ] reduce ; inline
index 7e780cbe5ef674cf56b22a4aef1335d362306143..b4761075628044451643170673cbabd6267c3d9b 100644 (file)
@@ -54,7 +54,7 @@ IN: heaps.tests
 : sort-entries ( entries -- entries' )
     [ [ key>> ] compare ] sort ;
 
-: delete-test ( n -- ? )
+: delete-test ( n -- obj1 obj2 )
     [
         random-alist
         <min-heap> [ heap-push-all ] keep
index 867f3732098b8d855683b0f934624b3160e5651f..9bb76f8d5a4767d73d973451d4c1b420ab7323c8 100644 (file)
@@ -74,7 +74,7 @@ $nl
     "shuffle-words"
     "words"
     "generic"
-    "tools"
+    "handbook-tools-reference"
 } ;
 
 ARTICLE: "cookbook-combinators" "Control flow cookbook"
index 2e01330d73ba9b723c62ae89085666822c19f552..95d4612cbed90b31ca9a781605973ed7c8c31afd 100644 (file)
@@ -4,7 +4,7 @@ definitions assocs sequences kernel namespaces parser arrays
 io.streams.string continuations debugger compiler.units eval ;
 
 [ ] [
-    "IN: help.crossref.tests USING: help.syntax help.markup ; : foo ( -- ) ; HELP: foo \"foo is great\" ; ARTICLE: \"foo\" \"Foo\" { $subsection foo } ;" eval
+    "IN: help.crossref.tests USING: help.syntax help.markup ; : foo ( -- ) ; HELP: foo \"foo is great\" ; ARTICLE: \"foo\" \"Foo\" { $subsection foo } ;" eval( -- )
 ] unit-test
 
 [ $subsection ] [
@@ -23,7 +23,7 @@ io.streams.string continuations debugger compiler.units eval ;
 ] unit-test
 
 [ ] [
-    "IN: help.crossref.tests USING: help.syntax help.markup ; : bar ( -- ) ; HELP: bar \"bar is great\" ; ARTICLE: \"bar\" \"Bar\" { $subsection bar } ;" eval
+    "IN: help.crossref.tests USING: help.syntax help.markup ; : bar ( -- ) ; HELP: bar \"bar is great\" ; ARTICLE: \"bar\" \"Bar\" { $subsection bar } ;" eval( -- )
 ] unit-test
 
 [ ] [
index 7bb66eca02fa2e019e72a300ba3889e5c2ae5e9a..c3365fe53fcae42519bb03cee1ba09edd42932f7 100644 (file)
@@ -32,7 +32,7 @@ IN: help.definitions.tests
         "hello" "help.definitions.tests" lookup "help" word-prop
     ] unit-test
 
-    [ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ( -- ) ; HELP: xxx ;" eval ] unit-test
+    [ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ( -- ) ; HELP: xxx ;" eval( -- ) ] unit-test
 
     [ ] [ "xxx" "help.definitions.tests" lookup print-topic ] unit-test
 
index 0845264d61312c9068d80f3fd2a0f4f49bb03b6a..ebce042e06054a0d063e304a3e8fb7cdb23f5c1a 100644 (file)
@@ -5,7 +5,7 @@ math system strings sbufs vectors byte-arrays quotations
 io.streams.byte-array classes.builtin parser lexer
 classes.predicate classes.union classes.intersection
 classes.singleton classes.tuple help.vocabs math.parser
-accessors definitions ;
+accessors definitions sets ;
 IN: help.handbook
 
 ARTICLE: "conventions" "Conventions"
@@ -197,29 +197,6 @@ ARTICLE: "io" "Input and output"
 { $subsection "io.ports" }
 { $see-also "destructors" } ;
 
-ARTICLE: "tools" "Developer tools"
-{ $subsection "tools.vocabs" }
-"Exploratory tools:"
-{ $subsection "see" }
-{ $subsection "editor" }
-{ $subsection "listener" }
-{ $subsection "tools.crossref" }
-{ $subsection "inspector" }
-{ $subsection "tools.completion" }
-{ $subsection "summary" }
-"Debugging tools:"
-{ $subsection "tools.annotations" }
-{ $subsection "tools.test" }
-{ $subsection "tools.threads" }
-"Performance tools:"
-{ $subsection "tools.memory" }
-{ $subsection "profiling" }
-{ $subsection "timing" }
-{ $subsection "tools.disassembler" }
-"Deployment tools:"
-{ $subsection "tools.deploy" }
-{ $see-also "ui-tools" } ;
-
 ARTICLE: "article-index" "Article index"
 { $index [ articles get keys ] } ;
 
@@ -248,59 +225,79 @@ ARTICLE: "class-index" "Class index"
 
 USING: help.cookbook help.tutorial ;
 
-ARTICLE: "handbook-language-reference" "Language reference"
-"Fundamentals:"
+ARTICLE: "handbook-language-reference" "The language"
+{ $heading "Fundamentals" }
 { $subsection "conventions" }
 { $subsection "syntax" }
 { $subsection "effects" }
-"Data types:"
+{ $subsection "evaluator" }
+{ $heading "Data types" }
 { $subsection "booleans" }
 { $subsection "numbers" }
 { $subsection "collections" }
-"Evaluation semantics:"
-{ $subsection "evaluator" }
+{ $heading "Evaluation" }
 { $subsection "words" }
 { $subsection "shuffle-words" }
 { $subsection "combinators" }
 { $subsection "errors" }
 { $subsection "continuations" }
-"Named values:"
+{ $heading "Named values" }
 { $subsection "locals" }
 { $subsection "namespaces" }
 { $subsection "namespaces-global" }
 { $subsection "values" }
-"Abstractions:"
+{ $heading "Abstractions" }
 { $subsection "objects" }
 { $subsection "destructors" }
 { $subsection "macros" }
 { $subsection "fry" }
-"Program organization:"
+{ $heading "Program organization" }
 { $subsection "vocabs.loader" }
 "Vocabularies tagged " { $link T{ vocab-tag { name "extensions" } } } " implement various additional language abstractions." ;
 
-ARTICLE: "handbook-environment-reference" "Environment reference"
-"Parse time and compile time:"
+ARTICLE: "handbook-system-reference" "The implementation"
+{ $heading "Parse time and compile time" }
 { $subsection "parser" }
 { $subsection "definitions" }
 { $subsection "vocabularies" }
 { $subsection "source-files" }
 { $subsection "compiler" }
-"Tools:"
-{ $subsection "prettyprint" }
-{ $subsection "tools" }
-{ $subsection "help" }
-{ $subsection "inference" }
+{ $heading "Virtual machine" }
 { $subsection "images" }
-"VM:"
 { $subsection "cli" }
 { $subsection "rc-files" }
 { $subsection "init" }
 { $subsection "system" }
 { $subsection "layouts" } ;
 
-ARTICLE: "handbook-library-reference" "Library reference"
-"This index only includes articles from loaded vocabularies. To explore more vocabularies, see " { $link "vocab-index" } "."
-{ $index [ "handbook" orphan-articles remove ] } ;
+ARTICLE: "handbook-tools-reference" "Developer tools"
+"The below tools are text-based. " { $link "ui-tools" } " are documented separately."
+{ $heading "Workflow" }
+{ $subsection "listener" }
+{ $subsection "editor" }
+{ $subsection "tools.vocabs" }
+{ $subsection "tools.test" }
+{ $subsection "help" }
+{ $heading "Debugging" }
+{ $subsection "prettyprint" }
+{ $subsection "inspector" }
+{ $subsection "tools.annotations" }
+{ $subsection "inference" }
+{ $heading "Browsing" }
+{ $subsection "see" }
+{ $subsection "tools.crossref" }
+{ $heading "Performance" }
+{ $subsection "timing" }
+{ $subsection "profiling" }
+{ $subsection "tools.memory" }
+{ $subsection "tools.threads" }
+{ $subsection "tools.disassembler" }
+{ $heading "Deployment" }
+{ $subsection "tools.deploy" } ;
+
+ARTICLE: "handbook-library-reference" "Libraries"
+"This index lists articles from loaded vocabularies which are not subsections of any other article. To explore more vocabularies, see " { $link "vocab-index" } "."
+{ $index [ orphan-articles { "help.home" "handbook" } diff ] } ;
 
 ARTICLE: "handbook" "Factor handbook"
 "Learn the language:"
@@ -308,11 +305,11 @@ ARTICLE: "handbook" "Factor handbook"
 { $subsection "first-program" }
 "Reference material:"
 { $subsection "handbook-language-reference" }
-{ $subsection "handbook-environment-reference" }
 { $subsection "io" }
 { $subsection "ui" }
+{ $subsection "handbook-system-reference" }
+{ $subsection "handbook-tools-reference" }
 { $subsection "ui-tools" }
-{ $subsection "unicode" }
 { $subsection "alien" }
 { $subsection "handbook-library-reference" }
 "Explore loaded libraries:"
index e6db2d3b9c3c7e400cb7c1b651ae8bf5006f0701..b40d1626702c24a9d4db273c89e057f4ca7f2557 100644 (file)
@@ -8,6 +8,7 @@ ARTICLE: "help.home" "Factor documentation"
   { $link "handbook" }
   { $link "vocab-index" }
   { $link "ui-tools" }
+  { $link "ui-listener" }
 }
 { $heading "Recently visited" }
 { $table
diff --git a/basis/help/lint/checks/authors.txt b/basis/help/lint/checks/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/help/lint/checks/checks.factor b/basis/help/lint/checks/checks.factor
new file mode 100644 (file)
index 0000000..4a15f86
--- /dev/null
@@ -0,0 +1,176 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs classes combinators
+combinators.short-circuit definitions effects eval fry grouping
+help help.markup help.topics io.streams.string kernel macros
+namespaces sequences sequences.deep sets sorting splitting
+strings unicode.categories values vocabs vocabs.loader words
+words.symbol summary debugger io ;
+IN: help.lint.checks
+
+ERROR: simple-lint-error message ;
+
+M: simple-lint-error summary message>> ;
+
+M: simple-lint-error error. summary print ;
+
+SYMBOL: vocabs-quot
+SYMBOL: all-vocabs
+SYMBOL: vocab-articles
+
+: check-example ( element -- )
+    '[
+        _ rest [
+            but-last "\n" join
+            [ (eval>string) ] call( code -- output )
+            "\n" ?tail drop
+        ] keep
+        peek assert=
+    ] vocabs-quot get call( quot -- ) ;
+
+: check-examples ( element -- )
+    \ $example swap elements [ check-example ] each ;
+
+: extract-values ( element -- seq )
+    \ $values swap elements dup empty? [
+        first rest [ first ] map prune natural-sort
+    ] unless ;
+
+: effect-values ( word -- seq )
+    stack-effect
+    [ in>> ] [ out>> ] bi append
+    [ dup pair? [ first ] when effect>string ] map
+    prune natural-sort ;
+
+: contains-funky-elements? ( element -- ? )
+    {
+        $shuffle
+        $values-x/y
+        $predicate
+        $class-description
+        $error-description
+    } swap '[ _ elements empty? not ] any? ;
+
+: don't-check-word? ( word -- ? )
+    {
+        [ macro? ]
+        [ symbol? ]
+        [ value-word? ]
+        [ parsing-word? ]
+        [ "declared-effect" word-prop not ]
+    } 1|| ;
+
+: check-values ( word element -- )
+    {
+        [
+            [ don't-check-word? ]
+            [ contains-funky-elements? ]
+            bi* or
+        ] [
+            [ effect-values ]
+            [ extract-values ]
+            bi* sequence=
+        ]
+    } 2|| [ "$values don't match stack effect" simple-lint-error ] unless ;
+
+: check-nulls ( element -- )
+    \ $values swap elements
+    null swap deep-member?
+    [ "$values should not contain null" simple-lint-error ] when ;
+
+: check-see-also ( element -- )
+    \ $see-also swap elements [
+        rest dup prune [ length ] bi@ assert=
+    ] each ;
+
+: vocab-exists? ( name -- ? )
+    [ vocab ] [ all-vocabs get member? ] bi or ;
+
+: check-modules ( element -- )
+    \ $vocab-link swap elements [
+        second
+        vocab-exists? [
+            "$vocab-link to non-existent vocabulary"
+            simple-lint-error
+        ] unless
+    ] each ;
+
+: check-rendering ( element -- )
+    [ print-content ] with-string-writer drop ;
+
+: check-strings ( str -- )
+    [
+        "\n\t" intersects? [
+            "Paragraph text should not contain \\n or \\t"
+            simple-lint-error
+        ] when
+    ] [
+        "  " swap subseq? [
+            "Paragraph text should not contain double spaces"
+            simple-lint-error
+        ] when
+    ] bi ;
+
+: check-whitespace ( str1 str2 -- )
+    [ " " tail? ] [ " " head? ] bi* or
+    [ "Missing whitespace between strings" simple-lint-error ] unless ;
+
+: check-bogus-nl ( element -- )
+    { { $nl } { { $nl } } } [ head? ] with any? [
+        "Simple element should not begin with a paragraph break"
+        simple-lint-error
+    ] when ;
+
+: check-class-description ( word element -- )
+    [ class? not ]
+    [ { $class-description } swap elements empty? not ] bi* and
+    [ "A word that is not a class has a $class-description" simple-lint-error ] when ;
+
+: check-article-title ( article -- )
+    article-title first LETTER?
+    [ "Article title must begin with a capital letter" simple-lint-error ] unless ;
+
+: check-elements ( element -- )
+    {
+        [ check-bogus-nl ]
+        [ [ string? ] filter [ check-strings ] each ]
+        [ [ simple-element? ] filter [ check-elements ] each ]
+        [ 2 <clumps> [ [ string? ] all? ] filter [ first2 check-whitespace ] each ]
+    } cleave ;
+
+: check-descriptions ( element -- )
+    { $description $class-description $var-description }
+    swap '[
+        _ elements [
+            rest { { } { "" } } member?
+            [ "Empty description" throw ] when
+        ] each
+    ] each ;
+
+: check-markup ( element -- )
+    {
+        [ check-elements ]
+        [ check-rendering ]
+        [ check-examples ]
+        [ check-modules ]
+        [ check-descriptions ]
+    } cleave ;
+
+: files>vocabs ( -- assoc )
+    vocabs
+    [ [ [ vocab-docs-path ] keep ] H{ } map>assoc ]
+    [ [ [ vocab-source-path ] keep ] H{ } map>assoc ]
+    bi assoc-union ;
+
+: group-articles ( -- assoc )
+    articles get keys
+    files>vocabs
+    H{ } clone [
+        '[
+            dup >link where dup
+            [ first _ at _ push-at ] [ 2drop ] if
+        ] each
+    ] keep ;
+
+: all-word-help ( words -- seq )
+    [ word-help ] filter ;
index 0c0fcf92d2790b407a3f17b1910a91769e16a448..ed74748356cfb9182838d7ea8729c41066102e85 100644 (file)
@@ -14,6 +14,10 @@ $nl
 "To run help lint, use one of the following two words:"
 { $subsection help-lint }
 { $subsection help-lint-all }
+"Once a help lint run completes, failures can be listed:"
+{ $subsection :lint-failures }
+"Help lint failures are also shown in the " { $link "ui.tools.error-list" } "."
+$nl
 "Help lint performs the following checks:"
 { $list
     "ensures examples run and produce stated output"
index 7ec8c59ba6be75f0442004aed6d285527f3db086..42f29bc8b7a7a9d9113f8006cbaaa07de5fae337 100755 (executable)
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: fry accessors sequences parser kernel help help.markup
-help.topics words strings classes tools.vocabs namespaces make
-io io.streams.string prettyprint definitions arrays vectors
-combinators combinators.short-circuit splitting debugger
-hashtables sorting effects vocabs vocabs.loader assocs editors
-continuations classes.predicate macros math sets eval
-vocabs.parser words.symbol values grouping unicode.categories
-sequences.deep ;
+USING: assocs continuations fry help help.lint.checks
+help.topics io kernel namespaces parser sequences
+source-files.errors tools.vocabs vocabs words classes
+locals tools.errors ;
+FROM: help.lint.checks => all-vocabs ;
 IN: help.lint
 
-SYMBOL: vocabs-quot
-
-: check-example ( element -- )
-    '[
-        _ rest [
-            but-last "\n" join
-            [ (eval>string) ] call( code -- output )
-            "\n" ?tail drop
-        ] keep
-        peek assert=
-    ] vocabs-quot get call( quot -- ) ;
-
-: check-examples ( element -- )
-    \ $example swap elements [ check-example ] each ;
-
-: extract-values ( element -- seq )
-    \ $values swap elements dup empty? [
-        first rest [ first ] map prune natural-sort
-    ] unless ;
-
-: effect-values ( word -- seq )
-    stack-effect
-    [ in>> ] [ out>> ] bi append
-    [ dup pair? [ first ] when effect>string ] map
-    prune natural-sort ;
-
-: contains-funky-elements? ( element -- ? )
-    {
-        $shuffle
-        $values-x/y
-        $predicate
-        $class-description
-        $error-description
-    } swap '[ _ elements empty? not ] any? ;
-
-: don't-check-word? ( word -- ? )
-    {
-        [ macro? ]
-        [ symbol? ]
-        [ value-word? ]
-        [ parsing-word? ]
-        [ "declared-effect" word-prop not ]
-    } 1|| ;
-
-: check-values ( word element -- )
-    {
-        [
-            [ don't-check-word? ]
-            [ contains-funky-elements? ]
-            bi* or
-        ] [
-            [ effect-values ]
-            [ extract-values ]
-            bi* sequence=
-        ]
-    } 2|| [ "$values don't match stack effect" throw ] unless ;
-
-: check-nulls ( element -- )
-    \ $values swap elements
-    null swap deep-member?
-    [ "$values should not contain null" throw ] when ;
-
-: check-see-also ( element -- )
-    \ $see-also swap elements [
-        rest dup prune [ length ] bi@ assert=
-    ] each ;
-
-: vocab-exists? ( name -- ? )
-    [ vocab ] [ "all-vocabs" get member? ] bi or ;
-
-: check-modules ( element -- )
-    \ $vocab-link swap elements [
-        second
-        vocab-exists? [ "$vocab-link to non-existent vocabulary" throw ] unless
-    ] each ;
-
-: check-rendering ( element -- )
-    [ print-content ] with-string-writer drop ;
-
-: check-strings ( str -- )
-    [
-        "\n\t" intersects?
-        [ "Paragraph text should not contain \\n or \\t" throw ] when
-    ] [
-        "  " swap subseq?
-        [ "Paragraph text should not contain double spaces" throw ] when
-    ] bi ;
-
-: check-whitespace ( str1 str2 -- )
-    [ " " tail? ] [ " " head? ] bi* or
-    [ "Missing whitespace between strings" throw ] unless ;
-
-: check-bogus-nl ( element -- )
-    { { $nl } { { $nl } } } [ head? ] with any?
-    [ "Simple element should not begin with a paragraph break" throw ] when ;
-
-: check-elements ( element -- )
-    {
-        [ check-bogus-nl ]
-        [ [ string? ] filter [ check-strings ] each ]
-        [ [ simple-element? ] filter [ check-elements ] each ]
-        [ 2 <clumps> [ [ string? ] all? ] filter [ first2 check-whitespace ] each ]
-    } cleave ;
-
-: check-descriptions ( element -- )
-    { $description $class-description $var-description }
-    swap '[
-        _ elements [
-            rest { { } { "" } } member?
-            [ "Empty description" throw ] when
-        ] each
-    ] each ;
-
-: check-markup ( element -- )
-    {
-        [ check-elements ]
-        [ check-rendering ]
-        [ check-examples ]
-        [ check-modules ]
-        [ check-descriptions ]
-    } cleave ;
-
-: check-class-description ( word element -- )
-    [ class? not ]
-    [ { $class-description } swap elements empty? not ] bi* and
-    [ "A word that is not a class has a $class-description" throw ] when ;
-
-: all-word-help ( words -- seq )
-    [ word-help ] filter ;
-
-TUPLE: help-error error topic ;
-
-C: <help-error> help-error
-
-M: help-error error.
-    [ "In " write topic>> pprint nl ]
-    [ error>> error. ]
-    bi ;
-
-: check-something ( obj quot -- )
-    flush '[ _ call( -- ) ] swap '[ _ <help-error> , ] recover ; inline
+SYMBOL: lint-failures
+
+lint-failures [ H{ } clone ] initialize
+
+TUPLE: help-lint-error < source-file-error ;
+
+SYMBOL: +help-lint-failure+
+
+T{ error-type
+   { type +help-lint-failure+ }
+   { word ":lint-failures" }
+   { plural "help lint failures" }
+   { icon "vocab:ui/tools/error-list/icons/help-lint-error.tiff" }
+   { quot [ lint-failures get values ] }
+   { forget-quot [ lint-failures get delete-at ] }
+} define-error-type
+
+M: help-lint-error error-type drop +help-lint-failure+ ;
+
+<PRIVATE
+
+: <help-lint-error> ( error topic -- help-lint-error )
+    \ help-lint-error <definition-error> ;
+
+PRIVATE>
+
+: help-lint-error ( error topic -- )
+    lint-failures get pick
+    [ [ [ <help-lint-error> ] keep ] dip set-at ] [ delete-at drop ] if
+    notify-error-observers ;
+
+<PRIVATE
+
+:: check-something ( topic quot -- )
+    [ quot call( -- ) f ] [ ] recover
+    topic help-lint-error ; inline
 
 : check-word ( word -- )
     [ with-file-vocabs ] vocabs-quot set
     dup word-help [
-        dup '[
+        [ >link ] keep '[
             _ dup word-help
             [ check-values ]
             [ check-class-description ]
@@ -165,69 +57,38 @@ M: help-error error.
 
 : check-words ( words -- ) [ check-word ] each ;
 
-: check-article-title ( article -- )
-    article-title first LETTER?
-    [ "Article title must begin with a capital letter" throw ] unless ;
-
 : check-article ( article -- )
     [ with-interactive-vocabs ] vocabs-quot set
-    dup '[
+    >link dup '[
         _
         [ check-article-title ]
         [ article-content check-markup ] bi
     ] check-something ;
 
-: files>vocabs ( -- assoc )
-    vocabs
-    [ [ [ vocab-docs-path ] keep ] H{ } map>assoc ]
-    [ [ [ vocab-source-path ] keep ] H{ } map>assoc ]
-    bi assoc-union ;
-
-: group-articles ( -- assoc )
-    articles get keys
-    files>vocabs
-    H{ } clone [
-        '[
-            dup >link where dup
-            [ first _ at _ push-at ] [ 2drop ] if
-        ] each
-    ] keep ;
-
 : check-about ( vocab -- )
     dup '[ _ vocab-help [ article drop ] when* ] check-something ;
 
-: check-vocab ( vocab -- seq )
+: check-vocab ( vocab -- )
     "Checking " write dup write "..." print
-    [
-        [ check-about ]
-        [ words [ check-word ] each ]
-        [ "vocab-articles" get at [ check-article ] each ]
-        tri
-    ] { } make ;
+    [ vocab check-about ]
+    [ words [ check-word ] each ]
+    [ vocab-articles get at [ check-article ] each ]
+    tri ;
 
-: run-help-lint ( prefix -- alist )
+PRIVATE>
+
+: help-lint ( prefix -- )
     [
-        all-vocabs-seq [ vocab-name ] map "all-vocabs" set
-        group-articles "vocab-articles" set
+        all-vocabs-seq [ vocab-name ] map all-vocabs set
+        group-articles vocab-articles set
         child-vocabs
-        [ dup check-vocab ] { } map>assoc
-        [ nip empty? not ] assoc-filter
+        [ check-vocab ] each
     ] with-scope ;
 
-: typos. ( assoc -- )
-    [
-        "==== ALL CHECKS PASSED" print
-    ] [
-        [
-            swap vocab-heading.
-            [ print-error nl ] each
-        ] assoc-each
-    ] if-empty ;
-
-: help-lint ( prefix -- ) run-help-lint typos. ;
-
 : help-lint-all ( -- ) "" help-lint ;
 
+: :lint-failures ( -- ) lint-failures get errors. ;
+
 : unlinked-words ( words -- seq )
     all-word-help [ article-parent not ] filter ;
 
@@ -235,6 +96,6 @@ M: help-error error.
     all-words
     [ word-help not ] filter
     [ article-parent ] filter
-    [ "predicating" word-prop not ] filter ;
+    [ predicate? not ] filter ;
 
 MAIN: help-lint
index e7438edd4d82d32643a615c037b3e2f7c4befd7b..7618e9cdeb6ae005117525ffe2a438475e4e4fb5 100644 (file)
@@ -4,12 +4,12 @@ IN: help.syntax.tests
 
 [
     [ "foobar" ] [
-        "IN: help.syntax.tests USE: help.syntax ABOUT: \"foobar\"" eval
+        "IN: help.syntax.tests USE: help.syntax ABOUT: \"foobar\"" eval( -- )
         "help.syntax.tests" vocab vocab-help
     ] unit-test
     
     [ { "foobar" } ] [
-        "IN: help.syntax.tests USE: help.syntax ABOUT: { \"foobar\" }" eval
+        "IN: help.syntax.tests USE: help.syntax ABOUT: { \"foobar\" }" eval( -- )
         "help.syntax.tests" vocab vocab-help
     ] unit-test
     
index f53bdee9c7ceb6a3090e746502f9781a604b185c..ac9223b5d213cc13f999695ba424d10431e62949 100644 (file)
@@ -29,7 +29,7 @@ SYMBOL: foo
     } "\n" join
     [
         "testfile" source-file file set
-        eval
+        eval( -- )
     ] with-scope
 ] unit-test
 
index 26812947c0c3880f2511038ab7443ae0274b2099..2ed18b7cd579623720b246c25bc41ea51b4097d8 100644 (file)
@@ -76,9 +76,11 @@ $nl
 { $code "." }
 "What we just did is called " { $emphasis "interactive testing" } ". A more advanced technique which comes into play with larger programs is " { $link "tools.test" } "."
 $nl
-"Open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool."
+"Create a test harness file using the scaffold tool:"
+{ $code "\"palindrome\" scaffold-tests" }
+"Now, open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool."
 $nl
-"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
+"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link POSTPONE: unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
 $nl
 "Add the following three lines to " { $snippet "palindrome-tests.factor" } ":"
 { $code
index 307fdd50314749880eed2d21aca99c3ac76433ea..d1997c73f99a68bac7df3be38f08ecfe3ccb389e 100644 (file)
@@ -184,6 +184,12 @@ ERROR: download-failed response ;
 : http-put ( post-data url -- response data )
     <put-request> http-request ;
 
+: <delete-request> ( url -- request )
+    "DELETE" <client-request> ;
+
+: http-delete ( url -- response data )
+    <delete-request> http-request ;
+
 USING: vocabs vocabs.loader ;
 
 "debugger" vocab [ "http.client.debugger" require ] when
diff --git a/basis/io/crlf/crlf-tests.factor b/basis/io/crlf/crlf-tests.factor
new file mode 100644 (file)
index 0000000..2412945
--- /dev/null
@@ -0,0 +1,8 @@
+IN: io.crlf.tests
+USING: io.crlf tools.test io.streams.string io ;
+
+[ "Hello, world." ] [ "Hello, world." [ read-crlf ] with-string-reader ] unit-test
+[ "Hello, world." ] [ "Hello, world.\r\n" [ read-crlf ] with-string-reader ] unit-test
+[ "Hello, world.\r" [ read-crlf ] with-string-reader ] must-fail
+[ f ] [ "" [ read-crlf ] with-string-reader ] unit-test
+[ "" ] [ "\r\n" [ read-crlf ] with-string-reader ] unit-test
index 53dddce199570b96ff257b43d01502c1364edeb3..29f10300de44283b42dde7d7ad0229909a29b378 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Daniel Ehrenberg, Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io kernel ;
+USING: io kernel sequences ;
 IN: io.crlf
 
 : crlf ( -- )
@@ -8,4 +8,4 @@ IN: io.crlf
 
 : read-crlf ( -- seq )
     "\r" read-until
-    [ CHAR: \r assert= read1 CHAR: \n assert= ] when* ;
+    [ CHAR: \r assert= read1 CHAR: \n assert= ] [ f like ] if* ;
index 358521473540ce253234015f96c15a63ed1f62a9..f20e65dc275a23b94e1ebc8f06dd6a0058c755d9 100644 (file)
@@ -140,7 +140,46 @@ HELP: <process-stream>
   { "desc" "a launch descriptor" }
   { "encoding" "an encoding descriptor" }
   { "stream" "a bidirectional stream" } }
-{ $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream of the given encoding." } ;
+{ $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream with the given encoding." } ;
+
+HELP: <process-reader>
+{ $values
+  { "desc" "a launch descriptor" }
+  { "encoding" "an encoding descriptor" }
+  { "stream" "an input stream" } }
+{ $description "Launches a process and redirects its output via a pipe which may be read as a stream with the given encoding." } ;
+
+HELP: <process-writer>
+{ $values
+  { "desc" "a launch descriptor" }
+  { "encoding" "an encoding descriptor" }
+  { "stream" "an output stream" }
+}
+{ $description "Launches a process and redirects its input via a pipe which may be written to as a stream with the given encoding." } ;
+
+HELP: with-process-stream
+{ $values
+  { "desc" "a launch descriptor" }
+  { "encoding" "an encoding descriptor" }
+  { "quot" quotation }
+}
+{ $description "Launches a process and redirects its input and output via a pair of pipes. The quotation is called with " { $link input-stream } " and " { $link output-stream } " rebound to these pipes." } ;
+
+HELP: with-process-reader
+{ $values
+  { "desc" "a launch descriptor" }
+  { "encoding" "an encoding descriptor" }
+  { "quot" quotation }
+}
+{ $description "Launches a process and redirects its output via a pipe. The quotation is called with " { $link input-stream } " and " { $link output-stream } " rebound to this pipe." } ;
+
+HELP: with-process-writer
+{ $values
+  { "desc" "a launch descriptor" }
+  { "encoding" "an encoding descriptor" }
+  { "quot" quotation }
+}
+{ $description "Launches a process and redirects its input via a pipe. The quotation is called with " { $link input-stream } " and " { $link output-stream } " rebound to this pipe." } ;
 
 HELP: wait-for-process
 { $values { "process" process } { "status" object } }
@@ -175,7 +214,11 @@ ARTICLE: "io.launcher.launch" "Launching processes"
 "Redirecting standard input and output to a pipe:"
 { $subsection <process-reader> }
 { $subsection <process-writer> }
-{ $subsection <process-stream> } ;
+{ $subsection <process-stream> }
+"Combinators built on top of the above:"
+{ $subsection with-process-reader }
+{ $subsection with-process-writer }
+{ $subsection with-process-stream } ;
 
 ARTICLE: "io.launcher.examples" "Launcher examples"
 "Starting a command and waiting for it to finish:"
index 07502e87a42f5fe2481bcb7d3dc8dbedbc8a5e6d..90504ccac2a1a4c460dfcf7c014057f0071b0c40 100644 (file)
@@ -10,13 +10,13 @@ USING: io.launcher.unix.parser tools.test ;
 [ V{ "abc" "def" } ] [ "abc def" tokenize-command ] unit-test
 [ V{ "abc def" } ] [ "abc\\ def" tokenize-command ] unit-test
 [ V{ "abc\\" "def" } ] [ "abc\\\\ def" tokenize-command ] unit-test
-[ V{ "abc\\ def" } ] [ "'abc\\\\ def'" tokenize-command ] unit-test
-[ V{ "abc\\ def" } ] [ "  'abc\\\\ def'" tokenize-command ] unit-test
-[ V{ "abc\\ def" "hey" } ] [ "'abc\\\\ def' hey" tokenize-command ] unit-test
-[ V{ "abc def" "hey" } ] [ "'abc def' \"hey\"" tokenize-command ] unit-test
-[ "'abc def' \"hey" tokenize-command ] must-fail
-[ "'abc def" tokenize-command ] must-fail
-[ V{ "abc def" "h\"ey" } ] [ "'abc def' \"h\\\"ey\"  " tokenize-command ] unit-test
+[ V{ "abc\\ def" } ] [ "\"abc\\\\ def\"" tokenize-command ] unit-test
+[ V{ "abc\\ def" } ] [ "  \"abc\\\\ def\"" tokenize-command ] unit-test
+[ V{ "abc\\ def" "hey" } ] [ "\"abc\\\\ def\" hey" tokenize-command ] unit-test
+[ V{ "abc def" "hey" } ] [ "\"abc def\" \"hey\"" tokenize-command ] unit-test
+[ "\"abc def\" \"hey" tokenize-command ] must-fail
+[ "\"abc def" tokenize-command ] must-fail
+[ V{ "abc def" "h\"ey" } ] [ "\"abc def\" \"h\\\"ey\"  " tokenize-command ] unit-test
 
 [
     V{
index 97e6dee95fc2a2cd1edddf8dbad169520706a0d3..bcc5f965e9e2340e1f8e5432c3614685d48b3a4b 100644 (file)
@@ -1,33 +1,17 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: peg peg.parsers kernel sequences strings words ;
+USING: peg peg.ebnf arrays sequences strings kernel ;
 IN: io.launcher.unix.parser
 
 ! Our command line parser. Supported syntax:
 ! foo bar baz -- simple tokens
 ! foo\ bar -- escaping the space
-! 'foo bar' -- quotation
 ! "foo bar" -- quotation
-: 'escaped-char' ( -- parser )
-    "\\" token any-char 2seq [ second ] action ;
-
-: 'quoted-char' ( delimiter -- parser' )
-    'escaped-char'
-    swap [ member? not ] curry satisfy
-    2choice ; inline
-
-: 'quoted' ( delimiter -- parser )
-    dup 'quoted-char' repeat0 swap dup surrounded-by ;
-
-: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ;
-
-: 'argument' ( -- parser )
-    "\"" 'quoted'
-    "'" 'quoted'
-    'unquoted' 3choice
-    [ >string ] action ;
-
-PEG: tokenize-command ( command -- ast/f )
-    'argument' " " token repeat1 list-of
-    " " token repeat0 tuck pack
-    just ;
+EBNF: tokenize-command
+space = " "
+escaped-char = "\" .:ch => [[ ch ]]
+quoted = '"' (escaped-char | [^"])*:a '"' => [[ a ]]
+unquoted = (escaped-char | [^ "])+
+argument = (quoted | unquoted) => [[ >string ]]
+command = space* (argument:a space* => [[ a ]])+:c !(.) => [[ c ]]
+;EBNF
index 04202365fd7df26c2800f91b9c51d7bb8bdeabf3..53b3d3ce7eb019ce51ebcbb0012a8e5815d91fce 100755 (executable)
@@ -98,7 +98,7 @@ IN: io.launcher.windows.nt.tests
         <process>
             console-vm "-script" "env.factor" 3array >>command
         ascii <process-reader> contents
-    ] with-directory eval
+    ] with-directory eval( -- alist )
 
     os-envs =
 ] unit-test
@@ -110,7 +110,7 @@ IN: io.launcher.windows.nt.tests
             +replace-environment+ >>environment-mode
             os-envs >>environment
         ascii <process-reader> contents
-    ] with-directory eval
+    ] with-directory eval( -- alist )
     
     os-envs =
 ] unit-test
@@ -121,7 +121,7 @@ IN: io.launcher.windows.nt.tests
             console-vm "-script" "env.factor" 3array >>command
             { { "A" "B" } } >>environment
         ascii <process-reader> contents
-    ] with-directory eval
+    ] with-directory eval( -- alist )
 
     "A" swap at
 ] unit-test
@@ -133,7 +133,7 @@ IN: io.launcher.windows.nt.tests
             { { "USERPROFILE" "XXX" } } >>environment
             +prepend-environment+ >>environment-mode
         ascii <process-reader> contents
-    ] with-directory eval
+    ] with-directory eval( -- alist )
 
     "USERPROFILE" swap at "XXX" =
 ] unit-test
index 8dce5275531aa0f218122220a4d70c2dfb1e55e9..a0beb1f421b3ac20602737ef597a49b859cd7c52 100644 (file)
@@ -192,7 +192,7 @@ M: object (client) ( remote -- client-in client-out local )
     ] with-destructors ;
 
 : <client> ( remote encoding -- stream local )
-    [ (client) -rot ] dip <encoder-duplex> swap ;
+    [ (client) ] dip swap [ <encoder-duplex> ] dip ;
 
 SYMBOL: local-address
 
index ed45d5ccb90adc1c950e2fce9d8f465ebc3549eb..6148394c5767a66dc294f01f63282a5a4130d119 100644 (file)
@@ -274,7 +274,7 @@ HELP: <input>
 { $description "Creates a new " { $link input } "." } ;
 
 HELP: standard-table-style
-{ $values { "style" hashtable } }
+{ $values { "value" hashtable } }
 { $description "Outputs a table style where cells are separated by 5-pixel gaps and framed by a light gray border. This style can be passed to " { $link tabular-output } "." } ;
 
 ARTICLE: "io.streams.plain" "Plain writer streams"
index 89fe90b5685b938437d3b7995021632618415356..66b5f0458fbcfb59584d6c61012fb095c571a1ef 100644 (file)
@@ -135,11 +135,11 @@ SYMBOL: wrap-margin
 SYMBOL: table-gap
 SYMBOL: table-border
 
-: standard-table-style ( -- style )
+CONSTANT: standard-table-style
     H{
         { table-gap { 5 5 } }
         { table-border T{ rgba f 0.8 0.8 0.8 1.0 } }
-    } ;
+    }
 
 ! Input history
 TUPLE: input string ;
index 014e096b1db41107fb68258536bb127521b6ecc1..0f13b6dd8624064c264d500e0f8b2edd4df0e00d 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax kernel io system prettyprint ;
+USING: help.markup help.syntax kernel io system prettyprint continuations ;
 IN: listener
 
 ARTICLE: "listener-watch" "Watching variables in the listener"
@@ -41,32 +41,18 @@ $nl
 { $example "{ 1 2 3 } [\n    .\n] each" "1\n2\n3" }
 "The listener knows when to expect more input by looking at the height of the stack. Parsing words such as " { $link POSTPONE: { } " leave elements on the parser stack, and corresponding words such as " { $link POSTPONE: } } " pop them."
 { $subsection "listener-watch" }
-"You can start a nested listener or exit a listener using the following words:"
+"To start a nested listener:"
 { $subsection listener }
-{ $subsection bye }
-"Finally, the multi-line expression reading word can be used independently of the rest of the listener:"
+"To exit the listener, invoke the " { $link return } " word."
+$nl
+"Multi-line quotations can be read independently of the rest of the listener:"
 { $subsection read-quot } ;
 
 ABOUT: "listener"
 
-<PRIVATE
-
-HELP: quit-flag
-{ $var-description "Variable set to true by " { $link bye } " word; it forces the next iteration of the " { $link listener } " loop to end." } ;
-
-PRIVATE>
-
 HELP: read-quot
 { $values { "quot/f" "a parsed quotation, or " { $link f } " indicating end of file" } }
 { $description "Reads a Factor expression which possibly spans more than one line from " { $link input-stream } ". Additional lines of input are read while the parser stack height is greater than one. Since structural parsing words push partial quotations on the stack, this will keep on reading input until all delimited parsing words are terminated." } ;
 
-HELP: listen
-{ $description "Prompts for an expression on " { $link input-stream } " and evaluates it. On end of file, " { $link quit-flag } " is set to terminate the listener loop." }
-{ $errors "If the expression input by the user throws an error, the error is printed to " { $link output-stream } " and the word returns normally." } ;
-
 HELP: listener
 { $description "Prompts for expressions on " { $link input-stream } " and evaluates them until end of file is reached." } ;
-
-HELP: bye
-{ $description "Exits the current listener." }
-{ $notes "This word is for interactive use only. To exit the Factor runtime, use " { $link exit } "." } ;
index 0616794939ee6a405eaa3fd1c5db3638dff6dbc8..7ed082234a0542847dc07a0a6a1b34c2071fd3c3 100644 (file)
@@ -25,7 +25,7 @@ SYNTAX: hello "Hi" print ;
                 "\\ + 1 2 3 4" parse-interactive
                 "cont" get continue-with
             ] ignore-errors
-            "USE: debugger :1" eval
+            "USE: debugger :1" eval( -- quot )
         ] callcc1
     ] unit-test
 ] with-file-vocabs
@@ -50,7 +50,7 @@ SYNTAX: hello "Hi" print ;
 
 [
     [ ] [
-        "IN: listener.tests : hello ( -- )\n\"world\" ;" parse-interactive
+        "IN: listener.tests : hello ( -- string )\n\"world\" ;" parse-interactive
         drop
     ] unit-test
 ] with-file-vocabs
index 4f7ccf227e54e12567e6e4d7f47916fa123278d5..4234a0023b4d9c09a38ed307b33e8f89fc263c7a 100644 (file)
@@ -4,7 +4,7 @@ USING: arrays hashtables io kernel math math.parser memory
 namespaces parser lexer sequences strings io.styles
 vectors words generic system combinators continuations debugger
 definitions compiler.units accessors colors prettyprint fry
-sets vocabs.parser ;
+sets vocabs.parser source-files.errors locals ;
 IN: listener
 
 GENERIC: stream-read-quot ( stream -- quot/f )
@@ -32,17 +32,9 @@ M: object stream-read-quot
 
 : read-quot ( -- quot/f ) input-stream get stream-read-quot ;
 
-<PRIVATE
-
-SYMBOL: quit-flag
-
-PRIVATE>
-
-: bye ( -- ) quit-flag on ;
-
 SYMBOL: visible-vars
 
-: show-var ( var -- ) visible-vars  [ swap suffix ] change ;
+: show-var ( var -- ) visible-vars [ swap suffix ] change ;
 
 : show-vars ( seq -- ) visible-vars [ swap union ] change ;
 
@@ -68,6 +60,8 @@ SYMBOL: max-stack-items
 
 10 max-stack-items set-global
 
+SYMBOL: error-summary-hook
+
 <PRIVATE
 
 : title. ( string -- )
@@ -96,26 +90,44 @@ SYMBOL: max-stack-items
         ] dip
     ] when stack. ;
 
-: stacks. ( -- )
+: datastack. ( datastack -- )
     display-stacks? get [
-        datastack [ nl "--- Data stack:" title. trimmed-stack. ] unless-empty
-    ] when ;
+        [ nl "--- Data stack:" title. trimmed-stack. ] unless-empty
+    ] [ drop ] if ;
 
 : prompt. ( -- )
-    "( " in get auto-use? get [ " - auto" append ] when " )" 3append
+    in get auto-use? get [ " - auto" append ] when "( " " )" surround
     H{ { background T{ rgba f 1 0.7 0.7 1 } } } format bl flush ;
 
-: listen ( -- )
-    visible-vars. stacks. prompt.
-    [ read-quot [ [ call-error-hook ] recover ] [ bye ] if* ]
-    [ dup lexer-error? [ call-error-hook ] [ rethrow ] if ] recover ;
+[ error-summary ] error-summary-hook set-global
+
+: call-error-summary-hook ( -- )
+    error-summary-hook get call( -- ) ;
+
+:: (listener) ( datastack -- )
+    call-error-summary-hook
+    visible-vars.
+    datastack datastack.
+    prompt.
+
+    [
+        read-quot [
+            '[ datastack _ with-datastack ]
+            [ call-error-hook datastack ]
+            recover
+        ] [ return ] if*
+    ] [
+        dup lexer-error?
+        [ call-error-hook datastack ]
+        [ rethrow ]
+        if
+    ] recover
 
-: until-quit ( -- )
-    quit-flag get [ quit-flag off ] [ listen until-quit ] if ;
+    (listener) ;
 
 PRIVATE>
 
 : listener ( -- )
-    [ until-quit ] with-interactive-vocabs ;
+    [ [ { } (listener) ] with-interactive-vocabs ] with-return ;
 
 MAIN: listener
index 4b0abb7f2d6d249b634c6d5702b60903ebe5f235..fecb76f1c0ac33e60bd7d85d6bfdda8b4e4500d3 100644 (file)
@@ -106,7 +106,8 @@ PRIVATE>
 
 : deep-sequence>cons ( sequence -- cons )
     [ <reversed> ] keep nil
-    [ tuck same? [ deep-sequence>cons ] when swons ] with reduce ;
+    [ [ nip ] [ same? ] 2bi [ deep-sequence>cons ] when swons ]
+    with reduce ;
 
 <PRIVATE
 :: (lmap>vector) ( acc list quot: ( elt -- elt' ) -- acc )
index 5e61c1ddfd45f0b881417557dcf7e9326d9547b4..d472a8b22b79a28b365e881a95d8ce53ec6139b9 100644 (file)
@@ -261,7 +261,7 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
 
 CONSTANT: new-definition "USING: math ;\nIN: locals.tests\n: a-word-with-locals ( -- x ) 2 3 + ;\n"
 
-[ ] [ new-definition eval ] unit-test
+[ ] [ new-definition eval( -- ) ] unit-test
 
 [ t ] [
     [ \ a-word-with-locals see ] with-string-writer
@@ -461,7 +461,7 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
 
 [
     "USING: locals fry math ; 1 '[ [let | A [ 10 ] | A _ + ] ]"
-    eval call
+    eval( -- ) call
 ] [ error>> >r/r>-in-fry-error? ] must-fail-with
     
 :: (funny-macro-test) ( obj quot -- ? ) obj { quot } 1&& ; inline
@@ -473,10 +473,10 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
 [ f ] [ 2 funny-macro-test ] unit-test
 
 ! Some odd parser corner cases
-[ "USE: locals [let" eval ] [ error>> unexpected-eof? ] must-fail-with
-[ "USE: locals [let |" eval ] [ error>> unexpected-eof? ] must-fail-with
-[ "USE: locals [let | a" eval ] [ error>> unexpected-eof? ] must-fail-with
-[ "USE: locals [|" eval ] [ error>> unexpected-eof? ] must-fail-with
+[ "USE: locals [let" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
+[ "USE: locals [let |" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
+[ "USE: locals [let | a" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
+[ "USE: locals [|" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
 
 [ 25 ] [ 5 [| a | { [ a sq ] } cond ] call ] unit-test
 [ 25 ] [ 5 [| | { [| a | a sq ] } ] call first call ] unit-test
@@ -491,19 +491,19 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
 
 [ 3 ] [ 3 [| a | \ a ] call ] unit-test
 
-[ "USE: locals [| | { [let | a [ 0 ] | a ] } ]" eval ] must-fail
+[ "USE: locals [| | { [let | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | { [wlet | a [ 0 ] | a ] } ]" eval ] must-fail
+[ "USE: locals [| | { [wlet | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | { [let* | a [ 0 ] | a ] } ]" eval ] must-fail
+[ "USE: locals [| | { [let* | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | [let | a! [ 0 ] | { a! } ] ]" eval ] must-fail
+[ "USE: locals [| | [let | a! [ 0 ] | { a! } ] ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval ] must-fail
+[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | { :> a } ]" eval ] must-fail
+[ "USE: locals [| | { :> a } ]" eval( -- ) ] must-fail
 
-[ "USE: locals 3 :> a" eval ] must-fail
+[ "USE: locals 3 :> a" eval( -- ) ] must-fail
 
 [ 3 ] [ 3 [| | :> a a ] call ] unit-test
 
@@ -584,4 +584,4 @@ M: integer ed's-bug neg ;
 :: ed's-test-case ( a -- b )
    { [ a ed's-bug ] } && ;
 
-[ t ] [ \ ed's-test-case optimized>> ] unit-test
\ No newline at end of file
+[ t ] [ \ ed's-test-case optimized>> ] unit-test
index 91aa6880e6b6cfa845a81021906cb0808d84a1cd..bf483f72ea6bb4f5dbb341b9b5e6ce06936031e3 100644 (file)
@@ -13,11 +13,11 @@ unit-test
 [ t ] [ \ see-test macro? ] unit-test
 
 [ t ] [
-    "USING: math ;\nIN: macros.tests\n: see-test ( a b -- c ) - ;\n" dup eval
+    "USING: math ;\nIN: macros.tests\n: see-test ( a b -- c ) - ;\n" dup eval( -- )
     [ \ see-test see ] with-string-writer =
 ] unit-test
 
 [ f ] [ \ see-test macro? ] unit-test
 
-[ ] [ "USING: macros stack-checker kernel ; IN: hanging-macro MACRO: c ( quot -- ) infer drop [ ] ; : a ( -- ) [ a ] c ;" eval ] unit-test
+[ ] [ "USING: macros stack-checker kernel ; IN: hanging-macro MACRO: c ( quot -- ) infer drop [ ] ; : a ( -- ) [ a ] c ;" eval( -- ) ] unit-test
 
index b21d8c6d733983bf237c6fc521dcdb16da43769a..ec0cb8c9e6bf70d1567026e37a07162c848a7355 100644 (file)
@@ -62,8 +62,7 @@ MACRO: match-cond ( assoc -- )
     } cond ;
 
 : match-replace ( object pattern1 pattern2 -- result )
-    -rot
-    match [ "Pattern does not match" throw ] unless*
+    [ match [ "Pattern does not match" throw ] unless* ] dip swap
     [ replace-patterns ] bind ;
 
 : ?1-tail ( seq -- tail/f )
index 378ca2fb4b0cbb99774c8f35b93d03a68270e58a..8b4345690143b980bd17f0eb552d3b0bd0b2aa1c 100644 (file)
@@ -255,11 +255,11 @@ IN: math.intervals.tests
     0 pick interval-contains? over first \ recip eq? and [
         2drop t
     ] [
-        [ [ random-element ] dip first execute ] 2keep
-        second execute interval-contains?
+        [ [ random-element ] dip first execute( a -- b ) ] 2keep
+        second execute( a -- b ) interval-contains?
     ] if ;
 
-[ t ] [ 80000 [ drop unary-test ] all? ] unit-test
+[ t ] [ 80000 iota [ drop unary-test ] all? ] unit-test
 
 : random-binary-op ( -- pair )
     {
@@ -286,11 +286,11 @@ IN: math.intervals.tests
     0 pick interval-contains? over first { / /i mod rem } member? and [
         3drop t
     ] [
-        [ [ [ random-element ] bi@ ] dip first execute ] 3keep
-        second execute interval-contains?
+        [ [ [ random-element ] bi@ ] dip first execute( a b -- c ) ] 3keep
+        second execute( a b -- c ) interval-contains?
     ] if ;
 
-[ t ] [ 80000 [ drop binary-test ] all? ] unit-test
+[ t ] [ 80000 iota [ drop binary-test ] all? ] unit-test
 
 : random-comparison ( -- pair )
     {
@@ -305,7 +305,7 @@ IN: math.intervals.tests
     [ [ [ random-element ] bi@ ] dip first execute ] 3keep
     second execute dup incomparable eq? [ 2drop t ] [ = ] if ;
 
-[ t ] [ 40000 [ drop comparison-test ] all? ] unit-test
+[ t ] [ 40000 iota [ drop comparison-test ] all? ] unit-test
 
 [ t ] [ -10 10 [a,b] 0 100 [a,b] assume> 0 10 (a,b] = ] unit-test
 
@@ -322,7 +322,7 @@ IN: math.intervals.tests
 [ t ] [ -10 10 [a,b] interval-abs 0 10 [a,b] = ] unit-test
 
 ! Test that commutative interval ops really are
-: random-interval-or-empty ( -- )
+: random-interval-or-empty ( -- obj )
     10 random 0 = [ empty-interval ] [ random-interval ] if ;
 
 : random-commutative-op ( -- op )
@@ -333,7 +333,7 @@ IN: math.intervals.tests
     } random ;
 
 [ t ] [
-    80000 [
+    80000 iota [
         drop
         random-interval-or-empty random-interval-or-empty
         random-commutative-op
diff --git a/basis/math/matrices/authors.txt b/basis/math/matrices/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/math/matrices/elimination/authors.txt b/basis/math/matrices/elimination/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/math/matrices/elimination/elimination-tests.factor b/basis/math/matrices/elimination/elimination-tests.factor
new file mode 100644 (file)
index 0000000..7c83339
--- /dev/null
@@ -0,0 +1,168 @@
+IN: math.matrices.elimination.tests
+USING: kernel math.matrices math.matrices.elimination
+tools.test sequences ;
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 1 0 }
+        { 0 0 0 1 }
+    }
+] [
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 1 0 }
+        { 0 0 0 1 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 1 0 }
+        { 0 0 0 1 }
+    }
+] [
+    {
+        { 1 0 0 0 }
+        { 1 1 0 0 }
+        { 1 0 1 0 }
+        { 1 0 0 1 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 1 0 }
+        { 0 0 0 1 }
+    }
+] [
+    {
+        { 1 0 0 0 }
+        { 1 1 0 0 }
+        { 1 0 1 0 }
+        { 1 1 0 1 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 1 0 }
+        { 0 0 0 1 }
+    }
+] [
+    {
+        { 1 0 0 0 }
+        { 1 1 0 0 }
+        { 1 1 0 1 }
+        { 1 0 1 0 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 0 0 }
+        { 0 0 0 0 }
+    }
+] [
+    {
+        { 0 1 0 0 }
+        { 1 0 0 0 }
+        { 1 0 0 0 }
+        { 1 0 0 0 }
+    } [
+        [ 1 ] [ 0 0 pivot-row ] unit-test
+        1 0 do-row
+    ] with-matrix
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 0 0 }
+        { 0 0 0 0 }
+    }
+] [
+    {
+        { 0 1 0 0 }
+        { 1 0 0 0 }
+        { 1 0 0 0 }
+        { 1 0 0 0 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 0 0 0 1 }
+        { 0 0 0 0 }
+    }
+] [
+    {
+        { 1 0 0 0 }
+        { 0 1 0 0 }
+        { 1 0 0 1 }
+        { 1 0 0 1 }
+    } echelon
+] unit-test
+
+[
+    {
+        { 1 0 0 1 }
+        { 0 1 0 1 }
+        { 0 0 0 -1 }
+        { 0 0 0 0 }
+    }
+] [
+    {
+        { 0 1 0 1 }
+        { 1 0 0 1 }
+        { 1 0 0 0 }
+        { 1 1 0 1 }
+    } echelon
+] unit-test
+
+[
+    2
+] [
+    {
+        { 0 0 }
+        { 0 0 }
+    } nullspace length
+] unit-test
+
+[
+    1 3
+] [
+    {
+        { 0 1 0 1 }
+        { 1 0 0 1 }
+        { 1 0 0 0 }
+        { 1 1 0 1 }
+    } null/rank
+] unit-test
+
+[
+    1 3
+] [
+    {
+        { 0 0 0 0 0 1 0 1 }
+        { 0 0 0 0 1 0 0 1 }
+        { 0 0 0 0 1 0 0 0 }
+        { 0 0 0 0 1 1 0 1 }
+    } null/rank
+] unit-test
+
+[ { { 1 0 -1 } { 0 1 2 } } ]
+[ { { 1 2 3 } { 4 5 6 } } solution ] unit-test
diff --git a/basis/math/matrices/elimination/elimination.factor b/basis/math/matrices/elimination/elimination.factor
new file mode 100755 (executable)
index 0000000..0368dd5
--- /dev/null
@@ -0,0 +1,114 @@
+! Copyright (C) 2006, 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.vectors math.matrices namespaces
+sequences ;
+IN: math.matrices.elimination
+
+SYMBOL: matrix
+
+: with-matrix ( matrix quot -- )
+    [ swap matrix set call matrix get ] with-scope ; inline
+
+: nth-row ( row# -- seq ) matrix get nth ;
+
+: change-row ( row# quot: ( seq -- seq ) -- )
+    matrix get swap change-nth ; inline
+
+: exchange-rows ( row# row# -- ) matrix get exchange ;
+
+: rows ( -- n ) matrix get length ;
+
+: cols ( -- n ) 0 nth-row length ;
+
+: skip ( i seq quot -- n )
+    over [ find-from drop ] dip length or ; inline
+
+: first-col ( row# -- n )
+    #! First non-zero column
+    0 swap nth-row [ zero? not ] skip ;
+
+: clear-scale ( col# pivot-row i-row -- n )
+    [ over ] dip nth dup zero? [
+        3drop 0
+    ] [
+        [ nth dup zero? ] dip swap [
+            2drop 0
+        ] [
+            swap / neg
+        ] if
+    ] if ;
+
+: (clear-col) ( col# pivot-row i -- )
+    [ [ clear-scale ] 2keep [ n*v ] dip v+ ] change-row ;
+
+: rows-from ( row# -- slice )
+    rows dup <slice> ;
+
+: clear-col ( col# row# rows -- )
+    [ nth-row ] dip [ [ 2dup ] dip (clear-col) ] each 2drop ;
+
+: do-row ( exchange-with row# -- )
+    [ exchange-rows ] keep
+    [ first-col ] keep
+    dup 1+ rows-from clear-col ;
+
+: find-row ( row# quot -- i elt )
+    [ rows-from ] dip find ; inline
+
+: pivot-row ( col# row# -- n )
+    [ dupd nth-row nth zero? not ] find-row 2nip ;
+
+: (echelon) ( col# row# -- )
+    over cols < over rows < and [
+        2dup pivot-row [ over do-row 1+ ] when*
+        [ 1+ ] dip (echelon)
+    ] [
+        2drop
+    ] if ;
+
+: echelon ( matrix -- matrix' )
+    [ 0 0 (echelon) ] with-matrix ;
+
+: nonzero-rows ( matrix -- matrix' )
+    [ [ zero? ] all? not ] filter ;
+
+: null/rank ( matrix -- null rank )
+    echelon dup length swap nonzero-rows length [ - ] keep ;
+
+: leading ( seq -- n elt ) [ zero? not ] find ;
+
+: reduced ( matrix' -- matrix'' )
+    [
+        rows <reversed> [
+            dup nth-row leading drop
+            dup [ swap dup clear-col ] [ 2drop ] if
+        ] each
+    ] with-matrix ;
+
+: basis-vector ( row col# -- )
+    [ clone ] dip
+    [ swap nth neg recip ] 2keep
+    [ 0 spin set-nth ] 2keep
+    [ n*v ] dip
+    matrix get set-nth ;
+
+: nullspace ( matrix -- seq )
+    echelon reduced dup empty? [
+        dup first length identity-matrix [
+            [
+                dup leading drop
+                dup [ basis-vector ] [ 2drop ] if
+            ] each
+        ] with-matrix flip nonzero-rows
+    ] unless ;
+
+: 1-pivots ( matrix -- matrix )
+    [ dup leading nip [ recip v*n ] when* ] map ;
+
+: solution ( matrix -- matrix )
+    echelon nonzero-rows reduced 1-pivots ;
+
+: inverse ( matrix -- matrix ) ! Assumes an invertible matrix
+    dup length
+    [ identity-matrix [ append ] 2map solution ] keep
+    [ tail ] curry map ;
diff --git a/basis/math/matrices/elimination/summary.txt b/basis/math/matrices/elimination/summary.txt
new file mode 100644 (file)
index 0000000..83972ab
--- /dev/null
@@ -0,0 +1 @@
+Solving systems of linear equations
diff --git a/basis/math/matrices/matrices-tests.factor b/basis/math/matrices/matrices-tests.factor
new file mode 100644 (file)
index 0000000..2094235
--- /dev/null
@@ -0,0 +1,109 @@
+IN: math.matrices.tests
+USING: math.matrices math.vectors tools.test math ;
+
+[
+    { { 0 } { 0 } { 0 } }
+] [
+    3 1 zero-matrix
+] unit-test
+
+[
+    { { 1 0 0 }
+       { 0 1 0 }
+       { 0 0 1 } }
+] [
+    3 identity-matrix
+] unit-test
+
+[
+    { { 1 0 4 }
+       { 0 7 0 }
+       { 6 0 3 } }
+] [
+    { { 1 0 0 }
+       { 0 2 0 }
+       { 0 0 3 } }
+       
+    { { 0 0 4 }
+       { 0 5 0 }
+       { 6 0 0 } }
+
+    m+
+] unit-test
+
+[
+    { { 1 0 4 }
+       { 0 7 0 }
+       { 6 0 3 } }
+] [
+    { { 1 0 0 }
+       { 0 2 0 }
+       { 0 0 3 } }
+       
+    { { 0 0 -4 }
+       { 0 -5 0 }
+       { -6 0 0 } }
+
+    m-
+] unit-test
+
+[
+    { 10 20 30 }
+] [
+    10 { 1 2 3 } n*v
+] unit-test
+
+[
+    { 3 4 }
+] [
+    { { 1 0 }
+       { 0 1 } }
+
+    { 3 4 }
+
+    m.v
+] unit-test
+
+[
+    { 4 3 }
+] [
+    { { 0 1 }
+       { 1 0 } }
+
+    { 3 4 }
+
+    m.v
+] unit-test
+
+[
+    { { 6 } }
+] [
+    { { 3 } } { { 2 } } m.
+] unit-test
+
+[
+    { { 11 } }
+] [
+    { { 1 3 } } { { 5 } { 2 } } m.
+] unit-test
+
+[
+    { { 28 } }
+] [
+    { { 2 4 6 } }
+
+    { { 1 }
+       { 2 }
+       { 3 } }
+    
+    m.
+] unit-test
+
+[ { 0 0 -1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
+[ { 1 0 0 } ] [ { 0 1 0 } { 0 0 1 } cross ] unit-test
+[ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
+
+[ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
+
+[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
+[ { 1 2 } { "a" "b" } cross-zip ] unit-test
\ No newline at end of file
diff --git a/basis/math/matrices/matrices.factor b/basis/math/matrices/matrices.factor
new file mode 100755 (executable)
index 0000000..7c687d7
--- /dev/null
@@ -0,0 +1,62 @@
+! Copyright (C) 2005, 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays kernel math math.order math.vectors sequences ;
+IN: math.matrices
+
+! Matrices
+: zero-matrix ( m n -- matrix )
+    [ nip 0 <array> ] curry map ;
+
+: identity-matrix ( n -- matrix )
+    #! Make a nxn identity matrix.
+    dup [ [ = 1 0 ? ] with map ] curry map ;
+
+! Matrix operations
+: mneg ( m -- m ) [ vneg ] map ;
+
+: n*m ( n m -- m ) [ n*v ] with map ;
+: m*n ( m n -- m ) [ v*n ] curry map ;
+: n/m ( n m -- m ) [ n/v ] with map ;
+: m/n ( m n -- m ) [ v/n ] curry map ;
+
+: m+   ( m m -- m ) [ v+ ] 2map ;
+: m-   ( m m -- m ) [ v- ] 2map ;
+: m*   ( m m -- m ) [ v* ] 2map ;
+: m/   ( m m -- m ) [ v/ ] 2map ;
+
+: v.m ( v m -- v ) flip [ v. ] with map ;
+: m.v ( m v -- v ) [ v. ] curry map ;
+: m.  ( m m -- m ) flip [ swap m.v ] curry map ;
+
+: mmin ( m -- n ) [ 1/0. ] dip [ [ min ] each ] each ;
+: mmax ( m -- n ) [ -1/0. ] dip [ [ max ] each ] each ;
+: mnorm ( m -- n ) dup mmax abs m/n ;
+
+<PRIVATE
+
+: x ( seq -- elt ) first ; inline
+: y ( seq -- elt ) second ; inline
+: z ( seq -- elt ) third ; inline
+
+: i ( seq1 seq2 -- n ) [ [ y ] [ z ] bi* * ] [ [ z ] [ y ] bi* * ] 2bi - ;
+: j ( seq1 seq2 -- n ) [ [ z ] [ x ] bi* * ] [ [ x ] [ z ] bi* * ] 2bi - ;
+: k ( seq1 seq2 -- n ) [ [ y ] [ x ] bi* * ] [ [ x ] [ y ] bi* * ] 2bi - ;
+
+PRIVATE>
+
+: cross ( vec1 vec2 -- vec3 ) [ i ] [ j ] [ k ] 2tri 3array ;
+
+: proj ( v u -- w )
+    [ [ v. ] [ norm-sq ] bi / ] keep n*v ;
+
+: (gram-schmidt) ( v seq -- newseq )
+    [ dupd proj v- ] each ;
+
+: gram-schmidt ( seq -- orthogonal )
+    V{ } clone [ over (gram-schmidt) over push ] reduce ;
+
+: norm-gram-schmidt ( seq -- orthonormal )
+    gram-schmidt [ normalize ] map ;
+
+: cross-zip ( seq1 seq2 -- seq1xseq2 )
+    [ [ 2array ] with map ] curry map ;
\ No newline at end of file
diff --git a/basis/math/matrices/summary.txt b/basis/math/matrices/summary.txt
new file mode 100644 (file)
index 0000000..0e9fa9a
--- /dev/null
@@ -0,0 +1 @@
+Matrix arithmetic
index 54378bd37e9bb00f8b0f4cb056afb67520e47c97..d82abe5b07aefbcd8b48e01ddea62b2c16b34ad7 100644 (file)
@@ -9,7 +9,7 @@ MEMO: fib ( m -- n )
 
 [ 89 ] [ 10 fib ] unit-test
 
-[ "USING: kernel math memoize generalizations ; IN: memoize.tests MEMO: x ( a b c d e -- f g h i j ) [ 1+ ] 4 ndip ;" eval ] must-fail
+[ "USING: kernel math memoize generalizations ; IN: memoize.tests MEMO: x ( a b c d e -- f g h i j ) [ 1+ ] 4 ndip ;" eval( -- ) ] must-fail
 
 MEMO: see-test ( a -- b ) reverse ;
 
@@ -17,7 +17,7 @@ MEMO: see-test ( a -- b ) reverse ;
 [ [ \ see-test see ] with-string-writer ]
 unit-test
 
-[ ] [ "IN: memoize.tests : fib ( -- ) ;" eval ] unit-test
+[ ] [ "IN: memoize.tests : fib ( -- ) ;" eval( -- ) ] unit-test
 
 [ "IN: memoize.tests\n: fib ( -- ) ;\n" ] [ [ \ fib see ] with-string-writer ] unit-test
 
index 4e10fc3de4548e3afc165ad5b8b5a64c055cfb9f..74ca07cda305d0b4322f92d9b8cb36a119d93a63 100644 (file)
@@ -61,3 +61,5 @@ M: memoized reset-word
 
 : invalidate-memoized ( inputs... word -- )
     [ stack-effect in>> packer call ] [ "memoize" word-prop delete-at ] bi ;
+
+\ invalidate-memoized t "no-compile" set-word-prop
\ No newline at end of file
index 0edfb05a3081da96ed583c0454792630a6be6cc7..0cf7556bcd01513f23472bd3f5082cca7bb969c8 100755 (executable)
@@ -137,9 +137,6 @@ ERROR: no-content-disposition multipart ;
         [ no-content-disposition ]
     } case ;
 
-: assert-sequence= ( a b -- )
-    2dup sequence= [ 2drop ] [ assert ] if ;
-
 : read-assert-sequence= ( sequence -- )
     [ length read ] keep assert-sequence= ;
 
index aad033600abaf4c17f8b9e9c58da1d9c9c117962..ed1f423bb0a982da596558b01dc8720fc9ad77d2 100644 (file)
@@ -56,6 +56,6 @@ TUPLE: color
 ! Test reshaping with a mirror
 1 2 3 color boa <mirror> "mirror" set
 
-[ ] [ "IN: mirrors.tests USE: math TUPLE: color { green integer } { red integer } { blue integer } ;" eval ] unit-test
+[ ] [ "IN: mirrors.tests USE: math TUPLE: color { green integer } { red integer } { blue integer } ;" eval( -- ) ] unit-test
 
 [ 1 ] [ "red" "mirror" get at ] unit-test
diff --git a/basis/models/arrow/smart/authors.txt b/basis/models/arrow/smart/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
index 45faf52b97948380e5235815975a2914f239d0d9..3cc22d8d40ab2314db7cfb1a9bb9cb305855dd70 100644 (file)
@@ -7,15 +7,15 @@ HELP: <smart-arrow>
 { $examples
   "A model which adds the values of two existing models:"
   { $example
-    "USING: models models.arrows.smart accessors math prettyprint ;"
+    "USING: models models.arrow.smart accessors kernel math prettyprint ;"
     "1 <model> 2 <model> [ + ] <smart-arrow>"
     "[ activate-model ] [ value>> ] bi ."
     "3"
   }
 } ;
 
-ARTICLE: "models.arrows.smart" "Smart arrow models"
-"The " { $vocab-link "models.arrows.smart" } " vocabulary generalizes arrows to arbitrary input arity. They're called “smart” because they resemble " { $link "combinators.smart" } "."
+ARTICLE: "models.arrow.smart" "Smart arrow models"
+"The " { $vocab-link "models.arrow.smart" } " vocabulary generalizes arrows to arbitrary input arity. They're called “smart” because they resemble " { $link "combinators.smart" } "."
 { $subsection <smart-arrow> } ;
 
-ABOUT: "models.arrows.smart"
\ No newline at end of file
+ABOUT: "models.arrow.smart"
\ No newline at end of file
diff --git a/basis/models/arrow/smart/smart-tests.factor b/basis/models/arrow/smart/smart-tests.factor
new file mode 100644 (file)
index 0000000..3e8375e
--- /dev/null
@@ -0,0 +1,4 @@
+IN: models.arrows.smart.tests
+USING: models.arrow.smart tools.test accessors models math kernel ;
+
+[ 7 ] [ 3 <model> 4 <model> [ + ] <smart-arrow> [ activate-model ] [ value>> ] bi ] unit-test
\ No newline at end of file
diff --git a/basis/models/arrow/smart/smart.factor b/basis/models/arrow/smart/smart.factor
new file mode 100644 (file)
index 0000000..257a2bb
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: models.arrow models.product stack-checker accessors fry
+generalizations macros kernel ;
+IN: models.arrow.smart
+
+MACRO: <smart-arrow> ( quot -- quot' )
+    [ infer in>> dup ] keep
+    '[ _ narray <product> [ _ firstn @ ] <arrow> ] ;
\ No newline at end of file
index 4bf74b3b92e06807bfbdb4da37a1de0b92007500..5ecb0fa34ada9a88cf9a3ac944fe6cb7bd7687e7 100644 (file)
@@ -1,12 +1,10 @@
 ! Copyright (C) 2008, 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays fry kernel models.product models.arrow
-sequences unicode.case ;
+USING: fry kernel models.arrow.smart sequences unicode.case ;
 IN: models.search
 
 : <search> ( values search quot -- model )
-    [ 2array <product> ] dip
-    '[ first2 _ curry filter ] <arrow> ;
+    '[ _ curry filter ] <smart-arrow> ; inline
 
 : <string-search> ( values search quot -- model )
-    '[ swap @ [ >case-fold ] bi@ subseq? ] <search> ;
+    '[ swap @ [ >case-fold ] bi@ subseq? ] <search> ; inline
index 23c150796fac63b956280264821018fcf3a3e0c6..efd2e4927b53aa8fe5c4569e5757565f8a1b2880 100644 (file)
@@ -1,8 +1,7 @@
-! Copyright (C) 2008 Slava Pestov
+! Copyright (C) 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays fry kernel models.product models.arrow
-sequences sorting ;
+USING: sorting models.arrow.smart fry ;
 IN: models.sort
 
 : <sort> ( values sort -- model )
-    2array <product> [ first2 sort ] <arrow> ;
\ No newline at end of file
+    [ '[ _ call( obj1 obj2 -- <=> ) ] sort ] <smart-arrow> ; inline
\ No newline at end of file
index 76e0c473b91049e301a9ce253e3a3343a8817947..d103e90beec923bac0d4d7de4c1e65dadb26975f 100755 (executable)
@@ -45,7 +45,7 @@ TUPLE: single-texture image dim loc texture-coords texture display-list disposed
 
 : adjust-texture-dim ( dim -- dim' )
     non-power-of-2-textures? get [
-        [ next-power-of-2 ] map
+        [ dup 1 = [ next-power-of-2 ] unless ] map
     ] unless ;
 
 : (tex-image) ( image bitmap -- )
@@ -128,7 +128,9 @@ M: single-texture dispose*
     [ display-list>> [ delete-dlist ] when* ] bi ;
 
 M: single-texture draw-scaled-texture
-    dup texture>> [ draw-textured-rect ] [ 2drop ] if ;
+    2dup dim>> = [ nip draw-texture ] [
+        dup texture>> [ draw-textured-rect ] [ 2drop ] if
+    ] if ;
 
 TUPLE: multi-texture grid display-list loc disposed ;
 
@@ -166,6 +168,8 @@ TUPLE: multi-texture grid display-list loc disposed ;
         f multi-texture boa
     ] with-destructors ;
 
+M: multi-texture draw-scaled-texture nip draw-texture ;
+
 M: multi-texture dispose* grid>> [ [ dispose ] each ] each ;
 
 CONSTANT: max-texture-size { 512 512 }
index cc83a55c7e65c2aed4ccf87afa2278e1fff37c3e..58102cffc351aed4ce24a4b6c2f62f9c3aa67ec6 100644 (file)
@@ -444,12 +444,12 @@ foo=<foreign any-char> 'd'
   "ad" parser4
 ] unit-test
 
-{ } [
- "USING: kernel peg.ebnf ; \"a\\n\" [EBNF foo='a' '\n'  => [[ drop \"\n\" ]] EBNF]" eval drop t
+{ } [
+ "USING: kernel peg.ebnf ; \"a\\n\" [EBNF foo='a' '\n'  => [[ drop \"\n\" ]] EBNF] drop" eval( -- ) 
 ] unit-test
 
 [
-  "USING: peg.ebnf ; <EBNF foo='a' foo='b' EBNF>" eval drop
+  "USING: peg.ebnf ; <EBNF foo='a' foo='b' EBNF>" eval( -- ) drop
 ] must-fail
 
 { t } [
@@ -521,12 +521,12 @@ Tok                = Spaces (Number | Special )
   "\\" [EBNF foo="\\" EBNF]
 ] unit-test
 
-[ "USE: peg.ebnf [EBNF EBNF]" eval ] must-fail
+[ "USE: peg.ebnf [EBNF EBNF]" eval( -- ) ] must-fail
 
 [ <" USE: peg.ebnf [EBNF
     lol = a
     lol = b
-  EBNF] "> eval
+  EBNF] "> eval( -- )
 ] [
     error>> [ redefined-rule? ] [ name>> "lol" = ] bi and
 ] must-fail-with
index 91f1dcf1f80b2a995a608e08904ac3199ee82cc2..ca9a86b6d92788a1d2e047a4f31eb66a08008232 100644 (file)
@@ -21,7 +21,7 @@ TUPLE: deque { front read-only } { back read-only } ;
     [ back>> ] [ front>> ] bi deque boa ;
 
 : flipped ( deque quot -- newdeque )
-    [ flip ] dip call flip ;
+    [ flip ] dip call flip ; inline
 PRIVATE>
 
 : deque-empty? ( deque -- ? )
index 5ed72e5d599904f61a92983ef5aa6ca181510635..eea31dd34e700c5475d231658dea0468da04ae29 100644 (file)
@@ -83,7 +83,7 @@ M: hash-0-b hashcode* 2drop 0 ;
 : random-string ( -- str )
     1000000 random ; ! [ CHAR: a CHAR: z [a,b] random ] "" replicate-as ;
 
-: random-assocs ( -- hash phash )
+: random-assocs ( -- hash phash )
     [ random-string ] replicate
     [ H{ } clone [ '[ swap _ set-at ] each-index ] keep ]
     [ PH{ } clone swap [ spin new-at ] each-index ]
@@ -92,7 +92,7 @@ M: hash-0-b hashcode* 2drop 0 ;
 : ok? ( assoc1 assoc2 -- ? )
     [ assoc= ] [ [ assoc-size ] bi@ = ] 2bi and ;
 
-: test-persistent-hashtables-1 ( n -- )
+: test-persistent-hashtables-1 ( n -- )
     random-assocs ok? ;
 
 [ t ] [ 10 test-persistent-hashtables-1 ] unit-test
@@ -106,7 +106,7 @@ M: hash-0-b hashcode* 2drop 0 ;
 [ t ] [ 10000 test-persistent-hashtables-1 ] unit-test
 [ t ] [ 50000 test-persistent-hashtables-1 ] unit-test
 
-: test-persistent-hashtables-2 ( n -- )
+: test-persistent-hashtables-2 ( n -- )
     random-assocs
     dup keys [
         [ nip over delete-at ] [ swap pluck-at nip ] 3bi
index 799d500c188256ac8a6c2de5d6e7f293b7658bba..a660d4a31174298c19491beed8083ee6caf86a50 100644 (file)
@@ -2,8 +2,8 @@ USING: arrays definitions io.streams.string io.streams.duplex
 kernel math namespaces parser prettyprint prettyprint.config
 prettyprint.sections sequences tools.test vectors words
 effects splitting generic.standard prettyprint.private
-continuations generic compiler.units tools.walker eval
-accessors make vocabs.parser see ;
+continuations generic compiler.units tools.continuations
+tools.continuations.private eval accessors make vocabs.parser see ;
 IN: prettyprint.tests
 
 [ "4" ] [ 4 unparse ] unit-test
@@ -90,7 +90,7 @@ unit-test
     [ \ blah see ] with-string-writer "\n" ?tail drop 6 tail*
 ] unit-test
 
-: check-see ( expect name -- )
+: check-see ( expect name -- )
     [
         use [ clone ] change
 
@@ -105,6 +105,7 @@ unit-test
 GENERIC: method-layout ( a -- b )
 
 M: complex method-layout
+    drop
     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     ;
 
@@ -116,8 +117,9 @@ M: object method-layout ;
 
 [
     {
-        "USING: math prettyprint.tests ;"
+        "USING: kernel math prettyprint.tests ;"
         "M: complex method-layout"
+        "    drop"
         "    \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
         "    ;"
         ""
@@ -180,15 +182,15 @@ DEFER: parse-error-file
     "string-layout-test" string-layout check-see
 ] unit-test
 
-: narrow-test ( -- str )
+: narrow-test ( -- array )
     {
         "USING: arrays combinators continuations kernel sequences ;"
         "IN: prettyprint.tests"
-        ": narrow-layout ( obj -- )"
+        ": narrow-layout ( obj1 obj2 -- obj3 )"
         "    {"
         "        { [ dup continuation? ] [ append ] }"
         "        { [ dup not ] [ drop reverse ] }"
-        "        { [ dup pair? ] [ delete ] }"
+        "        { [ dup pair? ] [ [ delete ] keep ] }"
         "    } cond ;"
     } ;
 
@@ -196,7 +198,7 @@ DEFER: parse-error-file
     "narrow-layout" narrow-test check-see
 ] unit-test
 
-: another-narrow-test ( -- str )
+: another-narrow-test ( -- array )
     {
         "IN: prettyprint.tests"
         ": another-narrow-layout ( -- obj )"
@@ -252,19 +254,15 @@ M: class-see-layout class-see-layout ;
 ! Regression
 [ t ] [
     "IN: prettyprint.tests\nGENERIC: generic-decl-test ( a -- b ) flushable\n"
-    dup eval
+    dup eval( -- )
     "generic-decl-test" "prettyprint.tests" lookup
     [ see ] with-string-writer =
 ] unit-test
 
-[ [ + ] ] [
-    [ \ + (step-into-execute) ] (remove-breakpoints)
-] unit-test
-
-[ [ (step-into-execute) ] ] [
-    [ (step-into-execute) ] (remove-breakpoints)
-] unit-test
+[ [ + ] ] [ [ \ + (step-into-execute) ] (remove-breakpoints) ] unit-test
 
+[ [ (step-into-execute) ] ] [ [ (step-into-execute) ] (remove-breakpoints) ] unit-test
 [ [ 2 2 + . ] ] [
     [ 2 2 \ + (step-into-execute) . ] (remove-breakpoints)
 ] unit-test
index fe58e3d07c02ba5629aa46d178ba33fbf3d48604..c35d7488ac5ac40bd460090679a279efb5bd81d0 100644 (file)
@@ -11,7 +11,7 @@ IN: random.mersenne-twister.tests
     100 [ 100 random ] replicate ;
 
 : test-rng ( seed quot -- )
-    [  <mersenne-twister> ] dip with-random ;
+    [  <mersenne-twister> ] dip with-random ; inline
 
 [ f ] [ 1234 [ randoms randoms = ] test-rng ] unit-test
 
index 1901f27a24507e2512d93a1f956aaaa0d2f05714..22d592c1dd2724fc2e2d4193087a0e87a3e7c1e8 100755 (executable)
@@ -1 +1,2 @@
 Slava Pestov
+Alex Chapman
index a219f0ba8b24cfcb6f21e5ffef844c2c099a3e20..9c10641c4ce5489f8b8dc742d58dcc0c72df4dfc 100644 (file)
@@ -1,38 +1,90 @@
-! Copyright (C) 2007 Slava Pestov
+! Copyright (C) 2007 Slava Pestov, 2009 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel ;
+USING: boxes help.markup help.syntax kernel math namespaces ;
 IN: refs
 
-ARTICLE: "refs" "References to assoc entries"
-"A " { $emphasis "reference" } " is an object encapsulating an assoc and a key; the reference then refers to either the key itself, or the value associated to the key. References can be read, written, and deleted. References are defined in the " { $vocab-link "refs" } " vocabulary."
+ARTICLE: "refs" "References"
+"References provide a uniform way of accessing and changing values. Some examples of referenced values are variables, tuple slots, and keys or values of assocs. References can be read, written, and deleted. References are defined in the " { $vocab-link "refs" } " vocabulary, and new reference types can be made by implementing the " { $link "refs-protocol" } "."
 { $subsection get-ref }
 { $subsection set-ref }
+{ $subsection set-ref* }
 { $subsection delete-ref }
-"References to keys:"
+"References to objects:"
+{ $subsection obj-ref }
+{ $subsection <obj-ref> }
+"References to assoc keys:"
 { $subsection key-ref }
 { $subsection <key-ref> }
-"References to values:"
+"References to assoc values:"
 { $subsection value-ref }
 { $subsection <value-ref> }
+"References to variables:"
+{ $subsection var-ref }
+{ $subsection <var-ref> }
+{ $subsection global-var-ref }
+{ $subsection <global-var-ref> }
+"References to tuple slots:"
+{ $subsection slot-ref }
+{ $subsection <slot-ref> }
+"Using boxes as references:"
+{ $subsection "box-refs" }
 "References are used by the UI inspector." ;
 
 ABOUT: "refs"
 
+ARTICLE: "refs-protocol" "Reference Protocol"
+"To use a class of objects as references you must implement the reference protocol for that class, and mark your class as an instance of the " { $link ref } " mixin class. All references must implement these two words:"
+{ $subsection get-ref }
+{ $subsection set-ref }
+"References may also implement:"
+{ $subsection delete-ref } ;
+
+ARTICLE: "box-refs" "Using Boxes as References"
+"Boxes are elements of the " { $link ref } " mixin class, so any box may be used as a reference. Bear in mind that boxes will still throw an error if you call " { $link get-ref } " on an empty box." ;
+
 HELP: ref
-{ $class-description "A class whose instances identify a key or value location in an associative structure. Instances of this clas are never used directly; only instances of " { $link key-ref } " and " { $link value-ref } " should be created." } ;
+{ $class-description "A mixin class whose instances encapsulate a value which can be read, written, and deleted. Instantiable members of this class include:" { $link obj-ref } ", " { $link var-ref } ", " { $link global-var-ref } ", " { $link slot-ref } ", " { $link box } ", " { $link key-ref } ", and " { $link value-ref } "." } ;
 
 HELP: delete-ref
 { $values { "ref" ref } }
-{ $description "Deletes the association entry pointed at by this reference." } ;
+{ $description "Deletes the value pointed to by this reference. In most references this simply sets the value to f, but in some cases it is more destructive, such as in " { $link value-ref } " and " { $link key-ref } ", where it actually deletes the entry from the underlying assoc." } ;
 
 HELP: get-ref
 { $values { "ref" ref } { "obj" object } }
-{ $description "Outputs the key or the value pointed at by this reference." } ;
+{ $description "Outputs the value pointed at by this reference." } ;
 
 HELP: set-ref
 { $values { "obj" object } { "ref" ref } }
-{ $description "Stores a new key or value at by this reference." } ;
+{ $description "Stores a new value at this reference." } ;
+
+HELP: obj-ref
+{ $class-description "Instances of this class contain a value which can be changed using the " { $link "refs-protocol" } ". New object references are created by calling " { $link <obj-ref> } "." } ;
+
+HELP: <obj-ref>
+{ $values { "obj" object } { "obj-ref" obj-ref } }
+{ $description "Creates a reference which contains the value it references." } ;
 
+HELP: var-ref
+{ $class-description "Instances of this class reference a variable as defined by the " { $vocab-link "namespaces" } " vocabulary. New variable references are created by calling " { $link <var-ref> } "." } ;
+
+HELP: <var-ref>
+{ $values { "var" object } { "var-ref" var-ref } }
+{ $description "Creates a reference to the given variable. Note that this reference behaves just like any variable when it comes to dynamic scope. For example, if you use " { $link set-ref } " in an inner scope and then leave that scope, then calling " { $link get-ref } " may not return the expected value. If this is not what you want, try using an " { $link obj-ref } " instead." } ;
+HELP: global-var-ref
+{ $class-description "Instances of this class reference a global variable. New global references are created by calling " { $link <global-var-ref> } "." } ;
+
+HELP: <global-var-ref>
+{ $values { "var" object } { "global-var-ref" global-var-ref } }
+{ $description "Creates a reference to a global variable." } ;
+
+HELP: slot-ref
+{ $class-description "Instances of this class identify a particular slot of a particular instance of a tuple. New slot references are created by calling " { $link <slot-ref> } "." } ;
+
+HELP: <slot-ref>
+{ $values { "tuple" tuple } { "slot" integer } { "slot-ref" slot-ref } }
+{ $description "Creates a reference to the value in a particular slot of the given tuple. The slot must be given as an integer, where the first user-defined slot is number 2. This is mostly just a proof of concept until we have a way of generating this slot number from a slot name." } ;
+  
 HELP: key-ref
 { $class-description "Instances of this class identify a key in an associative structure. New key references are created by calling " { $link <key-ref> } "." } ;
 
@@ -47,6 +99,37 @@ HELP: <value-ref>
 { $values { "assoc" "an assoc" } { "key" object } { "value-ref" value-ref } }
 { $description "Creates a reference to the value associated with " { $snippet "key" } " in " { $snippet "assoc" } "." } ;
 
-{ get-ref set-ref delete-ref } related-words
+{ get-ref set-ref delete-ref set-ref* } related-words
+  
+{ <obj-ref> <var-ref> <global-var-ref> <slot-ref> <key-ref> <value-ref> } related-words
 
-{ <key-ref> <value-ref> } related-words
+HELP: set-ref*
+{ $values { "ref" ref } { "obj" object } }
+{ $description "Just like " { $link set-ref } ", but leave the ref on the stack." } ;
+
+HELP: ref-on
+{ $values { "ref" ref } }
+{ $description "Sets the value of the ref to t." } ;
+
+HELP: ref-off
+{ $values { "ref" ref } }
+{ $description "Sets the value of the ref to f." } ;
+
+HELP: ref-inc
+{ $values { "ref" ref } }
+{ $description "Increment the value of the ref by 1." } ;
+
+HELP: ref-dec
+{ $values { "ref" ref } }
+{ $description "Decrement the value of the ref by 1." } ;
+
+HELP: take
+{ $values { "ref" ref } { "obj" object } }
+{ $description "Retrieve the value of the ref and then delete it, returning the value." } ;
+  
+{ ref-on ref-off ref-inc ref-dec take } related-words
+{ take delete-ref } related-words
+{ on ref-on } related-words
+{ off ref-off } related-words
+{ inc ref-inc } related-words
+{ dec ref-dec } related-words
index 1d921854e98fd080b3b12726083a13a004ff5457..bf58aaf43d43f49d1e6b15005be414a65192be81 100644 (file)
@@ -1,5 +1,7 @@
-USING: refs tools.test kernel ;
+USING: boxes kernel namespaces refs tools.test ;
+IN: refs.tests
 
+! assoc-refs
 [ 3 ] [
     H{ { "a" 3 } } "a" <value-ref> get-ref
 ] unit-test
@@ -20,3 +22,84 @@ USING: refs tools.test kernel ;
         set-ref
     ] keep
 ] unit-test
+
+SYMBOLS: lion giraffe elephant rabbit ;
+
+! obj-refs
+[ rabbit ] [ rabbit <obj-ref> get-ref ] unit-test
+[ rabbit ] [ f <obj-ref> rabbit set-ref* get-ref ] unit-test
+[ rabbit ] [ rabbit <obj-ref> take ] unit-test
+[ rabbit f ] [ rabbit <obj-ref> [ take ] keep get-ref ] unit-test
+[ lion ] [ rabbit <obj-ref> dup [ drop lion ] change-ref get-ref ] unit-test
+
+! var-refs 
+[ giraffe ] [ [ giraffe rabbit set rabbit <var-ref> get-ref ] with-scope ] unit-test
+
+[ rabbit ]
+[
+    [
+        lion rabbit set [
+            rabbit rabbit set rabbit <var-ref> get-ref
+        ] with-scope
+    ] with-scope
+] unit-test
+
+[ rabbit ] [
+    rabbit <var-ref>
+    [
+        lion rabbit set [
+            rabbit rabbit set get-ref
+        ] with-scope
+    ] with-scope
+] unit-test
+
+[ elephant ] [
+    rabbit <var-ref>
+    [
+        elephant rabbit set [
+            rabbit rabbit set
+        ] with-scope
+        get-ref
+    ] with-scope
+] unit-test
+
+[ rabbit ] [
+    rabbit <var-ref>
+    [
+        elephant set-ref* [
+            rabbit set-ref* get-ref
+        ] with-scope
+    ] with-scope
+] unit-test
+
+[ elephant ] [
+    rabbit <var-ref>
+    [
+        elephant set-ref* [
+            rabbit set-ref*
+        ] with-scope
+        get-ref
+    ] with-scope
+] unit-test
+
+! Top Hats
+[ lion ] [ lion rabbit set-global rabbit <global-var-ref> get-ref ] unit-test
+[ giraffe ] [ rabbit <global-var-ref> giraffe set-ref* get-ref ] unit-test
+
+! Tuple refs
+TUPLE: foo bar ;
+C: <foo> foo
+
+: test-tuple ( -- tuple )
+    rabbit <foo> ;
+
+: test-slot-ref ( -- slot-ref )
+    test-tuple 2 <slot-ref> ; ! hack!
+
+[ rabbit ] [ test-slot-ref get-ref ] unit-test
+[ lion ] [ test-slot-ref lion set-ref* get-ref ] unit-test
+
+! Boxes as refs
+[ rabbit ] [ <box> rabbit set-ref* get-ref ] unit-test
+[ <box> rabbit set-ref* lion set-ref* ] must-fail
+[ <box> get-ref ] must-fail
index 0164a1ea57872c3b5c33ca25056af2cffd542fc7..668cdd65c3dcfdb025dde18c106d416786ebbff4 100644 (file)
@@ -1,22 +1,77 @@
-! Copyright (C) 2007, 2008 Slava Pestov
+! Copyright (C) 2007, 2008 Slava Pestov, 2009 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: classes.tuple kernel assocs accessors ;
+USING: kernel assocs accessors boxes math namespaces ;
 IN: refs
 
-TUPLE: ref assoc key ;
+MIXIN: ref
 
-: >ref< ( ref -- key value ) [ key>> ] [ assoc>> ] bi ; inline
-
-: delete-ref ( ref -- ) >ref< delete-at ;
 GENERIC: get-ref ( ref -- obj )
 GENERIC: set-ref ( obj ref -- )
+GENERIC: delete-ref ( ref -- )
+
+! works like >>slot words
+: set-ref* ( ref obj -- ref ) over set-ref ;
+
+! very similar to change, on, off, +@, inc, and dec from namespaces
+: change-ref ( ref quot -- )
+    [ [ get-ref ] keep ] dip dip set-ref ; inline
+: ref-on ( ref -- ) t swap set-ref ;
+: ref-off ( ref -- ) f swap set-ref ;
+: ref-+@ ( n ref -- ) [ 0 or + ] change-ref ;
+: ref-inc ( ref -- ) 1 swap ref-+@ ;
+: ref-dec ( ref -- ) -1 swap ref-+@ ;
+
+: take ( ref -- obj )
+    dup get-ref swap delete-ref ;
+
+! delete-ref defaults to setting ref to f
+M: ref delete-ref ref-off ;
+
+TUPLE: obj-ref obj ;
+C: <obj-ref> obj-ref
+M: obj-ref get-ref obj>> ;
+M: obj-ref set-ref (>>obj) ;
+INSTANCE: obj-ref ref
+
+TUPLE: var-ref var ;
+C: <var-ref> var-ref
+M: var-ref get-ref var>> get ;
+M: var-ref set-ref var>> set ;
+INSTANCE: var-ref ref
+
+TUPLE: global-var-ref var ;
+C: <global-var-ref> global-var-ref
+M: global-var-ref get-ref var>> get-global ;
+M: global-var-ref set-ref var>> set-global ;
+INSTANCE: global-var-ref ref
+
+USE: slots.private
+TUPLE: slot-ref tuple slot ;
+C: <slot-ref> slot-ref
+: >slot-ref< ( slot-ref -- tuple slot ) [ tuple>> ] [ slot>> ] bi ; inline
+M: slot-ref get-ref >slot-ref< slot ;
+M: slot-ref set-ref >slot-ref< set-slot ;
+INSTANCE: slot-ref ref
+
+M: box get-ref box> ;
+M: box set-ref >box ;
+M: box delete-ref box> drop ;
+INSTANCE: box ref
+
+TUPLE: assoc-ref assoc key ;
+
+: >assoc-ref< ( assoc-ref -- key value ) [ key>> ] [ assoc>> ] bi ; inline
+
+M: assoc-ref delete-ref ( assoc-ref -- ) >assoc-ref< delete-at ;
 
-TUPLE: key-ref < ref ;
+TUPLE: key-ref < assoc-ref ;
 C: <key-ref> key-ref
 M: key-ref get-ref key>> ;
-M: key-ref set-ref >ref< rename-at ;
+M: key-ref set-ref >assoc-ref< rename-at ;
+INSTANCE: key-ref ref
 
-TUPLE: value-ref < ref ;
+TUPLE: value-ref < assoc-ref ;
 C: <value-ref> value-ref
-M: value-ref get-ref >ref< at ;
-M: value-ref set-ref >ref< set-at ;
+M: value-ref get-ref >assoc-ref< at ;
+M: value-ref set-ref >assoc-ref< set-at ;
+INSTANCE: value-ref ref
index 5ea9753fbaf66b9ec2a964a7a8db951f30a0cb9d..0e12014eefe4d6f983db2fef7a8b14d410de02ce 100644 (file)
@@ -4,7 +4,7 @@ IN: regexp.parser.tests
 : regexp-parses ( string -- )
     [ [ ] ] dip '[ _ parse-regexp drop ] unit-test ;
 
-: regexp-fails ( string -- )
+: regexp-fails ( string -- regexp )
     '[ _ parse-regexp ] must-fail ;
 
 {
index 22343868032108956f864c87579bf6f61736c5be..0479b104ccced7f45d3c35fe9fb8c0519e4a0c9d 100644 (file)
@@ -262,11 +262,11 @@ IN: regexp-tests
 ! Comment inside a regular expression
 [ t ] [ "ac" "a(?#boo)c" <regexp> matches? ] unit-test
 
-[ ] [ "USING: regexp kernel ; R' -{3}[+]{1,6}(?:!!)?\\s' drop" eval ] unit-test
+[ ] [ "USING: regexp kernel ; R' -{3}[+]{1,6}(?:!!)?\\s' drop" eval( -- ) ] unit-test
 
-[ ] [ "USING: regexp kernel ; R' (ftp|http|https)://(\\w+:?\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-/]))?' drop" eval ] unit-test
+[ ] [ "USING: regexp kernel ; R' (ftp|http|https)://(\\w+:?\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-/]))?' drop" eval( -- ) ] unit-test
 
-[ ] [ "USING: regexp kernel ; R' \\*[^\s*][^*]*\\*' drop" eval ] unit-test
+[ ] [ "USING: regexp kernel ; R' \\*[^\s*][^*]*\\*' drop" eval( -- ) ] unit-test
 
 [ "ab" ] [ "ab" "(a|ab)(bc)?" <regexp> first-match >string ] unit-test
 [ "abc" ] [ "abc" "(a|ab)(bc)?" <regexp> first-match >string ] unit-test
index 159b1e91e961fbe78dfa41a6b73d31f191d55278..ad5e36ed582827e2683e1c249cf123028d54df8f 100644 (file)
@@ -1,3 +1,5 @@
 Elie Chaftari
 Dirk Vleugels
 Slava Pestov
+Doug Coleman
+Daniel Ehrenberg
index 5d7791292bc3db8dace2c11f816126705a1e5267..dbff4fd214143a27e733be4c4b60c50a1116ddfb 100644 (file)
@@ -36,6 +36,7 @@ SYMBOL: data-mode
 
 : process ( -- )
     read-crlf {
+        { [ dup not ] [ f ] }
         {
             [ dup [ "HELO" head? ] [ "EHLO" head? ] bi or ]
             [ "220 and..?\r\n" write flush t ]
index 453f4009e281c61345e9c2dcbf52421af4edce9f..0b13113427782f23fd2d46e33a2a11729ee2a38d 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel quotations help.syntax help.markup
-io.sockets strings calendar ;
+io.sockets strings calendar io.encodings.utf8 ;
 IN: smtp
 
 HELP: smtp-domain
@@ -41,7 +41,9 @@ HELP: email
         { { $slot "to" } "The recipients of the e-mail. A sequence of e-mail addresses." }
         { { $slot "cc" } "Carbon-copy. A sequence of e-mail addresses." }
         { { $slot "bcc" } "Blind carbon-copy. A sequence of e-mail addresses." }
-        { { $slot "subject" } " The subject of the e-mail. A string." }
+        { { $slot "subject" } "The subject of the e-mail. A string." }
+        { { $slot "content-type" } { "The MIME type of the body. A string, default is " { $snippet "text/plain" } "." } }
+        { { $slot "encoding" } { "An encoding to send the body as. Default is " { $link utf8 } "." } }
         { { $slot "body" } " The body of the e-mail. A string." }
     }
 "The " { $slot "from" } " and " { $slot "to" } " slots are required; the rest are optional."
index 8a9107b905ff5a65cd85005fb17a3e531bd2d7ed..df6510afbf087b6fb471e901e308d66f5199a887 100644 (file)
@@ -16,7 +16,7 @@ IN: smtp.tests
 [ { "hello" "." "world" } validate-message ] must-fail
 
 [ "aGVsbG8Kd29ybGQ=\r\n.\r\n" ] [
-    "hello\nworld" [ send-body ] with-string-writer
+    T{ email { body "hello\nworld" } } [ send-body ] with-string-writer
 ] unit-test
 
 [ { "500 syntax error" } <response> check-response ]
@@ -51,7 +51,7 @@ IN: smtp.tests
 [
     {
         { "Content-Transfer-Encoding" "base64" }
-        { "Content-Type" "Text/plain; charset=utf-8" }
+        { "Content-Type" "text/plain; charset=UTF-8" }
         { "From" "Doug <erg@factorcode.org>" }
         { "MIME-Version" "1.0" }
         { "Subject" "Factor rules" }
index 03b9d8af11d67a69631b38568fcb96fa5d887dfd..bfba9ea28a2e407922bd77d41799c71dc53ea921 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2007, 2008 Elie CHAFTARI, Dirk Vleugels,
-! Slava Pestov, Doug Coleman.
+! Slava Pestov, Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays namespaces make io io.encodings.string
-io.encodings.utf8 io.timeouts io.sockets io.sockets.secure
-io.encodings.ascii kernel logging sequences combinators
-splitting assocs strings math.order math.parser random system
-calendar summary calendar.format accessors sets hashtables
-base64 debugger classes prettyprint io.crlf ;
+USING: arrays namespaces make io io.encodings.string io.encodings.utf8
+io.encodings.iana io.timeouts io.sockets io.sockets.secure
+io.encodings.ascii kernel logging sequences combinators splitting
+assocs strings math.order math.parser random system calendar summary
+calendar.format accessors sets hashtables base64 debugger classes
+prettyprint io.crlf words ;
 IN: smtp
 
 SYMBOL: smtp-domain
@@ -44,6 +44,8 @@ TUPLE: email
     { cc array }
     { bcc array }
     { subject string }
+    { content-type string initial: "text/plain" }
+    { encoding word initial: utf8 }
     { body string } ;
 
 : <email> ( -- email ) email new ; inline
@@ -85,8 +87,8 @@ M: message-contains-dot summary ( obj -- string )
     "." over member?
     [ message-contains-dot ] when ;
 
-: send-body ( body -- )
-    utf8 encode
+: send-body ( email -- )
+    [ body>> ] [ encoding>> ] bi encode
     >base64-lines write crlf
     "." command ;
 
@@ -162,9 +164,8 @@ M: plain-auth send-auth
 
 : encode-header ( string -- string' )
     dup aux>> [
-        "=?utf-8?B?"
-        swap utf8 encode >base64
-        "?=" 3append
+        utf8 encode >base64
+        "=?utf-8?B?" "?=" surround
     ] when ;
 
 ERROR: invalid-header-string string ;
@@ -195,24 +196,23 @@ ERROR: invalid-header-string string ;
     ! This could be much smarter.
     " " split1-last swap or "<" ?head drop ">" ?tail drop ;
 
-: utf8-mime-header ( -- alist )
-    {
-        { "MIME-Version" "1.0" }
-        { "Content-Transfer-Encoding" "base64" }
-        { "Content-Type" "Text/plain; charset=utf-8" }
-    } ;
+: email-content-type ( email -- content-type )
+    [ content-type>> ] [ encoding>> encoding>name ] bi "; charset=" glue ;
 
-: email>headers ( email -- hashtable )
+: email>headers ( email -- assoc )
     [
+        now timestamp>rfc822 "Date" set
+        message-id "Message-Id" set
+        "1.0" "MIME-Version" set
+        "base64" "Content-Transfer-Encoding" set
         {
             [ from>> "From" set ]
             [ to>> ", " join "To" set ]
             [ cc>> ", " join [ "Cc" set ] unless-empty ]
             [ subject>> "Subject" set ]
+            [ email-content-type "Content-Type" set ]
         } cleave
-        now timestamp>rfc822 "Date" set
-        message-id "Message-Id" set
-    ] { } make-assoc utf8-mime-header append ;
+    ] { } make-assoc ;
 
 : (send-email) ( headers email -- )
     [
@@ -227,7 +227,7 @@ ERROR: invalid-header-string string ;
         data get-ok
         swap write-headers
         crlf
-        body>> send-body get-ok
+        send-body get-ok
         quit get-ok
     ] with-smtp-connection ;
 
index cc89d497e78202b7349e121e214dd3ee4e255042..beb378d4bd8ee54eae769c566f40ece8dae64f02 100644 (file)
@@ -6,19 +6,21 @@ IN: sorting.slots
 
 HELP: compare-slots
 { $values
-     { "sort-specs" "a sequence of accessors ending with a comparator" }
-     { "<=>" { $link +lt+ } " " { $link +eq+ } " or " { $link +gt+ } }
+  { "obj1" object }
+  { "obj2" object }
+  { "sort-specs" "a sequence of accessors ending with a comparator" }
+  { "<=>" { $link +lt+ } " " { $link +eq+ } " or " { $link +gt+ } }
 }
 { $description "Compares two objects using a chain of intrinsic linear orders such that if two objects are " { $link +eq+ } ", then the next comparator is tried. The comparators are slot-name/comparator pairs." } ;
 
-HELP: sort-by-slots
+HELP: sort-by
 { $values
      { "seq" sequence } { "sort-specs" "a sequence of accessors ending with a comparator" }
-     { "sortedseq" sequence }
+     { "seq'" sequence }
 }
 { $description "Sorts a sequence of tuples by the sort-specs in " { $snippet "sort-spec" } ". A sort-spec is a sequence of slot accessors ending in a comparator." }
 { $examples
-    "Sort by slot c, then b descending:"
+    "Sort by slot a, then b descending:"
     { $example
         "USING: accessors math.order prettyprint sorting.slots ;"
         "IN: scratchpad"
@@ -27,32 +29,18 @@ HELP: sort-by-slots
         "    T{ sort-me f 2 3 } T{ sort-me f 3 2 }"
         "    T{ sort-me f 4 3 } T{ sort-me f 2 1 }"
         "}"
-        "{ { a>> <=> } { b>> >=< } } sort-by-slots ."
+        "{ { a>> <=> } { b>> >=< } } sort-by ."
         "{\n    T{ sort-me { a 2 } { b 3 } }\n    T{ sort-me { a 2 } { b 1 } }\n    T{ sort-me { a 3 } { b 2 } }\n    T{ sort-me { a 4 } { b 3 } }\n}"
     }
 } ;
 
-HELP: split-by-slots
-{ $values
-     { "accessor-seqs" "a sequence of sequences of tuple accessors" }
-     { "quot" quotation }
-}
-{ $description "Splits a sequence of tuples into a sequence of slices of tuples that have the same values in all slots in the accessor sequence. This word is only useful for splitting a sorted sequence, but is more efficient than partitioning in such a case." } ;
-
-HELP: sort-by
-{ $values
-    { "seq" sequence } { "sort-seq" "a sequence of comparators" }
-    { "sortedseq" sequence }
-}
-{ $description "Sorts a sequence by comparing elements by comparators, using subsequent comparators when there is a tie." } ;
-
 ARTICLE: "sorting.slots" "Sorting by slots"
 "The " { $vocab-link "sorting.slots" } " vocabulary can sort tuples by slot in ascending or descending order, using subsequent slots as tie-breakers." $nl
 "Comparing two objects by a sequence of slots:"
 { $subsection compare-slots }
 "Sorting a sequence of tuples by a slot/comparator pairs:"
-{ $subsection sort-by-slots }
-"Sorting a sequence by a sequence of comparators:"
-{ $subsection sort-by } ;
+{ $subsection sort-by }
+{ $subsection sort-keys-by }
+{ $subsection sort-values-by } ;
 
 ABOUT: "sorting.slots"
index 83900461c3dfbe0255c209edc71399b981ae3e30..5ebd4438fe94e9ab757be475b56d4a4a2e3a8f46 100644 (file)
@@ -24,7 +24,7 @@ TUPLE: tuple2 d ;
         T{ sort-test f 1 1 11 }
         T{ sort-test f 2 5 3 }
         T{ sort-test f 2 5 2 }
-    } { { a>> <=> } { b>> >=< } { c>> <=> } } sort-by-slots
+    } { { a>> <=> } { b>> >=< } { c>> <=> } } sort-by
 ] unit-test
 
 [
@@ -42,43 +42,14 @@ TUPLE: tuple2 d ;
         T{ sort-test f 1 1 11 }
         T{ sort-test f 2 5 3 }
         T{ sort-test f 2 5 2 }
-    } { { a>> human<=> } { b>> human>=< } { c>> <=> } } sort-by-slots
+    } { { a>> human<=> } { b>> human>=< } { c>> <=> } } sort-by
 ] unit-test
 
-[
-    {
-        {
-            T{ sort-test { a 1 } { b 1 } { c 10 } }
-            T{ sort-test { a 1 } { b 1 } { c 11 } }
-        }
-        { T{ sort-test { a 1 } { b 3 } { c 9 } } }
-        {
-            T{ sort-test { a 2 } { b 5 } { c 3 } }
-            T{ sort-test { a 2 } { b 5 } { c 2 } }
-        }
-    }
-] [
-    {
-        T{ sort-test f 1 3 9 }
-        T{ sort-test f 1 1 10 }
-        T{ sort-test f 1 1 11 }
-        T{ sort-test f 2 5 3 }
-        T{ sort-test f 2 5 2 }
-    }
-    { { a>> human<=> } { b>> <=> } } [ sort-by-slots ] keep
-    [ but-last-slice ] map split-by-slots [ >array ] map
-] unit-test
-
-: split-test ( seq -- seq' )
-    { { a>> } { b>> } } split-by-slots ;
-
-[ split-test ] must-infer
-
 [ { } ]
-[ { } { { a>> <=> } { b>> >=< } { c>> <=> } } sort-by-slots ] unit-test
+[ { } { { a>> <=> } { b>> >=< } { c>> <=> } } sort-by ] unit-test
 
 [ { } ]
-[ { } { } sort-by-slots ] unit-test
+[ { } { } sort-by ] unit-test
 
 [
     {
@@ -97,55 +68,7 @@ TUPLE: tuple2 d ;
         T{ sort-test f 6 f f T{ tuple2 f 3 } }
         T{ sort-test f 5 f f T{ tuple2 f 3 } }
         T{ sort-test f 6 f f T{ tuple2 f 2 } }
-    } { { tuple2>> d>> <=> } { a>> <=> } } sort-by-slots
-] unit-test
-
-[
-    {
-        {
-            T{ sort-test
-                { a 6 }
-                { tuple2 T{ tuple2 { d 1 } } }
-            }
-        }
-        {
-            T{ sort-test
-                { a 6 }
-                { tuple2 T{ tuple2 { d 2 } } }
-            }
-        }
-        {
-            T{ sort-test
-                { a 5 }
-                { tuple2 T{ tuple2 { d 3 } } }
-            }
-        }
-        {
-            T{ sort-test
-                { a 6 }
-                { tuple2 T{ tuple2 { d 3 } } }
-            }
-            T{ sort-test
-                { a 6 }
-                { tuple2 T{ tuple2 { d 3 } } }
-            }
-        }
-        {
-            T{ sort-test
-                { a 5 }
-                { tuple2 T{ tuple2 { d 4 } } }
-            }
-        }
-    }
-] [
-    {
-        T{ sort-test { a 6 } { tuple2 T{ tuple2 { d 1 } } } }
-        T{ sort-test { a 6 } { tuple2 T{ tuple2 { d 2 } } } }
-        T{ sort-test { a 5 } { tuple2 T{ tuple2 { d 3 } } } }
-        T{ sort-test { a 6 } { tuple2 T{ tuple2 { d 3 } } } }
-        T{ sort-test { a 6 } { tuple2 T{ tuple2 { d 3 } } } }
-        T{ sort-test { a 5 } { tuple2 T{ tuple2 { d 4 } } } }
-    } { { tuple2>> d>> } { a>> } } split-by-slots [ >array ] map
+    } { { tuple2>> d>> <=> } { a>> <=> } } sort-by
 ] unit-test
 
 
@@ -159,3 +82,15 @@ TUPLE: tuple2 d ;
     { { 3 2 1 } { 1 2 3 } { 1 3 2 } { 1 } }
     { length-test<=> <=> } sort-by
 ] unit-test
+
+[ { { 0 1 } { 1 2 } { 1 1 } { 3 2 } } ]
+[
+    { { 3 2 } { 1 2 } { 0 1 } { 1 1 } }
+    { length-test<=> <=> } sort-keys-by
+] unit-test
+
+[ { { 0 1 } { 1 1 } { 3 2 } { 1 2 } } ]
+[
+    { { 3 2 } { 1 2 } { 0 1 } { 1 1 } }
+    { length-test<=> <=> } sort-values-by
+] unit-test
index efec960c2749855d67a2a4ef86bc5b3e4c7b6d8c..e3b4bc88caea03974b29ce7d871834482790f61c 100644 (file)
@@ -1,45 +1,28 @@
 ! Copyright (C) 2009 Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit fry kernel macros math.order
-sequences words sorting sequences.deep assocs splitting.monotonic
-math ;
+USING: arrays fry kernel math.order sequences sorting ;
 IN: sorting.slots
 
-<PRIVATE
+: execute-comparator ( obj1 obj2 word -- <=>/f )
+    execute( obj1 obj2 -- <=> ) dup +eq+ eq? [ drop f ] when ;
 
-: short-circuit-comparator ( obj1 obj2 word --  comparator/? )
-    execute dup +eq+ eq? [ drop f ] when ; inline
+: execute-accessor ( obj1 obj2 word -- obj1' obj2' )
+    '[ _ execute( tuple -- value ) ] bi@ ;
 
-: slot-comparator ( seq -- quot )
-    [
-        but-last-slice
-        [ '[ [ _ execute ] bi@ ] ] map concat
-    ] [
-        peek
-        '[ @ _ short-circuit-comparator ]
-    ] bi ;
-
-PRIVATE>
-
-MACRO: compare-slots ( sort-specs -- <=> )
+: compare-slots ( obj1 obj2 sort-specs -- <=> )
     #! sort-spec: { accessors comparator }
-    [ slot-comparator ] map '[ _ 2|| +eq+ or ] ;
-
-MACRO: sort-by-slots ( sort-specs -- quot )
-    '[ [ _ compare-slots ] sort ] ;
-
-MACRO: compare-seq ( seq -- quot )
-    [ '[ _ short-circuit-comparator ] ] map '[ _ 2|| +eq+ or ] ;
+    [
+        dup array? [
+            unclip-last-slice
+            [ [ execute-accessor ] each ] dip
+        ] when execute-comparator
+    ] with with map-find drop +eq+ or ;
 
-MACRO: sort-by ( sort-seq -- quot )
-    '[ [ _ compare-seq ] sort ] ;
+: sort-by-with ( seq sort-specs quot -- seq' )
+    swap '[ _ bi@ _ compare-slots ] sort ; inline
 
-MACRO: sort-keys-by ( sort-seq -- quot )
-    '[ [ first ] bi@ _ compare-seq ] sort ;
+: sort-by ( seq sort-specs -- seq' ) [ ] sort-by-with ;
 
-MACRO: sort-values-by ( sort-seq -- quot )
-    '[ [ second ] bi@ _ compare-seq ] sort ;
+: sort-keys-by ( seq sort-seq -- seq' ) [ first ] sort-by-with ;
 
-MACRO: split-by-slots ( accessor-seqs -- quot )
-    [ [ '[ [ _ execute ] bi@ ] ] map concat [ = ] compose ] map
-    '[ [ _ 2&& ] slice monotonic-slice ] ;
+: sort-values-by ( seq sort-seq -- seq' ) [ second ] sort-by-with ;
index 07c26ad100f4490a19290245ab6eaadfba248570..156900f7270758bc17ad5efb19307e71a4392d79 100644 (file)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel generic sequences io words arrays summary effects
 continuations assocs accessors namespaces compiler.errors
-stack-checker.values stack-checker.recursive-state ;
+stack-checker.values stack-checker.recursive-state
+source-files.errors compiler.errors ;
 IN: stack-checker.errors
 
 : pretty-word ( word -- word' )
@@ -10,7 +11,7 @@ IN: stack-checker.errors
 
 TUPLE: inference-error error type word ;
 
-M: inference-error compiler-error-type type>> ;
+M: inference-error error-type type>> ;
 
 : (inference-error) ( ... class type -- * )
     [ boa ] dip
@@ -18,10 +19,10 @@ M: inference-error compiler-error-type type>> ;
     \ inference-error boa rethrow ; inline
 
 : inference-error ( ... class -- * )
-    +error+ (inference-error) ; inline
+    +compiler-error+ (inference-error) ; inline
 
 : inference-warning ( ... class -- * )
-    +warning+ (inference-error) ; inline
+    +compiler-warning+ (inference-error) ; inline
 
 TUPLE: literal-expected what ;
 
@@ -81,3 +82,8 @@ TUPLE: unknown-primitive-error ;
 
 : unknown-primitive-error ( -- * )
     \ unknown-primitive-error inference-warning ;
+
+TUPLE: transform-expansion-error word error ;
+
+: transform-expansion-error ( word error -- * )
+    \ transform-expansion-error inference-error ;
\ No newline at end of file
index 9dc82339b51d3074928f2045e4c6e11a559f7dff..d6cee8e08f4b0875f1990dcf078abdfccf5ecf7e 100644 (file)
@@ -1,19 +1,26 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel prettyprint io debugger
-sequences assocs stack-checker.errors summary effects ;
+sequences assocs stack-checker.errors summary effects make ;
 IN: stack-checker.errors.prettyprint
 
+M: inference-error summary error>> summary ;
+
 M: inference-error error-help error>> error-help ;
 
 M: inference-error error.
     [ word>> [ "In word: " write . ] when* ] [ error>> error. ] bi ;
 
-M: literal-expected error.
-    "Got a computed value where a " write what>> write " was expected" print ;
+M: literal-expected summary
+    [ "Got a computed value where a " % what>> % " was expected" % ] "" make ;
+
+M: literal-expected error. summary print ;
+
+M: unbalanced-branches-error summary
+    drop "Unbalanced branches" ;
 
 M: unbalanced-branches-error error.
-    "Unbalanced branches:" print
+    dup summary print
     [ quots>> ] [ branches>> [ length <effect> ] { } assoc>map ] bi zip
     [ [ first pprint-short bl ] [ second effect>string print ] bi ] each ;
 
@@ -25,16 +32,18 @@ M: too-many-r> summary
     drop
     "Quotation pops retain stack elements which it did not push" ;
 
-M: missing-effect error.
-    "The word " write
-    word>> pprint
-    " must declare a stack effect" print ;
+M: missing-effect summary
+    [
+        "The word " %
+        word>> name>> %
+        " must declare a stack effect" %
+    ] "" make ;
 
-M: effect-error error.
-    "Stack effects of the word " write
-    [ word>> pprint " do not match." print ]
-    [ "Inferred: " write inferred>> . ]
-    [ "Declared: " write declared>> . ] tri ;
+M: effect-error summary
+    [
+        "Stack effect declaration of the word " %
+        word>> name>> % " is wrong" %
+    ] "" make ;
 
 M: recursive-quotation-error error.
     "The quotation " write
@@ -42,26 +51,40 @@ M: recursive-quotation-error error.
     " calls itself." print
     "Stack effect inference is undecidable when quotation-level recursion is permitted." print ;
 
-M: undeclared-recursion-error error.
-    "The inline recursive word " write
-    word>> pprint
-    " must be declared recursive" print ;
+M: undeclared-recursion-error summary
+    drop
+    "Inline recursive words must be declared recursive" ;
 
-M: diverging-recursion-error error.
-    "The recursive word " write
-    word>> pprint
-    " digs arbitrarily deep into the stack" print ;
+M: diverging-recursion-error summary
+    [
+        "The recursive word " %
+        word>> name>> %
+        " digs arbitrarily deep into the stack" %
+    ] "" make ;
 
-M: unbalanced-recursion-error error.
-    "The recursive word " write
-    word>> pprint
-    " leaves with the stack having the wrong height" print ;
+M: unbalanced-recursion-error summary
+    [
+        "The recursive word " %
+        word>> name>> %
+        " leaves with the stack having the wrong height" %
+    ] "" make ;
 
-M: inconsistent-recursive-call-error error.
-    "The recursive word " write
-    word>> pprint
-    " calls itself with a different set of quotation parameters than were input" print ;
+M: inconsistent-recursive-call-error summary
+    [
+        "The recursive word " %
+        word>> name>> %
+        " calls itself with a different set of quotation parameters than were input" %
+    ] "" make ;
 
-M: unknown-primitive-error error.
+M: unknown-primitive-error summary
     drop
-    "Cannot determine stack effect statically" print ;
+    "Cannot determine stack effect statically" ;
+
+M: transform-expansion-error summary
+    drop
+    "Compiler transform threw an error" ;
+
+M: transform-expansion-error error.
+    [ summary print ]
+    [ "Word: " write word>> . nl ]
+    [ error>> error. ] tri ;
\ No newline at end of file
index c55e69a8a275fcda4af42d749345d63880cfad3d..ff7288202ab1abbf725ec8e891d61bba8970c103 100644 (file)
@@ -218,8 +218,7 @@ M: object infer-call*
     alien-callback
 } [ t "special" set-word-prop ] each
 
-{ call execute dispatch load-locals get-local drop-locals }
-[ t "no-compile" set-word-prop ] each
+\ clear t "no-compile" set-word-prop
 
 : non-inline-word ( word -- )
     dup called-dependency depends-on
index 117b6845b8847e683014a6eec4e2ce1e9965c206..6b9e9fd8b6cf583da6ec09140cada81e95672b4c 100644 (file)
@@ -524,7 +524,7 @@ ERROR: custom-error ;
 
 { 2 1 } [ [ + ] inference-invalidation-b ] must-infer-as
 
-[ ] [ "IN: stack-checker.tests : inference-invalidation-a ( -- a b ) 1 2 ;" eval ] unit-test
+[ ] [ "IN: stack-checker.tests : inference-invalidation-a ( -- a b ) 1 2 ;" eval( -- ) ] unit-test
 
 [ 3 ] [ inference-invalidation-c ] unit-test
 
@@ -536,7 +536,7 @@ M: object inference-invalidation-d inference-invalidation-c 2drop ;
 
 \ inference-invalidation-d must-infer
 
-[ ] [ "IN: stack-checker.tests : inference-invalidation-a ( -- ) ;" eval ] unit-test
+[ ] [ "IN: stack-checker.tests : inference-invalidation-a ( -- ) ;" eval( -- ) ] unit-test
 
 [ [ inference-invalidation-d ] infer ] must-fail
 
@@ -587,4 +587,4 @@ DEFER: eee'
 
 [ forget-test ] must-infer
 [ ] [ [ \ forget-test forget ] with-compilation-unit ] unit-test
-[ forget-test ] must-infer
\ No newline at end of file
+[ forget-test ] must-infer
index 0aa38769079edfbade031f4ba86f425561bf4d5f..abb1f2abdb575ce6f492dcf808ec6d25af1519f9 100644 (file)
@@ -1,6 +1,6 @@
 IN: stack-checker.transforms.tests
 USING: sequences stack-checker.transforms tools.test math kernel
-quotations stack-checker accessors combinators words arrays
+quotations stack-checker stack-checker.errors accessors combinators words arrays
 classes classes.tuple ;
 
 : compose-n-quot ( word n -- quot' ) <repetition> >quotation ;
@@ -70,4 +70,11 @@ DEFER: curry-folding-test ( quot -- )
 : member?-test ( a -- ? ) { 1 2 3 10 7 58 } member? ;
 
 [ f ] [ 1.0 member?-test ] unit-test
-[ t ] [ \ member?-test def>> first [ member?-test ] all? ] unit-test
\ No newline at end of file
+[ t ] [ \ member?-test def>> first [ member?-test ] all? ] unit-test
+
+! Macro expansion should throw its own type of error
+: bad-macro ( -- ) ;
+
+\ bad-macro [ "OOPS" throw ] 0 define-transform
+
+[ [ bad-macro ] infer ] [ inference-error? ] must-fail-with
\ No newline at end of file
index dfa46be7e2d5b19a92afb81f9a15446bb4ac49a3..fd62c4998da303168958a1a7ce3153b8e0558d2c 100755 (executable)
@@ -17,9 +17,14 @@ IN: stack-checker.transforms
         [ dup infer-word apply-word/effect ]
     } cond ;
 
+: call-transformer ( word stack quot -- newquot )
+    '[ _ _ with-datastack [ length 1 assert= ] [ first ] bi nip ]
+    [ transform-expansion-error ]
+    recover ;
+
 :: ((apply-transform)) ( word quot values stack rstate -- )
     rstate recursive-state
-    [ stack quot with-datastack first ] with-variable
+    [ word stack quot call-transformer ] with-variable
     [
         word inlined-dependency depends-on
         values [ length meta-d shorten-by ] [ #drop, ] bi
index adac84338d53552f2f3fbaee6a65a6a1b7edd56c..610a664c7b85f6542e6c3038051d0ee7bf20892f 100644 (file)
@@ -31,7 +31,7 @@ yield
 
 [ [ 3 throw ] "A" suspend ] [ 3 = ] must-fail-with
 
-:: spawn-namespace-test ( -- )
+:: spawn-namespace-test ( -- )
     [let | p [ <promise> ] g [ gensym ] |
         [
             g "x" set
index 9fa9d1e2aa1b317c401dbf762fe285eff76e91e2..bbd2ac2ca8c487c481b64b0771a14b2751976d53 100644 (file)
@@ -18,7 +18,7 @@ M: integer some-generic 1+ ;
 
 [ 4 ] [ 3 some-generic ] unit-test
 
-[ ] [ "IN: tools.annotations.tests USE: math M: integer some-generic 1- ;" eval ] unit-test
+[ ] [ "IN: tools.annotations.tests USE: math M: integer some-generic 1- ;" eval( -- ) ] unit-test
 
 [ 2 ] [ 3 some-generic ] unit-test
 
@@ -33,7 +33,7 @@ M: object another-generic ;
 
 \ another-generic watch
 
-[ ] [ "IN: tools.annotations.tests GENERIC: another-generic ( a -- b )" eval ] unit-test
+[ ] [ "IN: tools.annotations.tests GENERIC: another-generic ( a -- b )" eval( -- ) ] unit-test
 
 [ ] [ \ another-generic reset ] unit-test
 
index 64e6508ab62e34f45022872dbd1e638514b65667..2639d48be2c7a701e933991dded80d3d1a9145d5 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors kernel math sorting words parser io summary
 quotations sequences prettyprint continuations effects
 definitions compiler.units namespaces assocs tools.walker
-tools.time generic inspector fry ;
+tools.time generic inspector fry tools.continuations ;
 IN: tools.annotations
 
 GENERIC: reset ( word -- )
index 14cec8e85fc32db68027a4a874f1913774a27d43..99def097a25977126796ac2d3417f8fce55d9069 100644 (file)
@@ -3,20 +3,20 @@
 USING: accessors kernel arrays sequences math namespaces
 strings io fry vectors words assocs combinators sorting
 unicode.case unicode.categories math.order vocabs
-tools.vocabs unicode.data ;
+tools.vocabs unicode.data locals ;
 IN: tools.completion
 
-: (fuzzy) ( accum ch i full -- accum i ? )
-    index-from
-    [
-        [ swap push ] 2keep 1+ t
+:: (fuzzy) ( accum i full ch -- accum i full ? )
+    ch i full index-from [
+        :> i i accum push
+        accum i 1+ full t
     ] [
-        drop f -1 f
+        f -1 full f
     ] if* ;
 
 : fuzzy ( full short -- indices )
-    dup length <vector> -rot 0 -rot
-    [ -rot [ (fuzzy) ] keep swap ] all? 3drop ;
+    dup [ length <vector> 0 ] curry 2dip
+    [ (fuzzy) ] all? 3drop ;
 
 : (runs) ( runs n seq -- runs n )
     [
diff --git a/basis/tools/continuations/authors.txt b/basis/tools/continuations/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/tools/continuations/continuations.factor b/basis/tools/continuations/continuations.factor
new file mode 100644 (file)
index 0000000..3e28c59
--- /dev/null
@@ -0,0 +1,157 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: threads kernel namespaces continuations combinators
+sequences math namespaces.private continuations.private
+concurrency.messaging quotations kernel.private words
+sequences.private assocs models models.arrow arrays accessors
+generic generic.standard definitions make sbufs ;
+IN: tools.continuations
+
+<PRIVATE
+
+: after-break ( object -- )
+    {
+        { [ dup continuation? ] [ (continue) ] }
+        { [ dup not ] [ "Single stepping abandoned" rethrow ] }
+    } cond ;
+
+PRIVATE>
+
+SYMBOL: break-hook
+
+: break ( -- )
+    continuation callstack >>call
+    break-hook get call( continuation -- continuation' )
+    after-break ;
+
+\ break t "break?" set-word-prop
+
+GENERIC: add-breakpoint ( quot -- quot' )
+
+<PRIVATE
+
+M: callable add-breakpoint
+    dup [ break ] head? [ \ break prefix ] unless ;
+
+M: array add-breakpoint
+    [ add-breakpoint ] map ;
+
+M: object add-breakpoint ;
+
+: (step-into-quot) ( quot -- ) add-breakpoint call ;
+
+: (step-into-dip) ( quot -- ) add-breakpoint dip ;
+
+: (step-into-2dip) ( quot -- ) add-breakpoint 2dip ;
+
+: (step-into-3dip) ( quot -- ) add-breakpoint 3dip ;
+
+: (step-into-if) ( true false ? -- ) ? (step-into-quot) ;
+
+: (step-into-dispatch) ( array n -- ) nth (step-into-quot) ;
+
+: (step-into-execute) ( word -- )
+    {
+        { [ 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 uses \ suspend swap member? ] [ execute break ] }
+        { [ dup primitive? ] [ execute break ] }
+        [ def>> (step-into-quot) ]
+    } cond ;
+
+\ (step-into-execute) t "step-into?" set-word-prop
+
+: (step-into-continuation) ( -- )
+    continuation callstack >>call break ;
+
+: (step-into-call-next-method) ( method -- )
+    next-method-quot (step-into-quot) ;
+
+<< {
+    (step-into-quot)
+    (step-into-dip)
+    (step-into-2dip)
+    (step-into-3dip)
+    (step-into-if)
+    (step-into-dispatch)
+    (step-into-execute)
+    (step-into-continuation)
+    (step-into-call-next-method)
+} [ t "no-compile" set-word-prop ] each >>
+
+: change-frame ( continuation quot -- continuation' )
+    #! Applies quot to innermost call frame of the
+    #! continuation.
+    [ clone ] dip [
+        [ clone ] dip
+        [
+            [
+                [ innermost-frame-scan 1+ ]
+                [ innermost-frame-quot ] bi
+            ] dip call
+        ]
+        [ drop set-innermost-frame-quot ]
+        [ drop ]
+        2tri
+    ] curry change-call ; inline
+
+PRIVATE>
+
+: continuation-step ( continuation -- continuation' )
+    [
+        2dup length = [ nip [ break ] append ] [
+            2dup nth \ break = [ nip ] [
+                swap 1+ cut [ break ] glue 
+            ] if
+        ] if
+    ] change-frame ;
+
+: continuation-step-out ( continuation -- continuation' )
+    [ nip \ break suffix ] change-frame ;
+
+
+{
+    { call [ (step-into-quot) ] }
+    { dip [ (step-into-dip) ] }
+    { 2dip [ (step-into-2dip) ] }
+    { 3dip [ (step-into-3dip) ] }
+    { execute [ (step-into-execute) ] }
+    { if [ (step-into-if) ] }
+    { dispatch [ (step-into-dispatch) ] }
+    { continuation [ (step-into-continuation) ] }
+    { (call-next-method) [ (step-into-call-next-method) ] }
+} [ "step-into" set-word-prop ] assoc-each
+
+! Never step into these words
+: don't-step-into ( word -- )
+    dup [ execute break ] curry "step-into" set-word-prop ;
+
+{
+    >n ndrop >c c>
+    continue continue-with
+    stop suspend (spawn)
+} [ don't-step-into ] each
+
+\ break [ break ] "step-into" set-word-prop
+
+: continuation-step-into ( continuation -- continuation' )
+    [
+        swap cut [
+            swap %
+            [ \ break , ] [
+                unclip {
+                    { [ dup \ break eq? ] [ , ] }
+                    { [ dup quotation? ] [ add-breakpoint , \ break , ] }
+                    { [ dup array? ] [ add-breakpoint , \ break , ] }
+                    { [ dup word? ] [ literalize , \ (step-into-execute) , ] }
+                    [ , \ break , ]
+                } cond %
+            ] if-empty
+        ] [ ] make
+    ] change-frame ;
+
+: continuation-current ( continuation -- obj )
+    call>>
+    [ innermost-frame-scan 1+ ]
+    [ innermost-frame-quot ] bi ?nth ;
index 7c9a38796b5de053f56b9a0a3ba4c4f8c1bd64ff..37eec5eae2a4ce02d967394c30c62f15e00b1596 100755 (executable)
@@ -354,12 +354,10 @@ IN: tools.deploy.shaker
 
 : finish-deploy ( final-image -- )
     "Finishing up" show
-    [ { } set-datastack ] dip
-    { } set-retainstack
     V{ } set-namestack
     V{ } set-catchstack
     "Saving final image" show
-    [ save-image-and-exit ] call-clear ;
+    save-image-and-exit ;
 
 SYMBOL: deploy-vocab
 
@@ -376,9 +374,9 @@ SYMBOL: deploy-vocab
             [:c]
             [print-error]
             '[
-                [ _ execute ] [
-                    _ execute nl
-                    _ execute
+                [ _ execute( obj -- ) ] [
+                    _ execute( obj -- ) nl
+                    _ execute( obj -- )
                 ] recover
             ] %
         ] if
@@ -423,10 +421,10 @@ SYMBOL: deploy-vocab
 : deploy-error-handler ( quot -- )
     [
         strip-debugger?
-        [ error-continuation get call>> callstack>array die ]
+        [ error-continuation get call>> callstack>array die 1 exit ]
         ! Don't reference these words literally, if we're stripping the
         ! debugger out we don't want to load the prettyprinter at all
-        [ [:c] execute nl [print-error] execute flush ] if
+        [ [:c] execute( -- ) nl [print-error] execute( error -- ) flush ] if
         1 exit
     ] recover ; inline
 
index b4f862262752c82aede515fbc851dd4d3d812cd6..3310686f05c307abb2db64747fb6f27c97633cb5 100644 (file)
@@ -3,6 +3,6 @@
 USING: eval ;
 IN: tools.deploy.test.11
 
-: foo ( -- ) "USING: math prettyprint ; 2 2 + ." eval ;
+: foo ( -- ) "USING: math prettyprint ; 2 2 + ." eval( -- ) ;
 
 MAIN: foo
\ No newline at end of file
index a16e3c82c565bbc81bd31337556d3c8bcf1d708b..5d6816121d28074dc7901141d5eb1a9e7cdafd1f 100644 (file)
@@ -9,7 +9,7 @@ GENERIC: my-generic ( x -- b )
 
 M: integer my-generic sq ;
 
-M: fixnum my-generic call-next-method my-var get call ;
+M: fixnum my-generic call-next-method my-var get call( a -- b ) ;
 
 : test-7 ( -- )
     [ 1 + ] my-var set-global
diff --git a/basis/tools/errors/authors.txt b/basis/tools/errors/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/tools/errors/errors-docs.factor b/basis/tools/errors/errors-docs.factor
new file mode 100644 (file)
index 0000000..96b13b6
--- /dev/null
@@ -0,0 +1,49 @@
+IN: tools.errors
+USING: help.markup help.syntax source-files.errors words io
+compiler.errors ;
+
+ARTICLE: "compiler-errors" "Compiler warnings and errors"
+"After loading a vocabulary, you might see messages like:"
+{ $code
+    ":errors - print 2 compiler errors"
+    ":warnings - print 50 compiler warnings"
+}
+"These messages arise from the compiler's stack effect checker. Production code should not have any warnings and errors in it. Warning and error conditions are documented in " { $link "inference-errors" } "."
+$nl
+"Words to view warnings and errors:"
+{ $subsection :warnings }
+{ $subsection :errors }
+{ $subsection :linkage }
+"Compiler warnings and errors are reported using the " { $link "tools.errors" } " mechanism and are shown in the " { $link "ui.tools.error-list" } "." ;
+
+HELP: compiler-error
+{ $values { "error" "an error" } { "word" word } }
+{ $description "Saves the error for future persual via " { $link :errors } ", " { $link :warnings } " and " { $link :linkage } "." } ;
+
+HELP: :errors
+{ $description "Prints all serious compiler errors from the most recent compile to " { $link output-stream } "." } ;
+
+HELP: :warnings
+{ $description "Prints all ignorable compiler warnings from the most recent compile to " { $link output-stream } "." } ;
+
+HELP: :linkage
+{ $description "Prints all C library interface linkage errors from the most recent compile to " { $link output-stream } "." } ;
+
+{ :errors :warnings :linkage } related-words
+
+HELP: errors.
+{ $values { "errors" "a sequence of " { $link source-file-error } " instances" } }
+{ $description "Prints a list of errors, grouped by source file." } ;
+
+ARTICLE: "tools.errors" "Batch error reporting"
+"Some tools, such as the " { $link "compiler" } ", " { $link "tools.test" } " and " { $link "help.lint" } " need to report multiple errors at a time. Each error is associated with a source file, line number, and optionally, a definition. " { $link "errors" } " cannot be used for this purpose, so the " { $vocab-link "source-files.errors" } " vocabulary provides an alternative mechanism. Note that the words in this vocabulary are used for implementation only; to actually list errors, consult the documentation for the relevant tools."
+$nl
+"Source file errors inherit from a class:"
+{ $subsection source-file-error }
+"Printing an error summary:"
+{ $subsection error-summary }
+"Printing a list of errors:"
+{ $subsection errors. }
+"Batch errors are reported in the " { $link "ui.tools.error-list" } "." ;
+
+ABOUT: "tools.errors"
\ No newline at end of file
diff --git a/basis/tools/errors/errors.factor b/basis/tools/errors/errors.factor
new file mode 100644 (file)
index 0000000..0a28bde
--- /dev/null
@@ -0,0 +1,42 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs debugger io kernel sequences source-files.errors
+summary accessors continuations make math.parser io.styles namespaces
+compiler.errors ;
+IN: tools.errors
+
+#! Tools for source-files.errors. Used by tools.tests and others
+#! for error reporting
+
+M: source-file-error compute-restarts
+    error>> compute-restarts ;
+
+M: source-file-error error-help
+    error>> error-help ;
+
+M: source-file-error summary
+    [
+        [ file>> [ % ": " % ] [ "<Listener input>" % ] if* ]
+        [ line#>> [ # ] when* ] bi
+    ] "" make
+    ;
+
+M: source-file-error error.
+    [ summary print nl ] [ error>> error. ] bi ;
+
+: errors. ( errors -- )
+    group-by-source-file sort-errors
+    [
+        [ nl "==== " write print nl ]
+        [ [ nl ] [ error. ] interleave ]
+        bi*
+    ] assoc-each ;
+
+: compiler-errors. ( type -- )
+    errors-of-type values errors. ;
+
+: :errors ( -- ) +compiler-error+ compiler-errors. ;
+
+: :warnings ( -- ) +compiler-warning+ compiler-errors. ;
+
+: :linkage ( -- ) +linkage-error+ compiler-errors. ;
\ No newline at end of file
index 8d882099def92089f74227cfceeb87411f39b382..146a119a631ce0f745336c17d58e4f64662b4a08 100755 (executable)
@@ -75,7 +75,7 @@ M: object file-spec>string ( file-listing spec -- string )
 : list-files-slow ( listing-tool -- array )
     [ path>> ] [ sort>> ] [ specs>> ] tri '[
             [ dup name>> file-info file-listing boa ] map
-            _ [ sort-by-slots ] when*
+            _ [ sort-by ] when*
             [ _ [ file-spec>string ] with map ] map
     ] with-directory-entries ; inline
 
index 864a637096c0c75790b63ff4d57e74cb208fc96a..f4488136b2d7b32323acb884d07c07be762d7191 100644 (file)
@@ -7,7 +7,7 @@ continuations generic compiler.units sets classes fry ;
 IN: tools.profiler
 
 : profile ( quot -- )
-    [ t profiling call ] [ f profiling ] [ ] cleanup ;
+    [ t profiling call ] [ f profiling ] [ ] cleanup ; inline
 
 : filter-counts ( alist -- alist' )
     [ second 0 > ] filter ;
index 73e896d5ffbc2c63eea12ddd23f9770bb19f6952..f35da242663caa4e1b48557614c0dc6ab680b9c3 100755 (executable)
@@ -5,7 +5,8 @@ io.encodings.utf8 hashtables kernel namespaces sequences
 vocabs.loader io combinators calendar accessors math.parser
 io.streams.string ui.tools.operations quotations strings arrays
 prettyprint words vocabs sorting sets classes math alien urls
-splitting ascii combinators.short-circuit alarms words.symbol ;
+splitting ascii combinators.short-circuit alarms words.symbol
+system ;
 IN: tools.scaffold
 
 SYMBOL: developer-name
@@ -24,6 +25,9 @@ ERROR: no-vocab vocab ;
 
 : contains-separator? ( string -- ? ) [ path-separator? ] any? ;
 
+: ensure-vocab-exists ( string -- string )
+    dup vocabs member? [ no-vocab ] unless ;
+
 : check-vocab-name ( string -- string )
     [ ]
     [ contains-dot? [ vocab-name-contains-dot ] when ]
@@ -234,6 +238,7 @@ PRIVATE>
     [ (help.) ] [ nl vocabulary>> link-vocab ] bi ;
 
 : scaffold-help ( vocab -- )
+    ensure-vocab-exists
     [
         dup "-docs.factor" vocab/suffix>path scaffolding? [
             set-scaffold-docs-file
@@ -268,6 +273,7 @@ PRIVATE>
 PRIVATE>
 
 : scaffold-tests ( vocab -- )
+    ensure-vocab-exists
     dup "-tests.factor" vocab/suffix>path
     scaffolding? [
         set-scaffold-tests-file
@@ -296,8 +302,10 @@ SYMBOL: examples-flag
     [ home ] dip append-path
     [ touch-file ] [ "Click to edit: " write <pathname> . ] bi ;
 
-: scaffold-factor-boot-rc ( -- ) ".factor-boot-rc" scaffold-rc ;
+: scaffold-factor-boot-rc ( -- )
+    os windows? "factor-boot-rc" ".factor-boot-rc" ? scaffold-rc ;
 
-: scaffold-factor-rc ( -- ) ".factor-rc" scaffold-rc ;
+: scaffold-factor-rc ( -- )
+    os windows? "factor-rc" ".factor-rc" ? scaffold-rc ;
 
 : scaffold-emacs ( -- ) ".emacs" scaffold-rc ;
index 3cabff457f270a2258cfb302289859bb867a59cc..9122edcb67b2be3bb9ec57c441c5a1ff56396639 100644 (file)
@@ -3,33 +3,26 @@ IN: tools.test
 
 ARTICLE: "tools.test.write" "Writing unit tests"
 "Assert that a quotation outputs a specific set of values:"
-{ $subsection unit-test }
+{ $subsection POSTPONE: unit-test }
 "Assert that a quotation throws an error:"
-{ $subsection must-fail }
-{ $subsection must-fail-with }
+{ $subsection POSTPONE: must-fail }
+{ $subsection POSTPONE: must-fail-with }
 "Assert that a quotation or word has a specific static stack effect (see " { $link "inference" } "):"
-{ $subsection must-infer }
-{ $subsection must-infer-as } ;
+{ $subsection POSTPONE: must-infer }
+{ $subsection POSTPONE: must-infer-as }
+"All of the above are used like ordinary words but are actually parsing words. This ensures that parse-time state, namely the line number, can be associated with the test in question, and reported in test failures." ;
 
 ARTICLE: "tools.test.run" "Running unit tests"
 "The following words run test harness files; any test failures are collected and printed at the end:"
 { $subsection test }
-{ $subsection test-all } ;
-
-ARTICLE: "tools.test.failure" "Handling test failures"
-"Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Some tools inspect the test failures and takes some kind of action instead, for example, " { $vocab-link "mason" } "."
-$nl
-"The following words output an association list mapping vocabulary names to sequences of failures; a failure is an array having the shape " { $snippet "{ error test continuation }" } ", and the elements are as follows:"
-{ $list
-    { { $snippet "error" } " - the error thrown by the unit test" }
-    { { $snippet "test" } " - a pair " { $snippet "{ output input }" } " containing expected output and a unit test quotation which didn't produce this output" }
-    { { $snippet "continuation" } " - the traceback at the point of the error" }
-}
-"The following words run test harness files and output failures:"
-{ $subsection run-tests }
-{ $subsection run-all-tests }
+{ $subsection test-all }
 "The following word prints failures:"
-{ $subsection test-failures. } ;
+{ $subsection :test-failures }
+"Test failures are reported using the " { $link "tools.errors" } " mechanism and are shown in the " { $link "ui.tools.error-list" } "."
+$nl
+"Unit test failures are instances of a class, and are stored in a global variable:"
+{ $subsection test-failure }
+{ $subsection test-failures } ;
 
 ARTICLE: "tools.test" "Unit testing"
 "A unit test is a piece of code which starts with known input values, then compares the output of a word with an expected output, where the expected output is defined by the word's contract."
@@ -45,12 +38,12 @@ $nl
 $nl
 "If the test harness needs to define words, they should be placed in a vocabulary named " { $snippet { $emphasis "vocab" } ".tests" } " where " { $emphasis "vocab" } " is the vocab being tested."
 { $subsection "tools.test.write" }
-{ $subsection "tools.test.run" }
-{ $subsection "tools.test.failure" } ;
+{ $subsection "tools.test.run" } ;
 
 ABOUT: "tools.test"
 
 HELP: unit-test
+{ $syntax "[ output ] [ input ] unit-test" }
 { $values { "output" "a sequence of expected stack elements" } { "input" "a quotation run with an empty stack" } }
 { $description "Runs a quotation with an empty stack, comparing the resulting stack with " { $snippet "output" } ". Elements are compared using " { $link = } ". Throws an error if the expected stack does not match the resulting stack." } ;
 
@@ -78,17 +71,8 @@ HELP: test
 { $values { "prefix" "a vocabulary name" } }
 { $description "Runs unit tests for the vocabulary named " { $snippet "prefix" } " and all of its child vocabularies." } ;
 
-HELP: run-tests
-{ $values { "prefix" "a vocabulary name" } { "failures" "an association list of unit test failures" } }
-{ $description "Runs unit tests for the vocabulary named " { $snippet "prefix" } " and all of its child vocabularies. Outputs unit test failures as documented in " { $link "tools.test.failure" } "." } ;
-
 HELP: test-all
 { $description "Runs unit tests for all loaded vocabularies." } ;
 
-HELP: run-all-tests
-{ $values { "failures" "an association list of unit test failures" } }
-{ $description "Runs unit tests for all loaded vocabularies and outputs unit test failures as documented in " { $link "tools.test.failure" } "." } ;
-
-HELP: test-failures.
-{ $values { "assoc" "an association list of unit test failures" } }
-{ $description "Prints unit test failures output by " { $link run-tests } " or " { $link run-all-tests } " to " { $link output-stream } "." } ;
+HELP: :test-failures
+{ $description "Prints all pending unit test failures." } ;
index c6dea08d181556e9051b3dd3a310daa763b6b681..b98f58b1430e5b09b35829780de6058a42584831 100644 (file)
-! Copyright (C) 2003, 2008 Slava Pestov.
+! Copyright (C) 2003, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors namespaces arrays prettyprint sequences kernel
-vectors quotations words parser assocs combinators continuations
-debugger io io.styles io.files vocabs vocabs.loader source-files
-compiler.units summary stack-checker effects tools.vocabs fry ;
+USING: accessors arrays assocs combinators compiler.units
+continuations debugger effects fry generalizations io io.files
+io.styles kernel lexer locals macros math.parser namespaces
+parser prettyprint quotations sequences source-files splitting
+stack-checker summary unicode.case vectors vocabs vocabs.loader words
+tools.vocabs tools.errors source-files.errors io.streams.string make
+compiler.errors ;
 IN: tools.test
 
-SYMBOL: failures
+TUPLE: test-failure < source-file-error continuation ;
 
-: <failure> ( error what -- triple )
-    error-continuation get 3array ;
+SYMBOL: +test-failure+
 
-: failure ( error what -- )
+M: test-failure error-type drop +test-failure+ ;
+
+SYMBOL: test-failures
+
+test-failures [ V{ } clone ] initialize
+
+T{ error-type
+   { type +test-failure+ }
+   { word ":test-failures" }
+   { plural "unit test failures" }
+   { icon "vocab:ui/tools/error-list/icons/unit-test-error.tiff" }
+   { quot [ test-failures get ] }
+} define-error-type
+
+<PRIVATE
+
+: <test-failure> ( error experiment file line# -- triple )
+    test-failure new
+        swap >>line#
+        swap >>file
+        swap >>asset
+        swap >>error
+        error-continuation get >>continuation ;
+
+: failure ( error experiment file line# -- )
     "--> test failed!" print
-    <failure> failures get push ;
+    <test-failure> test-failures get push
+    notify-error-observers ;
 
-SYMBOL: this-test
+SYMBOL: file
 
-: (unit-test) ( what quot -- )
-    swap dup . flush this-test set
-    failures get [
-        [ this-test get failure ] recover
-    ] [
-        call
-    ] if ; inline
+: file-failure ( error -- )
+    f file get f failure ;
 
-: unit-test ( output input -- )
-    [ 2array ] 2keep '[
-        _ { } _ with-datastack swap >array assert=
-    ] (unit-test) ;
+:: (unit-test) ( output input -- error ? )
+    [ { } input with-datastack output assert-sequence= f f ] [ t ] recover ; inline
 
 : short-effect ( effect -- pair )
     [ in>> length ] [ out>> length ] bi 2array ;
 
-: must-infer-as ( effect quot -- )
-    [ 1quotation ] dip '[ _ infer short-effect ] unit-test ;
+:: (must-infer-as) ( effect quot -- error ? )
+    [ quot infer short-effect effect assert= f f ] [ t ] recover ; inline
+
+:: (must-infer) ( word/quot -- error ? )
+    word/quot dup word? [ '[ _ execute ] ] when :> quot
+    [ quot infer drop f f ] [ t ] recover ; inline
+
+TUPLE: did-not-fail ;
+CONSTANT: did-not-fail T{ did-not-fail }
+
+M: did-not-fail summary drop "Did not fail" ;
+
+:: (must-fail-with) ( quot pred -- error ? )
+    [ quot call did-not-fail t ]
+    [ dup pred call [ drop f f ] [ t ] if ] recover ; inline
+
+:: (must-fail) ( quot -- error ? )
+    [ quot call did-not-fail t ] [ drop f f ] recover ; inline
 
-: must-infer ( word/quot -- )
-    dup word? [ 1quotation ] when
-    '[ _ infer drop ] [ ] swap unit-test ;
+: experiment-title ( word -- string )
+    "(" ?head drop ")" ?tail drop { { CHAR: - CHAR: \s } } substitute >title ;
 
-: must-fail-with ( quot pred -- )
-    [ '[ @ f ] ] dip '[ _ _ recover ] [ t ] swap unit-test ;
+MACRO: <experiment> ( word -- )
+    [ stack-effect in>> length dup ]
+    [ name>> experiment-title ] bi
+    '[ _ ndup _ narray _ prefix ] ;
 
-: must-fail ( quot -- )
-    [ drop t ] must-fail-with ;
+: experiment. ( seq -- )
+    [ first write ": " write ] [ rest . ] bi ;
 
-: (run-test) ( vocab -- )
+:: experiment ( word: ( -- error ? ) line# -- )
+    word <experiment> :> e
+    e experiment.
+    word execute [
+        file get [
+            e file get line# failure
+        ] [ rethrow ] if
+    ] [ drop ] if ; inline
+
+: parse-test ( accum word -- accum )
+    literalize parsed
+    lexer get line>> parsed
+    \ experiment parsed ; inline
+
+<<
+
+SYNTAX: TEST:
+    scan
+    [ create-in ]
+    [ "(" ")" surround search '[ _ parse-test ] ] bi
+    define-syntax ;
+
+>>
+
+: run-test-file ( path -- )
+    dup file [
+        test-failures get file get +test-failure+ delete-file-errors
+        '[ _ run-file ] [ file-failure ] recover
+    ] with-variable ;
+
+: run-vocab-tests ( vocab -- )
     dup vocab source-loaded?>> [
-        vocab-tests [ run-file ] each
+        vocab-tests [ run-test-file ] each
     ] [ drop ] if ;
 
-: run-test ( vocab -- failures )
-    V{ } clone [
-        failures [
-            [ (run-test) ] [ swap failure ] recover
-        ] with-variable
-    ] keep ;
-
-: failure. ( triple -- )
-    dup second .
-    dup first print-error
-    "Traceback" swap third write-object ;
-
-: test-failures. ( assoc -- )
-    [
-        nl
-        [
-            "==== ALL TESTS PASSED" print
-        ] [
-            "==== FAILING TESTS:" print
-            [
-                swap vocab-heading.
-                [ failure. nl ] each
-            ] assoc-each
-        ] if-empty
-    ] [
-        "==== NOTHING TO TEST" print
-    ] if* ;
-
-: run-tests ( prefix -- failures )
-    child-vocabs [ f ] [
-        [ dup run-test ] { } map>assoc
-        [ second empty? not ] filter
-    ] if-empty ;
+: traceback-button. ( failure -- )
+    "[" write [ "Traceback" ] dip continuation>> write-object "]" print ;
 
-: test ( prefix -- )
-    run-tests test-failures. ;
+PRIVATE>
+
+TEST: unit-test
+TEST: must-infer-as
+TEST: must-infer
+TEST: must-fail-with
+TEST: must-fail
+
+M: test-failure error. ( error -- )
+    {
+        [ summary print nl ]
+        [ asset>> [ experiment. nl ] when* ]
+        [ error>> error. ]
+        [ traceback-button. ]
+    } cleave ;
 
-: run-all-tests ( -- failures )
-    "" run-tests ;
+: :test-failures ( -- ) test-failures get errors. ;
+
+: test ( prefix -- )
+    child-vocabs [ run-vocab-tests ] each ;
 
-: test-all ( -- )
-    run-all-tests test-failures. ;
+: test-all ( -- ) "" test ;
diff --git a/basis/tools/trace/authors.txt b/basis/tools/trace/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/tools/trace/trace-tests.factor b/basis/tools/trace/trace-tests.factor
new file mode 100644 (file)
index 0000000..74f7c40
--- /dev/null
@@ -0,0 +1,4 @@
+IN: tools.trace.tests
+USING: tools.trace tools.test sequences ;
+
+[ { 3 2 1 } ] [ { 1 2 3 } [ reverse ] trace ] unit-test
\ No newline at end of file
diff --git a/basis/tools/trace/trace.factor b/basis/tools/trace/trace.factor
new file mode 100644 (file)
index 0000000..e2c6bf8
--- /dev/null
@@ -0,0 +1,83 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: concurrency.promises models tools.continuations kernel
+sequences concurrency.messaging locals continuations threads
+namespaces namespaces.private make assocs accessors io strings
+prettyprint math math.parser words effects summary io.styles classes
+generic.math combinators.short-circuit ;
+IN: tools.trace
+
+: callstack-depth ( callstack -- n )
+    callstack>array length 2/ ;
+
+SYMBOL: end
+
+SYMBOL: exclude-vocabs
+SYMBOL: include-vocabs
+
+exclude-vocabs { "math" "accessors" } swap set-global
+
+: include? ( vocab -- ? )
+    include-vocabs get dup [ member? ] [ 2drop t ] if ;
+
+: exclude? ( vocab -- ? )
+    exclude-vocabs get dup [ member? ] [ 2drop f ] if ;
+
+: into? ( obj -- ? )
+    {
+        [ word? ]
+        [ predicate? not ]
+        [ math-generic? not ]
+        [
+            {
+                [ inline? ]
+                [
+                    {
+                        [ vocabulary>> include? ]
+                        [ vocabulary>> exclude? not ]
+                    } 1&&
+                ]
+            } 1||
+        ]
+    } 1&& ;
+
+TUPLE: trace-step word inputs ;
+
+M: trace-step summary
+    [
+        [ "Word: " % word>> name>> % ]
+        [ " -- inputs: " % inputs>> unparse-short % ] bi
+    ] "" make ;
+
+: <trace-step> ( continuation word -- trace-step )
+    [ nip ] [ [ data>> ] [ stack-effect in>> length ] bi* short tail* ] 2bi
+    \ trace-step boa ;
+
+: print-step ( continuation -- )
+    dup continuation-current dup word? [
+        [ nip name>> ] [ <trace-step> ] 2bi write-object nl
+    ] [
+        nip short.
+    ] if ;
+
+: print-depth ( continuation -- )
+    call>> callstack-depth
+    [ CHAR: \s <string> write ]
+    [ number>string write ": " write ] bi ;
+
+: trace-step ( continuation -- continuation' )
+    dup continuation-current end eq? [
+        [ print-depth ]
+        [ print-step ]
+        [
+            dup continuation-current into?
+            [ continuation-step-into ] [ continuation-step ] if
+        ] tri
+    ] unless ;
+
+: trace ( quot -- data )
+    [ [ trace-step ] break-hook ] dip
+    [ break ] [ end drop ] surround
+    with-variable ;
+
+<< \ trace t "no-compile" set-word-prop >>
\ No newline at end of file
index 6167a5be233fe5a42884d8d667c9be52563e1e45..66618ee23c5e1abd39a56246f736fa4d23feab1f 100644 (file)
@@ -78,7 +78,7 @@ SYMBOL: failures
             recover\r
         ] each\r
         failures get\r
-    ] with-compiler-errors ;\r
+    ] with-scope ;\r
 \r
 : source-modified? ( path -- ? )\r
     dup source-files get at [\r
index f2155ec125c9be8171f61a443618a5ca5a85dd37..80113607d42c44349ddd35607d737130f8ec8273 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: concurrency.promises models tools.walker kernel
-sequences concurrency.messaging locals continuations
-threads namespaces namespaces.private assocs accessors ;
+USING: concurrency.promises models tools.walker tools.continuations
+kernel sequences concurrency.messaging locals continuations threads
+namespaces namespaces.private assocs accessors ;
 IN: tools.walker.debug
 
 :: test-walker ( quot -- data )
index 3a5877c2861c5095f91cec26ff457612a4e2afef..6dabb73e30a0e9d0349259862fede157f168be3e 100644 (file)
@@ -1,7 +1,8 @@
 USING: tools.walker io io.streams.string kernel math
 math.private namespaces prettyprint sequences tools.test
 continuations math.parser threads arrays tools.walker.debug
-generic.standard sequences.private kernel.private ;
+generic.standard sequences.private kernel.private
+tools.continuations accessors words ;
 IN: tools.walker.tests
 
 [ { } ] [
@@ -112,3 +113,22 @@ IN: tools.walker.tests
 [ { } ] [
     [ "a" "b" set "c" "d" set [ ] test-walker ] with-scope
 ] unit-test
+
+: breakpoint-test ( -- x ) break 1 2 + ;
+
+\ breakpoint-test don't-step-into
+
+[ f ] [ \ breakpoint-test optimized>> ] unit-test
+
+[ { 3 } ] [ [ breakpoint-test ] test-walker ] unit-test
+
+GENERIC: method-breakpoint-test ( x -- y )
+
+TUPLE: method-breakpoint-tuple ;
+
+M: method-breakpoint-tuple method-breakpoint-test break drop 1 2 + ;
+
+\ method-breakpoint-test don't-step-into
+
+[ { 3 } ]
+[ [ T{ method-breakpoint-tuple } method-breakpoint-test ] test-walker ] unit-test
\ No newline at end of file
index b4ace6b770aef27a1eea84532c21c05121a0977c..4208c4420f5257741b024db8285adff5b1318e5c 100644 (file)
@@ -1,10 +1,11 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: threads kernel namespaces continuations combinators
 sequences math namespaces.private continuations.private
 concurrency.messaging quotations kernel.private words
 sequences.private assocs models models.arrow arrays accessors
-generic generic.standard definitions make sbufs ;
+generic generic.standard definitions make sbufs
+tools.continuations parser ;
 IN: tools.walker
 
 SYMBOL: show-walker-hook ! ( status continuation thread -- )
@@ -31,66 +32,18 @@ DEFER: start-walker-thread
         2dup start-walker-thread
     ] if* ;
 
-: show-walker ( -- thread )
-    get-walker-thread
-    [ show-walker-hook get call ] keep ;
-
-: after-break ( object -- )
-    {
-        { [ dup continuation? ] [ (continue) ] }
-        { [ dup quotation? ] [ call ] }
-        { [ dup not ] [ "Single stepping abandoned" rethrow ] }
-    } cond ;
-
-: break ( -- )
-    continuation callstack >>call
-    show-walker send-synchronous
-    after-break ;
-
-\ break t "break?" set-word-prop
-
 : walk ( quot -- quot' )
     \ break prefix [ break rethrow ] recover ;
 
-GENERIC: add-breakpoint ( quot -- quot' )
-
-M: callable add-breakpoint
-    dup [ break ] head? [ \ break prefix ] unless ;
-
-M: array add-breakpoint
-    [ add-breakpoint ] map ;
-
-M: object add-breakpoint ;
-
-: (step-into-quot) ( quot -- ) add-breakpoint call ;
-
-: (step-into-dip) ( quot -- ) add-breakpoint dip ;
-
-: (step-into-2dip) ( quot -- ) add-breakpoint 2dip ;
-
-: (step-into-3dip) ( quot -- ) add-breakpoint 3dip ;
-
-: (step-into-if) ( true false ? -- ) ? (step-into-quot) ;
-
-: (step-into-dispatch) ( array n -- ) nth (step-into-quot) ;
-
-: (step-into-execute) ( word -- )
-    {
-        { [ 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 uses \ suspend swap member? ] [ execute break ] }
-        { [ dup primitive? ] [ execute break ] }
-        [ def>> (step-into-quot) ]
-    } cond ;
+<< \ walk t "no-compile" set-word-prop >>
 
-\ (step-into-execute) t "step-into?" set-word-prop
-
-: (step-into-continuation) ( -- )
-    continuation callstack >>call break ;
-
-: (step-into-call-next-method) ( method -- )
-    next-method-quot (step-into-quot) ;
+break-hook [
+    [
+        get-walker-thread
+        [ show-walker-hook get call ] keep
+        send-synchronous
+    ]
+] initialize
 
 ! Messages sent to walker thread
 SYMBOL: step
@@ -106,74 +59,6 @@ SYMBOL: +running+
 SYMBOL: +suspended+
 SYMBOL: +stopped+
 
-: change-frame ( continuation quot -- continuation' )
-    #! Applies quot to innermost call frame of the
-    #! continuation.
-    [ clone ] dip [
-        [ clone ] dip
-        [
-            [
-                [ innermost-frame-scan 1+ ]
-                [ innermost-frame-quot ] bi
-            ] dip call
-        ]
-        [ drop set-innermost-frame-quot ]
-        [ drop ]
-        2tri
-    ] curry change-call ; inline
-
-: step-msg ( continuation -- continuation' ) USE: io
-    [
-        2dup length = [ nip [ break ] append ] [
-            2dup nth \ break = [ nip ] [
-                swap 1+ cut [ break ] glue 
-            ] if
-        ] if
-    ] change-frame ;
-
-: step-out-msg ( continuation -- continuation' )
-    [ nip \ break suffix ] change-frame ;
-
-{
-    { call [ (step-into-quot) ] }
-    { dip [ (step-into-dip) ] }
-    { 2dip [ (step-into-2dip) ] }
-    { 3dip [ (step-into-3dip) ] }
-    { execute [ (step-into-execute) ] }
-    { if [ (step-into-if) ] }
-    { dispatch [ (step-into-dispatch) ] }
-    { continuation [ (step-into-continuation) ] }
-    { (call-next-method) [ (step-into-call-next-method) ] }
-} [ "step-into" set-word-prop ] assoc-each
-
-! Never step into these words
-{
-    >n ndrop >c c>
-    continue continue-with
-    stop suspend (spawn)
-} [
-    dup [ execute break ] curry
-    "step-into" set-word-prop
-] each
-
-\ break [ break ] "step-into" set-word-prop
-
-: step-into-msg ( continuation -- continuation' )
-    [
-        swap cut [
-            swap %
-            [ \ break , ] [
-                unclip {
-                    { [ dup \ break eq? ] [ , ] }
-                    { [ dup quotation? ] [ add-breakpoint , \ break , ] }
-                    { [ dup array? ] [ add-breakpoint , \ break , ] }
-                    { [ dup word? ] [ literalize , \ (step-into-execute) , ] }
-                    [ , \ break , ]
-                } cond %
-            ] if-empty
-        ] [ ] make
-    ] change-frame ;
-
 : status ( -- symbol )
     walker-status tget value>> ;
 
@@ -200,13 +85,13 @@ SYMBOL: +stopped+
                 { f [ +stopped+ set-status f ] }
                 [
                     [ walker-continuation tget set-model ]
-                    [ step-into-msg ] bi
+                    [ continuation-step-into ] bi
                 ]
             } case
         ] handle-synchronous
     ] while ;
 
-: step-back-msg ( continuation -- continuation' )
+: continuation-step-back ( continuation -- continuation' )
     walker-history tget
     [ pop* ]
     [ [ nip pop ] unless-empty ] bi ;
@@ -220,20 +105,20 @@ SYMBOL: +stopped+
             {
                 ! These are sent by the walker tool. We reply
                 ! and keep cycling.
-                { step [ step-msg keep-running ] }
-                { step-out [ step-out-msg keep-running ] }
-                { step-into [ step-into-msg keep-running ] }
+                { step [ continuation-step keep-running ] }
+                { step-out [ continuation-step-out keep-running ] }
+                { step-into [ continuation-step-into keep-running ] }
                 { step-all [ keep-running ] }
                 { step-into-all [ step-into-all-loop ] }
                 { abandon [ drop f keep-running ] }
                 ! Pass quotation to debugged thread
                 { call-in [ keep-running ] }
                 ! Pass previous continuation to debugged thread
-                { step-back [ step-back-msg ] }
+                { step-back [ continuation-step-back ] }
             } case f
         ] handle-synchronous
     ] while ;
-
 : walker-loop ( -- )
     +running+ set-status
     [ status +stopped+ eq? ] [
@@ -276,4 +161,4 @@ SYMBOL: +stopped+
 ! For convenience
 IN: syntax
 
-: B ( -- ) break ;
+SYNTAX: B \ break parsed ;
index 46ecc1a37f4db36812a48d74ec3624697a3d9d63..eb8823b10781803c1b40db4b0632b2266780ad38 100644 (file)
@@ -70,7 +70,7 @@ CLASS: {
 ! Service support; evaluate Factor code from other apps
 :: do-service ( pboard error quot -- )
     pboard error ?pasteboard-string
-    dup [ quot call ] when
+    dup [ quot call( string -- result/f ) ] when
     [ pboard set-pasteboard-string ] when* ;
 
 CLASS: {
index d4b29592976e4dc4c5e99710a8c71b62e370001f..fb78abe917bacc41710a3df294639cb34c792000 100755 (executable)
@@ -3,11 +3,11 @@
 USING: accessors alien alien.c-types arrays ui ui.private ui.gadgets
 ui.gadgets.private ui.gestures ui.backend ui.clipboards
 ui.gadgets.worlds ui.render ui.event-loop assocs kernel math
-namespaces opengl sequences strings x11.xlib x11.events x11.xim
-x11.glx x11.clipboard x11.constants x11.windows io.encodings.string
-io.encodings.ascii io.encodings.utf8 combinators command-line
-math.vectors classes.tuple opengl.gl threads math.rectangles
-environment ascii ;
+namespaces opengl sequences strings x11 x11.xlib x11.events x11.xim
+x11.glx x11.clipboard x11.constants x11.windows x11.io
+io.encodings.string io.encodings.ascii io.encodings.utf8 combinators
+command-line math.vectors classes.tuple opengl.gl threads
+math.rectangles environment ascii ;
 IN: ui.backend.x11
 
 SINGLETON: x11-ui-backend
@@ -196,7 +196,7 @@ M: world client-event
     QueuedAfterFlush events-queued 0 > [
         next-event dup
         None XFilterEvent 0 = [ drop wait-event ] unless
-    ] [ ui-wait wait-event ] if ;
+    ] [ wait-for-display wait-event ] if ;
 
 M: x11-ui-backend do-events
     wait-event dup XAnyEvent-window window dup
index e02c6188f5ccd1c0c284f8614ab564c4ba651c6c..f7f7a757f54b9224833c1990f852cd9b5dd963fb 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel locals math math.order math.vectors
+USING: arrays kernel locals math math.functions math.order math.vectors
 sequences ui.gadgets accessors combinators ;
 IN: ui.baseline-alignment
 
@@ -24,35 +24,47 @@ TUPLE: gadget-metrics height ascent descent cap-height ;
     [ dup [ 2dup - ] [ f ] if ] dip
     gadget-metrics boa ; inline
 
+: ?supremum ( seq -- n/f )
+    sift [ f ] [ supremum ] if-empty ;
+
 : max-ascent ( seq -- n )
-    0 [ ascent>> [ max ] when* ] reduce ; inline
+    [ ascent>> ] map ?supremum ;
 
 : max-cap-height ( seq -- n )
-    0 [ cap-height>> [ max ] when* ] reduce ; inline
+    [ cap-height>> ] map ?supremum ;
 
 : max-descent ( seq -- n )
-    0 [ descent>> [ max ] when* ] reduce ; inline
+    [ descent>> ] map ?supremum ;
 
 : max-text-height ( seq -- y )
-    0 [ [ height>> ] [ ascent>> ] bi [ max ] [ drop ] if ] reduce ;
+    [ ascent>> ] filter [ height>> ] map ?supremum ;
 
 : max-graphics-height ( seq -- y )
-    0 [ [ height>> ] [ ascent>> ] bi [ drop ] [ max ] if ] reduce ;
-
-: (align-baselines) ( y max leading -- y' ) [ swap - ] dip + ;
+    [ ascent>> not ] filter [ height>> ] map ?supremum 0 or ;
 
 :: combine-metrics ( graphics-height ascent descent cap-height -- ascent' descent' )
-    cap-height 2 / :> mid-line 
-    graphics-height 2 /
-    [ ascent mid-line - max mid-line + >integer ]
-    [ descent mid-line + max mid-line - >integer ] bi ;
+    ascent [
+        cap-height 2 / :> mid-line 
+        graphics-height 2 /
+        [ ascent mid-line - max mid-line + floor >integer ]
+        [ descent mid-line + max mid-line - ceiling >integer ] bi
+    ] [ f f ] if ;
+
+: (measure-metrics) ( children sizes -- graphics-height ascent descent cap-height )
+    [ <gadget-metrics> ] 2map
+    {
+        [ max-graphics-height ]
+        [ max-ascent ]
+        [ max-descent ]
+        [ max-cap-height ]
+    } cleave ;
 
 PRIVATE>
 
 :: align-baselines ( gadgets -- ys )
     gadgets [ dup pref-dim <gadget-metrics> ] map
-    dup max-ascent :> max-ascent
-    dup max-cap-height :> max-cap-height
+    dup max-ascent 0 or :> max-ascent
+    dup max-cap-height 0 or :> max-cap-height
     dup max-graphics-height :> max-graphics-height
     
     max-cap-height max-graphics-height + 2 /i :> critical-line
@@ -61,20 +73,12 @@ PRIVATE>
 
     [
         dup ascent>>
-        [ ascent>> max-ascent text-leading ]
-        [ height>> max-graphics-height graphics-leading ] if
-        (align-baselines)
+        [ ascent>> max-ascent swap - text-leading ]
+        [ height>> max-graphics-height swap - 2/ graphics-leading ] if +
     ] map ;
 
 : measure-metrics ( children sizes -- ascent descent )
-    [ <gadget-metrics> ] 2map
-    {
-        [ max-graphics-height ]
-        [ max-ascent ]
-        [ max-descent ]
-        [ max-cap-height ]
-    } cleave
-    combine-metrics ;
+    (measure-metrics) combine-metrics ;
 
 : measure-height ( children sizes -- height )
-    measure-metrics + ;
\ No newline at end of file
+    (measure-metrics) dup [ combine-metrics + ] [ 3drop ] if ;
\ No newline at end of file
index bc07006d623d8c5efffb4a531b41c105b23cdd0f..32d6c0c8a65cd7d1f9ed5cc082f5a0b452726ab6 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors arrays hashtables kernel models math namespaces
 make sequences quotations math.vectors combinators sorting
 binary-search vectors dlists deques models threads
-concurrency.flags math.order math.rectangles fry ;
+concurrency.flags math.order math.rectangles fry locals ;
 IN: ui.gadgets
 
 ! Values for orientation slot
@@ -66,8 +66,8 @@ M: gadget children-on nip children>> ;
 : ((fast-children-on)) ( gadget dim axis -- <=> )
     [ swap loc>> v- ] dip v. 0 <=> ;
 
-: (fast-children-on) ( dim axis children -- i )
-    -rot '[ _ _ ((fast-children-on)) ] search drop ;
+:: (fast-children-on) ( dim axis children -- i )
+    children [ dim axis ((fast-children-on)) ] search drop ;
 
 PRIVATE>
 
index ddadb6b99edce0e53cce10ce9d32eb185160086b..123f7a540dcc7253566dafb964902563ee57feb2 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors ui.images ui.pens
-ui.pens.image ui.gadgets ;
+ui.pens.image ui.gadgets ui.gadgets.labels ;
 IN: ui.gadgets.icons
 
 TUPLE: icon < gadget ;
@@ -9,4 +9,6 @@ TUPLE: icon < gadget ;
 : <icon> ( image-name -- icon )
     icon new swap <image-pen> t >>fill? >>interior ;
 
-M: icon pref-dim* dup interior>> pen-pref-dim ;
\ No newline at end of file
+M: icon pref-dim* dup interior>> pen-pref-dim ;
+
+M: image-name >label <icon> ;
\ No newline at end of file
index cae7d12dc3feae0396edfaafcae67ecb2859de3f..b49f46c05a9e4429533f9a0c4cc8fdcd45f9f743 100644 (file)
@@ -90,4 +90,50 @@ IN: ui.gadgets.packs.tests
 
 [ ] [ "g" get prefer ] unit-test
 
-[ ] [ "g" get layout ] unit-test
\ No newline at end of file
+[ ] [ "g" get layout ] unit-test
+
+! Baseline alignment without any text gadgets should behave like align=1/2
+<shelf> +baseline+ >>align
+    <gadget> { 30 30 } >>dim add-gadget
+    <gadget> { 30 20 } >>dim add-gadget
+"g" set
+
+[ { 60 30 } ] [ "g" get pref-dim ] unit-test
+
+[ ] [ "g" get prefer ] unit-test
+
+[ ] [ "g" get layout ] unit-test
+
+[ V{ { 0 0 } { 30 5 } } ]
+[ "g" get children>> [ loc>> ] map ] unit-test
+
+<shelf> +baseline+ >>align
+<gadget> { 30 30 } >>dim add-gadget
+10 10 { 10 10 } <baseline-gadget> add-gadget
+"g" set
+
+[ ] [ "g" get prefer ] unit-test
+
+[ ] [ "g" get layout ] unit-test
+
+[ V{ { 0 0 } { 30 10 } } ]
+[ "g" get children>> [ loc>> ] map ] unit-test
+
+<shelf> +baseline+ >>align
+<shelf> <gadget> { 30 30 } >>dim add-gadget add-gadget
+10 10 { 10 10 } <baseline-gadget> add-gadget
+"g" set
+
+[ ] [ "g" get prefer ] unit-test
+
+[ ] [ "g" get layout ] unit-test
+
+[ V{ { 0 0 } { 30 10 } } ]
+[ "g" get children>> [ loc>> ] map ] unit-test
+
+<shelf> +baseline+ >>align
+<gadget> { 24 24 } >>dim add-gadget
+12 9 { 15 15 } <baseline-gadget> add-gadget
+"g" set
+
+[ { 39 24 } ] [ "g" get pref-dim ] unit-test
\ No newline at end of file
index 95f04dfe4dc13c1f29c8839a6e7848503fa52aa8..f47b374aeb30aad2559ff958d63b5bc92ef12866 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences ui.gadgets ui.baseline-alignment kernel math
-math.functions math.vectors math.order math.rectangles namespaces
-accessors fry combinators arrays ;
+USING: sequences ui.gadgets ui.baseline-alignment
+ui.baseline-alignment.private kernel math math.functions math.vectors
+math.order math.rectangles namespaces accessors fry combinators arrays ;
 IN: ui.gadgets.packs
 
 TUPLE: pack < gadget
@@ -84,8 +84,7 @@ M: pack pref-dim*
     children>> dup pref-dims measure-metrics drop ;
 
 : pack-cap-height ( pack -- n )
-    children>> [ cap-height ] map sift
-    [ f ] [ supremum ] if-empty ;
+    children>> [ cap-height ] map ?supremum ;
 
 PRIVATE>
 
index 0529437a76663c1d6edbb7c5877d4fcc3d39e615..01abe8b3d958c0175ee1f81b2a7be511fc65a917 100644 (file)
@@ -2,7 +2,7 @@ USING: alien ui.gadgets.panes ui.gadgets namespaces
 kernel sequences io io.styles io.streams.string tools.test
 prettyprint definitions help help.syntax help.markup
 help.stylesheet splitting ui.gadgets.debug models math summary
-inspector accessors help.topics see ;
+inspector accessors help.topics see fry ;
 IN: ui.gadgets.panes.tests
 
 : #children ( -- n ) "pane" get children>> length ;
@@ -18,8 +18,9 @@ IN: ui.gadgets.panes.tests
 [ t ] [ #children "num-children" get = ] unit-test
 
 : test-gadget-text ( quot -- ? )
-    dup make-pane gadget-text dup print "======" print
-    swap with-string-writer dup print = ;
+    '[ _ call( -- ) ]
+    [ make-pane gadget-text dup print "======" print ]
+    [ with-string-writer dup print ] bi = ;
 
 [ t ] [ [ "hello" write ] test-gadget-text ] unit-test
 [ t ] [ [ "hello" pprint ] test-gadget-text ] unit-test
index fcc121e584068186b53e5a71364ef20acc23299c..c8494216b40a271c4de452c780eca03f4d7c8338 100644 (file)
@@ -27,7 +27,7 @@ INSTANCE: fake-break word-break
 
 [ { 0 0 } ] [ "a" get loc>> ] unit-test
 
-[ { 45 15 } ] [ "b" get loc>> ] unit-test
+[ { 45 7 } ] [ "b" get loc>> ] unit-test
 
 [ { 0 30 } ] [ "c" get loc>> ] unit-test
 
index 621e7006c91fdac4dfe5fbc7492ce1f7cb5543b0..a0799c7b86e2d9e3e2577b060f8f3a4b088c022f 100644 (file)
@@ -10,7 +10,7 @@ IN: ui.gadgets.presentations
 TUPLE: presentation < button object hook ;
 
 : invoke-presentation ( presentation command -- )
-    [ [ dup hook>> call ] [ object>> ] bi ] dip
+    [ [ dup hook>> call( presentation -- ) ] [ object>> ] bi ] dip
     invoke-command ;
 
 : invoke-primary ( presentation -- )
index 17570a8714a805903c79f213533e0afa7a6da4be..fc564b6ffe9eabd8c644ef2e236489e591cab550 100644 (file)
@@ -74,7 +74,7 @@ CONSULT: table-protocol search-table table>> ;
         dup field>> { 2 2 } <filled-border> f track-add
         values search 500 milliseconds <delay> quot <string-search>
         renderer <table> f >>takes-focus? >>table
-        dup table>> <scroller> 1 track-add ;
+        dup table>> <scroller> 1 track-add ; inline
 
 M: search-table model-changed
     nip field>> clear-search-field ;
index 592900d0cbf6867141f511e1c41302f6341ca5cf..39e42aa723d7ffc1d79ce8ea440d84aefca641ef 100644 (file)
@@ -23,14 +23,14 @@ TUPLE: slot-editor < track ref close-hook update-hook text ;
 } define-command
 
 : close ( slot-editor -- )
-    dup close-hook>> call ;
+    dup close-hook>> call( slot-editor -- ) ;
 
 \ close H{
     { +description+ "Close the slot editor without saving changes." }
 } define-command
 
 : close-and-update ( slot-editor -- )
-    [ update-hook>> call ] [ close ] bi ;
+    [ update-hook>> call( -- ) ] [ close ] bi ;
 
 : slot-editor-value ( slot-editor -- object )
     text>> control-value parse-fresh first ;
@@ -44,11 +44,8 @@ TUPLE: slot-editor < track ref close-hook update-hook text ;
     { +description+ "Parse the object being edited, and store the result back into the edited slot." }
 } define-command
 
-: eval-1 ( string -- object )
-    1array [ eval ] with-datastack first ;
-
 : com-eval ( slot-editor -- )
-    [ [ text>> editor-string eval-1 ] [ ref>> ] bi set-ref ]
+    [ [ text>> editor-string eval( -- result ) ] [ ref>> ] bi set-ref ]
     [ close-and-update ]
     bi ;
 
index 77249149aee11e97986ee9b95d05e5791c765d40..3fe2156df0ee3e2673c781595fdf7d46a00b2bc7 100644 (file)
@@ -59,14 +59,19 @@ focused? ;
 
 GENERIC: cell-width ( font cell -- x )
 GENERIC: cell-height ( font cell -- y )
+GENERIC: cell-padding ( cell -- y )
 GENERIC: draw-cell ( font cell -- )
 
 M: string cell-width text-width ;
 M: string cell-height text-height ceiling ;
+M: string cell-padding drop 0 ;
 M: string draw-cell draw-text ;
 
+CONSTANT: image-padding 2
+
 M: image-name cell-width nip image-dim first ;
 M: image-name cell-height nip image-dim second ;
+M: image-name cell-padding drop image-padding ;
 M: image-name draw-cell nip draw-image ;
 
 : table-rows ( table -- rows )
@@ -87,7 +92,7 @@ CONSTANT: column-title-background COLOR: light-gray
     if ;
 
 : row-column-widths ( table row -- widths )
-    [ font>> ] dip [ cell-width ] with map ;
+    [ font>> ] dip [ [ cell-width ] [ cell-padding ] bi + ] with map ;
 
 : compute-total-width ( gap widths -- total )
     swap [ column-offsets drop ] keep - ;
@@ -162,9 +167,10 @@ M: table layout*
         '[ [ 0 2array ] [ _ 2array ] bi gl-line ] each
     ] bi ;
 
-: column-loc ( font column width align -- loc )
-    [ [ cell-width ] dip swap - ] dip
-    * >integer 0 2array ;
+:: column-loc ( font column width align -- loc )
+    font column cell-width width swap - align * column cell-padding 2 / 1 align - * +
+    font column cell-height \ line-height get swap - 2 /
+    [ >integer ] bi@ 2array ;
 
 : translate-column ( width gap -- )
     + 0 2array gl-translate ;
@@ -203,18 +209,21 @@ M: table draw-line ( row index table -- )
 
 M: table draw-gadget*
     dup control-value empty? [ drop ] [
-        {
-            [ draw-selected-row ]
-            [ draw-lines ]
-            [ draw-column-lines ]
-            [ draw-focused-row ]
-            [ draw-moused-row ]
-        } cleave
+        dup line-height \ line-height [
+            {
+                [ draw-selected-row ]
+                [ draw-lines ]
+                [ draw-column-lines ]
+                [ draw-focused-row ]
+                [ draw-moused-row ]
+            } cleave
+        ] with-variable
     ] if ;
 
 M: table line-height ( table -- y )
     [ font>> ] [ renderer>> prototype-row ] bi
-    [ cell-height ] with [ max ] map-reduce ;
+    [ [ cell-height ] [ cell-padding ] bi + ] with
+    [ max ] map-reduce ;
 
 M: table pref-dim*
     [ compute-column-widths drop ] keep
@@ -379,14 +388,16 @@ TUPLE: column-headers < gadget table ;
         column-title-background <solid> >>interior ;
 
 : draw-column-titles ( table -- )
-    {
-        [ renderer>> column-titles ]
-        [ column-widths>> ]
-        [ table-column-alignment ]
-        [ font>> column-title-font ]
-        [ gap>> ]
-    } cleave
-    draw-columns ;
+    dup font>> font-metrics height>> \ line-height [
+        {
+            [ renderer>> column-titles ]
+            [ column-widths>> ]
+            [ table-column-alignment ]
+            [ font>> column-title-font ]
+            [ gap>> ]
+        } cleave
+        draw-columns
+    ] with-variable ;
 
 M: column-headers draw-gadget*
     table>> draw-column-titles ;
index cfec6613b1427e97fcd9159778e3902e1beed5d7..4114a2c3b24c20a099022c85d4dff53b5a8c81cd 100644 (file)
@@ -4,7 +4,7 @@ ui.gestures ;
 IN: ui.operations
 
 : $operations ( element -- )
-    >quotation call
+    >quotation call( -- obj )
     f operations>commands
     command-map. ;
 
index 4ac2fbbaa86d2d038ac562d63dcc397ac501486c..c2732754f6bb9cbf381823e56c27e20a0a759ade 100644 (file)
@@ -46,7 +46,7 @@ HELP: offset>x
 
 HELP: line-metrics
 { $values { "font" font } { "string" string } { "metrics" line-metrics } }
-{ $contract "Outputs a " { $link line-metrics } " object with text measurements." } ;
+{ $contract "Outputs a " { $link metrics } " object with text measurements." } ;
 
 ARTICLE: "text-rendering" "Rendering text"
 "The " { $vocab-link "ui.text" } " vocabulary provides a cross-platform interface to the operating system's native font rendering engine. Currently, it uses Core Text on Mac OS X and FreeType on Windows and X11."
index 0c6e1fe05a5b34f111bd4d4bd13c2c8492f69433..a493d5d7d2d8cadd4f6c511b24e57715849116be 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: debugger help help.topics help.crossref help.home kernel models
+USING: debugger classes help help.topics help.crossref help.home kernel models
 compiler.units assocs words vocabs accessors fry arrays
 combinators.short-circuit namespaces sequences models help.apropos
 combinators ui ui.commands ui.gadgets ui.gadgets.panes
@@ -91,6 +91,10 @@ M: browser-gadget focusable-child* search-field>> ;
 : browser-window ( -- )
     "help.home" (browser-window) ;
 
+: error-help-window ( error -- )
+    [ error-help ]
+    [ dup tuple? [ class ] [ drop "errors" ] if ] bi or (browser-window) ;
+
 \ browser-window H{ { +nullary+ t } } define-command
 
 : com-browse ( link -- )
index 05d77793059c26e1d0d233d4ec7830749d609ec8..91ac96e0f9ae9adaa37a237589fdf52d57501be4 100644 (file)
@@ -46,7 +46,7 @@ SLOT: model
 
 : show-links-popup ( browser-gadget quot title -- )
     [ dup model>> ] 2dip <links-popup>
-    [ hand-loc get { 0 0 } <rect> show-glass ] [ request-focus ] bi ;
+    [ hand-loc get { 0 0 } <rect> show-glass ] [ request-focus ] bi ; inline
 
 : com-show-outgoing-links ( browser-gadget -- )
     [ uses ] "Outgoing links" show-links-popup ;
index c3ead4e3f5625f8cf55434ac295b231ac1c40c94..42666ab0643c82c22e13c9d4ab5dec18225de865 100644 (file)
@@ -8,7 +8,7 @@ ui.gadgets.buttons ui.gadgets.labels ui.gadgets.panes
 ui.gadgets.presentations ui.gadgets.viewports ui.gadgets.tables
 ui.gadgets.tracks ui.gadgets.scrollers ui.gadgets.panes
 ui.gadgets.borders ui.gadgets.status-bar ui.tools.traceback
-ui.tools.inspector ;
+ui.tools.inspector ui.tools.browser ;
 IN: ui.tools.debugger
 
 TUPLE: debugger < track error restarts restart-hook restart-list continuation ;
@@ -86,9 +86,7 @@ debugger "gestures" f {
 
 : com-traceback ( debugger -- ) continuation>> traceback-window ;
 
-: com-help ( debugger -- ) error>> (:help) ;
-
-\ com-help H{ { +listener+ t } } define-command
+: com-help ( debugger -- ) error>> error-help-window ;
 
 : com-edit ( debugger -- ) error>> (:edit) ;
 
diff --git a/basis/ui/tools/error-list/authors.txt b/basis/ui/tools/error-list/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/ui/tools/error-list/error-list-docs.factor b/basis/ui/tools/error-list/error-list-docs.factor
new file mode 100644 (file)
index 0000000..10ca80d
--- /dev/null
@@ -0,0 +1,20 @@
+IN: ui.tools.error-list
+USING: help.markup help.syntax ui.tools.common ui.commands ;
+
+ARTICLE: "ui.tools.error-list" "UI error list tool"
+"The error list tool displays messages generated by tools which process source files and definitions. To display the error list, press " { $command tool "common" show-error-list } " in any UI tool window."
+$nl
+"The " { $vocab-link "source-files.errors" } " vocabulary contains backend code used by this tool."
+{ $heading "Message icons" }
+{ $table
+    { "Icon" "Message type" "Reference" }
+    { { $image "vocab:ui/tools/error-list/icons/note.tiff" } "Parser note" { $link "parser" } }
+    { { $image "vocab:ui/tools/error-list/icons/syntax-error.tiff" } "Syntax error" { $link "syntax" } }
+    { { $image "vocab:ui/tools/error-list/icons/compiler-warning.tiff" } "Compiler warning" { $link "compiler-errors" } }
+    { { $image "vocab:ui/tools/error-list/icons/compiler-error.tiff" } "Compiler error" { $link "compiler-errors" } }
+    { { $image "vocab:ui/tools/error-list/icons/unit-test-error.tiff" } "Unit test failure" { $link "tools.test" } }
+    { { $image "vocab:ui/tools/error-list/icons/help-lint-error.tiff" } "Help lint failure" { $link "help.lint" } }
+    { { $image "vocab:ui/tools/error-list/icons/linkage-error.tiff" } "Linkage error" { $link "loading-libs" } }
+} ;
+
+ABOUT: "ui.tools.error-list"
diff --git a/basis/ui/tools/error-list/error-list.factor b/basis/ui/tools/error-list/error-list.factor
new file mode 100644 (file)
index 0000000..6a63a70
--- /dev/null
@@ -0,0 +1,205 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays sequences sorting assocs colors.constants fry
+combinators combinators.smart combinators.short-circuit editors make
+memoize compiler.units fonts kernel io.pathnames prettyprint
+source-files.errors math.parser init math.order models models.arrow
+models.arrow.smart models.search models.mapping models.delay debugger namespaces
+summary locals ui ui.commands ui.gadgets ui.gadgets.panes
+ui.gadgets.tables ui.gadgets.labeled ui.gadgets.tracks ui.gestures
+ui.operations ui.tools.browser ui.tools.common ui.gadgets.scrollers
+ui.tools.inspector ui.gadgets.status-bar ui.operations
+ui.gadgets.buttons ui.gadgets.borders ui.gadgets.packs
+ui.gadgets.labels ui.baseline-alignment ui.images
+compiler.errors calendar ;
+IN: ui.tools.error-list
+
+CONSTANT: source-file-icon
+    T{ image-name f "vocab:ui/tools/error-list/icons/source-file.tiff" }
+
+MEMO: error-icon ( type -- image-name )
+    error-icon-path <image-name> ;
+
+: <checkboxes> ( alist -- gadget )
+    [ <shelf> { 15 0 } >>gap ] dip
+    [ swap <checkbox> add-gadget ] assoc-each ;
+
+: <error-toggle> ( -- model gadget )
+    #! Linkage errors are not shown by default.
+    error-types get [ fatal?>> <model> ] assoc-map
+    [ [ [ error-icon ] dip ] assoc-map <checkboxes> ]
+    [ <mapping> ] bi ;
+
+TUPLE: error-list-gadget < tool
+visible-errors source-file error
+error-toggle source-file-table error-table error-display ;
+
+SINGLETON: source-file-renderer
+
+M: source-file-renderer row-columns
+    drop first2 [
+        [ source-file-icon ]
+        [ "<Listener input>" or ]
+        [ length number>string ] tri*
+    ] output>array ;
+
+M: source-file-renderer prototype-row
+    drop source-file-icon "" "" 3array ;
+
+M: source-file-renderer row-value
+    drop dup [ first [ <pathname> ] [ f ] if* ] when ;
+
+M: source-file-renderer column-titles
+    drop { "" "File" "Errors" } ;
+
+M: source-file-renderer column-alignment drop { 0 0 1 } ;
+
+M: source-file-renderer filled-column drop 1 ;
+
+: <source-file-model> ( model -- model' )
+    [ group-by-source-file >alist sort-keys ] <arrow> ;
+
+:: <source-file-table> ( error-list -- table )
+    error-list model>> <source-file-model>
+    source-file-renderer
+    <table>
+        [ invoke-primary-operation ] >>action
+        COLOR: dark-gray >>column-line-color
+        6 >>gap
+        5 >>min-rows
+        5 >>max-rows
+        60 >>min-cols
+        60 >>max-cols
+        t >>selection-required?
+        error-list source-file>> >>selected-value ;
+
+SINGLETON: error-renderer
+
+M: error-renderer row-columns
+    drop [
+        {
+            [ error-type error-icon ]
+            [ line#>> [ number>string ] [ "" ] if* ]
+            [ asset>> [ unparse-short ] [ "" ] if* ]
+            [ error>> summary ]
+        } cleave
+    ] output>array ;
+
+M: error-renderer prototype-row
+    drop [ +compiler-error+ error-icon "" "" "" ] output>array ;
+
+M: error-renderer row-value
+    drop ;
+
+M: error-renderer column-titles
+    drop { "" "Line" "Asset" "Error" } ;
+
+M: error-renderer column-alignment drop { 0 1 0 0 } ;
+
+: sort-errors ( seq -- seq' )
+    [ [ [ asset>> unparse-short ] [ line#>> ] bi 2array ] keep ] { } map>assoc
+    sort-keys values ;
+
+: file-matches? ( error pathname/f -- ? )
+    [ file>> ] [ dup [ string>> ] when ] bi* = ;
+
+: <error-table-model> ( error-list -- model )
+    [ model>> ] [ source-file>> ] bi
+    [ file-matches? ] <search>
+    [ sort-errors ] <arrow> ;
+
+:: <error-table> ( error-list -- table )
+    error-list <error-table-model>
+    error-renderer
+    <table>
+        [ invoke-primary-operation ] >>action
+        COLOR: dark-gray >>column-line-color
+        6 >>gap
+        5 >>min-rows
+        5 >>max-rows
+        60 >>min-cols
+        60 >>max-cols
+        t >>selection-required?
+        error-list error>> >>selected-value ;
+
+TUPLE: error-display < track ;
+
+: <error-display> ( error-list -- gadget )
+    vertical error-display new-track
+        add-toolbar
+        swap error>> >>model
+        dup model>> [ [ print-error ] when* ] <pane-control> <scroller> 1 track-add ;
+
+: com-inspect ( error-display -- )
+    model>> value>> [ inspector ] when* ;
+
+: com-help ( error-display -- )
+    model>> value>> [ error>> error-help-window ] when* ;
+
+: com-edit ( error-display -- )
+    model>> value>> [ edit-error ] when* ;
+
+error-display "toolbar" f {
+    { f com-inspect }
+    { f com-help }
+    { f com-edit }
+} define-command-map
+
+: <error-list-toolbar> ( error-list -- toolbar )
+    [ <toolbar> ] [ error-toggle>> "Show errors:" label-on-left add-gadget ] bi ;
+
+: <error-model> ( visible-errors model -- model' )
+    [ swap '[ error-type _ at ] filter ] <smart-arrow> ;
+
+:: <error-list-gadget> ( model -- gadget )
+    vertical error-list-gadget new-track
+        <error-toggle> [ >>error-toggle ] [ >>visible-errors ] bi*
+        dup visible-errors>> model <error-model> >>model 
+        f <model> >>source-file
+        f <model> >>error
+        dup <source-file-table> >>source-file-table
+        dup <error-table> >>error-table
+        dup <error-display> >>error-display
+    :> error-list
+    error-list vertical <track>
+        { 5 5 } >>gap
+        error-list <error-list-toolbar> f track-add
+        error-list source-file-table>> <scroller> "Source files" <labeled-gadget> 1/4 track-add
+        error-list error-table>> <scroller> "Errors" <labeled-gadget> 1/2 track-add
+        error-list error-display>> "Details" <labeled-gadget> 1/4 track-add
+    { 5 5 } <filled-border> 1 track-add ;
+
+M: error-list-gadget focusable-child*
+    source-file-table>> ;
+
+: error-list-help ( -- ) "ui.tools.error-list" com-browse ;
+
+\ error-list-help H{ { +nullary+ t } } define-command
+
+error-list-gadget "toolbar" f {
+    { T{ key-down f f "F1" } error-list-help }
+} define-command-map
+
+SYMBOL: error-list-model
+
+error-list-model [ f <model> ] initialize
+
+SINGLETON: updater
+
+M: updater errors-changed
+    drop f error-list-model get-global set-model ;
+
+[ updater add-error-observer ] "ui.tools.error-list" add-init-hook
+
+: <error-list-model> ( -- model )
+    error-list-model get-global
+    1/2 seconds <delay> [ drop all-errors ] <arrow> ;
+
+: error-list-window ( -- )
+    <error-list-model> <error-list-gadget> "Errors" open-status-window ;
+
+: show-error-list ( -- )
+    [ error-list-gadget? ] find-window
+    [ raise-window ] [ error-list-window ] if* ;
+
+\ show-error-list H{ { +nullary+ t } } define-command
diff --git a/basis/ui/tools/error-list/icons/compiler-error.tiff b/basis/ui/tools/error-list/icons/compiler-error.tiff
new file mode 100644 (file)
index 0000000..7a53d57
Binary files /dev/null and b/basis/ui/tools/error-list/icons/compiler-error.tiff differ
diff --git a/basis/ui/tools/error-list/icons/compiler-warning.tiff b/basis/ui/tools/error-list/icons/compiler-warning.tiff
new file mode 100644 (file)
index 0000000..405cfd4
Binary files /dev/null and b/basis/ui/tools/error-list/icons/compiler-warning.tiff differ
diff --git a/basis/ui/tools/error-list/icons/help-lint-error.tiff b/basis/ui/tools/error-list/icons/help-lint-error.tiff
new file mode 100644 (file)
index 0000000..464728a
Binary files /dev/null and b/basis/ui/tools/error-list/icons/help-lint-error.tiff differ
diff --git a/basis/ui/tools/error-list/icons/linkage-error.tiff b/basis/ui/tools/error-list/icons/linkage-error.tiff
new file mode 100644 (file)
index 0000000..78644fd
Binary files /dev/null and b/basis/ui/tools/error-list/icons/linkage-error.tiff differ
diff --git a/basis/ui/tools/error-list/icons/note.tiff b/basis/ui/tools/error-list/icons/note.tiff
new file mode 100644 (file)
index 0000000..834dea6
Binary files /dev/null and b/basis/ui/tools/error-list/icons/note.tiff differ
diff --git a/basis/ui/tools/error-list/icons/source-file.tiff b/basis/ui/tools/error-list/icons/source-file.tiff
new file mode 100644 (file)
index 0000000..5fb3375
Binary files /dev/null and b/basis/ui/tools/error-list/icons/source-file.tiff differ
diff --git a/basis/ui/tools/error-list/icons/syntax-error.tiff b/basis/ui/tools/error-list/icons/syntax-error.tiff
new file mode 100644 (file)
index 0000000..5446c80
Binary files /dev/null and b/basis/ui/tools/error-list/icons/syntax-error.tiff differ
diff --git a/basis/ui/tools/error-list/icons/unit-test-error.tiff b/basis/ui/tools/error-list/icons/unit-test-error.tiff
new file mode 100644 (file)
index 0000000..b6ea439
Binary files /dev/null and b/basis/ui/tools/error-list/icons/unit-test-error.tiff differ
index c329f037e178a20a71e904d3aa84ef0b1a06e14c..72f4e1fe66f747f8aea8b5d63db6ab9f52f05d1e 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax ui.commands ui.gadgets.slots
-ui.gadgets.editors ;
+ui.gadgets.editors kernel ;
 IN: ui.tools.inspector
 
 ARTICLE: "ui-inspector-edit" "Editing slot values in the inspector"
@@ -21,4 +21,8 @@ $nl
 "The UI inspector is an instance of " { $link inspector-gadget } "."
 { $subsection "ui-inspector-edit" } ;
 
+HELP: inspector
+{ $values { "obj" object } }
+{ $description "Opens a new inspector window displaying the slots of " { $snippet "obj" } "." } ;
+
 ABOUT: "ui-inspector"
\ No newline at end of file
index afe890b9c5264cc997792c243e8a39bca9d3a206..ec4fc80a4df3a772150b8589d37e199d02db1962 100644 (file)
@@ -27,6 +27,8 @@ ARTICLE: "ui-listener" "UI listener"
 { $command-map interactor "quotation" }
 { $heading "Editing commands" }
 "The text editing commands are standard; see " { $link "gadgets-editors-commands" } "."
+$nl
+"The listener displays a summary with any outstanding error conditions before every prompt. See " { $link "ui.tools.error-list" } " for details."
 { $heading "Implementation" }
 "Listeners are instances of " { $link listener-gadget } ". The listener consists of an output area (instance of " { $link pane } ") and an input area (instance of " { $link interactor } "). Clickable presentations can also be printed to the listener; see " { $link "ui-presentations" } "." ;
 
index 7cb3c70cbc2de118de752be69697f5463fd4e78c..6484b8e1c4f9c366c58f952e1a83187193887110 100644 (file)
@@ -1,10 +1,10 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs calendar combinators locals
-colors.constants combinators.short-circuit compiler.units
-help.tips concurrency.flags concurrency.mailboxes continuations
-destructors documents documents.elements fry hashtables help
-help.markup io io.styles kernel lexer listener math models
+source-files.errors colors.constants combinators.short-circuit
+compiler.units help.tips concurrency.flags concurrency.mailboxes
+continuations destructors documents documents.elements fry hashtables
+help help.markup io io.styles kernel lexer listener math models sets
 models.delay models.arrow namespaces parser prettyprint quotations
 sequences strings threads tools.vocabs vocabs vocabs.loader
 vocabs.parser words debugger ui ui.commands ui.pens.solid ui.gadgets
@@ -13,7 +13,8 @@ ui.gadgets.labeled ui.gadgets.panes ui.gadgets.scrollers
 ui.gadgets.status-bar ui.gadgets.tracks ui.gadgets.borders ui.gestures
 ui.operations ui.tools.browser ui.tools.common ui.tools.debugger
 ui.tools.listener.completion ui.tools.listener.popups
-ui.tools.listener.history ;
+ui.tools.listener.history ui.tools.error-list ;
+FROM: source-files.errors => all-errors ;
 IN: ui.tools.listener
 
 ! If waiting is t, we're waiting for user input, and invoking
@@ -356,10 +357,18 @@ interactor "completion" f {
     { T{ key-down f { C+ } "r" } history-completion-popup }
 } define-command-map
 
+: ui-error-summary ( -- )
+    error-counts keys [
+        [ icon>> 1array \ $image prefix " " 2array ] { } map-as
+        { "Press " { $command tool "common" show-error-list } " to view errors." }
+        append print-element nl
+    ] unless-empty ;
+
 : listener-thread ( listener -- )
     dup listener-streams [
         [ com-browse ] help-hook set
         '[ [ _ input>> ] 2dip debugger-popup ] error-hook set
+        [ ui-error-summary ] error-summary-hook set
         tip-of-the-day. nl
         listener
     ] with-streams* ;
index c6371ac8aaf3794e8f9eae2eb4a639f52e134bd7..3c160118978f7e10a67599a7a32490740d04fc8b 100644 (file)
@@ -1,15 +1,15 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations definitions generic help.topics threads
-stack-checker summary io.pathnames io.styles kernel namespaces
-parser prettyprint quotations tools.crossref tools.annotations
-editors tools.profiler tools.test tools.time tools.walker vocabs
-vocabs.loader words sequences tools.vocabs classes
-compiler.units accessors vocabs.parser macros.expander ui
-ui.tools.browser ui.tools.listener ui.tools.listener.completion
-ui.tools.profiler ui.tools.inspector ui.tools.traceback
-ui.commands ui.gadgets.editors ui.gestures ui.operations
-ui.tools.deploy models help.tips ;
+stack-checker summary io.pathnames io.styles kernel namespaces parser
+prettyprint quotations tools.crossref tools.annotations editors
+tools.profiler tools.test tools.time tools.walker vocabs vocabs.loader
+words sequences tools.vocabs classes compiler.errors compiler.units
+accessors vocabs.parser macros.expander ui ui.tools.browser
+ui.tools.listener ui.tools.listener.completion ui.tools.profiler
+ui.tools.inspector ui.tools.traceback ui.commands ui.gadgets.editors
+ui.gestures ui.operations ui.tools.deploy models help.tips
+source-files.errors ;
 IN: ui.tools.operations
 
 ! Objects
@@ -86,6 +86,21 @@ IN: ui.tools.operations
     { +listener+ t }
 } define-operation
 
+! Source file error
+[ source-file-error? ] \ edit-error H{
+    { +primary+ t }
+    { +secondary+ t }
+    { +listener+ t }
+} define-operation
+
+: com-reload ( error -- )
+    file>> run-file ;
+
+[ compiler-error? ] \ com-reload H{
+    { +listener+ t }
+} define-operation
+
+! Definitions
 : com-forget ( defspec -- )
     [ forget ] with-compilation-unit ;
 
@@ -173,4 +188,4 @@ interactor
 "These commands operate on the entire contents of the input area."
 [ ]
 [ quot-action ]
-define-operation-map
+define-operation-map
\ No newline at end of file
diff --git a/basis/ui/tools/profiler/profiler-tests.factor b/basis/ui/tools/profiler/profiler-tests.factor
new file mode 100644 (file)
index 0000000..86bebdd
--- /dev/null
@@ -0,0 +1,3 @@
+USING: ui.tools.profiler tools.test ;
+
+\ profiler-window must-infer
index 1c2318a35e94328d30cdf8f41231591ebb638cc5..5fef64ea8857e72b395f36a6f69529b49df93506 100644 (file)
@@ -11,6 +11,7 @@ ui.gadgets.tabbed ui.gadgets.status-bar ui.gadgets.borders
 ui.tools.browser ui.tools.common ui.baseline-alignment
 ui.operations ui.images ;
 FROM: models.arrow => <arrow> ;
+FROM: models.arrow.smart => <smart-arrow> ;
 FROM: models.product => <product> ;
 IN: ui.tools.profiler
 
@@ -112,8 +113,8 @@ M: method-renderer column-titles drop { "" "Method" "Count" } ;
 : <methods-model> ( profiler -- model )
     [
         [ method-counters <model> ] dip
-        [ generic>> ] [ class>> ] bi 3array <product>
-        [ first3 '[ _ _ method-matches? ] filter ] <arrow>
+        [ generic>> ] [ class>> ] bi
+        [ '[ _ _ method-matches? ] filter ] <smart-arrow>
     ] keep <profiler-model> ;
 
 : sort-by-name ( obj1 obj2 -- <=> )
@@ -208,6 +209,6 @@ profiler-gadget "toolbar" f {
 : profiler-window ( -- )
     <profiler-gadget> "Profiling results" open-status-window ;
 
-: com-profile ( quot -- ) profile profiler-window ;
+: com-profile ( quot -- ) profile profiler-window ; inline
 
 MAIN: profiler-window
index 52cd77d7263cdb656b02bad68248c59eca720dd1..92aa1be947a45de20403e81b1c5f5a1c2b88e0c9 100644 (file)
@@ -66,6 +66,7 @@ $nl
 { $subsection "ui-listener" }
 { $subsection "ui-browser" }
 { $subsection "ui-inspector" }
+{ $subsection "ui.tools.error-list" }
 { $subsection "ui.tools.profiler" }
 { $subsection "ui-walker" }
 { $subsection "ui.tools.deploy" }
index 203953db1a7b13f2935022878f99e738b1f57e50..c825c60dbb78bab21db794dfab4048a1c5e73698 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: memory system kernel tools.vocabs ui.tools.operations
-ui.tools.listener ui.tools.browser ui.tools.common
+ui.tools.listener ui.tools.browser ui.tools.common ui.tools.error-list
 ui.tools.walker ui.commands ui.gestures ui ui.private ;
 IN: ui.tools
 
@@ -30,4 +30,5 @@ tool "common" f {
     { T{ key-down f { A+ } "w" } close-window }
     { T{ key-down f { A+ } "q" } com-exit }
     { T{ key-down f f "F2" } refresh-all }
+    { T{ key-down f f "F3" } show-error-list }
 } define-command-map
\ No newline at end of file
index 011e3b4866f1ccc24546173ddd4302e7624a6258..9e73a312825506113c79a671d7de473dc2f0ea51 100644 (file)
@@ -1,6 +1,6 @@
 IN: ui.tools.walker\r
 USING: help.markup help.syntax ui.commands ui.operations\r
-ui.render tools.walker sequences ;\r
+ui.render tools.walker sequences tools.continuations ;\r
 \r
 ARTICLE: "ui-walker-step" "Stepping through code"\r
 "If the current position points to a word, the various stepping commands behave as follows:"\r
index f8b435441f7ecc749f5179e0204ce65d6694c356..82ab3d1f699ed6468bbf2d35d1bf285485cbd117 100644 (file)
@@ -7,7 +7,11 @@ HELP: url-decode
 
 HELP: url-encode
 { $values { "str" string } { "encoded" string } }
-{ $description "URL-encodes a string." } ;
+{ $description "URL-encodes a string, excluding certain characters, such as \"/\"." } ;
+
+HELP: url-encode-full
+{ $values { "str" string } { "encoded" string } }
+{ $description "URL-encodes a string, including all reserved characters, such as \"/\"." } ;
 
 HELP: url-quotable?
 { $values { "ch" "a character" } { "?" "a boolean" } }
index 15b71ac0dbc37b617bad000b810d7acba3d0c3c3..a5f5d62bfc885984865546e49157788f12cf6165 100644 (file)
@@ -14,6 +14,25 @@ IN: urls.encoding
         [ "/_-.:" member? ]
     } 1|| ; foldable
 
+! see http://tools.ietf.org/html/rfc3986#section-2.2
+: gen-delim? ( ch -- ? )
+    ":/?#[]@" member? ; foldable
+
+: sub-delim? ( ch -- ? )
+    "!$&'()*+,;=" member? ; foldable
+
+: reserved? ( ch -- ? )
+    [ gen-delim? ] [ sub-delim? ] bi or ; foldable
+
+! see http://tools.ietf.org/html/rfc3986#section-2.3
+: unreserved? ( ch -- ? )
+    {
+        [ letter? ]
+        [ LETTER? ]
+        [ digit? ]
+        [ "-._~" member? ]
+    } 1|| ; foldable
+
 <PRIVATE
 
 : push-utf8 ( ch -- )
@@ -27,6 +46,11 @@ PRIVATE>
         [ dup url-quotable? [ , ] [ push-utf8 ] if ] each
     ] "" make ;
 
+: url-encode-full ( str -- encoded )
+    [
+        [ dup unreserved? [ , ] [ push-utf8 ] if ] each
+    ] "" make ;
+
 <PRIVATE
 
 : url-decode-hex ( index str -- )
index f76e389dce76d50e1c07a0c18022cccdd9d8cea7..5b62f5479593d782352633acc034b5d322bcb13b 100644 (file)
@@ -1,5 +1,6 @@
 USING: alien.syntax kernel math windows.types math.bitwise ;
 IN: windows.advapi32
+
 LIBRARY: advapi32
 
 CONSTANT: PROV_RSA_FULL       1
@@ -122,6 +123,34 @@ C-STRUCT: ACCESS_ALLOWED_CALLBACK_ACE
 
 TYPEDEF: ACCESS_ALLOWED_CALLBACK_ACE* PACCESS_ALLOWED_CALLBACK_ACE
 
+C-STRUCT: SECURITY_DESCRIPTOR
+    { "UCHAR" "Revision" }
+    { "UCHAR" "Sbz1" }
+    { "WORD" "Control" }
+    { "PVOID" "Owner" }
+    { "PVOID" "Group" }
+    { "PACL" "Sacl" }
+    { "PACL" "Dacl" } ;
+
+TYPEDEF: SECURITY_DESCRIPTOR* PSECURITY_DESCRIPTOR
+
+CONSTANT: SE_OWNER_DEFAULTED 1
+CONSTANT: SE_GROUP_DEFAULTED 2
+CONSTANT: SE_DACL_PRESENT 4
+CONSTANT: SE_DACL_DEFAULTED 8
+CONSTANT: SE_SACL_PRESENT 16
+CONSTANT: SE_SACL_DEFAULTED 32
+CONSTANT: SE_DACL_AUTO_INHERIT_REQ 256
+CONSTANT: SE_SACL_AUTO_INHERIT_REQ 512
+CONSTANT: SE_DACL_AUTO_INHERITED 1024
+CONSTANT: SE_SACL_AUTO_INHERITED 2048
+CONSTANT: SE_DACL_PROTECTED 4096
+CONSTANT: SE_SACL_PROTECTED 8192
+CONSTANT: SE_SELF_RELATIVE 32768
+
+TYPEDEF: DWORD SECURITY_DESCRIPTOR_CONTROL
+TYPEDEF: SECURITY_DESCRIPTOR_CONTROL* PSECURITY_DESCRIPTOR_CONTROL
+
 
 ! typedef enum _TOKEN_INFORMATION_CLASS {
 CONSTANT: TokenUser 1
@@ -141,6 +170,140 @@ CONSTANT: TokenSessionReference 14
 CONSTANT: TokenSandBoxInert 15
 ! } TOKEN_INFORMATION_CLASS;
 
+TYPEDEF: DWORD ACCESS_MODE
+C-ENUM:
+    NOT_USED_ACCESS
+    GRANT_ACCESS
+    SET_ACCESS
+    DENY_ACCESS
+    REVOKE_ACCESS
+    SET_AUDIT_SUCCESS
+    SET_AUDIT_FAILURE ;
+
+TYPEDEF: DWORD MULTIPLE_TRUSTEE_OPERATION
+C-ENUM:
+    NO_MULTIPLE_TRUSTEE
+    TRUSTEE_IS_IMPERSONATE ;
+
+TYPEDEF: DWORD TRUSTEE_FORM
+C-ENUM:
+  TRUSTEE_IS_SID
+  TRUSTEE_IS_NAME
+  TRUSTEE_BAD_FORM
+  TRUSTEE_IS_OBJECTS_AND_SID
+  TRUSTEE_IS_OBJECTS_AND_NAME ;
+
+TYPEDEF: DWORD TRUSTEE_TYPE
+C-ENUM:
+    TRUSTEE_IS_UNKNOWN
+    TRUSTEE_IS_USER
+    TRUSTEE_IS_GROUP
+    TRUSTEE_IS_DOMAIN
+    TRUSTEE_IS_ALIAS
+    TRUSTEE_IS_WELL_KNOWN_GROUP
+    TRUSTEE_IS_DELETED
+    TRUSTEE_IS_INVALID
+    TRUSTEE_IS_COMPUTER ;
+
+TYPEDEF: DWORD SE_OBJECT_TYPE
+C-ENUM:
+    SE_UNKNOWN_OBJECT_TYPE
+    SE_FILE_OBJECT
+    SE_SERVICE
+    SE_PRINTER
+    SE_REGISTRY_KEY
+    SE_LMSHARE
+    SE_KERNEL_OBJECT
+    SE_WINDOW_OBJECT
+    SE_DS_OBJECT
+    SE_DS_OBJECT_ALL
+    SE_PROVIDER_DEFINED_OBJECT
+    SE_WMIGUID_OBJECT
+    SE_REGISTRY_WOW64_32KEY ;
+
+TYPEDEF: TRUSTEE* PTRUSTEE
+
+C-STRUCT: TRUSTEE
+    { "PTRUSTEE" "pMultipleTrustee" }
+    { "MULTIPLE_TRUSTEE_OPERATION" "MultipleTrusteeOperation" }
+    { "TRUSTEE_FORM" "TrusteeForm" }
+    { "TRUSTEE_TYPE" "TrusteeType" }
+    { "LPTSTR" "ptstrName" } ;
+
+C-STRUCT: EXPLICIT_ACCESS
+    { "DWORD" "grfAccessPermissions" }
+    { "ACCESS_MODE" "grfAccessMode" }
+    { "DWORD" "grfInheritance" }
+    { "TRUSTEE" "Trustee" } ;
+
+C-STRUCT: SID_IDENTIFIER_AUTHORITY
+    { { "BYTE" 6 } "Value" } ;
+
+TYPEDEF: SID_IDENTIFIER_AUTHORITY* PSID_IDENTIFIER_AUTHORITY
+
+CONSTANT: SECURITY_NULL_SID_AUTHORITY 0
+CONSTANT: SECURITY_WORLD_SID_AUTHORITY    1
+CONSTANT: SECURITY_LOCAL_SID_AUTHORITY    2
+CONSTANT: SECURITY_CREATOR_SID_AUTHORITY  3
+CONSTANT: SECURITY_NON_UNIQUE_AUTHORITY   4
+CONSTANT: SECURITY_NT_AUTHORITY   5
+CONSTANT: SECURITY_RESOURCE_MANAGER_AUTHORITY 6
+
+CONSTANT: SECURITY_NULL_RID 0
+CONSTANT: SECURITY_WORLD_RID 0
+CONSTANT: SECURITY_LOCAL_RID 0
+CONSTANT: SECURITY_CREATOR_OWNER_RID 0
+CONSTANT: SECURITY_CREATOR_GROUP_RID 1
+CONSTANT: SECURITY_CREATOR_OWNER_SERVER_RID 2
+CONSTANT: SECURITY_CREATOR_GROUP_SERVER_RID 3
+CONSTANT: SECURITY_DIALUP_RID 1
+CONSTANT: SECURITY_NETWORK_RID 2
+CONSTANT: SECURITY_BATCH_RID 3
+CONSTANT: SECURITY_INTERACTIVE_RID 4
+CONSTANT: SECURITY_SERVICE_RID 6
+CONSTANT: SECURITY_ANONYMOUS_LOGON_RID 7
+CONSTANT: SECURITY_PROXY_RID 8
+CONSTANT: SECURITY_SERVER_LOGON_RID 9
+CONSTANT: SECURITY_PRINCIPAL_SELF_RID 10
+CONSTANT: SECURITY_AUTHENTICATED_USER_RID 11
+CONSTANT: SECURITY_LOGON_IDS_RID 5
+CONSTANT: SECURITY_LOGON_IDS_RID_COUNT 3
+CONSTANT: SECURITY_LOCAL_SYSTEM_RID 18
+CONSTANT: SECURITY_NT_NON_UNIQUE 21
+CONSTANT: SECURITY_BUILTIN_DOMAIN_RID 32
+CONSTANT: DOMAIN_USER_RID_ADMIN 500
+CONSTANT: DOMAIN_USER_RID_GUEST 501
+CONSTANT: DOMAIN_GROUP_RID_ADMINS 512
+CONSTANT: DOMAIN_GROUP_RID_USERS 513
+CONSTANT: DOMAIN_GROUP_RID_GUESTS 514
+CONSTANT: DOMAIN_ALIAS_RID_ADMINS 544
+CONSTANT: DOMAIN_ALIAS_RID_USERS 545
+CONSTANT: DOMAIN_ALIAS_RID_GUESTS 546
+CONSTANT: DOMAIN_ALIAS_RID_POWER_USERS 547
+CONSTANT: DOMAIN_ALIAS_RID_ACCOUNT_OPS 548
+CONSTANT: DOMAIN_ALIAS_RID_SYSTEM_OPS 549
+CONSTANT: DOMAIN_ALIAS_RID_PRINT_OPS 550
+CONSTANT: DOMAIN_ALIAS_RID_BACKUP_OPS 551
+CONSTANT: DOMAIN_ALIAS_RID_REPLICATOR 552
+CONSTANT: SE_GROUP_MANDATORY 1
+CONSTANT: SE_GROUP_ENABLED_BY_DEFAULT 2
+CONSTANT: SE_GROUP_ENABLED 4
+CONSTANT: SE_GROUP_OWNER 8
+CONSTANT: SE_GROUP_LOGON_ID -1073741824
+
+! SID is a variable length structure
+TYPEDEF: void* PSID
+
+TYPEDEF: EXPLICIT_ACCESS* PEXPLICIT_ACCESS
+
+TYPEDEF: DWORD SECURITY_INFORMATION
+TYPEDEF: SECURITY_INFORMATION* PSECURITY_INFORMATION
+
+CONSTANT: OWNER_SECURITY_INFORMATION 1
+CONSTANT: GROUP_SECURITY_INFORMATION 2
+CONSTANT: DACL_SECURITY_INFORMATION 4
+CONSTANT: SACL_SECURITY_INFORMATION 8
+
 CONSTANT: DELETE                     HEX: 00010000
 CONSTANT: READ_CONTROL               HEX: 00020000
 CONSTANT: WRITE_DAC                  HEX: 00040000
@@ -187,6 +350,34 @@ CONSTANT: TOKEN_ADJUST_DEFAULT         HEX: 0080
         TOKEN_ADJUST_DEFAULT
     } flags ; foldable
 
+CONSTANT: HKEY_CLASSES_ROOT       1
+CONSTANT: HKEY_CURRENT_CONFIG     2
+CONSTANT: HKEY_CURRENT_USER       3
+CONSTANT: HKEY_LOCAL_MACHINE      4
+CONSTANT: HKEY_USERS              5
+
+CONSTANT: KEY_ALL_ACCESS          HEX: 0001
+CONSTANT: KEY_CREATE_LINK         HEX: 0002
+CONSTANT: KEY_CREATE_SUB_KEY      HEX: 0004
+CONSTANT: KEY_ENUMERATE_SUB_KEYS  HEX: 0008
+CONSTANT: KEY_EXECUTE             HEX: 0010
+CONSTANT: KEY_NOTIFY              HEX: 0020
+CONSTANT: KEY_QUERY_VALUE         HEX: 0040
+CONSTANT: KEY_READ                HEX: 0080
+CONSTANT: KEY_SET_VALUE           HEX: 0100
+CONSTANT: KEY_WOW64_64KEY         HEX: 0200
+CONSTANT: KEY_WOW64_32KEY         HEX: 0400
+CONSTANT: KEY_WRITE               HEX: 0800
+
+CONSTANT: REG_BINARY              1
+CONSTANT: REG_DWORD               2
+CONSTANT: REG_EXPAND_SZ           3
+CONSTANT: REG_MULTI_SZ            4
+CONSTANT: REG_QWORD               5
+CONSTANT: REG_SZ                  6
+
+TYPEDEF: DWORD REGSAM
+
 
 ! : I_ScGetCurrentGroupStateW ;
 ! : A_SHAFinal ;
@@ -224,7 +415,19 @@ FUNCTION: BOOL AdjustTokenPrivileges ( HANDLE TokenHandle,
                                PTOKEN_PRIVILEGES PreviousState,
                                PDWORD ReturnLength ) ;
 
-! : AllocateAndInitializeSid ;
+FUNCTION: BOOL AllocateAndInitializeSid (
+                PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+                BYTE nSubAuthorityCount,
+                DWORD dwSubAuthority0,
+                DWORD dwSubAuthority1,
+                DWORD dwSubAuthority2,
+                DWORD dwSubAuthority3,
+                DWORD dwSubAuthority4,
+                DWORD dwSubAuthority5,
+                DWORD dwSubAuthority6,
+                DWORD dwSubAuthority7,
+                PSID* pSid ) ;
+
 ! : AllocateLocallyUniqueId ;
 ! : AreAllAccessesGranted ;
 ! : AreAnyAccessesGranted ;
@@ -442,7 +645,8 @@ FUNCTION: BOOL CryptReleaseContext ( HCRYPTPROV hProv, DWORD dwFlags ) ;
 ! : GetExplicitEntriesFromAclA ;
 ! : GetExplicitEntriesFromAclW ;
 ! : GetFileSecurityA ;
-! : GetFileSecurityW ;
+FUNCTION: BOOL GetFileSecurityW ( LPCTSTR lpFileName, SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded ) ;
+ALIAS: GetFileSecurity GetFileSecurityW
 ! : GetInformationCodeAuthzLevelW ;
 ! : GetInformationCodeAuthzPolicyW ;
 ! : GetInheritanceSourceA ;
@@ -459,19 +663,20 @@ FUNCTION: BOOL CryptReleaseContext ( HCRYPTPROV hProv, DWORD dwFlags ) ;
 ! : GetMultipleTrusteeW ;
 ! : GetNamedSecurityInfoA ;
 ! : GetNamedSecurityInfoExA ;
-! : GetNamedSecurityInfoExW ;
-! : GetNamedSecurityInfoW ;
+! FUNCTION: DWORD GetNamedSecurityInfoExW
+FUNCTION: DWORD GetNamedSecurityInfoW ( LPTSTR pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl, PSECURITY_DESCRIPTOR* ppSecurityDescriptor ) ;
+ALIAS: GetNamedSecurityInfo GetNamedSecurityInfoW
 ! : GetNumberOfEventLogRecords ;
 ! : GetOldestEventLogRecord ;
 ! : GetOverlappedAccessResults ;
 ! : GetPrivateObjectSecurity ;
-! : GetSecurityDescriptorControl ;
-! : GetSecurityDescriptorDacl ;
-! : GetSecurityDescriptorGroup ;
-! : GetSecurityDescriptorLength ;
-! : GetSecurityDescriptorOwner ;
-! : GetSecurityDescriptorRMControl ;
-! : GetSecurityDescriptorSacl ;
+FUNCTION: BOOL GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision ) ;
+FUNCTION: BOOL GetSecurityDescriptorDacl ( PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL* pDacl, LPBOOL lpDaclDefaulted ) ;
+FUNCTION: BOOL GetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID* pGroup, LPBOOL lpGroupDefaulted ) ;
+FUNCTION: BOOL GetSecurityDescriptorLength ( PSECURITY_DESCRIPTOR pSecurityDescriptor ) ;
+FUNCTION: BOOL GetSecurityDescriptorOwner ( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID* pOwner, LPBOOL lpOwnerDefaulted ) ;
+FUNCTION: BOOL GetSecurityDescriptorRMControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor, PUCHAR RMControl ) ;
+FUNCTION: BOOL GetSecurityDescriptorSacl ( PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent, PACL* pSacl, LPBOOL lpSaclDefaulted ) ;
 ! : GetSecurityInfo ;
 ! : GetSecurityInfoExA ;
 ! : GetSecurityInfoExW ;
@@ -510,7 +715,7 @@ ALIAS: GetUserName GetUserNameW
 ! : ImpersonateNamedPipeClient ;
 ! : ImpersonateSelf ;
 FUNCTION: BOOL InitializeAcl ( PACL pAcl, DWORD nAclLength, DWORD dwAclRevision ) ;
-! : InitializeSecurityDescriptor ;
+FUNCTION: BOOL InitializeSecurityDescriptor ( PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision ) ;
 ! : InitializeSid ;
 ! : InitiateSystemShutdownA ;
 ! : InitiateSystemShutdownExA ;
@@ -674,8 +879,8 @@ FUNCTION: BOOL OpenThreadToken ( HANDLE ThreadHandle, DWORD DesiredAccess, BOOL
 ! : RegConnectRegistryW ;
 ! : RegCreateKeyA ;
 ! : RegCreateKeyExA ;
-! : RegCreateKeyExW ;
-! : RegCreateKeyW ;
+FUNCTION: LONG RegCreateKeyExW ( HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ) ;
+! : RegCreateKeyW
 ! : RegDeleteKeyA ;
 ! : RegDeleteKeyW ;
 ! : RegDeleteValueA ;
@@ -692,7 +897,7 @@ FUNCTION: BOOL OpenThreadToken ( HANDLE ThreadHandle, DWORD DesiredAccess, BOOL
 ! : RegLoadKeyA ;
 ! : RegLoadKeyW ;
 ! : RegNotifyChangeKeyValue ;
-! : RegOpenCurrentUser ;
+FUNCTION: LONG RegOpenCurrentUser ( REGSAM samDesired, PHKEY phkResult ) ;
 ! : RegOpenKeyA ;
 ! : RegOpenKeyExA ;
 ! : RegOpenKeyExW ;
@@ -705,7 +910,7 @@ FUNCTION: BOOL OpenThreadToken ( HANDLE ThreadHandle, DWORD DesiredAccess, BOOL
 ! : RegQueryMultipleValuesW ;
 ! : RegQueryValueA ;
 ! : RegQueryValueExA ;
-! : RegQueryValueExW ;
+FUNCTION: LONG RegQueryValueExW ( HKEY hKey, LPCTSTR lpValueName, LPWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ) ;
 ! : RegQueryValueW ;
 ! : RegReplaceKeyA ;
 ! : RegReplaceKeyW ;
@@ -756,7 +961,8 @@ FUNCTION: BOOL OpenThreadToken ( HANDLE ThreadHandle, DWORD DesiredAccess, BOOL
 ! : SetEntriesInAccessListA ;
 ! : SetEntriesInAccessListW ;
 ! : SetEntriesInAclA ;
-! : SetEntriesInAclW ;
+FUNCTION: DWORD SetEntriesInAclW ( ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS pListOfExplicitEntries, PACL OldAcl, PACL* NewAcl ) ;
+ALIAS: SetEntriesInAcl SetEntriesInAclW
 ! : SetEntriesInAuditListA ;
 ! : SetEntriesInAuditListW ;
 ! : SetFileSecurityA ;
@@ -767,7 +973,8 @@ FUNCTION: BOOL OpenThreadToken ( HANDLE ThreadHandle, DWORD DesiredAccess, BOOL
 ! : SetNamedSecurityInfoA ;
 ! : SetNamedSecurityInfoExA ;
 ! : SetNamedSecurityInfoExW ;
-! : SetNamedSecurityInfoW ;
+FUNCTION: DWORD SetNamedSecurityInfoW ( LPTSTR pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl ) ;
+ALIAS: SetNamedSecurityInfo SetNamedSecurityInfoW
 ! : SetPrivateObjectSecurity ;
 ! : SetPrivateObjectSecurityEx ;
 ! : SetSecurityDescriptorControl ;
diff --git a/basis/windows/dinput/constants/constants-tests.factor b/basis/windows/dinput/constants/constants-tests.factor
new file mode 100644 (file)
index 0000000..6778584
--- /dev/null
@@ -0,0 +1,5 @@
+IN: windows.dinput.constants.tests
+USING: tools.test windows.dinput.constants.private ;
+
+[ ] [ define-constants ] unit-test
+[ ] [ free-dinput-constants ] unit-test
\ No newline at end of file
index cd1033d41870b4f0085d9b1160751cd88a9fef9a..0f95c6d6839560737d9f0d560f86768cfee5d8f7 100755 (executable)
@@ -27,12 +27,12 @@ SYMBOLS:
 
 : (flag) ( thing -- integer )
     {
-        { [ dup word? ] [ execute ] }
-        { [ dup callable? ] [ call ] }
+        { [ dup word? ] [ execute( -- value ) ] }
+        { [ dup callable? ] [ call( -- value ) ] }
         [ ]
     } cond ;
 
-: (flags) ( array -- )
+: (flags) ( array -- )
     0 [ (flag) bitor ] reduce ;
 
 : (DIOBJECTDATAFORMAT) ( pguid dwOfs dwType dwFlags alien -- alien )
@@ -63,14 +63,16 @@ SYMBOLS:
     ] ;
 
 : (DIDATAFORMAT) ( dwSize dwObjSize dwFlags dwDataSize dwNumObjs rgodf alien -- alien )
-    [ {
-        [ set-DIDATAFORMAT-rgodf ]
-        [ set-DIDATAFORMAT-dwNumObjs ]
-        [ set-DIDATAFORMAT-dwDataSize ]
-        [ set-DIDATAFORMAT-dwFlags ]
-        [ set-DIDATAFORMAT-dwObjSize ]
-        [ set-DIDATAFORMAT-dwSize ]
-    } cleave ] keep ;
+    [
+        {
+            [ set-DIDATAFORMAT-rgodf ]
+            [ set-DIDATAFORMAT-dwNumObjs ]
+            [ set-DIDATAFORMAT-dwDataSize ]
+            [ set-DIDATAFORMAT-dwFlags ]
+            [ set-DIDATAFORMAT-dwObjSize ]
+            [ set-DIDATAFORMAT-dwSize ]
+        } cleave
+    ] keep ;
 
 : <DIDATAFORMAT> ( dwFlags dwDataSize struct rgodf-array -- alien )
     [ "DIDATAFORMAT" heap-size "DIOBJECTDATAFORMAT" heap-size ] 4 ndip
@@ -78,9 +80,10 @@ SYMBOLS:
     "DIDATAFORMAT" <c-object> (DIDATAFORMAT) ;
 
 : (malloc-guid-symbol) ( symbol guid -- )
-    global swap '[ [
-        _ execute [ byte-length malloc ] [ over byte-array>memory ] bi
-    ] unless* ] change-at ;
+    '[
+        _ execute( -- value )
+        [ byte-length malloc ] [ over byte-array>memory ] bi
+    ] initialize ;
 
 : define-guid-constants ( -- )
     {
@@ -105,7 +108,7 @@ SYMBOLS:
     } [ first2 (malloc-guid-symbol) ] each ;
 
 : define-joystick-format-constant ( -- )
-    c_dfDIJoystick2 global [ [
+    c_dfDIJoystick2 [
         DIDF_ABSAXIS
         "DIJOYSTATE2" heap-size
         "DIJOYSTATE2" {
@@ -274,10 +277,10 @@ SYMBOLS:
             { GUID_Slider_malloced "rglFSlider"   0 { DIDFT_OPTIONAL DIDFT_AXIS   DIDFT_ANYINSTANCE } DIDOI_ASPECTFORCE }
             { GUID_Slider_malloced "rglFSlider"   1 { DIDFT_OPTIONAL DIDFT_AXIS   DIDFT_ANYINSTANCE } DIDOI_ASPECTFORCE }
         } <DIDATAFORMAT>
-    ] unless* ] change-at ;
+    ] initialize ;
 
 : define-mouse-format-constant ( -- )
-    c_dfDIMouse2 global [ [
+    c_dfDIMouse2 [
         DIDF_RELAXIS
         "DIMOUSESTATE2" heap-size
         "DIMOUSESTATE2" {
@@ -293,13 +296,13 @@ SYMBOLS:
             { GUID_Button_malloced "rgbButtons" 6 { DIDFT_OPTIONAL DIDFT_ANYINSTANCE DIDFT_BUTTON } 0 }
             { GUID_Button_malloced "rgbButtons" 7 { DIDFT_OPTIONAL DIDFT_ANYINSTANCE DIDFT_BUTTON } 0 }
         } <DIDATAFORMAT>
-    ] unless* ] change-at ;
+    ] initialize ;
 
 ! Not a standard DirectInput format. Included for cross-platform niceness.
 ! This format returns the keyboard keys in USB HID order rather than Windows
 ! order
 : define-hid-keyboard-format-constant ( -- )
-    c_dfDIKeyboard_HID global [ [
+    c_dfDIKeyboard_HID [
         DIDF_RELAXIS
         256
         f {
@@ -560,10 +563,10 @@ SYMBOLS:
             { GUID_Key_malloced f 254 { DIDFT_OPTIONAL DIDFT_BUTTON [ 0 DIDFT_MAKEINSTANCE ] } 0 }
             { GUID_Key_malloced f 255 { DIDFT_OPTIONAL DIDFT_BUTTON [ 0 DIDFT_MAKEINSTANCE ] } 0 }
         } <DIDATAFORMAT>
-    ] unless* ] change-at ;
+    ] initialize ;
 
 : define-keyboard-format-constant ( -- )
-    c_dfDIKeyboard global [ [
+    c_dfDIKeyboard [
         DIDF_RELAXIS
         256
         f {
@@ -824,7 +827,7 @@ SYMBOLS:
             { GUID_Key_malloced f 254 { DIDFT_OPTIONAL DIDFT_BUTTON [ 254 DIDFT_MAKEINSTANCE ] } 0 }
             { GUID_Key_malloced f 255 { DIDFT_OPTIONAL DIDFT_BUTTON [ 255 DIDFT_MAKEINSTANCE ] } 0 }
         } <DIDATAFORMAT>
-    ] unless* ] change-at ;
+    ] initialize ;
 
 : define-format-constants ( -- )
     define-joystick-format-constant
@@ -837,7 +840,9 @@ SYMBOLS:
     define-format-constants ;
 
 [ define-constants ] "windows.dinput.constants" add-init-hook
-define-constants
+
+: uninitialize ( variable quot -- )
+    [ global ] dip '[ _ when* f ] change-at ; inline
 
 : free-dinput-constants ( -- )
     {
@@ -846,10 +851,11 @@ define-constants
         GUID_Slider_malloced GUID_Button_malloced GUID_Key_malloced GUID_POV_malloced GUID_Unknown_malloced
         GUID_SysMouse_malloced GUID_SysKeyboard_malloced GUID_Joystick_malloced GUID_SysMouseEm_malloced
         GUID_SysMouseEm2_malloced GUID_SysKeyboardEm_malloced GUID_SysKeyboardEm2_malloced
-    } [ global [ [ free ] when* f ] change-at ] each
+    } [ [ free ] uninitialize ] each
+
     {
         c_dfDIKeyboard c_dfDIKeyboard_HID c_dfDIMouse2 c_dfDIJoystick2
-    } [ global [ [ DIDATAFORMAT-rgodf free ] when* f ] change-at ] each ;
+    } [ [ DIDATAFORMAT-rgodf free ] uninitialize ] each ;
 
 PRIVATE>
 
index 794aa0e32e17277fd1cfc92ab5263bc43838d84c..9b7cd2e35e9dee9c5e5da062f34c4c81ee65d3b6 100755 (executable)
@@ -1501,7 +1501,6 @@ DESTRUCTOR: DeleteObject
 FUNCTION: BOOL ExtTextOutW ( HDC hdc, int X, int Y, UINT fuOptions, RECT* lprc, LPCTSTR lpString, UINT cbCount, INT* lpDx ) ;
 ALIAS: ExtTextOut ExtTextOutW
 ! FUNCTION: FillPath
-FUNCTION: int FillRect ( HDC hDC, RECT* lprc, HBRUSH hbr ) ;
 ! FUNCTION: FillRgn
 ! FUNCTION: FixBrushOrgEx
 ! FUNCTION: FlattenPath
index 6bf68304bb221e6af6772aa750c8024b36773ef3..2320bdd64800598d4f0633f3441065dc20e4018f 100644 (file)
@@ -1 +1,2 @@
 unportable
+bindings
index 36acc5e3464edc5db53d63ec9d715fc0c70f1f92..4d3dd81a0e7ef34ac058c40d8e3b770b50fd0f11 100755 (executable)
@@ -1477,7 +1477,7 @@ ALIAS: LoadLibraryEx LoadLibraryExW
 ! FUNCTION: LoadLibraryW
 ! FUNCTION: LoadModule
 ! FUNCTION: LoadResource
-! FUNCTION: LocalAlloc
+FUNCTION: HLOCAL LocalAlloc ( UINT uFlags, SIZE_T uBytes ) ;
 ! FUNCTION: LocalCompact
 ! FUNCTION: LocalFileTimeToFileTime
 ! FUNCTION: LocalFlags
index 9daac21697e4e254a2014334d790339292445dab..f3bc1becb2e483603c8eae5830222d5c3713d93c 100644 (file)
@@ -807,7 +807,7 @@ FUNCTION: UINT EnumClipboardFormats ( UINT format ) ;
 ! FUNCTION: EqualRect
 ! FUNCTION: ExcludeUpdateRgn
 ! FUNCTION: ExitWindowsEx
-! FUNCTION: FillRect
+FUNCTION: int FillRect ( HDC hDC, RECT* lprc, HBRUSH hbr ) ;
 FUNCTION: HWND FindWindowA ( char* lpClassName, char* lpWindowName ) ;
 FUNCTION: HWND FindWindowExA ( HWND hwndParent, HWND childAfter, char* lpClassName, char* lpWindowName ) ;
 ! FUNCTION: FindWindowExW
diff --git a/basis/windows/usp10/tags.txt b/basis/windows/usp10/tags.txt
new file mode 100644 (file)
index 0000000..2320bdd
--- /dev/null
@@ -0,0 +1,2 @@
+unportable
+bindings
diff --git a/basis/x11/authors.txt b/basis/x11/authors.txt
new file mode 100644 (file)
index 0000000..db8d844
--- /dev/null
@@ -0,0 +1,2 @@
+Eduardo Cavazos
+Slava Pestov
index 87b91624afb922eb4a86065e540ecf23df4249b5..20bf66c70484aaf0d5b0b811129ecc7bfee6b499 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings alien.syntax arrays
 kernel math namespaces sequences io.encodings.string
-io.encodings.utf8 io.encodings.ascii x11.xlib x11.constants
+io.encodings.utf8 io.encodings.ascii x11 x11.xlib x11.constants
 specialized-arrays.int accessors ;
 IN: x11.clipboard
 
index 07650a9da73125655928c472eb9fb9ca669cc6ad..5673dd7f76a201a8772e58776da263de16738bba 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types arrays hashtables io kernel math
 math.order namespaces prettyprint sequences strings combinators
-x11.xlib ;
+x11 x11.xlib ;
 IN: x11.events
 
 GENERIC: expose-event ( event window -- )
index e6001d3e592e4e73b1139e644c884d40bcf2c624..dc6157b87fe94cdb0a0324e40da95caa6ebc89e9 100644 (file)
@@ -2,8 +2,9 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! based on glx.h from xfree86, and some of glxtokens.h
-USING: alien alien.c-types alien.syntax x11.xlib namespaces make
-kernel sequences parser words specialized-arrays.int accessors ;
+USING: alien alien.c-types alien.syntax x11 x11.xlib x11.syntax
+namespaces make kernel sequences parser words specialized-arrays.int
+accessors ;
 IN: x11.glx
 
 LIBRARY: glx
@@ -36,52 +37,52 @@ TYPEDEF: XID GLXFBConfigID
 TYPEDEF: void* GLXContext  ! typedef struct __GLXcontextRec *GLXContext;
 TYPEDEF: void* GLXFBConfig ! typedef struct __GLXFBConfigRec *GLXFBConfig;
 
-FUNCTION: XVisualInfo* glXChooseVisual ( Display* dpy, int screen, int* attribList ) ;
-FUNCTION: void glXCopyContext ( Display* dpy, GLXContext src, GLXContext dst, ulong mask ) ;
-FUNCTION: GLXContext glXCreateContext ( Display* dpy, XVisualInfo* vis, GLXContext shareList, bool direct ) ;
-FUNCTION: GLXPixmap glXCreateGLXPixmap ( Display* dpy, XVisualInfo* vis, Pixmap pixmap ) ;
-FUNCTION: void glXDestroyContext ( Display* dpy, GLXContext ctx ) ;
-FUNCTION: void glXDestroyGLXPixmap ( Display* dpy, GLXPixmap pix ) ;
-FUNCTION: int glXGetConfig ( Display* dpy, XVisualInfo* vis, int attrib, int* value ) ;
-FUNCTION: GLXContext glXGetCurrentContext ( ) ;
-FUNCTION: GLXDrawable glXGetCurrentDrawable ( ) ;
-FUNCTION: bool glXIsDirect ( Display* dpy, GLXContext ctx ) ;
-FUNCTION: bool glXMakeCurrent ( Display* dpy, GLXDrawable drawable, GLXContext ctx ) ;
-FUNCTION: bool glXQueryExtension ( Display* dpy, int* errorBase, int* eventBase ) ;
-FUNCTION: bool glXQueryVersion ( Display* dpy, int* major, int* minor ) ;
-FUNCTION: void glXSwapBuffers ( Display* dpy, GLXDrawable drawable ) ;
-FUNCTION: void glXUseXFont ( Font font, int first, int count, int listBase ) ;
-FUNCTION: void glXWaitGL ( ) ;
-FUNCTION: void glXWaitX ( ) ;
-FUNCTION: char* glXGetClientString ( Display* dpy, int name ) ;
-FUNCTION: char* glXQueryServerString ( Display* dpy, int screen, int name ) ;
-FUNCTION: char* glXQueryExtensionsString ( Display* dpy, int screen ) ;
+X-FUNCTION: XVisualInfo* glXChooseVisual ( Display* dpy, int screen, int* attribList ) ;
+X-FUNCTION: void glXCopyContext ( Display* dpy, GLXContext src, GLXContext dst, ulong mask ) ;
+X-FUNCTION: GLXContext glXCreateContext ( Display* dpy, XVisualInfo* vis, GLXContext shareList, bool direct ) ;
+X-FUNCTION: GLXPixmap glXCreateGLXPixmap ( Display* dpy, XVisualInfo* vis, Pixmap pixmap ) ;
+X-FUNCTION: void glXDestroyContext ( Display* dpy, GLXContext ctx ) ;
+X-FUNCTION: void glXDestroyGLXPixmap ( Display* dpy, GLXPixmap pix ) ;
+X-FUNCTION: int glXGetConfig ( Display* dpy, XVisualInfo* vis, int attrib, int* value ) ;
+X-FUNCTION: GLXContext glXGetCurrentContext ( ) ;
+X-FUNCTION: GLXDrawable glXGetCurrentDrawable ( ) ;
+X-FUNCTION: bool glXIsDirect ( Display* dpy, GLXContext ctx ) ;
+X-FUNCTION: bool glXMakeCurrent ( Display* dpy, GLXDrawable drawable, GLXContext ctx ) ;
+X-FUNCTION: bool glXQueryExtension ( Display* dpy, int* errorBase, int* eventBase ) ;
+X-FUNCTION: bool glXQueryVersion ( Display* dpy, int* major, int* minor ) ;
+X-FUNCTION: void glXSwapBuffers ( Display* dpy, GLXDrawable drawable ) ;
+X-FUNCTION: void glXUseXFont ( Font font, int first, int count, int listBase ) ;
+X-FUNCTION: void glXWaitGL ( ) ;
+X-FUNCTION: void glXWaitX ( ) ;
+X-FUNCTION: char* glXGetClientString ( Display* dpy, int name ) ;
+X-FUNCTION: char* glXQueryServerString ( Display* dpy, int screen, int name ) ;
+X-FUNCTION: char* glXQueryExtensionsString ( Display* dpy, int screen ) ;
 
 ! New for GLX 1.3
-FUNCTION: GLXFBConfig* glXGetFBConfigs ( Display* dpy, int screen, int* nelements ) ;
-FUNCTION: GLXFBConfig* glXChooseFBConfig ( Display* dpy, int screen, int* attrib_list, int* nelements ) ;
-FUNCTION: int glXGetFBConfigAttrib ( Display* dpy, GLXFBConfig config, int attribute, int* value ) ;
-FUNCTION: XVisualInfo* glXGetVisualFromFBConfig ( Display* dpy, GLXFBConfig config ) ;
-FUNCTION: GLXWindow glXCreateWindow ( Display* dpy, GLXFBConfig config, Window win, int* attrib_list ) ;
-FUNCTION: void glXDestroyWindow ( Display* dpy, GLXWindow win ) ;
-FUNCTION: GLXPixmap glXCreatePixmap ( Display* dpy, GLXFBConfig config, Pixmap pixmap, int* attrib_list ) ;
-FUNCTION: void glXDestroyPixmap ( Display* dpy, GLXPixmap pixmap ) ;
-FUNCTION: GLXPbuffer glXCreatePbuffer ( Display* dpy, GLXFBConfig config, int* attrib_list ) ;
-FUNCTION: void glXDestroyPbuffer ( Display* dpy, GLXPbuffer pbuf ) ;
-FUNCTION: void glXQueryDrawable ( Display* dpy, GLXDrawable draw, int attribute, uint* value ) ;
-FUNCTION: GLXContext glXCreateNewContext ( Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, bool direct ) ;
-FUNCTION: bool glXMakeContextCurrent ( Display* display, GLXDrawable draw, GLXDrawable read, GLXContext ctx ) ;
-FUNCTION: GLXDrawable glXGetCurrentReadDrawable ( ) ;
-FUNCTION: Display*  glXGetCurrentDisplay ( ) ;
-FUNCTION: int glXQueryContext ( Display* dpy, GLXContext ctx, int attribute, int* value ) ;
-FUNCTION: void glXSelectEvent ( Display* dpy, GLXDrawable draw, ulong event_mask ) ;
-FUNCTION: void glXGetSelectedEvent ( Display* dpy, GLXDrawable draw, ulong* event_mask ) ;
+X-FUNCTION: GLXFBConfig* glXGetFBConfigs ( Display* dpy, int screen, int* nelements ) ;
+X-FUNCTION: GLXFBConfig* glXChooseFBConfig ( Display* dpy, int screen, int* attrib_list, int* nelements ) ;
+X-FUNCTION: int glXGetFBConfigAttrib ( Display* dpy, GLXFBConfig config, int attribute, int* value ) ;
+X-FUNCTION: XVisualInfo* glXGetVisualFromFBConfig ( Display* dpy, GLXFBConfig config ) ;
+X-FUNCTION: GLXWindow glXCreateWindow ( Display* dpy, GLXFBConfig config, Window win, int* attrib_list ) ;
+X-FUNCTION: void glXDestroyWindow ( Display* dpy, GLXWindow win ) ;
+X-FUNCTION: GLXPixmap glXCreatePixmap ( Display* dpy, GLXFBConfig config, Pixmap pixmap, int* attrib_list ) ;
+X-FUNCTION: void glXDestroyPixmap ( Display* dpy, GLXPixmap pixmap ) ;
+X-FUNCTION: GLXPbuffer glXCreatePbuffer ( Display* dpy, GLXFBConfig config, int* attrib_list ) ;
+X-FUNCTION: void glXDestroyPbuffer ( Display* dpy, GLXPbuffer pbuf ) ;
+X-FUNCTION: void glXQueryDrawable ( Display* dpy, GLXDrawable draw, int attribute, uint* value ) ;
+X-FUNCTION: GLXContext glXCreateNewContext ( Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, bool direct ) ;
+X-FUNCTION: bool glXMakeContextCurrent ( Display* display, GLXDrawable draw, GLXDrawable read, GLXContext ctx ) ;
+X-FUNCTION: GLXDrawable glXGetCurrentReadDrawable ( ) ;
+X-FUNCTION: Display*  glXGetCurrentDisplay ( ) ;
+X-FUNCTION: int glXQueryContext ( Display* dpy, GLXContext ctx, int attribute, int* value ) ;
+X-FUNCTION: void glXSelectEvent ( Display* dpy, GLXDrawable draw, ulong event_mask ) ;
+X-FUNCTION: void glXGetSelectedEvent ( Display* dpy, GLXDrawable draw, ulong* event_mask ) ;
 
 ! GLX 1.4 and later
-FUNCTION: void* glXGetProcAddress ( char* procname ) ;
+X-FUNCTION: void* glXGetProcAddress ( char* procname ) ;
 
 ! GLX_ARB_get_proc_address extension
-FUNCTION: void* glXGetProcAddressARB ( char* procname ) ;
+X-FUNCTION: void* glXGetProcAddressARB ( char* procname ) ;
 
 ! GLX Events
 ! (also skipped for now. only has GLXPbufferClobberEvent, the rest is handled by xlib methinks)
diff --git a/basis/x11/io/authors.txt b/basis/x11/io/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/x11/io/io.factor b/basis/x11/io/io.factor
new file mode 100644 (file)
index 0000000..0e618cd
--- /dev/null
@@ -0,0 +1,16 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.backend calendar threads kernel ;
+IN: x11.io
+
+HOOK: init-x-io io-backend ( -- )
+
+M: object init-x-io ;
+
+HOOK: wait-for-display io-backend ( -- )
+
+M: object wait-for-display 10 milliseconds sleep ;
+
+HOOK: awaken-event-loop io-backend ( -- )
+
+M: object awaken-event-loop ;
\ No newline at end of file
diff --git a/basis/x11/io/unix/authors.txt b/basis/x11/io/unix/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/x11/io/unix/tags.txt b/basis/x11/io/unix/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/x11/io/unix/unix.factor b/basis/x11/io/unix/unix.factor
new file mode 100644 (file)
index 0000000..821beb9
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.backend.unix io.backend.unix.multiplexers
+namespaces system x11 x11.xlib x11.io
+accessors threads sequences kernel ;
+IN: x11.io.unix
+
+SYMBOL: dpy-fd
+
+M: unix init-x-io dpy get XConnectionNumber <fd> dpy-fd set-global ;
+
+M: unix wait-for-display dpy-fd get +input+ wait-for-fd ;
+
+M: unix awaken-event-loop
+    dpy-fd get [ fd>> mx get remove-input-callbacks [ resume ] each ] when* ;
\ No newline at end of file
diff --git a/basis/x11/syntax/authors.txt b/basis/x11/syntax/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/x11/syntax/syntax.factor b/basis/x11/syntax/syntax.factor
new file mode 100644 (file)
index 0000000..db2adab
--- /dev/null
@@ -0,0 +1,9 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax alien.parser words x11.io sequences kernel ;
+IN: x11.syntax
+
+SYNTAX: X-FUNCTION:
+    (FUNCTION:)
+    [ \ awaken-event-loop suffix ] dip
+    define-declared ;
\ No newline at end of file
index 8085907bef7c8e2fb950fd60738134376033d3d6..87a212bd8e2531750cca8836628698676d340dee 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Eduardo Cavazos and Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types hashtables kernel math math.vectors
-math.bitwise namespaces sequences x11.xlib x11.constants x11.glx
+math.bitwise namespaces sequences x11 x11.xlib x11.constants x11.glx
 arrays fry ;
 IN: x11.windows
 
@@ -29,6 +29,8 @@ IN: x11.windows
 
 : window-attributes ( visinfo -- attributes )
     "XSetWindowAttributes" <c-object>
+    0 over set-XSetWindowAttributes-background_pixel
+    0 over set-XSetWindowAttributes-border_pixel
     [ [ create-colormap ] dip set-XSetWindowAttributes-colormap ] keep
     event-mask over set-XSetWindowAttributes-event_mask ;
 
diff --git a/basis/x11/x11.factor b/basis/x11/x11.factor
new file mode 100644 (file)
index 0000000..09328c6
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2005, 2009 Eduardo Cavazos, Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.strings continuations io
+io.encodings.ascii kernel namespaces x11.xlib x11.io
+vocabs vocabs.loader ;
+IN: x11
+
+SYMBOL: dpy
+SYMBOL: scr
+SYMBOL: root
+
+: init-locale ( -- )
+   LC_ALL "" setlocale [ "setlocale() failed" print flush ] unless
+   XSupportsLocale [ "XSupportsLocale() failed" print flush ] unless ;
+
+: flush-dpy ( -- ) dpy get XFlush drop ;
+
+: x-atom ( string -- atom ) [ dpy get ] dip 0 XInternAtom ;
+
+: check-display ( alien -- alien' )
+    [ "Cannot connect to X server - check $DISPLAY" throw ] unless* ;
+
+: init-x ( display-string -- )
+    init-locale
+    dup [ ascii string>alien ] when
+    XOpenDisplay check-display dpy set-global
+    dpy get XDefaultScreen scr set-global
+    dpy get scr get XRootWindow root set-global
+    init-x-io ;
+
+: close-x ( -- ) dpy get XCloseDisplay drop ;
+
+: with-x ( display-string quot -- )
+    [ init-x ] dip [ close-x ] [ ] cleanup ; inline
+
+"io.backend.unix" vocab [ "x11.io.unix" require ] when
\ No newline at end of file
index e06872fa83456402e0f74de3f33638911106f268..54f20a28ddc70499a00afc6fb336db6e4879eddd 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings arrays byte-arrays
 hashtables io io.encodings.string kernel math namespaces
-sequences strings continuations x11.xlib specialized-arrays.uint
+sequences strings continuations x11 x11.xlib specialized-arrays.uint
 accessors io.encodings.utf16n ;
 IN: x11.xim
 
@@ -22,7 +22,7 @@ SYMBOL: xim
     xim get-global XCloseIM drop f xim set-global ;
 
 : with-xim ( quot -- )
-    [ "Factor" init-xim ] dip [ close-xim ] [ ] cleanup ;
+    [ "Factor" init-xim ] dip [ close-xim ] [ ] cleanup ; inline
 
 : create-xic ( window classname -- xic )
     [
index 3394de87b271cd9bdd9f4b24f9503281477f0c73..638f5c8d565ede521f3d127ba81a503d77d445cd 100644 (file)
@@ -13,7 +13,7 @@
 
 USING: kernel arrays alien alien.c-types alien.strings
 alien.syntax math math.bitwise words sequences namespaces
-continuations io io.encodings.ascii ;
+continuations io io.encodings.ascii x11.syntax ;
 IN: x11.xlib
 
 LIBRARY: xlib
@@ -71,26 +71,26 @@ C-STRUCT: Display
 { "void*" "free_funcs" }
 { "int" "fd" } ;
 
-FUNCTION: Display* XOpenDisplay ( void* display_name ) ;
+X-FUNCTION: Display* XOpenDisplay ( void* display_name ) ;
 
 ! 2.2 Obtaining Information about the Display, Image Formats, or Screens
 
-FUNCTION: ulong XBlackPixel ( Display* display, int screen_number ) ;
-FUNCTION: ulong XWhitePixel ( Display* display, int screen_number ) ;
-FUNCTION: Colormap XDefaultColormap ( Display* display, int screen_number ) ;
-FUNCTION: int XDefaultDepth ( Display* display, int screen_number ) ;
-FUNCTION: GC XDefaultGC ( Display* display, int screen_number ) ;
-FUNCTION: int XDefaultScreen ( Display* display ) ;
-FUNCTION: Window XRootWindow ( Display* display, int screen_number ) ;
-FUNCTION: Window XDefaultRootWindow ( Display* display ) ;
-FUNCTION: int XProtocolVersion ( Display* display ) ;
-FUNCTION: int XProtocolRevision ( Display* display ) ;
-FUNCTION: int XQLength ( Display* display ) ;
-FUNCTION: int XScreenCount ( Display* display ) ;
-FUNCTION: int XConnectionNumber ( Display* display ) ;
+X-FUNCTION: ulong XBlackPixel ( Display* display, int screen_number ) ;
+X-FUNCTION: ulong XWhitePixel ( Display* display, int screen_number ) ;
+X-FUNCTION: Colormap XDefaultColormap ( Display* display, int screen_number ) ;
+X-FUNCTION: int XDefaultDepth ( Display* display, int screen_number ) ;
+X-FUNCTION: GC XDefaultGC ( Display* display, int screen_number ) ;
+X-FUNCTION: int XDefaultScreen ( Display* display ) ;
+X-FUNCTION: Window XRootWindow ( Display* display, int screen_number ) ;
+X-FUNCTION: Window XDefaultRootWindow ( Display* display ) ;
+X-FUNCTION: int XProtocolVersion ( Display* display ) ;
+X-FUNCTION: int XProtocolRevision ( Display* display ) ;
+X-FUNCTION: int XQLength ( Display* display ) ;
+X-FUNCTION: int XScreenCount ( Display* display ) ;
+X-FUNCTION: int XConnectionNumber ( Display* display ) ;
 
 ! 2.5 Closing the Display
-FUNCTION: int XCloseDisplay ( Display* display ) ;
+X-FUNCTION: int XCloseDisplay ( Display* display ) ;
 
 !
 ! 3 - Window Functions
@@ -147,17 +147,17 @@ CONSTANT: StaticGravity         10
 
 ! 3.3 - Creating Windows
 
-FUNCTION: Window XCreateWindow ( Display* display, Window parent, int x, int y, uint width, uint height, uint border_width, int depth, uint class, Visual* visual, ulong valuemask, XSetWindowAttributes* attributes ) ;
-FUNCTION: Window XCreateSimpleWindow ( Display* display, Window parent, int x, int y, uint width, uint height, uint border_width, ulong border, ulong background ) ;
-FUNCTION: Status XDestroyWindow ( Display* display, Window w ) ;
-FUNCTION: Status XMapWindow ( Display* display, Window window ) ;
-FUNCTION: Status XMapSubwindows ( Display* display, Window window ) ;
-FUNCTION: Status XUnmapWindow ( Display* display, Window w ) ;
-FUNCTION: Status XUnmapSubwindows ( Display* display, Window w ) ;
+X-FUNCTION: Window XCreateWindow ( Display* display, Window parent, int x, int y, uint width, uint height, uint border_width, int depth, uint class, Visual* visual, ulong valuemask, XSetWindowAttributes* attributes ) ;
+X-FUNCTION: Window XCreateSimpleWindow ( Display* display, Window parent, int x, int y, uint width, uint height, uint border_width, ulong border, ulong background ) ;
+X-FUNCTION: Status XDestroyWindow ( Display* display, Window w ) ;
+X-FUNCTION: Status XMapWindow ( Display* display, Window window ) ;
+X-FUNCTION: Status XMapSubwindows ( Display* display, Window window ) ;
+X-FUNCTION: Status XUnmapWindow ( Display* display, Window w ) ;
+X-FUNCTION: Status XUnmapSubwindows ( Display* display, Window w ) ;
 
 ! 3.5 Mapping Windows
 
-FUNCTION: int XMapRaised ( Display* display, Window w ) ;
+X-FUNCTION: int XMapRaised ( Display* display, Window w ) ;
 
 ! 3.7 - Configuring Windows
 
@@ -178,25 +178,25 @@ C-STRUCT: XWindowChanges
         { "Window" "sibling" }
         { "int" "stack_mode" } ;
 
-FUNCTION: Status XConfigureWindow ( Display* display, Window w, uint value_mask, XWindowChanges* values ) ;
-FUNCTION: Status XMoveWindow ( Display* display, Window w, int x, int y ) ;
-FUNCTION: Status XResizeWindow ( Display* display, Window w, uint width, uint height ) ;
-FUNCTION: Status XSetWindowBorderWidth ( Display* display, ulong w, uint width ) ;
+X-FUNCTION: Status XConfigureWindow ( Display* display, Window w, uint value_mask, XWindowChanges* values ) ;
+X-FUNCTION: Status XMoveWindow ( Display* display, Window w, int x, int y ) ;
+X-FUNCTION: Status XResizeWindow ( Display* display, Window w, uint width, uint height ) ;
+X-FUNCTION: Status XSetWindowBorderWidth ( Display* display, ulong w, uint width ) ;
 
 
 ! 3.8 Changing Window Stacking Order
 
-FUNCTION: Status XRaiseWindow ( Display* display, Window w ) ;
-FUNCTION: Status XLowerWindow ( Display* display, Window w ) ;
+X-FUNCTION: Status XRaiseWindow ( Display* display, Window w ) ;
+X-FUNCTION: Status XLowerWindow ( Display* display, Window w ) ;
 
 ! 3.9 - Changing Window Attributes
 
-FUNCTION: Status XChangeWindowAttributes (
+X-FUNCTION: Status XChangeWindowAttributes (
   Display* display, Window w, ulong valuemask, XSetWindowAttributes* attr ) ;
-FUNCTION: Status XSetWindowBackground (
+X-FUNCTION: Status XSetWindowBackground (
   Display* display, Window w, ulong background_pixel ) ;
-FUNCTION: Status XDefineCursor ( Display* display, Window w, Cursor cursor ) ;
-FUNCTION: Status XUndefineCursor ( Display* display, Window w ) ;
+X-FUNCTION: Status XDefineCursor ( Display* display, Window w, Cursor cursor ) ;
+X-FUNCTION: Status XUndefineCursor ( Display* display, Window w ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 4 - Window Information Functions
@@ -204,7 +204,7 @@ FUNCTION: Status XUndefineCursor ( Display* display, Window w ) ;
 
 ! 4.1 - Obtaining Window Information
 
-FUNCTION: Status XQueryTree (
+X-FUNCTION: Status XQueryTree (
   Display* display,
   Window w,
   Window* root_return,
@@ -236,13 +236,13 @@ C-STRUCT: XWindowAttributes
         { "Bool" "override_redirect" }
         { "Screen*" "screen" } ;
 
-FUNCTION: Status XGetWindowAttributes ( Display* display, Window w, XWindowAttributes* attr ) ;
+X-FUNCTION: Status XGetWindowAttributes ( Display* display, Window w, XWindowAttributes* attr ) ;
 
 CONSTANT: IsUnmapped            0
 CONSTANT: IsUnviewable          1
 CONSTANT: IsViewable            2
 
-FUNCTION: Status XGetGeometry (
+X-FUNCTION: Status XGetGeometry (
   Display* display,
   Drawable d,
   Window* root_return,
@@ -255,27 +255,27 @@ FUNCTION: Status XGetGeometry (
 
 ! 4.2 - Translating Screen Coordinates
 
-FUNCTION: Bool XQueryPointer ( Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, uint* mask_return ) ;
+X-FUNCTION: Bool XQueryPointer ( Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, uint* mask_return ) ;
 
 ! 4.3 - Properties and Atoms
 
-FUNCTION: Atom XInternAtom ( Display* display, char* atom_name, Bool only_if_exists ) ;
+X-FUNCTION: Atom XInternAtom ( Display* display, char* atom_name, Bool only_if_exists ) ;
 
-FUNCTION: char* XGetAtomName ( Display* display, Atom atom ) ;
+X-FUNCTION: char* XGetAtomName ( Display* display, Atom atom ) ;
 
 ! 4.4 - Obtaining and Changing Window Properties
 
-FUNCTION: int XGetWindowProperty ( Display* display, Window w, Atom property, long long_offset, long long_length, Bool delete, Atom req_type, Atom* actual_type_return, int* actual_format_return, ulong* nitems_return, ulong* bytes_after_return, char** prop_return ) ;
+X-FUNCTION: int XGetWindowProperty ( Display* display, Window w, Atom property, long long_offset, long long_length, Bool delete, Atom req_type, Atom* actual_type_return, int* actual_format_return, ulong* nitems_return, ulong* bytes_after_return, char** prop_return ) ;
 
-FUNCTION: int XChangeProperty ( Display* display, Window w, Atom property, Atom type, int format, int mode, void* data, int nelements ) ;
+X-FUNCTION: int XChangeProperty ( Display* display, Window w, Atom property, Atom type, int format, int mode, void* data, int nelements ) ;
 
 ! 4.5 Selections
 
-FUNCTION: int XSetSelectionOwner ( Display* display, Atom selection, Window owner, Time time ) ;
+X-FUNCTION: int XSetSelectionOwner ( Display* display, Atom selection, Window owner, Time time ) ;
 
-FUNCTION: Window XGetSelectionOwner ( Display* display, Atom selection ) ;
+X-FUNCTION: Window XGetSelectionOwner ( Display* display, Atom selection ) ;
 
-FUNCTION: int XConvertSelection ( Display* display, Atom selection, Atom target, Atom property, Window requestor, Time time ) ;
+X-FUNCTION: int XConvertSelection ( Display* display, Atom selection, Atom target, Atom property, Window requestor, Time time ) ;
 
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -284,8 +284,8 @@ FUNCTION: int XConvertSelection ( Display* display, Atom selection, Atom target,
 
 ! 5.1 - Creating and Freeing Pixmaps
 
-FUNCTION: Pixmap XCreatePixmap ( Display* display, Drawable d, uint width, uint height, uint depth ) ;
-FUNCTION: int XFreePixmap ( Display* display, Pixmap pixmap ) ;
+X-FUNCTION: Pixmap XCreatePixmap ( Display* display, Drawable d, uint width, uint height, uint depth ) ;
+X-FUNCTION: int XFreePixmap ( Display* display, Pixmap pixmap ) ;
 
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -300,13 +300,13 @@ C-STRUCT: XColor
         { "char" "flags" }
         { "char" "pad" } ;
 
-FUNCTION: Status XLookupColor ( Display* display, Colormap colormap, char* color_name, XColor* exact_def_return, XColor* screen_def_return ) ;
-FUNCTION: Status XAllocColor ( Display* display, Colormap colormap, XColor* screen_in_out ) ;
-FUNCTION: Status XQueryColor ( Display* display, Colormap colormap, XColor* def_in_out ) ;
+X-FUNCTION: Status XLookupColor ( Display* display, Colormap colormap, char* color_name, XColor* exact_def_return, XColor* screen_def_return ) ;
+X-FUNCTION: Status XAllocColor ( Display* display, Colormap colormap, XColor* screen_in_out ) ;
+X-FUNCTION: Status XQueryColor ( Display* display, Colormap colormap, XColor* def_in_out ) ;
 
 ! 6.4 Creating, Copying, and Destroying Colormaps
 
-FUNCTION: Colormap XCreateColormap ( Display* display, Window w, Visual* visual, int alloc ) ;
+X-FUNCTION: Colormap XCreateColormap ( Display* display, Window w, Visual* visual, int alloc ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 7 - Graphics Context Functions
@@ -378,27 +378,27 @@ C-STRUCT: XGCValues
         { "int" "dash_offset" }
         { "char" "dashes" } ;
 
-FUNCTION: GC XCreateGC ( Display* display, Window d, ulong valuemask, XGCValues* values ) ;
-FUNCTION: int XChangeGC ( Display* display, GC gc, ulong valuemask, XGCValues* values ) ;
-FUNCTION: Status XGetGCValues ( Display* display, GC gc, ulong valuemask, XGCValues* values_return ) ;
-FUNCTION: Status XSetForeground ( Display* display, GC gc, ulong foreground ) ;
-FUNCTION: Status XSetBackground ( Display* display, GC gc, ulong background ) ;
-FUNCTION: Status XSetFunction ( Display* display, GC gc, int function ) ;
-FUNCTION: Status XSetSubwindowMode ( Display* display, GC gc, int subwindow_mode ) ;
+X-FUNCTION: GC XCreateGC ( Display* display, Window d, ulong valuemask, XGCValues* values ) ;
+X-FUNCTION: int XChangeGC ( Display* display, GC gc, ulong valuemask, XGCValues* values ) ;
+X-FUNCTION: Status XGetGCValues ( Display* display, GC gc, ulong valuemask, XGCValues* values_return ) ;
+X-FUNCTION: Status XSetForeground ( Display* display, GC gc, ulong foreground ) ;
+X-FUNCTION: Status XSetBackground ( Display* display, GC gc, ulong background ) ;
+X-FUNCTION: Status XSetFunction ( Display* display, GC gc, int function ) ;
+X-FUNCTION: Status XSetSubwindowMode ( Display* display, GC gc, int subwindow_mode ) ;
 
-FUNCTION: GContext XGContextFromGC ( GC gc ) ;
+X-FUNCTION: GContext XGContextFromGC ( GC gc ) ;
 
-FUNCTION: Status XSetFont ( Display* display, GC gc, Font font ) ;
+X-FUNCTION: Status XSetFont ( Display* display, GC gc, Font font ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 8 - Graphics Functions
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-FUNCTION: Status XClearWindow ( Display* display, Window w ) ;
-FUNCTION: Status XDrawPoint ( Display* display, Drawable d, GC gc, int x, int y ) ;
-FUNCTION: Status XDrawLine ( Display* display, Drawable d, GC gc, int x1, int y1, int x2, int y2 ) ;
-FUNCTION: Status XDrawArc ( Display* display, Drawable d, GC gc, int x, int y, uint width, uint height, int angle1, int angle2 ) ;
-FUNCTION: Status XFillArc ( Display* display, Drawable d, GC gc, int x, int y, uint width, uint height, int angle1, int angle2 ) ;
+X-FUNCTION: Status XClearWindow ( Display* display, Window w ) ;
+X-FUNCTION: Status XDrawPoint ( Display* display, Drawable d, GC gc, int x, int y ) ;
+X-FUNCTION: Status XDrawLine ( Display* display, Drawable d, GC gc, int x1, int y1, int x2, int y2 ) ;
+X-FUNCTION: Status XDrawArc ( Display* display, Drawable d, GC gc, int x, int y, uint width, uint height, int angle1, int angle2 ) ;
+X-FUNCTION: Status XFillArc ( Display* display, Drawable d, GC gc, int x, int y, uint width, uint height, int angle1, int angle2 ) ;
 
 ! 8.5 - Font Metrics
 
@@ -410,9 +410,9 @@ C-STRUCT: XCharStruct
         { "short" "descent" }
         { "ushort" "attributes" } ;
 
-FUNCTION: Font XLoadFont ( Display* display, char* name ) ;
-FUNCTION: XFontStruct* XQueryFont ( Display* display, XID font_ID ) ;
-FUNCTION: XFontStruct* XLoadQueryFont ( Display* display, char* name ) ;
+X-FUNCTION: Font XLoadFont ( Display* display, char* name ) ;
+X-FUNCTION: XFontStruct* XQueryFont ( Display* display, XID font_ID ) ;
+X-FUNCTION: XFontStruct* XLoadQueryFont ( Display* display, char* name ) ;
 
 C-STRUCT: XFontStruct
         { "XExtData*" "ext_data" }
@@ -432,11 +432,11 @@ C-STRUCT: XFontStruct
         { "int" "ascent" }
         { "int" "descent" } ;
 
-FUNCTION: int XTextWidth ( XFontStruct* font_struct, char* string, int count ) ;
+X-FUNCTION: int XTextWidth ( XFontStruct* font_struct, char* string, int count ) ;
 
 ! 8.6 - Drawing Text
 
-FUNCTION: Status XDrawString (
+X-FUNCTION: Status XDrawString (
         Display* display,
         Drawable d,
         GC gc,
@@ -479,8 +479,8 @@ C-STRUCT: XImage
     { "XPointer"     "obdata" }
     { "XImage-funcs" "f" } ;
 
-FUNCTION: XImage* XGetImage ( Display* display, Drawable d, int x, int y, uint width, uint height, ulong plane_mask, int format ) ;
-FUNCTION: int XDestroyImage ( XImage *ximage ) ;
+X-FUNCTION: XImage* XGetImage ( Display* display, Drawable d, int x, int y, uint width, uint height, ulong plane_mask, int format ) ;
+X-FUNCTION: int XDestroyImage ( XImage *ximage ) ;
 
 : XImage-size ( ximage -- size )
     [ XImage-height ] [ XImage-bytes_per_line ] bi * ;
@@ -492,12 +492,12 @@ FUNCTION: int XDestroyImage ( XImage *ximage ) ;
 ! 9 - Window and Session Manager Functions
 !
 
-FUNCTION: Status XReparentWindow ( Display* display, Window w, Window parent, int x, int y ) ;
-FUNCTION: Status XAddToSaveSet ( Display* display, Window w ) ;
-FUNCTION: Status XRemoveFromSaveSet ( Display* display, Window w ) ;
-FUNCTION: Status XGrabServer ( Display* display ) ;
-FUNCTION: Status XUngrabServer ( Display* display ) ;
-FUNCTION: Status XKillClient ( Display* display, XID resource ) ;
+X-FUNCTION: Status XReparentWindow ( Display* display, Window w, Window parent, int x, int y ) ;
+X-FUNCTION: Status XAddToSaveSet ( Display* display, Window w ) ;
+X-FUNCTION: Status XRemoveFromSaveSet ( Display* display, Window w ) ;
+X-FUNCTION: Status XGrabServer ( Display* display ) ;
+X-FUNCTION: Status XUngrabServer ( Display* display ) ;
+X-FUNCTION: Status XKillClient ( Display* display, XID resource ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 10 - Events
@@ -1066,11 +1066,11 @@ C-UNION: XEvent
 ! 11 - Event Handling Functions
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-FUNCTION: Status XSelectInput ( Display* display, Window w, long event_mask ) ;
-FUNCTION: Status XFlush ( Display* display ) ;
-FUNCTION: Status XSync ( Display* display, int discard ) ;
-FUNCTION: Status XNextEvent ( Display* display, XEvent* event ) ;
-FUNCTION: Status XMaskEvent ( Display* display, long event_mask, XEvent* event_return ) ;
+X-FUNCTION: Status XSelectInput ( Display* display, Window w, long event_mask ) ;
+X-FUNCTION: Status XFlush ( Display* display ) ;
+X-FUNCTION: Status XSync ( Display* display, int discard ) ;
+X-FUNCTION: Status XNextEvent ( Display* display, XEvent* event ) ;
+X-FUNCTION: Status XMaskEvent ( Display* display, long event_mask, XEvent* event_return ) ;
 
 ! 11.3 - Event Queue Management
 
@@ -1078,16 +1078,16 @@ CONSTANT: QueuedAlready 0
 CONSTANT: QueuedAfterReading 1
 CONSTANT: QueuedAfterFlush 2
 
-FUNCTION: int XEventsQueued ( Display* display, int mode ) ;
-FUNCTION: int XPending ( Display* display ) ;
+X-FUNCTION: int XEventsQueued ( Display* display, int mode ) ;
+X-FUNCTION: int XPending ( Display* display ) ;
 
 ! 11.6 - Sending Events to Other Applications
 
-FUNCTION: Status XSendEvent ( Display* display, Window w, Bool propagate, long event_mask, XEvent* event_send ) ;
+X-FUNCTION: Status XSendEvent ( Display* display, Window w, Bool propagate, long event_mask, XEvent* event_send ) ;
 
 ! 11.8 - Handling Protocol Errors
 
-FUNCTION: int XSetErrorHandler ( void* handler ) ;
+X-FUNCTION: int XSetErrorHandler ( void* handler ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 12 - Input Device Functions
@@ -1095,7 +1095,7 @@ FUNCTION: int XSetErrorHandler ( void* handler ) ;
 
 CONSTANT: None 0
 
-FUNCTION: int XGrabPointer (
+X-FUNCTION: int XGrabPointer (
   Display* display,
   Window grab_window,
   Bool owner_events,
@@ -1106,16 +1106,16 @@ FUNCTION: int XGrabPointer (
   Cursor cursor,
   Time time ) ;
 
-FUNCTION: Status XUngrabPointer ( Display* display, Time time ) ;
-FUNCTION: Status XChangeActivePointerGrab ( Display* display, uint event_mask, Cursor cursor, Time time ) ;
-FUNCTION: Status XGrabKey ( Display* display, int keycode, uint modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode ) ;
-FUNCTION: Status XSetInputFocus ( Display* display, Window focus, int revert_to, Time time ) ;
+X-FUNCTION: Status XUngrabPointer ( Display* display, Time time ) ;
+X-FUNCTION: Status XChangeActivePointerGrab ( Display* display, uint event_mask, Cursor cursor, Time time ) ;
+X-FUNCTION: Status XGrabKey ( Display* display, int keycode, uint modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode ) ;
+X-FUNCTION: Status XSetInputFocus ( Display* display, Window focus, int revert_to, Time time ) ;
 
-FUNCTION: Status XGetInputFocus ( Display* display,
+X-FUNCTION: Status XGetInputFocus ( Display* display,
                                   Window*  focus_return,
                                   int*     revert_to_return ) ;
 
-FUNCTION: Status XWarpPointer ( Display* display, Window src_w, Window dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y ) ;
+X-FUNCTION: Status XWarpPointer ( Display* display, Window src_w, Window dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 14 - Inter-Client Communication Functions
@@ -1123,15 +1123,15 @@ FUNCTION: Status XWarpPointer ( Display* display, Window src_w, Window dest_w, i
 
 ! 14.1 Client to Window Manager Communication
 
-FUNCTION: Status XFetchName ( Display* display, Window w, char** window_name_return ) ;
-FUNCTION: Status XGetTransientForHint ( Display* display, Window w, Window* prop_window_return ) ;
+X-FUNCTION: Status XFetchName ( Display* display, Window w, char** window_name_return ) ;
+X-FUNCTION: Status XGetTransientForHint ( Display* display, Window w, Window* prop_window_return ) ;
 
 ! 14.1.1.  Manipulating Top-Level Windows
 
-FUNCTION: Status XIconifyWindow (
+X-FUNCTION: Status XIconifyWindow (
         Display* display, Window w, int screen_number ) ;
 
-FUNCTION: Status XWithdrawWindow (
+X-FUNCTION: Status XWithdrawWindow (
         Display* display, Window w, int screen_number ) ;
 
 ! 14.1.6 - Setting and Reading the WM_HINTS Property
@@ -1173,10 +1173,10 @@ C-STRUCT: XSizeHints
 
 ! 14.1.10.  Setting and Reading the WM_PROTOCOLS Property
 
-FUNCTION: Status XSetWMProtocols (
+X-FUNCTION: Status XSetWMProtocols (
         Display* display, Window w, Atom* protocols, int count ) ;
 
-FUNCTION: Status XGetWMProtocols (
+X-FUNCTION: Status XGetWMProtocols (
         Display* display,
         Window w,
         Atom** protocols_return,
@@ -1188,9 +1188,9 @@ FUNCTION: Status XGetWMProtocols (
 
 ! 16.1 Keyboard Utility Functions
 
-FUNCTION: KeySym XLookupKeysym ( XKeyEvent* key_event, int index ) ;
+X-FUNCTION: KeySym XLookupKeysym ( XKeyEvent* key_event, int index ) ;
 
-FUNCTION: int XLookupString (
+X-FUNCTION: int XLookupString (
         XKeyEvent* event_struct,
         void* buffer_return,
         int bytes_buffer,
@@ -1227,7 +1227,7 @@ C-STRUCT: XVisualInfo
 ! Appendix D - Compatibility Functions
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-FUNCTION: Status XSetStandardProperties (
+X-FUNCTION: Status XSetStandardProperties (
         Display* display,
         Window w,
         char* window_name,
@@ -1314,10 +1314,10 @@ CONSTANT: XA_LAST_PREDEFINED 68
 ! The rest of the stuff is not from the book.
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-FUNCTION: void XFree ( void* data ) ;
-FUNCTION: int XStoreName ( Display* display, Window w, char* window_name ) ;
-FUNCTION: void XSetWMNormalHints ( Display* display, Window w, XSizeHints* hints ) ;
-FUNCTION: int XBell ( Display* display, int percent ) ;
+X-FUNCTION: void XFree ( void* data ) ;
+X-FUNCTION: int XStoreName ( Display* display, Window w, char* window_name ) ;
+X-FUNCTION: void XSetWMNormalHints ( Display* display, Window w, XSizeHints* hints ) ;
+X-FUNCTION: int XBell ( Display* display, int percent ) ;
 
 ! !!! INPUT METHODS
 
@@ -1381,23 +1381,23 @@ CONSTANT: XLookupChars     2
 CONSTANT: XLookupKeySym    3
 CONSTANT: XLookupBoth      4
 
-FUNCTION: Bool XFilterEvent ( XEvent* event, Window w ) ;
+X-FUNCTION: Bool XFilterEvent ( XEvent* event, Window w ) ;
 
-FUNCTION: XIM XOpenIM ( Display* dpy, void* rdb, char* res_name, char* res_class ) ;
+X-FUNCTION: XIM XOpenIM ( Display* dpy, void* rdb, char* res_name, char* res_class ) ;
 
-FUNCTION: Status XCloseIM ( XIM im ) ;
+X-FUNCTION: Status XCloseIM ( XIM im ) ;
 
-FUNCTION: XIC XCreateIC ( XIM im, char* key1, Window value1, char* key2, Window value2, char* key3, int value3, char* key4, char* value4, char* key5, char* value5, int key6 ) ;
+X-FUNCTION: XIC XCreateIC ( XIM im, char* key1, Window value1, char* key2, Window value2, char* key3, int value3, char* key4, char* value4, char* key5, char* value5, int key6 ) ;
 
-FUNCTION: void XDestroyIC ( XIC ic ) ;
+X-FUNCTION: void XDestroyIC ( XIC ic ) ;
 
-FUNCTION: void XSetICFocus ( XIC ic ) ;
+X-FUNCTION: void XSetICFocus ( XIC ic ) ;
         
-FUNCTION: void XUnsetICFocus ( XIC ic ) ;
+X-FUNCTION: void XUnsetICFocus ( XIC ic ) ;
 
-FUNCTION: int XwcLookupString ( XIC ic, XKeyPressedEvent* event, ulong* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
+X-FUNCTION: int XwcLookupString ( XIC ic, XKeyPressedEvent* event, ulong* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
 
-FUNCTION: int Xutf8LookupString ( XIC ic, XKeyPressedEvent* event, char* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
+X-FUNCTION: int Xutf8LookupString ( XIC ic, XKeyPressedEvent* event, char* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
 
 ! !!! category of setlocale
 CONSTANT: LC_ALL      0
@@ -1407,37 +1407,8 @@ CONSTANT: LC_MONETARY 3
 CONSTANT: LC_NUMERIC  4
 CONSTANT: LC_TIME     5
 
-FUNCTION: char* setlocale ( int category, char* name ) ;
+X-FUNCTION: char* setlocale ( int category, char* name ) ;
 
-FUNCTION: Bool XSupportsLocale ( ) ;
+X-FUNCTION: Bool XSupportsLocale ( ) ;
 
-FUNCTION: char* XSetLocaleModifiers ( char* modifier_list ) ;
-
-SYMBOL: dpy
-SYMBOL: scr
-SYMBOL: root
-
-: init-locale ( -- )
-   LC_ALL "" setlocale [ "setlocale() failed" print flush ] unless
-   XSupportsLocale [ "XSupportsLocale() failed" print flush ] unless ;
-
-: flush-dpy ( -- ) dpy get XFlush drop ;
-
-: x-atom ( string -- atom ) dpy get swap 0 XInternAtom ;
-
-: check-display ( alien -- alien' )
-    [
-        "Cannot connect to X server - check $DISPLAY" throw
-    ] unless* ;
-
-: initialize-x ( display-string -- )
-    init-locale
-    dup [ ascii string>alien ] when
-    XOpenDisplay check-display dpy set-global
-    dpy get XDefaultScreen scr set-global
-    dpy get scr get XRootWindow root set-global ;
-
-: close-x ( -- ) dpy get XCloseDisplay drop ;
-
-: with-x ( display-string quot -- )
-    [ initialize-x ] dip [ close-x ] [ ] cleanup ;
+X-FUNCTION: char* XSetLocaleModifiers ( char* modifier_list ) ;
index 2fec39f14a791ceb8e5aec684934d5cb50298b01..53aab9ad045c0e5c6628243cac88a6b6ab06d1be 100755 (executable)
@@ -139,7 +139,6 @@ check_library_exists() {
 }
 
 check_X11_libraries() {
-    check_library_exists GLU
     check_library_exists GL
     check_library_exists X11
     check_library_exists pango-1.0
@@ -491,7 +490,7 @@ make_boot_image() {
 }
 
 install_build_system_apt() {
-    sudo apt-get --yes install libc6-dev libpango1.0-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
+    sudo apt-get --yes install libc6-dev libpango1.0-dev libx11-dev xorg-dev wget git-core git-doc rlwrap gcc make
     check_ret sudo
 }
 
index 6bd1d2f53a429f23a034eccfa356d19a2f27e55f..66e67ab32263ad8231588b72f644729c6db9f972 100644 (file)
@@ -145,12 +145,6 @@ ARTICLE: "reading-writing-memory" "Reading and writing memory directly"
 { $subsection set-alien-float }
 { $subsection set-alien-double } ;
 
-ARTICLE: "loading-libs" "Loading native libraries"
-"Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
-{ $subsection add-library }
-"Once a library has been defined, you can try loading it to see if the path name is correct:"
-{ $subsection load-library } ;
-
 ARTICLE: "alien-invoke" "Calling C from Factor"
 "The easiest way to call into a C library is to define bindings using a pair of parsing words:"
 { $subsection POSTPONE: LIBRARY: }
diff --git a/core/bootstrap/syntax-docs.factor b/core/bootstrap/syntax-docs.factor
new file mode 100644 (file)
index 0000000..e69de29
index 673c108b2737df41c677fd6dcd7ee20e0680b64c..08746d1ba7db5a0e6829e9b785e135e45a81d7f6 100644 (file)
@@ -29,10 +29,10 @@ M: method-forget-class method-forget-test ;
 ] unit-test
 
 ! Minor leak
-[ ] [ "IN: classes.tests TUPLE: forget-me ;" eval ] unit-test
+[ ] [ "IN: classes.tests TUPLE: forget-me ;" eval( -- ) ] unit-test
 [ ] [ f \ word set-global ] unit-test
-[ ] [ "IN: classes.tests USE: kernel USE: classes.algebra forget-me tuple class<= drop" eval ] unit-test
-[ ] [ "IN: classes.tests FORGET: forget-me" eval ] unit-test
+[ ] [ "IN: classes.tests USE: kernel USE: classes.algebra forget-me tuple class<= drop" eval( -- ) ] unit-test
+[ ] [ "IN: classes.tests FORGET: forget-me" eval( -- ) ] unit-test
 [ 0 ] [
     [ word? ] instances
     [ [ name>> "forget-me" = ] [ vocabulary>> "classes.tests" = ] bi and ] count
index 376eace4ed5c887ec5017c0dfde6536aae2b16ea..cd11591d6c3de001587fea2bbac35d62b83feb90 100644 (file)
@@ -42,7 +42,7 @@ INSTANCE: integer mx1
 [ t ] [ mx1 integer class<= ] unit-test
 [ t ] [ mx1 number class<= ] unit-test
 
-"IN: classes.mixin.tests USE: arrays INSTANCE: array mx1" eval
+"IN: classes.mixin.tests USE: arrays INSTANCE: array mx1" eval( -- )
 
 [ t ] [ array mx1 class<= ] unit-test
 [ f ] [ mx1 number class<= ] unit-test
@@ -118,4 +118,4 @@ MIXIN: move-instance-declaration-mixin
 
 [ ] [ "IN: classes.mixin.tests.a" <string-reader> "move-mixin-test-1" parse-stream drop ] unit-test
 
-[ { string } ] [ move-instance-declaration-mixin members ] unit-test
\ No newline at end of file
+[ { string } ] [ move-instance-declaration-mixin members ] unit-test
index 22b578426914e0d03001212476d32e458c9fad0f..b95507c78b346a794275b80375055bab7dab4620 100644 (file)
@@ -50,20 +50,20 @@ TUPLE: test-8 { b integer read-only } ;
 
 DEFER: foo
 
-[ "IN: classes.tuple.parser.tests TUPLE: foo < test-1 < ;" eval ]
+[ "IN: classes.tuple.parser.tests TUPLE: foo < test-1 < ;" eval( -- ) ]
 [ error>> invalid-slot-name? ]
 must-fail-with
 
-[ "IN: classes.tuple.parser.tests TUPLE: foo :" eval ]
+[ "IN: classes.tuple.parser.tests TUPLE: foo :" eval( -- ) ]
 [ error>> invalid-slot-name? ]
 must-fail-with
 
-[ "IN: classes.tuple.parser.tests TUPLE: foo" eval ]
+[ "IN: classes.tuple.parser.tests TUPLE: foo" eval( -- ) ]
 [ error>> unexpected-eof? ]
 must-fail-with
 
 2 [
-    [ "IN: classes.tuple.parser.tests USE: alien TUPLE: foo { slot dll } ;" eval ]
+    [ "IN: classes.tuple.parser.tests USE: alien TUPLE: foo { slot dll } ;" eval( -- ) ]
     [ error>> no-initial-value? ]
     must-fail-with
 
@@ -71,14 +71,14 @@ must-fail-with
 ] times
 
 2 [
-    [ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo { slot array initial: 5 } ;" eval ]
+    [ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo { slot array initial: 5 } ;" eval( -- ) ]
     [ error>> bad-initial-value? ]
     must-fail-with
 
     [ f ] [ \ foo tuple-class? ] unit-test
 ] times
 
-[ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo slot { slot array } ;" eval ]
+[ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo slot { slot array } ;" eval( -- ) ]
 [ error>> duplicate-slot-names? ]
 must-fail-with
 
@@ -107,7 +107,7 @@ TUPLE: parsing-corner-case x ;
         "    f"
         "    3"
         "}"
-    } "\n" join eval
+    } "\n" join eval( -- tuple )
 ] unit-test
 
 [ T{ parsing-corner-case f 3 } ] [
@@ -116,7 +116,7 @@ TUPLE: parsing-corner-case x ;
         "T{ parsing-corner-case"
         "    { x 3 }"
         "}"
-    } "\n" join eval
+    } "\n" join eval( -- tuple )
 ] unit-test
 
 [ T{ parsing-corner-case f 3 } ] [
@@ -125,7 +125,7 @@ TUPLE: parsing-corner-case x ;
         "T{ parsing-corner-case {"
         "    x 3 }"
         "}"
-    } "\n" join eval
+    } "\n" join eval( -- tuple )
 ] unit-test
 
 
@@ -133,12 +133,12 @@ TUPLE: parsing-corner-case x ;
     {
         "USE: classes.tuple.parser.tests T{ parsing-corner-case"
         "    { x 3 }"
-    } "\n" join eval
+    } "\n" join eval( -- tuple )
 ] [ error>> unexpected-eof? ] must-fail-with
 
 [
     {
         "USE: classes.tuple.parser.tests T{ parsing-corner-case {"
         "    x 3 }"
-    } "\n" join eval
+    } "\n" join eval( -- tuple )
 ] [ error>> unexpected-eof? ] must-fail-with
index 75d733b213213c7d22e35224a62a35c4bd13943c..68cdc20c538748de3655dcbec32ab496aea82bc5 100644 (file)
@@ -27,7 +27,7 @@ C: <redefinition-test> redefinition-test
 
 [ t ] [ "redefinition-test" get redefinition-test? ] unit-test
 
-"IN: classes.tuple.tests TUPLE: redefinition-test ;" eval
+"IN: classes.tuple.tests TUPLE: redefinition-test ;" eval( -- )
 
 [ t ] [ "redefinition-test" get redefinition-test? ] unit-test
 
@@ -39,7 +39,7 @@ C: <point> point
 [ ] [ 100 200 <point> "p" set ] unit-test
 
 ! Use eval to sequence parsing explicitly
-[ ] [ "IN: classes.tuple.tests TUPLE: point x y z ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: point x y z ;" eval( -- ) ] unit-test
 
 [ 100 ] [ "p" get x>> ] unit-test
 [ 200 ] [ "p" get y>> ] unit-test
@@ -51,7 +51,7 @@ C: <point> point
 
 [ 300 ] [ "p" get "z>>" "accessors" lookup execute ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: point z y ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: point z y ;" eval( -- ) ] unit-test
 
 [ 2 ] [ "p" get tuple-size ] unit-test
 
@@ -89,7 +89,7 @@ C: <empty> empty
 [ t length ] [ object>> t eq? ] must-fail-with
 
 [ "<constructor-test>" ]
-[ "IN: classes.tuple.test TUPLE: constructor-test ; C: <constructor-test> constructor-test" eval word name>> ] unit-test
+[ "IN: classes.tuple.test TUPLE: constructor-test ; C: <constructor-test> constructor-test" eval( -- ) word name>> ] unit-test
 
 TUPLE: size-test a b c d ;
 
@@ -102,7 +102,7 @@ GENERIC: <yo-momma> ( a -- b )
 
 TUPLE: yo-momma ;
 
-[ ] [ "IN: classes.tuple.tests C: <yo-momma> yo-momma" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests C: <yo-momma> yo-momma" eval( -- ) ] unit-test
 
 [ f ] [ \ <yo-momma> generic? ] unit-test
 
@@ -204,7 +204,7 @@ C: <erg's-reshape-problem> erg's-reshape-problem
 : cons-test-1 ( -- tuple ) \ erg's-reshape-problem new ;
 : cons-test-2 ( a b c d -- tuple ) \ erg's-reshape-problem boa ;
 
-[ ] [ "IN: classes.tuple.tests TUPLE: erg's-reshape-problem a b c d e f ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: erg's-reshape-problem a b c d e f ;" eval( -- ) ] unit-test
 
 [ ] [ 1 2 3 4 5 6 cons-test-2 "a" set ] unit-test
 
@@ -281,13 +281,13 @@ test-server-slot-values
 ] unit-test
 
 [
-    "IN: classes.tuple.tests TUPLE: bad-superclass < word ;" eval
+    "IN: classes.tuple.tests TUPLE: bad-superclass < word ;" eval( -- )
 ] must-fail
 
 ! Dynamically changing inheritance hierarchy
 TUPLE: electronic-device ;
 
-[ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram ;" eval( -- ) ] unit-test
 
 [ f ] [ electronic-device laptop class<= ] unit-test
 [ t ] [ server electronic-device class<= ] unit-test
@@ -303,17 +303,17 @@ TUPLE: electronic-device ;
 [ f ] [ "server" get laptop? ] unit-test
 [ t ] [ "server" get server? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: computer cpu ram ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: computer cpu ram ;" eval( -- ) ] unit-test
 
 [ f ] [ "laptop" get electronic-device? ] unit-test
 [ t ] [ "laptop" get computer? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram disk ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram disk ;" eval( -- ) ] unit-test
 
 test-laptop-slot-values
 test-server-slot-values
 
-[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ;" eval( -- ) ] unit-test
 
 test-laptop-slot-values
 test-server-slot-values
@@ -326,7 +326,7 @@ TUPLE: make-me-some-accessors voltage grounded? ;
 [ ] [ "laptop" get 220 >>voltage drop ] unit-test
 [ ] [ "server" get 110 >>voltage drop ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage grounded? ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage grounded? ;" eval( -- ) ] unit-test
 
 test-laptop-slot-values
 test-server-slot-values
@@ -334,7 +334,7 @@ test-server-slot-values
 [ 220 ] [ "laptop" get voltage>> ] unit-test
 [ 110 ] [ "server" get voltage>> ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device grounded? voltage ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device grounded? voltage ;" eval( -- ) ] unit-test
 
 test-laptop-slot-values
 test-server-slot-values
@@ -343,7 +343,7 @@ test-server-slot-values
 [ 110 ] [ "server" get voltage>> ] unit-test
 
 ! Reshaping superclass and subclass simultaneously
-[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ; TUPLE: computer < electronic-device cpu ram ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ; TUPLE: computer < electronic-device cpu ram ;" eval( -- ) ] unit-test
 
 test-laptop-slot-values
 test-server-slot-values
@@ -364,11 +364,11 @@ C: <test2> test2
 
 test-a/b
 
-[ ] [ "IN: classes.tuple.tests TUPLE: test1 a x ; TUPLE: test2 < test1 b y ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: test1 a x ; TUPLE: test2 < test1 b y ;" eval( -- ) ] unit-test
 
 test-a/b
 
-[ ] [ "IN: classes.tuple.tests TUPLE: test1 a ; TUPLE: test2 < test1 b ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: test1 a ; TUPLE: test2 < test1 b ;" eval( -- ) ] unit-test
 
 test-a/b
 
@@ -393,19 +393,19 @@ T{ move-up-2 f "a" "b" "c" } "move-up" set
 
 test-move-up
 
-[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a b c ; TUPLE: move-up-2 < move-up-1 ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a b c ; TUPLE: move-up-2 < move-up-1 ;" eval( -- ) ] unit-test
 
 test-move-up
 
-[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a c ; TUPLE: move-up-2 < move-up-1 b ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a c ; TUPLE: move-up-2 < move-up-1 b ;" eval( -- ) ] unit-test
 
 test-move-up
 
-[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 c ; TUPLE: move-up-2 < move-up-1 b a ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 c ; TUPLE: move-up-2 < move-up-1 b a ;" eval( -- ) ] unit-test
 
 test-move-up
 
-[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 ; TUPLE: move-up-2 < move-up-1 a b c ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 ; TUPLE: move-up-2 < move-up-1 a b c ;" eval( -- ) ] unit-test
 
 ! Constructors must be recompiled when changing superclass
 TUPLE: constructor-update-1 xxx ;
@@ -416,7 +416,7 @@ C: <constructor-update-2> constructor-update-2
 
 { 3 1 } [ <constructor-update-2> ] must-infer-as
 
-[ ] [ "IN: classes.tuple.tests TUPLE: constructor-update-1 xxx ttt www ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: constructor-update-1 xxx ttt www ;" eval( -- ) ] unit-test
 
 { 5 1 } [ <constructor-update-2> ] must-infer-as
 
@@ -431,7 +431,7 @@ UNION: redefinition-problem' redefinition-problem integer ;
 
 TUPLE: redefinition-problem-2 ;
 
-"IN: classes.tuple.tests TUPLE: redefinition-problem < redefinition-problem-2 ;" eval
+"IN: classes.tuple.tests TUPLE: redefinition-problem < redefinition-problem-2 ;" eval( -- )
 
 [ t ] [ 3 redefinition-problem'? ] unit-test
 
@@ -472,7 +472,7 @@ USE: vocabs
     ] with-compilation-unit
 ] unit-test
 
-[ "USE: words T{ word }" eval ]
+[ "USE: words T{ word }" eval( -- ) ]
 [ error>> T{ no-method f word new } = ]
 must-fail-with
 
@@ -485,7 +485,7 @@ must-fail-with
 
 [ t ] [ "forget-accessors-test" "classes.tuple.tests" lookup class? ] unit-test
 
-: accessor-exists? ( class name -- ? )
+: accessor-exists? ( name -- ? )
     [ "forget-accessors-test" "classes.tuple.tests" lookup ] dip
     ">>" append "accessors" lookup method >boolean ;
 
@@ -520,13 +520,13 @@ TUPLE: another-forget-accessors-test ;
 [ f ] [
     t parser-notes? [
         [
-            "IN: classes.tuple.tests TUPLE: shadow-1 a b ; TUPLE: shadow-2 < shadow-1 a b ;" eval
+            "IN: classes.tuple.tests TUPLE: shadow-1 a b ; TUPLE: shadow-2 < shadow-1 a b ;" eval( -- )
         ] with-string-writer empty?
     ] with-variable
 ] unit-test
 
 ! Missing error check
-[ "IN: classes.tuple.tests USE: words TUPLE: wrong-superclass < word ;" eval ] must-fail
+[ "IN: classes.tuple.tests USE: words TUPLE: wrong-superclass < word ;" eval( -- ) ] must-fail
 
 ! Class forget messyness
 TUPLE: subclass-forget-test ;
@@ -535,7 +535,7 @@ TUPLE: subclass-forget-test-1 < subclass-forget-test ;
 TUPLE: subclass-forget-test-2 < subclass-forget-test ;
 TUPLE: subclass-forget-test-3 < subclass-forget-test-2 ;
 
-[ ] [ "IN: classes.tuple.tests FORGET: subclass-forget-test" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests FORGET: subclass-forget-test" eval( -- ) ] unit-test
 
 [ { subclass-forget-test-2 } ]
 [ subclass-forget-test-2 class-usages ]
@@ -549,7 +549,7 @@ unit-test
 [ f ] [ subclass-forget-test-2 tuple-class? ] unit-test
 [ subclass-forget-test-3 new ] must-fail
 
-[ "IN: classes.tuple.tests TUPLE: subclass-forget-test-4 < subclass-forget-test-2 ;" eval ] must-fail
+[ "IN: classes.tuple.tests TUPLE: subclass-forget-test-4 < subclass-forget-test-2 ;" eval( -- ) ] must-fail
 
 ! More
 DEFER: subclass-reset-test
@@ -562,11 +562,11 @@ GENERIC: break-me ( obj -- )
 [ ] [ [ M\ integer break-me forget ] with-compilation-unit ] unit-test
 
 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
-[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-1 < subclass-reset-test ;" eval ] unit-test
-[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-2 < subclass-reset-test ;" eval ] unit-test
-[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-3 < subclass-reset-test-2 ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-1 < subclass-reset-test ;" eval( -- ) ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-2 < subclass-reset-test ;" eval( -- ) ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-3 < subclass-reset-test-2 ;" eval( -- ) ] unit-test
 
-[ ] [ "IN: classes.tuple.tests USE: kernel M: subclass-reset-test-1 break-me drop ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests USE: kernel M: subclass-reset-test-1 break-me drop ;" eval( -- ) ] unit-test
 
 [ ] [ "IN: classes.tuple.tests : subclass-reset-test ( -- ) ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
 
@@ -576,7 +576,7 @@ GENERIC: break-me ( obj -- )
 
 [ t ] [ \ break-me "methods" word-prop assoc-empty? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests USE: math USE: kernel M: integer break-me drop ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests USE: math USE: kernel M: integer break-me drop ;" eval( -- ) ] unit-test
 
 [ f ] [ \ break-me "methods" word-prop assoc-empty? ] unit-test
 
@@ -632,7 +632,7 @@ TUPLE: reshape-test x ;
 
 T{ reshape-test f "hi" } "tuple" set
 
-[ ] [ "IN: classes.tuple.tests TUPLE: reshape-test { x read-only } ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: reshape-test { x read-only } ;" eval( -- ) ] unit-test
 
 [ f ] [ \ reshape-test \ (>>x) method ] unit-test
 
@@ -640,11 +640,11 @@ T{ reshape-test f "hi" } "tuple" set
 
 [ "hi" ] [ "tuple" get x>> ] unit-test
 
-[ ] [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x integer read-only } ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x integer read-only } ;" eval( -- ) ] unit-test
 
 [ 0 ] [ "tuple" get x>> ] unit-test
 
-[ ] [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x fixnum initial: 4 read-only } ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x fixnum initial: 4 read-only } ;" eval( -- ) ] unit-test
 
 [ 0 ] [ "tuple" get x>> ] unit-test
 
@@ -660,20 +660,20 @@ ERROR: error-class-test a b c ;
 [ "( a b c -- * )" ] [ \ error-class-test stack-effect effect>string ] unit-test
 [ f ] [ \ error-class-test "inline" word-prop ] unit-test
 
-[ "IN: classes.tuple.tests ERROR: error-x ; : error-x 3 ;" eval ]
+[ "IN: classes.tuple.tests ERROR: error-x ; : error-x 3 ;" eval( -- ) ]
 [ error>> error>> redefine-error? ] must-fail-with
 
 DEFER: error-y
 
 [ ] [ [ \ error-y dup class? [ forget-class ] [ drop ] if ] with-compilation-unit ] unit-test
 
-[ ] [ "IN: classes.tuple.tests GENERIC: error-y ( a -- b )" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests GENERIC: error-y ( a -- b )" eval( -- ) ] unit-test
 
 [ f ] [ \ error-y tuple-class? ] unit-test
 
 [ t ] [ \ error-y generic? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests ERROR: error-y ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests ERROR: error-y ;" eval( -- ) ] unit-test
 
 [ t ] [ \ error-y tuple-class? ] unit-test
 
@@ -694,7 +694,7 @@ DEFER: error-y
 ] unit-test
 
 [ ] [
-    "IN: sequences TUPLE: reversed { seq read-only } ;" eval
+    "IN: sequences TUPLE: reversed { seq read-only } ;" eval( -- )
 ] unit-test
 
 TUPLE: bogus-hashcode-1 x ;
@@ -735,14 +735,14 @@ SLOT: kex
 
 DEFER: redefine-tuple-twice
 
-[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval( -- ) ] unit-test
 
 [ t ] [ \ redefine-tuple-twice symbol? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests DEFER: redefine-tuple-twice" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests DEFER: redefine-tuple-twice" eval( -- ) ] unit-test
 
 [ t ] [ \ redefine-tuple-twice deferred? ] unit-test
 
-[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval( -- ) ] unit-test
 
-[ t ] [ \ redefine-tuple-twice symbol? ] unit-test
\ No newline at end of file
+[ t ] [ \ redefine-tuple-twice symbol? ] unit-test
index 57b742595ffcc7f5ef06d4787a960cf9bf0e7d94..52550b2356aa46f2e845aa8ffa282cba13ead9ed 100644 (file)
@@ -26,13 +26,13 @@ M: union-1 generic-update-test drop "union-1" ;
 [ t ] [ union-1 number class<= ] unit-test
 [ "union-1" ] [ 1.0 generic-update-test ] unit-test
 
-"IN: classes.union.tests USE: math USE: arrays UNION: union-1 rational array ;" eval
+"IN: classes.union.tests USE: math USE: arrays UNION: union-1 rational array ;" eval( -- )
 
 [ t ] [ bignum union-1 class<= ] unit-test
 [ f ] [ union-1 number class<= ] unit-test
 [ "union-1" ] [ { 1.0 } generic-update-test ] unit-test
 
-"IN: classes.union.tests USE: math PREDICATE: union-1 < integer even? ;" eval
+"IN: classes.union.tests USE: math PREDICATE: union-1 < integer even? ;" eval( -- )
 
 [ f ] [ union-1 union-class? ] unit-test
 [ t ] [ union-1 predicate-class? ] unit-test
@@ -58,7 +58,7 @@ UNION: redefine-bug-2 redefine-bug-1 quotation ;
 [ t ] [ fixnum redefine-bug-2 class<= ] unit-test
 [ t ] [ quotation redefine-bug-2 class<= ] unit-test
 
-[ ] [ "IN: classes.union.tests USE: math UNION: redefine-bug-1 bignum ;" eval ] unit-test
+[ ] [ "IN: classes.union.tests USE: math UNION: redefine-bug-1 bignum ;" eval( -- ) ] unit-test
 
 [ t ] [ bignum redefine-bug-1 class<= ] unit-test
 [ f ] [ fixnum redefine-bug-2 class<= ] unit-test
index 76f9f63c49be13be25f66bd60a7e08af227d05c4..a8049f709ec46795dd3ee4afd1b9fed840f1bd5d 100644 (file)
@@ -357,7 +357,7 @@ DEFER: corner-case-1
 
 [ 4 ] [ 2 2 [ + ] curry 1array case ] unit-test
 
-: test-case-8 ( n -- )
+: test-case-8 ( n -- string )
     {
         { 1 [ "foo" ] }
     } case ;
index 4c600e06ca76bee4ed4c2e683e589c0176431489..1438edf3fa2dbfa88dda86389bb6edfbadec0ff4 100755 (executable)
@@ -86,6 +86,8 @@ ERROR: no-case object ;
         ] [ callable? ] if
     ] find nip ;
 
+\ case-find t "no-compile" set-word-prop
+
 : case ( obj assoc -- )
     case-find {
         { [ dup array? ] [ nip second call ] }
diff --git a/core/compiler/errors/authors.txt b/core/compiler/errors/authors.txt
deleted file mode 100755 (executable)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/core/compiler/errors/errors-docs.factor b/core/compiler/errors/errors-docs.factor
deleted file mode 100644 (file)
index 8368afe..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-IN: compiler.errors
-USING: help.markup help.syntax vocabs.loader words io
-quotations words.symbol ;
-
-ARTICLE: "compiler-errors" "Compiler warnings and errors"
-"After loading a vocabulary, you might see messages like:"
-{ $code
-    ":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 erroneous stack effect declarations."
-$nl
-"The precise warning and error conditions are documented in " { $link "inference-errors" } "."
-$nl
-"Words to view warnings and errors:"
-{ $subsection :errors }
-{ $subsection :warnings }
-{ $subsection :linkage }
-"Words such as " { $link require } " use a combinator which counts errors and prints a report at the end:"
-{ $subsection with-compiler-errors } ;
-
-HELP: compiler-errors
-{ $var-description "Global variable holding an assoc mapping words to compiler errors. This variable is set by " { $link with-compiler-errors } "." } ;
-
-ABOUT: "compiler-errors"
-
-HELP: compiler-error
-{ $values { "error" "an error" } { "word" word } }
-{ $description "If inside a " { $link with-compiler-errors } ", saves the error for future persual via " { $link :errors } ", " { $link :warnings } " and " { $link :linkage } ". If not inside a " { $link with-compiler-errors } ", ignores the error." } ;
-
-HELP: compiler-error.
-{ $values { "error" "an error" } { "word" word } }
-{ $description "Prints a compiler error to " { $link output-stream } "." } ;
-
-HELP: compiler-errors.
-{ $values { "type" symbol } }
-{ $description "Prints compiler errors to " { $link output-stream } ". The type parameter is one of " { $link +error+ } ", " { $link +warning+ } ", or " { $link +linkage+ } "." } ;
-HELP: :errors
-{ $description "Prints all serious compiler errors from the most recent compile to " { $link output-stream } "." } ;
-
-HELP: :warnings
-{ $description "Prints all ignorable compiler warnings from the most recent compile to " { $link output-stream } "." } ;
-
-HELP: :linkage
-{ $description "Prints all C library interface linkage errors from the most recent compile to " { $link output-stream } "." } ;
-
-{ :errors :warnings } related-words
-
-HELP: with-compiler-errors
-{ $values { "quot" quotation } }
-{ $description "Calls the quotation and collects any compiler warnings and errors. Compiler warnings and errors are summarized at the end and can be viewed with " { $link :errors } ", " { $link :warnings } ", and " { $link :linkage } "." }
-{ $notes "Nested calls to " { $link with-compiler-errors } " are ignored, and only the outermost call collects warnings and errors." } ;
diff --git a/core/compiler/errors/errors.factor b/core/compiler/errors/errors.factor
deleted file mode 100644 (file)
index 1ea497c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces make assocs io sequences
-sorting continuations math math.parser ;
-IN: compiler.errors
-
-SYMBOL: +error+
-SYMBOL: +warning+
-SYMBOL: +linkage+
-
-GENERIC: compiler-error-type ( error -- ? )
-
-M: object compiler-error-type drop +error+ ;
-
-GENERIC# compiler-error. 1 ( error word -- )
-
-SYMBOL: compiler-errors
-
-SYMBOL: with-compiler-errors?
-
-: errors-of-type ( type -- assoc )
-    compiler-errors get-global
-    swap [ [ nip compiler-error-type ] dip eq? ] curry
-    assoc-filter ;
-
-: compiler-errors. ( type -- )
-    errors-of-type >alist sort-keys
-    [ swap compiler-error. ] assoc-each ;
-
-: (compiler-report) ( what type word -- )
-    over errors-of-type assoc-empty? [ 3drop ] [
-        [
-            ":" %
-            %
-            " - print " %
-            errors-of-type assoc-size #
-            " " %
-            %
-            "." %
-        ] "" make print
-    ] if ;
-
-: compiler-report ( -- )
-    "semantic errors" +error+ "errors" (compiler-report)
-    "semantic warnings" +warning+ "warnings" (compiler-report)
-    "linkage errors" +linkage+ "linkage" (compiler-report) ;
-
-: :errors ( -- ) +error+ compiler-errors. ;
-
-: :warnings ( -- ) +warning+ compiler-errors. ;
-
-: :linkage ( -- ) +linkage+ compiler-errors. ;
-
-: compiler-error ( error word -- )
-    with-compiler-errors? get [
-        compiler-errors get pick
-        [ set-at ] [ delete-at drop ] if
-    ] [ 2drop ] if ;
-
-: with-compiler-errors ( quot -- )
-    with-compiler-errors? get "quiet" get or [ call ] [
-        [
-            with-compiler-errors? on
-            V{ } clone compiler-errors set-global
-            [ compiler-report ] [ ] cleanup
-        ] with-scope
-    ] if ; inline
diff --git a/core/compiler/errors/summary.txt b/core/compiler/errors/summary.txt
deleted file mode 100755 (executable)
index 01d106b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compiler warning and error reporting
index d84b377f361d92256d69b0bcc455f08dfeaf5f20..03c68815ccc1bfceff373d951f598f93f55c77b6 100644 (file)
@@ -1,6 +1,6 @@
-IN: compiler.units.tests
 USING: definitions compiler.units tools.test arrays sequences words kernel
-accessors namespaces fry ;
+accessors namespaces fry eval ;
+IN: compiler.units.tests
 
 [ [ [ ] define-temp ] with-compilation-unit ] must-infer
 [ [ [ ] define-temp ] with-nested-compilation-unit ] must-infer
@@ -30,4 +30,32 @@ accessors namespaces fry ;
         "a" get [ "B" ] define
     ] with-compilation-unit
     "b" get execute
-] unit-test
\ No newline at end of file
+] unit-test
+
+! Notify observers even if compilation unit did nothing
+SINGLETON: observer
+
+observer add-definition-observer
+
+SYMBOL: counter
+
+0 counter set-global
+
+M: observer definitions-changed 2drop global [ counter inc ] bind ;
+
+[ ] with-compilation-unit
+
+[ 1 ] [ counter get-global ] unit-test
+
+observer remove-definition-observer
+
+! Notify observers with nested compilation units
+observer add-definition-observer
+
+0 counter set-global
+
+DEFER: nesting-test
+
+[ ] [ "IN: compiler.units.tests << : nesting-test ( -- ) ; >>" eval( -- ) ] unit-test
+
+observer remove-definition-observer
index afa05f94426e20657ff84a932902518a27e08e22..a278bf0d5ecf4a90f38624a3bab0bfe3ff2f704a 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors arrays kernel continuations assocs namespaces
 sequences words vocabs definitions hashtables init sets
 math math.order classes classes.algebra classes.tuple
-classes.tuple.private generic ;
+classes.tuple.private generic source-files.errors ;
 IN: compiler.units
 
 SYMBOL: old-definitions
@@ -62,7 +62,7 @@ GENERIC: definitions-changed ( assoc obj -- )
     definition-observers get push ;
 
 : remove-definition-observer ( obj -- )
-    definition-observers get delete ;
+    definition-observers get delq ;
 
 : notify-definition-observers ( assoc -- )
     definition-observers get
@@ -132,17 +132,20 @@ GENERIC: definitions-changed ( assoc obj -- )
     changed-generics get compiled-generic-usages
     append assoc-combine keys ;
 
-: unxref-forgotten-definitions ( -- )
-    forgotten-definitions get
-    keys [ word? ] filter
-    [ delete-compiled-xref ] each ;
+: process-forgotten-definitions ( -- )
+    forgotten-definitions get keys
+    [ [ word? ] filter [ delete-compiled-xref ] each ]
+    [ [ delete-definition-errors ] each ]
+    bi ;
 
 : finish-compilation-unit ( -- )
     remake-generics
     to-recompile recompile
     update-tuples
-    unxref-forgotten-definitions
-    modify-code-heap ;
+    process-forgotten-definitions
+    modify-code-heap
+    updated-definitions notify-definition-observers
+    notify-error-observers ;
 
 : with-nested-compilation-unit ( quot -- )
     [
@@ -166,9 +169,5 @@ GENERIC: definitions-changed ( assoc obj -- )
         H{ } clone new-classes set
         <definitions> new-definitions set
         <definitions> old-definitions set
-        [
-            finish-compilation-unit
-            updated-definitions
-            notify-definition-observers
-        ] [ ] cleanup
+        [ finish-compilation-unit ] [ ] cleanup
     ] with-scope ; inline
index 0627ed5265dc78ebc614d872170f35e7adb74827..651169554eacabea03ece6839a3b596e4e761c0e 100644 (file)
@@ -30,7 +30,7 @@ $nl
 { $heading "Anti-pattern #4: Logging and rethrowing" }
 "If you are going to rethrow an error, do not log a message. If you do so, the user will see two log messages for the same error, which will clutter logs without adding any useful information." ;
 
-ARTICLE: "errors" "Error handling"
+ARTICLE: "errors" "Exception handling"
 "Support for handling exceptional situations such as bad user input, implementation bugs, and input/output errors is provided by a set of words built using continuations."
 $nl
 "Two words raise an error in the innermost error handler for the current dynamic extent:"
index 34a4ed28794c7b5d32f41902a0c0b74955c43cc9..2111cce358676c4e2a09eb9bc00effb1a1a6ebc0 100644 (file)
@@ -3,7 +3,7 @@ continuations debugger parser memory arrays words
 kernel.private accessors eval ;
 IN: continuations.tests
 
-: (callcc1-test) ( -- )
+: (callcc1-test) ( n obj -- n' obj )
     [ 1- dup ] dip ?push
     over 0 = [ "test-cc" get continue-with ] when
     (callcc1-test) ;
@@ -59,7 +59,7 @@ IN: continuations.tests
 ! : callstack-overflow callstack-overflow f ;
 ! [ callstack-overflow ] must-fail
 
-: don't-compile-me ( -- ) { } [ ] each ;
+: don't-compile-me ( -- ) { } [ ] each ;
 
 : foo ( -- ) callstack "c" set 3 don't-compile-me ;
 : bar ( -- a b ) 1 foo 2 ;
index 051d28d8c23eeca8a60a31c5343c60e641927987..56ac4a71e9721b678d38790992ea725f082a2152 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays vectors kernel kernel.private sequences
 namespaces make math splitting sorting quotations assocs
-combinators combinators.private accessors ;
+combinators combinators.private accessors words ;
 IN: continuations
 
 SYMBOL: error
@@ -74,12 +74,14 @@ C: <continuation> continuation
 <PRIVATE
 
 : (continue) ( continuation -- * )
-    >continuation<
-    set-catchstack
-    set-namestack
-    set-retainstack
-    [ set-datastack ] dip
-    set-callstack ;
+    [
+        >continuation<
+        set-catchstack
+        set-namestack
+        set-retainstack
+        [ set-datastack ] dip
+        set-callstack
+    ] (( continuation -- * )) call-effect-unsafe ;
 
 PRIVATE>
 
index f28332353e66de182023887fcf5920d327e58919..37f5cf40ae7d7392b9b6c8bd3638c83dc1a663e1 100755 (executable)
@@ -65,11 +65,11 @@ M: number union-containment drop 2 ;
 [ 2 ] [ 1.0 union-containment ] unit-test
 
 ! Testing recovery from bad method definitions
-"IN: generic.tests GENERIC: unhappy ( x -- x )" eval
+"IN: generic.tests GENERIC: unhappy ( x -- x )" eval( -- )
 [
-    "IN: generic.tests M: dictionary unhappy ;" eval
+    "IN: generic.tests M: dictionary unhappy ;" eval( -- )
 ] must-fail
-[ ] [ "IN: generic.tests GENERIC: unhappy ( x -- x )" eval ] unit-test
+[ ] [ "IN: generic.tests GENERIC: unhappy ( x -- x )" eval( -- ) ] unit-test
 
 GENERIC# complex-combination 1 ( a b -- c )
 M: string complex-combination drop ;
@@ -177,7 +177,7 @@ M: f generic-forget-test-3 ;
 
 [ ] [ [ "m" get forget ] with-compilation-unit ] unit-test
 
-[ ] [ "IN: generic.tests M: f generic-forget-test-3 ;" eval ] unit-test
+[ ] [ "IN: generic.tests M: f generic-forget-test-3 ;" eval( -- ) ] unit-test
 
 [ ] [ [ "m" get forget ] with-compilation-unit ] unit-test
 
@@ -193,7 +193,7 @@ M: integer a-generic a-word ;
 
 [ t ] [ "m" get \ a-word usage memq? ] unit-test
 
-[ ] [ "IN: generic.tests : a-generic ( -- ) ;" eval ] unit-test
+[ ] [ "IN: generic.tests : a-generic ( -- ) ;" eval( -- ) ] unit-test
 
 [ f ] [ "m" get \ a-word usage memq? ] unit-test
 
@@ -207,25 +207,25 @@ M: integer a-generic a-word ;
     M: boii jeah ;
     GENERIC: jeah* ( a -- b )
     M: boii jeah* jeah ;
-    "> eval
+    "> eval( -- )
 
     <"
     IN: compiler.tests
     FORGET: boii
-    "> eval
+    "> eval( -- )
     
     <"
     IN: compiler.tests
     TUPLE: boii ;
     M: boii jeah ;
-    "> eval
+    "> eval( -- )
 ] unit-test
 
 ! call-next-method cache test
 GENERIC: c-n-m-cache ( a -- b )
 
 ! Force it to be unoptimized
-M: fixnum c-n-m-cache { } [ ] like call call-next-method ;
+M: fixnum c-n-m-cache { } [ ] like call( -- ) call-next-method ;
 M: integer c-n-m-cache 1 + ;
 M: number c-n-m-cache ;
 
@@ -244,4 +244,4 @@ GENERIC: move-method-generic ( a -- b )
 
 [ ] [ "IN: generic.tests.a" <string-reader> "move-method-test-1" parse-stream drop ] unit-test
 
-[ { string } ] [ \ move-method-generic order ] unit-test
\ No newline at end of file
+[ { string } ] [ \ move-method-generic order ] unit-test
index 65a802dc2dd3c968a85e96fe66292abee698848a..7fdb339069eca9036636f1c73754a79778d932ce 100644 (file)
@@ -33,6 +33,8 @@ M: generic definition drop f ;
 
 GENERIC: effective-method ( generic -- method )
 
+\ effective-method t "no-compile" set-word-prop
+
 : next-method-class ( class generic -- class/f )
     order [ class<= ] with filter reverse dup length 1 =
     [ drop f ] [ second ] if ;
index c88bd9d97ed1b9cf3fe4bda5ec45ce15eaa3e4be..7e91adfaa191e5155daeb47dca0a803b4edf6b7b 100644 (file)
@@ -82,6 +82,8 @@ M: engine-word stack-effect
         effect boa
     ] [ 2drop f ] if ;
 
+M: engine-word where "tuple-dispatch-generic" word-prop where ;
+
 M: engine-word crossref? "forgotten" word-prop not ;
 
 M: engine-word irrelevant? drop t ;
index a6269135f4193db65ebe15788d2ecdef1f1c6a46..420dd169914138c15c44e9c0269d19521ee57cd8 100644 (file)
@@ -66,7 +66,7 @@ M: circle area radius>> sq pi * ;
 
 GENERIC: perimiter ( shape -- n )
 
-: rectangle-perimiter ( n -- n ) + 2 * ;
+: rectangle-perimiter ( l w -- n ) + 2 * ;
 
 M: rectangle perimiter
     [ width>> ] [ height>> ] bi
index 63346f4701fecfea0a490c394377aa83be4408c3..84a356805bc0cbe4e23b9e4893d62419309ff116 100644 (file)
@@ -27,7 +27,7 @@ IN: kernel.tests
 
 [ ] [ :c ] unit-test
 
-: (overflow-d-alt) ( -- ) 3 ;
+: (overflow-d-alt) ( -- ) 3 ;
 
 : overflow-d-alt ( -- ) (overflow-d-alt) overflow-d-alt ;
 
@@ -107,7 +107,7 @@ IN: kernel.tests
 ! Regression
 : (loop) ( a b c d -- )
     [ pick ] dip swap [ pick ] dip swap
-    < [ [ 1+ ] 3dip (loop) ] [ 2drop 2drop ] if ; inline
+    < [ [ 1+ ] 3dip (loop) ] [ 2drop 2drop ] if ; inline recursive
 
 : loop ( obj obj -- )
     H{ } values swap [ dup length swap ] dip 0 -roll (loop) ;
@@ -168,4 +168,4 @@ IN: kernel.tests
 
 [ 3 -1 5/6 ] [ 1 2 3 4 5 6 [ + ] [ - ] [ / ] 2tri* ] unit-test
 
-[ { 1 2 } { 3 4 } { 5 6 } ] [ 1 2 3 4 5 6 [ 2array ] 2tri@ ] unit-test
\ No newline at end of file
+[ { 1 2 } { 3 4 } { 5 6 } ] [ 1 2 3 4 5 6 [ 2array ] 2tri@ ] unit-test
index 995c7e6064677498d9a7fee3ed1c8b6c274508ba..670c21d6ffb967d6c0835a48cbed1722fe0bd1a9 100644 (file)
@@ -15,7 +15,7 @@ IN: memory.tests
 [ [ ] instances ] must-infer
 
 ! Code GC wasn't kicking in when needed
-: leak-step ( -- ) 800000 f <array> 1quotation call drop ;
+: leak-step ( -- ) 800000 f <array> 1quotation call( -- obj ) drop ;
 
 : leak-loop ( -- ) 100 [ leak-step ] times ;
 
index 3ba414fe6beb9304cbd6ff56def0e823ddd92697..2add8663d812fefbf2e90571f52534eb28021288 100644 (file)
@@ -3,50 +3,50 @@ io.streams.string namespaces classes effects source-files assocs
 sequences strings io.files io.pathnames definitions
 continuations sorting classes.tuple compiler.units debugger
 vocabs vocabs.loader accessors eval combinators lexer
-vocabs.parser words.symbol multiline ;
+vocabs.parser words.symbol multiline source-files.errors ;
 IN: parser.tests
 
 \ run-file must-infer
 
 [
     [ 1 [ 2 [ 3 ] 4 ] 5 ]
-    [ "1\n[\n2\n[\n3\n]\n4\n]\n5" eval ]
+    [ "1\n[\n2\n[\n3\n]\n4\n]\n5" eval( -- a b c ) ]
     unit-test
 
     [ t t f f ]
-    [ "t t f f" eval ]
+    [ "t t f f" eval( -- ? ? ? ? ) ]
     unit-test
 
     [ "hello world" ]
-    [ "\"hello world\"" eval ]
+    [ "\"hello world\"" eval( -- string ) ]
     unit-test
 
     [ "\n\r\t\\" ]
-    [ "\"\\n\\r\\t\\\\\"" eval ]
+    [ "\"\\n\\r\\t\\\\\"" eval( -- string ) ]
     unit-test
 
     [ "hello world" ]
     [
         "IN: parser.tests : hello ( -- str ) \"hello world\" ;"
-        eval "USE: parser.tests hello" eval
+        eval( -- ) "USE: parser.tests hello" eval( -- string )
     ] unit-test
 
     [ ]
-    [ "! This is a comment, people." eval ]
+    [ "! This is a comment, people." eval( -- ) ]
     unit-test
 
     ! Test escapes
 
     [ " " ]
-    [ "\"\\u000020\"" eval ]
+    [ "\"\\u000020\"" eval( -- string ) ]
     unit-test
 
     [ "'" ]
-    [ "\"\\u000027\"" eval ]
+    [ "\"\\u000027\"" eval( -- string ) ]
     unit-test
 
     ! Test EOL comments in multiline strings.
-    [ "Hello" ] [ "#! This calls until-eol.\n\"Hello\"" eval ] unit-test
+    [ "Hello" ] [ "#! This calls until-eol.\n\"Hello\"" eval( -- string ) ] unit-test
 
     [ word ] [ \ f class ] unit-test
 
@@ -68,7 +68,7 @@ IN: parser.tests
     [ \ baz "declared-effect" word-prop terminated?>> ]
     unit-test
 
-    [ ] [ "IN: parser.tests USE: math : effect-parsing-test ( a b -- d ) - ;" eval ] unit-test
+    [ ] [ "IN: parser.tests USE: math : effect-parsing-test ( a b -- d ) - ;" eval( -- ) ] unit-test
 
     [ t ] [
         "effect-parsing-test" "parser.tests" lookup
@@ -79,14 +79,14 @@ IN: parser.tests
     [ \ effect-parsing-test "declared-effect" word-prop ] unit-test
 
     ! Funny bug
-    [ 2 ] [ "IN: parser.tests : \0. ( -- x ) 2 ; \0." eval ] unit-test
+    [ 2 ] [ "IN: parser.tests : \0. ( -- x ) 2 ; \0." eval( -- n ) ] unit-test
 
-    [ "IN: parser.tests : missing-- ( a b ) ;" eval ] must-fail
+    [ "IN: parser.tests : missing-- ( a b ) ;" eval( -- ) ] must-fail
 
     ! These should throw errors
-    [ "HEX: zzz" eval ] must-fail
-    [ "OCT: 999" eval ] must-fail
-    [ "BIN: --0" eval ] must-fail
+    [ "HEX: zzz" eval( -- obj ) ] must-fail
+    [ "OCT: 999" eval( -- obj ) ] must-fail
+    [ "BIN: --0" eval( -- obj ) ] must-fail
 
     ! Another funny bug
     [ t ] [
@@ -102,14 +102,14 @@ IN: parser.tests
     ] unit-test
     DEFER: foo
 
-    "IN: parser.tests USING: math prettyprint ; SYNTAX: foo 2 2 + . ;" eval
+    "IN: parser.tests USING: math prettyprint ; SYNTAX: foo 2 2 + . ;" eval( -- )
 
-    [ ] [ "USE: parser.tests foo" eval ] unit-test
+    [ ] [ "USE: parser.tests foo" eval( -- ) ] unit-test
 
-    "IN: parser.tests USING: math prettyprint ; : foo ( -- ) 2 2 + . ;" eval
+    "IN: parser.tests USING: math prettyprint ; : foo ( -- ) 2 2 + . ;" eval( -- )
 
     [ t ] [
-        "USE: parser.tests \\ foo" eval
+        "USE: parser.tests \\ foo" eval( -- word )
         "foo" "parser.tests" lookup eq?
     ] unit-test
 
@@ -269,12 +269,12 @@ IN: parser.tests
     ] unit-test
 
     [ ] [
-        "IN: parser.tests : <bogus-error> ( -- ) ; : bogus ( -- ) <bogus-error> ;"
+        "IN: parser.tests : <bogus-error> ( -- ) ; : bogus ( -- error ) <bogus-error> ;"
         <string-reader> "bogus-error" parse-stream drop
     ] unit-test
 
     [ ] [
-        "IN: parser.tests TUPLE: bogus-error ; C: <bogus-error> bogus-error : bogus ( -- ) <bogus-error> ;"
+        "IN: parser.tests TUPLE: bogus-error ; C: <bogus-error> bogus-error : bogus ( -- error ) <bogus-error> ;"
         <string-reader> "bogus-error" parse-stream drop
     ] unit-test
 
@@ -339,16 +339,16 @@ IN: parser.tests
     ] [ error>> error>> error>> redefine-error? ] must-fail-with
 
     [ ] [
-        "IN: parser.tests : foo ( x y -- z ) 1 2 ; : bar ( a -- b ) ;" eval
+        "IN: parser.tests : foo ( x y -- z ) 1 2 ; : bar ( a -- b ) ;" eval( -- )
     ] unit-test
 
     [
-        "IN: parser.tests : foo ( x y -- z) 1 2 ; : bar ( a -- b ) ;" eval
+        "IN: parser.tests : foo ( x y -- z) 1 2 ; : bar ( a -- b ) ;" eval( -- )
     ] must-fail
 ] with-file-vocabs
 
 [ ] [
-    "IN: parser.tests USE: kernel PREDICATE: foo < object ( x -- y ) ;" eval
+    "IN: parser.tests USE: kernel PREDICATE: foo < object ( x -- y ) ;" eval( -- )
 ] unit-test
 
 [ t ] [
@@ -422,31 +422,31 @@ IN: parser.tests
 ] unit-test
 
 [
-    "USE: this-better-not-exist" eval
+    "USE: this-better-not-exist" eval( -- )
 ] must-fail
 
-[ ": foo ;" eval ] [ error>> error>> no-current-vocab? ] must-fail-with
+[ ": foo ;" eval( -- ) ] [ error>> error>> no-current-vocab? ] must-fail-with
 
-[ 92 ] [ "CHAR: \\" eval ] unit-test
-[ 92 ] [ "CHAR: \\\\" eval ] unit-test
+[ 92 ] [ "CHAR: \\" eval( -- n ) ] unit-test
+[ 92 ] [ "CHAR: \\\\" eval( -- n ) ] unit-test
 
 [ ] [
     {
         "IN: parser.tests"
-        "USING: math arrays ;"
-        "GENERIC: change-combination ( a -- b )"
-        "M: integer change-combination 1 ;"
-        "M: array change-combination 2 ;"
+        "USING: math arrays kernel ;"
+        "GENERIC: change-combination ( obj a -- b )"
+        "M: integer change-combination 2drop 1 ;"
+        "M: array change-combination 2drop 2 ;"
     } "\n" join <string-reader> "change-combination-test" parse-stream drop
 ] unit-test
 
 [ ] [
     {
         "IN: parser.tests"
-        "USING: math arrays ;"
-        "GENERIC# change-combination 1 ( a -- b )"
-        "M: integer change-combination 1 ;"
-        "M: array change-combination 2 ;"
+        "USING: math arrays kernel ;"
+        "GENERIC# change-combination 1 ( obj a -- b )"
+        "M: integer change-combination 2drop 1 ;"
+        "M: array change-combination 2drop 2 ;"
     } "\n" join <string-reader> "change-combination-test" parse-stream drop
 ] unit-test
 
@@ -463,7 +463,7 @@ IN: parser.tests
 ] unit-test
 
 [ [ ] ] [
-    "IN: parser.tests : staging-problem-test-1 ( -- ) 1 ; : staging-problem-test-2 ( -- ) staging-problem-test-1 ;"
+    "IN: parser.tests : staging-problem-test-1 ( -- a ) 1 ; : staging-problem-test-2 ( -- a ) staging-problem-test-1 ;"
     <string-reader> "staging-problem-test" parse-stream
 ] unit-test
 
@@ -472,7 +472,7 @@ IN: parser.tests
 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
 
 [ [ ] ] [
-    "IN: parser.tests << : staging-problem-test-1 ( -- ) 1 ; >> : staging-problem-test-2 ( -- ) staging-problem-test-1 ;"
+    "IN: parser.tests << : staging-problem-test-1 ( -- a ) 1 ; >> : staging-problem-test-2 ( -- a ) staging-problem-test-1 ;"
     <string-reader> "staging-problem-test" parse-stream
 ] unit-test
 
@@ -480,10 +480,10 @@ IN: parser.tests
 
 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
 
-[ "DEFER: blahy" eval ] [ error>> error>> no-current-vocab? ] must-fail-with
+[ "DEFER: blahy" eval( -- ) ] [ error>> error>> no-current-vocab? ] must-fail-with
 
 [
-    "IN: parser.tests SYNTAX: blahy ; FORGET: blahy" eval
+    "IN: parser.tests SYNTAX: blahy ; FORGET: blahy" eval( -- )
 ] [
     error>> staging-violation?
 ] must-fail-with
@@ -491,12 +491,12 @@ IN: parser.tests
 ! Bogus error message
 DEFER: blahy
 
-[ "IN: parser.tests USE: kernel TUPLE: blahy < tuple ; : blahy ( -- ) ; TUPLE: blahy < tuple ; : blahy ( -- ) ;" eval ]
+[ "IN: parser.tests USE: kernel TUPLE: blahy < tuple ; : blahy ( -- ) ; TUPLE: blahy < tuple ; : blahy ( -- ) ;" eval( -- ) ]
 [ error>> error>> def>> \ blahy eq? ] must-fail-with
 
 [ ] [ f lexer set f file set "Hello world" note. ] unit-test
 
-[ "CHAR: \\u9999999999999" eval ] must-fail
+[ "CHAR: \\u9999999999999" eval( -- n ) ] must-fail
 
 SYMBOLS: a b c ;
 
@@ -506,15 +506,15 @@ SYMBOLS: a b c ;
 
 DEFER: blah
 
-[ ] [ "IN: parser.tests GENERIC: blah ( -- )" eval ] unit-test
-[ ] [ "IN: parser.tests SYMBOLS: blah ;" eval ] unit-test
+[ ] [ "IN: parser.tests GENERIC: blah ( -- )" eval( -- ) ] unit-test
+[ ] [ "IN: parser.tests SYMBOLS: blah ;" eval( -- ) ] unit-test
 
 [ f ] [ \ blah generic? ] unit-test
 [ t ] [ \ blah symbol? ] unit-test
 
 DEFER: blah1
 
-[ "IN: parser.tests SINGLETONS: blah1 blah1 blah1 ;" eval ]
+[ "IN: parser.tests SINGLETONS: blah1 blah1 blah1 ;" eval( -- ) ]
 [ error>> error>> def>> \ blah1 eq? ]
 must-fail-with
 
@@ -545,10 +545,10 @@ EXCLUDE: qualified.tests.bar => x ;
 [ 3 ] [ x ] unit-test
 [ 4 ] [ y ] unit-test
 
-[ "IN: qualified.tests FROM: qualified.tests => doesnotexist ;" eval ]
+[ "IN: qualified.tests FROM: qualified.tests => doesnotexist ;" eval( -- ) ]
 [ error>> no-word-error? ] must-fail-with
 
-[ "IN: qualified.tests RENAME: doesnotexist qualified.tests => blahx" eval ]
+[ "IN: qualified.tests RENAME: doesnotexist qualified.tests => blahx" eval( -- ) ]
 [ error>> no-word-error? ] must-fail-with
 
 ! Two similar bugs
index 6d613a8b2459e30340bc3a46ec36a3845ba2f3da..9876818d2618755d1969ac2386aaedc3f9da6a5e 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays definitions generic assocs kernel math namespaces
-sequences strings vectors words words.symbol quotations io combinators
-sorting splitting math.parser effects continuations io.files vocabs
-io.encodings.utf8 source-files classes hashtables compiler.errors
-compiler.units accessors sets lexer vocabs.parser effects.parser slots ;
+sequences strings vectors words words.symbol quotations io
+combinators sorting splitting math.parser effects continuations
+io.files vocabs io.encodings.utf8 source-files classes
+hashtables compiler.units accessors sets lexer vocabs.parser
+effects.parser slots ;
 IN: parser
 
 : location ( -- loc )
@@ -179,6 +180,7 @@ SYMBOL: interactive-vocabs
     "math.order"
     "memory"
     "namespaces"
+    "parser"
     "prettyprint"
     "see"
     "sequences"
@@ -190,6 +192,7 @@ SYMBOL: interactive-vocabs
     "tools.annotations"
     "tools.crossref"
     "tools.disassembler"
+    "tools.errors"
     "tools.memory"
     "tools.profiler"
     "tools.test"
@@ -280,11 +283,9 @@ print-use-hook [ [ ] ] initialize
 
 : parse-file ( file -- quot )
     [
-        [
-            [ parsing-file ] keep
-            [ utf8 <file-reader> ] keep
-            parse-stream
-        ] with-compiler-errors
+        [ parsing-file ] keep
+        [ utf8 <file-reader> ] keep
+        parse-stream
     ] [
         over parse-file-restarts rethrow-restarts
         drop parse-file
index a72f4adf8805b30e8390baf7aefc543220e0fd4d..603d6f2847d3b49940af4c70ec2c45268ee4f3cf 100644 (file)
@@ -24,6 +24,7 @@ ARTICLE: "wrappers" "Wrappers"
 "Wrappers are used to push words on the data stack; they evaluate to the object being wrapped:"
 { $subsection wrapper }
 { $subsection literalize }
+"Wrapper literal syntax is documented in " { $link "syntax-words" } "."
 { $see-also "combinators" } ;
 
 ABOUT: "quotations"
index 564309a6fb5c4e9aed549a92ac5c3df17f297eaa..79195d19384e1f00a32597fe1503051b02f1901e 100755 (executable)
@@ -568,6 +568,11 @@ M: sequence <=>
     2dup [ length ] bi@ =
     [ mismatch not ] [ 2drop f ] if ; inline
 
+ERROR: assert-sequence got expected ;
+
+: assert-sequence= ( a b -- )
+    2dup sequence= [ 2drop ] [ assert-sequence ] if ;
+
 : sequence-hashcode-step ( oldhash newpart -- newhash )
     >fixnum swap [
         [ -2 fixnum-shift-fast ] [ 5 fixnum-shift-fast ] bi
index 767cec48301c0ac4f1d969b3f5e746af888b1fc7..7ac8446842d24aa564a7de8e43158849d054b3ce 100644 (file)
@@ -25,12 +25,12 @@ TUPLE: hello length ;
 [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
 
 ! See if declarations are cleared on redefinition
-[ ] [ "IN: slots.tests TUPLE: r/w-test { foo read-only } ;" eval ] unit-test
+[ ] [ "IN: slots.tests TUPLE: r/w-test { foo read-only } ;" eval( -- ) ] unit-test
 
 [ t ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test
 [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
 
-[ ] [ "IN: slots.tests TUPLE: r/w-test foo ;" eval ] unit-test
+[ ] [ "IN: slots.tests TUPLE: r/w-test foo ;" eval( -- ) ] unit-test
 
 [ f ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test
 [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
index a353f5094736da78b96f07ec3cdd928870bbb0c8..63c0319c1ce429251258b010169ccd47d83f941c 100755 (executable)
@@ -222,7 +222,7 @@ M: slot-spec make-slot
     [ make-slot ] map ;
 
 : finalize-slots ( specs base -- specs )
-    over length [ + ] with map [ >>offset ] 2map ;
+    over length iota [ + ] with map [ >>offset ] 2map ;
 
 : slot-named ( name specs -- spec/f )
     [ name>> = ] with find nip ;
diff --git a/core/source-files/errors/authors.txt b/core/source-files/errors/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/core/source-files/errors/errors-tests.factor b/core/source-files/errors/errors-tests.factor
new file mode 100644 (file)
index 0000000..f13790f
--- /dev/null
@@ -0,0 +1,10 @@
+USING: assocs compiler.errors compiler.units definitions
+namespaces source-files.errors tools.test words ;
+IN: source-files.errors.tests
+
+DEFER: forget-test
+
+[ ] [ [ \ forget-test [ 1 ] (( -- )) define-declared ] with-compilation-unit ] unit-test
+[ t ] [ \ forget-test compiler-errors get key? ] unit-test
+[ ] [ [ \ forget-test forget ] with-compilation-unit ] unit-test
+[ f ] [ \ forget-test compiler-errors get key? ] unit-test
\ No newline at end of file
diff --git a/core/source-files/errors/errors.factor b/core/source-files/errors/errors.factor
new file mode 100644 (file)
index 0000000..f6f4f48
--- /dev/null
@@ -0,0 +1,77 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs kernel math.order sorting sequences definitions
+namespaces arrays splitting io math.parser math init ;
+IN: source-files.errors
+
+TUPLE: source-file-error error asset file line# ;
+
+: sort-errors ( errors -- alist )
+    [ [ [ line#>> ] compare ] sort ] { } assoc-map-as sort-keys ;
+
+: group-by-source-file ( errors -- assoc )
+    H{ } clone [ [ push-at ] curry [ dup file>> ] prepose each ] keep ;
+
+TUPLE: error-type type word plural icon quot forget-quot { fatal? initial: t } ;
+
+GENERIC: error-type ( error -- type )
+
+: <definition-error> ( error definition class -- source-file-error )
+    new
+        swap
+        [ >>asset ]
+        [ where [ first2 [ >>file ] [ >>line# ] bi* ] when* ] bi
+        swap >>error ; inline
+
+SYMBOL: error-types
+
+error-types [ V{ } clone ] initialize
+
+: define-error-type ( error-type -- )
+    dup type>> error-types get set-at ;
+
+: error-icon-path ( type -- icon )
+    error-types get at icon>> ;
+
+: error-counts ( -- alist )
+    error-types get
+    [ nip dup quot>> call( -- seq ) length ] assoc-map
+    [ [ fatal?>> ] [ 0 > ] bi* and ] assoc-filter ;
+
+: error-summary ( -- )
+    error-counts [
+        over
+        [ word>> write ]
+        [ " - show " write number>string write bl ]
+        [ plural>> print ] tri*
+    ] assoc-each ;
+
+: all-errors ( -- errors )
+    error-types get values
+    [ quot>> call( -- seq ) ] map
+    concat ;
+
+GENERIC: errors-changed ( observer -- )
+
+SYMBOL: error-observers
+
+[ V{ } clone error-observers set-global ] "source-files.errors" add-init-hook
+
+: add-error-observer ( observer -- ) error-observers get push ;
+
+: remove-error-observer ( observer -- ) error-observers get delq ;
+
+: notify-error-observers ( -- ) error-observers get [ errors-changed ] each ;
+
+: delete-file-errors ( seq file type -- )
+    [
+        [ swap file>> = ] [ swap error-type = ]
+        bi-curry* bi and not
+    ] 2curry filter-here
+    notify-error-observers ;
+
+: delete-definition-errors ( definition -- )
+    error-types get [
+        second forget-quot>> dup
+        [ call( definition -- ) ] [ 2drop ] if
+    ] with each ;
\ No newline at end of file
index c8441ba3b0a2bf65605720ee4f50f0a66aa1d976..6884a10d039231cb822fd5471367ddb2bac929df 100644 (file)
@@ -4,7 +4,7 @@ USING: arrays definitions generic assocs kernel math namespaces
 sequences strings vectors words quotations io io.files
 io.pathnames combinators sorting splitting math.parser effects
 continuations checksums checksums.crc32 vocabs hashtables graphs
-compiler.units io.encodings.utf8 accessors ;
+compiler.units io.encodings.utf8 accessors source-files.errors ;
 IN: source-files
 
 SYMBOL: source-files
@@ -61,8 +61,7 @@ M: pathname where string>> 1 2array ;
     [
         source-file
         [ unxref-source ]
-        [ definitions>> [ keys forget-all ] each ]
-        bi
+        [ definitions>> [ keys forget-all ] each ] bi
     ]
     [ source-files get delete-at ]
     bi ;
@@ -77,21 +76,20 @@ M: pathname forget*
 
 SYMBOL: file
 
-TUPLE: source-file-error error file ;
-
-: <source-file-error> ( msg -- error )
+: wrap-source-file-error ( error -- * )
+    file get rollback-source-file
     \ source-file-error new
-        file get >>file
-        swap >>error ;
+        f >>line#
+        file get path>> >>file
+        swap >>error rethrow ;
 
 : with-source-file ( name quot -- )
     #! Should be called from inside with-compilation-unit.
     [
-        swap source-file
-        dup file set
-        definitions>> old-definitions set
         [
-            file get rollback-source-file
-            <source-file-error> rethrow
-        ] recover
+            source-file
+            [ file set ]
+            [ definitions>> old-definitions set ] bi
+        ] dip
+        [ wrap-source-file-error ] recover
     ] with-scope ; inline
index 87531caee4c5107c65e24e6020960e404127dd01..f7c8a89e8c3b12bca00521a8bdcc9d28d98a542e 100644 (file)
@@ -143,7 +143,7 @@ IN: vocabs.loader.tests
 forget-junk
 
 [ { } ] [
-    "IN: xabbabbja" eval "xabbabbja" vocab-files
+    "IN: xabbabbja" eval( -- ) "xabbabbja" vocab-files
 ] unit-test
 
 [ "xabbabbja" forget-vocab ] with-compilation-unit
index 4f9005e11061fed8915062e79b77c3d838be274f..6561c55b6714f1236f664c242c4da8b5099a7a56 100644 (file)
@@ -3,7 +3,7 @@
 USING: namespaces make sequences io io.files io.pathnames kernel
 assocs words vocabs definitions parser continuations hashtables
 sorting source-files arrays combinators strings system
-math.parser compiler.errors splitting init accessors sets ;
+math.parser splitting init accessors sets ;
 IN: vocabs.loader
 
 SYMBOL: vocab-roots
@@ -80,11 +80,11 @@ SYMBOL: load-help?
 PRIVATE>
 
 : require ( vocab -- )
-    [ load-vocab drop ] with-compiler-errors ;
+    load-vocab drop ;
 
 : reload ( name -- )
     dup vocab
-    [ [ [ load-source ] [ load-docs ] bi ] with-compiler-errors ]
+    [ [ load-source ] [ load-docs ] bi ]
     [ require ]
     ?if ;
 
@@ -125,9 +125,7 @@ PRIVATE>
 [
     dup vocab-name blacklist get at* [ rethrow ] [
         drop dup find-vocab-root
-        [ [ (load-vocab) ] with-compiler-errors ]
-        [ dup vocab [ ] [ no-vocab ] ?if ]
-        if
+        [ (load-vocab) ] [ dup vocab [ ] [ no-vocab ] ?if ] if
     ] if
 ] load-vocab-hook set-global
 
index 0278a4d4b98afb80441faa0f396763e3c8dfd37d..c4bc8519a9ed48f81b99f42cdf8d1a04ba99a9a9 100644 (file)
@@ -2,5 +2,5 @@ USING: math eval tools.test effects ;
 IN: words.alias.tests
 
 ALIAS: foo +
-[ ] [ "IN: words.alias.tests CONSTANT: foo 5" eval ] unit-test
-[ (( -- value )) ] [ \ foo stack-effect ] unit-test
\ No newline at end of file
+[ ] [ "IN: words.alias.tests CONSTANT: foo 5" eval( -- ) ] unit-test
+[ (( -- value )) ] [ \ foo stack-effect ] unit-test
diff --git a/core/words/constant/constant-docs.factor b/core/words/constant/constant-docs.factor
new file mode 100644 (file)
index 0000000..3175b5d
--- /dev/null
@@ -0,0 +1,12 @@
+USING: help.markup help.syntax words.constant ;
+IN: words.constant
+
+ARTICLE: "words.constant" "Constants"
+"There is a syntax for defining words which push literals on the stack."
+$nl
+"Define a new word that pushes a literal on the stack:"
+{ $subsection POSTPONE: CONSTANT: }
+"Define an constant at run-time:"
+{ $subsection define-constant } ;
+
+ABOUT: "words.constant"
index 1ad6928acbab2e0c8319df57d765bd15328a0ee6..c20ee66de8e8c236c93f410ba8d3354bdc9f4e14 100644 (file)
@@ -31,7 +31,7 @@ $nl
 { $subsection define }
 { $subsection define-declared }
 { $subsection define-inline }
-"Word definitions should declare their stack effect, unless the definition is completely trivial. See " { $link "effect-declaration" } "."
+"Word definitions must declare their stack effect. See " { $link "effect-declaration" } "."
 $nl
 "All other types of word definitions, such as " { $link "words.symbol" } " and " { $link "generic" } ", are just special cases of the above." ;
 
@@ -75,6 +75,7 @@ ARTICLE: "word-definition" "Defining words"
 { $subsection "colon-definition" }
 { $subsection "words.symbol" }
 { $subsection "words.alias" }
+{ $subsection "words.constant" }
 { $subsection "primitives" }
 { $subsection "deferred" }
 { $subsection "declarations" }
index 305541119b692d8e8845f14020b261ec69cd791d..3ba5e1f6932ff08bf544209970a983c727fbb571 100755 (executable)
@@ -6,7 +6,7 @@ IN: words.tests
 
 [ 4 ] [
     [
-        "poo" "words.tests" create [ 2 2 + ] define
+        "poo" "words.tests" create [ 2 2 + ] (( -- n )) define-declared
     ] with-compilation-unit
     "poo" "words.tests" lookup execute
 ] unit-test
@@ -51,7 +51,7 @@ SYMBOL: a-symbol
 ! See if redefining a generic as a colon def clears some
 ! word props.
 GENERIC: testing ( a -- b )
-"IN: words.tests : testing ( -- ) ;" eval
+"IN: words.tests : testing ( -- ) ;" eval( -- )
 
 [ f ] [ \ testing generic? ] unit-test
 
@@ -88,7 +88,7 @@ DEFER: calls-a-gensym
     [
         \ calls-a-gensym
         gensym dup "x" set 1quotation
-        define
+        (( x -- x )) define-declared
     ] with-compilation-unit
 ] unit-test
 
@@ -116,10 +116,10 @@ DEFER: x
 [ ] [ "no-loc" "words.tests" create drop ] unit-test
 [ f ] [ "no-loc" "words.tests" lookup where ] unit-test
 
-[ ] [ "IN: words.tests : no-loc-2 ( -- ) ;" eval ] unit-test
+[ ] [ "IN: words.tests : no-loc-2 ( -- ) ;" eval( -- ) ] unit-test
 [ f ] [ "no-loc-2" "words.tests" lookup where ] unit-test
 
-[ ] [ "IN: words.tests : test-last ( -- ) ;" eval ] unit-test
+[ ] [ "IN: words.tests : test-last ( -- ) ;" eval( -- ) ] unit-test
 [ "test-last" ] [ word name>> ] unit-test
 
 ! regression
@@ -146,15 +146,15 @@ SYMBOL: quot-uses-b
     [ forget ] with-compilation-unit
 ] when*
 
-[ "IN: words.tests : undef-test ( -- ) ; << undef-test >>" eval ]
+[ "IN: words.tests : undef-test ( -- ) ; << undef-test >>" eval( -- ) ]
 [ error>> undefined? ] must-fail-with
 
 [ ] [
-    "IN: words.tests GENERIC: symbol-generic ( -- )" eval
+    "IN: words.tests GENERIC: symbol-generic ( -- )" eval( -- )
 ] unit-test
 
 [ ] [
-    "IN: words.tests SYMBOL: symbol-generic" eval
+    "IN: words.tests SYMBOL: symbol-generic" eval( -- )
 ] unit-test
 
 [ t ] [ "symbol-generic" "words.tests" lookup symbol? ] unit-test
@@ -174,14 +174,14 @@ SYMBOL: quot-uses-b
 [ f ] [ "symbol-generic" "words.tests" lookup generic? ] unit-test
 
 ! Regressions
-[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; foldable" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; foldable" eval( -- ) ] unit-test
 [ t ] [ "decl-forget-test" "words.tests" lookup "foldable" word-prop ] unit-test
-[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval( -- ) ] unit-test
 [ f ] [ "decl-forget-test" "words.tests" lookup "foldable" word-prop ] unit-test
 
-[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; flushable" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; flushable" eval( -- ) ] unit-test
 [ t ] [ "decl-forget-test" "words.tests" lookup "flushable" word-prop ] unit-test
-[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval( -- ) ] unit-test
 [ f ] [ "decl-forget-test" "words.tests" lookup "flushable" word-prop ] unit-test
 
 [ { } ]
index aae0b40d381b521ec920dd6df43dcf852a1dd145..b9679ec26beddbd600ad4b86b9e35f8538bd4235 100755 (executable)
@@ -75,8 +75,6 @@ VAR: present-space
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r
 \r
 ! namespace utilities\r
-    \r
-: make* ( seq -- seq ) [ dup quotation? [ call ] [ ] if ] map ;\r
 \r
 : closed-quot ( quot -- quot )\r
   namestack swap '[ namestack [ _ set-namestack @ ] dip set-namestack ] ;\r
@@ -156,9 +154,9 @@ VAR: present-space
     3 model-projection <model> view4> (>>model) ;\r
 \r
 : camera-action ( quot -- quot ) \r
-    [ drop [ ] observer3d>  \r
+    '[ drop _ observer3d>  \r
     with-self update-observer-projections ] \r
-    make* closed-quot ;\r
+    closed-quot ;\r
 \r
 : win3D ( text gadget -- ) \r
     "navigateur 4D : " rot append open-window ;\r
@@ -400,7 +398,7 @@ M: handler handle-gesture ( gesture gadget -- ? )
 \r
 : add-keyboard-delegate ( obj -- obj )\r
  <handler>\r
-{\r
+H{\r
         { T{ key-down f f "LEFT" }  \r
             [ [ rotation-step turn-left ] camera-action ] }\r
         { T{ key-down f f "RIGHT" } \r
@@ -435,7 +433,7 @@ M: handler handle-gesture ( gesture gadget -- ? )
         { T{ key-down f f "3" } [ mvt-3D-3  camera-action ] }\r
         { T{ key-down f f "4" } [ mvt-3D-4  camera-action ] }\r
 \r
-    } [ make* ] map >hashtable >>table\r
+    } >>table\r
     ;    \r
 \r
 ! --------------------------------------------\r
index 9bd0e9c011ae4570796ab6cfbcceb9d1f28570a5..51bebc38778596ae7890dc5eb1a58f23b2b222e1 100755 (executable)
@@ -72,17 +72,17 @@ file-chooser H{
 : init-filelist-model ( file-chooser -- file-chooser )\r
     dup list-of-files <model> >>model ; \r
 \r
-: (fc-go) ( file-chooser quot -- )\r
+: (fc-go) ( file-chooser button quot -- )\r
     [ [ file-chooser? ] find-parent dup path>> ] dip\r
     call\r
     normalize-path swap set-model\r
     update-filelist-model\r
-    drop ;\r
+    drop ; inline\r
 \r
-: fc-go-parent ( file-chooser -- )\r
+: fc-go-parent ( file-chooser button -- )\r
     [ dup value>> parent-directory ] (fc-go) ;\r
 \r
-: fc-go-home ( file-chooser -- )\r
+: fc-go-home ( file-chooser button -- )\r
     [ home ] (fc-go) ;\r
 \r
 : fc-change-directory ( file-chooser file -- )\r
@@ -92,11 +92,9 @@ file-chooser H{
 ;\r
 \r
 : fc-load-file ( file-chooser file -- )\r
-  dupd [ selected-file>> ] [ name>> ] bi* swap set-model \r
-  [ path>> value>> ] \r
-  [ selected-file>> value>> append ] \r
-  [ hook>> ] tri\r
-  call\r
+  over [ name>> ] [ selected-file>> ] bi* set-model \r
+  [ [ path>> value>> ] [ selected-file>> value>> ] bi append ] [ hook>> ] bi\r
+  call( path -- )\r
 ; inline\r
 \r
 ! : fc-ok-action ( file-chooser -- quot )\r
diff --git a/extra/advice/advice-docs.factor b/extra/advice/advice-docs.factor
deleted file mode 100644 (file)
index 0a5d5f8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-IN: advice
-USING: help.markup help.syntax tools.annotations words coroutines ;
-
-HELP: make-advised
-{ $values { "word" "a word to annotate in preparation of advising" } }
-{ $description "Prepares a word for being advised.  This is done by: "
-    { $list
-        { "Annotating it to call the appropriate words before, around, and after the original body " }
-        { "Adding " { $snippet "before" } ", " { $snippet "around" } ", and " { $snippet "after" } " properties, which will contain the advice" }
-        { "Adding an " { $snippet "advised" } "property, which can later be used to determine if a given word is defined (see " { $link advised? } ")" }
-    }
-}
-{ $see-also advised? annotate } ;
-
-HELP: advised?
-{ $values { "word" "a word" } { "?" "t or f, indicating if " { $snippet "word" } " is advised" } }
-{ $description "Determines whether or not the given word has any advice on it." } ;
-
-HELP: ad-do-it
-{ $values { "input" "an object" } { "result" "an object" } }
-{ $description "Calls either the next applicable around advice or the main body, returning back to the point it was called from when finished.  This word should only be called from inside advice." }
-{ $see-also coyield } ;
-
-ARTICLE: "advice" "Advice"
-"Advice is a simple way of adding additition functionality to words by adding 'hooks' to a word, which can act before, after, or around the calling of the word." ;
-
-ABOUT: "advice"
\ No newline at end of file
diff --git a/extra/advice/advice-tests.factor b/extra/advice/advice-tests.factor
deleted file mode 100644 (file)
index a141489..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences io io.streams.string math tools.test advice math.parser
-parser namespaces multiline eval words assocs ;
-IN: advice.tests
-
-[
-    [ ad-do-it ] must-fail
-    
-    : foo ( -- str ) "foo" ; 
-    \ foo make-advised
-    { "bar" "foo" } [
-        [ "bar" ] "barify" \ foo advise-before
-        foo
-    ] unit-test
-    { "bar" "foo" "baz" } [
-        [ "baz" ] "bazify" \ foo advise-after
-        foo
-    ] unit-test
-    { "foo" "baz" } [
-        "barify" \ foo before remove-advice
-        foo
-    ] unit-test
-    : bar ( a -- b ) 1+ ;
-    \ bar make-advised
-
-    { 11 } [
-        [ 2 * ] "double" \ bar advise-before
-        5 bar
-    ] unit-test 
-
-    { 11/3 } [
-        [ 3 / ] "third" \ bar advise-after
-        5 bar
-    ] unit-test
-
-    { -2 } [
-        [ -1 * ad-do-it 3 + ] "frobnobicate" \ bar advise-around
-        5 bar
-    ] unit-test
-
-    : add ( a b -- c ) + ;
-    \ add make-advised
-
-    { 10 } [
-        [ [ 2 * ] bi@ ] "double-args" \ add advise-before
-        2 3 add
-    ] unit-test 
-
-    { 21 } [
-        [ 3 * ad-do-it 1- ] "around1" \ add advise-around
-        2 3 add
-    ] unit-test 
-
-!     { 9 } [
-!         [ [ 1- ] bi@ ad-do-it 2 / ] "around2" \ add advise-around
-!         2 3 add
-!     ] unit-test
-
-!     { { "around1" "around2" } } [
-!         \ add around word-prop keys
-!     ] unit-test
-
-    { 5 f } [
-        \ add unadvise
-        2 3 add \ add advised?
-    ] unit-test
-
-!     : quux ( a b -- c ) * ;
-
-!     { f t 3+3/4 } [
-!         <" USING: advice kernel math ;
-!            IN: advice.tests
-!            \ quux advised?
-!            ADVISE: quux halve before [ 2 / ] bi@ ;
-!            \ quux advised? 
-!            3 5 quux"> eval
-!     ] unit-test
-
-!     { 3+3/4 "1+1/2 2+1/2 3+3/4" } [
-!         <" USING: advice kernel math math.parser io io.streams.string ;
-!            IN: advice.tests
-!            ADVISE: quux log around
-!            2dup [ number>string write " " write ] bi@
-!            ad-do-it 
-!            dup number>string write ;
-!            [ 3 5 quux ] with-string-writer"> eval
-!     ] unit-test 
-] with-scope
\ No newline at end of file
diff --git a/extra/advice/advice.factor b/extra/advice/advice.factor
deleted file mode 100644 (file)
index 9c09634..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-! Copyright (C) 2008 James Cash
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences fry words assocs linked-assocs tools.annotations
-coroutines lexer parser quotations arrays namespaces continuations ;
-IN: advice
-
-SYMBOLS: before after around advised in-advice? ;
-
-: advised? ( word -- ? )
-    advised word-prop ;
-
-DEFER: make-advised
-
-<PRIVATE
-: init-around-co ( quot -- coroutine )
-    \ coreset suffix cocreate ;
-PRIVATE>
-
-: advise ( quot name word loc --  )
-    dup around eq? [ [ init-around-co ] 3dip ] when
-    over advised? [ over make-advised ] unless
-    word-prop set-at ;
-    
-: advise-before ( quot name word --  ) before advise ;
-    
-: advise-after ( quot name word --  ) after advise ;
-
-: advise-around ( quot name word --  ) around advise ;
-
-: get-advice ( word type -- seq )
-    word-prop values ;
-
-: call-before ( word --  )
-    before get-advice [ call ] each ;
-
-: call-after ( word --  )
-    after get-advice [ call ] each ;
-
-: call-around ( main word --  )
-    t in-advice? [
-        around get-advice tuck 
-        [ [ coresume ] each ] [ call ] [ <reversed> [ coresume ] each ] tri*
-    ] with-variable ;
-
-: remove-advice ( name word loc --  )
-    word-prop delete-at ;
-
-: ad-do-it ( input -- result )
-    in-advice? get [ "ad-do-it should only be called inside 'around' advice" throw ] unless coyield ;
-    
-: make-advised ( word -- )
-    [ dup '[ [ _ ] dip over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ]
-    [ { before after around } [ <linked-hash> swap set-word-prop ] with each ] 
-    [ t advised set-word-prop ] tri ;
-
-: unadvise ( word --  )
-    [ reset ] [ { before after around advised } [ f swap set-word-prop ] with each ] bi ;
-
-SYNTAX: ADVISE: ! word adname location => word adname quot loc
-    scan-word scan scan-word parse-definition swap [ spin ] dip advise ;
-    
-SYNTAX: UNADVISE:    
-    scan-word parsed \ unadvise parsed ;
\ No newline at end of file
diff --git a/extra/advice/authors.txt b/extra/advice/authors.txt
deleted file mode 100644 (file)
index 4b7af4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-James Cash
diff --git a/extra/advice/summary.txt b/extra/advice/summary.txt
deleted file mode 100644 (file)
index a6f9c06..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Implmentation of advice/aspects
diff --git a/extra/advice/tags.txt b/extra/advice/tags.txt
deleted file mode 100644 (file)
index f427429..0000000
+++ /dev/null
@@ -1 +0,0 @@
-extensions
index f06bc2fb81f4dc00f14668c83b47cec7dc0eeb44..31a4b75eb2e985bddb92e7b55d992bd2671c0f92 100644 (file)
@@ -54,7 +54,7 @@ C: <transaction> transaction
 : process-day ( account date -- )
     2dup accumulate-interest ?pay-interest ;
 
-: each-day ( quot start end -- )
+: each-day ( quot: ( -- ) start end -- )
     2dup before? [
         [ dup [ over [ swap call ] dip ] dip 1 days time+ ] dip each-day
     ] [
@@ -63,7 +63,7 @@ C: <transaction> transaction
 
 : process-to-date ( account date -- account )
     over interest-last-paid>> 1 days time+
-    [ dupd process-day ] spin each-day ; inline
+    [ dupd process-day ] spin each-day ;
 
 : inserting-transactions ( account transactions -- account )
     [ [ date>> process-to-date ] keep >>transaction ] each ;
index f6e5f7ca39655ddbdf42bb74cdc34911e02cbfbf..350a29f8659db7b5430cd8c5ac5c521f2cdaf416 100644 (file)
@@ -5,7 +5,7 @@ IN: benchmark.base64
 
 : base64-benchmark ( -- )
     65535 [ 255 bitand ] "" map-as
-    100 [ >base64 base64> ] times
+    20 [ >base64 base64> ] times
     drop ;
 
 MAIN: base64-benchmark
index 489dc5e73faa5f475f87209f8ee445c57b7c75fb..ca48e6208c8167abf5c495282284d3746513fb7d 100755 (executable)
@@ -1,21 +1,35 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel vocabs vocabs.loader tools.time tools.vocabs
 arrays assocs io.styles io help.markup prettyprint sequences
-continuations debugger math ;
+continuations debugger math namespaces ;
 IN: benchmark
 
-: run-benchmark ( vocab -- result )
+<PRIVATE
+
+SYMBOL: timings
+SYMBOL: errors
+
+PRIVATE>
+
+: run-benchmark ( vocab -- )
     [ "=== " write vocab-name print flush ] [
-        [ [ require ] [ [ run ] benchmark ] bi ] curry
-        [ error. f ] recover
+        [ [ require ] [ [ run ] benchmark ] [ ] tri timings ]
+        [ swap errors ]
+        recover get set-at
     ] bi ;
 
-: run-benchmarks ( -- assoc )
-    "benchmark" all-child-vocabs-seq
-    [ dup run-benchmark ] { } map>assoc ;
+: run-benchmarks ( -- timings errors )
+    [
+        V{ } clone timings set
+        V{ } clone errors set
+        "benchmark" all-child-vocabs-seq
+        [ run-benchmark ] each
+        timings get
+        errors get
+    ] with-scope ;
 
-: benchmarks. ( assoc -- )
+: timings. ( assocs -- )
     standard-table-style [
         [
             [ "Benchmark" write ] with-cell
@@ -24,13 +38,21 @@ IN: benchmark
         [
             [
                 [ [ 1array $vocab-link ] with-cell ]
-                [ [ 1000000 /f pprint-cell ] [ [ "failed" write ] with-cell ] if* ] bi*
+                [ 1000000 /f pprint-cell ]
+                bi*
             ] with-row
         ] assoc-each
     ] tabular-output nl ;
 
+: benchmark-errors. ( errors -- )
+    [
+        [ "=== " write vocab-name print ]
+        [ error. ]
+        bi*
+    ] assoc-each ;
+
 : benchmarks ( -- )
-    run-benchmarks benchmarks. ;
+    run-benchmarks [ timings. ] [ benchmark-errors. ] bi* ;
 
 MAIN: benchmarks
 
index 9849ac2dbe4d17e0e38aa3c719568d756997efc8..d94c1d1335ddcb8845b2bb321caabe6a4439be84 100644 (file)
@@ -8,7 +8,7 @@ IN: benchmark.beust1
     1 [a,b] [ number>string all-unique? ] count ; inline
 
 : beust ( -- )
-    10000000 count-numbers
+    2000000 count-numbers
     number>string " unique numbers." append print ;
 
 MAIN: beust
index f96dc77961b0f2519f5b64a7de10a41016cd9a93..d269ef3503b24ac8ead2036542f2352def61dc48 100755 (executable)
@@ -34,7 +34,7 @@ IN: benchmark.beust2
 
 :: beust ( -- )
     [let | i! [ 0 ] |
-        10000000000 [ i 1+ i! ] count-numbers
+        5000000000 [ i 1+ i! ] count-numbers
         i number>string " unique numbers." append print
     ] ;
 
index 64d1b6c53333c889a86feb285ee7df122d617ab8..f81b6a21a2f09a40b3cd6e6f197ad31afdcc1d7f 100755 (executable)
@@ -9,6 +9,6 @@ USING: math kernel alien ;
     ] alien-callback\r
     "int" { "int" } "cdecl" alien-indirect ;\r
 \r
-: fib-main ( -- ) 34 fib drop ;\r
+: fib-main ( -- ) 32 fib drop ;\r
 \r
 MAIN: fib-main\r
index 5030cb69041bcc6a8a6db58386c5d590448fe6b2..de60049c84bcfdd4945025c56fe76cff059aab5f 100644 (file)
@@ -1,7 +1,7 @@
-USING: checksums checksums.md5 io.files kernel ;
+USING: checksums checksums.md5 sequences byte-arrays kernel ;
 IN: benchmark.md5
 
 : md5-file ( -- )
-    "vocab:mime/multipart/multipart-tests.factor" md5 checksum-file drop ;
+    2000000 iota >byte-array md5 checksum-bytes drop ;
 
 MAIN: md5-file
index d2eb4cdab516be55c12187715c799d1585e000b2..4eab7c16693ae6b49ceb09d1a01c70b22b9a9c0c 100755 (executable)
@@ -11,6 +11,6 @@ IN: benchmark.random
     ] with-file-writer ;
 
 : random-main ( -- )
-    1000000 write-random-numbers ;
+    300000 write-random-numbers ;
 
 MAIN: random-main
index 8e19ba9a8fd8e2d8c26f93eab19db4ed5fa00b31..c1a7af2966098d4ccf727e166a8a558b88564b74 100644 (file)
@@ -1,7 +1,7 @@
-USING: checksums checksums.sha1 io.files kernel ;
+USING: checksums checksums.sha1 sequences byte-arrays kernel ;
 IN: benchmark.sha1
 
 : sha1-file ( -- )
-    "vocab:mime/multipart/multipart-tests.factor" sha1 checksum-file drop ;
+    2000000 iota >byte-array sha1 checksum-bytes drop ;
 
 MAIN: sha1-file
index bb7aebba62c46699bc465e2cccc89793c3ad9ea6..b1f27830ee96609ad0f9e3411cbaabcbbf6855b6 100644 (file)
@@ -9,6 +9,6 @@ IN: benchmark.sum-file
     ascii [ 0 sum-file-loop ] with-file-reader . ;
 
 : sum-file-main ( -- )
-    random-numbers-path sum-file ;
+    5 [ random-numbers-path sum-file ] times ;
 
 MAIN: sum-file-main
index 51276336e352bfadc0e6b008ea70747a6442bd88..6b334822c093083e79a1c7b014958a78d1130c1d 100644 (file)
@@ -19,9 +19,10 @@ TUPLE: coroutine resumecc exitcc originalcc ;
 : coresume ( v co -- result )
   [ 
     >>exitcc
-    resumecc>> call
+    resumecc>> call( -- )
     #! At this point, the coroutine quotation must have terminated
-    #! normally (without calling coyield, coreset, or coterminate). This shouldn't happen.
+    #! normally (without calling coyield, coreset, or coterminate).
+    #! This shouldn't happen.
     f over
   ] callcc1 2nip ;
 
@@ -47,4 +48,4 @@ TUPLE: coroutine resumecc exitcc originalcc ;
 : coreset ( v --  )
   current-coro get dup
   originalcc>> >>resumecc
-  exitcc>> continue-with ;
\ No newline at end of file
+  exitcc>> continue-with ;
diff --git a/extra/couchdb/authors.txt b/extra/couchdb/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/couchdb/couchdb-tests.factor b/extra/couchdb/couchdb-tests.factor
new file mode 100644 (file)
index 0000000..d7161a1
--- /dev/null
@@ -0,0 +1,46 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs couchdb kernel namespaces sequences strings tools.test ;
+IN: couchdb.tests
+
+! You must have a CouchDB server (currently only the version from svn will
+! work) running on localhost and listening on the default port for these tests
+! to work.
+
+<default-server> "factor-test" <db> [
+    [ ] [ couch get create-db ] unit-test
+    [ couch get create-db ] must-fail
+    [ ] [ couch get delete-db ] unit-test
+    [ couch get delete-db ] must-fail
+    [ ] [ couch get ensure-db ] unit-test
+    [ ] [ couch get ensure-db ] unit-test
+    [ 0 ] [ couch get db-info "doc_count" swap at ] unit-test
+    [ ] [ couch get compact-db ] unit-test
+    [ t ] [ couch get server>> next-uuid string? ] unit-test
+    [ ] [ H{
+            { "Subject" "I like Planktion" }
+            { "Tags" { "plankton" "baseball" "decisions" } }
+            { "Body"
+              "I decided today that I don't like baseball. I like plankton." }
+            { "Author" "Rusty" }
+            { "PostedDate" "2006-08-15T17:30:12Z-04:00" }
+           } save-doc ] unit-test
+    [ t ] [ couch get all-docs "rows" swap at first "id" swap at dup "id" set string? ] unit-test
+    [ t ] [ "id" get dup load-doc id> = ] unit-test
+    [ ] [ "id" get load-doc save-doc ] unit-test
+    [ "Rusty" ] [ "id" get load-doc "Author" swap at ] unit-test
+    [ ] [ "id" get load-doc "Alex" "Author" pick set-at save-doc ] unit-test
+    [ "Alex" ] [ "id" get load-doc "Author" swap at ] unit-test
+    [ 1 ] [ "function(doc) { emit(null, doc) }" temp-view-map "total_rows" swap at ] unit-test
+    [ ] [ H{
+         { "_id" "_design/posts" }
+         { "language" "javascript" }
+         { "views" H{
+             { "all" H{ { "map" "function(doc) { emit(null, doc) }" } } }
+           }
+         }
+       } save-doc ] unit-test
+    [ t ] [ "id" get load-doc delete-doc string? ] unit-test
+    [ "id" get load-doc ] must-fail
+    [ ] [ couch get delete-db ] unit-test
+] with-couch
diff --git a/extra/couchdb/couchdb.factor b/extra/couchdb/couchdb.factor
new file mode 100644 (file)
index 0000000..da71acb
--- /dev/null
@@ -0,0 +1,200 @@
+! Copyright (C) 2008, 2009 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs continuations debugger hashtables http
+http.client io io.encodings.string io.encodings.utf8 json.reader
+json.writer kernel make math math.parser namespaces sequences strings
+urls urls.encoding vectors ;
+IN: couchdb
+
+! NOTE: This code only works with the latest couchdb (0.9.*), because old
+! versions didn't provide the /_uuids feature which this code relies on when
+! creating new documents.
+
+SYMBOL: couch
+: with-couch ( db quot -- )
+    couch swap with-variable ; inline
+
+! errors
+TUPLE: couchdb-error { data assoc } ;
+C: <couchdb-error> couchdb-error
+
+M: couchdb-error error. ( error -- )
+    "CouchDB Error: " write data>>
+    "error" over at [ print ] when*
+    "reason" swap at [ print ] when* ;
+
+PREDICATE: file-exists-error < couchdb-error
+    data>> "error" swap at "file_exists" = ;
+
+! http tools
+: couch-http-request ( request -- data )
+    [ http-request ] [
+        dup download-failed? [
+            response>> body>> json> <couchdb-error> throw
+        ] [
+            rethrow
+        ] if
+    ] recover nip ;
+
+: couch-request ( request -- assoc )
+    couch-http-request json> ;
+
+: couch-get ( url -- assoc )
+    <get-request> couch-request ;
+
+: couch-put ( post-data url -- assoc )
+    <put-request> couch-request ;
+
+: couch-post ( post-data url -- assoc )
+    <post-request> couch-request ;
+
+: couch-delete ( url -- assoc )
+    <delete-request> couch-request ;
+
+: response-ok ( assoc -- assoc )
+    "ok" over delete-at* and t assert= ;
+
+: response-ok* ( assoc -- )
+    response-ok drop ;
+
+! server
+TUPLE: server { host string } { port integer } { uuids vector } { uuids-to-cache integer } ;
+
+: default-couch-host ( -- host ) "localhost" ; inline
+: default-couch-port ( -- port ) 5984 ; inline
+: default-uuids-to-cache ( -- n ) 100 ; inline
+
+: <server> ( host port -- server )
+    V{ } clone default-uuids-to-cache server boa ;
+
+: <default-server> ( -- server )
+    default-couch-host default-couch-port <server> ;
+
+: (server-url) ( server -- )
+    "http://" % [ host>> % ] [ CHAR: : , port>> number>string % ] bi CHAR: / , ; inline
+
+: server-url ( server -- url )
+    [ (server-url) ] "" make ;
+
+: all-dbs ( server -- dbs )
+    server-url "_all_dbs" append couch-get ;
+
+: uuids-url ( server -- url )
+    [ dup server-url % "_uuids?count=" % uuids-to-cache>> number>string % ] "" make ;
+
+: uuids-get ( server -- uuids )
+     uuids-url couch-get "uuids" swap at >vector ;
+
+: get-uuids ( server -- server )
+    dup uuids-get [ nip ] curry change-uuids ;
+
+: ensure-uuids ( server -- server )
+    dup uuids>> empty? [ get-uuids ] when ;
+
+: next-uuid ( server -- uuid )
+    ensure-uuids uuids>> pop ;
+
+! db 
+TUPLE: db { server server } { name string } ;
+C: <db> db
+
+: (db-url) ( db -- )
+    [ server>> server-url % ] [ name>> % ] bi CHAR: / , ; inline
+
+: db-url ( db -- url )
+    [ (db-url) ] "" make ;
+
+: create-db ( db -- )
+    f swap db-url couch-put response-ok* ;
+
+: ensure-db ( db -- )
+    [ create-db ] [
+        dup file-exists-error? [ 2drop ] [ rethrow ] if
+    ] recover ;
+
+: delete-db ( db -- )
+    db-url couch-delete drop ;
+
+: db-info ( db -- info )
+    db-url couch-get ;
+
+: compact-db ( db -- )
+    f swap db-url "_compact" append couch-post response-ok* ;
+
+: all-docs ( db -- docs )
+    ! TODO: queries. Maybe pass in a hashtable with options
+    db-url "_all_docs" append couch-get ;
+
+: <json-post-data> ( assoc -- post-data )
+    >json utf8 encode "application/json" <post-data> swap >>data ;
+
+! documents
+: id> ( assoc -- id ) "_id" swap at ; 
+: >id ( assoc id -- assoc ) "_id" pick set-at ;
+: rev> ( assoc -- rev ) "_rev" swap at ;
+: >rev ( assoc rev -- assoc ) "_rev" pick set-at ;
+: attachments> ( assoc -- attachments ) "_attachments" swap at ;
+: >attachments ( assoc attachments -- assoc ) "_attachments" pick set-at ;
+
+: copy-key ( to from to-key from-key -- )
+    rot at spin set-at ;
+
+: copy-id ( to from -- )
+    "_id" "id" copy-key ;
+
+: copy-rev ( to from -- )
+    "_rev" "rev" copy-key ;
+
+: id-url ( id -- url )
+    couch get db-url swap url-encode-full append ;
+
+: doc-url ( assoc -- url )
+    id> id-url ;
+
+: temp-view ( view -- results )
+    <json-post-data> couch get db-url "_temp_view" append couch-post ;
+
+: temp-view-map ( map -- results )
+    "map" H{ } clone [ set-at ] keep temp-view ;
+
+: save-doc-as ( assoc id -- )
+    [ dup <json-post-data> ] dip id-url couch-put response-ok
+    [ copy-id ] [ copy-rev ] 2bi ;
+
+: save-new-doc ( assoc -- )
+    couch get server>> next-uuid save-doc-as ;
+
+: save-doc ( assoc -- )
+    dup id> [ save-doc-as ] [ save-new-doc ] if* ; 
+
+: load-doc ( id -- assoc )
+    id-url couch-get ;
+
+: delete-doc ( assoc -- deletion-revision )
+    [
+        [ doc-url % ]
+        [ "?rev=" % "_rev" swap at % ] bi
+    ] "" make couch-delete response-ok "rev" swap at  ;
+
+: remove-keys ( assoc keys -- )
+    swap [ delete-at ] curry each ;
+
+: remove-couch-info ( assoc -- )
+    { "_id" "_rev" "_attachments" } remove-keys ;
+
+! : construct-attachment ( content-type data -- assoc )
+!     H{ } clone "name" pick set-at "content-type" pick set-at ;
+! 
+! : add-attachment ( assoc name attachment -- )
+!     pick attachments> [ H{ } clone ] unless* 
+! 
+! : attach ( assoc name content-type data -- )
+!     construct-attachment H{ } clone
+
+! TODO:
+! - startkey, limit, descending, etc.
+! - loading specific revisions
+! - views
+! - attachments
+! - bulk insert/update
+! - ...?
index 5b2e63838ab56d78b52fc80fcb399c71af82e9c1..f47eb7010c6dbbf0b4c16862f628d87edafcb065 100644 (file)
@@ -28,4 +28,4 @@ TUPLE: packet data addr socket ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: forever ( quot -- ) [ call ] [ forever ] bi ;         inline recursive
\ No newline at end of file
+: forever ( quot: ( -- ) -- ) [ call ] [ forever ] bi ; inline recursive
\ No newline at end of file
index c3b1a8a3f291105a1fdda8071ed0d3f16a237dbc..019b9105bccffeda453321890b08e416fbfdf9bc 100644 (file)
@@ -21,7 +21,7 @@ SYMBOL: fuel-eval-res-flag
 t fuel-eval-res-flag set-global
 
 : fuel-eval-restartable? ( -- ? )
-    fuel-eval-res-flag get-global ; inline
+    fuel-eval-res-flag get-global ;
 
 : fuel-push-status ( -- )
     in get use get clone restarts get-global clone
@@ -29,7 +29,7 @@ t fuel-eval-res-flag set-global
     fuel-status-stack get push ;
 
 : fuel-pop-restarts ( restarts -- )
-    fuel-eval-restartable? [ drop ] [ clone restarts set-global ] if ; inline
+    fuel-eval-restartable? [ drop ] [ clone restarts set-global ] if ;
 
 : fuel-pop-status ( -- )
     fuel-status-stack get empty? [
@@ -39,35 +39,32 @@ t fuel-eval-res-flag set-global
         [ restarts>> fuel-pop-restarts ] tri
     ] unless ;
 
-: fuel-forget-error ( -- ) f error set-global ; inline
-: fuel-forget-result ( -- ) f fuel-eval-result set-global ; inline
-: fuel-forget-output ( -- ) f fuel-eval-output set-global ; inline
+: fuel-forget-error ( -- ) f error set-global ;
+: fuel-forget-result ( -- ) f fuel-eval-result set-global ;
+: fuel-forget-output ( -- ) f fuel-eval-output set-global ;
 : fuel-forget-status ( -- )
-    fuel-forget-error fuel-forget-result fuel-forget-output ; inline
+    fuel-forget-error fuel-forget-result fuel-forget-output ;
 
 : fuel-send-retort ( -- )
     error get fuel-eval-result get-global fuel-eval-output get-global
     3array fuel-pprint flush nl "<~FUEL~>" write nl flush ;
 
 : (fuel-begin-eval) ( -- )
-    fuel-push-status fuel-forget-status ; inline
+    fuel-push-status fuel-forget-status ;
 
 : (fuel-end-eval) ( output -- )
-    fuel-eval-output set-global fuel-send-retort fuel-pop-status ; inline
+    fuel-eval-output set-global fuel-send-retort fuel-pop-status ;
 
 : (fuel-eval) ( lines -- )
-    [ [ parse-lines ] with-compilation-unit call ] curry
-    [ print-error ] recover ; inline
-
-: (fuel-eval-each) ( lines -- )
-    [ 1vector (fuel-eval) ] each ; inline
+    [ [ parse-lines ] with-compilation-unit call( -- ) ] curry
+    [ print-error ] recover ;
 
 : (fuel-eval-usings) ( usings -- )
-    [ "USING: " prepend " ;" append ] map
-    (fuel-eval-each) fuel-forget-error fuel-forget-output ;
+    [ "USE: " prepend ] map
+    (fuel-eval) fuel-forget-error fuel-forget-output ;
 
 : (fuel-eval-in) ( in -- )
-    [ dup "IN: " prepend 1vector (fuel-eval) in set ] when* ; inline
+    [ dup "IN: " prepend 1array (fuel-eval) in set ] when* ;
 
 : (fuel-eval-in-context) ( lines in usings -- )
     (fuel-begin-eval)
index a8c2adc3e1a3ccc8b10f58ed308c99163fe3ad77..3c623212b05ade78108f04231ffff39c61adfc09 100644 (file)
@@ -126,7 +126,7 @@ PRIVATE>
 : fuel-vocab-summary ( name -- )
     (fuel-vocab-summary) fuel-eval-set-result ;
 
-: fuel-index ( quot -- ) call format-index fuel-eval-set-result ;
+: fuel-index ( quot -- ) call( -- seq ) format-index fuel-eval-set-result ;
 
 : fuel-get-vocabs/tag ( tag -- )
     (fuel-get-vocabs/tag) fuel-eval-set-result ;
index 9dcbd763686fc6b7a3955cbcf7e8f6b5da9d603f..41f1102768345c23b87c0bf41755b61bf2a2650a 100644 (file)
@@ -3,7 +3,7 @@
 
 USING: accessors arrays classes.tuple combinators continuations io
 kernel lexer math prettyprint quotations sequences source-files
-strings words ;
+source-files.errors strings words ;
 
 IN: fuel.pprint
 
diff --git a/extra/graph-theory/authors.txt b/extra/graph-theory/authors.txt
deleted file mode 100644 (file)
index 9366723..0000000
+++ /dev/null
@@ -1 +0,0 @@
-William Schlieper
diff --git a/extra/graph-theory/graph-theory-docs.factor b/extra/graph-theory/graph-theory-docs.factor
deleted file mode 100644 (file)
index 39c1163..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-! See http://factorcode.org/license.txt for BSD licence.
-USING: help.markup help.syntax ;
-
-IN: graph-theory
-
-ARTICLE: "graph-protocol" "Graph protocol"
-"All graphs must be instances of the graph mixin:"
-{ $subsection graph }
-"All graphs must implement a method on the following generic word:"
-{ $subsection vertices }
-"At least one of the following two generic words must have a method; the " { $link graph } " mixin has default definitions which are mutually recursive:"
-{ $subsection adjlist }
-{ $subsection adj? }
-"All mutable graphs must implement a method on the following generic word:"
-{ $subsection add-blank-vertex }
-"All mutable undirected graphs must implement a method on the following generic word:"
-{ $subsection add-edge }
-"Mutable directed graphs should not implement the above word, as it has a default definition defined in terms of the following generic word:"
-{ $subsection add-edge* }
-"The following two words have default definitions, but are available as generics to allow implementations to optimize them:"
-{ $subsection num-vertices }
-{ $subsection num-edges } ;
-
-HELP: graph
-{ $class-description "A mixin class whose instances are graphs.  Custom implementations of the graph protocol should be declared as instances of this mixin for all graph functionality to work correctly:"
-    { $code "INSTANCE: hex-board graph" }
-} ;
-
-{ vertices num-vertices num-edges } related-words
-
-HELP: vertices
-{ $values { "graph" graph } { "seq" "The vertices" } }
-{ $description "Returns the vertices of the graph." } ;
-
-HELP: num-vertices
-{ $values { "graph" graph } { "n" "The number of vertices" } }
-{ $description "Returns the number of vertices in the graph." } ;
-
-HELP: num-edges
-{ $values { "graph" "A graph" } { "n" "The number of edges" } }
-{ $description "Returns the number of edges in the graph." } ;
-
-{ adjlist adj? } related-words
-
-HELP: adjlist
-{ $values
-    { "from" "The index of a vertex" }
-    { "graph" "The graph to be examined" }
-    { "seq" "The adjacency list" } }
-{ $description "Returns a sequence of vertices that this vertex links to" } ;
-
-HELP: adj?
-{ $values
-    { "from" "The index of a vertex" }
-    { "to" "The index of a vertex" }
-    { "graph" "A graph" }
-    { "?" "A boolean" } }
-{ $description "Returns a boolean describing whether there is an edge in the graph between from and to." } ;
-
-{ add-blank-vertex add-blank-vertices add-edge add-edge* } related-words
-
-HELP: add-blank-vertex
-{ $values
-    { "index" "A vertex index" }
-    { "graph" "A graph" } }
-{ $description "Adds a vertex to the graph." } ;
-
-HELP: add-blank-vertices
-{ $values
-    { "seq" "A sequence of vertex indices" }
-    { "graph" "A graph" } }
-{ $description "Adds vertices with indices in seq to the graph." } ;
-
-HELP: add-edge*
-{ $values
-    { "from" "The index of a vertex" }
-    { "to" "The index of another vertex" }
-    { "graph" "A graph" } }
-{ $description "Adds a one-way edge to the graph, between " { $snippet "from" } " and " { $snippet "to" } "."
-  $nl 
-  "If you want to add a two-way edge, use " { $link add-edge } " instead." } ;
-
-HELP: add-edge
-{ $values
-    { "u" "The index of a vertex" }
-    { "v" "The index of another vertex" }
-    { "graph" "A graph" } }
-{ $description "Adds a two-way edge to the graph, between " { $snippet "u" } " and " { $snippet "v" } "."
-  $nl
-  "If you want to add a one-way edge, use " { $link add-edge* } " instead." } ;
-
-{ depth-first full-depth-first dag? topological-sort } related-words
-
-HELP: depth-first
-{ $values
-    { "v" "The vertex to start the search at" }
-    { "graph" "The graph to search" }
-    { "pre" "A quotation of the form ( n -- )" }
-    { "post" "A quotation of the form ( n -- )" }
-    { "?list" "A list of booleans describing the vertices visited in the search" }
-    { "?" "A boolean describing whether or not the end-search error was thrown" } }
-{ $description "Performs a depth-first search on " { $emphasis "graph" } ".  The variable " { $emphasis "graph" } " can be accessed in both quotations."
-  $nl
-  "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first."
-  $nl
-  "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first."
-  $nl
-  { $emphasis "?list" } " is a list of booleans, " { $link t } " for every vertex visted during the search, and " { $link f } " for every vertex not visited." } ;
-
-HELP: full-depth-first
-{ $values
-    { "graph" "The graph to search" }
-    { "pre" "A quotation of the form ( n -- )" }
-    { "post" "A quotation of the form ( n -- )" }
-    { "tail" "A quotation of the form ( -- )" }
-    { "?" "A boolean describing whether or not the end-search error was thrown" } }
-{ $description "Performs a depth-first search on " { $emphasis "graph" } ".  The variable " { $emphasis "graph" } "can be accessed in both quotations."
-  $nl
-  "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first."
-  $nl
-  "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first."
-  $nl
-  "The " { $emphasis "tail" } " quotation is run after each time the depth-first search runs out of nodes.  On an undirected graph this will be each connected subgroup but on a directed graph it can be more complex." } ;
-
-HELP: dag?
-{ $values
-    { "graph" graph }
-    { "?" "A boolean indicating if the graph is acyclic" } }
-{ $description "Using a depth-first search, determines if the specified directed graph is a directed acyclic graph.  An undirected graph will produce a false result, as the algorithm does not eliminate cycles of length 2, which will include any edge that goes both ways." } ;
-
-HELP: topological-sort
-{ $values
-    { "graph" graph }
-    { "seq/f" "Either a sequence of values or f" } }
-{ $description "Using a depth-first search, topologically sorts the specified directed graph.  Returns f if the graph contains any cycles, and a topologically sorted sequence otherwise." } ;
diff --git a/extra/graph-theory/graph-theory.factor b/extra/graph-theory/graph-theory.factor
deleted file mode 100644 (file)
index b14832d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: kernel combinators fry continuations sequences arrays vectors assocs hashtables heaps namespaces ;
-
-IN: graph-theory
-
-MIXIN: graph
-SYMBOL: visited?
-ERROR: end-search ;
-
-GENERIC: vertices ( graph -- seq ) flushable
-
-GENERIC: num-vertices ( graph -- n ) flushable
-
-GENERIC: num-edges ( graph -- n ) flushable
-
-GENERIC: adjlist ( from graph -- seq ) flushable
-
-GENERIC: adj? ( from to graph -- ? ) flushable
-
-GENERIC: add-blank-vertex ( index graph -- )
-
-GENERIC: delete-blank-vertex ( index graph -- )
-
-GENERIC: add-edge* ( from to graph -- )
-
-GENERIC: add-edge ( u v graph -- )
-
-GENERIC: delete-edge* ( from to graph -- )
-
-GENERIC: delete-edge ( u v graph -- )
-
-M: graph num-vertices
-    vertices length ;
-
-M: graph num-edges
-   [ vertices ] [ '[ _ adjlist length ] map sum ] bi ;
-
-M: graph adjlist
-    [ vertices ] [ swapd '[ _ swap _ adj? ] filter ] bi ;
-
-M: graph adj?
-    swapd adjlist index >boolean ;
-
-M: graph add-edge
-    [ add-edge* ] [ swapd add-edge* ] 3bi ;
-
-M: graph delete-edge
-    [ delete-edge* ] [ swapd delete-edge* ] 3bi ;
-
-: add-blank-vertices ( seq graph -- )
-    '[ _ add-blank-vertex ] each ;
-
-: delete-vertex ( index graph -- )
-    [ adjlist ]
-    [ '[ _ _ 3dup adj? [ delete-edge* ] [ 3drop ] if ] each ]
-    [ delete-blank-vertex ] 2tri ;
-
-<PRIVATE
-
-: search-wrap ( quot graph -- ? )
-    [ [ graph set ] [ vertices [ f 2array ] map >hashtable visited? set ] bi
-      [ t ] compose [ dup end-search? [ drop f ] [ rethrow ] if ] recover ] with-scope ; inline
-
-: (depth-first) ( v pre post -- )
-    { [ 2drop visited? get t -rot set-at ] 
-      [ drop call ]
-      [ [ graph get adjlist ] 2dip
-        '[ dup visited? get at [ drop ] [ _ _ (depth-first) ] if ] each ]
-      [ nip call ] } 3cleave ; inline
-
-PRIVATE>
-
-: depth-first ( v graph pre post -- ?list ? )
-    '[ _ _ (depth-first) visited? get ] swap search-wrap ; inline
-
-: full-depth-first ( graph pre post tail -- ? )
-    '[ [ visited? get [ nip not ] assoc-find ] 
-       [ drop _ _ (depth-first) @ ] 
-       while 2drop ] swap search-wrap ; inline
-
-: dag? ( graph -- ? )
-    V{ } clone swap [ 2dup swap push dupd
-                     '[ _ swap graph get adj? not ] all? 
-                      [ end-search ] unless ]
-                    [ drop dup pop* ] [ ] full-depth-first nip ;
-
-: topological-sort ( graph -- seq/f )
-    dup dag?
-    [ V{ } swap [ drop ] [ prefix ] [ ] full-depth-first drop ]
-    [ drop f ] if ;
diff --git a/extra/graph-theory/reversals/reversals.factor b/extra/graph-theory/reversals/reversals.factor
deleted file mode 100644 (file)
index 1ea1a3f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: accessors kernel graph-theory ;
-
-IN: graph-theory.reversals
-
-TUPLE: reversal graph ;
-
-GENERIC: reverse-graph ( graph -- reversal )
-
-M: graph reverse-graph reversal boa ;
-
-M: reversal reverse-graph graph>> ;
-
-INSTANCE: reversal graph
-
-M: reversal vertices
-    graph>> vertices ;
-
-M: reversal adj?
-    swapd graph>> adj? ;
diff --git a/extra/graph-theory/sparse/sparse.factor b/extra/graph-theory/sparse/sparse.factor
deleted file mode 100644 (file)
index 5c6365b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: accessors kernel sequences arrays vectors sets assocs hashtables graph-theory namespaces fry ;
-
-IN: graph-theory.sparse
-
-TUPLE: sparse-graph alist ; 
-
-: <sparse-graph> ( -- sparse-graph )
-    H{ } clone sparse-graph boa ;
-
-: >sparse-graph ( graph -- sparse-graph )
-    [ vertices ] keep
-    '[ dup _ adjlist 2array ] map >hashtable sparse-graph boa ;
-
-INSTANCE: sparse-graph graph
-
-M: sparse-graph vertices
-    alist>> keys ;
-
-M: sparse-graph adjlist
-    alist>> at ;
-
-M: sparse-graph add-blank-vertex 
-    alist>> V{ } clone -rot set-at ;
-
-M: sparse-graph delete-blank-vertex
-    alist>> delete-at ;
-
-M: sparse-graph add-edge*
-    alist>> swapd at adjoin ;
-
-M: sparse-graph delete-edge*
-    alist>> swapd at delete ;
diff --git a/extra/graph-theory/summary.txt b/extra/graph-theory/summary.txt
deleted file mode 100644 (file)
index 3e1d791..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Graph-theoretic algorithms
diff --git a/extra/graph-theory/tags.txt b/extra/graph-theory/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
index 4eaa98495328e5f9f94067cb87a2784d0e870855..cf9e9c836aceb06ca93cafc7cc0c78d2ba30ca61 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007 Doug Coleman.
+! Copyright (C) 2007, 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors images images.loader io.pathnames kernel namespaces
 opengl opengl.gl opengl.textures sequences strings ui ui.gadgets
@@ -27,11 +27,8 @@ M: image-gadget draw-gadget* ( gadget -- )
 
 GENERIC: image. ( object -- )
 
-: default-image. ( path -- )
-    <image-gadget> gadget. ;
+M: string image. ( image -- ) load-image image. ;
 
-M: string image. ( image -- ) load-image default-image. ;
+M: pathname image. ( image -- ) load-image image. ;
 
-M: pathname image. ( image -- ) load-image default-image. ;
-
-M: image image. ( image -- ) default-image. ;
+M: image image. ( image -- ) <image-gadget> gadget. ;
index ed268e558daaee26b47325b1ef03b13c6672861b..5597422898768672224e33f76c05fe8a97b87a0c 100644 (file)
@@ -40,7 +40,7 @@ M: ast-array infix-codegen
 M: ast-op infix-codegen
     [ left>> infix-codegen ] [ right>> infix-codegen ]
     [ op>> select-op ] tri
-    2over [ number? ] both? [ call ] [
+    2over [ number? ] both? [ call( a b -- c ) ] [
         [ [ prepare-operand ] bi@ ] dip '[ @ @ @ ]
     ] if ;
 
index 218ed92018908c7d6bf2d4d45ba2027f60bb257a..539fba54ebd171e8f8a30f5fd47dd60cdca4d068 100644 (file)
@@ -58,7 +58,8 @@ IN: irc.messages.tests
      { command "NICK" }
      { parameters  { } }
      { trailing "someuser2" }
-     { sender "someuser" } } }
+     { sender "someuser" }
+     { nickname "someuser2" } } }
 [ ":someuser!n=user@some.where NICK :someuser2"
   string>irc-message f >>timestamp ] unit-test
 
diff --git a/extra/jamshred/authors.txt b/extra/jamshred/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/deploy.factor b/extra/jamshred/deploy.factor
new file mode 100644 (file)
index 0000000..9a18cf1
--- /dev/null
@@ -0,0 +1,12 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 1 }
+    { deploy-reflection 1 }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Jamshred" }
+}
diff --git a/extra/jamshred/game/authors.txt b/extra/jamshred/game/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/game/game.factor b/extra/jamshred/game/game.factor
new file mode 100644 (file)
index 0000000..9cb5bc7
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel opengl arrays sequences jamshred.log jamshred.player jamshred.sound jamshred.tunnel math math.constants math.vectors ;
+IN: jamshred.game
+
+TUPLE: jamshred sounds tunnel players running quit ;
+
+: <jamshred> ( -- jamshred )
+    <sounds> <random-tunnel> "Player 1" pick <player>
+    2dup swap play-in-tunnel 1array f f jamshred boa ;
+
+: jamshred-player ( jamshred -- player )
+    ! TODO: support more than one player
+    players>> first ;
+
+: jamshred-update ( jamshred -- )
+    dup running>> [
+        jamshred-player update-player
+    ] [ drop ] if ;
+
+: toggle-running ( jamshred -- )
+    dup running>> [
+        f >>running drop
+    ] [
+        [ jamshred-player moved ]
+        [ t >>running drop ] bi
+    ] if ;
+
+: mouse-moved ( x-radians y-radians jamshred -- )
+    jamshred-player -rot turn-player ;
+
+: units-per-full-roll ( -- n ) 50 ;
+
+: jamshred-roll ( jamshred n -- )
+    [ jamshred-player ] dip 2 pi * * units-per-full-roll / roll-player ;
+        
+: mouse-scroll-x ( jamshred x -- ) jamshred-roll ;
+
+: mouse-scroll-y ( jamshred y -- )
+    neg swap jamshred-player change-player-speed ;
diff --git a/extra/jamshred/gl/authors.txt b/extra/jamshred/gl/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/gl/gl.factor b/extra/jamshred/gl/gl.factor
new file mode 100644 (file)
index 0000000..bae275e
--- /dev/null
@@ -0,0 +1,112 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types jamshred.game jamshred.oint
+jamshred.player jamshred.tunnel kernel math math.constants
+math.functions math.vectors opengl opengl.gl opengl.glu
+opengl.demo-support sequences specialized-arrays.float ;
+IN: jamshred.gl
+
+: min-vertices ( -- n ) 6 ; inline
+: max-vertices ( -- n ) 32 ; inline
+
+: n-vertices ( -- n ) 32 ; inline
+
+! render enough of the tunnel that it looks continuous
+: n-segments-ahead ( -- n ) 60 ; inline
+: n-segments-behind ( -- n ) 40 ; inline
+
+: wall-drawing-offset ( -- n )
+    #! so that we can't see through the wall, we draw it a bit further away
+    0.15 ;
+
+: wall-drawing-radius ( segment -- r )
+    radius>> wall-drawing-offset + ;
+
+: wall-up ( segment -- v )
+    [ wall-drawing-radius ] [ up>> ] bi n*v ;
+
+: wall-left ( segment -- v )
+    [ wall-drawing-radius ] [ left>> ] bi n*v ;
+
+: segment-vertex ( theta segment -- vertex )
+    [
+        [ wall-up swap sin v*n ] [ wall-left swap cos v*n ] 2bi v+
+    ] [
+        location>> v+
+    ] bi ;
+
+: segment-vertex-normal ( vertex segment -- normal )
+    location>> swap v- normalize ;
+
+: segment-vertex-and-normal ( segment theta -- vertex normal )
+    swap [ segment-vertex ] keep dupd segment-vertex-normal ;
+
+: equally-spaced-radians ( n -- seq )
+    #! return a sequence of n numbers between 0 and 2pi
+    dup [ / pi 2 * * ] curry map ;
+
+: draw-segment-vertex ( segment theta -- )
+    over color>> gl-color segment-vertex-and-normal
+    gl-normal gl-vertex ;
+
+: draw-vertex-pair ( theta next-segment segment -- )
+    rot tuck draw-segment-vertex draw-segment-vertex ;
+
+: draw-segment ( next-segment segment -- )
+    GL_QUAD_STRIP [
+        [ draw-vertex-pair ] 2curry
+        n-vertices equally-spaced-radians float-array{ 0.0 } append swap each
+    ] do-state ;
+
+: draw-segments ( segments -- )
+    1 over length pick subseq swap [ draw-segment ] 2each ;
+
+: segments-to-render ( player -- segments )
+    dup nearest-segment>> number>> dup n-segments-behind -
+    swap n-segments-ahead + rot tunnel>> sub-tunnel ;
+
+: draw-tunnel ( player -- )
+    segments-to-render draw-segments ;
+
+: init-graphics ( -- )
+    GL_DEPTH_TEST glEnable
+    GL_SCISSOR_TEST glDisable
+    1.0 glClearDepth
+    0.0 0.0 0.0 0.0 glClearColor
+    GL_PROJECTION glMatrixMode glPushMatrix
+    GL_MODELVIEW glMatrixMode glPushMatrix
+    GL_LEQUAL glDepthFunc
+    GL_LIGHTING glEnable
+    GL_LIGHT0 glEnable
+    GL_FOG glEnable
+    GL_FOG_DENSITY 0.09 glFogf
+    GL_FRONT GL_AMBIENT_AND_DIFFUSE glColorMaterial
+    GL_COLOR_MATERIAL glEnable
+    GL_LIGHT0 GL_POSITION float-array{ 0.0 0.0 0.0 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_AMBIENT float-array{ 0.2 0.2 0.2 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_DIFFUSE float-array{ 1.0 1.0 1.0 1.0 } underlying>> glLightfv
+    GL_LIGHT0 GL_SPECULAR float-array{ 1.0 1.0 1.0 1.0 } underlying>> glLightfv ;
+
+: cleanup-graphics ( -- )
+    GL_DEPTH_TEST glDisable
+    GL_SCISSOR_TEST glEnable
+    GL_MODELVIEW glMatrixMode glPopMatrix
+    GL_PROJECTION glMatrixMode glPopMatrix
+    GL_LIGHTING glDisable
+    GL_LIGHT0 glDisable
+    GL_FOG glDisable
+    GL_COLOR_MATERIAL glDisable ;
+
+: pre-draw ( width height -- )
+    GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
+    GL_PROJECTION glMatrixMode glLoadIdentity
+    dup 0 = [ 2drop ] [ / >float 45.0 swap 0.1 100.0 gluPerspective ] if
+    GL_MODELVIEW glMatrixMode glLoadIdentity ;
+
+: player-view ( player -- )
+    [ location>> ]
+    [ [ location>> ] [ forward>> ] bi v+ ]
+    [ up>> ] tri gl-look-at ;
+
+: draw-jamshred ( jamshred width height -- )
+    pre-draw jamshred-player [ player-view ] [ draw-tunnel ] bi ;
diff --git a/extra/jamshred/jamshred.factor b/extra/jamshred/jamshred.factor
new file mode 100644 (file)
index 0000000..49624e2
--- /dev/null
@@ -0,0 +1,94 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays calendar jamshred.game jamshred.gl jamshred.player jamshred.log kernel math math.constants math.rectangles math.vectors namespaces sequences threads ui ui.backend ui.gadgets ui.gadgets.worlds ui.gestures ui.render ;
+IN: jamshred
+
+TUPLE: jamshred-gadget < gadget { jamshred jamshred } last-hand-loc ;
+
+: <jamshred-gadget> ( jamshred -- gadget )
+    jamshred-gadget new swap >>jamshred ;
+
+: default-width ( -- x ) 800 ;
+: default-height ( -- y ) 600 ;
+
+M: jamshred-gadget pref-dim*
+    drop default-width default-height 2array ;
+
+M: jamshred-gadget draw-gadget* ( gadget -- )
+    [ jamshred>> ] [ dim>> first2 draw-jamshred ] bi ;
+
+: jamshred-loop ( gadget -- )
+    dup jamshred>> quit>> [
+        drop
+    ] [
+        [ jamshred>> jamshred-update ]
+        [ relayout-1 ]
+        [ 100 milliseconds sleep jamshred-loop ] tri 
+    ] if ;
+
+: fullscreen ( gadget -- )
+    find-world t swap set-fullscreen* ;
+
+: no-fullscreen ( gadget -- )
+    find-world f swap set-fullscreen* ;
+
+: toggle-fullscreen ( world -- )
+    [ fullscreen? not ] keep set-fullscreen* ;
+
+M: jamshred-gadget graft* ( gadget -- )
+    [ find-gl-context init-graphics ]
+    [ [ jamshred-loop ] curry in-thread ] bi ;
+
+M: jamshred-gadget ungraft* ( gadget -- )
+    dup find-gl-context cleanup-graphics jamshred>> t swap (>>quit) ;
+
+: jamshred-restart ( jamshred-gadget -- )
+    <jamshred> >>jamshred drop ;
+
+: pix>radians ( n m -- theta )
+    / pi 4 * * ; ! 2 / / pi 2 * * ;
+
+: x>radians ( x gadget -- theta )
+    #! translate motion of x pixels to an angle
+    dim>> first pix>radians neg ;
+
+: y>radians ( y gadget -- theta )
+    #! translate motion of y pixels to an angle
+    dim>> second pix>radians ;
+
+: (handle-mouse-motion) ( jamshred-gadget mouse-motion -- )
+    dupd [ first swap x>radians ] [ second swap y>radians ] 2bi
+    rot jamshred>> mouse-moved ;
+    
+: handle-mouse-motion ( jamshred-gadget -- )
+    hand-loc get [
+        over last-hand-loc>> [
+            v- (handle-mouse-motion) 
+        ] [ 2drop ] if* 
+    ] 2keep >>last-hand-loc drop ;
+
+: handle-mouse-scroll ( jamshred-gadget -- )
+    jamshred>> scroll-direction get
+    [ first mouse-scroll-x ]
+    [ second mouse-scroll-y ] 2bi ;
+
+: quit ( gadget -- )
+    [ no-fullscreen ] [ close-window ] bi ;
+
+jamshred-gadget H{
+    { T{ key-down f f "r" } [ jamshred-restart ] }
+    { T{ key-down f f " " } [ jamshred>> toggle-running ] }
+    { T{ key-down f f "f" } [ find-world toggle-fullscreen ] }
+    { T{ key-down f f "UP" } [ jamshred>> jamshred-player 1 swap change-player-speed ] }
+    { T{ key-down f f "DOWN" } [ jamshred>> jamshred-player -1 swap change-player-speed ] }
+    { T{ key-down f f "LEFT" } [ jamshred>> 1 jamshred-roll ] }
+    { T{ key-down f f "RIGHT" } [ jamshred>> -1 jamshred-roll ] }
+    { T{ key-down f f "q" } [ quit ] }
+    { motion [ handle-mouse-motion ] }
+    { mouse-scroll [ handle-mouse-scroll ] }
+} set-gestures
+
+: jamshred-window ( -- )
+    [ <jamshred> <jamshred-gadget> "Jamshred" open-window ] with-ui ;
+
+MAIN: jamshred-window
diff --git a/extra/jamshred/log/log.factor b/extra/jamshred/log/log.factor
new file mode 100644 (file)
index 0000000..f2517d1
--- /dev/null
@@ -0,0 +1,10 @@
+USING: kernel logging ;
+IN: jamshred.log
+
+LOG: (jamshred-log) DEBUG
+
+: with-jamshred-log ( quot -- )
+    "jamshred" swap with-logging ; inline
+
+: jamshred-log ( message -- )
+    [ (jamshred-log) ] with-jamshred-log ; ! ugly...
diff --git a/extra/jamshred/oint/authors.txt b/extra/jamshred/oint/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/oint/oint-tests.factor b/extra/jamshred/oint/oint-tests.factor
new file mode 100644 (file)
index 0000000..401935f
--- /dev/null
@@ -0,0 +1,8 @@
+USING: jamshred.oint tools.test ;
+IN: jamshred.oint-tests
+
+[ { 0 -1 -1 } ] [ { 0 1 -1 } { 0 -1 0 } reflect ] unit-test
+[ { 0 1 0 } ] [ { 1 1 0 } { 1 0 0 } proj-perp ] unit-test
+[ { 1 0 0 } ] [ { 1 1 0 } { 0 1 0 } proj-perp ] unit-test
+[ { 1/2 -1/2 0 } ] [ { 1 0 0 } { 1 1 0 } proj-perp ] unit-test
+[ { -1/2 1/2 0 } ] [ { 0 1 0 } { 1 1 0 } proj-perp ] unit-test
diff --git a/extra/jamshred/oint/oint.factor b/extra/jamshred/oint/oint.factor
new file mode 100644 (file)
index 0000000..ae72bd8
--- /dev/null
@@ -0,0 +1,73 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays kernel locals math math.constants math.functions math.matrices math.vectors math.quaternions random sequences ;
+IN: jamshred.oint
+
+! An oint is a point with three linearly independent unit vectors
+! given relative to that point. In jamshred a player's location and
+! direction are given by the player's oint. Similarly, a tunnel
+! segment's location and orientation are given by an oint.
+
+TUPLE: oint location forward up left ;
+C: <oint> oint
+
+: rotation-quaternion ( theta axis -- quaternion )
+    swap 2 / dup cos swap sin rot n*v first3 rect> [ rect> ] dip 2array ;
+
+: rotate-vector ( q qrecip v -- v )
+    v>q swap q* q* q>v ;
+
+: rotate-oint ( oint theta axis -- )
+    rotation-quaternion dup qrecip pick
+    [ forward>> rotate-vector >>forward ]
+    [ up>> rotate-vector >>up ]
+    [ left>> rotate-vector >>left ] 3tri drop ;
+
+: left-pivot ( oint theta -- )
+    over left>> rotate-oint ;
+
+: up-pivot ( oint theta -- )
+    over up>> rotate-oint ;
+
+: forward-pivot ( oint theta -- )
+    over forward>> rotate-oint ;
+
+: random-float+- ( n -- m )
+    #! find a random float between -n/2 and n/2
+    dup 10000 * >fixnum random 10000 / swap 2 / - ;
+
+: random-turn ( oint theta -- )
+    2 / 2dup random-float+- left-pivot random-float+- up-pivot ;
+
+: location+ ( v oint -- )
+    [ location>> v+ ] [ (>>location) ] bi ;
+
+: go-forward ( distance oint -- )
+    [ forward>> n*v ] [ location+ ] bi ;
+
+: distance-vector ( oint oint -- vector )
+    [ location>> ] bi@ swap v- ;
+
+: distance ( oint oint -- distance )
+    distance-vector norm ;
+
+: scalar-projection ( v1 v2 -- n )
+    #! the scalar projection of v1 onto v2
+    tuck v. swap norm / ;
+
+: proj-perp ( u v -- w )
+    dupd proj v- ;
+
+: perpendicular-distance ( oint oint -- distance )
+    tuck distance-vector swap 2dup left>> scalar-projection abs
+    -rot up>> scalar-projection abs + ;
+
+:: reflect ( v n -- v' )
+    #! bounce v on a surface with normal n
+    v v n v. n n v. / 2 * n n*v v- ;
+
+: half-way ( p1 p2 -- p3 )
+    over v- 2 v/n v+ ;
+
+: half-way-between-oints ( o1 o2 -- p )
+    [ location>> ] bi@ half-way ;
diff --git a/extra/jamshred/player/authors.txt b/extra/jamshred/player/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/player/player.factor b/extra/jamshred/player/player.factor
new file mode 100644 (file)
index 0000000..d33b78f
--- /dev/null
@@ -0,0 +1,137 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors colors.constants combinators jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel locals math math.constants math.order math.ranges math.vectors math.matrices sequences shuffle specialized-arrays.float strings system ;
+IN: jamshred.player
+
+TUPLE: player < oint
+    { name string }
+    { sounds sounds }
+    tunnel
+    nearest-segment
+    { last-move integer }
+    { speed float } ;
+
+! speeds are in GL units / second
+: default-speed ( -- speed ) 1.0 ;
+: max-speed ( -- speed ) 30.0 ;
+
+: <player> ( name sounds -- player )
+    [ float-array{ 0 0 5 } float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 } ] 2dip
+    f f 0 default-speed player boa ;
+
+: turn-player ( player x-radians y-radians -- )
+    [ over ] dip left-pivot up-pivot ;
+
+: roll-player ( player z-radians -- )
+    forward-pivot ;
+
+: to-tunnel-start ( player -- )
+    [ tunnel>> first dup location>> ]
+    [ tuck (>>location) (>>nearest-segment) ] bi ;
+
+: play-in-tunnel ( player segments -- )
+    >>tunnel to-tunnel-start ;
+
+: update-nearest-segment ( player -- )
+    [ tunnel>> ] [ dup nearest-segment>> nearest-segment ]
+    [ (>>nearest-segment) ] tri ;
+
+: update-time ( player -- seconds-passed )
+    millis swap [ last-move>> - 1000 / ] [ (>>last-move) ] 2bi ;
+
+: moved ( player -- ) millis swap (>>last-move) ;
+
+: speed-range ( -- range )
+    max-speed [0,b] ;
+
+: change-player-speed ( inc player -- )
+    [ + speed-range clamp-to-range ] change-speed drop ;
+
+: multiply-player-speed ( n player -- )
+    [ * speed-range clamp-to-range ] change-speed drop ; 
+
+: distance-to-move ( seconds-passed player -- distance )
+    speed>> * ;
+
+: bounce ( d-left player -- d-left' player )
+    {
+        [ dup nearest-segment>> bounce-off-wall ]
+        [ sounds>> bang ]
+        [ 3/4 swap multiply-player-speed ]
+        [ ]
+    } cleave ;
+
+:: (distance) ( heading player -- current next location heading )
+    player nearest-segment>>
+    player [ tunnel>> ] [ nearest-segment>> ] bi heading heading-segment
+    player location>> heading ;
+
+: distance-to-heading-segment ( heading player -- distance )
+    (distance) distance-to-next-segment ;
+
+: distance-to-heading-segment-area ( heading player -- distance )
+    (distance) distance-to-next-segment-area ;
+
+: distance-to-collision ( player -- distance )
+    dup nearest-segment>> (distance-to-collision) ;
+
+: almost-to-collision ( player -- distance )
+    distance-to-collision 0.1 - dup 0 < [ drop 0 ] when ;
+
+: from ( player -- radius distance-from-centre )
+    [ nearest-segment>> dup radius>> swap ] [ location>> ] bi
+    distance-from-centre ;
+
+: distance-from-wall ( player -- distance ) from - ;
+: fraction-from-centre ( player -- fraction ) from swap / ;
+: fraction-from-wall ( player -- fraction )
+    fraction-from-centre 1 swap - ;
+
+: update-nearest-segment2 ( heading player -- )
+    2dup distance-to-heading-segment-area 0 <= [
+        [ tunnel>> ] [ nearest-segment>> rot heading-segment ]
+        [ (>>nearest-segment) ] tri
+    ] [
+        2drop
+    ] if ;
+
+:: move-player-on-heading ( d-left player distance heading -- d-left' player )
+    [let* | d-to-move [ d-left distance min ]
+            move-v [ d-to-move heading n*v ] |
+        move-v player location+
+        heading player update-nearest-segment2
+        d-left d-to-move - player ] ;
+
+: distance-to-move-freely ( player -- distance )
+    [ almost-to-collision ]
+    [ [ forward>> ] keep distance-to-heading-segment-area ] bi min ;
+
+: ?move-player-freely ( d-left player -- d-left' player )
+    over 0 > [
+        ! must make sure we are moving a significant distance, otherwise
+        ! we can recurse endlessly due to floating-point imprecision.
+        ! (at least I /think/ that's what causes it...)
+        dup distance-to-move-freely dup 0.1 > [
+            over forward>> move-player-on-heading ?move-player-freely
+        ] [ drop ] if
+    ] when ;
+
+: drag-heading ( player -- heading )
+    [ forward>> ] [ nearest-segment>> forward>> proj ] bi ;
+
+: drag-player ( d-left player -- d-left' player )
+    dup [ [ drag-heading ] keep distance-to-heading-segment-area ]
+    [ drag-heading move-player-on-heading ] bi ;
+
+: (move-player) ( d-left player -- d-left' player )
+    ?move-player-freely over 0 > [
+        ! bounce
+        drag-player
+        (move-player)
+    ] when ;
+
+: move-player ( player -- )
+    [ update-time ] [ distance-to-move ] [ (move-player) 2drop ] tri ;
+
+: update-player ( player -- )
+    [ move-player ] [ nearest-segment>> "white" named-color swap (>>color) ] bi ;
diff --git a/extra/jamshred/sound/sound.factor b/extra/jamshred/sound/sound.factor
new file mode 100644 (file)
index 0000000..6a9b331
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors io.pathnames kernel openal sequences ;
+IN: jamshred.sound
+
+TUPLE: sounds bang ;
+
+: assign-sound ( source wav-path -- )
+    resource-path create-buffer-from-wav AL_BUFFER swap set-source-param ;
+
+: <sounds> ( -- sounds )
+    init-openal 1 gen-sources first sounds boa
+    dup bang>> "extra/jamshred/sound/bang.wav" assign-sound ;
+
+: bang ( sounds -- ) bang>> source-play check-error ;
diff --git a/extra/jamshred/summary.txt b/extra/jamshred/summary.txt
new file mode 100644 (file)
index 0000000..e26fc1c
--- /dev/null
@@ -0,0 +1 @@
+A simple 3d tunnel racing game
diff --git a/extra/jamshred/tags.txt b/extra/jamshred/tags.txt
new file mode 100644 (file)
index 0000000..8ae5957
--- /dev/null
@@ -0,0 +1,2 @@
+applications
+games
diff --git a/extra/jamshred/tunnel/authors.txt b/extra/jamshred/tunnel/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/jamshred/tunnel/tunnel-tests.factor b/extra/jamshred/tunnel/tunnel-tests.factor
new file mode 100644 (file)
index 0000000..8e2f1a6
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays jamshred.oint jamshred.tunnel kernel math.vectors sequences specialized-arrays.float tools.test ;
+IN: jamshred.tunnel.tests
+
+[ 0 ] [ T{ segment f { 0 0 0 } f f f 0 }
+        T{ segment f { 1 1 1 } f f f 1 }
+        T{ oint f { 0 0 0.25 } }
+        nearer-segment number>> ] unit-test
+
+[ 0 ] [ T{ oint f { 0 0 0 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+[ 1 ] [ T{ oint f { 0 0 -1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+[ 2 ] [ T{ oint f { 0 0.1 -2.1 } } <straight-tunnel> find-nearest-segment number>> ] unit-test
+
+[ 3 ] [ <straight-tunnel> T{ oint f { 0 0 -3.25 } } 0 nearest-segment-forward number>> ] unit-test
+
+[ float-array{ 0 0 0 } ] [ <straight-tunnel> T{ oint f { 0 0 -0.25 } } over first nearest-segment location>> ] unit-test
+
+: test-segment-oint ( -- oint )
+    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint> ;
+
+[ { -1 0 0 } ] [ test-segment-oint { 1 0 0 } vector-to-centre ] unit-test
+[ { 1 0 0 } ] [ test-segment-oint { -1 0 0 } vector-to-centre ] unit-test
+[ { 0 -1 0 } ] [ test-segment-oint { 0 1 0 } vector-to-centre ] unit-test
+[ { 0 1 0 } ] [ test-segment-oint { 0 -1 0 } vector-to-centre ] unit-test
+[ { -1 0 0 } ] [ test-segment-oint { 1 0 -1 } vector-to-centre ] unit-test
+[ { 1 0 0 } ] [ test-segment-oint { -1 0 -1 } vector-to-centre ] unit-test
+[ { 0 -1 0 } ] [ test-segment-oint { 0 1 -1 } vector-to-centre ] unit-test
+[ { 0 1 0 } ] [ test-segment-oint { 0 -1 -1 } vector-to-centre ] unit-test
+
+: simplest-straight-ahead ( -- oint segment )
+    { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } <oint>
+    initial-segment ;
+
+[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-heading ] unit-test
+[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-relative-location ] unit-test
+
+: simple-collision-up ( -- oint segment )
+    { 0 0 0 } { 0 1 0 } { 0 0 1 } { -1 0 0 } <oint>
+    initial-segment ;
+
+[ { 0.0 1.0 0.0 } ] [ simple-collision-up sideways-heading ] unit-test
+[ { 0.0 0.0 0.0 } ] [ simple-collision-up sideways-relative-location ] unit-test
+[ { 0.0 1.0 0.0 } ]
+[ simple-collision-up collision-vector 0 0 0 3array v+ ] unit-test
diff --git a/extra/jamshred/tunnel/tunnel.factor b/extra/jamshred/tunnel/tunnel.factor
new file mode 100644 (file)
index 0000000..4c4b3e6
--- /dev/null
@@ -0,0 +1,165 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays colors combinators kernel locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences specialized-arrays.float vectors jamshred.oint ;
+IN: jamshred.tunnel
+
+: n-segments ( -- n ) 5000 ; inline
+
+TUPLE: segment < oint number color radius ;
+C: <segment> segment
+
+: segment-number++ ( segment -- )
+    [ number>> 1+ ] keep (>>number) ;
+
+: random-color ( -- color )
+    { 100 100 100 } [ random 100 / >float ] map first3 1.0 <rgba> ;
+
+: tunnel-segment-distance ( -- n ) 0.4 ;
+: random-rotation-angle ( -- theta ) pi 20 / ;
+
+: random-segment ( previous-segment -- segment )
+    clone dup random-rotation-angle random-turn
+    tunnel-segment-distance over go-forward
+    random-color >>color dup segment-number++ ;
+
+: (random-segments) ( segments n -- segments )
+    dup 0 > [
+        [ dup peek random-segment over push ] dip 1- (random-segments)
+    ] [ drop ] if ;
+
+: default-segment-radius ( -- r ) 1 ;
+
+: initial-segment ( -- segment )
+    float-array{ 0 0 0 } float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 }
+    0 random-color default-segment-radius <segment> ;
+
+: random-segments ( n -- segments )
+    initial-segment 1vector swap (random-segments) ;
+
+: simple-segment ( n -- segment )
+    [ float-array{ 0 0 -1 } n*v float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 } ] keep
+    random-color default-segment-radius <segment> ;
+
+: simple-segments ( n -- segments )
+    [ simple-segment ] map ;
+
+: <random-tunnel> ( -- segments )
+    n-segments random-segments ;
+
+: <straight-tunnel> ( -- segments )
+    n-segments simple-segments ;
+
+: sub-tunnel ( from to segments -- segments )
+    #! return segments between from and to, after clamping from and to to
+    #! valid values
+    [ sequence-index-range [ clamp-to-range ] curry bi@ ] keep <slice> ;
+
+: nearer-segment ( segment segment oint -- segment )
+    #! return whichever of the two segments is nearer to the oint
+    [ 2dup ] dip tuck distance [ distance ] dip < -rot ? ;
+
+: (find-nearest-segment) ( nearest next oint -- nearest ? )
+    #! find the nearest of 'next' and 'nearest' to 'oint', and return
+    #! t if the nearest hasn't changed
+    pick [ nearer-segment dup ] dip = ;
+
+: find-nearest-segment ( oint segments -- segment )
+    dup first swap rest-slice rot [ (find-nearest-segment) ] curry
+    find 2drop ;
+    
+: nearest-segment-forward ( segments oint start -- segment )
+    rot dup length swap <slice> find-nearest-segment ;
+
+: nearest-segment-backward ( segments oint start -- segment )
+    swapd 1+ 0 spin <slice> <reversed> find-nearest-segment ;
+
+: nearest-segment ( segments oint start-segment -- segment )
+    #! find the segment nearest to 'oint', and return it.
+    #! start looking at segment 'start-segment'
+    number>> over [
+        [ nearest-segment-forward ] 3keep nearest-segment-backward
+    ] dip nearer-segment ;
+
+: get-segment ( segments n -- segment )
+    over sequence-index-range clamp-to-range swap nth ;
+
+: next-segment ( segments current-segment -- segment )
+    number>> 1+ get-segment ;
+
+: previous-segment ( segments current-segment -- segment )
+    number>> 1- get-segment ;
+
+: heading-segment ( segments current-segment heading -- segment )
+    #! the next segment on the given heading
+    over forward>> v. 0 <=> {
+        { +gt+ [ next-segment ] }
+        { +lt+ [ previous-segment ] }
+        { +eq+ [ nip ] } ! current segment
+    } case ;
+
+:: distance-to-next-segment ( current next location heading -- distance )
+    [let | cf [ current forward>> ] |
+        cf next location>> v. cf location v. - cf heading v. / ] ;
+
+:: distance-to-next-segment-area ( current next location heading -- distance )
+    [let | cf [ current forward>> ]
+           h [ next current half-way-between-oints ] |
+        cf h v. cf location v. - cf heading v. / ] ;
+
+: vector-to-centre ( seg loc -- v )
+    over location>> swap v- swap forward>> proj-perp ;
+
+: distance-from-centre ( seg loc -- distance )
+    vector-to-centre norm ;
+
+: wall-normal ( seg oint -- n )
+    location>> vector-to-centre normalize ;
+
+: distant ( -- n ) 1000 ;
+
+: max-real ( a b -- c )
+    #! sometimes collision-coefficient yields complex roots, so we ignore these (hack)
+    dup real? [
+        over real? [ max ] [ nip ] if
+    ] [
+        drop dup real? [ drop distant ] unless
+    ] if ;
+
+:: collision-coefficient ( v w r -- c )
+    v norm 0 = [
+        distant
+    ] [
+        [let* | a [ v dup v. ]
+                b [ v w v. 2 * ]
+                c [ w dup v. r sq - ] |
+            c b a quadratic max-real ]
+    ] if ;
+
+: sideways-heading ( oint segment -- v )
+    [ forward>> ] bi@ proj-perp ;
+
+: sideways-relative-location ( oint segment -- loc )
+    [ [ location>> ] bi@ v- ] keep forward>> proj-perp ;
+
+: (distance-to-collision) ( oint segment -- distance )
+    [ sideways-heading ] [ sideways-relative-location ]
+    [ nip radius>> ] 2tri collision-coefficient ;
+
+: collision-vector ( oint segment -- v )
+    dupd (distance-to-collision) swap forward>> n*v ;
+
+: bounce-forward ( segment oint -- )
+    [ wall-normal ] [ forward>> swap reflect ] [ (>>forward) ] tri ;
+
+: bounce-left ( segment oint -- )
+    #! must be done after forward
+    [ forward>> vneg ] dip [ left>> swap reflect ]
+    [ forward>> proj-perp normalize ] [ (>>left) ] tri ;
+
+: bounce-up ( segment oint -- )
+    #! must be done after forward and left!
+    nip [ forward>> ] [ left>> cross ] [ (>>up) ] tri ;
+
+: bounce-off-wall ( oint segment -- )
+    swap [ bounce-forward ] [ bounce-left ] [ bounce-up ] 2tri ;
+
index 02f5ce8b21ebbaa8c08c4da6950a46ef1a20b0e1..9f86336f96229e7695a9aa83c75f108a0f1ad2f8 100755 (executable)
@@ -141,7 +141,7 @@ TUPLE: key-caps-gadget < gadget keys alarm ;
         swap [ 
             " " [ drop ] <border-button>
             swap [ first >>loc ] [ second >>dim ] bi
-        ] [ execute ] bi*
+        ] [ execute( -- value ) ] bi*
     ] dip set-nth ;
 
 : add-keys-gadgets ( gadget -- gadget )
index 7ac69d298057301e834cba23108c15083180005a..4ba8e2f66b34fca014983b88a587f55a7da30be6 100755 (executable)
@@ -165,7 +165,7 @@ DEFER: (d)
     swap call [ at 0 or ] curry map ; inline
 
 : op-matrix ( domain range quot -- matrix )
-    rot [ [ 2dup ] dip (op-matrix) ] map 2nip ; inline
+    rot [ (op-matrix) ] with with map ; inline
 
 : d-matrix ( domain range -- matrix )
     [ (d) ] op-matrix ;
index 70035f18546769168ee95181ffa24f5c9775ac44..7326bc65b0b4e610b17b1e4ee09f6a8fb79abbb9 100644 (file)
@@ -2,7 +2,7 @@ USING: io lint kernel math tools.test ;
 IN: lint.tests
 
 ! Don't write code like this
-: lint1 ( -- ) [ "hi" print ] [ ] if ; ! when
+: lint1 ( obj -- ) [ "hi" print ] [ ] if ; ! when
 
 [ { { lint1 { [ [ ] if ] } } } ] [ \ lint1 lint-word ] unit-test
 
index 1e3705629fdbf71b253b2872c08010ff1994424a..4f5825e4ddc1bb345c54500bf646c45bef7e36f4 100644 (file)
@@ -1,5 +1,2 @@
 USING: mason.build tools.test sequences ;
 IN: mason.build.tests
-
-{ create-build-dir enter-build-dir clone-builds-factor record-id }
-[ must-infer ] each
index 90ca1d31ff3938c4b23526b8351b1d68d9f8ec8f..199d48dec07bcab00f03e3dac98182d083f81a39 100644 (file)
@@ -1,8 +1,9 @@
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays calendar io.directories io.encodings.utf8
+USING: arrays kernel calendar io.directories io.encodings.utf8
 io.files io.launcher mason.child mason.cleanup mason.common
-mason.help mason.release mason.report namespaces prettyprint ;
+mason.help mason.release mason.report mason.email mason.notify
+namespaces prettyprint ;
 IN: mason.build
 
 QUALIFIED: continuations
@@ -14,20 +15,21 @@ QUALIFIED: continuations
 : enter-build-dir  ( -- ) build-dir set-current-directory ;
 
 : clone-builds-factor ( -- )
-    "git" "clone" builds/factor 3array try-process ;
+    "git" "clone" builds/factor 3array try-output-process ;
 
-: record-id ( -- )
-    "factor" [ git-id ] with-directory "git-id" to-file ;
+: begin-build ( -- )
+    "factor" [ git-id ] with-directory
+    [ "git-id" to-file ] [ notify-begin-build ] bi ;
 
 : build ( -- )
     create-build-dir
     enter-build-dir
     clone-builds-factor
     [
-        record-id
+        begin-build
         build-child
-        upload-help
-        release
+        [ notify-report ]
+        [ status-clean eq? [ upload-help release ] when ] bi
     ] [ cleanup ] [ ] continuations:cleanup ;
 
 MAIN: build
index 27bb42ed074ad465cda3cc4fefb2868ad39e8b4f..2d5a7c663598d58781a6d63250225b164e5f4751 100644 (file)
@@ -1,5 +1,5 @@
 IN: mason.child.tests
-USING: mason.child mason.config tools.test namespaces ;
+USING: mason.child mason.config tools.test namespaces io kernel sequences ;
 
 [ { "make" "winnt-x86-32" } ] [
     [
@@ -40,3 +40,23 @@ USING: mason.child mason.config tools.test namespaces ;
         boot-cmd
     ] with-scope
 ] unit-test
+
+[ [ "Hi" print ] [ drop 3 ] [ 4 ] recover-else ] must-infer
+
+[ 4 ] [ [ "Hi" print ] [ drop 3 ] [ 4 ] recover-else ] unit-test
+
+[ 3 ] [ [ "Hi" throw ] [ drop 3 ] [ 4 ] recover-else ] unit-test
+
+[ "A" ] [
+    {
+        { [ 3 throw ] [ { "X" "Y" "Z" "A" } nth ] }
+        [ "B" ]
+    } recover-cond
+] unit-test
+
+[ "B" ] [
+    {
+        { [ ] [ ] }
+        [ "B" ]
+    } recover-cond
+] unit-test
\ No newline at end of file
index feb11933fbcd884c644d2e621552256e684931d2..8132e620788b7ae365a164487b554d945a636838 100755 (executable)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays calendar combinators.short-circuit
+USING: accessors arrays calendar combinators.short-circuit fry
 continuations debugger io.directories io.files io.launcher
 io.pathnames io.encodings.ascii kernel make mason.common mason.config
-mason.platform mason.report mason.email namespaces sequences ;
+mason.platform mason.report mason.notify namespaces sequences
+quotations macros ;
 IN: mason.child
 
 : make-cmd ( -- args )
@@ -58,29 +59,18 @@ IN: mason.child
         try-process
     ] with-directory ;
 
-: return-with ( obj -- * ) return-continuation get continue-with ;
+: recover-else ( try catch else -- )
+    [ [ '[ @ f t ] ] [ '[ @ f ] ] bi* recover ] dip '[ drop @ ] when ; inline
 
-: build-clean? ( -- ? )
-    {
-        [ load-everything-vocabs-file eval-file empty? ]
-        [ test-all-vocabs-file eval-file empty? ]
-        [ help-lint-vocabs-file eval-file empty? ]
-        [ compiler-errors-file eval-file empty? ]
-    } 0&& ;
-
-: build-child ( -- )
-    [
-        return-continuation set
-
-        copy-image
+MACRO: recover-cond ( alist -- )
+    dup { [ length 1 = ] [ first callable? ] } 1&&
+    [ first ] [ [ first first2 ] [ rest ] bi '[ _ _ [ _ recover-cond ] recover-else ] ] if ;
 
-        [ make-vm ] [ compile-failed-report status-error return-with ] recover
-        [ boot ] [ boot-failed-report status-error return-with ] recover
-        [ test ] [ test-failed-report status-error return-with ] recover
-
-        successful-report
-
-        build-clean? status-clean status-dirty ? return-with
-    ] callcc1
-    status set
-    email-report ;
\ No newline at end of file
+: build-child ( -- status )
+    copy-image
+    {
+        { [ notify-make-vm make-vm ] [ compile-failed ] }
+        { [ notify-boot boot ] [ boot-failed ] }
+        { [ notify-test test ] [ test-failed ] }
+        [ success ]
+    } recover-cond ;
\ No newline at end of file
index a273696f516fcc464903cd1ceab5a62e4d1d5132..3e6209fed0777d0b95cabdd5debd6b531b4a641b 100755 (executable)
@@ -5,13 +5,14 @@ io.directories.hierarchy io.files io.launcher kernel
 mason.common mason.config mason.platform namespaces ;
 IN: mason.cleanup
 
+: compress ( filename -- )
+    dup exists? [ "bzip2" swap 2array try-output-process ] [ drop ] if ;
+
 : compress-image ( -- )
-    "bzip2" boot-image-name 2array try-process ;
+    boot-image-name compress ;
 
 : compress-test-log ( -- )
-    "test-log" exists? [
-        { "bzip2" "test-log" } try-process
-    ] when ;
+    "test-log" compress ;
 
 : cleanup ( -- )
     builder-debug get [
index 047bdaa84435a7a203f640af9f87201f4162e5ca..285a684f0659993167239f349579391483c4b6df 100755 (executable)
@@ -4,15 +4,27 @@ USING: kernel namespaces sequences splitting system accessors
 math.functions make io io.files io.pathnames io.directories
 io.directories.hierarchy io.launcher io.encodings.utf8 prettyprint
 combinators.short-circuit parser combinators calendar
-calendar.format arrays mason.config locals system ;
+calendar.format arrays mason.config locals system debugger ;
 IN: mason.common
 
+ERROR: output-process-error output process ;
+
+M: output-process-error error.
+    [ "Process:" print process>> . nl ]
+    [ "Output:" print output>> print ]
+    bi ;
+
+: try-output-process ( command -- )
+    >process +stdout+ >>stderr utf8 <process-reader*>
+    [ contents ] [ dup wait-for-process ] bi*
+    0 = [ 2drop ] [ output-process-error ] if ;
+
 HOOK: really-delete-tree os ( path -- )
 
 M: windows really-delete-tree
     #! Workaround: Cygwin GIT creates read-only files for
     #! some reason.
-    [ { "chmod" "ug+rw" "-R" } swap (normalize-path) suffix try-process ]
+    [ { "chmod" "ug+rw" "-R" } swap (normalize-path) suffix try-output-process ]
     [ delete-tree ]
     bi ;
 
@@ -23,7 +35,7 @@ M: unix really-delete-tree delete-tree ;
     <process>
         swap >>command
         15 minutes >>timeout
-    try-process ;
+    try-output-process ;
 
 :: upload-safely ( local username host remote -- )
     [let* | temp [ remote ".incomplete" append ]
@@ -68,7 +80,7 @@ SYMBOL: stamp
 : prepare-build-machine ( -- )
     builds-dir get make-directories
     builds-dir get
-    [ { "git" "clone" "git://factorcode.org/git/factor.git" } try-process ]
+    [ { "git" "clone" "git://factorcode.org/git/factor.git" } try-output-process ]
     with-directory ;
 
 : git-id ( -- id )
@@ -87,17 +99,19 @@ CONSTANT: test-all-errors-file "test-all-errors"
 CONSTANT: help-lint-vocabs-file "help-lint-vocabs"
 CONSTANT: help-lint-errors-file "help-lint-errors"
 
+CONSTANT: compiler-errors-file "compiler-errors"
+CONSTANT: compiler-error-messages-file "compiler-error-messages"
+
 CONSTANT: boot-time-file "boot-time"
 CONSTANT: load-time-file "load-time"
-CONSTANT: compiler-errors-file "compiler-errors"
 CONSTANT: test-time-file "test-time"
 CONSTANT: help-lint-time-file "help-lint-time"
 CONSTANT: benchmark-time-file "benchmark-time"
 CONSTANT: html-help-time-file "html-help-time"
 
 CONSTANT: benchmarks-file "benchmarks"
-
-SYMBOL: status
+CONSTANT: benchmark-error-messages-file "benchmark-error-messages"
+CONSTANT: benchmark-error-vocabs-file "benchmark-error-vocabs"
 
 SYMBOL: status-error ! didn't bootstrap, or crashed
 SYMBOL: status-dirty ! bootstrapped but not all tests passed
index 51b09543f483583e7bc061a6f25cd5d18d5809a7..5ec44df0a90a6d9616247f506333bbc7a57a63ea 100644 (file)
@@ -11,12 +11,17 @@ builds-dir get-global [
     home "builds" append-path builds-dir set-global
 ] unless
 
-! Who sends build reports.
+! Who sends build report e-mails.
 SYMBOL: builder-from
 
-! Who receives build reports.
+! Who receives build report e-mails.
 SYMBOL: builder-recipients
 
+! (Optional) twitter credentials for status updates.
+SYMBOL: builder-twitter-username
+
+SYMBOL: builder-twitter-password
+
 ! (Optional) CPU architecture to build for.
 SYMBOL: target-cpu
 
@@ -34,6 +39,12 @@ target-os get-global [
 ! Keep test-log around?
 SYMBOL: builder-debug
 
+! Host to send status notifications to.
+SYMBOL: status-host
+
+! Username to log in.
+SYMBOL: status-username
+
 SYMBOL: upload-help?
 
 ! The below are only needed if upload-help is true.
index 5bde9a9cfead3217003110b0f8d58af7d2ebac47..e2afe01a5661025f8dfde9c27b11ba86b4274a78 100644 (file)
@@ -5,7 +5,6 @@ USING: mason.email mason.common mason.config namespaces tools.test ;
     [
         "linux" target-os set
         "x86.64" target-cpu set
-        status-error status set
-        subject prefix-subject
+        status-error subject prefix-subject
     ] with-scope
 ] unit-test
index f25f7e5cfae4b55f0bb7830f4f228826d51b4687..23203e5222022600ef569ebab5d3f2f3b9f83ad6 100644 (file)
@@ -1,35 +1,35 @@
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces accessors combinators make smtp
-debugger prettyprint io io.streams.string io.encodings.utf8
-io.files io.sockets
+USING: kernel namespaces accessors combinators make smtp debugger
+prettyprint io io.streams.string io.encodings.utf8 io.files io.sockets
 mason.common mason.platform mason.config ;
 IN: mason.email
 
 : prefix-subject ( str -- str' )
     [ "mason on " % platform % ": " % % ] "" make ;
 
-: email-status ( body subject -- )
+: email-status ( body content-type subject -- )
     <email>
         builder-from get >>from
         builder-recipients get >>to
         swap prefix-subject >>subject
+        swap >>content-type
         swap >>body
     send-email ;
 
-: subject ( -- str )
-    status get {
+: subject ( status -- str )
+    {
         { status-clean [ "clean" ] }
         { status-dirty [ "dirty" ] }
         { status-error [ "error" ] }
     } case ;
 
-: email-report ( -- )
-    "report" utf8 file-contents subject email-status ;
+: email-report ( report status -- )
+    [ "text/html" ] dip subject email-status ;
 
 : email-error ( error callstack -- )
     [
         "Fatal error on " write host-name print nl
         [ error. ] [ callstack. ] bi*
-    ] with-string-writer "fatal error"
+    ] with-string-writer "text/plain" "fatal error"
     email-status ;
index 9a4e2be99630001a594b870551f96fd1229112cf..9ed9653a081de64787772b717c4b8b7417bf9e89 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays help.html io.directories io.files io.launcher
 kernel make mason.common mason.config namespaces sequences ;
@@ -6,7 +6,7 @@ IN: mason.help
 
 : make-help-archive ( -- )
     "factor/temp" [
-        { "tar" "cfz" "docs.tar.gz" "docs" } try-process
+        { "tar" "cfz" "docs.tar.gz" "docs" } try-output-process
     ] with-directory ;
 
 : upload-help-archive ( -- )
@@ -16,11 +16,8 @@ IN: mason.help
     help-directory get "/docs.tar.gz" append
     upload-safely ;
 
-: (upload-help) ( -- )
+: upload-help ( -- )
     upload-help? get [
         make-help-archive
         upload-help-archive
-    ] when ;
-
-: upload-help ( -- )
-    status get status-clean eq? [ (upload-help) ] when ;
+    ] when ;
\ No newline at end of file
index 299a2f4e1fe1a885bd24cd656577f2269a4e8455..d425985e7632f8ac2244942b41db41a04ba34b54 100644 (file)
@@ -6,7 +6,8 @@ mason.email mason.updates namespaces threads ;
 IN: mason
 
 : build-loop-error ( error -- )
-    error-continuation get call>> email-error ;
+    [ "Build loop error:" print flush error. flush ]
+    [ error-continuation get call>> email-error ] bi ;
 
 : build-loop-fatal ( error -- )
     "FATAL BUILDER ERROR:" print
diff --git a/extra/mason/notify/authors.txt b/extra/mason/notify/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/mason/notify/notify.factor b/extra/mason/notify/notify.factor
new file mode 100644 (file)
index 0000000..6bf4ae0
--- /dev/null
@@ -0,0 +1,48 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays accessors io io.sockets io.encodings.utf8 io.files
+io.launcher kernel make mason.config mason.common mason.email
+mason.twitter namespaces sequences ;
+IN: mason.notify
+
+: status-notify ( input-file args -- )
+    status-host get [
+        [
+            "ssh" , status-host get , "-l" , status-username get ,
+            "./mason-notify" ,
+            host-name ,
+            target-cpu get ,
+            target-os get ,
+        ] { } make prepend
+        <process>
+            swap >>command
+            swap [ +closed+ ] unless* >>stdin
+        try-output-process
+    ] [ 2drop ] if ;
+
+: notify-begin-build ( git-id -- )
+    [ "Starting build of GIT ID " write print flush ]
+    [ f swap "git-id" swap 2array status-notify ]
+    bi ;
+
+: notify-make-vm ( -- )
+    "Compiling VM" print flush
+    f { "make-vm" } status-notify ;
+
+: notify-boot ( -- )
+    "Bootstrapping" print flush
+    f { "boot" } status-notify ;
+
+: notify-test ( -- )
+    "Running tests" print flush
+    f { "test" } status-notify ;
+
+: notify-report ( status -- )
+    [ "Build finished with status: " write print flush ]
+    [
+        [ "report" utf8 file-contents ] dip email-report
+        "report" { "report" } status-notify
+    ] bi ;
+
+: notify-release ( archive-name -- )
+    "Uploaded " prepend [ print flush ] [ mason-tweet ] bi ;
\ No newline at end of file
index fff8b83c234356a7b6a0fba4a86d14af85ecaf66..79d6993a911a0a73f17b739833ed966fb0ac4f5d 100755 (executable)
@@ -18,23 +18,23 @@ IN: mason.release.archive
 
 : archive-name ( -- string ) base-name extension append ;
 
-: make-windows-archive ( -- )
-    [ "zip" , "-r" , archive-name , "factor" , ] { } make try-process ;
+: make-windows-archive ( archive-name -- )
+    [ "zip" , "-r" , , "factor" , ] { } make try-output-process ;
 
-: make-macosx-archive ( -- )
-    { "mkdir" "dmg-root" } try-process
-    { "cp" "-R" "factor" "dmg-root" } try-process
+: make-macosx-archive ( archive-name -- )
+    { "mkdir" "dmg-root" } try-output-process
+    { "cp" "-R" "factor" "dmg-root" } try-output-process
     { "hdiutil" "create"
         "-srcfolder" "dmg-root"
         "-fs" "HFS+"
     "-volname" "factor" }
-    archive-name suffix try-process
+    swap suffix try-output-process
     "dmg-root" really-delete-tree ;
 
-: make-unix-archive ( -- )
-    [ "tar" , "-cvzf" , archive-name , "factor" , ] { } make try-process ;
+: make-unix-archive ( archive-name -- )
+    [ "tar" , "-cvzf" , , "factor" , ] { } make try-output-process ;
 
-: make-archive ( -- )
+: make-archive ( archive-name -- )
     target-os get {
         { "winnt" [ make-windows-archive ] }
         { "macosx" [ make-macosx-archive ] }
@@ -44,5 +44,5 @@ IN: mason.release.archive
 : releases ( -- path )
     builds-dir get "releases" append-path dup make-directories ;
 
-: save-archive ( -- )
-    archive-name releases move-file-into ;
\ No newline at end of file
+: save-archive ( archive-name -- )
+    releases move-file-into ;
\ No newline at end of file
index bbb47ba0d387001ea16f812a68a833612ed88d29..fc4ad0b08a6977b9475d3f8125eaef504537b570 100644 (file)
@@ -1,16 +1,17 @@
-! Copyright (C) 2008 Eduardo Cavazos.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel debugger namespaces sequences splitting
+USING: kernel debugger namespaces sequences splitting combinators
 combinators io io.files io.launcher prettyprint bootstrap.image
 mason.common mason.release.branch mason.release.tidy
-mason.release.archive mason.release.upload ;
+mason.release.archive mason.release.upload mason.notify ;
 IN: mason.release
 
-: (release) ( -- )
+: release ( -- )
     update-clean-branch
     tidy
-    make-archive
-    upload
-    save-archive ;
-
-: release ( -- ) status get status-clean eq? [ (release) ] when ;
\ No newline at end of file
+    archive-name {
+        [ make-archive ]
+        [ upload ]
+        [ save-archive ]
+        [ notify-release ]
+    } cleave ;
\ No newline at end of file
index 68f2ffcdb5f866bd8be8b17bcfd7f2b4bdbbe531..d3e11c3fc339f03b1a9474c5f6d0a650f3c061c8 100644 (file)
@@ -8,14 +8,13 @@ IN: mason.release.upload
 : remote-location ( -- dest )
     upload-directory get "/" platform 3append ;
 
-: remote-archive-name ( -- dest )
-    remote-location "/" archive-name 3append ;
+: remote-archive-name ( archive-name -- dest )
+    [ remote-location "/" ] dip 3append ;
 
-: upload ( -- )
+: upload ( archive-name -- )
     upload-to-factorcode? get [
-        archive-name
         upload-username get
         upload-host get
-        remote-archive-name
+        pick remote-archive-name
         upload-safely
-    ] when ;
+    ] [ drop ] if ;
index 7f5c4f1d3046035b6e615a5c024d614b30bad94c..a9e8e2802b2f5fbda272cb5a8e04480137d08513 100644 (file)
@@ -1,2 +1,4 @@
 IN: mason.report.tests
 USING: mason.report tools.test ;
+
+{ 0 0 } [ [ ] with-report ] must-infer-as
\ No newline at end of file
index 52e1608885f6e3901de4250523d8fbc2aa4ecddc..0839652d553ffc08ad5648a3e02720ccfda7cb8a 100644 (file)
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces debugger fry io io.files io.sockets
-io.encodings.utf8 prettyprint benchmark mason.common
-mason.platform mason.config sequences ;
+USING: benchmark combinators.smart debugger fry io assocs
+io.encodings.utf8 io.files io.sockets io.streams.string kernel
+locals mason.common mason.config mason.platform math namespaces
+prettyprint sequences xml.syntax xml.writer combinators.short-circuit ;
 IN: mason.report
 
-: time. ( file -- )
-    [ write ": " write ] [ eval-file milli-seconds>time print ] bi ;
-
-: common-report ( -- )
-    "Build machine: " write host-name print
-    "CPU: " write target-cpu get print
-    "OS: " write target-os get print
-    "Build directory: " write build-dir print
-    "git id: " write "git-id" eval-file print nl ;
+: common-report ( -- xml )
+    target-os get
+    target-cpu get
+    host-name
+    build-dir
+    "git-id" eval-file
+    [XML
+    <h1>Build report for <->/<-></h1>
+    <table>
+    <tr><td>Build machine:</td><td><-></td></tr>
+    <tr><td>Build directory:</td><td><-></td></tr>
+    <tr><td>GIT ID:</td><td><-></td></tr>
+    </table>
+    XML] ;
 
 : with-report ( quot -- )
-    [ "report" utf8 ] dip '[ common-report @ ] with-file-writer ; inline
+    [ "report" utf8 ] dip
+    '[
+        common-report
+        _ call( -- xml )
+        [XML <html><body><-><-></body></html> XML]
+        pprint-xml
+    ] with-file-writer ; inline
 
-: compile-failed-report ( error -- )
+:: failed-report ( error file what -- status )
     [
-        "VM compile failed:" print nl
-        "compile-log" cat nl
-        error.
-    ] with-report ;
+        error [ error. ] with-string-writer :> error
+        file utf8 file-contents 400 short tail* :> output
+        
+        [XML
+        <h2><-what-></h2>
+        Build output:
+        <pre><-output-></pre>
+        Launcher error:
+        <pre><-error-></pre>
+        XML]
+    ] with-report
+    status-error ;
 
-: boot-failed-report ( error -- )
-    [
-        "Bootstrap failed:" print nl
-        "boot-log" 100 cat-n nl
-        error.
-    ] with-report ;
+: compile-failed ( error -- status )
+    "compile-log" "VM compilation failed" failed-report ;
+
+: boot-failed ( error -- status )
+    "boot-log" "Bootstrap failed" failed-report ;
+
+: test-failed ( error -- status )
+    "test-log" "Tests failed" failed-report ;
+
+: timings-table ( -- xml )
+    {
+        boot-time-file
+        load-time-file
+        test-time-file
+        help-lint-time-file
+        benchmark-time-file
+        html-help-time-file
+    } [
+        execute( -- string )
+        dup utf8 file-contents milli-seconds>time
+        [XML <tr><td><-></td><td><-></td></tr> XML]
+    ] map [XML <h2>Timings</h2> <table><-></table> XML] ;
+
+: error-dump ( heading vocabs-file messages-file -- xml )
+    [ eval-file ] dip over empty? [ 3drop f ] [
+        [ ]
+        [ [ [XML <li><-></li> XML] ] map [XML <ul><-></ul> XML] ]
+        [ utf8 file-contents ]
+        tri*
+        [XML <h1><-></h1> <-> Details: <pre><-></pre> XML]
+    ] if ;
 
-: test-failed-report ( error -- )
+: benchmarks-table ( assoc -- xml )
     [
-        "Tests failed:" print nl
-        "test-log" 100 cat-n nl
-        error.
-    ] with-report ;
+        1000000 /f
+        [XML <tr><td><-></td><td><-></td></tr> XML]
+    ] { } assoc>map [XML <h2>Benchmarks</h2> <table><-></table> XML] ;
 
 : successful-report ( -- )
     [
-        boot-time-file time.
-        load-time-file time.
-        test-time-file time.
-        help-lint-time-file time.
-        benchmark-time-file time.
-        html-help-time-file time.
-
-        nl
-
-        load-everything-vocabs-file eval-file [
-            "== Did not pass load-everything:" print .
-            load-everything-errors-file cat
-        ] unless-empty
-
-        compiler-errors-file eval-file [
-            "== Vocabularies with compiler errors:" print .
-        ] unless-empty
-
-        test-all-vocabs-file eval-file [
-            "== Did not pass test-all:" print .
-            test-all-errors-file cat
-        ] unless-empty
-
-        help-lint-vocabs-file eval-file [
-            "== Did not pass help-lint:" print .
-            help-lint-errors-file cat
-        ] unless-empty
-
-        "== Benchmarks:" print
-        benchmarks-file eval-file benchmarks.
-    ] with-report ;
\ No newline at end of file
+        [
+            timings-table
+
+            "Load failures"
+            load-everything-vocabs-file
+            load-everything-errors-file
+            error-dump
+
+            "Compiler warnings and errors"
+            compiler-errors-file
+            compiler-error-messages-file
+            error-dump
+
+            "Unit test failures"
+            test-all-vocabs-file
+            test-all-errors-file
+            error-dump
+            
+            "Help lint failures"
+            help-lint-vocabs-file
+            help-lint-errors-file
+            error-dump
+
+            "Benchmark errors"
+            benchmark-error-vocabs-file
+            benchmark-error-messages-file
+            error-dump
+            
+            "Benchmark timings"
+            benchmarks-file eval-file benchmarks-table
+        ] output>array
+    ] with-report ;
+
+: build-clean? ( -- ? )
+    {
+        [ load-everything-vocabs-file eval-file empty? ]
+        [ test-all-vocabs-file eval-file empty? ]
+        [ help-lint-vocabs-file eval-file empty? ]
+        [ compiler-errors-file eval-file empty? ]
+        [ benchmark-error-vocabs-file eval-file empty? ]
+    } 0&& ;
+
+: success ( -- status )
+    successful-report build-clean? status-clean status-dirty ? ;
\ No newline at end of file
index bc00f659fa5ae87625628c001a4e1726ec56635c..912fbaa17a5b0460f087f03d8f888d293eaafc51 100644 (file)
@@ -1,10 +1,10 @@
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs benchmark bootstrap.stage2
-compiler.errors generic help.html help.lint io.directories
+USING: accessors assocs benchmark bootstrap.stage2 compiler.errors
+source-files.errors generic help.html help.lint io.directories
 io.encodings.utf8 io.files kernel mason.common math namespaces
-prettyprint sequences sets sorting tools.test tools.time
-tools.vocabs words system io ;
+prettyprint sequences sets sorting tools.test tools.time tools.vocabs
+words system io tools.errors locals ;
 IN: mason.test
 
 : do-load ( -- )
@@ -19,27 +19,36 @@ M: word word-vocabulary vocabulary>> ;
 
 M: method-body word-vocabulary "method-generic" word-prop word-vocabulary ;
 
+:: do-step ( errors summary-file details-file -- )
+    errors
+    [ error-type +linkage-error+ eq? not ] filter
+    [ file>> ] map prune natural-sort summary-file to-file
+    errors details-file utf8 [ errors. ] with-file-writer ;
+
 : do-compile-errors ( -- )
-    compiler-errors-file utf8 [
-        +error+ errors-of-type keys
-        [ word-vocabulary ] map
-        prune natural-sort .
-    ] with-file-writer ;
+    compiler-errors get values
+    compiler-errors-file
+    compiler-error-messages-file
+    do-step ;
 
 : do-tests ( -- )
-    run-all-tests
-    [ keys test-all-vocabs-file to-file ]
-    [ test-all-errors-file utf8 [ test-failures. ] with-file-writer ]
-    bi ;
+    test-all test-failures get
+    test-all-vocabs-file
+    test-all-errors-file
+    do-step ;
 
 : do-help-lint ( -- )
-    "" run-help-lint
-    [ keys help-lint-vocabs-file to-file ]
-    [ help-lint-errors-file utf8 [ typos. ] with-file-writer ]
-    bi ;
+    help-lint-all lint-failures get values
+    help-lint-vocabs-file
+    help-lint-errors-file
+    do-step ;
 
 : do-benchmarks ( -- )
-    run-benchmarks benchmarks-file to-file ;
+    run-benchmarks
+    [ benchmarks-file to-file ] [
+        [ keys benchmark-error-vocabs-file to-file ]
+        [ benchmark-error-messages-file utf8 [ benchmark-errors. ] with-file-writer ] bi
+    ] bi* ;
 
 : benchmark-ms ( quot -- ms )
     benchmark 1000 /i ; inline
diff --git a/extra/mason/twitter/authors.txt b/extra/mason/twitter/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/mason/twitter/twitter.factor b/extra/mason/twitter/twitter.factor
new file mode 100644 (file)
index 0000000..21f1bca
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: debugger fry kernel mason.config namespaces twitter ;
+IN: mason.twitter
+
+: mason-tweet ( message -- )
+    builder-twitter-username get builder-twitter-password get and
+    [
+        [
+            builder-twitter-username get twitter-username set
+            builder-twitter-password get twitter-password set
+            '[ _ tweet ] try
+        ] with-scope
+    ] [ drop ] if ;
\ No newline at end of file
index e3a009feb5c6dfebefb96d972d156051c68542f2..4bd1bc1b81fcc3c0022386327db20f3ead24dee7 100644 (file)
@@ -18,5 +18,5 @@ IN: math.binpack
     [ dup zip ] dip binpack [ keys ] map ;
 
 : binpack! ( items quot n -- bins ) 
-    [ dupd map zip ] dip binpack [ keys ] map ;
+    [ dupd map zip ] dip binpack [ keys ] map ; inline
 
index 11e57d2639700258f3cbbaae4859977a12430069..78c726d370606c745bd185898b0a34790dcfb11b 100644 (file)
@@ -9,10 +9,10 @@ IN: math.function-tools
     [ bi - ] 2curry ; inline
 
 : eval ( x func -- pt )
-    dupd call 2array ; inline
+    dupd call( x -- y ) 2array ; inline
 
 : eval-inverse ( y func -- pt )
-    dupd call swap 2array ; inline
+    dupd call( y -- x ) swap 2array ; inline
 
 : eval3d ( x y func -- pt )
-    [ 2dup ] dip call 3array ; inline
+    [ 2dup ] dip call( x y -- z ) 3array ; inline
diff --git a/extra/math/matrices/authors.txt b/extra/math/matrices/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/extra/math/matrices/elimination/authors.txt b/extra/math/matrices/elimination/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/extra/math/matrices/elimination/elimination-tests.factor b/extra/math/matrices/elimination/elimination-tests.factor
deleted file mode 100644 (file)
index 7c83339..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-IN: math.matrices.elimination.tests
-USING: kernel math.matrices math.matrices.elimination
-tools.test sequences ;
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 1 0 }
-        { 0 0 0 1 }
-    }
-] [
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 1 0 }
-        { 0 0 0 1 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 1 0 }
-        { 0 0 0 1 }
-    }
-] [
-    {
-        { 1 0 0 0 }
-        { 1 1 0 0 }
-        { 1 0 1 0 }
-        { 1 0 0 1 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 1 0 }
-        { 0 0 0 1 }
-    }
-] [
-    {
-        { 1 0 0 0 }
-        { 1 1 0 0 }
-        { 1 0 1 0 }
-        { 1 1 0 1 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 1 0 }
-        { 0 0 0 1 }
-    }
-] [
-    {
-        { 1 0 0 0 }
-        { 1 1 0 0 }
-        { 1 1 0 1 }
-        { 1 0 1 0 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 0 0 }
-        { 0 0 0 0 }
-    }
-] [
-    {
-        { 0 1 0 0 }
-        { 1 0 0 0 }
-        { 1 0 0 0 }
-        { 1 0 0 0 }
-    } [
-        [ 1 ] [ 0 0 pivot-row ] unit-test
-        1 0 do-row
-    ] with-matrix
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 0 0 }
-        { 0 0 0 0 }
-    }
-] [
-    {
-        { 0 1 0 0 }
-        { 1 0 0 0 }
-        { 1 0 0 0 }
-        { 1 0 0 0 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 0 0 0 1 }
-        { 0 0 0 0 }
-    }
-] [
-    {
-        { 1 0 0 0 }
-        { 0 1 0 0 }
-        { 1 0 0 1 }
-        { 1 0 0 1 }
-    } echelon
-] unit-test
-
-[
-    {
-        { 1 0 0 1 }
-        { 0 1 0 1 }
-        { 0 0 0 -1 }
-        { 0 0 0 0 }
-    }
-] [
-    {
-        { 0 1 0 1 }
-        { 1 0 0 1 }
-        { 1 0 0 0 }
-        { 1 1 0 1 }
-    } echelon
-] unit-test
-
-[
-    2
-] [
-    {
-        { 0 0 }
-        { 0 0 }
-    } nullspace length
-] unit-test
-
-[
-    1 3
-] [
-    {
-        { 0 1 0 1 }
-        { 1 0 0 1 }
-        { 1 0 0 0 }
-        { 1 1 0 1 }
-    } null/rank
-] unit-test
-
-[
-    1 3
-] [
-    {
-        { 0 0 0 0 0 1 0 1 }
-        { 0 0 0 0 1 0 0 1 }
-        { 0 0 0 0 1 0 0 0 }
-        { 0 0 0 0 1 1 0 1 }
-    } null/rank
-] unit-test
-
-[ { { 1 0 -1 } { 0 1 2 } } ]
-[ { { 1 2 3 } { 4 5 6 } } solution ] unit-test
diff --git a/extra/math/matrices/elimination/elimination.factor b/extra/math/matrices/elimination/elimination.factor
deleted file mode 100755 (executable)
index 0368dd5..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-! Copyright (C) 2006, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.vectors math.matrices namespaces
-sequences ;
-IN: math.matrices.elimination
-
-SYMBOL: matrix
-
-: with-matrix ( matrix quot -- )
-    [ swap matrix set call matrix get ] with-scope ; inline
-
-: nth-row ( row# -- seq ) matrix get nth ;
-
-: change-row ( row# quot: ( seq -- seq ) -- )
-    matrix get swap change-nth ; inline
-
-: exchange-rows ( row# row# -- ) matrix get exchange ;
-
-: rows ( -- n ) matrix get length ;
-
-: cols ( -- n ) 0 nth-row length ;
-
-: skip ( i seq quot -- n )
-    over [ find-from drop ] dip length or ; inline
-
-: first-col ( row# -- n )
-    #! First non-zero column
-    0 swap nth-row [ zero? not ] skip ;
-
-: clear-scale ( col# pivot-row i-row -- n )
-    [ over ] dip nth dup zero? [
-        3drop 0
-    ] [
-        [ nth dup zero? ] dip swap [
-            2drop 0
-        ] [
-            swap / neg
-        ] if
-    ] if ;
-
-: (clear-col) ( col# pivot-row i -- )
-    [ [ clear-scale ] 2keep [ n*v ] dip v+ ] change-row ;
-
-: rows-from ( row# -- slice )
-    rows dup <slice> ;
-
-: clear-col ( col# row# rows -- )
-    [ nth-row ] dip [ [ 2dup ] dip (clear-col) ] each 2drop ;
-
-: do-row ( exchange-with row# -- )
-    [ exchange-rows ] keep
-    [ first-col ] keep
-    dup 1+ rows-from clear-col ;
-
-: find-row ( row# quot -- i elt )
-    [ rows-from ] dip find ; inline
-
-: pivot-row ( col# row# -- n )
-    [ dupd nth-row nth zero? not ] find-row 2nip ;
-
-: (echelon) ( col# row# -- )
-    over cols < over rows < and [
-        2dup pivot-row [ over do-row 1+ ] when*
-        [ 1+ ] dip (echelon)
-    ] [
-        2drop
-    ] if ;
-
-: echelon ( matrix -- matrix' )
-    [ 0 0 (echelon) ] with-matrix ;
-
-: nonzero-rows ( matrix -- matrix' )
-    [ [ zero? ] all? not ] filter ;
-
-: null/rank ( matrix -- null rank )
-    echelon dup length swap nonzero-rows length [ - ] keep ;
-
-: leading ( seq -- n elt ) [ zero? not ] find ;
-
-: reduced ( matrix' -- matrix'' )
-    [
-        rows <reversed> [
-            dup nth-row leading drop
-            dup [ swap dup clear-col ] [ 2drop ] if
-        ] each
-    ] with-matrix ;
-
-: basis-vector ( row col# -- )
-    [ clone ] dip
-    [ swap nth neg recip ] 2keep
-    [ 0 spin set-nth ] 2keep
-    [ n*v ] dip
-    matrix get set-nth ;
-
-: nullspace ( matrix -- seq )
-    echelon reduced dup empty? [
-        dup first length identity-matrix [
-            [
-                dup leading drop
-                dup [ basis-vector ] [ 2drop ] if
-            ] each
-        ] with-matrix flip nonzero-rows
-    ] unless ;
-
-: 1-pivots ( matrix -- matrix )
-    [ dup leading nip [ recip v*n ] when* ] map ;
-
-: solution ( matrix -- matrix )
-    echelon nonzero-rows reduced 1-pivots ;
-
-: inverse ( matrix -- matrix ) ! Assumes an invertible matrix
-    dup length
-    [ identity-matrix [ append ] 2map solution ] keep
-    [ tail ] curry map ;
diff --git a/extra/math/matrices/elimination/summary.txt b/extra/math/matrices/elimination/summary.txt
deleted file mode 100644 (file)
index 83972ab..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Solving systems of linear equations
diff --git a/extra/math/matrices/matrices-tests.factor b/extra/math/matrices/matrices-tests.factor
deleted file mode 100644 (file)
index 2094235..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-IN: math.matrices.tests
-USING: math.matrices math.vectors tools.test math ;
-
-[
-    { { 0 } { 0 } { 0 } }
-] [
-    3 1 zero-matrix
-] unit-test
-
-[
-    { { 1 0 0 }
-       { 0 1 0 }
-       { 0 0 1 } }
-] [
-    3 identity-matrix
-] unit-test
-
-[
-    { { 1 0 4 }
-       { 0 7 0 }
-       { 6 0 3 } }
-] [
-    { { 1 0 0 }
-       { 0 2 0 }
-       { 0 0 3 } }
-       
-    { { 0 0 4 }
-       { 0 5 0 }
-       { 6 0 0 } }
-
-    m+
-] unit-test
-
-[
-    { { 1 0 4 }
-       { 0 7 0 }
-       { 6 0 3 } }
-] [
-    { { 1 0 0 }
-       { 0 2 0 }
-       { 0 0 3 } }
-       
-    { { 0 0 -4 }
-       { 0 -5 0 }
-       { -6 0 0 } }
-
-    m-
-] unit-test
-
-[
-    { 10 20 30 }
-] [
-    10 { 1 2 3 } n*v
-] unit-test
-
-[
-    { 3 4 }
-] [
-    { { 1 0 }
-       { 0 1 } }
-
-    { 3 4 }
-
-    m.v
-] unit-test
-
-[
-    { 4 3 }
-] [
-    { { 0 1 }
-       { 1 0 } }
-
-    { 3 4 }
-
-    m.v
-] unit-test
-
-[
-    { { 6 } }
-] [
-    { { 3 } } { { 2 } } m.
-] unit-test
-
-[
-    { { 11 } }
-] [
-    { { 1 3 } } { { 5 } { 2 } } m.
-] unit-test
-
-[
-    { { 28 } }
-] [
-    { { 2 4 6 } }
-
-    { { 1 }
-       { 2 }
-       { 3 } }
-    
-    m.
-] unit-test
-
-[ { 0 0 -1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
-[ { 1 0 0 } ] [ { 0 1 0 } { 0 0 1 } cross ] unit-test
-[ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
-
-[ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
-
-[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
-[ { 1 2 } { "a" "b" } cross-zip ] unit-test
\ No newline at end of file
diff --git a/extra/math/matrices/matrices.factor b/extra/math/matrices/matrices.factor
deleted file mode 100755 (executable)
index 7c687d7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-! Copyright (C) 2005, 2009 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math math.order math.vectors sequences ;
-IN: math.matrices
-
-! Matrices
-: zero-matrix ( m n -- matrix )
-    [ nip 0 <array> ] curry map ;
-
-: identity-matrix ( n -- matrix )
-    #! Make a nxn identity matrix.
-    dup [ [ = 1 0 ? ] with map ] curry map ;
-
-! Matrix operations
-: mneg ( m -- m ) [ vneg ] map ;
-
-: n*m ( n m -- m ) [ n*v ] with map ;
-: m*n ( m n -- m ) [ v*n ] curry map ;
-: n/m ( n m -- m ) [ n/v ] with map ;
-: m/n ( m n -- m ) [ v/n ] curry map ;
-
-: m+   ( m m -- m ) [ v+ ] 2map ;
-: m-   ( m m -- m ) [ v- ] 2map ;
-: m*   ( m m -- m ) [ v* ] 2map ;
-: m/   ( m m -- m ) [ v/ ] 2map ;
-
-: v.m ( v m -- v ) flip [ v. ] with map ;
-: m.v ( m v -- v ) [ v. ] curry map ;
-: m.  ( m m -- m ) flip [ swap m.v ] curry map ;
-
-: mmin ( m -- n ) [ 1/0. ] dip [ [ min ] each ] each ;
-: mmax ( m -- n ) [ -1/0. ] dip [ [ max ] each ] each ;
-: mnorm ( m -- n ) dup mmax abs m/n ;
-
-<PRIVATE
-
-: x ( seq -- elt ) first ; inline
-: y ( seq -- elt ) second ; inline
-: z ( seq -- elt ) third ; inline
-
-: i ( seq1 seq2 -- n ) [ [ y ] [ z ] bi* * ] [ [ z ] [ y ] bi* * ] 2bi - ;
-: j ( seq1 seq2 -- n ) [ [ z ] [ x ] bi* * ] [ [ x ] [ z ] bi* * ] 2bi - ;
-: k ( seq1 seq2 -- n ) [ [ y ] [ x ] bi* * ] [ [ x ] [ y ] bi* * ] 2bi - ;
-
-PRIVATE>
-
-: cross ( vec1 vec2 -- vec3 ) [ i ] [ j ] [ k ] 2tri 3array ;
-
-: proj ( v u -- w )
-    [ [ v. ] [ norm-sq ] bi / ] keep n*v ;
-
-: (gram-schmidt) ( v seq -- newseq )
-    [ dupd proj v- ] each ;
-
-: gram-schmidt ( seq -- orthogonal )
-    V{ } clone [ over (gram-schmidt) over push ] reduce ;
-
-: norm-gram-schmidt ( seq -- orthonormal )
-    gram-schmidt [ normalize ] map ;
-
-: cross-zip ( seq1 seq2 -- seq1xseq2 )
-    [ [ 2array ] with map ] curry map ;
\ No newline at end of file
diff --git a/extra/math/matrices/summary.txt b/extra/math/matrices/summary.txt
deleted file mode 100644 (file)
index 0e9fa9a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Matrix arithmetic
index 6b46ba02430a6e78464ba76bed93907128296957..261f33c4f3aa30540826f7f4aa7ae9929095e1d4 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel sequences namespaces make math math.ranges
-math.vectors vectors ;
+USING: kernel math math.ranges math.vectors namespaces
+sequences ;
 IN: math.numerical-integration
 
 SYMBOL: num-steps
@@ -15,7 +15,7 @@ SYMBOL: num-steps
     length 2 / 2 - { 2 4 } <repetition> concat
     { 1 4 } { 1 } surround ;
 
-: integrate-simpson ( from to f -- x )
+: integrate-simpson ( from to quot -- x )
     [ setup-simpson-range dup ] dip 
     map dup generate-simpson-weights
-    v. swap [ third ] keep first - 6 / * ;
+    v. swap [ third ] keep first - 6 / * ; inline
diff --git a/extra/morse/authors.txt b/extra/morse/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/morse/morse-docs.factor b/extra/morse/morse-docs.factor
new file mode 100644 (file)
index 0000000..e35967d
--- /dev/null
@@ -0,0 +1,33 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax ;
+IN: morse
+
+HELP: ch>morse
+{ $values
+    { "ch" "A character that has a morse code translation" } { "str" "A string consisting of zero or more dots and dashes" } }
+{ $description "If the given character has a morse code translation, then return that translation, otherwise return an empty string." } ;
+
+HELP: morse>ch
+{ $values
+    { "str" "A string of dots and dashes that represents a single character in morse code" } { "ch" "The translated character" } }
+{ $description "If the given string represents a morse code character, then return that character, otherwise return f" } ;
+
+HELP: >morse
+{ $values
+    { "str" "A string of ASCII characters which can be translated into morse code" } { "str" "A string in morse code" } }
+{ $description "Translates ASCII text into morse code, represented by a series of dots, dashes, and slashes." }
+{ $see-also morse> ch>morse } ;
+
+HELP: morse>
+{ $values { "str" "A string of morse code, in which the character '.' represents dots, '-' dashes, ' ' spaces between letters, and ' / ' spaces between words." } { "str" "The ASCII translation of the given string" } }
+{ $description "Translates morse code into ASCII text" }
+{ $see-also >morse morse>ch } ;
+
+HELP: play-as-morse*
+{ $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } }
+{ $description "Plays a string as morse code" } ;
+
+HELP: play-as-morse
+{ $values { "str" "A string of ascii characters which can be translated into morse code" } }
+{ $description "Plays a string as morse code" } ;
diff --git a/extra/morse/morse-tests.factor b/extra/morse/morse-tests.factor
new file mode 100644 (file)
index 0000000..1444489
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays morse strings tools.test ;
+
+[ "" ] [ CHAR: \\ ch>morse ] unit-test
+[ "..." ] [ CHAR: s ch>morse ] unit-test
+[ CHAR: s ] [ "..." morse>ch ] unit-test
+[ f ] [ "..--..--.." morse>ch ] unit-test
+[ "-- --- .-. ... . / -.-. --- -.. ." ] [ "morse code" >morse ] unit-test
+[ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test
+[ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test
+! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
+! [ ] [ "Factor rocks!" play-as-morse ] unit-test
diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor
new file mode 100644 (file)
index 0000000..54abce9
--- /dev/null
@@ -0,0 +1,182 @@
+! Copyright (C) 2007, 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors ascii assocs combinators hashtables kernel lists math
+namespaces make openal parser-combinators promises sequences
+strings synth synth.buffers unicode.case ;
+IN: morse
+
+<PRIVATE
+: morse-codes ( -- array )
+    {
+        { CHAR: a ".-"    }
+        { CHAR: b "-..."  }
+        { CHAR: c "-.-."  }
+        { CHAR: d "-.."   }
+        { CHAR: e "."     }
+        { CHAR: f "..-."  }
+        { CHAR: g "--."   }
+        { CHAR: h "...."  }
+        { CHAR: i ".."    }
+        { CHAR: j ".---"  }
+        { CHAR: k "-.-"   }
+        { CHAR: l ".-.."  }
+        { CHAR: m "--"    }
+        { CHAR: n "-."    }
+        { CHAR: o "---"   }
+        { CHAR: p ".--."  }
+        { CHAR: q "--.-"  }
+        { CHAR: r ".-."   }
+        { CHAR: s "..."   }
+        { CHAR: t "-"     }
+        { CHAR: u "..-"   }
+        { CHAR: v "...-"  }
+        { CHAR: w ".--"   }
+        { CHAR: x "-..-"  }
+        { CHAR: y "-.--"  }
+        { CHAR: z "--.."  }
+        { CHAR: 1 ".----" }
+        { CHAR: 2 "..---" }
+        { CHAR: 3 "...--" }
+        { CHAR: 4 "....-" }
+        { CHAR: 5 "....." }
+        { CHAR: 6 "-...." }
+        { CHAR: 7 "--..." }
+        { CHAR: 8 "---.." }
+        { CHAR: 9 "----." }
+        { CHAR: 0 "-----" }
+        { CHAR: . ".-.-.-" }
+        { CHAR: , "--..--" }
+        { CHAR: ? "..--.." }
+        { CHAR: ' ".----." }
+        { CHAR: ! "-.-.--" }
+        { CHAR: / "-..-."  }
+        { CHAR: ( "-.--."  }
+        { CHAR: ) "-.--.-" }
+        { CHAR: & ".-..."  }
+        { CHAR: : "---..." }
+        { CHAR: ; "-.-.-." }
+        { CHAR: = "-...- " }
+        { CHAR: + ".-.-."  }
+        { CHAR: - "-....-" }
+        { CHAR: _ "..--.-" }
+        { CHAR: " ".-..-." }
+        { CHAR: $ "...-..-" }
+        { CHAR: @ ".--.-." }
+        { CHAR: \s "/" }
+    } ;
+
+: ch>morse-assoc ( -- assoc )
+    morse-codes >hashtable ;
+
+: morse>ch-assoc ( -- assoc )
+    morse-codes [ reverse ] map >hashtable ;
+
+PRIVATE>
+
+: ch>morse ( ch -- str )
+    ch>lower ch>morse-assoc at* swap "" ? ;
+
+: morse>ch ( str -- ch )
+    morse>ch-assoc at* swap f ? ;
+
+: >morse ( str -- str )
+    [
+        [ CHAR: \s , ] [ ch>morse % ] interleave
+    ] "" make ;
+
+<PRIVATE
+
+: dot-char ( -- ch ) CHAR: . ;
+: dash-char ( -- ch ) CHAR: - ;
+: char-gap-char ( -- ch ) CHAR: \s ;
+: word-gap-char ( -- ch ) CHAR: / ;
+
+: =parser ( obj -- parser )
+    [ = ] curry satisfy ;
+
+LAZY: 'dot' ( -- parser )
+    dot-char =parser ;
+
+LAZY: 'dash' ( -- parser )
+    dash-char =parser ;
+
+LAZY: 'char-gap' ( -- parser )
+    char-gap-char =parser ;
+
+LAZY: 'word-gap' ( -- parser )
+    word-gap-char =parser ;
+
+LAZY: 'morse-char' ( -- parser )
+    'dot' 'dash' <|> <+> ;
+
+LAZY: 'morse-word' ( -- parser )
+    'morse-char' 'char-gap' list-of ;
+
+LAZY: 'morse-words' ( -- parser )
+    'morse-word' 'word-gap' list-of ;
+
+PRIVATE>
+
+: morse> ( str -- str )
+    'morse-words' parse car parsed>> [
+        [ 
+            >string morse>ch
+        ] map >string
+    ] map [ [ CHAR: \s , ] [ % ] interleave ] "" make ;
+
+<PRIVATE
+SYMBOLS: source dot-buffer dash-buffer intra-char-gap-buffer letter-gap-buffer ;
+
+: queue ( symbol -- )
+    get source get swap queue-buffer ;
+
+: dot ( -- ) dot-buffer queue ;
+: dash ( -- ) dash-buffer queue ;
+: intra-char-gap ( -- ) intra-char-gap-buffer queue ;
+: letter-gap ( -- ) letter-gap-buffer queue ;
+
+: beep-freq ( -- n ) 880 ;
+
+: <morse-buffer> ( -- buffer )
+    half-sample-freq <8bit-mono-buffer> ;
+
+: sine-buffer ( seconds -- id )
+    beep-freq swap <morse-buffer> >sine-wave-buffer
+    send-buffer id>> ;
+
+: silent-buffer ( seconds -- id )
+    <morse-buffer> >silent-buffer send-buffer id>> ;
+
+: make-buffers ( unit-length -- )
+    {
+        [ sine-buffer dot-buffer set ]
+        [ 3 * sine-buffer dash-buffer set ]
+        [ silent-buffer intra-char-gap-buffer set ]
+        [ 3 * silent-buffer letter-gap-buffer set ]
+    } cleave ;
+
+: playing-morse ( quot unit-length -- )
+    [
+        init-openal 1 gen-sources first source set make-buffers
+        call
+        source get source-play
+    ] with-scope ; inline
+
+: play-char ( ch -- )
+    [ intra-char-gap ] [
+        {
+            { dot-char [ dot ] }
+            { dash-char [ dash ] }
+            { word-gap-char [ intra-char-gap ] }
+        } case
+    ] interleave ;
+
+PRIVATE>
+
+: play-as-morse* ( str unit-length -- )
+    [
+        [ letter-gap ] [ ch>morse play-char ] interleave
+    ] swap playing-morse ; inline
+
+: play-as-morse ( str -- )
+    0.05 play-as-morse* ; inline
diff --git a/extra/morse/summary.txt b/extra/morse/summary.txt
new file mode 100644 (file)
index 0000000..2c1f091
--- /dev/null
@@ -0,0 +1 @@
+Converts between text and morse code, and plays morse code.
diff --git a/extra/morse/tags.txt b/extra/morse/tags.txt
new file mode 100644 (file)
index 0000000..1e107f5
--- /dev/null
@@ -0,0 +1 @@
+examples
diff --git a/extra/openal/authors.txt b/extra/openal/authors.txt
new file mode 100644 (file)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/openal/backend/authors.txt b/extra/openal/backend/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/openal/backend/backend.factor b/extra/openal/backend/backend.factor
new file mode 100644 (file)
index 0000000..41069dc
--- /dev/null
@@ -0,0 +1,4 @@
+USING: namespaces system ;
+IN: openal.backend
+
+HOOK: load-wav-file os ( filename -- format data size frequency )
diff --git a/extra/openal/example/authors.txt b/extra/openal/example/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/openal/example/example.factor b/extra/openal/example/example.factor
new file mode 100644 (file)
index 0000000..4d979a8
--- /dev/null
@@ -0,0 +1,33 @@
+! Copyright (C) 2007 Chris Double.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: calendar kernel openal sequences threads ;\r
+IN: openal.example\r
+\r
+: play-hello ( -- )\r
+    init-openal\r
+    1 gen-sources\r
+    first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param\r
+    source-play\r
+    1000 milliseconds sleep ;\r
+  \r
+: (play-file) ( source -- )\r
+    100 milliseconds sleep\r
+    dup source-playing? [ (play-file) ] [ drop ] if ;\r
+\r
+: play-file ( filename -- )\r
+    init-openal\r
+    create-buffer-from-file \r
+    1 gen-sources\r
+    first dup [ AL_BUFFER rot set-source-param ] dip\r
+    dup source-play\r
+    check-error\r
+    (play-file) ;\r
+\r
+: play-wav ( filename -- )\r
+    init-openal\r
+    create-buffer-from-wav \r
+    1 gen-sources\r
+    first dup [ AL_BUFFER rot set-source-param ] dip\r
+    dup source-play\r
+    check-error\r
+    (play-file) ;\r
diff --git a/extra/openal/macosx/authors.txt b/extra/openal/macosx/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/openal/macosx/macosx.factor b/extra/openal/macosx/macosx.factor
new file mode 100644 (file)
index 0000000..81d360e
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types kernel alien alien.syntax shuffle
+openal.backend namespaces system generalizations ;
+IN: openal.macosx
+
+LIBRARY: alut
+
+FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency ) ;
+
+M: macosx load-wav-file ( path -- format data size frequency )
+    0 <int> f <void*> 0 <int> 0 <int>
+    [ alutLoadWAVFile ] 4 nkeep
+    [ [ [ *int ] dip *void* ] dip *int ] dip *int ;
diff --git a/extra/openal/macosx/tags.txt b/extra/openal/macosx/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/extra/openal/openal.factor b/extra/openal/openal.factor
new file mode 100644 (file)
index 0000000..6e9721b
--- /dev/null
@@ -0,0 +1,297 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors arrays alien system combinators alien.syntax namespaces
+       alien.c-types sequences vocabs.loader shuffle
+       openal.backend specialized-arrays.uint alien.libraries generalizations ;
+IN: openal
+
+<< "alut" {
+        { [ os windows? ]  [ "alut.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libalut.so" ] }
+    } cond "cdecl" add-library >>
+
+<< "openal" {
+        { [ os windows? ]  [ "OpenAL32.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libopenal.so" ] }
+    } cond "cdecl" add-library >>
+
+LIBRARY: openal
+
+TYPEDEF: char ALboolean 
+TYPEDEF: char ALchar
+TYPEDEF: char ALbyte
+TYPEDEF: uchar ALubyte
+TYPEDEF: short ALshort
+TYPEDEF: ushort ALushort
+TYPEDEF: int ALint
+TYPEDEF: uint ALuint
+TYPEDEF: int ALsizei
+TYPEDEF: int ALenum
+TYPEDEF: float ALfloat
+TYPEDEF: double ALdouble
+
+CONSTANT: AL_INVALID -1
+CONSTANT: AL_NONE 0
+CONSTANT: AL_FALSE 0
+CONSTANT: AL_TRUE 1
+CONSTANT: AL_SOURCE_RELATIVE HEX: 202
+CONSTANT: AL_CONE_INNER_ANGLE HEX: 1001
+CONSTANT: AL_CONE_OUTER_ANGLE HEX: 1002
+CONSTANT: AL_PITCH HEX: 1003
+CONSTANT: AL_POSITION HEX: 1004
+CONSTANT: AL_DIRECTION HEX: 1005
+CONSTANT: AL_VELOCITY HEX: 1006
+CONSTANT: AL_LOOPING HEX: 1007
+CONSTANT: AL_BUFFER HEX: 1009
+CONSTANT: AL_GAIN HEX: 100A
+CONSTANT: AL_MIN_GAIN HEX: 100D
+CONSTANT: AL_MAX_GAIN HEX: 100E
+CONSTANT: AL_ORIENTATION HEX: 100F
+CONSTANT: AL_CHANNEL_MASK HEX: 3000
+CONSTANT: AL_SOURCE_STATE HEX: 1010
+CONSTANT: AL_INITIAL HEX: 1011
+CONSTANT: AL_PLAYING HEX: 1012
+CONSTANT: AL_PAUSED HEX: 1013
+CONSTANT: AL_STOPPED HEX: 1014
+CONSTANT: AL_BUFFERS_QUEUED HEX: 1015
+CONSTANT: AL_BUFFERS_PROCESSED HEX: 1016
+CONSTANT: AL_SEC_OFFSET HEX: 1024
+CONSTANT: AL_SAMPLE_OFFSET HEX: 1025
+CONSTANT: AL_BYTE_OFFSET HEX: 1026
+CONSTANT: AL_SOURCE_TYPE HEX: 1027
+CONSTANT: AL_STATIC HEX: 1028
+CONSTANT: AL_STREAMING HEX: 1029
+CONSTANT: AL_UNDETERMINED HEX: 1030
+CONSTANT: AL_FORMAT_MONO8 HEX: 1100
+CONSTANT: AL_FORMAT_MONO16 HEX: 1101
+CONSTANT: AL_FORMAT_STEREO8 HEX: 1102
+CONSTANT: AL_FORMAT_STEREO16 HEX: 1103
+CONSTANT: AL_REFERENCE_DISTANCE HEX: 1020
+CONSTANT: AL_ROLLOFF_FACTOR HEX: 1021
+CONSTANT: AL_CONE_OUTER_GAIN HEX: 1022
+CONSTANT: AL_MAX_DISTANCE HEX: 1023
+CONSTANT: AL_FREQUENCY HEX: 2001
+CONSTANT: AL_BITS HEX: 2002
+CONSTANT: AL_CHANNELS HEX: 2003
+CONSTANT: AL_SIZE HEX: 2004
+CONSTANT: AL_UNUSED HEX: 2010
+CONSTANT: AL_PENDING HEX: 2011
+CONSTANT: AL_PROCESSED HEX: 2012
+CONSTANT: AL_NO_ERROR AL_FALSE
+CONSTANT: AL_INVALID_NAME HEX: A001
+CONSTANT: AL_ILLEGAL_ENUM HEX: A002
+CONSTANT: AL_INVALID_ENUM HEX: A002
+CONSTANT: AL_INVALID_VALUE HEX: A003
+CONSTANT: AL_ILLEGAL_COMMAND HEX: A004
+CONSTANT: AL_INVALID_OPERATION HEX: A004
+CONSTANT: AL_OUT_OF_MEMORY HEX: A005
+CONSTANT: AL_VENDOR HEX: B001
+CONSTANT: AL_VERSION HEX: B002
+CONSTANT: AL_RENDERER HEX: B003
+CONSTANT: AL_EXTENSIONS HEX: B004
+CONSTANT: AL_DOPPLER_FACTOR HEX: C000
+CONSTANT: AL_DOPPLER_VELOCITY HEX: C001
+CONSTANT: AL_SPEED_OF_SOUND HEX: C003
+CONSTANT: AL_DISTANCE_MODEL HEX: D000
+CONSTANT: AL_INVERSE_DISTANCE HEX: D001
+CONSTANT: AL_INVERSE_DISTANCE_CLAMPED HEX: D002
+CONSTANT: AL_LINEAR_DISTANCE HEX: D003
+CONSTANT: AL_LINEAR_DISTANCE_CLAMPED HEX: D004
+CONSTANT: AL_EXPONENT_DISTANCE HEX: D005
+CONSTANT: AL_EXPONENT_DISTANCE_CLAMPED HEX: D006
+
+FUNCTION: void alEnable ( ALenum capability ) ;
+FUNCTION: void alDisable ( ALenum capability ) ; 
+FUNCTION: ALboolean alIsEnabled ( ALenum capability ) ; 
+FUNCTION: ALchar* alGetString ( ALenum param ) ;
+FUNCTION: void alGetBooleanv ( ALenum param, ALboolean* data ) ;
+FUNCTION: void alGetIntegerv ( ALenum param, ALint* data ) ;
+FUNCTION: void alGetFloatv ( ALenum param, ALfloat* data ) ;
+FUNCTION: void alGetDoublev ( ALenum param, ALdouble* data ) ;
+FUNCTION: ALboolean alGetBoolean ( ALenum param ) ;
+FUNCTION: ALint alGetInteger ( ALenum param ) ;
+FUNCTION: ALfloat alGetFloat ( ALenum param ) ;
+FUNCTION: ALdouble alGetDouble ( ALenum param ) ;
+FUNCTION: ALenum alGetError (  ) ;
+FUNCTION: ALboolean alIsExtensionPresent ( ALchar* extname ) ;
+FUNCTION: void* alGetProcAddress ( ALchar* fname ) ;
+FUNCTION: ALenum alGetEnumValue ( ALchar* ename ) ;
+FUNCTION: void alListenerf ( ALenum param, ALfloat value ) ;
+FUNCTION: void alListener3f ( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alListenerfv ( ALenum param, ALfloat* values ) ; 
+FUNCTION: void alListeneri ( ALenum param, ALint value ) ;
+FUNCTION: void alListener3i ( ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alListeneriv ( ALenum param, ALint* values ) ;
+FUNCTION: void alGetListenerf ( ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetListener3f ( ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) ;
+FUNCTION: void alGetListenerfv ( ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetListeneri ( ALenum param, ALint* value ) ;
+FUNCTION: void alGetListener3i ( ALenum param, ALint* value1, ALint* value2, ALint* value3 ) ;
+FUNCTION: void alGetListeneriv ( ALenum param, ALint* values ) ;
+FUNCTION: void alGenSources ( ALsizei n, ALuint* sources ) ; 
+FUNCTION: void alDeleteSources ( ALsizei n, ALuint* sources ) ;
+FUNCTION: ALboolean alIsSource ( ALuint sid ) ; 
+FUNCTION: void alSourcef ( ALuint sid, ALenum param, ALfloat value ) ; 
+FUNCTION: void alSource3f ( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ; 
+FUNCTION: void alSourcei ( ALuint sid, ALenum param, ALint value ) ; 
+FUNCTION: void alSource3i ( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alSourceiv ( ALuint sid, ALenum param, ALint* values ) ;
+FUNCTION: void alGetSourcef ( ALuint sid, ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetSource3f ( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
+FUNCTION: void alGetSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetSourcei ( ALuint sid,  ALenum param, ALint* value ) ;
+FUNCTION: void alGetSource3i ( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
+FUNCTION: void alGetSourceiv ( ALuint sid,  ALenum param, ALint* values ) ;
+FUNCTION: void alSourcePlayv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourceStopv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourceRewindv ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourcePausev ( ALsizei ns, ALuint* sids ) ;
+FUNCTION: void alSourcePlay ( ALuint sid ) ;
+FUNCTION: void alSourceStop ( ALuint sid ) ;
+FUNCTION: void alSourceRewind ( ALuint sid ) ;
+FUNCTION: void alSourcePause ( ALuint sid ) ;
+FUNCTION: void alSourceQueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
+FUNCTION: void alSourceUnqueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
+FUNCTION: void alGenBuffers ( ALsizei n, ALuint* buffers ) ;
+FUNCTION: void alDeleteBuffers ( ALsizei n, ALuint* buffers ) ;
+FUNCTION: ALboolean alIsBuffer ( ALuint bid ) ;
+FUNCTION: void alBufferData ( ALuint bid, ALenum format, void* data, ALsizei size, ALsizei freq ) ;
+FUNCTION: void alBufferf ( ALuint bid, ALenum param, ALfloat value ) ;
+FUNCTION: void alBuffer3f ( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
+FUNCTION: void alBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alBufferi ( ALuint bid, ALenum param, ALint value ) ;
+FUNCTION: void alBuffer3i ( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
+FUNCTION: void alBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
+FUNCTION: void alGetBufferf ( ALuint bid, ALenum param, ALfloat* value ) ;
+FUNCTION: void alGetBuffer3f ( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
+FUNCTION: void alGetBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
+FUNCTION: void alGetBufferi ( ALuint bid, ALenum param, ALint* value ) ;
+FUNCTION: void alGetBuffer3i ( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
+FUNCTION: void alGetBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
+FUNCTION: void alDopplerFactor ( ALfloat value ) ;
+FUNCTION: void alDopplerVelocity ( ALfloat value ) ;
+FUNCTION: void alSpeedOfSound ( ALfloat value ) ;
+FUNCTION: void alDistanceModel ( ALenum distanceModel ) ;
+
+LIBRARY: alut
+
+CONSTANT: ALUT_API_MAJOR_VERSION 1
+CONSTANT: ALUT_API_MINOR_VERSION 1
+CONSTANT: ALUT_ERROR_NO_ERROR 0
+CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
+CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
+CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
+CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
+CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
+CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
+CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
+CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
+CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
+CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
+CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
+CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
+CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
+CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
+CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
+CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
+CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
+CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
+CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
+CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
+CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
+CONSTANT: ALUT_LOADER_BUFFER HEX: 300
+CONSTANT: ALUT_LOADER_MEMORY HEX: 301
+
+FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutExit ( ) ;
+FUNCTION: ALenum alutGetError ( ) ;
+FUNCTION: char* alutGetErrorString ( ALenum error ) ;
+FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
+FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
+FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
+FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
+FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
+FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
+FUNCTION: ALint alutGetMajorVersion ( ) ;
+FUNCTION: ALint alutGetMinorVersion ( ) ;
+FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
+
+FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
+
+SYMBOL: init
+
+: init-openal ( -- )
+    init get-global expired? [
+        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
+        1337 <alien> init set-global
+    ] when ;
+
+: exit-openal ( -- )
+    init get-global expired? [
+        alutExit 0 = [ "Could not close OpenAL" throw ] when
+        f init set-global
+    ] unless ;
+
+: gen-sources ( size -- seq )
+    dup <uint-array> [ alGenSources ] keep ;
+
+: gen-buffers ( size -- seq )
+    dup <uint-array> [ alGenBuffers ] keep ;
+
+: gen-buffer ( -- buffer ) 1 gen-buffers first ;
+
+: create-buffer-from-file ( filename -- buffer )
+    alutCreateBufferFromFile dup AL_NONE = [
+        "create-buffer-from-file failed" throw
+    ] when ;
+
+os macosx? "openal.macosx" "openal.other" ? require
+
+: create-buffer-from-wav ( filename -- buffer )
+    gen-buffer dup rot load-wav-file
+    [ alBufferData ] 4 nkeep alutUnloadWAV ;
+
+: queue-buffers ( source buffers -- )
+    [ length ] [ >uint-array ] bi alSourceQueueBuffers ;
+
+: queue-buffer ( source buffer -- )
+    1array queue-buffers ;
+
+: set-source-param ( source param value -- )
+    alSourcei ;
+
+: get-source-param ( source param -- value )
+    0 <uint> dup [ alGetSourcei ] dip *uint ;
+
+: set-buffer-param ( source param value -- )
+    alBufferi ;
+
+: get-buffer-param ( source param -- value )
+    0 <uint> dup [ alGetBufferi ] dip *uint ;
+
+: source-play ( source -- ) alSourcePlay ;
+
+: source-stop ( source -- ) alSourceStop ;
+
+: check-error ( -- )
+    alGetError dup ALUT_ERROR_NO_ERROR = [
+        drop
+    ] [
+        alGetString throw
+    ] if ;
+
+: source-playing? ( source -- bool )
+    AL_SOURCE_STATE get-source-param AL_PLAYING = ;
diff --git a/extra/openal/other/authors.txt b/extra/openal/other/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/openal/other/other.factor b/extra/openal/other/other.factor
new file mode 100644 (file)
index 0000000..0936c94
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types alien.syntax combinators generalizations
+kernel openal.backend ;
+IN: openal.other
+
+LIBRARY: alut
+
+FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency, ALboolean* looping ) ;
+
+M: object load-wav-file ( filename -- format data size frequency )
+    0 <int> f <void*> 0 <int> 0 <int>
+    [ 0 <char> alutLoadWAVFile ] 4 nkeep
+    { [ *int ] [ *void* ] [ *int ] [ *int ] } spread ;
diff --git a/extra/openal/summary.txt b/extra/openal/summary.txt
new file mode 100644 (file)
index 0000000..5df8b3a
--- /dev/null
@@ -0,0 +1 @@
+OpenAL 3D audio library binding
diff --git a/extra/openal/tags.txt b/extra/openal/tags.txt
new file mode 100644 (file)
index 0000000..a5b2257
--- /dev/null
@@ -0,0 +1,2 @@
+bindings
+audio
index 99e8099f38e38bc92b47d2e9d4ec72e0f438fdb1..030d0a2a7350846091072034c68868d0bee76f4d 100755 (executable)
@@ -76,7 +76,7 @@ M: satisfy-parser parse ( input parser -- list )
     over empty? [
         2drop nil
     ] [
-        quot>> [ unclip-slice dup ] dip call
+        quot>> [ unclip-slice dup ] dip call( char -- ? )
         [ swap <parse-results> ] [ 2drop nil ] if
     ] if ;
 
index 7e876b0934949f17042d848536f7a0cb4a5bc5cd..d6fdefd1aa2b0fd474d4319ee8590c7cdb9530c5 100644 (file)
@@ -7,7 +7,7 @@ SYMBOL: sum
 : range ( r from to -- n )
     over - 1 + rot [ 
         -rot [ over + pick call drop ] each 2drop f  
-    ] bshift 2nip ;
+    ] bshift 2nip ; inline
 
 [ 55 ] [
     0 sum set 
index 7ec294ca2e9137d5364b774c41481725374c878f..829679570eecefeb8c95258db03ddc21955bdfbf 100755 (executable)
@@ -4,7 +4,7 @@ IN: partial-continuations
 USING: kernel continuations arrays sequences quotations ;
 
 : breset ( quot -- )
-    [ 1array swap keep first continue-with ] callcc1 nip ;
+    [ 1array swap keep first continue-with ] callcc1 nip ; inline
 
 : (bshift) ( v r k -- obj )
     [ dup first -rot ] dip
index 90d2e0e34c80d6782552400b2a36d6ba548a26cc..e7acf1f5bbe1b87feddbc4f839434ac92f7f5f6b 100644 (file)
@@ -43,7 +43,7 @@ M: lex-hash at*
 
 : parse* ( parser -- ast )
     compile
-    [ execute [ error-stack get first throw ] unless* ] with-global-lexer
+    [ execute( -- result ) [ error-stack get first throw ] unless* ] with-global-lexer
     ast>> ;
 
 : create-bnf ( name parser -- )
index 9d98ac67668817bbf2cdc514fdcabaaa2dfd602f..beed787fba1504fb86708b992623b3e386fa72bb 100644 (file)
@@ -95,7 +95,7 @@ PRIVATE>
 : euler011 ( -- answer )
     [
         { [ horizontal ] [ vertical ] [ diagonal/ ] [ diagonal\ ] }
-        [ call 4 max-product , ] each
+        [ call( -- matrix ) 4 max-product , ] each
     ] { } make supremum ;
 
 ! [ euler011 ] 100 ave-time
index a4aded7096c28bac286382f637e15a3f9065b5a2..9c7c4fee74d18667c27079fe4a954994480a99d0 100644 (file)
@@ -66,7 +66,7 @@ IN: project-euler.018
            91  71  52  38  17  14  91  43  58  50  27  29  48
          63  66  04  68  89  53  67  30  73  16  69  87  40  31
        04  62  98  27  23  09  70  98  73  93  38  53  60  04  23
-     } 15 [ 1+ cut swap ] map nip ;
+     } 15 iota [ 1+ cut swap ] map nip ;
 
 PRIVATE>
 
index 5ff5234679c318fbaf47874f9e9e3e5424c05c3c..64c9ec445e373a6b4c40b71d19c05bcef77a4cad 100755 (executable)
@@ -27,7 +27,9 @@ IN: project-euler.032
 <PRIVATE
 
 : source-032 ( -- seq )
-    9 factorial [ 9 permutation [ 1+ ] map 10 digits>integer ] map ;
+    9 factorial iota [
+        9 permutation [ 1+ ] map 10 digits>integer
+    ] map ;
 
 : 1and4 ( n -- ? )
     number>string 1 cut-slice 4 cut-slice
index e013e165751fc7128e4ee3b71b2833052bbef935..314698534fe8dfc0e8b2845d3cf644a5b6ddf0bd 100644 (file)
@@ -50,13 +50,13 @@ IN: project-euler.150
     615949 * 797807 + 20 2^ rem dup 19 2^ - ; inline
 
 : sums-triangle ( -- seq )
-    0 1000 [ 1+ [ next ] replicate partial-sums ] map nip ;
+    0 1000 iota [ 1+ [ next ] replicate partial-sums ] map nip ;
 
 :: (euler150) ( m -- n )
     [let | table [ sums-triangle ] |
         m [| x |
             x 1+ [| y |
-                m x - [| z |
+                m x - iota [| z |
                     x z + table nth-unsafe
                     [ y z + 1+ swap nth-unsafe ]
                     [ y        swap nth-unsafe ] bi -
index d6c98ea203ab4b23e451bd6a43f6dc295b8f2c65..5f1c75ba8a0ee9607a960bd7ebd3937222950bf2 100644 (file)
@@ -41,7 +41,7 @@ METHOD: expand { glob-expr }
     [ ]
   if ;
 
-METHOD: expand { factor-expr } expr>> eval unparse ;
+METHOD: expand { factor-expr } expr>> eval>string ;
 
 DEFER: expansion
 
@@ -64,7 +64,7 @@ METHOD: expand { object } ;
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : run-sword ( basic-expr -- )
-  command>> expansion unclip "shell" lookup execute ;
+  command>> expansion unclip "shell" lookup execute( arguments -- ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
diff --git a/extra/synth/authors.txt b/extra/synth/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/synth/buffers/authors.txt b/extra/synth/buffers/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/synth/buffers/buffers.factor b/extra/synth/buffers/buffers.factor
new file mode 100644 (file)
index 0000000..671ebea
--- /dev/null
@@ -0,0 +1,76 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types combinators kernel locals math math.ranges openal sequences sequences.merged specialized-arrays.uchar specialized-arrays.short ;
+IN: synth.buffers
+
+TUPLE: buffer sample-freq 8bit? id ;
+
+: <buffer> ( sample-freq 8bit? -- buffer )
+    f buffer boa ;
+
+TUPLE: mono-buffer < buffer data ;
+
+: <mono-buffer> ( sample-freq 8bit? -- buffer )
+    f f mono-buffer boa ;
+
+: <8bit-mono-buffer> ( sample-freq -- buffer ) t <mono-buffer> ;
+: <16bit-mono-buffer> ( sample-freq -- buffer ) f <mono-buffer> ;
+
+TUPLE: stereo-buffer < buffer left-data right-data ;
+
+: <stereo-buffer> ( sample-freq 8bit? -- buffer )
+    f f f stereo-buffer boa ;
+
+: <8bit-stereo-buffer> ( sample-freq -- buffer ) t <stereo-buffer> ;
+: <16bit-stereo-buffer> ( sample-freq -- buffer ) f <stereo-buffer> ;
+
+PREDICATE: 8bit-buffer < buffer 8bit?>> ;
+PREDICATE: 16bit-buffer < buffer 8bit?>> not ;
+INTERSECTION: 8bit-mono-buffer 8bit-buffer mono-buffer ;
+INTERSECTION: 16bit-mono-buffer 16bit-buffer mono-buffer ;
+INTERSECTION: 8bit-stereo-buffer 8bit-buffer stereo-buffer ;
+INTERSECTION: 16bit-stereo-buffer 16bit-buffer stereo-buffer ;
+
+GENERIC: buffer-format ( buffer -- format )
+M: 8bit-mono-buffer buffer-format drop AL_FORMAT_MONO8 ;
+M: 16bit-mono-buffer buffer-format drop AL_FORMAT_MONO16 ;
+M: 8bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO8 ;
+M: 16bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO16 ;
+
+: 8bit-buffer-data ( seq -- data size )
+    [ 128 * >integer 128 + ] uchar-array{ } map-as [ underlying>> ] [ length ] bi ;
+
+: 16bit-buffer-data ( seq -- data size )
+    [ 32768 * >integer ] short-array{ } map-as [ underlying>> ] [ byte-length ] bi ;
+
+: stereo-data ( stereo-buffer -- left right )
+    [ left-data>> ] [ right-data>> ] bi@ ;
+
+: interleaved-stereo-data ( stereo-buffer -- data )
+    stereo-data <2merged> ;
+
+GENERIC: buffer-data ( buffer -- data size )
+M: 8bit-mono-buffer buffer-data data>> 8bit-buffer-data ;
+M: 16bit-mono-buffer buffer-data data>> 16bit-buffer-data ;
+M: 8bit-stereo-buffer buffer-data
+    interleaved-stereo-data 8bit-buffer-data ;
+M: 16bit-stereo-buffer buffer-data
+    interleaved-stereo-data 16bit-buffer-data ;
+
+: telephone-sample-freq ( -- n ) 8000 ;
+: half-sample-freq ( -- n ) 22050 ;
+: cd-sample-freq ( -- n ) 44100 ;
+: digital-sample-freq ( -- n ) 48000 ;
+: professional-sample-freq ( -- n ) 88200 ;
+
+: send-buffer ( buffer -- buffer )
+    {
+        [ gen-buffer dup [ >>id ] dip ]
+        [ buffer-format ]
+        [ buffer-data ]
+        [ sample-freq>> alBufferData ]
+    } cleave ;
+
+: ?send-buffer ( buffer -- buffer )
+    dup id>> [ send-buffer ] unless ;
+
diff --git a/extra/synth/example/authors.txt b/extra/synth/example/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/synth/example/example.factor b/extra/synth/example/example.factor
new file mode 100644 (file)
index 0000000..747cfb9
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays kernel namespaces make openal sequences
+synth synth.buffers ;
+IN: synth.example
+
+: play-sine-wave ( freq seconds sample-freq -- )
+    init-openal
+    <16bit-mono-buffer> >sine-wave-buffer send-buffer id>>
+    1 gen-sources first
+    [ AL_BUFFER rot set-source-param ] [ source-play ] bi
+    check-error ;
+
+: test-instrument1 ( -- harmonics )
+    [
+        1 0.5 <harmonic> ,
+        2 0.125 <harmonic> ,
+        3 0.0625 <harmonic> ,
+        4 0.03125 <harmonic> ,
+    ] { } make ;
+
+: test-instrument2 ( -- harmonics )
+    [
+        1 0.25 <harmonic> ,
+        2 0.25 <harmonic> ,
+        3 0.25 <harmonic> ,
+        4 0.25 <harmonic> ,
+    ] { } make ;
+
+: sine-instrument ( -- harmonics )
+    1 1 <harmonic> 1array ;
+
+: test-note-buffer ( note -- )
+    init-openal
+    test-instrument2 swap cd-sample-freq <16bit-mono-buffer>
+    >note send-buffer id>>
+    1 gen-sources first [ swap queue-buffer ] [ source-play ] bi
+    check-error ;
diff --git a/extra/synth/summary.txt b/extra/synth/summary.txt
new file mode 100644 (file)
index 0000000..ece5893
--- /dev/null
@@ -0,0 +1 @@
+Simple sound synthesis using OpenAL.
diff --git a/extra/synth/synth.factor b/extra/synth/synth.factor
new file mode 100644 (file)
index 0000000..be1e594
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel locals math math.constants math.functions memoize openal synth.buffers sequences sequences.modified sequences.repeating ;
+IN: synth
+
+MEMO: single-sine-wave ( samples/wave -- seq )
+    pi 2 * over / [ * sin ] curry map ;
+
+: (sine-wave) ( samples/wave n-samples -- seq )
+    [ single-sine-wave ] dip <repeating> ;
+
+: sine-wave ( sample-freq freq seconds -- seq )
+    pick * >integer [ /i ] dip (sine-wave) ;
+
+: >sine-wave-buffer ( freq seconds buffer -- buffer )
+    [ sample-freq>> -rot sine-wave ] keep swap >>data ;
+
+: >silent-buffer ( seconds buffer -- buffer )
+    tuck sample-freq>> * >integer 0 <repetition> >>data ;
+
+TUPLE: harmonic n amplitude ;
+C: <harmonic> harmonic
+
+TUPLE: note hz secs ;
+C: <note> note
+
+: harmonic-freq ( note harmonic -- freq )
+    n>> swap hz>> * ;
+
+:: note-harmonic-data ( harmonic note buffer -- data )
+    buffer sample-freq>> note harmonic harmonic-freq note secs>> sine-wave
+    harmonic amplitude>> <scaled> ;
+
+: >note ( harmonics note buffer -- buffer )
+    dup -roll [ note-harmonic-data ] 2curry map <summed> >>data ;
+
index 37c022fe43382c9b26b3f89d2e4ab3294afe6cab..297157c08bd88248d8d2bd71c8b1a6549ef90b8b 100755 (executable)
@@ -1,8 +1,10 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
 USING: combinators io io.files io.files.links io.directories
 io.pathnames io.streams.string kernel math math.parser
 continuations namespaces pack prettyprint sequences strings
 system tools.hexdump io.encodings.binary summary accessors
-io.backend byte-arrays ;
+io.backend byte-arrays io.streams.byte-array splitting ;
 IN: tar
 
 CONSTANT: zero-checksum 256
@@ -10,37 +12,35 @@ CONSTANT: block-size 512
 
 TUPLE: tar-header name mode uid gid size mtime checksum typeflag
 linkname magic version uname gname devmajor devminor prefix ;
-ERROR: checksum-error ;
 
-SYMBOLS: base-dir filename ;
+ERROR: checksum-error ;
 
-: tar-trim ( seq -- newseq ) [ "\0 " member? ] trim ;
+: trim-string ( seq -- newseq ) [ "\0 " member? ] trim ;
 
-: read-c-string* ( n -- str/f )
+: read-c-string ( n -- str/f )
     read [ zero? ] trim-tail [ f ] when-empty ;
 
 : read-tar-header ( -- obj )
     \ tar-header new
-    100 read-c-string* >>name
-    8 read-c-string* tar-trim oct> >>mode
-    8 read-c-string* tar-trim oct> >>uid
-    8 read-c-string* tar-trim oct> >>gid
-    12 read-c-string* tar-trim oct> >>size
-    12 read-c-string* tar-trim oct> >>mtime
-    8 read-c-string* tar-trim oct> >>checksum
-    read1 >>typeflag
-    100 read-c-string* >>linkname
-    6 read >>magic
-    2 read >>version
-    32 read-c-string* >>uname
-    32 read-c-string* >>gname
-    8 read tar-trim oct> >>devmajor
-    8 read tar-trim oct> >>devminor
-    155 read-c-string* >>prefix ;
-
-: header-checksum ( seq -- x )
-    148 cut-slice 8 tail-slice
-    [ sum ] bi@ + 256 + ;
+        100 read-c-string >>name
+        8 read-c-string trim-string oct> >>mode
+        8 read-c-string trim-string oct> >>uid
+        8 read-c-string trim-string oct> >>gid
+        12 read-c-string trim-string oct> >>size
+        12 read-c-string trim-string oct> >>mtime
+        8 read-c-string trim-string oct> >>checksum
+        read1 >>typeflag
+        100 read-c-string >>linkname
+        6 read >>magic
+        2 read >>version
+        32 read-c-string >>uname
+        32 read-c-string >>gname
+        8 read trim-string oct> >>devmajor
+        8 read trim-string oct> >>devminor
+        155 read-c-string >>prefix ;
+
+: checksum-header ( seq -- n )
+    148 cut-slice 8 tail-slice [ sum ] bi@ + 256 + ;
 
 : read-data-blocks ( tar-header -- )
     dup size>> 0 > [
@@ -60,29 +60,34 @@ SYMBOLS: base-dir filename ;
     ] if ;
 
 : parse-tar-header ( seq -- obj )
-    [ header-checksum ] keep over zero-checksum = [
+    [ checksum-header ] keep over zero-checksum = [
         2drop
         \ tar-header new
             0 >>size
             0 >>checksum
     ] [
-        [ read-tar-header ] with-string-reader
+        binary [ read-tar-header ] with-byte-reader
         [ checksum>> = [ checksum-error ] unless ] keep
     ] if ;
 
 ERROR: unknown-typeflag ch ;
-M: unknown-typeflag summary ( obj -- str )
-    ch>> 1string "Unknown typeflag: " prepend ;
 
-: tar-prepend-path ( path -- newpath )
-    base-dir get prepend-path ;
+M: unknown-typeflag summary ( obj -- str )
+    ch>> [ "Unknown typeflag: " ] dip prefix ;
 
 : read/write-blocks ( tar-header path -- )
     binary [ read-data-blocks ] with-file-writer ;
 
+: prepend-current-directory ( path -- path' )
+    current-directory get prepend-path ;
+
 ! Normal file
 : typeflag-0 ( header -- )
-    dup name>> tar-prepend-path read/write-blocks ;
+    dup name>> dup "global_pax_header" = [
+        drop [ read-data-blocks ] with-string-writer drop
+    ] [
+        prepend-current-directory read/write-blocks
+    ] if ;
 
 ! Hard link
 : typeflag-1 ( header -- ) unknown-typeflag ;
@@ -99,7 +104,7 @@ M: unknown-typeflag summary ( obj -- str )
 
 ! Directory
 : typeflag-5 ( header -- )
-    name>> tar-prepend-path make-directories ;
+    name>> prepend-current-directory make-directories ;
 
 ! FIFO
 : typeflag-6 ( header -- ) unknown-typeflag ;
@@ -139,7 +144,7 @@ M: unknown-typeflag summary ( obj -- str )
     drop ;
     ! <string-writer> [ read-data-blocks ] keep
     ! >string [ zero? ] trim-tail filename set
-    ! filename get tar-prepend-path make-directories ;
+    ! filename get prepend-current-directory make-directories ;
 
 ! Multi volume continuation entry
 : typeflag-M ( header -- ) unknown-typeflag ;
@@ -157,7 +162,7 @@ M: unknown-typeflag summary ( obj -- str )
 : typeflag-X ( header -- ) unknown-typeflag ;
 
 : (parse-tar) ( -- )
-    block-size read dup length 512 = [
+    block-size read dup length block-size = [
         parse-tar-header
         dup typeflag>>
         {
@@ -189,7 +194,7 @@ M: unknown-typeflag summary ( obj -- str )
         drop
     ] if ;
 
-: parse-tar ( path -- )
-    normalize-path dup parent-directory base-dir [
+: untar ( path -- )
+    normalize-path [ ] [ parent-directory ] bi [
          binary [ (parse-tar) ] with-file-reader
-    ] with-variable ;
+    ] with-directory ;
index aa98793c70ef6a2642e2288df9c6ae5b2877a409..5ff5bb38791e46072eb91a8969bc9aa3428899c3 100644 (file)
@@ -90,7 +90,7 @@ M: list focusable-child* drop t ;
 
 : invoke-value-action ( list -- )
     dup list-empty? [
-        dup hook>> call
+        dup hook>> call( list -- )
     ] [
         [ index>> ] keep nth-gadget invoke-secondary
     ] if ;
index beeddc7abb7ac8a0604eaf727b60721c8a80a679..77cd916139f9778fb13025559b01efdc128ac6a3 100644 (file)
@@ -20,8 +20,8 @@ DEFER: to-strings
   dup class
     {
       { \ string    [ ] }
-      { \ quotation [ call ] }
-      { \ word      [ execute ] }
+      { \ quotation [ call( -- string ) ] }
+      { \ word      [ execute( -- string ) ] }
       { \ fixnum    [ number>string ] }
       { \ array     [ to-strings concat ] }
     }
index d62096fffcef9d5d59a523f3ba1b37623247a22f..2fa9b5fb1d5e501f3d46837b5a1d4f20c0f31ae7 100644 (file)
@@ -25,8 +25,8 @@ M: counter-app init-session* drop 0 count sset ;
 
 : <counter-app> ( -- responder )
     counter-app new-dispatcher
-        [ 1+ ] <counter-action> "inc" add-responder
-        [ 1- ] <counter-action> "dec" add-responder
+        [ 1 + ] <counter-action> "inc" add-responder
+        [ 1 - ] <counter-action> "dec" add-responder
         <display-action> "" add-responder ;
 
 ! Deployment example
index b60f1b1b6a59abf7cff73eecd95f3cf7a96c7cc7..f82eb6dcd88594f3a1dcac50baa6e5494f58753d 100644 (file)
@@ -79,8 +79,7 @@ site-watcher-db <alloy>
 main-responder set-global
 
 M: site-watcher-app init-user-profile
-    drop B
-    "username" value "email" value <account> insert-tuple ;
+    drop "username" value "email" value <account> insert-tuple ;
 
 : init-db ( -- )
     site-watcher-db [
index d0116a7f2dc3060e5c60b9e8e5d117d6cb950b5d..a838c6763aecd4588f209da7ac13348a576d1095 100644 (file)
@@ -12,7 +12,7 @@ CONSTANT: site-list-url URL" $site-watcher-app/spider-list"
         { site-watcher-app "spider-list" } >>template
         [
             ! Silly query
-            username spidering-sites [ site>> ] map
+            username spidering-sites [ site>> ] map
             "sites" set-value
         ] >>init
     <protected>
index 34cd19c34fc99344f8b86536dfd7a51f4cf2d703..11a1e325c3f857961c350fadae02c20c6e98c0b3 100644 (file)
@@ -58,7 +58,7 @@ SYMBOL: *calling*
   swap [ * - ] keep 2array ;
   
 : change-global ( variable quot -- )
-  global swap change-at ;
+  global swap change-at ; inline
 
 : (correct-for-timing-overhead) ( timingshash -- timingshash )
   time-dummy-word [ subtract-overhead ] curry assoc-map ;  
@@ -75,7 +75,7 @@ SYMBOL: *calling*
       correct-for-timing-overhead
       "total time:" write
   ] dip pprint nl
-  print-word-timings nl ;
+  print-word-timings nl ; inline
 
 : profile-vocab ( vocab quot -- )
   "annotating vocab..." print flush
@@ -88,4 +88,4 @@ SYMBOL: *calling*
       correct-for-timing-overhead
       "total time:" write
   ] dip pprint
-  print-word-timings ;
+  print-word-timings ; inline
diff --git a/unmaintained/advice/advice-docs.factor b/unmaintained/advice/advice-docs.factor
new file mode 100644 (file)
index 0000000..0a5d5f8
--- /dev/null
@@ -0,0 +1,27 @@
+IN: advice
+USING: help.markup help.syntax tools.annotations words coroutines ;
+
+HELP: make-advised
+{ $values { "word" "a word to annotate in preparation of advising" } }
+{ $description "Prepares a word for being advised.  This is done by: "
+    { $list
+        { "Annotating it to call the appropriate words before, around, and after the original body " }
+        { "Adding " { $snippet "before" } ", " { $snippet "around" } ", and " { $snippet "after" } " properties, which will contain the advice" }
+        { "Adding an " { $snippet "advised" } "property, which can later be used to determine if a given word is defined (see " { $link advised? } ")" }
+    }
+}
+{ $see-also advised? annotate } ;
+
+HELP: advised?
+{ $values { "word" "a word" } { "?" "t or f, indicating if " { $snippet "word" } " is advised" } }
+{ $description "Determines whether or not the given word has any advice on it." } ;
+
+HELP: ad-do-it
+{ $values { "input" "an object" } { "result" "an object" } }
+{ $description "Calls either the next applicable around advice or the main body, returning back to the point it was called from when finished.  This word should only be called from inside advice." }
+{ $see-also coyield } ;
+
+ARTICLE: "advice" "Advice"
+"Advice is a simple way of adding additition functionality to words by adding 'hooks' to a word, which can act before, after, or around the calling of the word." ;
+
+ABOUT: "advice"
\ No newline at end of file
diff --git a/unmaintained/advice/advice-tests.factor b/unmaintained/advice/advice-tests.factor
new file mode 100644 (file)
index 0000000..396687e
--- /dev/null
@@ -0,0 +1,94 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences io io.streams.string math tools.test advice math.parser
+parser namespaces multiline eval words assocs ;
+IN: advice.tests
+
+[
+    [ ad-do-it ] must-fail
+    
+    : foo ( -- str ) "foo" ; 
+    \ foo make-advised
+    { "bar" "foo" } [
+        [ "bar" ] "barify" \ foo advise-before
+        foo
+    ] unit-test
+    { "bar" "foo" "baz" } [
+        [ "baz" ] "bazify" \ foo advise-after
+        foo
+    ] unit-test
+    { "foo" "baz" } [
+        "barify" \ foo before remove-advice
+        foo
+    ] unit-test
+    : bar ( a -- b ) 1 + ;
+    \ bar make-advised
+
+    { 11 } [
+        [ 2 * ] "double" \ bar advise-before
+        5 bar
+    ] unit-test 
+
+    { 11/3 } [
+        [ 3 / ] "third" \ bar advise-after
+        5 bar
+    ] unit-test
+
+    { -2 } [
+        [ -1 * ad-do-it 3 + ] "frobnobicate" \ bar advise-around
+        5 bar
+    ] unit-test
+
+    : add ( a b -- c ) + ;
+    \ add make-advised
+
+    { 10 } [
+        [ [ 2 * ] bi@ ] "double-args" \ add advise-before
+        2 3 add
+    ] unit-test 
+
+    { 21 } [
+        [ 3 * ad-do-it 1- ] "around1" \ add advise-around
+        2 3 add
+    ] unit-test 
+
+!     { 9 } [
+!         [ [ 1- ] bi@ ad-do-it 2 / ] "around2" \ add advise-around
+!         2 3 add
+!     ] unit-test
+
+!     { { "around1" "around2" } } [
+!         \ add around word-prop keys
+!     ] unit-test
+
+    { 5 f } [
+        \ add unadvise
+        2 3 add \ add advised?
+    ] unit-test
+
+!     : quux ( a b -- c ) * ;
+
+!     { f t 3+3/4 } [
+!         <" USING: advice kernel math ;
+!            IN: advice.tests
+!            \ quux advised?
+!            ADVISE: quux halve before [ 2 / ] bi@ ;
+!            \ quux advised? 
+!            3 5 quux"> eval
+!     ] unit-test
+
+!     { 3+3/4 "1+1/2 2+1/2 3+3/4" } [
+!         <" USING: advice kernel math math.parser io io.streams.string ;
+!            IN: advice.tests
+!            ADVISE: quux log around
+!            2dup [ number>string write " " write ] bi@
+!            ad-do-it 
+!            dup number>string write ;
+!            [ 3 5 quux ] with-string-writer"> eval
+!     ] unit-test 
+] with-scope
diff --git a/unmaintained/advice/advice.factor b/unmaintained/advice/advice.factor
new file mode 100644 (file)
index 0000000..4428045
--- /dev/null
@@ -0,0 +1,69 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences fry words assocs linked-assocs tools.annotations
+coroutines lexer parser quotations arrays namespaces continuations
+summary ;
+IN: advice
+
+SYMBOLS: before after around advised in-advice? ;
+
+: advised? ( word -- ? )
+    advised word-prop ;
+
+DEFER: make-advised
+
+<PRIVATE
+: init-around-co ( quot -- coroutine )
+    \ coreset suffix cocreate ;
+PRIVATE>
+
+: advise ( quot name word loc --  )
+    dup around eq? [ [ init-around-co ] 3dip ] when
+    over advised? [ over make-advised ] unless
+    word-prop set-at ;
+    
+: advise-before ( quot name word --  ) before advise ;
+    
+: advise-after ( quot name word --  ) after advise ;
+
+: advise-around ( quot name word --  ) around advise ;
+
+: get-advice ( word type -- seq )
+    word-prop values ;
+
+: call-before ( word --  )
+    before get-advice [ call ] each ;
+
+: call-after ( word --  )
+    after get-advice [ call ] each ;
+
+: call-around ( main word --  )
+    t in-advice? [
+        around get-advice tuck 
+        [ [ coresume ] each ] [ call ] [ <reversed> [ coresume ] each ] tri*
+    ] with-variable ;
+
+: remove-advice ( name word loc --  )
+    word-prop delete-at ;
+
+ERROR: ad-do-it-error ;
+
+M: ad-do-it-error summary
+    drop "ad-do-it should only be called inside 'around' advice" ;
+
+: ad-do-it ( input -- result )
+    in-advice? get [ ad-do-it-error ] unless coyield ;
+    
+: make-advised ( word -- )
+    [ dup '[ [ _ ] dip over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ]
+    [ { before after around } [ <linked-hash> swap set-word-prop ] with each ] 
+    [ t advised set-word-prop ] tri ;
+
+: unadvise ( word --  )
+    [ reset ] [ { before after around advised } [ f swap set-word-prop ] with each ] bi ;
+
+SYNTAX: ADVISE: ! word adname location => word adname quot loc
+    scan-word scan scan-word parse-definition swap [ spin ] dip advise ;
+    
+SYNTAX: UNADVISE:    
+    scan-word parsed \ unadvise parsed ;
diff --git a/unmaintained/advice/authors.txt b/unmaintained/advice/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/unmaintained/advice/summary.txt b/unmaintained/advice/summary.txt
new file mode 100644 (file)
index 0000000..a6f9c06
--- /dev/null
@@ -0,0 +1 @@
+Implmentation of advice/aspects
diff --git a/unmaintained/advice/tags.txt b/unmaintained/advice/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/unmaintained/graph-theory/authors.txt b/unmaintained/graph-theory/authors.txt
new file mode 100644 (file)
index 0000000..9366723
--- /dev/null
@@ -0,0 +1 @@
+William Schlieper
diff --git a/unmaintained/graph-theory/graph-theory-docs.factor b/unmaintained/graph-theory/graph-theory-docs.factor
new file mode 100644 (file)
index 0000000..39c1163
--- /dev/null
@@ -0,0 +1,135 @@
+! See http://factorcode.org/license.txt for BSD licence.
+USING: help.markup help.syntax ;
+
+IN: graph-theory
+
+ARTICLE: "graph-protocol" "Graph protocol"
+"All graphs must be instances of the graph mixin:"
+{ $subsection graph }
+"All graphs must implement a method on the following generic word:"
+{ $subsection vertices }
+"At least one of the following two generic words must have a method; the " { $link graph } " mixin has default definitions which are mutually recursive:"
+{ $subsection adjlist }
+{ $subsection adj? }
+"All mutable graphs must implement a method on the following generic word:"
+{ $subsection add-blank-vertex }
+"All mutable undirected graphs must implement a method on the following generic word:"
+{ $subsection add-edge }
+"Mutable directed graphs should not implement the above word, as it has a default definition defined in terms of the following generic word:"
+{ $subsection add-edge* }
+"The following two words have default definitions, but are available as generics to allow implementations to optimize them:"
+{ $subsection num-vertices }
+{ $subsection num-edges } ;
+
+HELP: graph
+{ $class-description "A mixin class whose instances are graphs.  Custom implementations of the graph protocol should be declared as instances of this mixin for all graph functionality to work correctly:"
+    { $code "INSTANCE: hex-board graph" }
+} ;
+
+{ vertices num-vertices num-edges } related-words
+
+HELP: vertices
+{ $values { "graph" graph } { "seq" "The vertices" } }
+{ $description "Returns the vertices of the graph." } ;
+
+HELP: num-vertices
+{ $values { "graph" graph } { "n" "The number of vertices" } }
+{ $description "Returns the number of vertices in the graph." } ;
+
+HELP: num-edges
+{ $values { "graph" "A graph" } { "n" "The number of edges" } }
+{ $description "Returns the number of edges in the graph." } ;
+
+{ adjlist adj? } related-words
+
+HELP: adjlist
+{ $values
+    { "from" "The index of a vertex" }
+    { "graph" "The graph to be examined" }
+    { "seq" "The adjacency list" } }
+{ $description "Returns a sequence of vertices that this vertex links to" } ;
+
+HELP: adj?
+{ $values
+    { "from" "The index of a vertex" }
+    { "to" "The index of a vertex" }
+    { "graph" "A graph" }
+    { "?" "A boolean" } }
+{ $description "Returns a boolean describing whether there is an edge in the graph between from and to." } ;
+
+{ add-blank-vertex add-blank-vertices add-edge add-edge* } related-words
+
+HELP: add-blank-vertex
+{ $values
+    { "index" "A vertex index" }
+    { "graph" "A graph" } }
+{ $description "Adds a vertex to the graph." } ;
+
+HELP: add-blank-vertices
+{ $values
+    { "seq" "A sequence of vertex indices" }
+    { "graph" "A graph" } }
+{ $description "Adds vertices with indices in seq to the graph." } ;
+
+HELP: add-edge*
+{ $values
+    { "from" "The index of a vertex" }
+    { "to" "The index of another vertex" }
+    { "graph" "A graph" } }
+{ $description "Adds a one-way edge to the graph, between " { $snippet "from" } " and " { $snippet "to" } "."
+  $nl 
+  "If you want to add a two-way edge, use " { $link add-edge } " instead." } ;
+
+HELP: add-edge
+{ $values
+    { "u" "The index of a vertex" }
+    { "v" "The index of another vertex" }
+    { "graph" "A graph" } }
+{ $description "Adds a two-way edge to the graph, between " { $snippet "u" } " and " { $snippet "v" } "."
+  $nl
+  "If you want to add a one-way edge, use " { $link add-edge* } " instead." } ;
+
+{ depth-first full-depth-first dag? topological-sort } related-words
+
+HELP: depth-first
+{ $values
+    { "v" "The vertex to start the search at" }
+    { "graph" "The graph to search" }
+    { "pre" "A quotation of the form ( n -- )" }
+    { "post" "A quotation of the form ( n -- )" }
+    { "?list" "A list of booleans describing the vertices visited in the search" }
+    { "?" "A boolean describing whether or not the end-search error was thrown" } }
+{ $description "Performs a depth-first search on " { $emphasis "graph" } ".  The variable " { $emphasis "graph" } " can be accessed in both quotations."
+  $nl
+  "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first."
+  $nl
+  "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first."
+  $nl
+  { $emphasis "?list" } " is a list of booleans, " { $link t } " for every vertex visted during the search, and " { $link f } " for every vertex not visited." } ;
+
+HELP: full-depth-first
+{ $values
+    { "graph" "The graph to search" }
+    { "pre" "A quotation of the form ( n -- )" }
+    { "post" "A quotation of the form ( n -- )" }
+    { "tail" "A quotation of the form ( -- )" }
+    { "?" "A boolean describing whether or not the end-search error was thrown" } }
+{ $description "Performs a depth-first search on " { $emphasis "graph" } ".  The variable " { $emphasis "graph" } "can be accessed in both quotations."
+  $nl
+  "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first."
+  $nl
+  "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first."
+  $nl
+  "The " { $emphasis "tail" } " quotation is run after each time the depth-first search runs out of nodes.  On an undirected graph this will be each connected subgroup but on a directed graph it can be more complex." } ;
+
+HELP: dag?
+{ $values
+    { "graph" graph }
+    { "?" "A boolean indicating if the graph is acyclic" } }
+{ $description "Using a depth-first search, determines if the specified directed graph is a directed acyclic graph.  An undirected graph will produce a false result, as the algorithm does not eliminate cycles of length 2, which will include any edge that goes both ways." } ;
+
+HELP: topological-sort
+{ $values
+    { "graph" graph }
+    { "seq/f" "Either a sequence of values or f" } }
+{ $description "Using a depth-first search, topologically sorts the specified directed graph.  Returns f if the graph contains any cycles, and a topologically sorted sequence otherwise." } ;
diff --git a/unmaintained/graph-theory/graph-theory.factor b/unmaintained/graph-theory/graph-theory.factor
new file mode 100644 (file)
index 0000000..1b4224c
--- /dev/null
@@ -0,0 +1,91 @@
+! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel combinators fry continuations sequences arrays
+vectors assocs hashtables heaps namespaces ;
+IN: graph-theory
+
+MIXIN: graph
+SYMBOL: visited?
+ERROR: end-search ;
+
+GENERIC: vertices ( graph -- seq ) flushable
+
+GENERIC: num-vertices ( graph -- n ) flushable
+
+GENERIC: num-edges ( graph -- n ) flushable
+
+GENERIC: adjlist ( from graph -- seq ) flushable
+
+GENERIC: adj? ( from to graph -- ? ) flushable
+
+GENERIC: add-blank-vertex ( index graph -- )
+
+GENERIC: delete-blank-vertex ( index graph -- )
+
+GENERIC: add-edge* ( from to graph -- )
+
+GENERIC: add-edge ( u v graph -- )
+
+GENERIC: delete-edge* ( from to graph -- )
+
+GENERIC: delete-edge ( u v graph -- )
+
+M: graph num-vertices
+    vertices length ;
+
+M: graph num-edges
+   [ vertices ] [ '[ _ adjlist length ] sigma ] bi ;
+
+M: graph adjlist
+    [ vertices ] [ swapd '[ _ swap _ adj? ] filter ] bi ;
+
+M: graph adj?
+    swapd adjlist index >boolean ;
+
+M: graph add-edge
+    [ add-edge* ] [ swapd add-edge* ] 3bi ;
+
+M: graph delete-edge
+    [ delete-edge* ] [ swapd delete-edge* ] 3bi ;
+
+: add-blank-vertices ( seq graph -- )
+    '[ _ add-blank-vertex ] each ;
+
+: delete-vertex ( index graph -- )
+    [ adjlist ]
+    [ '[ _ _ 3dup adj? [ delete-edge* ] [ 3drop ] if ] each ]
+    [ delete-blank-vertex ] 2tri ;
+
+<PRIVATE
+
+: search-wrap ( quot graph -- ? )
+    [ [ graph set ] [ vertices [ f 2array ] map >hashtable visited? set ] bi
+      [ t ] compose [ dup end-search? [ drop f ] [ rethrow ] if ] recover ] with-scope ; inline
+
+: (depth-first) ( v pre post -- )
+    { [ 2drop visited? get t -rot set-at ] 
+      [ drop call ]
+      [ [ graph get adjlist ] 2dip
+        '[ dup visited? get at [ drop ] [ _ _ (depth-first) ] if ] each ]
+      [ nip call ] } 3cleave ; inline
+
+PRIVATE>
+
+: depth-first ( v graph pre post -- ?list ? )
+    '[ _ _ (depth-first) visited? get ] swap search-wrap ; inline
+
+: full-depth-first ( graph pre post tail -- ? )
+    '[ [ visited? get [ nip not ] assoc-find ] 
+       [ drop _ _ (depth-first) @ ] 
+       while 2drop ] swap search-wrap ; inline
+
+: dag? ( graph -- ? )
+    V{ } clone swap [ 2dup swap push dupd
+                     '[ _ swap graph get adj? not ] all? 
+                      [ end-search ] unless ]
+                    [ drop dup pop* ] [ ] full-depth-first nip ;
+
+: topological-sort ( graph -- seq/f )
+    dup dag?
+    [ V{ } clone swap [ drop ] [ prefix ] [ ] full-depth-first drop ]
+    [ drop f ] if ;
diff --git a/unmaintained/graph-theory/reversals/reversals.factor b/unmaintained/graph-theory/reversals/reversals.factor
new file mode 100644 (file)
index 0000000..1ea1a3f
--- /dev/null
@@ -0,0 +1,22 @@
+! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: accessors kernel graph-theory ;
+
+IN: graph-theory.reversals
+
+TUPLE: reversal graph ;
+
+GENERIC: reverse-graph ( graph -- reversal )
+
+M: graph reverse-graph reversal boa ;
+
+M: reversal reverse-graph graph>> ;
+
+INSTANCE: reversal graph
+
+M: reversal vertices
+    graph>> vertices ;
+
+M: reversal adj?
+    swapd graph>> adj? ;
diff --git a/unmaintained/graph-theory/sparse/sparse.factor b/unmaintained/graph-theory/sparse/sparse.factor
new file mode 100644 (file)
index 0000000..5c6365b
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: accessors kernel sequences arrays vectors sets assocs hashtables graph-theory namespaces fry ;
+
+IN: graph-theory.sparse
+
+TUPLE: sparse-graph alist ; 
+
+: <sparse-graph> ( -- sparse-graph )
+    H{ } clone sparse-graph boa ;
+
+: >sparse-graph ( graph -- sparse-graph )
+    [ vertices ] keep
+    '[ dup _ adjlist 2array ] map >hashtable sparse-graph boa ;
+
+INSTANCE: sparse-graph graph
+
+M: sparse-graph vertices
+    alist>> keys ;
+
+M: sparse-graph adjlist
+    alist>> at ;
+
+M: sparse-graph add-blank-vertex 
+    alist>> V{ } clone -rot set-at ;
+
+M: sparse-graph delete-blank-vertex
+    alist>> delete-at ;
+
+M: sparse-graph add-edge*
+    alist>> swapd at adjoin ;
+
+M: sparse-graph delete-edge*
+    alist>> swapd at delete ;
diff --git a/unmaintained/graph-theory/summary.txt b/unmaintained/graph-theory/summary.txt
new file mode 100644 (file)
index 0000000..3e1d791
--- /dev/null
@@ -0,0 +1 @@
+Graph-theoretic algorithms
diff --git a/unmaintained/graph-theory/tags.txt b/unmaintained/graph-theory/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/unmaintained/morse/authors.txt b/unmaintained/morse/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/unmaintained/morse/morse-docs.factor b/unmaintained/morse/morse-docs.factor
deleted file mode 100644 (file)
index e35967d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax ;
-IN: morse
-
-HELP: ch>morse
-{ $values
-    { "ch" "A character that has a morse code translation" } { "str" "A string consisting of zero or more dots and dashes" } }
-{ $description "If the given character has a morse code translation, then return that translation, otherwise return an empty string." } ;
-
-HELP: morse>ch
-{ $values
-    { "str" "A string of dots and dashes that represents a single character in morse code" } { "ch" "The translated character" } }
-{ $description "If the given string represents a morse code character, then return that character, otherwise return f" } ;
-
-HELP: >morse
-{ $values
-    { "str" "A string of ASCII characters which can be translated into morse code" } { "str" "A string in morse code" } }
-{ $description "Translates ASCII text into morse code, represented by a series of dots, dashes, and slashes." }
-{ $see-also morse> ch>morse } ;
-
-HELP: morse>
-{ $values { "str" "A string of morse code, in which the character '.' represents dots, '-' dashes, ' ' spaces between letters, and ' / ' spaces between words." } { "str" "The ASCII translation of the given string" } }
-{ $description "Translates morse code into ASCII text" }
-{ $see-also >morse morse>ch } ;
-
-HELP: play-as-morse*
-{ $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } }
-{ $description "Plays a string as morse code" } ;
-
-HELP: play-as-morse
-{ $values { "str" "A string of ascii characters which can be translated into morse code" } }
-{ $description "Plays a string as morse code" } ;
diff --git a/unmaintained/morse/morse-tests.factor b/unmaintained/morse/morse-tests.factor
deleted file mode 100644 (file)
index 1444489..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays morse strings tools.test ;
-
-[ "" ] [ CHAR: \\ ch>morse ] unit-test
-[ "..." ] [ CHAR: s ch>morse ] unit-test
-[ CHAR: s ] [ "..." morse>ch ] unit-test
-[ f ] [ "..--..--.." morse>ch ] unit-test
-[ "-- --- .-. ... . / -.-. --- -.. ." ] [ "morse code" >morse ] unit-test
-[ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test
-[ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test
-! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
-! [ ] [ "Factor rocks!" play-as-morse ] unit-test
diff --git a/unmaintained/morse/morse.factor b/unmaintained/morse/morse.factor
deleted file mode 100644 (file)
index 2951c96..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-! Copyright (C) 2007, 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs combinators hashtables kernel lists math
-namespaces make openal parser-combinators promises sequences
-strings symbols synth synth.buffers unicode.case ;
-IN: morse
-
-<PRIVATE
-: morse-codes ( -- array )
-    {
-        { CHAR: a ".-"    }
-        { CHAR: b "-..."  }
-        { CHAR: c "-.-."  }
-        { CHAR: d "-.."   }
-        { CHAR: e "."     }
-        { CHAR: f "..-."  }
-        { CHAR: g "--."   }
-        { CHAR: h "...."  }
-        { CHAR: i ".."    }
-        { CHAR: j ".---"  }
-        { CHAR: k "-.-"   }
-        { CHAR: l ".-.."  }
-        { CHAR: m "--"    }
-        { CHAR: n "-."    }
-        { CHAR: o "---"   }
-        { CHAR: p ".--."  }
-        { CHAR: q "--.-"  }
-        { CHAR: r ".-."   }
-        { CHAR: s "..."   }
-        { CHAR: t "-"     }
-        { CHAR: u "..-"   }
-        { CHAR: v "...-"  }
-        { CHAR: w ".--"   }
-        { CHAR: x "-..-"  }
-        { CHAR: y "-.--"  }
-        { CHAR: z "--.."  }
-        { CHAR: 1 ".----" }
-        { CHAR: 2 "..---" }
-        { CHAR: 3 "...--" }
-        { CHAR: 4 "....-" }
-        { CHAR: 5 "....." }
-        { CHAR: 6 "-...." }
-        { CHAR: 7 "--..." }
-        { CHAR: 8 "---.." }
-        { CHAR: 9 "----." }
-        { CHAR: 0 "-----" }
-        { CHAR: . ".-.-.-" }
-        { CHAR: , "--..--" }
-        { CHAR: ? "..--.." }
-        { CHAR: ' ".----." }
-        { CHAR: ! "-.-.--" }
-        { CHAR: / "-..-."  }
-        { CHAR: ( "-.--."  }
-        { CHAR: ) "-.--.-" }
-        { CHAR: & ".-..."  }
-        { CHAR: : "---..." }
-        { CHAR: ; "-.-.-." }
-        { CHAR: = "-...- " }
-        { CHAR: + ".-.-."  }
-        { CHAR: - "-....-" }
-        { CHAR: _ "..--.-" }
-        { CHAR: " ".-..-." }
-        { CHAR: $ "...-..-" }
-        { CHAR: @ ".--.-." }
-        { CHAR: \s "/" }
-    } ;
-
-: ch>morse-assoc ( -- assoc )
-    morse-codes >hashtable ;
-
-: morse>ch-assoc ( -- assoc )
-    morse-codes [ reverse ] map >hashtable ;
-
-PRIVATE>
-
-: ch>morse ( ch -- str )
-    ch>lower ch>morse-assoc at* swap "" ? ;
-
-: morse>ch ( str -- ch )
-    morse>ch-assoc at* swap f ? ;
-
-: >morse ( str -- str )
-    [
-        [ CHAR: \s , ] [ ch>morse % ] interleave
-    ] "" make ;
-
-<PRIVATE
-
-: dot-char ( -- ch ) CHAR: . ;
-: dash-char ( -- ch ) CHAR: - ;
-: char-gap-char ( -- ch ) CHAR: \s ;
-: word-gap-char ( -- ch ) CHAR: / ;
-
-: =parser ( obj -- parser )
-    [ = ] curry satisfy ;
-
-LAZY: 'dot' ( -- parser )
-    dot-char =parser ;
-
-LAZY: 'dash' ( -- parser )
-    dash-char =parser ;
-
-LAZY: 'char-gap' ( -- parser )
-    char-gap-char =parser ;
-
-LAZY: 'word-gap' ( -- parser )
-    word-gap-char =parser ;
-
-LAZY: 'morse-char' ( -- parser )
-    'dot' 'dash' <|> <+> ;
-
-LAZY: 'morse-word' ( -- parser )
-    'morse-char' 'char-gap' list-of ;
-
-LAZY: 'morse-words' ( -- parser )
-    'morse-word' 'word-gap' list-of ;
-
-PRIVATE>
-
-: morse> ( str -- str )
-    'morse-words' parse car parsed>> [
-        [ 
-            >string morse>ch
-        ] map >string
-    ] map [ [ CHAR: \s , ] [ % ] interleave ] "" make ;
-
-<PRIVATE
-SYMBOLS: source dot-buffer dash-buffer intra-char-gap-buffer letter-gap-buffer ;
-
-: queue ( symbol -- )
-    get source get swap queue-buffer ;
-
-: dot ( -- ) dot-buffer queue ;
-: dash ( -- ) dash-buffer queue ;
-: intra-char-gap ( -- ) intra-char-gap-buffer queue ;
-: letter-gap ( -- ) letter-gap-buffer queue ;
-
-: beep-freq 880 ;
-
-: <morse-buffer> ( -- buffer )
-    half-sample-freq <8bit-mono-buffer> ;
-
-: sine-buffer ( seconds -- id )
-    beep-freq swap <morse-buffer> >sine-wave-buffer
-    send-buffer id>> ;
-
-: silent-buffer ( seconds -- id )
-    <morse-buffer> >silent-buffer send-buffer id>> ;
-
-: make-buffers ( unit-length -- )
-    {
-        [ sine-buffer dot-buffer set ]
-        [ 3 * sine-buffer dash-buffer set ]
-        [ silent-buffer intra-char-gap-buffer set ]
-        [ 3 * silent-buffer letter-gap-buffer set ]
-    } cleave ;
-
-: playing-morse ( quot unit-length -- )
-    [
-        init-openal 1 gen-sources first source set make-buffers
-        call
-        source get source-play
-    ] with-scope ;
-
-: play-char ( ch -- )
-    [ intra-char-gap ] [
-        {
-            { dot-char [ dot ] }
-            { dash-char [ dash ] }
-            { word-gap-char [ intra-char-gap ] }
-        } case
-    ] interleave ;
-
-PRIVATE>
-
-: play-as-morse* ( str unit-length -- )
-    [
-        [ letter-gap ] [ ch>morse play-char ] interleave
-    ] swap playing-morse ;
-
-: play-as-morse ( str -- )
-    0.05 play-as-morse* ;
diff --git a/unmaintained/morse/summary.txt b/unmaintained/morse/summary.txt
deleted file mode 100644 (file)
index 2c1f091..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Converts between text and morse code, and plays morse code.
diff --git a/unmaintained/morse/tags.txt b/unmaintained/morse/tags.txt
deleted file mode 100644 (file)
index 1e107f5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-examples
diff --git a/unmaintained/openal/authors.txt b/unmaintained/openal/authors.txt
deleted file mode 100644 (file)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/unmaintained/openal/backend/authors.txt b/unmaintained/openal/backend/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/unmaintained/openal/backend/backend.factor b/unmaintained/openal/backend/backend.factor
deleted file mode 100644 (file)
index 41069dc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-USING: namespaces system ;
-IN: openal.backend
-
-HOOK: load-wav-file os ( filename -- format data size frequency )
diff --git a/unmaintained/openal/example/authors.txt b/unmaintained/openal/example/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/unmaintained/openal/example/example.factor b/unmaintained/openal/example/example.factor
deleted file mode 100644 (file)
index ae0b50a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-! Copyright (C) 2007 Chris Double.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-!\r
-IN: openal.example\r
-USING: openal kernel alien threads sequences calendar ;\r
-\r
-: play-hello ( -- )\r
-  init-openal\r
-  1 gen-sources\r
-  first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param\r
-  source-play\r
-  1000 milliseconds sleep ;\r
-  \r
-: (play-file) ( source -- )\r
-  100 milliseconds sleep\r
-  dup source-playing? [ (play-file) ] [ drop ] if ;\r
-\r
-: play-file ( filename -- )\r
-  init-openal\r
-  create-buffer-from-file \r
-  1 gen-sources\r
-  first dup >r AL_BUFFER rot set-source-param r>\r
-  dup source-play\r
-  check-error\r
-  (play-file) ;\r
-\r
-: play-wav ( filename -- )\r
-  init-openal\r
-  create-buffer-from-wav \r
-  1 gen-sources\r
-  first dup >r AL_BUFFER rot set-source-param r>\r
-  dup source-play\r
-  check-error\r
-  (play-file) ;
\ No newline at end of file
diff --git a/unmaintained/openal/macosx/authors.txt b/unmaintained/openal/macosx/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/unmaintained/openal/macosx/macosx.factor b/unmaintained/openal/macosx/macosx.factor
deleted file mode 100644 (file)
index abc0d65..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types kernel alien alien.syntax shuffle
-combinators.lib openal.backend namespaces system ;
-IN: openal.macosx
-
-LIBRARY: alut
-
-FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency ) ;
-
-M: macosx load-wav-file ( path -- format data size frequency )
-    0 <int> f <void*> 0 <int> 0 <int>
-    [ alutLoadWAVFile ] 4keep
-    [ [ [ *int ] dip *void* ] dip *int ] dip *int ;
diff --git a/unmaintained/openal/macosx/tags.txt b/unmaintained/openal/macosx/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/unmaintained/openal/openal.factor b/unmaintained/openal/openal.factor
deleted file mode 100644 (file)
index 8533308..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel arrays alien system combinators alien.syntax namespaces
-       alien.c-types sequences vocabs.loader shuffle
-       openal.backend specialized-arrays.uint ;
-IN: openal
-
-<< "alut" {
-        { [ os windows? ]  [ "alut.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libalut.so" ] }
-    } cond "cdecl" add-library >>
-
-<< "openal" {
-        { [ os windows? ]  [ "OpenAL32.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libopenal.so" ] }
-    } cond "cdecl" add-library >>
-
-LIBRARY: openal
-
-TYPEDEF: char ALboolean 
-TYPEDEF: char ALchar
-TYPEDEF: char ALbyte
-TYPEDEF: uchar ALubyte
-TYPEDEF: short ALshort
-TYPEDEF: ushort ALushort
-TYPEDEF: int ALint
-TYPEDEF: uint ALuint
-TYPEDEF: int ALsizei
-TYPEDEF: int ALenum
-TYPEDEF: float ALfloat
-TYPEDEF: double ALdouble
-
-CONSTANT: AL_INVALID -1
-CONSTANT: AL_NONE 0
-CONSTANT: AL_FALSE 0
-CONSTANT: AL_TRUE 1
-CONSTANT: AL_SOURCE_RELATIVE HEX: 202
-CONSTANT: AL_CONE_INNER_ANGLE HEX: 1001
-CONSTANT: AL_CONE_OUTER_ANGLE HEX: 1002
-CONSTANT: AL_PITCH HEX: 1003
-CONSTANT: AL_POSITION HEX: 1004
-CONSTANT: AL_DIRECTION HEX: 1005
-CONSTANT: AL_VELOCITY HEX: 1006
-CONSTANT: AL_LOOPING HEX: 1007
-CONSTANT: AL_BUFFER HEX: 1009
-CONSTANT: AL_GAIN HEX: 100A
-CONSTANT: AL_MIN_GAIN HEX: 100D
-CONSTANT: AL_MAX_GAIN HEX: 100E
-CONSTANT: AL_ORIENTATION HEX: 100F
-CONSTANT: AL_CHANNEL_MASK HEX: 3000
-CONSTANT: AL_SOURCE_STATE HEX: 1010
-CONSTANT: AL_INITIAL HEX: 1011
-CONSTANT: AL_PLAYING HEX: 1012
-CONSTANT: AL_PAUSED HEX: 1013
-CONSTANT: AL_STOPPED HEX: 1014
-CONSTANT: AL_BUFFERS_QUEUED HEX: 1015
-CONSTANT: AL_BUFFERS_PROCESSED HEX: 1016
-CONSTANT: AL_SEC_OFFSET HEX: 1024
-CONSTANT: AL_SAMPLE_OFFSET HEX: 1025
-CONSTANT: AL_BYTE_OFFSET HEX: 1026
-CONSTANT: AL_SOURCE_TYPE HEX: 1027
-CONSTANT: AL_STATIC HEX: 1028
-CONSTANT: AL_STREAMING HEX: 1029
-CONSTANT: AL_UNDETERMINED HEX: 1030
-CONSTANT: AL_FORMAT_MONO8 HEX: 1100
-CONSTANT: AL_FORMAT_MONO16 HEX: 1101
-CONSTANT: AL_FORMAT_STEREO8 HEX: 1102
-CONSTANT: AL_FORMAT_STEREO16 HEX: 1103
-CONSTANT: AL_REFERENCE_DISTANCE HEX: 1020
-CONSTANT: AL_ROLLOFF_FACTOR HEX: 1021
-CONSTANT: AL_CONE_OUTER_GAIN HEX: 1022
-CONSTANT: AL_MAX_DISTANCE HEX: 1023
-CONSTANT: AL_FREQUENCY HEX: 2001
-CONSTANT: AL_BITS HEX: 2002
-CONSTANT: AL_CHANNELS HEX: 2003
-CONSTANT: AL_SIZE HEX: 2004
-CONSTANT: AL_UNUSED HEX: 2010
-CONSTANT: AL_PENDING HEX: 2011
-CONSTANT: AL_PROCESSED HEX: 2012
-CONSTANT: AL_NO_ERROR AL_FALSE
-CONSTANT: AL_INVALID_NAME HEX: A001
-CONSTANT: AL_ILLEGAL_ENUM HEX: A002
-CONSTANT: AL_INVALID_ENUM HEX: A002
-CONSTANT: AL_INVALID_VALUE HEX: A003
-CONSTANT: AL_ILLEGAL_COMMAND HEX: A004
-CONSTANT: AL_INVALID_OPERATION HEX: A004
-CONSTANT: AL_OUT_OF_MEMORY HEX: A005
-CONSTANT: AL_VENDOR HEX: B001
-CONSTANT: AL_VERSION HEX: B002
-CONSTANT: AL_RENDERER HEX: B003
-CONSTANT: AL_EXTENSIONS HEX: B004
-CONSTANT: AL_DOPPLER_FACTOR HEX: C000
-CONSTANT: AL_DOPPLER_VELOCITY HEX: C001
-CONSTANT: AL_SPEED_OF_SOUND HEX: C003
-CONSTANT: AL_DISTANCE_MODEL HEX: D000
-CONSTANT: AL_INVERSE_DISTANCE HEX: D001
-CONSTANT: AL_INVERSE_DISTANCE_CLAMPED HEX: D002
-CONSTANT: AL_LINEAR_DISTANCE HEX: D003
-CONSTANT: AL_LINEAR_DISTANCE_CLAMPED HEX: D004
-CONSTANT: AL_EXPONENT_DISTANCE HEX: D005
-CONSTANT: AL_EXPONENT_DISTANCE_CLAMPED HEX: D006
-
-FUNCTION: void alEnable ( ALenum capability ) ;
-FUNCTION: void alDisable ( ALenum capability ) ; 
-FUNCTION: ALboolean alIsEnabled ( ALenum capability ) ; 
-FUNCTION: ALchar* alGetString ( ALenum param ) ;
-FUNCTION: void alGetBooleanv ( ALenum param, ALboolean* data ) ;
-FUNCTION: void alGetIntegerv ( ALenum param, ALint* data ) ;
-FUNCTION: void alGetFloatv ( ALenum param, ALfloat* data ) ;
-FUNCTION: void alGetDoublev ( ALenum param, ALdouble* data ) ;
-FUNCTION: ALboolean alGetBoolean ( ALenum param ) ;
-FUNCTION: ALint alGetInteger ( ALenum param ) ;
-FUNCTION: ALfloat alGetFloat ( ALenum param ) ;
-FUNCTION: ALdouble alGetDouble ( ALenum param ) ;
-FUNCTION: ALenum alGetError (  ) ;
-FUNCTION: ALboolean alIsExtensionPresent ( ALchar* extname ) ;
-FUNCTION: void* alGetProcAddress ( ALchar* fname ) ;
-FUNCTION: ALenum alGetEnumValue ( ALchar* ename ) ;
-FUNCTION: void alListenerf ( ALenum param, ALfloat value ) ;
-FUNCTION: void alListener3f ( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alListenerfv ( ALenum param, ALfloat* values ) ; 
-FUNCTION: void alListeneri ( ALenum param, ALint value ) ;
-FUNCTION: void alListener3i ( ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alListeneriv ( ALenum param, ALint* values ) ;
-FUNCTION: void alGetListenerf ( ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetListener3f ( ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) ;
-FUNCTION: void alGetListenerfv ( ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetListeneri ( ALenum param, ALint* value ) ;
-FUNCTION: void alGetListener3i ( ALenum param, ALint* value1, ALint* value2, ALint* value3 ) ;
-FUNCTION: void alGetListeneriv ( ALenum param, ALint* values ) ;
-FUNCTION: void alGenSources ( ALsizei n, ALuint* sources ) ; 
-FUNCTION: void alDeleteSources ( ALsizei n, ALuint* sources ) ;
-FUNCTION: ALboolean alIsSource ( ALuint sid ) ; 
-FUNCTION: void alSourcef ( ALuint sid, ALenum param, ALfloat value ) ; 
-FUNCTION: void alSource3f ( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ; 
-FUNCTION: void alSourcei ( ALuint sid, ALenum param, ALint value ) ; 
-FUNCTION: void alSource3i ( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alSourceiv ( ALuint sid, ALenum param, ALint* values ) ;
-FUNCTION: void alGetSourcef ( ALuint sid, ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetSource3f ( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
-FUNCTION: void alGetSourcefv ( ALuint sid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetSourcei ( ALuint sid,  ALenum param, ALint* value ) ;
-FUNCTION: void alGetSource3i ( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
-FUNCTION: void alGetSourceiv ( ALuint sid,  ALenum param, ALint* values ) ;
-FUNCTION: void alSourcePlayv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourceStopv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourceRewindv ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourcePausev ( ALsizei ns, ALuint* sids ) ;
-FUNCTION: void alSourcePlay ( ALuint sid ) ;
-FUNCTION: void alSourceStop ( ALuint sid ) ;
-FUNCTION: void alSourceRewind ( ALuint sid ) ;
-FUNCTION: void alSourcePause ( ALuint sid ) ;
-FUNCTION: void alSourceQueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
-FUNCTION: void alSourceUnqueueBuffers ( ALuint sid, ALsizei numEntries, ALuint* bids ) ;
-FUNCTION: void alGenBuffers ( ALsizei n, ALuint* buffers ) ;
-FUNCTION: void alDeleteBuffers ( ALsizei n, ALuint* buffers ) ;
-FUNCTION: ALboolean alIsBuffer ( ALuint bid ) ;
-FUNCTION: void alBufferData ( ALuint bid, ALenum format, void* data, ALsizei size, ALsizei freq ) ;
-FUNCTION: void alBufferf ( ALuint bid, ALenum param, ALfloat value ) ;
-FUNCTION: void alBuffer3f ( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) ;
-FUNCTION: void alBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alBufferi ( ALuint bid, ALenum param, ALint value ) ;
-FUNCTION: void alBuffer3i ( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) ;
-FUNCTION: void alBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
-FUNCTION: void alGetBufferf ( ALuint bid, ALenum param, ALfloat* value ) ;
-FUNCTION: void alGetBuffer3f ( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) ;
-FUNCTION: void alGetBufferfv ( ALuint bid, ALenum param, ALfloat* values ) ;
-FUNCTION: void alGetBufferi ( ALuint bid, ALenum param, ALint* value ) ;
-FUNCTION: void alGetBuffer3i ( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) ;
-FUNCTION: void alGetBufferiv ( ALuint bid, ALenum param, ALint* values ) ;
-FUNCTION: void alDopplerFactor ( ALfloat value ) ;
-FUNCTION: void alDopplerVelocity ( ALfloat value ) ;
-FUNCTION: void alSpeedOfSound ( ALfloat value ) ;
-FUNCTION: void alDistanceModel ( ALenum distanceModel ) ;
-
-LIBRARY: alut
-
-CONSTANT: ALUT_API_MAJOR_VERSION 1
-CONSTANT: ALUT_API_MINOR_VERSION 1
-CONSTANT: ALUT_ERROR_NO_ERROR 0
-CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
-CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
-CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
-CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
-CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
-CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
-CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
-CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
-CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
-CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
-CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
-CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
-CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
-CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
-CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
-CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
-CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
-CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
-CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
-CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
-CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
-CONSTANT: ALUT_LOADER_BUFFER HEX: 300
-CONSTANT: ALUT_LOADER_MEMORY HEX: 301
-
-FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutExit ( ) ;
-FUNCTION: ALenum alutGetError ( ) ;
-FUNCTION: char* alutGetErrorString ( ALenum error ) ;
-FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
-FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
-FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
-FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
-FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
-FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
-FUNCTION: ALint alutGetMajorVersion ( ) ;
-FUNCTION: ALint alutGetMinorVersion ( ) ;
-FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
-
-FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
-
-SYMBOL: init
-
-: init-openal ( -- )
-    init get-global expired? [
-        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
-        1337 <alien> init set-global
-    ] when ;
-
-: exit-openal ( -- )
-    init get-global expired? [
-        alutExit 0 = [ "Could not close OpenAL" throw ] when
-        f init set-global
-    ] unless ;
-
-: <uint-array> ( n -- byte-array ) "ALuint" <c-array> ;
-
-: gen-sources ( size -- seq )
-    dup <uint-array> 2dup underlying>> alGenSources swap ;
-
-: gen-buffers ( size -- seq )
-    dup <uint-array> 2dup underlying>> alGenBuffers swap ;
-
-: gen-buffer ( -- buffer ) 1 gen-buffers first ;
-
-: create-buffer-from-file ( filename -- buffer )
-    alutCreateBufferFromFile dup AL_NONE = [
-        "create-buffer-from-file failed" throw
-    ] when ;
-
-os macosx? "openal.macosx" "openal.other" ? require
-
-: create-buffer-from-wav ( filename -- buffer )
-    gen-buffer dup rot load-wav-file
-    [ alBufferData ] 4keep alutUnloadWAV ;
-
-: queue-buffers ( source buffers -- )
-    [ length ] [ >uint-array underlying>> ] bi alSourceQueueBuffers ;
-
-: queue-buffer ( source buffer -- )
-    1array queue-buffers ;
-
-: set-source-param ( source param value -- )
-    alSourcei ;
-
-: get-source-param ( source param -- value )
-    0 <uint> dup [ alGetSourcei ] dip *uint ;
-
-: set-buffer-param ( source param value -- )
-    alBufferi ;
-
-: get-buffer-param ( source param -- value )
-    0 <uint> dup [ alGetBufferi ] dip *uint ;
-
-: source-play ( source -- ) alSourcePlay ;
-
-: source-stop ( source -- ) alSourceStop ;
-
-: check-error ( -- )
-    alGetError dup ALUT_ERROR_NO_ERROR = [
-        drop
-    ] [
-        alGetString throw
-    ] if ;
-
-: source-playing? ( source -- bool )
-    AL_SOURCE_STATE get-source-param AL_PLAYING = ;
diff --git a/unmaintained/openal/other/authors.txt b/unmaintained/openal/other/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/unmaintained/openal/other/other.factor b/unmaintained/openal/other/other.factor
deleted file mode 100644 (file)
index d0429fb..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: openal.backend alien.c-types kernel alien alien.syntax
-shuffle combinators.lib ;
-IN: openal.other
-
-LIBRARY: alut
-
-FUNCTION: void alutLoadWAVFile ( ALbyte* fileName, ALenum* format, void** data, ALsizei* size, ALsizei* frequency, ALboolean* looping ) ;
-
-M: object load-wav-file ( filename -- format data size frequency )
-  0 <int> f <void*> 0 <int> 0 <int>
-  [ 0 <char> alutLoadWAVFile ] 4keep
-  >r >r >r *int r> *void* r> *int r> *int ;
diff --git a/unmaintained/openal/summary.txt b/unmaintained/openal/summary.txt
deleted file mode 100644 (file)
index 5df8b3a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-OpenAL 3D audio library binding
diff --git a/unmaintained/openal/tags.txt b/unmaintained/openal/tags.txt
deleted file mode 100644 (file)
index a5b2257..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-bindings
-audio
diff --git a/unmaintained/synth/authors.txt b/unmaintained/synth/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/unmaintained/synth/buffers/authors.txt b/unmaintained/synth/buffers/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/unmaintained/synth/buffers/buffers.factor b/unmaintained/synth/buffers/buffers.factor
deleted file mode 100644 (file)
index b0128ca..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types combinators kernel locals math math.ranges openal sequences sequences.merged ;
-IN: synth.buffers
-
-TUPLE: buffer sample-freq 8bit? id ;
-
-: <buffer> ( sample-freq 8bit? -- buffer )
-    f buffer boa ;
-
-TUPLE: mono-buffer < buffer data ;
-
-: <mono-buffer> ( sample-freq 8bit? -- buffer )
-    f f mono-buffer boa ;
-
-: <8bit-mono-buffer> ( sample-freq -- buffer ) t <mono-buffer> ;
-: <16bit-mono-buffer> ( sample-freq -- buffer ) f <mono-buffer> ;
-
-TUPLE: stereo-buffer < buffer left-data right-data ;
-
-: <stereo-buffer> ( sample-freq 8bit? -- buffer )
-    f f f stereo-buffer boa ;
-
-: <8bit-stereo-buffer> ( sample-freq -- buffer ) t <stereo-buffer> ;
-: <16bit-stereo-buffer> ( sample-freq -- buffer ) f <stereo-buffer> ;
-
-PREDICATE: 8bit-buffer < buffer 8bit?>> ;
-PREDICATE: 16bit-buffer < buffer 8bit?>> not ;
-INTERSECTION: 8bit-mono-buffer 8bit-buffer mono-buffer ;
-INTERSECTION: 16bit-mono-buffer 16bit-buffer mono-buffer ;
-INTERSECTION: 8bit-stereo-buffer 8bit-buffer stereo-buffer ;
-INTERSECTION: 16bit-stereo-buffer 16bit-buffer stereo-buffer ;
-
-GENERIC: buffer-format ( buffer -- format )
-M: 8bit-mono-buffer buffer-format drop AL_FORMAT_MONO8 ;
-M: 16bit-mono-buffer buffer-format drop AL_FORMAT_MONO16 ;
-M: 8bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO8 ;
-M: 16bit-stereo-buffer buffer-format drop AL_FORMAT_STEREO16 ;
-
-: 8bit-buffer-data ( seq -- data size )
-    [ 128 * >integer 128 + ] uchar-array{ } map-as [ underlying>> ] [ length ] bi ;
-
-: 16bit-buffer-data ( seq -- data size )
-    [ 32768 * >integer ] short-array{ } map-as [ underlying>> ] [ byte-length ] bi ;
-
-: stereo-data ( stereo-buffer -- left right )
-    [ left-data>> ] [ right-data>> ] bi@ ;
-
-: interleaved-stereo-data ( stereo-buffer -- data )
-    stereo-data <2merged> ;
-
-GENERIC: buffer-data ( buffer -- data size )
-M: 8bit-mono-buffer buffer-data data>> 8bit-buffer-data ;
-M: 16bit-mono-buffer buffer-data data>> 16bit-buffer-data ;
-M: 8bit-stereo-buffer buffer-data
-    interleaved-stereo-data 8bit-buffer-data ;
-M: 16bit-stereo-buffer buffer-data
-    interleaved-stereo-data 16bit-buffer-data ;
-
-: telephone-sample-freq 8000 ;
-: half-sample-freq 22050 ;
-: cd-sample-freq 44100 ;
-: digital-sample-freq 48000 ;
-: professional-sample-freq 88200 ;
-
-: send-buffer ( buffer -- buffer )
-    {
-        [ gen-buffer dup [ >>id ] dip ]
-        [ buffer-format ]
-        [ buffer-data ]
-        [ sample-freq>> alBufferData ]
-    } cleave ;
-
-: ?send-buffer ( buffer -- buffer )
-    dup id>> [ send-buffer ] unless ;
-
diff --git a/unmaintained/synth/example/authors.txt b/unmaintained/synth/example/authors.txt
deleted file mode 100644 (file)
index e9c193b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Alex Chapman
diff --git a/unmaintained/synth/example/example.factor b/unmaintained/synth/example/example.factor
deleted file mode 100644 (file)
index 747cfb9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel namespaces make openal sequences
-synth synth.buffers ;
-IN: synth.example
-
-: play-sine-wave ( freq seconds sample-freq -- )
-    init-openal
-    <16bit-mono-buffer> >sine-wave-buffer send-buffer id>>
-    1 gen-sources first
-    [ AL_BUFFER rot set-source-param ] [ source-play ] bi
-    check-error ;
-
-: test-instrument1 ( -- harmonics )
-    [
-        1 0.5 <harmonic> ,
-        2 0.125 <harmonic> ,
-        3 0.0625 <harmonic> ,
-        4 0.03125 <harmonic> ,
-    ] { } make ;
-
-: test-instrument2 ( -- harmonics )
-    [
-        1 0.25 <harmonic> ,
-        2 0.25 <harmonic> ,
-        3 0.25 <harmonic> ,
-        4 0.25 <harmonic> ,
-    ] { } make ;
-
-: sine-instrument ( -- harmonics )
-    1 1 <harmonic> 1array ;
-
-: test-note-buffer ( note -- )
-    init-openal
-    test-instrument2 swap cd-sample-freq <16bit-mono-buffer>
-    >note send-buffer id>>
-    1 gen-sources first [ swap queue-buffer ] [ source-play ] bi
-    check-error ;
diff --git a/unmaintained/synth/summary.txt b/unmaintained/synth/summary.txt
deleted file mode 100644 (file)
index ece5893..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Simple sound synthesis using OpenAL.
diff --git a/unmaintained/synth/synth.factor b/unmaintained/synth/synth.factor
deleted file mode 100644 (file)
index be1e594..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-! Copyright (C) 2008 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel locals math math.constants math.functions memoize openal synth.buffers sequences sequences.modified sequences.repeating ;
-IN: synth
-
-MEMO: single-sine-wave ( samples/wave -- seq )
-    pi 2 * over / [ * sin ] curry map ;
-
-: (sine-wave) ( samples/wave n-samples -- seq )
-    [ single-sine-wave ] dip <repeating> ;
-
-: sine-wave ( sample-freq freq seconds -- seq )
-    pick * >integer [ /i ] dip (sine-wave) ;
-
-: >sine-wave-buffer ( freq seconds buffer -- buffer )
-    [ sample-freq>> -rot sine-wave ] keep swap >>data ;
-
-: >silent-buffer ( seconds buffer -- buffer )
-    tuck sample-freq>> * >integer 0 <repetition> >>data ;
-
-TUPLE: harmonic n amplitude ;
-C: <harmonic> harmonic
-
-TUPLE: note hz secs ;
-C: <note> note
-
-: harmonic-freq ( note harmonic -- freq )
-    n>> swap hz>> * ;
-
-:: note-harmonic-data ( harmonic note buffer -- data )
-    buffer sample-freq>> note harmonic harmonic-freq note secs>> sine-wave
-    harmonic amplitude>> <scaled> ;
-
-: >note ( harmonics note buffer -- buffer )
-    dup -roll [ note-harmonic-data ] 2curry map <summed> >>data ;
-
index a91eff67837db8848063c391e50616f0a5271ab7..2252d07541f05ceb10a1d6db8050ae9572f73d63 100755 (executable)
@@ -149,20 +149,23 @@ void copy_roots(void)
        copy_registered_locals();
        copy_stack_elements(extra_roots_region,extra_roots);
 
-       save_stacks();
-       F_CONTEXT *stacks = stack_chain;
-
-       while(stacks)
+       if(!performing_compaction)
        {
-               copy_stack_elements(stacks->datastack_region,stacks->datastack);
-               copy_stack_elements(stacks->retainstack_region,stacks->retainstack);
+               save_stacks();
+               F_CONTEXT *stacks = stack_chain;
+
+               while(stacks)
+               {
+                       copy_stack_elements(stacks->datastack_region,stacks->datastack);
+                       copy_stack_elements(stacks->retainstack_region,stacks->retainstack);
 
-               copy_handle(&stacks->catchstack_save);
-               copy_handle(&stacks->current_callback_save);
+                       copy_handle(&stacks->catchstack_save);
+                       copy_handle(&stacks->current_callback_save);
 
-               mark_active_blocks(stacks);
+                       mark_active_blocks(stacks);
 
-               stacks = stacks->next;
+                       stacks = stacks->next;
+               }
        }
 
        int i;
index 354c9398a54a9f207d238a4a7d0788a1024ed308..feae26706d4f48f9b3993aeda1ef106306aa7b9b 100755 (executable)
@@ -5,6 +5,7 @@ DLLEXPORT void minor_gc(void);
 
 F_ZONE *newspace;
 bool performing_gc;
+bool performing_compaction;
 CELL collecting_gen;
 
 /* if true, we collecting AGING space for the second time, so if it is still
index a1987180d0fa9280d3a002336a22081030a15aaf..9cc97df0d94db5eaad9dc34d1f8cb97d98943f4e 100755 (executable)
@@ -187,7 +187,9 @@ void primitive_save_image_and_exit(void)
                userenv[i] = F;
 
        /* do a full GC + code heap compaction */
+       performing_compaction = true;
        compact_code_heap();
+       performing_compaction = false;
 
        UNREGISTER_C_STRING(path);