]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorJoe Groff <arcata@gmail.com>
Tue, 10 Jun 2008 01:24:10 +0000 (18:24 -0700)
committerJoe Groff <arcata@gmail.com>
Tue, 10 Jun 2008 01:24:10 +0000 (18:24 -0700)
462 files changed:
core/alien/c-types/c-types.factor
core/alien/compiler/compiler-tests.factor
core/alien/compiler/compiler.factor
core/alien/remote-control/remote-control.factor
core/alien/syntax/syntax.factor
core/assocs/assocs-docs.factor
core/assocs/assocs.factor
core/bootstrap/compiler/compiler.factor
core/bootstrap/image/image.factor
core/bootstrap/primitives.factor
core/bootstrap/syntax.factor
core/classes/algebra/algebra-tests.factor
core/classes/classes-tests.factor
core/classes/classes.factor
core/classes/mixin/mixin.factor
core/classes/tuple/tuple-tests.factor
core/classes/tuple/tuple.factor
core/classes/union/union.factor
core/command-line/command-line.factor
core/compiler/compiler.factor
core/compiler/constants/constants.factor
core/compiler/errors/errors.factor
core/compiler/tests/intrinsics.factor
core/compiler/tests/redefine.factor [new file with mode: 0644]
core/compiler/tests/simple.factor
core/compiler/tests/stack-trace.factor
core/compiler/tests/templates.factor
core/compiler/units/units.factor
core/continuations/continuations.factor
core/cpu/architecture/architecture.factor
core/cpu/ppc/bootstrap.factor
core/cpu/x86/32/32.factor
core/cpu/x86/allot/allot.factor
core/cpu/x86/architecture/architecture.factor
core/cpu/x86/assembler/assembler.factor
core/cpu/x86/bootstrap.factor
core/cpu/x86/intrinsics/intrinsics.factor
core/debugger/debugger.factor
core/definitions/definitions.factor
core/effects/effects-docs.factor
core/effects/effects-tests.factor
core/effects/effects.factor
core/generator/generator.factor
core/generator/registers/registers.factor
core/generic/generic-tests.factor
core/generic/generic.factor
core/generic/standard/engines/tag/tag.factor
core/generic/standard/engines/tuple/tuple.factor
core/generic/standard/standard-tests.factor
core/generic/standard/standard.factor
core/grouping/authors.txt [new file with mode: 0644]
core/grouping/grouping-docs.factor [new file with mode: 0644]
core/grouping/grouping-tests.factor [new file with mode: 0644]
core/grouping/grouping.factor [new file with mode: 0644]
core/grouping/summary.txt [new file with mode: 0644]
core/grouping/tags.txt [new file with mode: 0644]
core/hashtables/hashtables-docs.factor
core/hashtables/hashtables.factor
core/inference/backend/backend-docs.factor
core/inference/backend/backend.factor
core/inference/class/class-tests.factor
core/inference/class/class.factor
core/inference/dataflow/dataflow.factor
core/inference/errors/errors.factor
core/inference/inference-docs.factor
core/inference/inference-tests.factor
core/inference/inference.factor
core/inference/known-words/known-words.factor
core/inference/state/state-tests.factor
core/inference/state/state.factor
core/inference/transforms/transforms-tests.factor
core/inference/transforms/transforms.factor
core/io/files/files-tests.factor
core/io/files/files.factor
core/io/streams/string/string.factor
core/kernel/kernel-docs.factor
core/kernel/kernel.factor
core/math/bitfields/bitfields-tests.factor
core/math/bitfields/bitfields.factor
core/math/integers/integers-tests.factor
core/math/intervals/intervals-tests.factor
core/math/intervals/intervals.factor
core/math/parser/parser.factor
core/optimizer/control/control.factor
core/optimizer/inlining/inlining.factor
core/optimizer/optimizer-tests.factor
core/parser/parser-docs.factor
core/parser/parser.factor
core/prettyprint/backend/backend.factor
core/prettyprint/prettyprint-tests.factor
core/prettyprint/prettyprint.factor
core/prettyprint/sections/sections.factor
core/quotations/quotations.factor
core/sequences/sequences-docs.factor
core/slots/slots-docs.factor
core/slots/slots.factor
core/splitting/splitting-docs.factor
core/splitting/splitting-tests.factor
core/splitting/splitting.factor
core/syntax/syntax-docs.factor
core/syntax/syntax.factor
core/threads/threads.factor
core/vocabs/loader/loader.factor
core/words/words-docs.factor
core/words/words.factor
extra/alias/alias.factor [new file with mode: 0755]
extra/asn1/asn1.factor
extra/base64/base64.factor
extra/benchmark/continuations/continuations.factor
extra/benchmark/dispatch2/dispatch2.factor
extra/benchmark/dispatch3/dispatch3.factor
extra/benchmark/dispatch4/dispatch4.factor
extra/benchmark/fasta/fasta.factor
extra/benchmark/fib1/fib1.factor
extra/benchmark/fib2/fib2.factor
extra/benchmark/fib3/fib3.factor
extra/benchmark/fib4/fib4.factor
extra/benchmark/fib5/fib5.factor
extra/benchmark/fib6/fib6.factor
extra/benchmark/iteration/iteration.factor
extra/benchmark/mandel/mandel.factor
extra/benchmark/nsieve-bits/nsieve-bits.factor
extra/benchmark/nsieve/nsieve.factor
extra/benchmark/partial-sums/partial-sums.factor
extra/benchmark/random/random.factor
extra/benchmark/raytracer/raytracer.factor
extra/benchmark/recursive/recursive.factor
extra/benchmark/reverse-complement/reverse-complement.factor
extra/benchmark/sockets/sockets.factor
extra/benchmark/sort/sort.factor
extra/benchmark/typecheck1/typecheck1.factor
extra/benchmark/typecheck2/typecheck2.factor
extra/benchmark/typecheck3/typecheck3.factor
extra/benchmark/typecheck4/typecheck4.factor
extra/bitfields/bitfields.factor
extra/bootstrap/help/help.factor
extra/bootstrap/image/upload/upload.factor
extra/bunny/model/model.factor
extra/cairo/gadgets/gadgets.factor
extra/calendar/calendar.factor
extra/calendar/format/format.factor
extra/calendar/format/macros/macros-tests.factor
extra/checksums/md5/md5.factor
extra/checksums/sha2/sha2.factor
extra/cocoa/messages/messages.factor
extra/concurrency/mailboxes/mailboxes.factor
extra/concurrency/messaging/messaging.factor
extra/cords/authors.txt [new file with mode: 0644]
extra/cords/cords-tests.factor [new file with mode: 0644]
extra/cords/cords.factor [new file with mode: 0644]
extra/cords/summary.txt [new file with mode: 0644]
extra/cords/tags.txt [new file with mode: 0644]
extra/core-foundation/fsevents/fsevents.factor
extra/cpu/8080/emulator/emulator.factor
extra/crypto/common/common.factor
extra/db/postgresql/ffi/ffi.factor
extra/db/postgresql/lib/lib.factor
extra/db/sql/sql.factor
extra/db/tuples/tuples.factor
extra/delegate/protocols/protocols.factor
extra/dns/server/server.factor [new file with mode: 0644]
extra/documents/documents.factor
extra/editors/editors.factor
extra/freetype/freetype.factor
extra/fry/fry.factor
extra/furnace/actions/actions-tests.factor
extra/furnace/actions/actions.factor
extra/furnace/asides/asides.factor [new file with mode: 0644]
extra/furnace/auth/login/login.factor
extra/furnace/auth/login/login.xml
extra/furnace/auth/providers/db/db.factor
extra/furnace/boilerplate/boilerplate.factor
extra/furnace/flash/flash.factor [new file with mode: 0644]
extra/furnace/flows/flows.factor [deleted file]
extra/furnace/furnace-tests.factor
extra/furnace/furnace.factor
extra/furnace/rss/rss.factor [deleted file]
extra/furnace/sessions/sessions.factor
extra/furnace/syndication/syndication.factor [new file with mode: 0644]
extra/geo-ip/geo-ip.factor
extra/globs/globs.factor
extra/hardware-info/windows/nt/nt.factor
extra/hello-world/hello-world.factor
extra/help/cookbook/cookbook.factor
extra/help/help.factor
extra/help/html/html.factor [new file with mode: 0644]
extra/help/markup/markup.factor
extra/help/syntax/syntax.factor
extra/hexdump/hexdump.factor
extra/html/components/components-tests.factor
extra/html/components/components.factor
extra/html/elements/elements.factor
extra/html/streams/streams.factor
extra/html/templates/chloe/chloe-tests.factor
extra/html/templates/chloe/chloe.factor
extra/html/templates/chloe/test/test10.xml [new file with mode: 0644]
extra/html/templates/chloe/test/test11.xml [new file with mode: 0644]
extra/html/templates/chloe/test/test12.xml [new file with mode: 0644]
extra/http/client/client.factor
extra/http/http-tests.factor
extra/http/http.factor
extra/http/server/cgi/cgi.factor
extra/http/server/dispatchers/dispatchers.factor
extra/http/server/redirection/redirection-tests.factor
extra/http/server/server-tests.factor [new file with mode: 0644]
extra/http/server/server.factor
extra/icfp/2006/2006.factor
extra/io/encodings/8-bit/8-bit.factor
extra/io/pipes/pipes.factor
extra/io/ports/ports.factor
extra/io/sockets/sockets.factor
extra/io/unix/launcher/launcher.factor
extra/io/unix/launcher/parser/parser.factor
extra/io/unix/linux/monitors/monitors.factor
extra/io/unix/select/select.factor
extra/io/windows/files/files.factor
extra/io/windows/mmap/mmap.factor
extra/jamshred/gl/gl.factor
extra/jamshred/jamshred.factor
extra/jamshred/oint/oint.factor
extra/jamshred/player/player.factor
extra/jamshred/tunnel/tunnel-tests.factor
extra/jamshred/tunnel/tunnel.factor
extra/json/reader/reader.factor
extra/koszul/koszul.factor
extra/lazy-lists/authors.txt [deleted file]
extra/lazy-lists/examples/authors.txt [deleted file]
extra/lazy-lists/examples/examples-tests.factor [deleted file]
extra/lazy-lists/examples/examples.factor [deleted file]
extra/lazy-lists/lazy-lists-docs.factor [deleted file]
extra/lazy-lists/lazy-lists-tests.factor [deleted file]
extra/lazy-lists/lazy-lists.factor [deleted file]
extra/lazy-lists/old-doc.html [deleted file]
extra/lazy-lists/summary.txt [deleted file]
extra/lazy-lists/tags.txt [deleted file]
extra/lisp/lisp-tests.factor
extra/lisp/lisp.factor
extra/lisp/parser/parser-tests.factor
extra/lisp/parser/parser.factor
extra/lists/authors.txt [new file with mode: 0644]
extra/lists/lazy/authors.txt [new file with mode: 0644]
extra/lists/lazy/examples/authors.txt [new file with mode: 0755]
extra/lists/lazy/examples/examples-tests.factor [new file with mode: 0644]
extra/lists/lazy/examples/examples.factor [new file with mode: 0644]
extra/lists/lazy/lazy-docs.factor [new file with mode: 0644]
extra/lists/lazy/lazy-tests.factor [new file with mode: 0644]
extra/lists/lazy/lazy.factor [new file with mode: 0644]
extra/lists/lazy/old-doc.html [new file with mode: 0644]
extra/lists/lazy/summary.txt [new file with mode: 0644]
extra/lists/lazy/tags.txt [new file with mode: 0644]
extra/lists/lists-docs.factor [new file with mode: 0644]
extra/lists/lists-tests.factor [new file with mode: 0644]
extra/lists/lists.factor [new file with mode: 0644]
extra/lists/summary.txt [new file with mode: 0644]
extra/lists/tags.txt [new file with mode: 0644]
extra/locals/backend/backend-tests.factor
extra/locals/locals.factor
extra/logging/analysis/analysis.factor
extra/logging/logging.factor
extra/logging/parser/parser.factor
extra/logging/server/server.factor
extra/macros/macros.factor
extra/match/match.factor
extra/math/erato/erato-tests.factor
extra/math/erato/erato.factor
extra/math/fft/fft.factor
extra/math/functions/functions-tests.factor
extra/math/functions/functions.factor
extra/math/haar/haar.factor
extra/math/libm/libm.factor [changed mode: 0644->0755]
extra/math/matrices/elimination/elimination.factor
extra/math/matrices/matrices.factor
extra/math/polynomials/polynomials.factor
extra/math/primes/factors/factors.factor
extra/math/primes/primes-tests.factor
extra/math/primes/primes.factor
extra/math/text/english/english.factor
extra/memoize/memoize.factor
extra/minneapolis-talk/minneapolis-talk.factor
extra/models/models.factor
extra/monads/monads-tests.factor
extra/monads/monads.factor
extra/money/money.factor
extra/morse/morse.factor
extra/mortar/mortar.factor
extra/multi-methods/multi-methods.factor
extra/namespaces/lib/lib.factor
extra/nehe/nehe.factor
extra/numbers-game/numbers-game.factor
extra/openal/openal.factor
extra/opengl/gadgets/gadgets-tests.factor [new file with mode: 0644]
extra/opengl/gadgets/gadgets.factor
extra/opengl/opengl.factor
extra/openssl/openssl.factor
extra/optimizer/debugger/debugger.factor
extra/optimizer/report/report.factor
extra/ori/ori.factor
extra/pango/cairo/cairo.factor
extra/pango/cairo/gadgets/gadgets.factor
extra/pango/cairo/samples/samples.factor [new file with mode: 0644]
extra/pango/ft2/ft2.factor [new file with mode: 0644]
extra/pango/ft2/gadgets/gadgets.factor [new file with mode: 0644]
extra/pango/gadgets/gadgets.factor [new file with mode: 0644]
extra/pango/layouts/layouts.factor [new file with mode: 0644]
extra/pango/pango.factor
extra/parser-combinators/parser-combinators-docs.factor
extra/parser-combinators/parser-combinators-tests.factor
extra/parser-combinators/parser-combinators.factor
extra/parser-combinators/simple/simple-docs.factor
extra/parser-combinators/simple/simple.factor
extra/persistent-vectors/authors.txt [new file with mode: 0644]
extra/persistent-vectors/persistent-vectors-docs.factor [new file with mode: 0644]
extra/persistent-vectors/persistent-vectors-tests.factor [new file with mode: 0644]
extra/persistent-vectors/persistent-vectors.factor [new file with mode: 0644]
extra/persistent-vectors/summary.txt [new file with mode: 0644]
extra/persistent-vectors/tags.txt [new file with mode: 0644]
extra/present/present.factor [new file with mode: 0644]
extra/project-euler/007/007.factor
extra/project-euler/011/011.factor
extra/project-euler/059/059.factor
extra/project-euler/134/134.factor
extra/qualified/qualified.factor
extra/random/blum-blum-shub/blum-blum-shub-tests.factor
extra/regexp/regexp.factor
extra/regexp2/regexp2-tests.factor [deleted file]
extra/regexp2/regexp2.factor [deleted file]
extra/reports/noise/noise.factor
extra/rss/atom.xml [deleted file]
extra/rss/authors.txt [deleted file]
extra/rss/readme.txt [deleted file]
extra/rss/rss-tests.factor [deleted file]
extra/rss/rss.factor [deleted file]
extra/rss/rss1.xml [deleted file]
extra/rss/summary.txt [deleted file]
extra/sequences/lib/lib.factor
extra/slides/slides.factor
extra/smtp/smtp.factor
extra/state-machine/state-machine.factor
extra/state-parser/state-parser.factor
extra/sudoku/sudoku.factor
extra/syndication/authors.txt [new file with mode: 0755]
extra/syndication/readme.txt [new file with mode: 0644]
extra/syndication/summary.txt [new file with mode: 0755]
extra/syndication/syndication-tests.factor [new file with mode: 0755]
extra/syndication/syndication.factor [new file with mode: 0644]
extra/syndication/tags.txt [new file with mode: 0644]
extra/syndication/test/atom.xml [new file with mode: 0644]
extra/syndication/test/rss1.xml [new file with mode: 0644]
extra/taxes/taxes.factor
extra/tetris/game/game.factor
extra/tetris/piece/piece.factor
extra/tools/crossref/crossref.factor
extra/tools/deploy/backend/backend.factor
extra/tools/deploy/config/config.factor
extra/tools/deploy/test/1/1.factor
extra/tools/deploy/test/2/2.factor
extra/tools/deploy/test/3/3.factor
extra/tools/disassembler/disassembler.factor
extra/tools/memory/memory.factor
extra/tools/profiler/profiler-docs.factor
extra/tools/profiler/profiler-tests.factor
extra/tools/profiler/profiler.factor
extra/tools/time/time.factor
extra/tools/walker/walker.factor
extra/trees/splay/splay.factor
extra/trees/trees.factor
extra/tty-server/tty-server.factor
extra/tuple-arrays/tuple-arrays-docs.factor
extra/tuple-arrays/tuple-arrays.factor
extra/turing/turing.factor
extra/ui/clipboards/clipboards.factor
extra/ui/commands/commands-docs.factor
extra/ui/gadgets/buttons/buttons.factor
extra/ui/gadgets/editors/editors.factor
extra/ui/gadgets/frame-buffer/frame-buffer.factor
extra/ui/gadgets/frames/frames.factor
extra/ui/gadgets/gadgets.factor
extra/ui/gadgets/grids/grids.factor
extra/ui/gadgets/labelled/labelled.factor
extra/ui/gadgets/panes/panes.factor
extra/ui/gadgets/paragraphs/paragraphs.factor
extra/ui/gadgets/scrollers/scrollers.factor
extra/ui/gadgets/sliders/sliders.factor
extra/ui/gadgets/theme/theme.factor
extra/ui/gadgets/viewports/viewports.factor
extra/ui/gadgets/worlds/worlds.factor
extra/ui/render/render.factor
extra/ui/tools/browser/browser.factor
extra/ui/tools/debugger/debugger.factor
extra/ui/tools/deploy/deploy.factor
extra/ui/tools/inspector/inspector.factor
extra/ui/tools/listener/listener.factor
extra/ui/tools/operations/operations.factor
extra/ui/tools/profiler/profiler.factor
extra/ui/tools/search/search.factor
extra/ui/tools/tools.factor
extra/ui/tools/walker/walker.factor
extra/ui/tools/workspace/workspace.factor
extra/ui/windows/windows.factor
extra/unicode/collation/collation-tests.factor
extra/unicode/data/data.factor
extra/units/si/si.factor
extra/units/units.factor
extra/unix/linux/inotify/inotify.factor
extra/unix/stat/macosx/macosx.factor
extra/urls/urls-tests.factor
extra/urls/urls.factor
extra/values/values.factor
extra/vars/vars.factor
extra/webapps/blogs/blogs-common.xml [new file with mode: 0644]
extra/webapps/blogs/blogs.css [new file with mode: 0644]
extra/webapps/blogs/blogs.factor [new file with mode: 0644]
extra/webapps/blogs/edit-post.xml [new file with mode: 0644]
extra/webapps/blogs/list-posts.xml [new file with mode: 0644]
extra/webapps/blogs/new-post.xml [new file with mode: 0644]
extra/webapps/blogs/user-posts.xml [new file with mode: 0644]
extra/webapps/blogs/view-post.xml [new file with mode: 0644]
extra/webapps/factor-website/factor-website.factor
extra/webapps/pastebin/paste.xml
extra/webapps/pastebin/pastebin-common.xml
extra/webapps/pastebin/pastebin.factor
extra/webapps/planet/admin.xml
extra/webapps/planet/entry-summary.xml [deleted file]
extra/webapps/planet/entry.xml [deleted file]
extra/webapps/planet/mini-planet.xml
extra/webapps/planet/planet-common.xml
extra/webapps/planet/planet.factor
extra/webapps/planet/planet.xml
extra/webapps/todo/todo.factor
extra/webapps/todo/todo.xml
extra/webapps/user-admin/user-admin.factor
extra/webapps/user-admin/user-admin.xml
extra/webapps/wee-url/shorten.xml [new file with mode: 0644]
extra/webapps/wee-url/show.xml [new file with mode: 0644]
extra/webapps/wee-url/wee-url.factor [new file with mode: 0644]
extra/webapps/wee-url/wee-url.xml [new file with mode: 0644]
extra/webapps/wiki/changes.xml
extra/webapps/wiki/page-common.xml
extra/webapps/wiki/user-edits.xml
extra/webapps/wiki/wiki-common.xml
extra/webapps/wiki/wiki.factor
extra/windows/advapi32/advapi32.factor [changed mode: 0644->0755]
extra/windows/com/syntax/syntax.factor
extra/windows/gdi32/gdi32.factor [changed mode: 0644->0755]
extra/windows/kernel32/kernel32.factor [changed mode: 0644->0755]
extra/windows/opengl32/opengl32.factor [changed mode: 0644->0755]
extra/windows/user32/user32.factor [changed mode: 0644->0755]
extra/windows/windows.factor
extra/windows/winsock/winsock.factor
extra/x11/clipboard/clipboard.factor
extra/x11/constants/constants.factor
extra/x11/xlib/xlib.factor
extra/xml-rpc/example.factor
extra/xml-rpc/xml-rpc.factor
extra/xml/errors/errors.factor
extra/xmode/keyword-map/keyword-map.factor
extra/xmode/loader/loader.factor
extra/xmode/loader/syntax/syntax.factor
extra/xmode/marker/marker.factor
extra/xmode/utilities/utilities.factor
extra/yahoo/yahoo-docs.factor
misc/factor.el

index 44c0112c77dbddd211fb342c248a4b71d591278a..87fa553dc37d63e2268bc871c01bc295cb72a313 100755 (executable)
@@ -5,7 +5,7 @@ assocs kernel kernel.private libc math
 namespaces parser sequences strings words assocs splitting
 math.parser cpu.architecture alien alien.accessors quotations
 layouts system compiler.units io.files io.encodings.binary
-accessors combinators ;
+accessors combinators effects ;
 IN: alien.c-types
 
 DEFER: <int>
@@ -214,7 +214,8 @@ M: long-long-type box-return ( type -- )
     >r ">c-" swap "-array" 3append r> create ;
 
 : define-to-array ( type vocab -- )
-    [ to-array-word ] 2keep >c-array-quot define ;
+    [ to-array-word ] 2keep >c-array-quot
+    (( array -- byte-array )) define-declared ;
 
 : c-array>quot ( type vocab -- quot )
     [
@@ -227,7 +228,8 @@ M: long-long-type box-return ( type -- )
     >r "c-" swap "-array>" 3append r> create ;
 
 : define-from-array ( type vocab -- )
-    [ from-array-word ] 2keep c-array>quot define ;
+    [ from-array-word ] 2keep c-array>quot
+    (( c-ptr n -- array )) define-declared ;
 
 : define-primitive-type ( type name -- )
     "alien.c-types"
index 5d847e364f0fb73dfae7d40d847958d1b8d9a3e2..eb7652aefd776bf3f0553b86a27a5b7210cd8d59 100755 (executable)
@@ -77,7 +77,7 @@ FUNCTION: tiny ffi_test_17 int x ;
 
 [ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
 
-: indirect-test-1
+: indirect-test-1 ( ptr -- result )
     "int" { } "cdecl" alien-indirect ;
 
 { 1 1 } [ indirect-test-1 ] must-infer-as
@@ -86,7 +86,7 @@ FUNCTION: tiny ffi_test_17 int x ;
 
 [ -1 indirect-test-1 ] must-fail
 
-: indirect-test-2
+: indirect-test-2 ( x y ptr -- result )
     "int" { "int" "int" } "cdecl" alien-indirect gc ;
 
 { 3 1 } [ indirect-test-2 ] must-infer-as
@@ -95,7 +95,7 @@ FUNCTION: tiny ffi_test_17 int x ;
 [ 2 3 "ffi_test_2" f dlsym indirect-test-2 ]
 unit-test
 
-: indirect-test-3
+: indirect-test-3 ( a b c d ptr -- result )
     "int" { "int" "int" "int" "int" } "stdcall" alien-indirect
     gc ;
 
@@ -139,7 +139,7 @@ FUNCTION: void ffi_test_20 double x1, double x2, double x3,
 
 ! Make sure XT doesn't get clobbered in stack frame
 
-: ffi_test_31
+: ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a ptr -- result y )
     "void"
     f "ffi_test_31"
     { "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" }
@@ -286,21 +286,21 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
 
 ! Test callbacks
 
-: callback-1 "void" { } "cdecl" [ ] alien-callback ;
+: callback-1 ( -- callback ) "void" { } "cdecl" [ ] alien-callback ;
 
 [ 0 1 ] [ [ callback-1 ] infer dup effect-in swap effect-out ] unit-test
 
 [ t ] [ callback-1 alien? ] unit-test
 
-: callback_test_1 "void" { } "cdecl" alien-indirect ;
+: callback_test_1 ( ptr -- ) "void" { } "cdecl" alien-indirect ;
 
 [ ] [ callback-1 callback_test_1 ] unit-test
 
-: callback-2 "void" { } "cdecl" [ [ 5 throw ] ignore-errors ] alien-callback ;
+: callback-2 ( -- callback ) "void" { } "cdecl" [ [ 5 throw ] ignore-errors ] alien-callback ;
 
 [ ] [ callback-2 callback_test_1 ] unit-test
 
-: callback-3 "void" { } "cdecl" [ 5 "x" set ] alien-callback ;
+: callback-3 ( -- callback ) "void" { } "cdecl" [ 5 "x" set ] alien-callback ;
 
 [ t ] [
     namestack*
@@ -314,7 +314,7 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
     ] with-scope
 ] unit-test
 
-: callback-4
+: callback-4 ( -- callback )
     "void" { } "cdecl" [ "Hello world" write ] alien-callback
     gc ;
 
@@ -322,14 +322,14 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
     [ callback-4 callback_test_1 ] with-string-writer
 ] unit-test
 
-: callback-5
+: callback-5 ( -- callback )
     "void" { } "cdecl" [ gc ] alien-callback ;
 
 [ "testing" ] [
     "testing" callback-5 callback_test_1
 ] unit-test
 
-: callback-5a
+: callback-5a ( -- callback )
     "void" { } "cdecl" [ 8000000 f <array> drop ] alien-callback ;
 
 ! Hack; if we're on ARM, we probably don't have much RAM, so
@@ -340,26 +340,26 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
 !     ] unit-test
 ! ] unless
 
-: callback-6
+: callback-6 ( -- callback )
     "void" { } "cdecl" [ [ continue ] callcc0 ] alien-callback ;
 
 [ 1 2 3 ] [ callback-6 callback_test_1 1 2 3 ] unit-test
 
-: callback-7
+: callback-7 ( -- callback )
     "void" { } "cdecl" [ 1000 sleep ] alien-callback ;
 
 [ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test
 
 [ f ] [ namespace global eq? ] unit-test
 
-: callback-8
+: callback-8 ( -- callback )
     "void" { } "cdecl" [
         [ continue ] callcc0
     ] alien-callback ;
 
 [ ] [ callback-8 callback_test_1 ] unit-test
 
-: callback-9
+: callback-9 ( -- callback )
     "int" { "int" "int" "int" } "cdecl" [
         + + 1+
     ] alien-callback ;
index 67665b4d7ebc47f474fa923cc1c4d27da24ecc14..ac1895e37e0079f661fb3549985b3ac675c159a8 100755 (executable)
@@ -216,7 +216,8 @@ M: alien-invoke-error summary
     drop
     "Words calling ``alien-invoke'' must be compiled with the optimizing compiler." ;
 
-: pop-parameters pop-literal nip [ expand-constants ] map ;
+: pop-parameters ( -- seq )
+    pop-literal nip [ expand-constants ] map ;
 
 : stdcall-mangle ( symbol node -- symbol )
     "@"
index 1d713f6eddaa59a37aacf96ad7cf369b30b77b39..027663a6458cdbeb72ff3bc552ffd5ac8886eb9e 100755 (executable)
@@ -4,14 +4,14 @@ USING: alien alien.c-types alien.strings parser threads words
 kernel.private kernel io.encodings.utf8 ;
 IN: alien.remote-control
 
-: eval-callback
+: eval-callback ( -- callback )
     "void*" { "char*" } "cdecl"
     [ eval>string utf8 malloc-string ] alien-callback ;
 
-: yield-callback
+: yield-callback ( -- callback )
     "void" { } "cdecl" [ yield ] alien-callback ;
 
-: sleep-callback
+: sleep-callback ( -- callback )
     "void" { "long" } "cdecl" [ sleep ] alien-callback ;
 
 : ?callback ( word -- alien )
index b2e819f8fbf91b695d7092216f1e4c29cbf345c7..def5b02ba03f3c05b1d3c0043d1397d38140d13c 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays alien alien.c-types alien.structs alien.arrays
 alien.strings kernel math namespaces parser sequences words
-quotations math.parser splitting effects prettyprint
+quotations math.parser splitting grouping effects prettyprint
 prettyprint.sections prettyprint.backend assocs combinators ;
 IN: alien.syntax
 
index 68be9c9b06fa83a94af72468069d1e61b54b8683..b33773cf9e06a8735d7a239d9b37c136fd098f78 100755 (executable)
@@ -39,9 +39,7 @@ ARTICLE: "assocs-protocol" "Associative mapping protocol"
 "All associative mappings must implement methods on the following generic words:"
 { $subsection at* }
 { $subsection assoc-size }
-"At least one of the following two generic words must have a method; the " { $link assoc } " mixin has default definitions which are mutually recursive:"
 { $subsection >alist }
-{ $subsection assoc-find }
 "Mutable assocs should implement the following additional words:"
 { $subsection set-at }
 { $subsection delete-at }
@@ -94,6 +92,7 @@ $nl
 $nl
 "The standard functional programming idioms:"
 { $subsection assoc-each }
+{ $subsection assoc-find }
 { $subsection assoc-map }
 { $subsection assoc-push-if }
 { $subsection assoc-filter }
@@ -139,8 +138,7 @@ HELP: new-assoc
 
 HELP: assoc-find
 { $values { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "key" "the successful key, or f" } { "value" "the successful value, or f" } { "?" "a boolean" } }
-{ $contract "Applies a predicate quotation to each entry in the assoc. Returns the key or value that the quotation succeeds on, or " { $link f } " for both if the quotation fails. It also returns a boolean describing whether there was anything found." }
-{ $notes "The " { $link assoc } " mixin has a default implementation for this generic word which first converts the assoc to an association list, then iterates over that with the " { $link find } " combinator for sequences." } ;
+{ $description "Applies a predicate quotation to each entry in the assoc. Returns the key and value that the quotation succeeds on, or " { $link f } " for both if the quotation fails. It also returns a boolean describing whether there was anything found; this can be used to distinguish between a key and a value equal to " { $link f } ", or nothing being found." } ;
 
 HELP: clear-assoc
 { $values { "assoc" assoc } }
index 6b0798f2e307fd107b7bab75ea208a9156a718d9..15afce3e936fc18b3f988677bb5e4d41015b8369 100755 (executable)
@@ -20,11 +20,9 @@ GENERIC: assoc-clone-like ( assoc exemplar -- newassoc )
 
 GENERIC: >alist ( assoc -- newassoc )
 
-GENERIC# assoc-find 1 ( assoc quot -- key value ? ) inline
-
-M: assoc assoc-find
-    >r >alist [ first2 ] r> compose find swap
-    [ first2 t ] [ drop f f f ] if ;
+: assoc-find ( assoc quot -- key value ? )
+    >r >alist r> [ first2 ] prepose find swap
+    [ first2 t ] [ drop f f f ] if ; inline
 
 : key? ( key assoc -- ? ) at* nip ; inline
 
@@ -153,7 +151,7 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
 : extract-keys ( seq assoc -- subassoc )
     [ [ dupd at ] curry ] keep map>assoc ;
 
-M: assoc >alist [ 2array ] { } assoc>map ;
+M: assoc >alist [ 2array ] { } assoc>map ;
 
 : value-at ( value assoc -- key/f )
     swap [ = nip ] curry assoc-find 2drop ;
index 7ad1c6978b30e916b775ff679137d09e477aea0c..5480bac4f581f6fb478c3fd10b98599a6e3a7a11 100755 (executable)
@@ -18,7 +18,8 @@ IN: bootstrap.compiler
 
 enable-compiler
 
-: compile-uncompiled [ compiled? not ] filter compile ;
+: compile-uncompiled ( words -- )
+    [ compiled? not ] filter compile ;
 
 nl
 "Compiling..." write flush
@@ -41,7 +42,7 @@ nl
 
     underlying
 
-    find-pair-next namestack*
+    namestack*
 
     bitand bitor bitxor bitnot
 } compile-uncompiled
index aa7377adbf10618ad0d0c6bea5327c81fcf29dc4..0187a6ce52707193635ded0358e25fbd3d9c9402 100755 (executable)
@@ -4,7 +4,7 @@ USING: alien arrays bit-arrays byte-arrays generic assocs
 hashtables assocs hashtables.private io kernel kernel.private
 math namespaces parser prettyprint sequences sequences.private
 strings sbufs vectors words quotations assocs system layouts
-splitting growable classes classes.builtin classes.tuple
+splitting grouping growable classes classes.builtin classes.tuple
 classes.tuple.private words.private io.binary io.files vocabs
 vocabs.loader source-files definitions debugger float-arrays
 quotations.private sequences.private combinators
@@ -85,13 +85,6 @@ SYMBOL: objects
 : 1-offset              8 ; inline
 : -1-offset             9 ; inline
 
-: array-start 2 bootstrap-cells object tag-number - ;
-: scan@ array-start bootstrap-cell - ;
-: wrapper@ bootstrap-cell object tag-number - ;
-: word-xt@ 8 bootstrap-cells object tag-number - ;
-: quot-array@ bootstrap-cell object tag-number - ;
-: quot-xt@ 3 bootstrap-cells object tag-number - ;
-
 : jit-define ( quot rc rt offset name -- )
     >r { [ { } make ] [ ] [ ] [ ] } spread 4array r> set ;
 
@@ -203,9 +196,9 @@ GENERIC: ' ( obj -- ptr )
 
 ! Bignums
 
-: bignum-bits bootstrap-cell-bits 2 - ;
+: bignum-bits ( -- n ) bootstrap-cell-bits 2 - ;
 
-: bignum-radix bignum-bits 2^ 1- ;
+: bignum-radix ( -- n ) bignum-bits 2^ 1- ;
 
 : bignum>seq ( n -- seq )
     #! n is positive or zero.
@@ -248,15 +241,15 @@ M: float '
 
 ! Padded with fixnums for 8-byte alignment
 
-: t, t t-offset fixup ;
+: t, ( -- ) t t-offset fixup ;
 
 M: f '
     #! f is #define F RETAG(0,F_TYPE)
     drop \ f tag-number ;
 
-:  0,  0 >bignum '  0-offset fixup ;
-:  1,  1 >bignum '  1-offset fixup ;
-: -1, -1 >bignum ' -1-offset fixup ;
+:  0, ( -- )  0 >bignum '  0-offset fixup ;
+:  1, ( -- )  1 >bignum '  1-offset fixup ;
+: -1, ( -- ) -1 >bignum ' -1-offset fixup ;
 
 ! Words
 
index 6fc8ca768557d351f3609626fb61ad47903e697f..6a3c1c35d5659b15eaa6c4e6dcf515dcb7c80312 100755 (executable)
@@ -31,6 +31,7 @@ crossref off
 ! Bring up a bare cross-compiling vocabulary.
 "syntax" vocab vocab-words bootstrap-syntax set
 H{ } clone dictionary set
+H{ } clone new-classes set
 H{ } clone changed-definitions set
 H{ } clone forgotten-definitions set
 H{ } clone root-cache set
index d995cc31762e4678b41fd62324aa8c1095ec301c..f3d7707878b789d60ba09860cb9d0a76fbf22b6d 100755 (executable)
@@ -10,6 +10,7 @@ IN: bootstrap.syntax
     "\""
     "#!"
     "("
+    "(("
     ":"
     ";"
     "<PRIVATE"
index 0b8fb9680be970040909ae2e1164a6d62710aafe..28e899d08ba89c0188b152e3d691d6a1d9b7d2f3 100755 (executable)
@@ -12,11 +12,11 @@ IN: classes.algebra.tests
 \ flatten-class must-infer\r
 \ flatten-builtin-class must-infer\r
 \r
-: class= [ class<= ] [ swap class<= ] 2bi and ;\r
+: class= ( cls1 cls2 -- ? ) [ class<= ] [ swap class<= ] 2bi and ;\r
 \r
-: class-and* >r class-and r> class= ;\r
+: class-and* ( cls1 cls2 cls3 -- ? ) >r class-and r> class= ;\r
 \r
-: class-or* >r class-or r> class= ;\r
+: class-or* ( cls1 cls2 cls3 -- ? ) >r class-or r> class= ;\r
 \r
 [ t ] [ object  object  object class-and* ] unit-test\r
 [ t ] [ fixnum  object  fixnum class-and* ] unit-test\r
@@ -193,9 +193,9 @@ UNION: z1 b1 c1 ;
 [ f ] [ null { number fixnum null } min-class ] unit-test\r
 \r
 ! Test for hangs?\r
-: random-class classes random ;\r
+: random-class ( -- class ) classes random ;\r
 \r
-: random-op\r
+: random-op ( -- word )\r
     {\r
         class-and\r
         class-or\r
@@ -211,13 +211,13 @@ UNION: z1 b1 c1 ;
     ] unit-test\r
 ] times\r
 \r
-: random-boolean\r
+: random-boolean ( -- ? )\r
     { t f } random ;\r
 \r
-: boolean>class\r
+: boolean>class ( ? -- class )\r
     object null ? ;\r
 \r
-: random-boolean-op\r
+: random-boolean-op ( -- word )\r
     {\r
         and\r
         or\r
@@ -225,9 +225,10 @@ UNION: z1 b1 c1 ;
         xor\r
     } random ;\r
 \r
-: class-xor [ class-or ] 2keep class-and class-not class-and ;\r
+: class-xor ( cls1 cls2 -- cls3 )\r
+    [ class-or ] 2keep class-and class-not class-and ;\r
 \r
-: boolean-op>class-op\r
+: boolean-op>class-op ( word -- word' )\r
     {\r
         { and class-and }\r
         { or class-or }\r
index eb55b5fccdba8129c02e3d0678c1cd59bb777b85..a03fed7fcbf3c8503730219504d1bad839037d5d 100755 (executable)
@@ -79,7 +79,7 @@ INSTANCE: integer mx1
 [ \ mx1 forget ] with-compilation-unit
 
 ! Empty unions were causing problems
-GENERIC: empty-union-test
+GENERIC: empty-union-test ( obj -- obj )
 
 UNION: empty-union-1 ;
 
@@ -162,7 +162,7 @@ TUPLE: flat-mx-2-1 ; INSTANCE: flat-mx-2-1 flat-mx-2
 [ t ] [ "hi" \ hi-tag instance? ] unit-test
 
 ! Regression
-GENERIC: method-forget-test
+GENERIC: method-forget-test ( obj -- obj )
 TUPLE: method-forget-class ;
 M: method-forget-class method-forget-test ;
 
index 2c9e1d4787d67235b92474fbc7177cb4fda5deb3..593213c5c637e9912155939e9d754172f267f9fa 100755 (executable)
@@ -38,7 +38,7 @@ PREDICATE: tuple-class < class
 : predicate-word ( word -- predicate )
     [ word-name "?" append ] keep word-vocabulary create ;
 
-: predicate-effect 1 { "?" } <effect> ;
+: predicate-effect T{ effect f 1 { "?" } } ;
 
 PREDICATE: predicate < word "predicating" word-prop >boolean ;
 
@@ -67,8 +67,6 @@ GENERIC: reset-class ( class -- )
 
 M: word reset-class drop ;
 
-<PRIVATE
-
 ! update-map
 : class-uses ( class -- seq )
     [
@@ -81,6 +79,8 @@ M: word reset-class drop ;
 : class-usages ( class -- assoc )
     [ update-map get at ] closure ;
 
+<PRIVATE
+
 : update-map+ ( class -- )
     dup class-uses update-map get add-vertex ;
 
@@ -100,6 +100,7 @@ M: word reset-class drop ;
 : (define-class) ( word props -- )
     >r
     dup reset-class
+    dup class? [ dup new-class ] unless
     dup deferred? [ dup define-symbol ] when
     dup word-props
     r> assoc-union over set-word-props
@@ -115,13 +116,13 @@ GENERIC: update-class ( class -- )
 
 M: class update-class drop ;
 
-GENERIC: update-methods ( assoc -- )
+GENERIC: update-methods ( class assoc -- )
 
 : update-classes ( class -- )
-    class-usages
-    [ [ drop update-class ] assoc-each ]
+    dup class-usages
+    [ nip keys [ update-class ] each ]
     [ update-methods ]
-    bi ;
+    2bi ;
 
 : define-class ( word superclass members participants metaclass -- )
     #! If it was already a class, update methods after.
index 6f888ceca167a6b91751ffb1a23f5757f55361a8..9ffcd952e3008243c0d7d0cd5b29226426fb0f31 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: classes classes.union words kernel sequences
-definitions combinators arrays accessors ;
+definitions combinators arrays assocs generic accessors ;
 IN: classes.mixin
 
 PREDICATE: mixin-class < union-class "mixin" word-prop ;
@@ -12,8 +12,9 @@ M: mixin-class reset-class
 M: mixin-class rank-class drop 3 ;
 
 : redefine-mixin-class ( class members -- )
-    dupd define-union-class
-    t "mixin" set-word-prop ;
+    [ (define-union-class) ]
+    [ drop t "mixin" set-word-prop ]
+    2bi ;
 
 : define-mixin-class ( class -- )
     dup mixin-class? [
@@ -30,17 +31,35 @@ TUPLE: check-mixin-class mixin ;
     ] unless ;
 
 : if-mixin-member? ( class mixin true false -- )
-    >r >r check-mixin-class 2dup members memq? r> r> if ; inline
+    [ check-mixin-class 2dup members memq? ] 2dip if ; inline
 
 : change-mixin-class ( class mixin quot -- )
-    [ members swap bootstrap-word ] prepose keep
+    [ [ members swap bootstrap-word ] dip call ] [ drop ] 2bi
     swap redefine-mixin-class ; inline
 
+: update-classes/new ( mixin -- )
+    class-usages
+    [ keys [ update-class ] each ]
+    [ implementors [ make-generic ] each ] bi ;
+
 : add-mixin-instance ( class mixin -- )
-    [ 2drop ] [ [ suffix ] change-mixin-class ] if-mixin-member? ;
+    #! Note: we call update-classes on the new member, not the
+    #! mixin. This ensures that we only have to update the
+    #! methods whose specializer intersects the new member, not
+    #! the entire mixin (since the other mixin members are not
+    #! affected at all). Also, all usages of the mixin will get
+    #! updated by transitivity; the mixins usages appear in
+    #! class-usages of the member, now that it's been added.
+    [ 2drop ] [
+        [ [ suffix ] change-mixin-class ] 2keep drop
+        dup new-class? [ update-classes/new ] [ update-classes ] if
+    ] if-mixin-member? ;
 
 : remove-mixin-instance ( class mixin -- )
-    [ [ swap remove ] change-mixin-class ] [ 2drop ] if-mixin-member? ;
+    [
+        [ [ swap remove ] change-mixin-class ] keep
+        update-classes
+    ] [ 2drop ] if-mixin-member? ;
 
 ! Definition protocol implementation ensures that removing an
 ! INSTANCE: declaration from a source file updates the mixin.
index ab6c139f7b00832a9f72ce1ffa11a23a4fa58e94..dc99734ce51b2f529c46810e4a0c527df35c007a 100755 (executable)
@@ -8,7 +8,7 @@ columns math.order classes.private ;
 IN: classes.tuple.tests
 
 TUPLE: rect x y w h ;
-: <rect> rect boa ;
+: <rect> ( x y w h -- rect ) rect boa ;
 
 : move ( x rect -- rect )
     [ + ] change-x ;
@@ -69,7 +69,7 @@ C: <predicate-test> predicate-test
 PREDICATE: silly-pred < tuple
     class \ rect = ;
 
-GENERIC: area
+GENERIC: area ( obj -- n )
 M: silly-pred area dup w>> swap h>> * ;
 
 TUPLE: circle radius ;
@@ -164,7 +164,7 @@ C: <t4> t4
 [ 1 ] [ <t4> 1 m2 ] unit-test
 
 ! another combination issue
-GENERIC: silly
+GENERIC: silly ( obj -- obj obj )
 
 UNION: my-union slice repetition column array vector reversed ;
 
@@ -208,8 +208,8 @@ C: <erg's-reshape-problem> erg's-reshape-problem
 
 ! We want to make sure constructors are recompiled when
 ! tuples are reshaped
-: cons-test-1 \ erg's-reshape-problem new ;
-: cons-test-2 \ erg's-reshape-problem boa ;
+: 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
 
@@ -242,7 +242,7 @@ C: <laptop> laptop
 [ t ] [ "laptop" get computer? ] unit-test
 [ t ] [ "laptop" get tuple? ] unit-test
 
-: test-laptop-slot-values
+: test-laptop-slot-values ( -- )
     [ laptop ] [ "laptop" get class ] unit-test
     [ "Pentium" ] [ "laptop" get cpu>> ] unit-test
     [ 128 ] [ "laptop" get ram>> ] unit-test
@@ -275,7 +275,7 @@ C: <server> server
 [ t ] [ "server" get computer? ] unit-test
 [ t ] [ "server" get tuple? ] unit-test
 
-: test-server-slot-values
+: test-server-slot-values ( -- )
     [ server ] [ "server" get class ] unit-test
     [ "PowerPC" ] [ "server" get cpu>> ] unit-test
     [ 64 ] [ "server" get ram>> ] unit-test
@@ -375,7 +375,7 @@ C: <test2> test2
 
 "a" "b" <test2> "test" set
 
-: test-a/b
+: test-a/b ( -- )
     [ "a" ] [ "test" get a>> ] unit-test
     [ "b" ] [ "test" get b>> ] unit-test ;
 
@@ -403,7 +403,7 @@ TUPLE: move-up-2 < move-up-1 c ;
 
 T{ move-up-2 f "a" "b" "c" } "move-up" set
 
-: test-move-up
+: test-move-up ( -- )
     [ "a" ] [ "move-up" get a>> ] unit-test
     [ "b" ] [ "move-up" get b>> ] unit-test
     [ "c" ] [ "move-up" get c>> ] unit-test ;
index 4e6ce0d2bb9922e2980c3d9234ea4aa3237f266e..0b54d7d69f883430b6183fbdd8af3c4a8576479c 100755 (executable)
@@ -176,7 +176,7 @@ M: tuple-class update-class
         2drop
         [
             [ update-tuples-after ]
-            [ changed-definition ]
+            [ +inlined+ changed-definition ]
             [ redefined ]
             tri
         ] each-subclass
index 923c11183f801a83bc1420e439b0798b768381ce..74e29cfb01b47e974c5d2c03d4367fb058eb232e 100755 (executable)
@@ -22,10 +22,11 @@ PREDICATE: union-class < class
 
 M: union-class update-class define-union-predicate ;
 
+: (define-union-class) ( class members -- )
+    f swap f union-class define-class ;
+
 : define-union-class ( class members -- )
-    [ f swap f union-class define-class ]
-    [ drop update-classes ]
-    2bi ;
+    [ (define-union-class) ] [ drop update-classes ] 2bi ;
 
 M: union-class reset-class
     { "class" "metaclass" "members" } reset-props ;
index 84020abca0e5e99ec01ae06395d6438da0af3cd4..fb4fd374a76a3a86449943d349c9b127922e5d59 100644 (file)
@@ -36,7 +36,7 @@ SYMBOL: main-vocab-hook
         main-vocab-hook get [ call ] [ "listener" ] if*
     ] if ;
 
-: default-cli-args
+: default-cli-args ( -- )
     global [
         "quiet" off
         "script" off
index ef00e94dd52070d052bb3bb2618844f2b15238a1..8c653b866e4e4e7d99e1c73a72e2b9a1e42b3e83 100755 (executable)
@@ -35,7 +35,7 @@ IN: compiler
     [ swap save-effect ]
     [ compiled-unxref ]
     [
-        dup compiled-crossref?
+        dup crossref?
         [ dependencies get compiled-xref ] [ drop ] if
     ] tri ;
 
index 8610f490eca490000785d909f4b1de8d97edb9e5..622c63d7f0fefe7666a246abbd2fd934ff61efd2 100755 (executable)
@@ -6,18 +6,20 @@ IN: compiler.constants
 ! These constants must match vm/memory.h
 : card-bits 8 ;
 : deck-bits 18 ;
-: card-mark HEX: 40 HEX: 80 bitor ;
+: card-mark ( -- n ) HEX: 40 HEX: 80 bitor ;
 
 ! These constants must match vm/layouts.h
-: header-offset object tag-number neg ;
-: float-offset 8 float tag-number - ;
-: string-offset 4 bootstrap-cells object tag-number - ;
-: profile-count-offset 7 bootstrap-cells object tag-number - ;
-: byte-array-offset 2 bootstrap-cells object tag-number - ;
-: alien-offset 3 bootstrap-cells object tag-number - ;
-: underlying-alien-offset bootstrap-cell object tag-number - ;
-: tuple-class-offset bootstrap-cell tuple tag-number - ;
-: class-hash-offset bootstrap-cell object tag-number - ;
-: word-xt-offset 8 bootstrap-cells object tag-number - ;
-: word-code-offset 9 bootstrap-cells object tag-number - ;
-: compiled-header-size 4 bootstrap-cells ;
+: header-offset ( -- n ) object tag-number neg ;
+: float-offset ( -- n ) 8 float tag-number - ;
+: string-offset ( -- n ) 4 bootstrap-cells object tag-number - ;
+: profile-count-offset ( -- n ) 7 bootstrap-cells object tag-number - ;
+: byte-array-offset ( -- n ) 2 bootstrap-cells object tag-number - ;
+: alien-offset ( -- n ) 3 bootstrap-cells object tag-number - ;
+: underlying-alien-offset ( -- n ) bootstrap-cell object tag-number - ;
+: tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ;
+: class-hash-offset ( -- n ) bootstrap-cell object tag-number - ;
+: word-xt-offset ( -- n ) 8 bootstrap-cells object tag-number - ;
+: quot-xt-offset ( -- n ) 3 bootstrap-cells object tag-number - ;
+: word-code-offset ( -- n ) 9 bootstrap-cells object tag-number - ;
+: array-start-offset ( -- n ) 2 bootstrap-cells object tag-number - ;
+: compiled-header-size ( -- n ) 4 bootstrap-cells ;
index e7dc5156e468f5d4c9aa3f68128c9822e1c14eb8..2bea6ad97426f307055eaa32495133d2609a668f 100755 (executable)
@@ -59,11 +59,11 @@ PRIVATE>
         [ set-at ] [ delete-at drop ] if
     ] [ 2drop ] if ;
 
-: :errors +error+ compiler-errors. ;
+: :errors ( -- ) +error+ compiler-errors. ;
 
-: :warnings +warning+ compiler-errors. ;
+: :warnings ( -- ) +warning+ compiler-errors. ;
 
-: :linkage +linkage+ compiler-errors. ;
+: :linkage ( -- ) +linkage+ compiler-errors. ;
 
 : with-compiler-errors ( quot -- )
     with-compiler-errors? get "quiet" get or [ call ] [
index 6fb6afe0c607e17e76a2aa1e675b70bde4a3fa7b..0e5c96eca01fc4ad63e5efc0cf7614799a67b669 100755 (executable)
@@ -252,7 +252,7 @@ cell 8 = [
 ! Some randomized tests
 : compiled-fixnum* fixnum* ;
 
-: test-fixnum*
+: test-fixnum* ( -- )
     32 random-bits >fixnum 32 random-bits >fixnum
     2dup
     [ fixnum* ] 2keep compiled-fixnum* =
@@ -262,7 +262,7 @@ cell 8 = [
 
 : compiled-fixnum>bignum fixnum>bignum ;
 
-: test-fixnum>bignum
+: test-fixnum>bignum ( -- )
     32 random-bits >fixnum
     dup [ fixnum>bignum ] keep compiled-fixnum>bignum =
     [ drop ] [ "Oops" throw ] if ;
@@ -271,7 +271,7 @@ cell 8 = [
 
 : compiled-bignum>fixnum bignum>fixnum ;
 
-: test-bignum>fixnum
+: test-bignum>fixnum ( -- )
     5 random [ drop 32 random-bits ] map product >bignum
     dup [ bignum>fixnum ] keep compiled-bignum>fixnum =
     [ drop ] [ "Oops" throw ] if ;
@@ -377,7 +377,7 @@ cell 8 = [
 [ 252 ] [ B{ 1 2 3 -4 5 } 3 [ { byte-array fixnum } declare alien-unsigned-1 ] compile-call ] unit-test
 [ -4 ] [ B{ 1 2 3 -4 5 } 3 [ { byte-array fixnum } declare alien-signed-1 ] compile-call ] unit-test
 
-: xword-def word-def [ { fixnum } declare ] prepend ;
+: xword-def ( word -- def ) word-def [ { fixnum } declare ] prepend ;
 
 [ -100 ] [ -100 <char> [ { byte-array } declare *char ] compile-call ] unit-test
 [ 156 ] [ -100 <uchar> [ { byte-array } declare *uchar ] compile-call ] unit-test
diff --git a/core/compiler/tests/redefine.factor b/core/compiler/tests/redefine.factor
new file mode 100644 (file)
index 0000000..b87898c
--- /dev/null
@@ -0,0 +1,14 @@
+IN: compiler.tests
+USING: compiler tools.test math parser ;
+
+GENERIC: method-redefine-test ( a -- b )
+
+M: integer method-redefine-test 3 + ;
+
+: method-redefine-test-1 ( -- b ) 3 method-redefine-test ;
+
+[ 6 ] [ method-redefine-test-1 ] unit-test
+
+[ ] [ "IN: compiler.tests USE: math M: fixnum method-redefine-test 4 + ;" eval ] unit-test
+
+[ 7 ] [ method-redefine-test-1 ] unit-test
index bc9c56864c32b722c2319eab00e905ab27ac1452..68c85d6d972be8c9e3afb8e5eed7ef591397e1f6 100755 (executable)
@@ -69,31 +69,31 @@ IN: compiler.tests
 
 ! Regression
 
-: empty ;
+: empty ( -- ) ;
 
 [ "b" ] [ 1 [ empty { [ "a" ] [ "b" ] } dispatch ] compile-call ] unit-test
 
-: dummy-if-1 t [ ] [ ] if ;
+: dummy-if-1 ( -- ) t [ ] [ ] if ;
 
 [ ] [ dummy-if-1 ] unit-test
 
-: dummy-if-2 f [ ] [ ] if ;
+: dummy-if-2 ( -- ) f [ ] [ ] if ;
 
 [ ] [ dummy-if-2 ] unit-test
 
-: dummy-if-3 t [ 1 ] [ 2 ] if ;
+: dummy-if-3 ( -- n ) t [ 1 ] [ 2 ] if ;
 
 [ 1 ] [ dummy-if-3 ] unit-test
 
-: dummy-if-4 f [ 1 ] [ 2 ] if ;
+: dummy-if-4 ( -- n ) f [ 1 ] [ 2 ] if ;
 
 [ 2 ] [ dummy-if-4 ] unit-test
 
-: dummy-if-5 0 dup 1 fixnum<= [ drop 1 ] [ ] if ;
+: dummy-if-5 ( -- n ) 0 dup 1 fixnum<= [ drop 1 ] [ ] if ;
 
 [ 1 ] [ dummy-if-5 ] unit-test
 
-: dummy-if-6
+: dummy-if-6 ( n -- n )
     dup 1 fixnum<= [
         drop 1
     ] [
@@ -102,7 +102,7 @@ IN: compiler.tests
 
 [ 17 ] [ 10 dummy-if-6 ] unit-test
 
-: dead-code-rec
+: dead-code-rec ( -- obj )
     t [
         3.2
     ] [
@@ -111,11 +111,11 @@ IN: compiler.tests
 
 [ 3.2 ] [ dead-code-rec ] unit-test
 
-: one-rec [ f one-rec ] [ "hi" ] if ;
+: one-rec ( ? -- obj ) [ f one-rec ] [ "hi" ] if ;
 
 [ "hi" ] [ t one-rec ] unit-test
 
-: after-if-test
+: after-if-test ( -- n )
     t [ ] [ ] if 5 ;
 
 [ 5 ] [ after-if-test ] unit-test
@@ -127,37 +127,37 @@ DEFER: countdown-b
 
 [ ] [ 10 countdown-b ] unit-test
 
-: dummy-when-1 t [ ] when ;
+: dummy-when-1 ( -- ) t [ ] when ;
 
 [ ] [ dummy-when-1 ] unit-test
 
-: dummy-when-2 f [ ] when ;
+: dummy-when-2 ( -- ) f [ ] when ;
 
 [ ] [ dummy-when-2 ] unit-test
 
-: dummy-when-3 dup [ dup fixnum* ] when ;
+: dummy-when-3 ( a -- b ) dup [ dup fixnum* ] when ;
 
 [ 16 ] [ 4 dummy-when-3 ] unit-test
 [ f ] [ f dummy-when-3 ] unit-test
 
-: dummy-when-4 dup [ dup dup fixnum* fixnum* ] when swap ;
+: dummy-when-4 ( a b -- a b ) dup [ dup dup fixnum* fixnum* ] when swap ;
 
 [ 64 f ] [ f 4 dummy-when-4 ] unit-test
 [ f t ] [ t f dummy-when-4 ] unit-test
 
-: dummy-when-5 f [ dup fixnum* ] when ;
+: dummy-when-5 ( a -- b ) f [ dup fixnum* ] when ;
 
 [ f ] [ f dummy-when-5 ] unit-test
 
-: dummy-unless-1 t [ ] unless ;
+: dummy-unless-1 ( -- ) t [ ] unless ;
 
 [ ] [ dummy-unless-1 ] unit-test
 
-: dummy-unless-2 f [ ] unless ;
+: dummy-unless-2 ( -- ) f [ ] unless ;
 
 [ ] [ dummy-unless-2 ] unit-test
 
-: dummy-unless-3 dup [ drop 3 ] unless ;
+: dummy-unless-3 ( a -- b ) dup [ drop 3 ] unless ;
 
 [ 3 ] [ f dummy-unless-3 ] unit-test
 [ 4 ] [ 4 dummy-unless-3 ] unit-test
@@ -201,7 +201,7 @@ DEFER: countdown-b
     ] compile-call
 ] unit-test
 
-GENERIC: single-combination-test
+GENERIC: single-combination-test ( obj1 obj2 -- obj )
 
 M: object single-combination-test drop ;
 M: f single-combination-test nip ;
@@ -214,13 +214,13 @@ M: integer single-combination-test drop ;
 
 DEFER: single-combination-test-2
 
-: single-combination-test-4
+: single-combination-test-4 ( obj -- obj )
     dup [ single-combination-test-2 ] when ;
 
-: single-combination-test-3
+: single-combination-test-3 ( obj -- obj )
     drop 3 ;
 
-GENERIC: single-combination-test-2
+GENERIC: single-combination-test-2 ( obj -- obj )
 M: object single-combination-test-2 single-combination-test-3 ;
 M: f single-combination-test-2 single-combination-test-4 ;
 
index 9ee774d81d59e59691bb3d52b5d2e0030da828fb..3b1a5c6c85081e77f430c1faed16ce6cd0da02fc 100755 (executable)
@@ -1,15 +1,15 @@
 IN: compiler.tests
 USING: compiler tools.test namespaces sequences
 kernel.private kernel math continuations continuations.private
-words splitting sorting ;
+words splitting grouping sorting ;
 
 : symbolic-stack-trace ( -- newseq )
     error-continuation get continuation-call callstack>array
     2 group flip first ;
 
-: foo 3 throw 7 ;
-: bar foo 4 ;
-: baz bar 5 ;
+: foo ( -- * ) 3 throw 7 ;
+: bar ( -- * ) foo 4 ;
+: baz ( -- * ) bar 5 ;
 [ baz ] [ 3 = ] must-fail-with
 [ t ] [
     symbolic-stack-trace
@@ -17,9 +17,9 @@ words splitting sorting ;
     { baz bar foo throw } tail?
 ] unit-test
 
-: bleh [ 3 + ] map [ 0 > ] filter ;
+: bleh ( seq -- seq' ) [ 3 + ] map [ 0 > ] filter ;
 
-: stack-trace-contains? symbolic-stack-trace memq? ;
+: stack-trace-contains? ( word -- ? ) symbolic-stack-trace memq? ;
 
 [ t ] [
     [ { 1 "hi" } bleh ] ignore-errors \ + stack-trace-contains?
@@ -31,7 +31,7 @@ words splitting sorting ;
     \ > stack-trace-contains?
 ] unit-test
 
-: quux { 1 2 3 } [ "hi" throw ] sort ;
+: quux ( -- seq ) { 1 2 3 } [ "hi" throw ] sort ;
 
 [ t ] [
     [ 10 quux ] ignore-errors
index 14d75cdc03e9b0877c2e45e932bf9a7fb8138d70..65ef68deb8c72966963dc759f03dac79141f946b 100755 (executable)
@@ -31,7 +31,7 @@ unit-test
 
 [ 2 ] [ 1 2 [ swap fixnum/i ] compile-call ] unit-test
 
-: foo ;
+: foo ( -- ) ;
 
 [ 5 5 ]
 [ 1.2 [ tag [ foo ] keep ] compile-call ]
@@ -103,10 +103,10 @@ unit-test
 
 
 ! Test how dispatch handles the end of a basic block
-: try-breaking-dispatch
+: try-breaking-dispatch ( n a b -- a b str )
     float+ swap { [ "hey" ] [ "bye" ] } dispatch ;
 
-: try-breaking-dispatch-2
+: try-breaking-dispatch-2 ( -- ? )
     1 1.0 2.5 try-breaking-dispatch "bye" = >r 3.5 = r> and ;
 
 [ t ] [
@@ -143,7 +143,7 @@ unit-test
 ] unit-test
 
 ! Regression
-: foox
+: foox ( obj -- obj )
     dup not
     [ drop 3 ] [ dup tuple? [ drop 4 ] [ drop 5 ] if ] if ;
 
@@ -189,7 +189,7 @@ TUPLE: my-tuple ;
 ] unit-test
 
 ! Regression
-: a-dummy drop "hi" print ;
+: a-dummy ( -- ) drop "hi" print ;
 
 [ ] [
     1 [
@@ -203,7 +203,7 @@ TUPLE: my-tuple ;
     ] compile-call
 ] unit-test
 
-: float-spill-bug
+: float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b )
     {
         [ dup float+ ]
         [ dup float+ ]
index c2e84429cf5ed873de0bd4f5b4d40d461d88c694..658a64315ee45c2805eef4e8a45c78a6b496af38 100755 (executable)
@@ -66,14 +66,14 @@ GENERIC: definitions-changed ( assoc obj -- )
 
 : compile ( words -- )
     recompile-hook get call
-    dup [ drop compiled-crossref? ] assoc-contains?
+    dup [ drop crossref? ] assoc-contains?
     modify-code-heap ;
 
 SYMBOL: outdated-tuples
 SYMBOL: update-tuples-hook
 
 : call-recompile-hook ( -- )
-    changed-definitions get keys [ word? ] filter
+    changed-definitions get [ drop word? ] assoc-filter
     compiled-usages recompile-hook get call ;
 
 : call-update-tuples-hook ( -- )
@@ -82,8 +82,7 @@ SYMBOL: update-tuples-hook
 : finish-compilation-unit ( -- )
     call-recompile-hook
     call-update-tuples-hook
-    dup [ drop compiled-crossref? ] assoc-contains? modify-code-heap
-     ;
+    dup [ drop crossref? ] assoc-contains? modify-code-heap ;
 
 : with-nested-compilation-unit ( quot -- )
     [
@@ -97,6 +96,7 @@ SYMBOL: update-tuples-hook
         H{ } clone changed-definitions set
         H{ } clone forgotten-definitions set
         H{ } clone outdated-tuples set
+        H{ } clone new-classes set
         <definitions> new-definitions set
         <definitions> old-definitions set
         [
index 76f2cdef7a3e92a3ce1a27f0efdad005ff96beeb..087661dff47587f94e8d5025c51800226e2852bd 100755 (executable)
@@ -26,7 +26,7 @@ SYMBOL: restarts
     #! with a declaration.
     f { object } declare ;
 
-: init-catchstack V{ } clone 1 setenv ;
+: init-catchstack ( -- ) V{ } clone 1 setenv ;
 
 PRIVATE>
 
index 338c5341bc51724f5711854d9212c1b0bf0356f7..42bf37d17f639b5f1b58f1cac5e7c869e5e6c72c 100755 (executable)
@@ -41,12 +41,12 @@ HOOK: stack-frame cpu ( frame-size -- n )
 ! Set up caller stack frame
 HOOK: %prologue cpu ( n -- )
 
-: %prologue-later \ %prologue-later , ;
+: %prologue-later ( -- ) \ %prologue-later , ;
 
 ! Tear down stack frame
 HOOK: %epilogue cpu ( n -- )
 
-: %epilogue-later \ %epilogue-later , ;
+: %epilogue-later ( -- ) \ %epilogue-later , ;
 
 ! Store word XT in stack frame
 HOOK: %save-word-xt cpu ( -- )
@@ -195,7 +195,7 @@ HOOK: %unbox-any-c-ptr cpu ( dst src -- )
 HOOK: %box-alien cpu ( dst src -- )
 
 ! GC check
-HOOK: %gc cpu
+HOOK: %gc cpu ( -- )
 
 : operand ( var -- op ) get v>operand ; inline
 
index 18c7e8b92ee5a2c3624335b046f04698c1d1034c..cf380d69f153ca8d04ad55cef4d4d50eca495173 100755 (executable)
@@ -72,7 +72,7 @@ big-endian on
 ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define\r
 \r
 : jit-call-quot ( -- )\r
-    temp-reg quot-reg quot-xt@ LWZ             ! load quotation-xt\r
+    temp-reg quot-reg quot-xt-offset LWZ       ! load quotation-xt\r
     temp-reg MTCTR                             ! jump to quotation-xt\r
     BCTR ;\r
 \r
@@ -93,7 +93,7 @@ big-endian on
     temp-reg ds-reg 0 LWZ                      ! load index\r
     temp-reg dup 1 SRAWI                       ! turn it into an array offset\r
     quot-reg dup temp-reg ADD                  ! compute quotation location\r
-    quot-reg dup array-start LWZ               ! load quotation\r
+    quot-reg dup array-start-offset LWZ        ! load quotation\r
     ds-reg dup 4 SUBI                          ! pop index\r
     jit-call-quot\r
 ] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define\r
index 9ef8177cf3a6f76d74a5925b0037efa8db4e4c4d..3c6e4963e1afe058cd6fc753ba7925ed8ac22cca 100755 (executable)
@@ -31,21 +31,23 @@ M: int-regs return-reg drop EAX ;
 M: int-regs param-regs drop { } ;
 M: int-regs vregs drop { EAX ECX EDX EBP } ;
 M: int-regs push-return-reg return-reg PUSH ;
-: load/store-int-return return-reg stack-reg rot [+] ;
+: load/store-int-return ( n reg-class -- src dst )
+    return-reg stack-reg rot [+] ;
 M: int-regs load-return-reg load/store-int-return MOV ;
 M: int-regs store-return-reg load/store-int-return swap MOV ;
 
 M: float-regs param-regs drop { } ;
 M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
 
-: FSTP 4 = [ FSTPS ] [ FSTPL ] if ;
+: FSTP ( operand size -- ) 4 = [ FSTPS ] [ FSTPL ] if ;
 
 M: float-regs push-return-reg
     stack-reg swap reg-size [ SUB  stack-reg [] ] keep FSTP ;
 
-: FLD 4 = [ FLDS ] [ FLDL ] if ;
+: FLD ( operand size -- ) 4 = [ FLDS ] [ FLDL ] if ;
 
-: load/store-float-return reg-size >r stack@ r> ;
+: load/store-float-return ( n reg-class -- op size )
+    [ stack@ ] [ reg-size ] bi* ;
 M: float-regs load-return-reg load/store-float-return FLD ;
 M: float-regs store-return-reg load/store-float-return FSTP ;
 
@@ -151,7 +153,7 @@ M: x86.32 %box ( n reg-class func -- )
         >r (%box) r> f %alien-invoke
     ] with-aligned-stack ;
     
-: (%box-long-long)
+: (%box-long-long) ( n -- )
     #! If n is f, push the return registers onto the stack; we
     #! are boxing a return value of a C function. If n is an
     #! integer, push [ESP+n]:[ESP+n+4] on the stack; we are
@@ -166,7 +168,7 @@ M: x86.32 %box ( n reg-class func -- )
 
 M: x86.32 %box-long-long ( n func -- )
     8 [
-        >r (%box-long-long) r> f %alien-invoke
+        [ (%box-long-long) ] [ f %alien-invoke ] bi*
     ] with-aligned-stack ;
 
 M: x86.32 %box-large-struct ( n size -- )
@@ -260,7 +262,7 @@ os windows? [
     4 "double" c-type set-c-type-align
 ] unless
 
-: sse2? "Intrinsic" throw ;
+: sse2? ( -- ? ) "Intrinsic" throw ;
 
 \ sse2? [
     { EAX EBX ECX EDX } [ PUSH ] each
index 63870f94cddd359dd8c3834910dac989caf12b6e..144a9560d72ed2b1bba4c4910e7ef1ae97b974a5 100755 (executable)
@@ -6,7 +6,7 @@ sequences generic arrays generator generator.fixup
 generator.registers system layouts alien ;
 IN: cpu.x86.allot
 
-: allot-reg
+: allot-reg ( -- reg )
     #! We temporarily use the datastack register, since it won't
     #! be accessed inside the quotation given to %allot in any
     #! case.
index 88881b19a8fa090796e49d83c6d0c6e07120733f..2a3d16694ea4c20842f45f1c0b759c9dd4cc3830 100755 (executable)
@@ -7,12 +7,12 @@ generator generator.registers generator.fixup system layouts
 combinators compiler.constants math.order ;
 IN: cpu.x86.architecture
 
-HOOK: ds-reg cpu
-HOOK: rs-reg cpu
-HOOK: stack-reg cpu
-HOOK: stack-save-reg cpu
+HOOK: ds-reg cpu ( -- reg )
+HOOK: rs-reg cpu ( -- reg )
+HOOK: stack-reg cpu ( -- reg )
+HOOK: stack-save-reg cpu ( -- reg )
 
-: stack@ stack-reg swap [+] ;
+: stack@ ( n -- op ) stack-reg swap [+] ;
 
 : reg-stack ( n reg -- op ) swap cells neg [+] ;
 
@@ -36,14 +36,14 @@ GENERIC: load-return-reg ( stack@ reg-class -- )
 GENERIC: store-return-reg ( stack@ reg-class -- )
 
 ! Only used by inline allocation
-HOOK: temp-reg-1 cpu
-HOOK: temp-reg-2 cpu
+HOOK: temp-reg-1 cpu ( -- reg )
+HOOK: temp-reg-2 cpu ( -- reg )
 
 HOOK: address-operand cpu ( address -- operand )
 
-HOOK: fixnum>slot@ cpu
+HOOK: fixnum>slot@ cpu ( op -- )
 
-HOOK: prepare-division cpu
+HOOK: prepare-division cpu ( -- )
 
 M: immediate load-literal v>operand swap v>operand MOV ;
 
@@ -53,7 +53,7 @@ M: x86 stack-frame ( n -- i )
 M: x86 %save-word-xt ( -- )
     temp-reg v>operand 0 MOV rc-absolute-cell rel-this ;
 
-: factor-area-size 4 cells ;
+: factor-area-size ( -- n ) 4 cells ;
 
 M: x86 %prologue ( n -- )
     dup cell + PUSH
@@ -120,7 +120,7 @@ M: x86 %peek [ v>operand ] bi@ MOV ;
 
 M: x86 %replace swap %peek ;
 
-: (%inc) swap cells dup 0 > [ ADD ] [ neg SUB ] if ;
+: (%inc) ( n reg -- ) swap cells dup 0 > [ ADD ] [ neg SUB ] if ;
 
 M: x86 %inc-d ( n -- ) ds-reg (%inc) ;
 
@@ -139,7 +139,7 @@ M: x86 small-enough? ( n -- ? )
 
 : %tag-fixnum ( reg -- ) tag-bits get SHL ;
 
-: temp@ stack-reg \ stack-frame get rot - [+] ;
+: temp@ ( n -- op ) stack-reg \ stack-frame get rot - [+] ;
 
 : struct-return@ ( size n -- n )
     [
index bc6a12d167a674c6c1dd14de5870406aa5da7bf8..452a102341ad85f418eab302c8458ec958c34c87 100755 (executable)
@@ -22,7 +22,7 @@ IN: cpu.x86.assembler
 : define-registers ( names size -- )
     >r dup length r> [ define-register ] curry 2each ;
 
-: REGISTERS:
+: REGISTERS: ( -- )
     scan-word ";" parse-tokens swap define-registers ; parsing
 
 >>
@@ -76,31 +76,31 @@ TUPLE: indirect base index scale displacement ;
 
 M: indirect extended? base>> extended? ;
 
-: canonicalize-EBP
+: canonicalize-EBP ( indirect -- indirect )
     #! { EBP } ==> { EBP 0 }
     dup base>> { EBP RBP R13 } member? [
         dup displacement>> [ 0 >>displacement ] unless
-    ] when drop ;
+    ] when ;
 
-: canonicalize-ESP
+: canonicalize-ESP ( indirect -- indirect )
     #! { ESP } ==> { ESP ESP }
-    dup base>> { ESP RSP R12 } member? [ ESP >>index ] when drop ;
+    dup base>> { ESP RSP R12 } member? [ ESP >>index ] when ;
 
-: canonicalize ( indirect -- )
+: canonicalize ( indirect -- indirect )
     #! Modify the indirect to work around certain addressing mode
     #! quirks.
-    [ canonicalize-EBP ] [ canonicalize-ESP ] bi ;
+    canonicalize-EBP canonicalize-ESP ;
 
 : <indirect> ( base index scale displacement -- indirect )
-    indirect boa dup canonicalize ;
+    indirect boa canonicalize ;
 
-: reg-code "register" word-prop 7 bitand ;
+: reg-code ( reg -- n ) "register" word-prop 7 bitand ;
 
-: indirect-base* base>> EBP or reg-code ;
+: indirect-base* ( op -- n ) base>> EBP or reg-code ;
 
-: indirect-index* index>> ESP or reg-code ;
+: indirect-index* ( op -- n ) index>> ESP or reg-code ;
 
-: indirect-scale* scale>> 0 or ;
+: indirect-scale* ( op -- n ) scale>> 0 or ;
 
 GENERIC: sib-present? ( op -- ? )
 
@@ -145,10 +145,10 @@ GENERIC# n, 1 ( value n -- )
 
 M: integer n, >le % ;
 M: byte n, >r value>> r> n, ;
-: 1, 1 n, ; inline
-: 4, 4 n, ; inline
-: 2, 2 n, ; inline
-: cell, bootstrap-cell n, ; inline
+: 1, ( n -- ) 1 n, ; inline
+: 4, ( n -- ) 4 n, ; inline
+: 2, ( n -- ) 2 n, ; inline
+: cell, ( n -- ) bootstrap-cell n, ; inline
 
 : mod-r/m, ( reg# indirect -- )
     [ 3 shift ] [ [ modifier 6 shift ] [ r/m ] bi ] bi* bitor bitor , ;
@@ -196,10 +196,10 @@ M: object operand-64? drop f ;
         [ nip operand-64? ]
     } cond and ;
 
-: rex.r
+: rex.r ( m op -- n )
     extended? [ BIN: 00000100 bitor ] when ;
 
-: rex.b
+: rex.b ( m op -- n )
     [ extended? [ BIN: 00000001 bitor ] when ] keep
     dup indirect? [
         index>> extended? [ BIN: 00000010 bitor ] when
@@ -225,7 +225,7 @@ M: object operand-64? drop f ;
     #! the opcode.
     >r dupd prefix-1 reg-code r> + , ;
 
-: opcode, dup array? [ % ] [ , ] if ;
+: opcode, ( opcode -- ) dup array? [ % ] [ , ] if ;
 
 : extended-opcode ( opcode -- opcode' ) OCT: 17 swap 2array ;
 
@@ -240,7 +240,7 @@ M: object operand-64? drop f ;
     #! 'reg' field of the mod-r/m byte.
     first3 >r >r over r> prefix-1 r> opcode, swap addressing ;
 
-: immediate-operand-size-bit
+: immediate-operand-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode )
     pick integer? [ first3 BIN: 1 opcode-or 3array ] when ;
 
 : immediate-1 ( imm dst reg,rex.w,opcode -- )
@@ -249,7 +249,7 @@ M: object operand-64? drop f ;
 : immediate-4 ( imm dst reg,rex.w,opcode -- )
     immediate-operand-size-bit 1-operand 4, ;
 
-: immediate-fits-in-size-bit
+: immediate-fits-in-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode )
     pick integer? [ first3 BIN: 10 opcode-or 3array ] when ;
 
 : immediate-1/4 ( imm dst reg,rex.w,opcode -- )
@@ -320,38 +320,38 @@ M: operand MOV HEX: 88 2-operand ;
 
 ! Control flow
 GENERIC: JMP ( op -- )
-: (JMP) HEX: e9 , 0 4, rc-relative ;
+: (JMP) ( -- rel-class ) HEX: e9 , 0 4, rc-relative ;
 M: callable JMP (JMP) rel-word ;
 M: label JMP (JMP) label-fixup ;
 M: operand JMP { BIN: 100 t HEX: ff } 1-operand ;
 
 GENERIC: CALL ( op -- )
-: (CALL) HEX: e8 , 0 4, rc-relative ;
+: (CALL) ( -- rel-class ) HEX: e8 , 0 4, rc-relative ;
 M: callable CALL (CALL) rel-word ;
 M: label CALL (CALL) label-fixup ;
 M: operand CALL { BIN: 010 t HEX: ff } 1-operand ;
 
 GENERIC# JUMPcc 1 ( addr opcode -- )
-: (JUMPcc) extended-opcode, 0 4, rc-relative ;
+: (JUMPcc) ( n -- rel-class ) extended-opcode, 0 4, rc-relative ;
 M: callable JUMPcc (JUMPcc) rel-word ;
 M: label JUMPcc (JUMPcc) label-fixup ;
 
-: JO  HEX: 80 JUMPcc ;
-: JNO HEX: 81 JUMPcc ;
-: JB  HEX: 82 JUMPcc ;
-: JAE HEX: 83 JUMPcc ;
-: JE  HEX: 84 JUMPcc ; ! aka JZ
-: JNE HEX: 85 JUMPcc ;
-: JBE HEX: 86 JUMPcc ;
-: JA  HEX: 87 JUMPcc ;
-: JS  HEX: 88 JUMPcc ;
-: JNS HEX: 89 JUMPcc ;
-: JP  HEX: 8a JUMPcc ;
-: JNP HEX: 8b JUMPcc ;
-: JL  HEX: 8c JUMPcc ;
-: JGE HEX: 8d JUMPcc ;
-: JLE HEX: 8e JUMPcc ;
-: JG  HEX: 8f JUMPcc ;
+: JO  ( dst -- ) HEX: 80 JUMPcc ;
+: JNO ( dst -- ) HEX: 81 JUMPcc ;
+: JB  ( dst -- ) HEX: 82 JUMPcc ;
+: JAE ( dst -- ) HEX: 83 JUMPcc ;
+: JE  ( dst -- ) HEX: 84 JUMPcc ; ! aka JZ
+: JNE ( dst -- ) HEX: 85 JUMPcc ;
+: JBE ( dst -- ) HEX: 86 JUMPcc ;
+: JA  ( dst -- ) HEX: 87 JUMPcc ;
+: JS  ( dst -- ) HEX: 88 JUMPcc ;
+: JNS ( dst -- ) HEX: 89 JUMPcc ;
+: JP  ( dst -- ) HEX: 8a JUMPcc ;
+: JNP ( dst -- ) HEX: 8b JUMPcc ;
+: JL  ( dst -- ) HEX: 8c JUMPcc ;
+: JGE ( dst -- ) HEX: 8d JUMPcc ;
+: JLE ( dst -- ) HEX: 8e JUMPcc ;
+: JG  ( dst -- ) HEX: 8f JUMPcc ;
 
 : LEAVE ( -- ) HEX: c9 , ;
 
@@ -399,8 +399,8 @@ M: operand CMP OCT: 070 2-operand ;
 : DIV  ( dst -- ) { BIN: 110 t HEX: f7 } 1-operand ;
 : IDIV ( src -- ) { BIN: 111 t HEX: f7 } 1-operand ;
 
-: CDQ HEX: 99 , ;
-: CQO HEX: 48 , CDQ ;
+: CDQ ( -- ) HEX: 99 , ;
+: CQO ( -- ) HEX: 48 , CDQ ;
 
 : ROL ( dst n -- ) swap { BIN: 000 t HEX: c0 } immediate-1 ;
 : ROR ( dst n -- ) swap { BIN: 001 t HEX: c0 } immediate-1 ;
@@ -423,26 +423,26 @@ M: operand IMUL2 OCT: 257 extended-opcode (2-operand) ;
 ! Conditional move
 : MOVcc ( dst src cc -- ) extended-opcode swapd (2-operand) ;
 
-: CMOVO  HEX: 40 MOVcc ;
-: CMOVNO HEX: 41 MOVcc ;
-: CMOVB  HEX: 42 MOVcc ;
-: CMOVAE HEX: 43 MOVcc ;
-: CMOVE  HEX: 44 MOVcc ; ! aka CMOVZ
-: CMOVNE HEX: 45 MOVcc ;
-: CMOVBE HEX: 46 MOVcc ;
-: CMOVA  HEX: 47 MOVcc ;
-: CMOVS  HEX: 48 MOVcc ;
-: CMOVNS HEX: 49 MOVcc ;
-: CMOVP  HEX: 4a MOVcc ;
-: CMOVNP HEX: 4b MOVcc ;
-: CMOVL  HEX: 4c MOVcc ;
-: CMOVGE HEX: 4d MOVcc ;
-: CMOVLE HEX: 4e MOVcc ;
-: CMOVG  HEX: 4f MOVcc ;
+: CMOVO  ( dst src -- ) HEX: 40 MOVcc ;
+: CMOVNO ( dst src -- ) HEX: 41 MOVcc ;
+: CMOVB  ( dst src -- ) HEX: 42 MOVcc ;
+: CMOVAE ( dst src -- ) HEX: 43 MOVcc ;
+: CMOVE  ( dst src -- ) HEX: 44 MOVcc ; ! aka CMOVZ
+: CMOVNE ( dst src -- ) HEX: 45 MOVcc ;
+: CMOVBE ( dst src -- ) HEX: 46 MOVcc ;
+: CMOVA  ( dst src -- ) HEX: 47 MOVcc ;
+: CMOVS  ( dst src -- ) HEX: 48 MOVcc ;
+: CMOVNS ( dst src -- ) HEX: 49 MOVcc ;
+: CMOVP  ( dst src -- ) HEX: 4a MOVcc ;
+: CMOVNP ( dst src -- ) HEX: 4b MOVcc ;
+: CMOVL  ( dst src -- ) HEX: 4c MOVcc ;
+: CMOVGE ( dst src -- ) HEX: 4d MOVcc ;
+: CMOVLE ( dst src -- ) HEX: 4e MOVcc ;
+: CMOVG  ( dst src -- ) HEX: 4f MOVcc ;
 
 ! CPU Identification
 
-: CPUID HEX: a2 extended-opcode, ;
+: CPUID ( -- ) HEX: a2 extended-opcode, ;
 
 ! x87 Floating Point Unit
 
index ea4cadd51bfe5d39afc00b8165d1113884337a17..bd1b0f2871e2fbb604d9e48042c9c4a77ba7410e 100755 (executable)
@@ -60,7 +60,7 @@ big-endian off
     arg0 \ f tag-number CMP                    ! compare it with f
     arg0 arg1 [] CMOVNE                        ! load true branch if not equal
     arg0 arg1 bootstrap-cell [+] CMOVE         ! load false branch if equal
-    arg0 quot-xt@ [+] JMP                      ! jump to quotation-xt
+    arg0 quot-xt-offset [+] JMP                ! jump to quotation-xt
 ] rc-absolute-cell rt-literal 1 rex-length + jit-if-jump jit-define
 
 [
@@ -70,8 +70,8 @@ big-endian off
     fixnum>slot@                               ! turn it into an array offset
     ds-reg bootstrap-cell SUB                  ! pop index
     arg0 arg1 ADD                              ! compute quotation location
-    arg0 arg0 array-start [+] MOV              ! load quotation
-    arg0 quot-xt@ [+] JMP                      ! execute branch
+    arg0 arg0 array-start-offset [+] MOV       ! load quotation
+    arg0 quot-xt-offset [+] JMP                ! execute branch
 ] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define
 
 [
index 667f08c053a3291b2dec77df0de7e980d16098d3..0ee8a0a1d980985e26a54ef40dc02c73d56043bf 100755 (executable)
@@ -20,16 +20,16 @@ IN: cpu.x86.intrinsics
 } define-intrinsic
 
 ! Slots
-: %slot-literal-known-tag
+: %slot-literal-known-tag ( -- op )
     "obj" operand
     "n" get cells
     "obj" get operand-tag - [+] ;
 
-: %slot-literal-any-tag
+: %slot-literal-any-tag ( -- op )
     "obj" operand %untag
     "obj" operand "n" get cells [+] ;
 
-: %slot-any
+: %slot-any ( -- op )
     "obj" operand %untag
     "n" operand fixnum>slot@
     "obj" operand "n" operand [+] ;
@@ -399,15 +399,15 @@ IN: cpu.x86.intrinsics
         { +clobber+ { "offset" } }
     } ;
 
-: define-getter
+: define-getter ( word quot reg -- )
     [ %alien-integer-get ] 2curry
     alien-integer-get-template
     define-intrinsic ;
 
-: define-unsigned-getter
+: define-unsigned-getter ( word reg -- )
     [ small-reg dup XOR MOV ] swap define-getter ;
 
-: define-signed-getter
+: define-signed-getter ( word reg -- )
     [ [ >r MOV small-reg r> MOVSX ] curry ] keep define-getter ;
 
 : %alien-integer-set ( quot reg -- )
@@ -429,7 +429,7 @@ IN: cpu.x86.intrinsics
         { +clobber+ { "value" "offset" } }
     } ;
 
-: define-setter
+: define-setter ( word reg -- )
     [ swap MOV ] swap
     [ %alien-integer-set ] 2curry
     alien-integer-set-template
index 17219ba92b08375f3ddb7398afacf0ce66e91f15..cfad1447377f1dd064bbe2ac4f3f7bfc443ee14b 100755 (executable)
@@ -36,12 +36,12 @@ M: string error. print ;
 : :vars ( -- )
     error-continuation get continuation-name namestack. ;
 
-: :res ( n -- )
+: :res ( n -- )
     1- restarts get-global nth f restarts set-global restart ;
 
-: :1 1 :res ;
-: :2 2 :res ;
-: :3 3 :res ;
+: :1 ( -- * ) 1 :res ;
+: :2 ( -- * ) 2 :res ;
+: :3 ( -- * ) 3 :res ;
 
 : restart. ( restart n -- )
     [
@@ -143,15 +143,15 @@ M: relative-overflow summary
 : stack-overflow. ( obj name -- )
     write " stack overflow" print drop ;
 
-: datastack-underflow. "Data" stack-underflow. ;
-: datastack-overflow. "Data" stack-overflow. ;
-: retainstack-underflow. "Retain" stack-underflow. ;
-: retainstack-overflow. "Retain" stack-overflow. ;
+: datastack-underflow. ( obj -- ) "Data" stack-underflow. ;
+: datastack-overflow. ( obj -- ) "Data" stack-overflow. ;
+: retainstack-underflow. ( obj -- ) "Retain" stack-underflow. ;
+: retainstack-overflow. ( obj -- ) "Retain" stack-overflow. ;
 
-: memory-error.
+: memory-error. ( error -- )
     "Memory protection fault at address " write third .h ;
 
-: primitive-error.
+: primitive-error. ( error -- ) 
     "Unimplemented primitive" print drop ;
 
 PREDICATE: kernel-error < array
@@ -161,7 +161,7 @@ PREDICATE: kernel-error < array
         [ second 0 15 between? ]
     } cond ;
 
-: kernel-errors
+: kernel-errors ( error -- n errors )
     second {
         { 0  [ expired-error.          ] }
         { 1  [ io-error.               ] }
index 459512b83a29ef9e5907425c13ec2926c058b20d..0a83e43097348ca580d18c2035b450b75f8c8156 100755 (executable)
@@ -7,10 +7,21 @@ ERROR: no-compilation-unit definition ;
 
 SYMBOL: changed-definitions
 
-: changed-definition ( defspec -- )
-    dup changed-definitions get
-    [ no-compilation-unit ] unless*
-    set-at ;
+SYMBOL: +inlined+
+SYMBOL: +called+
+
+: changed-definition ( defspec how -- )
+    swap changed-definitions get
+    [ set-at ] [ no-compilation-unit ] if* ;
+
+SYMBOL: new-classes
+
+: new-class ( word -- )
+    dup new-classes get
+    [ set-at ] [ no-compilation-unit ] if* ;
+
+: new-class? ( word -- ? )
+    new-classes get key? ;
 
 GENERIC: where ( defspec -- loc )
 
@@ -47,7 +58,17 @@ M: object uses drop f ;
 
 : xref ( defspec -- ) dup uses crossref get add-vertex ;
 
-: usage ( defspec -- seq ) \ f or crossref get at keys ;
+: usage ( defspec -- seq ) crossref get at keys ;
+
+GENERIC: irrelevant? ( defspec -- ? )
+
+M: object irrelevant? drop f ;
+
+GENERIC: smart-usage ( defspec -- seq )
+
+M: f smart-usage drop \ f smart-usage ;
+
+M: object smart-usage usage [ irrelevant? not ] filter ;
 
 : unxref ( defspec -- )
     dup uses crossref get remove-vertex ;
index 9e37ba4c85d66dba99a27ac863ef3b8ee0ca7b06..66beae443f9022509d44754f97639cbe7d50c020 100644 (file)
@@ -2,7 +2,9 @@ USING: help.markup help.syntax math strings words ;
 IN: effects
 
 ARTICLE: "effect-declaration" "Stack effect declaration"
-"It is good practice to declare the stack effects of words using the following syntax:"
+"Stack effects of words must be declared, with the exception of words which only push literals on the stack."
+$nl
+"Stack effects are declared with the following syntax:"
 { $code ": sq ( x -- y ) dup * ;" }
 "A stack effect declaration is written in parentheses and lists word inputs and outputs, separated by " { $snippet "--" } ". Stack effect declarations are read in using a parsing word:"
 { $subsection POSTPONE: ( }
@@ -28,18 +30,21 @@ $nl
 ARTICLE: "effects" "Stack effects"
 "A " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that an operation takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output."
 $nl
+"Stack effects of words can be declared."
+{ $subsection "effect-declaration" }
 "Stack effects are first-class, and words for working with them are found in the " { $vocab-link "effects" } " vocabulary."
 { $subsection effect }
 { $subsection effect? }
-"Stack effects of words can be declared."
-{ $subsection "effect-declaration" }
+"There is a literal syntax for stack objects. It is most often used with " { $link define-declared } "."
+{ $subsection POSTPONE: (( }
 "Getting a word's declared stack effect:"
 { $subsection stack-effect }
 "Converting a stack effect to a string form:"
 { $subsection effect>string }
 "Comparing effects:"
 { $subsection effect-height }
-{ $subsection effect<= } ;
+{ $subsection effect<= }
+{ $see-also "inference" } ;
 
 ABOUT: "effects"
 
index 234f567f25e9fabbb9d02a11acd610ed7fc53dfc..c592ef6c92e21e7ad03fe9d6fe015b560c2a15ee 100644 (file)
@@ -1,9 +1,17 @@
 IN: effects.tests
-USING: effects tools.test ;
+USING: effects tools.test prettyprint accessors sequences ;
 
 [ t ] [ 1 1 <effect> 2 2 <effect> effect<= ] unit-test
 [ f ] [ 1 0 <effect> 2 2 <effect> effect<= ] unit-test
 [ t ] [ 2 2 <effect> 2 2 <effect> effect<= ] unit-test
 [ f ] [ 3 3 <effect> 2 2 <effect> effect<= ] unit-test
 [ f ] [ 2 3 <effect> 2 2 <effect> effect<= ] unit-test
-[ t ] [ 2 3 <effect> f effect<= ] unit-test
+[ 2 ] [ (( a b -- c )) in>> length ] unit-test
+[ 1 ] [ (( a b -- c )) out>> length ] unit-test
+
+
+[ "(( a b -- c d ))" ] [ { "a" "b" } { "c" "d" } <effect> unparse ] unit-test
+[ "(( -- c d ))" ] [ { } { "c" "d" } <effect> unparse ] unit-test
+[ "(( a b -- ))" ] [ { "a" "b" } { } <effect> unparse ] unit-test
+[ "(( -- ))" ] [ { } { } <effect> unparse ] unit-test
+[ "(( a b -- c ))" ] [ (( a b -- c )) unparse ] unit-test
index 80a4f679c012b99b7aa22779edbe20405035f3de..099260f11148fc2be72933bb937f3da4c357b441 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math namespaces sequences strings words assocs
-combinators ;
+combinators accessors ;
 IN: effects
 
 TUPLE: effect in out terminated? ;
@@ -11,14 +11,13 @@ TUPLE: effect in out terminated? ;
     effect boa ;
 
 : effect-height ( effect -- n )
-    dup effect-out length swap effect-in length - ;
+    [ out>> length ] [ in>> length ] bi - ;
 
 : effect<= ( eff1 eff2 -- ? )
     {
-        { [ dup not ] [ t ] }
-        { [ over effect-terminated? ] [ t ] }
-        { [ dup effect-terminated? ] [ f ] }
-        { [ 2dup [ effect-in length ] bi@ > ] [ f ] }
+        { [ over terminated?>> ] [ t ] }
+        { [ dup terminated?>> ] [ f ] }
+        { [ 2dup [ in>> length ] bi@ > ] [ f ] }
         { [ 2dup [ effect-height ] bi@ = not ] [ f ] }
         [ t ]
     } cond 2nip ;
@@ -34,10 +33,10 @@ M: integer (stack-picture) drop "object" ;
 : effect>string ( effect -- string )
     [
         "( " %
-        dup effect-in stack-picture %
-        "-- " %
-        dup effect-out stack-picture %
-        effect-terminated? [ "* " % ] when
+        [ in>> stack-picture % "-- " % ]
+        [ out>> stack-picture % ]
+        [ terminated?>> [ "* " % ] when ]
+        tri
         ")" %
     ] "" make ;
 
@@ -50,16 +49,16 @@ M: word stack-effect
     swap word-props [ at ] curry map [ ] find nip ;
 
 M: effect clone
-    [ effect-in clone ] keep effect-out clone <effect> ;
+    [ in>> clone ] keep effect-out clone <effect> ;
 
 : split-shuffle ( stack shuffle -- stack1 stack2 )
-    effect-in length cut* ;
+    in>> length cut* ;
 
 : load-shuffle ( stack shuffle -- )
-    effect-in [ set ] 2each ;
+    in>> [ set ] 2each ;
 
 : shuffled-values ( shuffle -- values )
-    effect-out [ get ] map ;
+    out>> [ get ] map ;
 
 : shuffle* ( stack shuffle -- newstack )
     [ [ load-shuffle ] keep shuffled-values ] with-scope ;
index b8de9c35176bb631b3ba2cdaa9e6fb37668c5e37..684c058913d3a3f6351d6909d6d884fde1d98649 100755 (executable)
@@ -72,8 +72,8 @@ GENERIC: generate-node ( node -- next )
 
 : word-dataflow ( word -- effect dataflow )
     [
-        dup "no-effect" word-prop [ no-effect ] when
-        dup "no-compile" word-prop [ no-effect ] when
+        dup "cannot-infer" word-prop [ cannot-infer-effect ] when
+        dup "no-compile" word-prop [ cannot-infer-effect ] when
         dup specialized-def over dup 2array 1array infer-quot
         finish-word
     ] with-infer ;
index c5e1ea54a63f562095cde24d5aa881d37b865d35..ded1c82ee43b1e2e7bff7c8b3cfcae36970c3abe 100755 (executable)
@@ -67,7 +67,7 @@ INSTANCE: temp-reg value
 ! A data stack location.
 TUPLE: ds-loc n class ;
 
-: <ds-loc> f ds-loc boa ;
+: <ds-loc> ( n -- loc ) f ds-loc boa ;
 
 M: ds-loc minimal-ds-loc* ds-loc-n min ;
 M: ds-loc operand-class* ds-loc-class ;
@@ -78,7 +78,7 @@ M: ds-loc live-loc?
 ! A retain stack location.
 TUPLE: rs-loc n class ;
 
-: <rs-loc> f rs-loc boa ;
+: <rs-loc> ( n -- loc ) f rs-loc boa ;
 M: rs-loc operand-class* rs-loc-class ;
 M: rs-loc set-operand-class set-rs-loc-class ;
 M: rs-loc live-loc?
@@ -177,7 +177,7 @@ INSTANCE: constant value
 <PRIVATE
 
 ! Moving values between locations and registers
-: %move-bug "Bug in generator.registers" throw ;
+: %move-bug ( -- * ) "Bug in generator.registers" throw ;
 
 : %unbox-c-ptr ( dst src -- )
     dup operand-class {
@@ -231,7 +231,7 @@ GENERIC: finalize-height ( stack -- )
 : new-phantom-stack ( class -- stack )
     >r 0 V{ } clone r> boa ; inline
 
-: (loc)
+: (loc) ( m stack -- n )
     #! Utility for methods on <loc>
     height>> - ;
 
index 600f422274ed19a67549f9c40bb941c862781854..9d968a3a98427febe689ddb3f37d6f3804c5420a 100755 (executable)
@@ -156,7 +156,7 @@ M: integer generic-forget-test-1 / ;
     [ word-name "generic-forget-test-1/integer" = ] contains?
 ] unit-test
 
-GENERIC: generic-forget-test-2
+GENERIC: generic-forget-test-2 ( a b -- c )
 
 M: sequence generic-forget-test-2 = ;
 
@@ -174,7 +174,7 @@ M: sequence generic-forget-test-2 = ;
     [ word-name "generic-forget-test-2/sequence" = ] contains?
 ] unit-test
 
-GENERIC: generic-forget-test-3
+GENERIC: generic-forget-test-3 ( a -- b )
 
 M: f generic-forget-test-3 ;
 
index b9a556e316298e127868bb4be6ba01155275ea08..fb9820008a575abef8584fc07a5c4f3e7ff98c0c 100755 (executable)
@@ -56,8 +56,19 @@ TUPLE: check-method class generic ;
         \ check-method boa throw
     ] unless ; inline
 
-: with-methods ( generic quot -- )
-    swap [ "methods" word-prop swap call ] keep make-generic ;
+: affected-methods ( class generic -- seq )
+    "methods" word-prop swap
+    [ nip classes-intersect? ] curry assoc-filter
+    values ;
+
+: update-generic ( class generic -- )
+    [ affected-methods [ +called+ changed-definition ] each ]
+    [ make-generic ]
+    bi ;
+
+: with-methods ( class generic quot -- )
+    [ [ "methods" word-prop ] dip call ]
+    [ drop update-generic ] 3bi ;
     inline
 
 : method-word-name ( class word -- string )
@@ -117,6 +128,9 @@ M: method-spec definition
 M: method-spec forget*
     first2 method forget* ;
 
+M: method-spec smart-usage
+    second smart-usage ;
+
 M: method-body definer
     drop \ M: \ ; ;
 
@@ -134,15 +148,20 @@ M: method-body forget*
         [ t "forgotten" set-word-prop ] bi
     ] if ;
 
-: implementors* ( classes -- words )
+M: method-body smart-usage
+    "method-generic" word-prop smart-usage ;
+
+GENERIC: implementors ( class/classes -- seq )
+
+M: class implementors
+    all-words [ "methods" word-prop key? ] with filter ;
+
+M: assoc implementors
     all-words [
-        "methods" word-prop keys
+         "methods" word-prop keys
         swap [ key? ] curry contains?
     ] with filter ;
 
-: implementors ( class -- seq )
-    dup associate implementors* ;
-
 : forget-methods ( class -- )
     [ implementors ] [ [ swap 2array ] curry ] bi map forget-all ;
 
@@ -158,8 +177,8 @@ M: class forget* ( class -- )
     ]
     [ call-next-method ] bi ;
 
-M: assoc update-methods ( assoc -- )
-    implementors* [ make-generic ] each ;
+M: assoc update-methods ( class assoc -- )
+    implementors [ update-generic ] with each ;
 
 : define-generic ( word combination -- )
     over "combination" word-prop over = [
index 6344bec5360f96a11b6ba5e46d8c45e6ecc452ca..c1e72a65deaf0c080cfa64676ad551594cda20ee 100644 (file)
@@ -38,7 +38,7 @@ C: <hi-tag-dispatch-engine> hi-tag-dispatch-engine
     \ hi-tag bootstrap-word
     \ <hi-tag-dispatch-engine> convert-methods ;
 
-: num-hi-tags num-types get num-tags get - ;
+: num-hi-tags ( -- n ) num-types get num-tags get - ;
 
 : hi-tag-number ( class -- n )
     "type" word-prop num-tags get - ;
index 51ea4f8225cec8c64eb22f1294bfbf6659a728a8..9a780383b5c2d3278cc13c5d90b0dd6d52e88674 100644 (file)
@@ -4,7 +4,7 @@ USING: kernel classes.tuple.private hashtables assocs sorting
 accessors combinators sequences slots.private math.parser words
 effects namespaces generic generic.standard.engines
 classes.algebra math math.private kernel.private
-quotations arrays ;
+quotations arrays definitions ;
 IN: generic.standard.engines.tuple
 
 TUPLE: echelon-dispatch-engine n methods ;
@@ -44,7 +44,7 @@ M: trivial-tuple-dispatch-engine engine>quot
     >alist V{ } clone [ hashcode 1array ] distribute-buckets
     [ <trivial-tuple-dispatch-engine> ] map ;
 
-: word-hashcode% [ 1 slot ] % ;
+: word-hashcode% ( -- ) [ 1 slot ] % ;
 
 : class-hash-dispatch-quot ( methods -- quot )
     [
@@ -64,8 +64,9 @@ M: engine-word stack-effect
     [ extra-values ] [ stack-effect ] bi
     dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
 
-M: engine-word compiled-crossref?
-    drop t ;
+M: engine-word crossref? drop t ;
+
+M: engine-word irrelevant? drop t ;
 
 : remember-engine ( word -- )
     generic get "engines" word-prop push ;
@@ -77,7 +78,7 @@ M: engine-word compiled-crossref?
 : define-engine-word ( quot -- word )
     >r <engine-word> dup r> define ;
 
-: array-nth% 2 + , [ slot { word } declare ] % ;
+: array-nth% ( n -- ) 2 + , [ slot { word } declare ] % ;
 
 : tuple-layout-superclasses ( obj -- array )
     { tuple } declare
index 1bff9ae15d716260360639e03b8bb4e96b0aa7fe..93956fec00bf234a0b472c0e0500c1a1a5e57ae0 100644 (file)
@@ -3,9 +3,10 @@ USING: tools.test math math.functions math.constants
 generic.standard strings sequences arrays kernel accessors
 words float-arrays byte-arrays bit-arrays parser namespaces
 quotations inference vectors growable hashtables sbufs
-prettyprint byte-vectors bit-vectors float-vectors ;
+prettyprint byte-vectors bit-vectors float-vectors definitions
+generic sets graphs assocs ;
 
-GENERIC: lo-tag-test
+GENERIC: lo-tag-test ( obj -- obj' )
 
 M: integer lo-tag-test 3 + ;
 
@@ -20,7 +21,7 @@ M: complex lo-tag-test sq ;
 [ -1/2 ] [ 1+1/2 lo-tag-test ] unit-test
 [ -16 ] [ C{ 0 4 } lo-tag-test ] unit-test
 
-GENERIC: hi-tag-test
+GENERIC: hi-tag-test ( obj -- obj' )
 
 M: string hi-tag-test ", in bed" append ;
 
@@ -52,7 +53,7 @@ TUPLE: circle < shape radius ;
 
 C: <circle> circle
 
-GENERIC: area
+GENERIC: area ( shape -- n )
 
 M: abstract-rectangle area [ width>> ] [ height>> ] bi * ;
 
@@ -62,15 +63,15 @@ M: circle area radius>> sq pi * ;
 [ 12 ] [ 4 3 2 <parallelogram> area ] unit-test
 [ t ] [ 2 <circle> area 4 pi * = ] unit-test
 
-GENERIC: perimiter
+GENERIC: perimiter ( shape -- n )
 
-: rectangle-perimiter + 2 * ;
+: rectangle-perimiter ( n -- n ) + 2 * ;
 
 M: rectangle perimiter
     [ width>> ] [ height>> ] bi
     rectangle-perimiter ;
 
-: hypotenuse [ sq ] bi@ + sqrt ;
+: hypotenuse ( a b -- c ) [ sq ] bi@ + sqrt ;
 
 M: parallelogram perimiter
     [ width>> ]
@@ -82,7 +83,7 @@ M: circle perimiter 2 * pi * ;
 [ 14 ] [ 4 3 <rectangle> perimiter ] unit-test
 [ 30 ] [ 10 4 3 <parallelogram> perimiter ] unit-test
 
-GENERIC: big-mix-test
+GENERIC: big-mix-test ( obj -- obj' )
 
 M: object big-mix-test drop "object" ;
 
@@ -124,7 +125,7 @@ M: circle big-mix-test drop "circle" ;
 [ "tuple" ] [ H{ } big-mix-test ] unit-test
 [ "object" ] [ \ + big-mix-test ] unit-test
 
-GENERIC: small-lo-tag
+GENERIC: small-lo-tag ( obj -- obj )
 
 M: fixnum small-lo-tag drop "fixnum" ;
 
@@ -225,7 +226,7 @@ M: b funky* "b" , call-next-method ;
 
 M: c funky* "c" , call-next-method ;
 
-: funky [ funky* ] { } make ;
+: funky ( obj -- seq ) [ funky* ] { } make ;
 
 [ { "b" "x" "z" } ] [ T{ b } funky ] unit-test
 
@@ -287,3 +288,24 @@ M: sbuf no-stack-effect-decl ;
 [ ] [ \ no-stack-effect-decl see ] unit-test
 
 [ ] [ \ no-stack-effect-decl word-def . ] unit-test
+
+! Cross-referencing with generic words
+TUPLE: xref-tuple-1 ;
+TUPLE: xref-tuple-2 < xref-tuple-1 ;
+
+: (xref-test) ( obj -- ) drop ;
+
+GENERIC: xref-test ( obj -- )
+
+M: xref-tuple-1 xref-test (xref-test) ;
+M: xref-tuple-2 xref-test (xref-test) ;
+
+[ t ] [
+    \ xref-test
+    \ xref-tuple-1 \ xref-test method [ usage unique ] closure key?
+] unit-test
+
+[ t ] [
+    \ xref-test
+    \ xref-tuple-2 \ xref-test method [ usage unique ] closure key?
+] unit-test
index 98194e7ef3026fa29a92b77acfb79f0b8c7fe283..f58d016c222e9ee9561825fbc215f9b285324d6e 100644 (file)
@@ -81,14 +81,8 @@ ERROR: no-method object generic ;
                 "methods" word-prop
                 [ generic get mangle-method ] assoc-map
                 [ find-default default set ]
-                [
-                    generic get "inline" word-prop [
-                        <predicate-dispatch-engine>
-                    ] [
-                        <big-dispatch-engine>
-                    ] if
-                ] bi
-                engine>quot
+                [ <big-dispatch-engine> ]
+                bi engine>quot
             ]
         } cleave
     ] with-scope ;
diff --git a/core/grouping/authors.txt b/core/grouping/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/core/grouping/grouping-docs.factor b/core/grouping/grouping-docs.factor
new file mode 100644 (file)
index 0000000..894412d
--- /dev/null
@@ -0,0 +1,100 @@
+USING: help.markup help.syntax sequences strings ;
+IN: grouping
+
+ARTICLE: "grouping" "Groups and clumps"
+"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
+{ $subsection groups }
+{ $subsection <groups> }
+{ $subsection <sliced-groups> }
+"A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
+{ $subsection clumps }
+{ $subsection <clumps> }
+{ $subsection <sliced-clumps> }
+"The difference can be summarized as the following:"
+{ $list
+    { "With groups, the subsequences form the original sequence when concatenated:"
+        { $unchecked-example "dup n groups concat sequence= ." "t" }
+    }
+    { "With clumps, collecting the first element of each subsequence but the last one, together with the last subseqence, yields the original sequence:"
+        { $unchecked-example "dup n clumps unclip-last >r [ first ] map r> append sequence= ." "t" }
+    }
+} ;
+
+ABOUT: "grouping"
+
+HELP: groups
+{ $class-description "Instances are virtual sequences whose elements are disjoint fixed-length subsequences of an underlying sequence. Groups are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
+$nl
+"New groups are created by calling " { $link <groups> } " and " { $link <sliced-groups> } "." }
+{ $see-also group } ;
+
+HELP: group
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
+{ $description "Splits the sequence into disjoint groups of " { $snippet "n" } " elements and collects the groups into a new array." }
+{ $notes "If the sequence length is not a multiple of " { $snippet "n" } ", the final subsequence in the list will be shorter than " { $snippet "n" } " elements." }
+{ $examples
+    { $example "USING: splitting prettyprint ;" "{ 3 1 3 3 7 } 2 group ." "{ { 3 1 } { 3 3 } { 7 } }" }
+} ;
+
+HELP: <groups>
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "groups" groups } }
+{ $description "Outputs a virtual sequence whose elements are disjoint subsequences of " { $snippet "n" } " elements from the underlying sequence." }
+{ $examples
+    { $example
+        "USING: arrays kernel prettyprint sequences splitting ;"
+        "9 >array 3 <groups> dup reverse-here concat >array ." "{ 6 7 8 3 4 5 0 1 2 }"
+    }
+} ;
+
+HELP: <sliced-groups>
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "groups" groups } }
+{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
+{ $examples
+    { $example
+        "USING: arrays kernel prettyprint sequences splitting ;"
+        "9 >array 3 <sliced-groups>"
+        "dup [ reverse-here ] each concat >array ."
+        "{ 2 1 0 5 4 3 8 7 6 }"
+    }
+} ;
+
+HELP: clumps
+{ $class-description "Instances are virtual sequences whose elements are overlapping fixed-length subsequences o an underlying sequence. Clumps are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
+$nl
+"New clumps are created by calling " { $link <clumps> } " and " { $link <sliced-clumps> } "." } ;
+
+HELP: clump
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
+{ $description "Splits the sequence into overlapping clumps of " { $snippet "n" } " elements and collects the clumps into a new array." }
+{ $errors "Throws an error if " { $snippet "n" } " is smaller than the length of the sequence." }
+{ $examples
+    { $example "USING: splitting prettyprint ;" "{ 3 1 3 3 7 } 2 clump ." "{ { 3 1 } { 1 3 } { 3 3 } { 3 7 } }" }
+} ;
+
+HELP: <clumps>
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
+{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
+{ $examples
+    "Running averages:"
+    { $example
+        "USING: splitting sequences math prettyprint kernel ;"
+        "IN: scratchpad"
+        ": share-price"
+        "    { 13/50 51/100 13/50 1/10 4/5 17/20 33/50 3/25 19/100 3/100 } ;"
+        ""
+        "share-price 4 <clumps> [ [ sum ] [ length ] bi / ] map ."
+        "{ 113/400 167/400 201/400 241/400 243/400 91/200 1/4 }"
+    }
+} ;
+
+HELP: <sliced-clumps>
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
+{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence." } ;
+
+{ clumps groups } related-words
+
+{ clump group } related-words
+
+{ <clumps> <groups> } related-words
+
+{ <sliced-clumps> <sliced-groups> } related-words
diff --git a/core/grouping/grouping-tests.factor b/core/grouping/grouping-tests.factor
new file mode 100644 (file)
index 0000000..dcf62e1
--- /dev/null
@@ -0,0 +1,12 @@
+USING: grouping tools.test kernel sequences arrays ;
+IN: grouping.tests
+
+[ { 1 2 3 } 0 group ] must-fail
+
+[ { "hell" "o wo" "rld" } ] [ "hello world" 4 group ] unit-test
+
+[ { V{ "a" "b" } V{ f f } } ] [
+    V{ "a" "b" } clone 2 <groups>
+    2 over set-length
+    >array
+] unit-test
diff --git a/core/grouping/grouping.factor b/core/grouping/grouping.factor
new file mode 100644 (file)
index 0000000..c12d431
--- /dev/null
@@ -0,0 +1,68 @@
+! Copyright (C) 2005, 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.order strings arrays vectors sequences
+accessors ;
+IN: grouping
+
+TUPLE: abstract-groups seq n ;
+
+: check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
+
+: new-groups ( seq n class -- groups )
+    >r check-groups r> boa ; inline
+
+GENERIC: group@ ( n groups -- from to seq )
+
+M: abstract-groups nth group@ subseq ;
+
+M: abstract-groups set-nth group@ <slice> 0 swap copy ;
+
+M: abstract-groups like drop { } like ;
+
+INSTANCE: abstract-groups sequence
+
+TUPLE: groups < abstract-groups ;
+
+: <groups> ( seq n -- groups )
+    groups new-groups ; inline
+
+M: groups length
+    [ seq>> length ] [ n>> ] bi [ + 1- ] keep /i ;
+
+M: groups set-length
+    [ n>> * ] [ seq>> ] bi set-length ;
+
+M: groups group@
+    [ n>> [ * dup ] keep + ] [ seq>> ] bi [ length min ] keep ;
+
+TUPLE: sliced-groups < groups ;
+
+: <sliced-groups> ( seq n -- groups )
+    sliced-groups new-groups ; inline
+
+M: sliced-groups nth group@ <slice> ;
+
+TUPLE: clumps < abstract-groups ;
+
+: <clumps> ( seq n -- clumps )
+    clumps new-groups ; inline
+
+M: clumps length
+    [ seq>> length ] [ n>> ] bi - 1+ ;
+
+M: clumps set-length
+    [ n>> + 1- ] [ seq>> ] bi set-length ;
+
+M: clumps group@
+    [ n>> over + ] [ seq>> ] bi ;
+
+TUPLE: sliced-clumps < groups ;
+
+: <sliced-clumps> ( seq n -- clumps )
+    sliced-clumps new-groups ; inline
+
+M: sliced-clumps nth group@ <slice> ;
+
+: group ( seq n -- array ) <groups> { } like ;
+
+: clump ( seq n -- array ) <clumps> { } like ;
diff --git a/core/grouping/summary.txt b/core/grouping/summary.txt
new file mode 100644 (file)
index 0000000..3695129
--- /dev/null
@@ -0,0 +1 @@
+Grouping sequence elements into subsequences
diff --git a/core/grouping/tags.txt b/core/grouping/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index aff59ee8a5f08ce495efd6c5ece13bf8a63bfdce..e3b21e629e3b11109907b6c8010cdfba8e581725 100755 (executable)
@@ -10,9 +10,7 @@ $nl
 $nl
 "The " { $link hash-count } " slot is the number of entries including deleted entries, and " { $link hash-deleted } " is the number of deleted entries."
 { $subsection <hash-array> }
-{ $subsection nth-pair }
 { $subsection set-nth-pair }
-{ $subsection find-pair }
 "If a hashtable's keys are mutated, or if hashing algorithms change, hashtables can be rehashed:"
 { $subsection rehash } ;
 
@@ -74,24 +72,12 @@ HELP: new-key@
 { $values { "key" "a key" } { "hash" hashtable } { "array" "the underlying array of the hashtable" } { "n" "the index where the key would be stored" } { "empty?" "a boolean indicating whether the location is currently empty" } }
 { $description "Searches the hashtable for the key using a linear probing strategy. If the key is not present in the hashtable, outputs the index where it should be stored." } ;
 
-HELP: nth-pair
-{ $values { "n" "an index in the sequence" } { "seq" "a sequence" } { "key" "the first element of the pair" } { "value" "the second element of the pair" } }
-{ $description "Fetches the elements with index " { $snippet "n" } " and " { $snippet "n+1" } ", respectively." }
-{ $warning "This word is in the " { $vocab-link "hashtables.private" } " vocabulary because it does not perform bounds checks." } ;
-
-{ nth-pair set-nth-pair } related-words
-
 HELP: set-nth-pair
 { $values { "value" "the second element of the pair" } { "key" "the first element of the pair" } { "seq" "a sequence" } { "n" "an index in the sequence" } }
 { $description "Stores a pair of values into the elements with index " { $snippet "n" } " and " { $snippet "n+1" } ", respectively." }
 { $warning "This word is in the " { $vocab-link "hashtables.private" } " vocabulary because it does not perform bounds checks." }
 { $side-effects "seq" } ;
 
-HELP: find-pair
-{ $values { "array" "an array of pairs" } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "key" "the successful key" } { "value" "the successful value" } { "?" "a boolean of whether there was success" } }
-{ $description "Applies a quotation to successive pairs in the array, yielding the first successful pair." }
-{ $warning "This word is in the " { $vocab-link "hashtables.private" } " vocabulary because passing an array of odd length can lead to memory corruption." } ;
-
 HELP: reset-hash
 { $values { "n" "a positive integer specifying hashtable capacity" } { "hash" hashtable } }
 { $description "Resets the underlying array of the hashtable to a new array with the given capacity. Removes all entries from the hashtable." }
index ea2f67255c02df70a27af3cf1de7025d71f2cf97..a1dba07fb0dc57712f8f6db44a894d612b6a3241 100755 (executable)
@@ -1,7 +1,7 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel kernel.private slots.private math assocs
-       math.private sequences sequences.private vectors ;
+math.private sequences sequences.private vectors grouping ;
 IN: hashtables
 
 <PRIVATE
@@ -48,10 +48,6 @@ IN: hashtables
 : new-key@ ( key hash -- array n empty? )
     hash-array 2dup hash@ (new-key@) ; inline
 
-: nth-pair ( n seq -- key value )
-    swap 2 fixnum+fast 2dup slot -rot 1 fixnum+fast slot ;
-    inline
-
 : set-nth-pair ( value key seq n -- )
     2 fixnum+fast [ set-slot ] 2keep
     1 fixnum+fast set-slot ; inline
@@ -67,28 +63,8 @@ IN: hashtables
     [ rot hash-count+ set-nth-pair t ]
     [ rot drop set-nth-pair f ] if ; inline
 
-: find-pair-next >r 2 fixnum+fast r> ; inline
-
-: (find-pair) ( quot i array -- key value ? )
-    2dup array-capacity eq? [
-        3drop f f f
-    ] [
-        2dup array-nth tombstone? [
-            find-pair-next (find-pair)
-        ] [
-            [ nth-pair rot call ] 3keep roll [
-                nth-pair >r nip r> t
-            ] [
-                find-pair-next (find-pair)
-            ] if
-        ] if
-    ] if ; inline
-
-: find-pair ( array quot -- key value ? )
-    0 rot (find-pair) ; inline
-
-: (rehash) ( hash array -- )
-    [ swap pick (set-hash) drop f ] find-pair 2drop 2drop ;
+: (rehash) ( hash alist -- )
+    swap [ swapd (set-hash) drop ] curry assoc-each ;
 
 : hash-large? ( hash -- ? )
     [ hash-count 3 fixnum*fast  ]
@@ -98,7 +74,7 @@ IN: hashtables
     [ hash-deleted 10 fixnum*fast ] [ hash-count ] bi fixnum> ;
 
 : grow-hash ( hash -- )
-    [ dup hash-array swap assoc-size 1+ ] keep
+    [ dup >alist swap assoc-size 1+ ] keep
     [ reset-hash ] keep
     swap (rehash) ;
 
@@ -136,8 +112,8 @@ M: hashtable assoc-size ( hash -- n )
     dup hash-count swap hash-deleted - ;
 
 : rehash ( hash -- )
-    dup hash-array
-    dup length ((empty)) <array> pick set-hash-array
+    dup >alist
+    over hash-array length ((empty)) <array> pick set-hash-array
     0 pick set-hash-count
     0 pick set-hash-deleted
     (rehash) ;
@@ -148,8 +124,8 @@ M: hashtable set-at ( value key hash -- )
 : associate ( value key -- hash )
     2 <hashtable> [ set-at ] keep ;
 
-M: hashtable assoc-find ( hash quot -- key value ? )
-    >r hash-array r> find-pair ;
+M: hashtable >alist
+    hash-array 2 <groups> [ first tombstone? not ] filter ;
 
 M: hashtable clone
     (clone) dup hash-array clone over set-hash-array ;
index 91314d13120121507fb12027bd32ed28885520eb..2fd867f442cb102c87f0f6e6859a2b8ea41c23cd 100755 (executable)
@@ -43,9 +43,9 @@ HELP: consume/produce
 { $values { "node" "a dataflow node" } { "effect" "an instance of " { $link effect } } }
 { $description "Adds a node to the dataflow graph that calls " { $snippet "word" } " with a stack effect of " { $snippet "effect" } "." } ;
 
-HELP: no-effect
+HELP: cannot-infer-effect
 { $values { "word" word } }
-{ $description "Throws a " { $link no-effect } " error." }
+{ $description "Throws a " { $link cannot-infer-effect } " error." }
 { $error-description "Thrown when inference encounters a call to a word which is already known not to have a static stack effect, due to a prior inference attempt failing." } ;
 
 HELP: inline-word
@@ -61,8 +61,8 @@ HELP: effect-error
 { $description "Throws an " { $link effect-error } "." }
 { $error-description "Thrown when a word's inferred stack effect does not match its declared stack effect." } ;
 
-HELP: recursive-declare-error
-{ $error-description "Thrown when inference encounters a recursive call to a word lacking a stack effect declaration. Recursive words must declare a stack effect in order to compile. Due to implementation detail, generic words are recursive, and thus the same restriction applies." } ;
+HELP: missing-effect
+{ $error-description "Thrown when inference encounters a word lacking a stack effect declaration. Stack effects of words must be declared, with the exception of words which only push literals on the stack." } ;
 
 HELP: recursive-quotation-error
 { $error-description "Thrown when a quotation calls itself, directly or indirectly, within the same word. Stack effect inference becomes equivalent to the halting problem if quotation recursion has to be taken into account, hence it is not permitted." }
index c49e7fda8ab19642513e1825f2a5c010be5653ce..080e77af02a30432467c2df278492a098d838f0a 100755 (executable)
@@ -4,7 +4,7 @@ USING: inference.dataflow inference.state arrays generic io
 io.streams.string kernel math namespaces parser prettyprint
 sequences strings vectors words quotations effects classes
 continuations debugger assocs combinators compiler.errors
-generic.standard.engines.tuple accessors math.order ;
+generic.standard.engines.tuple accessors math.order definitions ;
 IN: inference.backend
 
 : recursive-label ( word -- label/f )
@@ -21,6 +21,28 @@ M: engine-word inline?
 M: word inline?
     "inline" word-prop ;
 
+SYMBOL: visited
+
+: reset-on-redefine { "inferred-effect" "cannot-infer" } ; inline
+
+: (redefined) ( word -- )
+    dup visited get key? [ drop ] [
+        [ reset-on-redefine reset-props ]
+        [ dup visited get set-at ]
+        [
+            crossref get at keys
+            [ word? ] filter
+            [
+                [ reset-on-redefine [ word-prop ] with contains? ]
+                [ inline? ]
+                bi or
+            ] filter
+            [ (redefined) ] each
+        ] tri
+    ] if ;
+
+M: word redefined H{ } clone visited [ (redefined) ] with-variable ;
+
 : local-recursive-state ( -- assoc )
     recursive-state get dup keys
     [ dup word? [ inline? ] when not ] find drop
@@ -68,8 +90,9 @@ M: object value-literal \ literal-expected inference-warning ;
     meta-d [ add-inputs ] change d-in [ + ] change ;
 
 : current-effect ( -- effect )
-    d-in get meta-d get length <effect>
-    terminated? get over set-effect-terminated? ;
+    d-in get
+    meta-d get length <effect>
+    terminated? get >>terminated? ;
 
 : init-inference ( -- )
     terminated? off
@@ -93,13 +116,13 @@ M: wrapper apply-object
     terminated? on #terminate node, ;
 
 : infer-quot ( quot rstate -- )
-    recursive-state get >r
-    recursive-state set
-    [ apply-object terminated? get not ] all? drop
-    r> recursive-state set ;
+    recursive-state get [
+        recursive-state set
+        [ apply-object terminated? get not ] all? drop
+    ] dip recursive-state set ;
 
 : infer-quot-recursive ( quot word label -- )
-    recursive-state get -rot 2array prefix infer-quot ;
+    2array recursive-state get swap prefix infer-quot ;
 
 : time-bomb ( error -- )
     [ throw ] curry recursive-state get infer-quot ;
@@ -114,9 +137,9 @@ TUPLE: recursive-quotation-error quot ;
         value-literal recursive-quotation-error inference-error
     ] [
         dup value-literal callable? [
-            dup value-literal
-            over value-recursion
-            rot f 2array prefix infer-quot
+            [ value-literal ]
+            [ [ value-recursion ] keep f 2array prefix ]
+            bi infer-quot
         ] [
             drop bad-call
         ] if
@@ -169,26 +192,26 @@ TUPLE: too-many-r> ;
     meta-d get push-all ;
 
 : if-inline ( word true false -- )
-    >r >r dup inline? r> r> if ; inline
+    [ dup inline? ] 2dip if ; inline
 
 : consume/produce ( effect node -- )
-    over effect-in over consume-values
-    over effect-out over produce-values
-    node,
-    effect-terminated? [ terminate ] when ;
+    [ [ in>> ] dip consume-values ]
+    [ [ out>> ] dip produce-values ]
+    [ node, terminated?>> [ terminate ] when ]
+    2tri ;
 
 GENERIC: constructor ( value -- word/f )
 
 GENERIC: infer-uncurry ( value -- )
 
 M: curried infer-uncurry
-    drop pop-d dup curried-obj push-d curried-quot push-d ;
+    drop pop-d [ obj>> push-d ] [ quot>> push-d ] bi ;
 
 M: curried constructor
     drop \ curry ;
 
 M: composed infer-uncurry
-    drop pop-d dup composed-quot1 push-d composed-quot2 push-d ;
+    drop pop-d [ quot1>> push-d ] [ quot2>> push-d ] bi ;
 
 M: composed constructor
     drop \ compose ;
@@ -233,13 +256,13 @@ M: object constructor drop f ;
 DEFER: unify-values
 
 : unify-curries ( seq -- value )
-    dup [ curried-obj ] map unify-values
-    swap [ curried-quot ] map unify-values
+    [ [ obj>> ] map unify-values ]
+    [ [ quot>> ] map unify-values ] bi
     <curried> ;
 
 : unify-composed ( seq -- value )
-    dup [ composed-quot1 ] map unify-values
-    swap [ composed-quot2 ] map unify-values
+    [ [ quot1>> ] map unify-values ]
+    [ [ quot2>> ] map unify-values ] bi
     <composed> ;
 
 TUPLE: cannot-unify-specials ;
@@ -270,7 +293,7 @@ TUPLE: unbalanced-branches-error quots in out ;
 
 : unify-inputs ( max-d-in d-in meta-d -- meta-d )
     dup [
-        [ >r - r> length + ] keep add-inputs nip
+        [ [ - ] dip length + ] keep add-inputs nip
     ] [
         2nip
     ] if ;
@@ -296,21 +319,24 @@ TUPLE: unbalanced-branches-error quots in out ;
     [ swap at ] curry map ;
 
 : datastack-effect ( seq -- )
-    dup quotation branch-variable
-    over d-in branch-variable
-    rot meta-d active-variable
-    unify-effect meta-d set d-in set ;
+    [ quotation branch-variable ]
+    [ d-in branch-variable ]
+    [ meta-d active-variable ] tri
+    unify-effect
+    [ d-in set ] [ meta-d set ] bi* ;
 
 : retainstack-effect ( seq -- )
-    dup quotation branch-variable
-    over length 0 <repetition>
-    rot meta-r active-variable
-    unify-effect meta-r set drop ;
+    [ quotation branch-variable ]
+    [ length 0 <repetition> ]
+    [ meta-r active-variable ] tri
+    unify-effect
+    [ drop ] [ meta-r set ] bi* ;
 
 : unify-effects ( seq -- )
-    dup datastack-effect
-    dup retainstack-effect
-    [ terminated? swap at ] all? terminated? set ;
+    [ datastack-effect ]
+    [ retainstack-effect ]
+    [ [ terminated? swap at ] all? terminated? set ]
+    tri ;
 
 : unify-dataflow ( effects -- nodes )
     dataflow-graph branch-variable ;
@@ -325,14 +351,17 @@ TUPLE: unbalanced-branches-error quots in out ;
 : infer-branch ( last value -- namespace )
     [
         copy-inference
-        dup value-literal quotation set
-        infer-quot-value
+
+        [ value-literal quotation set ]
+        [ infer-quot-value ]
+        bi
+
         terminated? get [ drop ] [ call node, ] if
     ] H{ } make-assoc ; inline
 
 : (infer-branches) ( last branches -- list )
     [ infer-branch ] with map
-    dup unify-effects unify-dataflow ; inline
+    [ unify-effects ] [ unify-dataflow ] bi ; inline
 
 : infer-branches ( last branches node -- )
     #! last is a quotation which provides a #return or a #values
@@ -353,24 +382,43 @@ TUPLE: unbalanced-branches-error quots in out ;
         #call consume/produce
     ] if ;
 
-TUPLE: no-effect word ;
+TUPLE: cannot-infer-effect word ;
 
-: no-effect ( word -- * ) \ no-effect inference-warning ;
+: cannot-infer-effect ( word -- * )
+    \ cannot-infer-effect inference-warning ;
 
-TUPLE: effect-error word effect ;
+TUPLE: effect-error word inferred declared ;
 
-: effect-error ( word effect -- * )
+: effect-error ( word inferred declared -- * )
     \ effect-error inference-error ;
 
+TUPLE: missing-effect word ;
+
+: effect-required? ( word -- ? )
+    {
+        { [ dup inline? ] [ drop f ] }
+        { [ dup deferred? ] [ drop f ] }
+        { [ dup crossref? not ] [ drop f ] }
+        [ word-def [ [ word? ] [ primitive? not ] bi and ] contains? ]
+    } cond ;
+
+: ?missing-effect ( word -- )
+    dup effect-required?
+    [ missing-effect inference-error ] [ drop ] if ;
+
 : check-effect ( word effect -- )
-    dup pick stack-effect effect<=
-    [ 2drop ] [ effect-error ] if ;
+    over stack-effect {
+        { [ dup not ] [ 2drop ?missing-effect ] }
+        { [ 2dup effect<= ] [ 3drop ] }
+        [ effect-error ]
+    } cond ;
 
 : finish-word ( word -- )
     current-effect
-    2dup check-effect
-    over recorded get push
-    "inferred-effect" set-word-prop ;
+    [ check-effect ]
+    [ drop recorded get push ]
+    [ "inferred-effect" set-word-prop ]
+    2tri ;
 
 : infer-word ( word -- effect )
     [
@@ -382,12 +430,11 @@ TUPLE: effect-error word effect ;
             finish-word
             current-effect
         ] with-scope
-    ] [ ] [ t "no-effect" set-word-prop ] cleanup ;
+    ] [ ] [ t "cannot-infer" set-word-prop ] cleanup ;
 
 : custom-infer ( word -- )
     #! Customized inference behavior
-    dup +inlined+ depends-on
-    "infer" word-prop call ;
+    [ +inlined+ depends-on ] [ "infer" word-prop call ] bi ;
 
 : cached-infer ( word -- )
     dup "inferred-effect" word-prop make-call-node ;
@@ -395,18 +442,16 @@ TUPLE: effect-error word effect ;
 : apply-word ( word -- )
     {
         { [ dup "infer" word-prop ] [ custom-infer ] }
-        { [ dup "no-effect" word-prop ] [ no-effect ] }
+        { [ dup "cannot-infer" word-prop ] [ cannot-infer-effect ] }
         { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
         [ dup infer-word make-call-node ]
     } cond ;
 
-TUPLE: recursive-declare-error word ;
-
-: declared-infer ( word -- )
+: declared-infer ( word -- )                       
     dup stack-effect [
         make-call-node
     ] [
-        \ recursive-declare-error inference-error
+        \ missing-effect inference-error
     ] if* ;
 
 GENERIC: collect-label-info* ( label node -- )
@@ -434,47 +479,67 @@ M: #return collect-label-info*
     dup node-param #return node,
     dataflow-graph get 1array over set-node-children ;
 
-: inlined-block? "inlined-block" word-prop ;
+: inlined-block? ( word -- ? )
+    "inlined-block" word-prop ;
 
-: <inlined-block> gensym dup t "inlined-block" set-word-prop ;
+: <inlined-block> ( -- word )
+    gensym dup t "inlined-block" set-word-prop ;
 
 : inline-block ( word -- #label data )
     [
         copy-inference nest-node
-        dup word-def swap <inlined-block>
+        [ word-def ] [ <inlined-block> ] bi
         [ infer-quot-recursive ] 2keep
         #label unnest-node
         dup collect-label-info
     ] H{ } make-assoc ;
 
 : join-values ( #label -- )
-    calls>> [ node-in-d ] map meta-d get suffix
+    calls>> [ in-d>> ] map meta-d get suffix
     unify-lengths unify-stacks
     meta-d [ length tail* ] change ;
 
 : splice-node ( node -- )
-    dup node-successor [
-        dup node, penultimate-node f over set-node-successor
-        dup current-node set
-    ] when drop ;
-
-: apply-infer ( hash -- )
-    { meta-d meta-r d-in terminated? }
-    [ swap [ at ] curry map ] keep
-    [ set ] 2each ;
+    dup successor>> [
+        [ node, ] [ penultimate-node ] bi
+        f >>successor
+        current-node set
+    ] [ drop ] if ;
+
+: apply-infer ( data -- )
+    { meta-d meta-r d-in terminated? } swap extract-keys
+    namespace swap update ;
+
+: current-stack-height ( -- n )
+    d-in get meta-d get length - ;
+
+: word-stack-height ( word -- n )
+    stack-effect effect-height ;
+
+: bad-recursive-declaration ( word inferred -- )
+    dup 0 < [ 0 swap ] [ 0 ] if <effect>
+    over stack-effect
+    effect-error ;
+
+: check-stack-height ( word height -- )
+    over word-stack-height over =
+    [ 2drop ] [ bad-recursive-declaration ] if ;
+
+: inline-recursive-word ( word #label -- )
+    current-stack-height [
+        flatten-meta-d [ join-values inline-block apply-infer ] dip >>in-d
+        [ node, ]
+        [ calls>> [ [ flatten-curries ] modify-values ] each ]
+        [ word>> ]
+        tri
+    ] dip
+    current-stack-height -
+    check-stack-height ;
 
 : inline-word ( word -- )
-    dup inline-block over recursive-label? [
-        flatten-meta-d >r
-        drop join-values inline-block apply-infer
-        r> over set-node-in-d
-        dup node,
-        calls>> [
-            [ flatten-curries ] modify-values
-        ] each
-    ] [
-        apply-infer node-child node-successor splice-node drop
-    ] if ;
+    dup inline-block over recursive-label?
+    [ drop inline-recursive-word ]
+    [ apply-infer node-child successor>> splice-node drop ] if ;
 
 M: word apply-object
     [
index e6ce2cfa0b8406f3ed3db8bdb60848487353fb7d..770763bfb6b78dd88f6128dff9ace5bcf71f3fdc 100755 (executable)
@@ -142,7 +142,7 @@ M: object xyz ;
 [ f ] [ [ <reversed> length ] \ slot inlined? ] unit-test
 
 ! We don't want to use = to compare literals
-: foo reverse ;
+: foo ( seq -- seq' ) reverse ;
 
 \ foo [
     [
index dc632425fe4335e7e78ffc4af54d7579ef5ce13d..2f7058ba9650294a436eef7c8b7b0ed8a81e0403 100755 (executable)
@@ -41,11 +41,11 @@ C: <interval-constraint> interval-constraint
 GENERIC: apply-constraint ( constraint -- )
 GENERIC: constraint-satisfied? ( constraint -- ? )
 
-: `input node get in-d>> nth ;
-: `output node get out-d>> nth ;
-: class, <class-constraint> , ;
-: literal, <literal-constraint> , ;
-: interval, <interval-constraint> , ;
+: `input ( n -- value ) node get in-d>> nth ;
+: `output ( n -- value ) node get out-d>> nth ;
+: class, ( class value -- ) <class-constraint> , ;
+: literal, ( literal value -- ) <literal-constraint> , ;
+: interval, ( interval value -- ) <interval-constraint> , ;
 
 M: f apply-constraint drop ;
 
index d7e3e78308fec3445760880b4cc0c0d8ce35e380..734c1c551cc171155f061574fa0eadac04b858a8 100755 (executable)
@@ -6,7 +6,7 @@ inference.state accessors combinators ;
 IN: inference.dataflow
 
 ! Computed value
-: <computed> \ <computed> counter ;
+: <computed> ( -- value ) \ <computed> counter ;
 
 ! Literal value
 TUPLE: value < identity-tuple literal uid recursion ;
@@ -88,7 +88,7 @@ M: object flatten-curry , ;
 : r-tail ( n -- seq )
     dup zero? [ drop f ] [ meta-r get swap tail* ] if ;
 
-: node-child node-children first ;
+: node-child ( node -- child ) node-children first ;
 
 TUPLE: #label < node word loop? returns calls ;
 
@@ -217,9 +217,9 @@ M: #call-label calls-label* param>> eq? ;
 
 SYMBOL: node-stack
 
-: >node node-stack get push ;
-: node> node-stack get pop ;
-: node@ node-stack get peek ;
+: >node ( node -- ) node-stack get push ;
+: node> ( -- node ) node-stack get pop ;
+: node@ ( -- node ) node-stack get peek ;
 
 : iterate-next ( -- node ) node@ successor>> ;
 
index f565420cacdaecc91d313344f4a84d36ddec6d1d..4a750402431ef7025e2097b596d2777c6fb85cb8 100644 (file)
@@ -5,20 +5,18 @@ USING: inference.backend inference.dataflow kernel generic
 sequences prettyprint io words arrays inspector effects debugger
 assocs accessors ;
 
+M: inference-error error-help error>> error-help ;
+
 M: inference-error error.
     dup rstate>>
     keys [ dup value? [ value-literal ] when ] map
     dup empty? [ "Word: " write dup peek . ] unless
     swap error>> error. "Nesting: " write . ;
 
-M: inference-error error-help drop f ;
-
 M: unbalanced-branches-error error.
     "Unbalanced branches:" print
-    dup unbalanced-branches-error-quots
-    over unbalanced-branches-error-in
-    rot unbalanced-branches-error-out [ length ] map
-    3array flip [ [ bl ] [ pprint ] interleave nl ] each ;
+    [ quots>> ] [ in>> ] [ out>> [ length ] map ] tri 3array flip
+    [ [ bl ] [ pprint ] interleave nl ] each ;
 
 M: literal-expected summary
     drop "Literal value expected" ;
@@ -31,25 +29,23 @@ M: too-many-r> summary
     drop
     "Quotation pops retain stack elements which it did not push" ;
 
-M: no-effect error.
-    "Unable to infer stack effect of " write no-effect-word . ;
+M: cannot-infer-effect error.
+    "Unable to infer stack effect of " write word>> . ;
 
-M: recursive-declare-error error.
-    "The recursive word " write
-    recursive-declare-error-word pprint
+M: missing-effect error.
+    "The word " write
+    word>> pprint
     " must declare a stack effect" print ;
 
 M: effect-error error.
     "Stack effects of the word " write
-    dup effect-error-word pprint
-    " do not match." print
-    "Declared: " write
-    dup effect-error-word stack-effect effect>string .
-    "Inferred: " write effect-error-effect effect>string . ;
+    [ word>> pprint " do not match." print ]
+    [ "Inferred: " write inferred>> effect>string . ]
+    [ "Declared: " write declared>> effect>string . ] tri ;
 
 M: recursive-quotation-error error.
     "The quotation " write
-    recursive-quotation-error-quot pprint
+    quot>> pprint
     " calls itself." print
     "Stack effect inference is undecidable when quotation-level recursion is permitted." print ;
 
index d79c82ed6518699cc1f7bed44ed931f787d24d66..5900e5a844412e6038bf41f622921c631bb2cb36 100755 (executable)
@@ -83,13 +83,13 @@ ARTICLE: "inference-errors" "Inference errors"
 "Main wrapper for all inference errors:"
 { $subsection inference-error }
 "Specific inference errors:"
-{ $subsection no-effect }
+{ $subsection cannot-infer-effect }
 { $subsection literal-expected }
 { $subsection too-many->r }
 { $subsection too-many-r> }
 { $subsection unbalanced-branches-error }
 { $subsection effect-error }
-{ $subsection recursive-declare-error } ;
+{ $subsection missing-effect } ;
 
 ARTICLE: "inference" "Stack effect inference"
 "The stack effect inference tool is used to check correctness of code before it is run. It is also used by the compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile."
@@ -108,7 +108,8 @@ $nl
 { $subsection "inference-limitations" }
 { $subsection "inference-errors" }
 { $subsection "dataflow-graphs" }
-{ $subsection "compiler-transforms" } ;
+{ $subsection "compiler-transforms" }
+{ $see-also "effects" } ;
 
 ABOUT: "inference"
 
index 0d3eb03cf43e510a5aac289dbba529562ae8c4ad..7f073bfad966861eb52e322bff1bb5916032f339 100755 (executable)
@@ -48,20 +48,12 @@ IN: inference.tests
 ] must-fail
 
 ! Test inference of termination of control flow
-: termination-test-1
-    "foo" throw ;
+: termination-test-1 ( -- * ) "foo" throw ;
 
-: termination-test-2 [ termination-test-1 ] [ 3 ] if ;
+: termination-test-2 ( ? -- x ) [ termination-test-1 ] [ 3 ] if ;
 
 { 1 1 } [ termination-test-2 ] must-infer-as
 
-: infinite-loop infinite-loop ;
-
-[ [ infinite-loop ] infer ] must-fail
-
-: no-base-case-1 dup [ no-base-case-1 ] [ no-base-case-1 ] if ;
-[ [ no-base-case-1 ] infer ] must-fail
-
 : simple-recursion-1 ( obj -- obj )
     dup [ simple-recursion-1 ] [ ] if ;
 
@@ -131,7 +123,7 @@ SYMBOL: sym-test
 
 { 0 1 } [ sym-test ] must-infer-as
 
-: terminator-branch
+: terminator-branch ( a -- b )
     dup [
         length
     ] [
@@ -198,11 +190,10 @@ DEFER: blah4
 [ [ [ 1 ] [ ] bad-combinator ] infer ] must-fail
 
 ! Regression
-: bad-input#
+{ 2 2 } [
     dup string? [ 2array throw ] unless
-    over string? [ 2array throw ] unless ;
-
-{ 2 2 } [ bad-input# ] must-infer-as
+    over string? [ 2array throw ] unless
+] must-infer-as
 
 ! Regression
 
@@ -224,7 +215,7 @@ DEFER: do-crap*
 { 2 1 } [ too-deep ] must-infer-as
 
 ! Error reporting is wrong
-MATH: xyz
+MATH: xyz ( a b -- c )
 M: fixnum xyz 2array ;
 M: float xyz
     [ 3 ] bi@ swapd >r 2array swap r> 2array swap ;
@@ -448,7 +439,7 @@ DEFER: bar
 ! Incorrect stack declarations on inline recursive words should
 ! be caught
 : fooxxx ( a b -- c ) over [ foo ] when ; inline
-: barxxx fooxxx ;
+: barxxx ( a b -- c ) fooxxx ;
 
 [ [ barxxx ] infer ] must-fail
 
@@ -472,9 +463,7 @@ M: string my-hook "a string" ;
 
 DEFER: deferred-word
 
-: calls-deferred-word [ deferred-word ] [ 3 ] if ;
-
-{ 1 1 } [ calls-deferred-word ] must-infer-as
+{ 1 1 } [ [ deferred-word ] [ 3 ] if ] must-infer-as
 
 USE: inference.dataflow
 
@@ -549,10 +538,34 @@ ERROR: custom-error ;
 { 1 0 } [ [ ] map-children ] must-infer-as
 
 ! Corner case
-! [ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail
-
-! [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail
-
-! : erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline
-
-! [ [ erg's-inference-bug ] infer ] must-fail
+[ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail
+
+[ [ [ f dup ] [ ] [ ] while ] infer ] must-fail
+
+: erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline
+
+[ [ erg's-inference-bug ] infer ] must-fail
+
+! : inference-invalidation-a ( -- );
+! : inference-invalidation-b ( quot -- ) [ inference-invalidation-a ] dip call ; inline
+! : inference-invalidation-c ( a b -- c ) [ + ] inference-invalidation-b ;
+! 
+! [ 7 ] [ 4 3 inference-invalidation-c ] unit-test
+! 
+! { 2 1 } [ [ + ] inference-invalidation-b ] must-infer-as
+! 
+! [ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test
+! 
+! [ 3 ] [ inference-invalidation-c ] unit-test
+! 
+! { 0 1 } [ inference-invalidation-c ] must-infer-as
+! 
+! GENERIC: inference-invalidation-d ( obj -- )
+! 
+! M: object inference-invalidation-d inference-invalidation-c 2drop ;
+! 
+! \ inference-invalidation-d must-infer
+! 
+! [ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test
+! 
+! [ [ inference-invalidation-d ] infer ] must-fail
index 3f52eaadf4691f66aa5f9b0565420a9098a6f2d1..d73e43cdfc1199cb2b8d1cfea2ddc3ecc9e48f6f 100755 (executable)
@@ -29,6 +29,6 @@ M: callable dataflow-with
 
 : forget-errors ( -- )
     all-words [
-        dup subwords [ f "no-effect" set-word-prop ] each
-        f "no-effect" set-word-prop
+        dup subwords [ f "cannot-infer" set-word-prop ] each
+        f "cannot-infer" set-word-prop
     ] each ;
index 2d45ce0d0caf81fb4ef2508bed59c814636d6186..3282cbb5e22ac6ea1a324d7a8b1d332d355e465c 100755 (executable)
@@ -583,7 +583,7 @@ set-primitive-effect
 
 \ (set-os-envs) { array } { } <effect> set-primitive-effect
 
-\ do-primitive [ \ do-primitive no-effect ] "infer" set-word-prop
+\ do-primitive [ \ do-primitive cannot-infer-effect ] "infer" set-word-prop
 
 \ dll-valid? { object } { object } <effect> set-primitive-effect
 
index c63786dc9e6390404ed7e77358ab094e45d22882..21f59bf0204f487a65b071481b5125420cfb1d79 100644 (file)
@@ -1,5 +1,6 @@
 IN: inference.state.tests
-USING: tools.test inference.state words kernel namespaces ;
+USING: tools.test inference.state words kernel namespaces
+definitions ;
 
 : computing-dependencies ( quot -- dependencies )
     H{ } clone [ dependencies rot with-variable ] keep ;
index 6f0eecf2d9617419863fdfb55c6e3ebdec4ae454..1d1ccaa2a9f638df10a9aabf521904e5a90d4326 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs namespaces sequences kernel words ;
+USING: assocs namespaces sequences kernel definitions ;
 IN: inference.state
 
 ! Nesting state to solve recursion
@@ -12,16 +12,16 @@ SYMBOL: d-in
 ! Compile-time data stack
 SYMBOL: meta-d
 
-: push-d meta-d get push ;
-: pop-d meta-d get pop ;
-: peek-d meta-d get peek ;
+: push-d ( obj -- ) meta-d get push ;
+: pop-d  ( -- obj ) meta-d get pop ;
+: peek-d ( -- obj ) meta-d get peek ;
 
 ! Compile-time retain stack
 SYMBOL: meta-r
 
-: push-r meta-r get push ;
-: pop-r meta-r get pop ;
-: peek-r meta-r get peek ;
+: push-r ( obj -- ) meta-r get push ;
+: pop-r  ( -- obj ) meta-r get pop ;
+: peek-r ( -- obj ) meta-r get peek ;
 
 ! Head of dataflow IR
 SYMBOL: dataflow-graph
index a5b898315a625fa2c01671a40013c4c43bf0de80..f90dd2350c5c3e808485e3131f1249675cd9c10f 100755 (executable)
@@ -3,10 +3,10 @@ USING: sequences inference.transforms tools.test math kernel
 quotations inference accessors combinators words arrays
 classes ;
 
-: compose-n-quot <repetition> >quotation ;
-: compose-n compose-n-quot call ;
+: compose-n-quot ( word -- quot' ) <repetition> >quotation ;
+: compose-n ( quot -- ) compose-n-quot call ;
 \ compose-n [ compose-n-quot ] 2 define-transform
-: compose-n-test 2 \ + compose-n ;
+: compose-n-test ( a b c -- x ) 2 \ + compose-n ;
 
 [ 6 ] [ 1 2 3 compose-n-test ] unit-test
 
@@ -20,25 +20,12 @@ classes ;
 
 [ 512 ] [ 1 { { 1+ 8 } } bitfield-quot call ] unit-test
 
-\ new must-infer
-
-TUPLE: a-tuple x y z ;
-
-: set-slots-test ( x y z -- )
-    { set-a-tuple-x set-a-tuple-y } set-slots ;
-
-\ set-slots-test must-infer
-
-: set-slots-test-2
-    { set-a-tuple-x set-a-tuple-x } set-slots ;
-
-[ [ set-slots-test-2 ] infer ] must-fail
-
 TUPLE: color r g b ;
 
 C: <color> color
 
-: cleave-test { [ r>> ] [ g>> ] [ b>> ] } cleave ;
+: cleave-test ( color -- r g b )
+    { [ r>> ] [ g>> ] [ b>> ] } cleave ;
 
 { 1 3 } [ cleave-test ] must-infer-as
 
@@ -46,13 +33,13 @@ C: <color> color
 
 [ 1 2 3 ] [ 1 2 3 <color> \ cleave-test word-def call ] unit-test
 
-: 2cleave-test { [ 2array ] [ + ] [ - ] } 2cleave ;
+: 2cleave-test ( a b -- c d e ) { [ 2array ] [ + ] [ - ] } 2cleave ;
 
 [ { 1 2 } 3 -1 ] [ 1 2 2cleave-test ] unit-test
 
 [ { 1 2 } 3 -1 ] [ 1 2 \ 2cleave-test word-def call ] unit-test
 
-: spread-test { [ sq ] [ neg ] [ recip ] } spread ;
+: spread-test ( a b c -- d e f ) { [ sq ] [ neg ] [ recip ] } spread ;
 
 [ 16 -3 1/6 ] [ 4 3 6 spread-test ] unit-test
 
index 0040629edd444786c06184f78f5b03d064c70025..5ca10c75450d67b4ba4068e87962cfa7dfa036aa 100755 (executable)
@@ -3,7 +3,7 @@
 USING: arrays kernel words sequences generic math namespaces
 quotations assocs combinators math.bitfields inference.backend
 inference.dataflow inference.state classes.tuple.private effects
-inspector hashtables classes generic sets ;
+inspector hashtables classes generic sets definitions ;
 IN: inference.transforms
 
 : pop-literals ( n -- rstate seq )
index f10bcef8a92ea5b76d68cb61e5102944c32515c9..e201d663a613efdf316f0e08917b80e1ee49ff9b 100755 (executable)
@@ -5,6 +5,8 @@ strings accessors io.encodings.utf8 math destructors ;
 
 \ exists? must-infer
 \ (exists?) must-infer
+\ file-info must-infer
+\ link-info must-infer
 
 [ ] [ "blahblah" temp-file dup exists? [ delete-directory ] [ drop ] if ] unit-test
 [ ] [ "blahblah" temp-file make-directory ] unit-test
index ff265e43b16df39cb6c93c8f9f8a4e5742c8df44..56a9a461cfdab322cfc05e0955ab3f841cecdcf5 100755 (executable)
@@ -260,7 +260,8 @@ HOOK: delete-directory io-backend ( path -- )
         delete-file
     ] if ;
 
-: to-directory over file-name append-path ;
+: to-directory ( from to -- from to' )
+    over file-name append-path ;
 
 ! Moving and renaming files
 HOOK: move-file io-backend ( from to -- )
index 355e913b14c912bf6a4f8edbfc02de5eca6057ae..d2b092abe8d3c0fbe7aff5de42a5dadf4b228096 100755 (executable)
@@ -26,7 +26,8 @@ M: growable stream-read1 dup empty? [ drop f ] [ pop ] if ;
 : growable-read-until ( growable n -- str )
     >fixnum dupd tail-slice swap harden-as dup reverse-here ;
 
-: find-last-sep swap [ memq? ] curry find-last drop ;
+: find-last-sep ( seq seps -- n )
+    swap [ memq? ] curry find-last drop ;
 
 M: growable stream-read-until
     [ find-last-sep ] keep over [
index c39010f228f98d1578f781428a987a2dcc4aac4a..82f0db1364713f6a1003400703e52600dfb1630b 100755 (executable)
@@ -219,6 +219,16 @@ $nl
 { $example "t \\ t eq? ." "t" }
 "Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ;
 
+ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic"
+"Certain simple conditional forms can be expressed in a simpler manner using boolean logic."
+$nl
+"The following two lines are equivalent:"
+{ $code "[ drop f ] unless" "swap and" }
+"The following two lines are equivalent:"
+{ $code "[ ] [ ] ?if" "swap or" }
+"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
+{ $code "[ L ] unless*" "L or" } ;
+
 ARTICLE: "conditionals" "Conditionals and logic"
 "The basic conditionals:"
 { $subsection if }
@@ -238,6 +248,7 @@ ARTICLE: "conditionals" "Conditionals and logic"
 { $subsection and }
 { $subsection or }
 { $subsection xor }
+{ $subsection "conditionals-boolean-equivalence" }
 "See " { $link "combinators" } " for forms which abstract away common patterns involving multiple nested branches."
 { $see-also "booleans" "bitwise-arithmetic" both? either? } ;
 
@@ -720,9 +731,7 @@ HELP: unless*
 { $description "Variant of " { $link if* } " with no true quotation." }
 { $notes
 "The following two lines are equivalent:"
-{ $code "X [ Y ] unless*" "X dup [ ] [ drop Y ] if" }
-"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
-{ $code "[ L ] unless*" "L or" } } ;
+{ $code "X [ Y ] unless*" "X dup [ ] [ drop Y ] if" } } ;
 
 HELP: ?if
 { $values { "default" object } { "cond" "a generalized boolean" } { "true" "a quotation with stack effect " { $snippet "( cond -- )" } } { "false" "a quotation with stack effect " { $snippet "( default -- )" } } }
index 9112dbf25eb28fc6eeec6fb98c7fc7588f6e3007..61f687c95a1ac715b1c21f40cc933c4c539b5674 100755 (executable)
@@ -72,7 +72,7 @@ DEFER: if
     >r keep r> call ; inline
 
 : tri ( x p q r -- )
-    >r pick >r bi r> r> call ; inline
+    >r >r keep r> keep r> call ; inline
 
 ! Double cleavers
 : 2bi ( x y p q -- )
@@ -93,7 +93,7 @@ DEFER: if
     >r dip r> call ; inline
 
 : tri* ( x y z p q r -- )
-    >r rot >r bi* r> r> call ; inline
+    >r >r 2dip r> dip r> call ; inline
 
 ! Double spreaders
 : 2bi* ( w x y z p q -- )
index 6dfc51f4409c4afcf6961a67161535051346fc42..70533ac33f3cd22b679926bd95697a236fc38064 100755 (executable)
@@ -10,7 +10,7 @@ IN: math.bitfields.tests
 : a 1 ; inline
 : b 2 ; inline
 
-: foo { a b } flags ;
+: foo ( -- flags ) { a b } flags ;
 
 [ 3 ] [ foo ] unit-test
 [ 3 ] [ { a b } flags ] unit-test
index 77cc40180ea31c73552eace1bd918513a2901e60..a0fb17ef4882402ced25a101befab4259e07a7ae 100644 (file)
@@ -3,7 +3,7 @@
 USING: arrays kernel math sequences words ;
 IN: math.bitfields
 
-GENERIC: (bitfield) inline
+GENERIC: (bitfield) ( value accum shift -- newaccum )
 
 M: integer (bitfield) ( value accum shift -- newaccum )
     swapd shift bitor ;
index db50d262ad66d222e98c0466245a2d4ac02f5f93..f428df33ae7bc56ecb7dd968de00663ab21f0fe6 100755 (executable)
@@ -192,7 +192,7 @@ unit-test
 [ f ] [ 0 power-of-2? ] unit-test
 [ t ] [ 1 power-of-2? ] unit-test
 
-: ratio>float [ >bignum ] bi@ /f ;
+: ratio>float ( a b -- f ) [ >bignum ] bi@ /f ;
 
 [ 5. ] [ 5 1 ratio>float ] unit-test
 [ 4. ] [ 4 1 ratio>float ] unit-test
@@ -206,7 +206,7 @@ unit-test
 [ HEX: 3fe553522d230931 ]
 [ 61967020039 92984792073 ratio>float double>bits ] unit-test
 
-: random-integer
+: random-integer ( -- n )
     32 random-bits
     1 random zero? [ neg ] when
     1 random zero? [ >bignum ] when ;
index ba728e67c0dcd7c42530b74962072cfd504f355a..82ec51b3f158e6114d202fb8fc3d040e6c6ff604 100755 (executable)
@@ -177,7 +177,7 @@ IN: math.intervals.tests
         { 3 [ (a,b] ] }
     } case ;
 
-: random-op
+: random-op ( -- pair )
     {
         { + interval+ }
         { - interval- }
@@ -192,7 +192,7 @@ IN: math.intervals.tests
     ] when
     random ;
 
-: interval-test
+: interval-test ( -- ? )
     random-interval random-interval random-op ! 3dup . . .
     0 pick interval-contains? over first { / /i } member? and [
         3drop t
@@ -204,7 +204,7 @@ IN: math.intervals.tests
 
 [ t ] [ 40000 [ drop interval-test ] all? ] unit-test
 
-: random-comparison
+: random-comparison ( -- pair )
     {
         { < interval< }
         { <= interval<= }
@@ -212,7 +212,7 @@ IN: math.intervals.tests
         { >= interval>= }
     } random ;
 
-: comparison-test
+: comparison-test ( -- ? )
     random-interval random-interval random-comparison
     [ >r [ random-element ] bi@ r> first execute ] 3keep
     second execute dup incomparable eq? [
index 324d628fd1c9e217a798e8c8d85cf484170cdaf7..7d0519600743b5ecedd65c3fdbc97820969a2c3f 100755 (executable)
@@ -8,9 +8,9 @@ TUPLE: interval from to ;
 
 C: <interval> interval
 
-: open-point f 2array ;
+: open-point ( n -- endpoint ) f 2array ;
 
-: closed-point t 2array ;
+: closed-point ( n -- endpoint ) t 2array ;
 
 : [a,b] ( a b -- interval )
     >r closed-point r> closed-point <interval> ;
@@ -197,7 +197,8 @@ SYMBOL: incomparable
     [ interval-to ] bi@ =
     and and ;
 
-: (interval<) over interval-from over interval-from endpoint< ;
+: (interval<) ( i1 i2 -- i1 i2 ? )
+    over interval-from over interval-from endpoint< ;
 
 : interval< ( i1 i2 -- ? )
     {
index d1b8e6fd37dafc30fbdc6fa09a3a0d1d7dcf0e6e..5d048f0b8e2125959642fefed7726b1a78e0a7e7 100755 (executable)
@@ -43,7 +43,7 @@ DEFER: base>
 SYMBOL: radix
 SYMBOL: negative?
 
-: sign negative? get "-" "+" ? ;
+: sign ( -- str ) negative? get "-" "+" ? ;
 
 : with-radix ( radix quot -- )
     radix swap with-variable ; inline
index 7ab0ffc8067e117ff3dc2e6ec550abf3fbfc948f..f3f9f519911c96d24e215df289c5c28c1534eee5 100755 (executable)
@@ -161,7 +161,8 @@ SYMBOL: potential-loops
         } cond
     ] if ;
 
-: fold-if-branch? dup node-in-d first known-boolean-value? ;
+: fold-if-branch? ( node -- value ? )
+    dup node-in-d first known-boolean-value? ;
 
 : fold-if-branch ( node value -- node' )
     over drop-inputs >r
@@ -214,7 +215,7 @@ SYMBOL: potential-loops
 : clone-node ( node -- newnode )
     clone dup [ clone ] modify-values ;
 
-: lift-branch
+: lift-branch ( node tail -- )
     over
     last-node clone-node
     dup node-in-d \ #merge out-node
index 393264e459e89905926274a9f0fe5d1975f26374..9e8f805acf0217a17a1bd99f14c65b471e8fb755 100755 (executable)
@@ -7,7 +7,7 @@ combinators classes classes.algebra generic.math
 optimizer.math.partial continuations optimizer.def-use
 optimizer.backend generic.standard optimizer.specializers
 optimizer.def-use optimizer.pattern-match generic.standard
-optimizer.control kernel.private ;
+optimizer.control kernel.private definitions ;
 IN: optimizer.inlining
 
 : remember-inlining ( node history -- )
@@ -61,12 +61,8 @@ DEFER: (flat-length)
     [ dispatch# node-class# ] keep specific-method ;
 
 : inline-standard-method ( node word -- node )
-    2dup dispatching-class dup [
-        over +inlined+ depends-on
-        swap method 1quotation f splice-quot
-    ] [
-        3drop t
-    ] if ;
+    2dup dispatching-class dup
+    [ swap method 1quotation f splice-quot ] [ 3drop t ] if ;
 
 ! Partial dispatch of math-generic words
 : normalize-math-class ( class -- class' )
index 6f4ae2c1d5bccb4cb0983b03ab50f91295aef5b7..7032e58b3fa742a11ec665d0a93a70f5ec076dc2 100755 (executable)
@@ -101,7 +101,7 @@ TUPLE: pred-test ;
 
 ! regression
 GENERIC: void-generic ( obj -- * )
-: breakage "hi" void-generic ;
+: breakage ( -- * ) "hi" void-generic ;
 [ t ] [ \ breakage compiled? ] unit-test
 [ breakage ] must-fail
 
@@ -116,12 +116,12 @@ GENERIC: void-generic ( obj -- * )
 
 ! another regression
 : constant-branch-fold-0 "hey" ; foldable
-: constant-branch-fold-1 constant-branch-fold-0 "hey" = ; inline
+: constant-branch-fold-1 ( -- ? ) constant-branch-fold-0 "hey" = ; inline
 [ 1 ] [ [ constant-branch-fold-1 [ 1 ] [ 2 ] if ] compile-call ] unit-test
 
 ! another regression
 : foo f ;
-: bar foo 4 4 = and ;
+: bar ( -- ? ) foo 4 4 = and ;
 [ f ] [ bar ] unit-test
 
 ! ensure identities are working in some form
@@ -131,7 +131,7 @@ GENERIC: void-generic ( obj -- * )
 ] unit-test
 
 ! compiling <tuple> with a non-literal class failed
-: <tuple>-regression <tuple> ;
+: <tuple>-regression ( class -- tuple ) <tuple> ;
 
 [ t ] [ \ <tuple>-regression compiled? ] unit-test
 
@@ -254,7 +254,7 @@ TUPLE: silly-tuple a b ;
 [ ] [ [ <tuple> ] dataflow optimize drop ] unit-test
 
 ! Make sure we have sane heuristics
-: should-inline? method flat-length 10 <= ;
+: should-inline? ( generic class -- ? ) method flat-length 10 <= ;
 
 [ t ] [ \ fixnum \ shift should-inline? ] unit-test
 [ f ] [ \ array \ equal? should-inline? ] unit-test
@@ -264,7 +264,7 @@ TUPLE: silly-tuple a b ;
 [ t ] [ \ sbuf \ set-nth-unsafe should-inline? ] unit-test
 
 ! Regression
-: lift-throw-tail-regression
+: lift-throw-tail-regression ( obj -- obj str )
     dup integer? [ "an integer" ] [
         dup string? [ "a string" ] [
             "error" throw
@@ -294,7 +294,7 @@ TUPLE: silly-tuple a b ;
 GENERIC: generic-inline-test ( x -- y )
 M: integer generic-inline-test ;
 
-: generic-inline-test-1
+: generic-inline-test-1 ( -- x )
     1
     generic-inline-test
     generic-inline-test
@@ -319,7 +319,7 @@ M: integer generic-inline-test ;
 
 HINTS: recursive-inline-hang array ;
 
-: recursive-inline-hang-1
+: recursive-inline-hang-1 ( -- a )
     { } recursive-inline-hang ;
 
 [ t ] [ \ recursive-inline-hang-1 compiled? ] unit-test
@@ -350,7 +350,7 @@ USE: sequences.private
 
 [ 2 4 6.0 0 ] [ counter-example' ] unit-test
 
-: member-test { + - * / /i } member? ;
+: member-test ( obj -- ? ) { + - * / /i } member? ;
 
 \ member-test must-infer
 [ ] [ \ member-test word-dataflow optimize 2drop ] unit-test
index 418278baeedea73385999404db1b0d97126311af..1dc47432d355ecbd6c76430674df74d0fbe77cd4 100755 (executable)
@@ -188,7 +188,7 @@ $nl
 
 ABOUT: "parser"
 
-: $parsing-note
+: $parsing-note ( children -- )
     drop
     "This word should only be called from parsing words."
     $notes ;
@@ -431,9 +431,9 @@ HELP: lexer-factory
 { $var-description "A variable holding a quotation with stack effect " { $snippet "( lines -- lexer )" } ". This quotation is called by the parser to create " { $link lexer } " instances. This variable can be rebound to a quotation which outputs a custom tuple delegating to " { $link lexer } " to customize syntax." } ;
 
 HELP: parse-effect
-{ $values { "effect" "an instance of " { $link effect } } }
+{ $values { "end" string } { "effect" "an instance of " { $link effect } } }
 { $description "Parses a stack effect from the current input line." }
-{ $examples "This word is used by " { $link POSTPONE: ( } " to parse stack effect declarations." }
+{ $examples "This word is used by " { $link POSTPONE: ( } " and " { $link POSTPONE: (( } " to parse stack effect declarations." }
 $parsing-note ;
 
 HELP: parse-base
index 46e93753b547905769f8d124f1461f275f7709c8..e99f2b850bd4f5c75f7e4b6d271a0e65da5b9be0 100755 (executable)
@@ -221,6 +221,8 @@ ERROR: unexpected want got ;
 PREDICATE: unexpected-eof < unexpected
     unexpected-got not ;
 
+M: parsing-word stack-effect drop (( parsed -- parsed )) ;
+
 : unexpected-eof ( word -- * ) f unexpected ;
 
 : (parse-tokens) ( accum end -- accum )
@@ -357,16 +359,15 @@ M: staging-violation summary
     "A parsing word cannot be used in the same file it is defined in." ;
 
 : execute-parsing ( word -- )
-    [ changed-definitions get key? [ staging-violation ] when ]
-    [ execute ]
-    bi ;
+    dup changed-definitions get key? [ staging-violation ] when
+    execute ;
 
 : parse-step ( accum end -- accum ? )
     scan-word {
         { [ 2dup eq? ] [ 2drop f ] }
         { [ dup not ] [ drop unexpected-eof t ] }
         { [ dup delimiter? ] [ unexpected t ] }
-        { [ dup parsing? ] [ nip execute-parsing t ] }
+        { [ dup parsing-word? ] [ nip execute-parsing t ] }
         [ pick push drop t ]
     } cond ;
 
@@ -393,15 +394,15 @@ SYMBOL: lexer-factory
     lexer-factory get call (parse-lines) ;
 
 ! Parsing word utilities
-: parse-effect ( -- effect )
-    ")" parse-tokens "(" over member? [
-        "Stack effect declaration must not contain (" throw
-    ] [
+: parse-effect ( end -- effect )
+    parse-tokens dup { "(" "((" } intersect empty? [
         { "--" } split1 dup [
             <effect>
         ] [
             "Stack effect declaration must contain --" throw
         ] if
+    ] [
+        "Stack effect declaration must not contain ( or ((" throw
     ] if ;
 
 ERROR: bad-number ;
@@ -415,7 +416,7 @@ ERROR: bad-number ;
 : parse-definition ( -- quot )
     \ ; parse-until >quotation ;
 
-: (:) CREATE-WORD parse-definition ;
+: (:) ( -- word def ) CREATE-WORD parse-definition ;
 
 SYMBOL: current-class
 SYMBOL: current-generic
@@ -429,11 +430,11 @@ SYMBOL: current-generic
         r> call
     ] with-scope ; inline
 
-: (M:)
+: (M:) ( method def -- )
     CREATE-METHOD [ parse-definition ] with-method-definition ;
 
 : scan-object ( -- object )
-    scan-word dup parsing?
+    scan-word dup parsing-word?
     [ V{ } clone swap execute first ] when ;
 
 GENERIC: expected>string ( obj -- str )
index f992b9ca01cfa0290df21f50f46651d3ea9a8857..3df408cb1064c8200ffa9a6797d82d9b0f17599a 100755 (executable)
@@ -5,11 +5,13 @@ hashtables io assocs kernel math namespaces sequences strings
 sbufs io.styles vectors words prettyprint.config
 prettyprint.sections quotations io io.files math.parser effects
 classes.tuple math.order classes.tuple.private classes
-float-arrays ;
+float-arrays combinators ;
 IN: prettyprint.backend
 
 GENERIC: pprint* ( obj -- )
 
+M: effect pprint* effect>string "(" swap ")" 3append text ;
+
 : ?effect-height ( word -- n )
     stack-effect [ effect-height ] [ 0 ] if* ;
 
@@ -26,9 +28,11 @@ GENERIC: pprint* ( obj -- )
 : word-style ( word -- style )
     dup "word-style" word-prop >hashtable [
         [
-            dup presented set
-            dup parsing? over delimiter? rot t eq? or or
-            [ bold font-style set ] when
+            [ presented set ]
+            [
+                [ parsing-word? ] [ delimiter? ] [ t eq? ] tri or or
+                [ bold font-style set ] when
+            ] bi
         ] bind
     ] keep ;
 
@@ -43,13 +47,16 @@ GENERIC: pprint* ( obj -- )
     <block swap pprint-word call block> ; inline
 
 M: word pprint*
-    dup parsing? [
+    dup parsing-word? [
         \ POSTPONE: [ pprint-word ] pprint-prefix
     ] [
-        dup "break-before" word-prop line-break
-        dup pprint-word
-        dup ?start-group dup ?end-group
-        "break-after" word-prop line-break
+        {
+            [ "break-before" word-prop line-break ]
+            [ pprint-word ]
+            [ ?start-group ]
+            [ ?end-group ]
+            [ "break-after" word-prop line-break ]
+        } cleave
     ] if ;
 
 M: real pprint* number>string text ;
index f5ec263f117d0d969c7d2dc12d10d1cc2f34e79d..d5f4dd5906f80c8b00215422785de28b588ae333 100755 (executable)
@@ -34,23 +34,6 @@ unit-test
 
 [ "SBUF\" hello world\"" ] [ SBUF" hello world" unparse ] unit-test
 
-
-[ "( a b -- c d )" ] [
-    { "a" "b" } { "c" "d" } <effect> effect>string
-] unit-test
-
-[ "( -- c d )" ] [
-    { } { "c" "d" } <effect> effect>string
-] unit-test
-
-[ "( a b -- )" ] [
-    { "a" "b" } { } <effect> effect>string
-] unit-test
-
-[ "( -- )" ] [
-    { } { } <effect> effect>string
-] unit-test
-
 [ "W{ \\ + }" ] [ [ W{ \ + } ] first unparse ] unit-test
 
 [ ] [ \ fixnum see ] unit-test
index a3c3f4926bb2eb7ee9adbbf881f9a7b8a19fc89f..298fc83e9d3cc4b26b68e55622a0f93e1a0ecbaf 100755 (executable)
@@ -4,11 +4,11 @@ IN: prettyprint
 USING: arrays generic generic.standard assocs io kernel
 math namespaces sequences strings io.styles io.streams.string
 vectors words prettyprint.backend prettyprint.sections
-prettyprint.config sorting splitting math.parser vocabs
+prettyprint.config sorting splitting grouping math.parser vocabs
 definitions effects classes.builtin classes.tuple io.files
 classes continuations hashtables classes.mixin classes.union
 classes.intersection classes.predicate classes.singleton
-combinators quotations sets ;
+combinators quotations sets accessors ;
 
 : make-pprint ( obj quot -- block in use )
     [
@@ -145,46 +145,51 @@ GENERIC: see ( defspec -- )
     definer drop pprint-word ;
 
 : stack-effect. ( word -- )
-    dup parsing? over symbol? or not swap stack-effect and
+    [ [ parsing-word? ] [ symbol? ] bi or not ] [ stack-effect ] bi and
     [ effect>string comment. ] when* ;
 
 : word-synopsis ( word -- )
-    dup seeing-word
-    dup definer.
-    dup pprint-word
-    stack-effect. ;
+    {
+        [ seeing-word ]
+        [ definer. ]
+        [ pprint-word ]
+        [ stack-effect. ] 
+    } cleave ;
 
 M: word synopsis* word-synopsis ;
 
 M: simple-generic synopsis* word-synopsis ;
 
 M: standard-generic synopsis*
-    dup definer.
-    dup seeing-word
-    dup pprint-word
-    dup dispatch# pprint*
-    stack-effect. ;
+    {
+        [ definer. ]
+        [ seeing-word ]
+        [ pprint-word ]
+        [ dispatch# pprint* ]
+        [ stack-effect. ]
+    } cleave ;
 
 M: hook-generic synopsis*
-    dup definer.
-    dup seeing-word
-    dup pprint-word
-    dup "combination" word-prop hook-combination-var pprint*
-    stack-effect. ;
+    {
+        [ definer. ]
+        [ seeing-word ]
+        [ pprint-word ]
+        [ "combination" word-prop hook-combination-var pprint* ]
+        [ stack-effect. ]
+    } cleave ;
 
 M: method-spec synopsis*
     first2 method synopsis* ;
 
 M: method-body synopsis*
-    dup dup
-    definer.
-    "method-class" word-prop pprint-word
-    "method-generic" word-prop pprint-word ;
+    [ definer. ]
+    [ "method-class" word-prop pprint-word ]
+    [ "method-generic" word-prop pprint-word ] tri ;
 
 M: mixin-instance synopsis*
-    dup definer.
-    dup mixin-instance-class pprint-word
-    mixin-instance-mixin pprint-word ;
+    [ definer. ]
+    [ class>> pprint-word ]
+    [ mixin>> pprint-word ] tri ;
 
 M: pathname synopsis* pprint* ;
 
@@ -220,7 +225,7 @@ M: word declarations.
         POSTPONE: flushable
     } [ declaration. ] with each ;
 
-: pprint-; \ ; pprint-word ;
+: pprint-; ( -- ) \ ; pprint-word ;
 
 : (see) ( spec -- )
     <colon dup synopsis*
index 73d362010717a0907dea62b9ac6338711096d882..bc88e1e8107e3df2044c69bcc144d9b2c5d6c150 100644 (file)
@@ -190,9 +190,9 @@ M: block short-section ( block -- )
 : if-nonempty ( block quot -- )
     >r dup empty-block? [ drop ] r> if ; inline
 
-: (<block) pprinter-stack get push ;
+: (<block) ( block -- ) pprinter-stack get push ;
 
-: <block f <block> (<block) ;
+: <block ( -- ) f <block> (<block) ;
 
 : <object ( obj -- ) presented associate <block> (<block) ;
 
@@ -288,7 +288,7 @@ M: colon unindent-first-line? drop t ;
 SYMBOL: prev
 SYMBOL: next
 
-: split-groups [ t , ] when ;
+: split-groups ( ? -- ) [ t , ] when ;
 
 M: f section-start-group? drop t ;
 
index 2a0f5d289ff9364072a0b31407012ab56248fc5e..f3436c9a916713972491e5daa36abc731fd395ef 100755 (executable)
@@ -53,11 +53,13 @@ M: compose length
     [ compose-first length ]
     [ compose-second length ] bi + ;
 
-M: compose nth
+M: compose virtual-seq compose-first ;
+
+M: compose virtual@
     2dup compose-first length < [
         compose-first
     ] [
         [ compose-first length - ] [ compose-second ] bi
-    ] if nth ;
+    ] if ;
 
-INSTANCE: compose immutable-sequence
+INSTANCE: compose virtual-sequence
index 2c1a3b8ab90acf5f5a75f86665676a0d64beb8af..86a2aa12f691d46247272afeea97e3477dc90d40 100755 (executable)
@@ -231,6 +231,7 @@ $nl
 { $subsection "sequences-search" }
 { $subsection "sequences-comparing" }
 { $subsection "sequences-split" }
+{ $subsection "grouping" }
 { $subsection "sequences-destructive" }
 { $subsection "sequences-stacks" }
 { $subsection "sequences-sorting" }
index 29facb31f286512429de8c2f8a5d36812f05a03f..8cd86606bce4a2ded364c1ac3be196d5f555960b 100755 (executable)
@@ -118,19 +118,11 @@ HELP: define-slot-word
 { $description "Defines " { $snippet "word" } " to be a simple type-checking generic word that receives the slot number on the stack as a fixnum." }
 $low-level-note ;
 
-HELP: reader-effect
-{ $values { "class" class } { "spec" slot-spec } { "effect" "an instance of " { $link effect } } }
-{ $description "The stack effect of slot reader words is " { $snippet "( object -- value )" } "." } ;
-
 HELP: define-reader
 { $values { "class" class } { "name" string } { "slot" integer } }
 { $description "Defines a reader word to read a slot from instances of " { $snippet "class" } "." }
 $low-level-note ;
 
-HELP: writer-effect
-{ $values { "class" class } { "spec" slot-spec } { "effect" "an instance of " { $link effect } } }
-{ $description "The stack effect of slot writer words is " { $snippet "( value obj -- )" } "." } ;
-
 HELP: define-writer
 { $values { "class" class } { "name" string } { "slot" integer } }
 { $description "Defines a generic word " { $snippet "writer" } " to write a new value to a slot in instances of " { $snippet "class" } "." }
index e46e507b9dcdee35239566ec9712da47b44ca1e1..cf77fb14e4f6b3a0516531a892ce44e264e04161 100755 (executable)
@@ -27,36 +27,28 @@ C: <slot-spec> slot-spec
     >r "accessors" create dup r>
     "declared-effect" set-word-prop ;
 
-: reader-effect T{ effect f { "object" } { "value" } } ; inline
-
 : reader-word ( name -- word )
-    ">>" append reader-effect create-accessor ;
+    ">>" append (( object -- value )) create-accessor ;
 
 : define-reader ( class slot name -- )
     reader-word object reader-quot define-slot-word ;
 
-: writer-effect T{ effect f { "value" "object" } { } } ; inline
-
 : writer-word ( name -- word )
-    "(>>" swap ")" 3append writer-effect create-accessor ;
+    "(>>" swap ")" 3append (( value object -- )) create-accessor ;
 
 : define-writer ( class slot name -- )
     writer-word [ set-slot ] define-slot-word ;
 
-: setter-effect T{ effect f { "object" "value" } { "object" } } ; inline
-
 : setter-word ( name -- word )
-    ">>" prepend setter-effect create-accessor ;
+    ">>" prepend (( object value -- object )) create-accessor ;
 
 : define-setter ( name -- )
     dup setter-word dup deferred? [
         [ \ over , swap writer-word , ] [ ] make define-inline
     ] [ 2drop ] if ;
 
-: changer-effect T{ effect f { "object" "quot" } { "object" } } ; inline
-
 : changer-word ( name -- word )
-    "change-" prepend changer-effect create-accessor ;
+    "change-" prepend (( object quot -- object )) create-accessor ;
 
 : define-changer ( name -- )
     dup changer-word dup deferred? [
index 1beafc710adf79110daf9f4d4ea4600d511eec27..472b303059ef50380e37f954b30ac362ec9b35e0 100644 (file)
@@ -1,25 +1,6 @@
 USING: help.markup help.syntax sequences strings ;
 IN: splitting
 
-ARTICLE: "groups-clumps" "Groups and clumps"
-"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
-{ $subsection groups }
-{ $subsection <groups> }
-{ $subsection <sliced-groups> }
-"A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
-{ $subsection clumps }
-{ $subsection <clumps> }
-{ $subsection <sliced-clumps> }
-"The difference can be summarized as the following:"
-{ $list
-    { "With groups, the subsequences form the original sequence when concatenated:"
-        { $unchecked-example "dup n groups concat sequence= ." "t" }
-    }
-    { "With clumps, collecting the first element of each subsequence but the last one, together with the last subseqence, yields the original sequence:"
-        { $unchecked-example "dup n clumps unclip-last >r [ first ] map r> append sequence= ." "t" }
-    }
-} ;
-
 ARTICLE: "sequences-split" "Splitting sequences"
 "Splitting sequences at occurrences of subsequences:"
 { $subsection ?head }
@@ -29,8 +10,7 @@ ARTICLE: "sequences-split" "Splitting sequences"
 { $subsection split1 }
 { $subsection split }
 "Splitting a string into lines:"
-{ $subsection string-lines }
-{ $subsection "groups-clumps" } ;
+{ $subsection string-lines } ;
 
 ABOUT: "sequences-split"
 
@@ -49,83 +29,6 @@ HELP: split
 { $description "Splits " { $snippet "seq" } " at each occurrence of an element of " { $snippet "separators" } ", and outputs an array of pieces. The pieces do not include the elements along which the sequence was split." }
 { $examples { $example "USING: prettyprint splitting ;" "\"hello world-how are you?\" \" -\" split ." "{ \"hello\" \"world\" \"how\" \"are\" \"you?\" }" } } ;
 
-HELP: groups
-{ $class-description "Instances are virtual sequences whose elements are disjoint fixed-length subsequences of an underlying sequence. Groups are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
-$nl
-"New groups are created by calling " { $link <groups> } " and " { $link <sliced-groups> } "." }
-{ $see-also group } ;
-
-HELP: group
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
-{ $description "Splits the sequence into disjoint groups of " { $snippet "n" } " elements and collects the groups into a new array." }
-{ $notes "If the sequence length is not a multiple of " { $snippet "n" } ", the final subsequence in the list will be shorter than " { $snippet "n" } " elements." }
-{ $examples
-    { $example "USING: splitting prettyprint ;" "{ 3 1 3 3 7 } 2 group ." "{ { 3 1 } { 3 3 } { 7 } }" }
-} ;
-
-HELP: <groups>
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "groups" groups } }
-{ $description "Outputs a virtual sequence whose elements are disjoint subsequences of " { $snippet "n" } " elements from the underlying sequence." }
-{ $examples
-    { $example
-        "USING: arrays kernel prettyprint sequences splitting ;"
-        "9 >array 3 <groups> dup reverse-here concat >array ." "{ 6 7 8 3 4 5 0 1 2 }"
-    }
-} ;
-
-HELP: <sliced-groups>
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "groups" groups } }
-{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
-{ $examples
-    { $example
-        "USING: arrays kernel prettyprint sequences splitting ;"
-        "9 >array 3 <sliced-groups>"
-        "dup [ reverse-here ] each concat >array ."
-        "{ 2 1 0 5 4 3 8 7 6 }"
-    }
-} ;
-
-HELP: clumps
-{ $class-description "Instances are virtual sequences whose elements are overlapping fixed-length subsequences o an underlying sequence. Clumps are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
-$nl
-"New clumps are created by calling " { $link <clumps> } " and " { $link <sliced-clumps> } "." } ;
-
-HELP: clump
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
-{ $description "Splits the sequence into overlapping clumps of " { $snippet "n" } " elements and collects the clumps into a new array." }
-{ $errors "Throws an error if " { $snippet "n" } " is smaller than the length of the sequence." }
-{ $examples
-    { $example "USING: splitting prettyprint ;" "{ 3 1 3 3 7 } 2 clump ." "{ { 3 1 } { 1 3 } { 3 3 } { 3 7 } }" }
-} ;
-
-HELP: <clumps>
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
-{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
-{ $examples
-    "Running averages:"
-    { $example
-        "USING: splitting sequences math prettyprint kernel ;"
-        "IN: scratchpad"
-        ": share-price"
-        "    { 13/50 51/100 13/50 1/10 4/5 17/20 33/50 3/25 19/100 3/100 } ;"
-        ""
-        "share-price 4 <clumps> [ [ sum ] [ length ] bi / ] map ."
-        "{ 113/400 167/400 201/400 241/400 243/400 91/200 1/4 }"
-    }
-} ;
-
-HELP: <sliced-clumps>
-{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
-{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence." } ;
-
-{ clumps groups } related-words
-
-{ clump group } related-words
-
-{ <clumps> <groups> } related-words
-
-{ <sliced-clumps> <sliced-groups> } related-words
-
 HELP: ?head
 { $values { "seq" "a sequence" } { "begin" "a sequence" } { "newseq" "a new sequence" } { "?" "a boolean" } }
 { $description "Tests if " { $snippet "seq" } " starts with " { $snippet "begin" } ". If there is a match, outputs the subrange of " { $snippet "seq" } " excluding " { $snippet "begin" } ", and " { $link t } ". If there is no match, outputs " { $snippet "seq" } " and " { $link f } "." } ;
index 34757e6b22ff5d7a59bc2e86d91a4821258f6e30..0f3dbdea1b0189e0bb48f4e60e811f4e15eccdb7 100644 (file)
@@ -1,10 +1,6 @@
 USING: splitting tools.test kernel sequences arrays ;
 IN: splitting.tests
 
-[ { 1 2 3 } 0 group ] must-fail
-
-[ { "hell" "o wo" "rld" } ] [ "hello world" 4 group ] unit-test
-
 [ "hello" "world ." ] [ "hello world ." " " split1 ] unit-test
 [ "hello" "world-+." ] [ "hello-+world-+." "-+" split1 ] unit-test
 [ "goodbye" f ] [ "goodbye" " " split1 ] unit-test
@@ -56,9 +52,3 @@ unit-test
 [ { "hello" "hi" } ] [ "hello\nhi" string-lines ] unit-test
 [ { "hello" "hi" } ] [ "hello\rhi" string-lines ] unit-test
 [ { "hello" "hi" } ] [ "hello\r\nhi" string-lines ] unit-test
-
-[ { V{ "a" "b" } V{ f f } } ] [
-    V{ "a" "b" } clone 2 <groups>
-    2 over set-length
-    >array
-] unit-test
index 62e7ef3782564a12cba0e3ca6b084bcd0a5d4c63..c30ea462c10f751aa10b879f94fa9e8d6aa27450 100755 (executable)
@@ -4,69 +4,6 @@ USING: kernel math namespaces strings arrays vectors sequences
 sets math.order accessors ;
 IN: splitting
 
-TUPLE: abstract-groups seq n ;
-
-: check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
-
-: construct-groups ( seq n class -- groups )
-    >r check-groups r> boa ; inline
-
-GENERIC: group@ ( n groups -- from to seq )
-
-M: abstract-groups nth group@ subseq ;
-
-M: abstract-groups set-nth group@ <slice> 0 swap copy ;
-
-M: abstract-groups like drop { } like ;
-
-INSTANCE: abstract-groups sequence
-
-TUPLE: groups < abstract-groups ;
-
-: <groups> ( seq n -- groups )
-    groups construct-groups ; inline
-
-M: groups length
-    [ seq>> length ] [ n>> ] bi [ + 1- ] keep /i ;
-
-M: groups set-length
-    [ n>> * ] [ seq>> ] bi set-length ;
-
-M: groups group@
-    [ n>> [ * dup ] keep + ] [ seq>> ] bi [ length min ] keep ;
-
-TUPLE: sliced-groups < groups ;
-
-: <sliced-groups> ( seq n -- groups )
-    sliced-groups construct-groups ; inline
-
-M: sliced-groups nth group@ <slice> ;
-
-TUPLE: clumps < abstract-groups ;
-
-: <clumps> ( seq n -- clumps )
-    clumps construct-groups ; inline
-
-M: clumps length
-    [ seq>> length ] [ n>> ] bi - 1+ ;
-
-M: clumps set-length
-    [ n>> + 1- ] [ seq>> ] bi set-length ;
-
-M: clumps group@
-    [ n>> over + ] [ seq>> ] bi ;
-
-TUPLE: sliced-clumps < groups ;
-
-: <sliced-clumps> ( seq n -- clumps )
-    sliced-clumps construct-groups ; inline
-
-M: sliced-clumps nth group@ <slice> ;
-
-: group ( seq n -- array ) <groups> { } like ;
-
-: clump ( seq n -- array ) <clumps> { } like ;
-
 : ?head ( seq begin -- newseq ? )
     2dup head? [ length tail t ] [ drop f ] if ;
 
index 0dc834ad6b35076cd04e242c9d1918ee3f50f76e..db1b875eb60fca3f52807d0668b56445181a52d8 100755 (executable)
@@ -319,9 +319,9 @@ HELP: POSTPONE:
 { $notes "This word is used inside parsing words to delegate further action to another parsing word, and to refer to parsing words literally from literal arrays and such." } ;
 
 HELP: :
-{ $syntax ": word definition... ;" }
+{ $syntax ": word ( stack -- effect ) definition... ;" }
 { $values { "word" "a new word to define" } { "definition" "a word definition" } }
-{ $description "Defines a word in the current vocabulary." }
+{ $description "Defines a word with the given stack effect in the current vocabulary. The stack effect is optional for words which only push literals on the stack." }
 { $examples { $code ": ask-name ( -- name )\n    \"What is your name? \" write readln ;\n: greet ( name -- )\n    \"Greetings, \" write print ;\n: friend ( -- )\n    ask-name greet ;" } } ;
 
 { POSTPONE: : POSTPONE: ; define } related-words
@@ -346,7 +346,7 @@ HELP: \
 { $syntax "\\ word" }
 { $values { "word" "a word" } }
 { $description "Reads the next word from the input and appends a wrapper holding the word to the parse tree. When the evaluator encounters a wrapper, it pushes the wrapped word literally on the data stack." }
-{ $examples "The following two lines are equivalent:" { $code "0 \\ <vector> execute\n0 <vector>" } } ;
+{ $examples "The following two lines are equivalent:" { $code "0 \\ <vector> execute\n0 <vector>" } "If " { $snippet "foo" } " is a symbol, the following two lines are equivalent:" { $code "foo" "\\ foo" } } ;
 
 HELP: DEFER:
 { $syntax "DEFER: word" }
@@ -413,7 +413,21 @@ HELP: (
 { $syntax "( inputs -- outputs )" }
 { $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
 { $description "Declares the stack effect of the most recently defined word, storing a new " { $link effect } " instance in the " { $snippet "\"declared-effect\"" } " word property." }
-{ $notes "Recursive words must have a declared stack effect to compile. See " { $link "effect-declaration" } " for details." } ;
+{ $notes "All words except those only pushing literals on the stack must have a stack effect declaration. See " { $link "effect-declaration" } " for details." } ;
+
+HELP: ((
+{ $syntax "(( inputs -- outputs ))" }
+{ $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
+{ $description "Literal stack effect syntax." }
+{ $notes "Useful for meta-programming with " { $link define-declared } "." }
+{ $examples
+    { $code
+        "SYMBOL: my-dynamic-word"
+        "USING: math random words ;"
+        "3 { [ + ] [ - ] [ * ] [ / ] } random curry"
+        "(( x -- y )) define-declared"
+    }
+} ;
 
 HELP: !
 { $syntax "! comment..." }
@@ -526,6 +540,9 @@ HELP: PREDICATE:
         "it satisfies the predicate"
     }
     "Each predicate must be defined as a subclass of some other class. This ensures that predicates inheriting from disjoint classes do not need to be exhaustively tested during method dispatch."
+}
+{ $examples
+    { $code "USING: math ;" "PREDICATE: positive < integer 0 > ;" }
 } ;
 
 HELP: TUPLE:
index 27c8609a99bd105dcd3ab81699c0efca3dac2691..a0d601e2ad76718d82d6ab876a775971ab401189 100755 (executable)
@@ -182,10 +182,14 @@ IN: bootstrap.syntax
     ] define-syntax
 
     "(" [
-        parse-effect word
+        ")" parse-effect word
         [ swap "declared-effect" set-word-prop ] [ drop ] if*
     ] define-syntax
 
+    "((" [
+        "))" parse-effect parsed
+    ] define-syntax
+
     "MAIN:" [ scan-word in get vocab set-vocab-main ] define-syntax
 
     "<<" [
index a1c7e208dc15021682ed287dd43a9ec6c62eb53c..c23ced42b9be999344bae00b3b5caf69a55e5744 100755 (executable)
@@ -37,11 +37,11 @@ mailbox variables sleep-entry ;
 : thread-registered? ( thread -- ? )
     id>> threads key? ;
 
-: check-unregistered
+: check-unregistered ( thread -- thread )
     dup thread-registered?
     [ "Thread already stopped" throw ] when ;
 
-: check-registered
+: check-registered ( thread -- thread )
     dup thread-registered?
     [ "Thread is not running" throw ] unless ;
 
index 1489750154be7d5b35b765850b456de802144cb4..04cf9a2ac1b712ce54d2e592b7ab928a8defa4b1 100755 (executable)
@@ -50,18 +50,18 @@ H{ } clone root-cache set-global
 
 SYMBOL: load-help?
 
-: source-was-loaded t swap set-vocab-source-loaded? ;
+: source-was-loaded ( vocab -- ) t swap set-vocab-source-loaded? ;
 
-: source-wasn't-loaded f swap set-vocab-source-loaded? ;
+: source-wasn't-loaded ( vocab -- ) f swap set-vocab-source-loaded? ;
 
 : load-source ( vocab -- )
     [ source-wasn't-loaded ] keep
     [ vocab-source-path [ bootstrap-file ] when* ] keep
     source-was-loaded ;
 
-: docs-were-loaded t swap set-vocab-docs-loaded? ;
+: docs-were-loaded ( vocab -- ) t swap set-vocab-docs-loaded? ;
 
-: docs-weren't-loaded f swap set-vocab-docs-loaded? ;
+: docs-weren't-loaded ( vocab -- ) f swap set-vocab-docs-loaded? ;
 
 : load-docs ( vocab -- )
     load-help? get [
index 14e6197683c1411220af1872cdd7228734b8fbe9..96998441924cd0ac9704e3aa91364414d7fd2c41 100755 (executable)
@@ -334,7 +334,7 @@ HELP: bootstrap-word
 { $values { "word" word } { "target" word } }
 { $description "Looks up a word with the same name and vocabulary as the given word, performing a transformation to handle parsing words in the target dictionary. Used during bootstrap to transfer host words to the target dictionary." } ;
 
-HELP: parsing?
+HELP: parsing-word?
 { $values { "obj" object } { "?" "a boolean" } }
 { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: parsing } "." }
 { $notes "Outputs " { $link f } " if the object is not a word." } ;
index 5549f980106b91df23ee9918b93aac3bce5ee4f5..22d22d83fbf0a249923cd27b0512cb7ceca995d8 100755 (executable)
@@ -102,7 +102,7 @@ SYMBOL: compiled-crossref
 compiled-crossref global [ H{ } assoc-like ] change-at
 
 : compiled-xref ( word dependencies -- )
-    [ drop compiled-crossref? ] assoc-filter
+    [ drop crossref? ] assoc-filter
     2dup "compiled-uses" set-word-prop
     compiled-crossref get add-vertex* ;
 
@@ -114,46 +114,31 @@ compiled-crossref global [ H{ } assoc-like ] change-at
     dup compiled-unxref
     compiled-crossref get delete-at ;
 
-SYMBOL: +inlined+
-SYMBOL: +called+
-
 : compiled-usage ( word -- assoc )
     compiled-crossref get at ;
 
-: compiled-usages ( words -- seq )
-    [ unique dup ] keep [
-        compiled-usage [ nip +inlined+ eq? ] assoc-filter update
-    ] with each keys ;
-
-<PRIVATE
-
-SYMBOL: visited
-
-: reset-on-redefine { "inferred-effect" "no-effect" } ; inline
-
-: (redefined) ( word -- )
-    dup visited get key? [ drop ] [
-        [ reset-on-redefine reset-props ]
-        [ dup visited get set-at ]
-        [
-            crossref get at keys
-            [ word? ] filter
-            [ reset-on-redefine [ word-prop ] with contains? ] filter
-            [ (redefined) ] each
-        ] tri
-    ] if ;
+: compiled-usages ( assoc -- seq )
+    clone [
+        dup [
+            [
+                [ compiled-usage ] dip
+                +inlined+ eq? [
+                    [ nip +inlined+ eq? ] assoc-filter
+                ] when
+            ] dip swap update
+        ] curry assoc-each
+    ] keep keys ;
 
-PRIVATE>
+GENERIC: redefined ( word -- )
 
-: redefined ( word -- )
-    H{ } clone visited [ (redefined) ] with-variable ;
+M: object redefined drop ;
 
 : define ( word def -- )
     [ ] like
     over unxref
     over redefined
     over set-word-def
-    dup changed-definition
+    dup +inlined+ changed-definition
     dup crossref? [ dup xref ] when drop ;
 
 : define-declared ( word def effect -- )
@@ -220,8 +205,7 @@ ERROR: bad-create name vocab ;
 : constructor-word ( name vocab -- word )
     >r "<" swap ">" 3append r> create ;
 
-: parsing? ( obj -- ? )
-    dup word? [ "parsing" word-prop ] [ drop f ] if ;
+PREDICATE: parsing-word < word "parsing" word-prop ;
 
 : delimiter? ( obj -- ? )
     dup word? [ "delimiter" word-prop ] [ drop f ] if ;
@@ -244,6 +228,6 @@ M: word hashcode*
 
 M: word literalize <wrapper> ;
 
-: ?word-name dup word? [ word-name ] when ;
+: ?word-name ( word -- name ) dup word? [ word-name ] when ;
 
 : xref-words ( -- ) all-words [ xref ] each ;
diff --git a/extra/alias/alias.factor b/extra/alias/alias.factor
new file mode 100755 (executable)
index 0000000..f468340
--- /dev/null
@@ -0,0 +1,16 @@
+USING: words quotations kernel effects sequences parser ;\r
+IN: alias\r
+\r
+PREDICATE: alias < word "alias" word-prop ;\r
+\r
+M: alias reset-word\r
+    [ call-next-method ] [ f "alias" set-word-prop ] bi ;\r
+\r
+M: alias stack-effect\r
+    word-def first stack-effect ;\r
+\r
+: define-alias ( new old -- )\r
+    [ 1quotation define-inline ]\r
+    [ drop t "alias" set-word-prop ] 2bi ;\r
+\r
+: ALIAS: CREATE-WORD scan-word define-alias ; parsing\r
index 50102d19292973af4a694e1a2e5b727c5486a1cd..7b46aa87de6612be9c51e1f490294d07c4e35d02 100644 (file)
@@ -48,7 +48,7 @@ SYMBOL: elements
 
 TUPLE: element syntax id tag tagclass encoding contentlength newobj objtype ;
 
-: <element> element new ;
+: <element> ( -- element ) element new ;
 
 : set-id ( -- boolean )
     read1 dup elements get set-element-id ;
index 074640c53652a55d5ffbf0f842ae5670780f6ecb..600a8f4c3dc953e38262dac63c0878fcc010d8f4 100644 (file)
@@ -1,5 +1,5 @@
 USING: kernel math sequences namespaces io.binary splitting
- strings hashtables ;
+grouping strings hashtables ;
 IN: base64
 
 <PRIVATE
index 376a75b9a3e40f5f95b80c00d68ac72143335de9..4e113d86d3cc20b5a76747f7aea2d91c891cd0a5 100644 (file)
@@ -1,7 +1,7 @@
 USING: math kernel continuations ;
 IN: benchmark.continuations
 
-: continuations-main
+: continuations-main ( -- )
     100000 [ drop [ continue ] callcc0 ] each-integer ;
 
 MAIN: continuations-main
index 53e9c9a14c6e1e3f5e7ebb2d500d6ebf3e8833e8..4e4d3f8bd577541770f4c1beccae27320cee8436 100644 (file)
@@ -1,7 +1,8 @@
-USING: namespaces math sequences splitting kernel columns ;
+USING: namespaces math sequences splitting grouping
+kernel columns ;
 IN: benchmark.dispatch2
 
-: sequences
+: sequences ( -- seq )
     [
         1 ,
         10 >bignum ,
@@ -21,9 +22,9 @@ IN: benchmark.dispatch2
         1 [ + ] curry ,
     ] { } make ;
 
-: don't-flush-me drop ;
+: don't-flush-me ( obj -- ) drop ;
 
-: dispatch-test
+: dispatch-test ( -- )
     1000000 sequences
     [ [ 0 swap nth don't-flush-me ] each ] curry times ;
 
index 409d6d4a0f1866b5dbb6bb8e763686fdb52c232d..4e4712a1a9b4d0867710e1589f1b5bed419b2e6c 100644 (file)
@@ -1,5 +1,5 @@
-USING: sequences math mirrors splitting kernel namespaces
-assocs alien.syntax columns ;
+USING: sequences math mirrors splitting grouping
+kernel namespaces assocs alien.syntax columns ;
 IN: benchmark.dispatch3
 
 GENERIC: g ( obj -- str )
@@ -14,7 +14,7 @@ M: number g drop "number" ;
 
 M: object g drop "object" ;
 
-: objects
+: objects ( -- seq )
     [
         H{ } ,
         \ + <mirror> ,
@@ -42,7 +42,7 @@ M: object g drop "object" ;
         ALIEN: 1234 ,
     ] { } make ;
 
-: dispatch-test
+: dispatch-test ( -- )
     2000000 objects [ [ g drop ] each ] curry times ;
 
 MAIN: dispatch-test
index a92772a9236d7c77b46585e99c4c8f40d92f5fa3..2f989b77231f2b82cbd064b2b8e952534c1754c0 100755 (executable)
@@ -2,7 +2,7 @@ USING: kernel.private kernel sequences math combinators
 sequences.private ;
 IN: benchmark.dispatch4
 
-: foobar-1
+: foobar-1 ( n -- val )
     dup {
         [ 0 eq? [ 0 ] [ "x" ] if ]
         [ 1 eq? [ 1 ] [ "x" ] if ]
@@ -26,7 +26,7 @@ IN: benchmark.dispatch4
         [ 19 eq? [ 19 ] [ "x" ] if ]
     } dispatch ;
 
-: foobar-2
+: foobar-2 ( n -- val )
     {
         { [ dup 0 eq? ] [ drop 0 ] }
         { [ dup 1 eq? ] [ drop 1 ] }
@@ -50,14 +50,14 @@ IN: benchmark.dispatch4
         { [ dup 19 eq? ] [ drop 19 ] }
     } cond ;
 
-: foobar-test-1
+: foobar-test-1 ( -- )
     20000000 [
         20 [
             foobar-1 drop
         ] each
     ] times ;
 
-: foobar-test-2
+: foobar-test-2 ( -- )
     20000000 [
         20 [
             foobar-2 drop
index d449c0fc5b43a0d044ab4dd96a1167f844e585d0..015f762c7b97e75db60a8d8acd3b4925b59a80a0 100755 (executable)
@@ -105,6 +105,6 @@ HINTS: random fixnum ;
 
     ] ;
 
-: run-fasta 2500000 reverse-complement-in fasta ;
+: run-fasta ( -- ) 2500000 reverse-complement-in fasta ;
 
 MAIN: run-fasta
index ad7fb0e7e13620a3f90087e2431d8ff515b9c3e8..20f18032f045f327c04dd127f08b80ab5a4de97d 100644 (file)
@@ -9,6 +9,6 @@ IN: benchmark.fib1
         swap 1 fixnum-fast fast-fixnum-fib fixnum+fast
     ] if ;
 
-: fib-main 34 fast-fixnum-fib 9227465 assert= ;
+: fib-main ( -- ) 34 fast-fixnum-fib 9227465 assert= ;
 
 MAIN: fib-main
index bedfedf6b0f450d12f1bbf29526f8aa9d9a0ed49..043a98f394dfaab317ee95c6f9eab14d6558b98c 100644 (file)
@@ -8,6 +8,6 @@ IN: benchmark.fib2
         1 fixnum- dup fixnum-fib swap 1 fixnum- fixnum-fib fixnum+
     ] if ;
 
-: fib-main 34 fixnum-fib 9227465 assert= ;
+: fib-main ( -- ) 34 fixnum-fib 9227465 assert= ;
 
 MAIN: fib-main
index c2b86f6bfaae102641bc96b98d9b9cc329e909d2..13eaef8e0cd5e387e50cef8c1b24f14176f49806 100644 (file)
@@ -4,6 +4,6 @@ IN: benchmark.fib3
 : fib ( m -- n )
     dup 1 <= [ drop 1 ] [ dup 1 - fib swap 2 - fib + ] if ;
 
-: fib-main 34 fib 9227465 assert= ;
+: fib-main ( -- ) 34 fib 9227465 assert= ;
 
 MAIN: fib-main
index a6415fb50f2efb19a5476fe466024742be390349..7cf756e11f891bbb16845029f990e4fc2a03ba48 100644 (file)
@@ -17,6 +17,6 @@ C: <box> box
         swap box-i swap box-i + <box>
     ] if ;
 
-: fib-main T{ box f 34 } tuple-fib T{ box f 9227465 } assert= ;
+: fib-main ( -- ) T{ box f 34 } tuple-fib T{ box f 9227465 } assert= ;
 
 MAIN: fib-main
index 6f4765af7b9b3a385f66798b7a131766e28750a0..7b33a5b2b410abdcc8cd3c5fefb6c62704d5d76a 100644 (file)
@@ -14,6 +14,6 @@ SYMBOL: n
         ] if
     ] with-scope ;
 
-: fib-main 30 namespace-fib 1346269 assert= ;
+: fib-main ( -- ) 30 namespace-fib 1346269 assert= ;
 
 MAIN: fib-main
index cc42028df638efc787ea024b5654c4c3fb93574c..594b451876e1968c592f0fb788d7f6a4cae04643 100755 (executable)
@@ -1,7 +1,7 @@
 IN: benchmark.fib6\r
 USING: math kernel alien ;\r
 \r
-: fib\r
+: fib ( x -- y )\r
     "int" { "int" } "cdecl" [\r
         dup 1 <= [ drop 1 ] [\r
             1- dup fib swap 1- fib +\r
@@ -9,6 +9,6 @@ USING: math kernel alien ;
     ] alien-callback\r
     "int" { "int" } "cdecl" alien-indirect ;\r
 \r
-: fib-main 25 fib drop ;\r
+: fib-main ( -- ) 25 fib drop ;\r
 \r
 MAIN: fib-main\r
index 61c22d5a295d08beba3fc2ed167e9d3d7bb48fb1..f49d21d5a36829664733903f94b73b54af176758 100644 (file)
@@ -4,14 +4,14 @@ kernel ;
 
 : <range> ( from to -- seq ) dup <slice> ; inline
 
-: vector-iter 100 [ 0 100000 <range> >vector [ ] map drop ] times ;
-: array-iter 100 [ 0 100000 <range> >array [ ] map drop ] times ;
-: string-iter 100 [ 0 100000 <range> >string [ ] map drop ] times ;
-: sbuf-iter 100 [ 0 100000 <range> >sbuf [ ] map drop ] times ;
-: reverse-iter 100 [ 0 100000 <range> >vector <reversed> [ ] map drop ] times ;
-: dot-iter 100 [ 0 100000 <range> dup v. drop ] times ;
+: vector-iter ( -- ) 100 [ 0 100000 <range> >vector [ ] map drop ] times ;
+: array-iter ( -- ) 100 [ 0 100000 <range> >array [ ] map drop ] times ;
+: string-iter ( -- ) 100 [ 0 100000 <range> >string [ ] map drop ] times ;
+: sbuf-iter ( -- ) 100 [ 0 100000 <range> >sbuf [ ] map drop ] times ;
+: reverse-iter ( -- ) 100 [ 0 100000 <range> >vector <reversed> [ ] map drop ] times ;
+: dot-iter ( -- ) 100 [ 0 100000 <range> dup v. drop ] times ;
 
-: iter-main
+: iter-main ( -- )
     vector-iter
     array-iter
     string-iter
index b9b139d7e344835da1aaccd382b2d39cad76c602..5adbb7c66844704d795ee7d350c46029b75fe37b 100755 (executable)
@@ -54,7 +54,7 @@ SYMBOL: cols
 : ppm-header ( w h -- )
     "P6\n" % swap # " " % # "\n255\n" % ;
 
-: buf-size width height * 3 * 100 + ;
+: buf-size ( -- n ) width height * 3 * 100 + ;
 
 : mandel ( -- data )
     [
index fe70246cb5dfc65cc6e0fd2c08e157c0aff42123..18dced09cc293513b72f53189da3eb490ce2f451 100644 (file)
@@ -31,6 +31,6 @@ bit-arrays namespaces io ;
     dup 1- 2^ 10000 * nsieve-bits.
     2 - 2^ 10000 * nsieve-bits. ;
 
-: nsieve-bits-main* 11 nsieve-bits-main ;
+: nsieve-bits-main* ( -- ) 11 nsieve-bits-main ;
 
 MAIN: nsieve-bits-main*
index 7cae1e2a9bc15fca2c25c26587a7a9e30d309f4e..1e327d901a9b929c2b161eeec0d78ab20dc85964 100644 (file)
@@ -30,6 +30,6 @@ arrays namespaces io ;
     dup 1 - 2^ 10000 * nsieve.
     2 - 2^ 10000 * nsieve. ;
 
-: nsieve-main* 9 nsieve-main ;
+: nsieve-main* ( -- ) 9 nsieve-main ;
 
 MAIN: nsieve-main*
index 8eb883241be0b16c5408496ecaffb19675035886..2d8cdc40c7299eb20860ebe1ac2b22410dd4e04e 100644 (file)
@@ -58,6 +58,6 @@ HINTS: gregory fixnum ;
         ] with each
     ] tabular-output ;
 
-: partial-sums-main 2500000 partial-sums ;
+: partial-sums-main ( -- ) 2500000 partial-sums ;
 
 MAIN: partial-sums-main
index 775595709a46ebd6502febd57e766a3523e76f5b..985c9a59b24477dd9f542290990bbe040d8a0cd2 100755 (executable)
@@ -1,7 +1,8 @@
 USING: io.files io.encodings.ascii random math.parser io math ;
 IN: benchmark.random
 
-: random-numbers-path "random-numbers.txt" temp-file ;
+: random-numbers-path ( -- path )
+    "random-numbers.txt" temp-file ;
 
 : write-random-numbers ( n -- )
     random-numbers-path ascii [
index 3ec8cb4245e68212279365276635989bd458da55..7d7ec244fbcde15a239fdefd10187b005effd3c9 100755 (executable)
@@ -169,7 +169,7 @@ DEFER: create ( level c r -- scene )
         [ [ oversampling sq / pgm-pixel ] each ] each
     ] B{ } make ;
 
-: raytracer-main
+: raytracer-main ( -- )
     run "raytracer.pnm" temp-file binary set-file-contents ;
 
 MAIN: raytracer-main
index f69547df6069cc9852a7a2b2c536d3be60297e8e..c8bae8a56ac7e860e1d9e1dd608afc1c2c67e447 100755 (executable)
@@ -32,6 +32,6 @@ IN: benchmark.recursive
 
 HINTS: recursive fixnum ;
 
-: recursive-main 11 recursive ;
+: recursive-main ( -- ) 11 recursive ;
 
 MAIN: recursive-main
index 5fdaf49d8f4bad3132d9d25fece63910a865c497..b7c1db043cc89e82035a3b38469ec984de3fc75d 100755 (executable)
@@ -1,6 +1,6 @@
 USING: io io.files io.streams.duplex kernel sequences
 sequences.private strings vectors words memoize splitting
-hints unicode.case continuations io.encodings.ascii ;
+grouping hints unicode.case continuations io.encodings.ascii ;
 IN: benchmark.reverse-complement
 
 MEMO: trans-map ( -- str )
@@ -38,10 +38,10 @@ HINTS: do-line vector string ;
         ] with-file-reader
     ] with-file-writer ;
 
-: reverse-complement-in
+: reverse-complement-in ( -- path )
     "reverse-complement-in.txt" temp-file ;
 
-: reverse-complement-out
+: reverse-complement-out ( -- path )
     "reverse-complement-out.txt" temp-file ;
 
 : reverse-complement-main ( -- )
index 673a67d93f68b8e6ec5e62c036ecbfb0d3abe865..66c9c11167d8fda2233e332ea46cfb251a90612f 100755 (executable)
@@ -8,7 +8,7 @@ SYMBOL: counter
 
 : number-of-requests 1 ;
 
-: server-addr "127.0.0.1" 7777 <inet4> ;
+: server-addr ( -- addr ) "127.0.0.1" 7777 <inet4> ;
 
 : server-loop ( server -- )
     dup accept drop [
index cd6189fe225cfad28d2e11e9788f0b59a61652a2..983a9e86b1017c066e504e04b00b82d68e8028a8 100755 (executable)
@@ -2,7 +2,7 @@ USING: kernel sequences sorting benchmark.random math.parser
 io.files io.encodings.ascii ;
 IN: benchmark.sort
 
-: sort-benchmark
+: sort-benchmark ( -- )
     random-numbers-path
     ascii file-lines [ string>number ] map
     natural-sort drop ;
index fd7bb6e80295171e31bd74205aaa343ffa652f69..434094a2a38489c91f4160b63bcb33b999e46949 100644 (file)
@@ -3,8 +3,8 @@ IN: benchmark.typecheck1
 
 TUPLE: hello n ;
 
-: foo 0 100000000 [ over hello-n + ] times ;
+: foo ( obj -- obj n ) 0 100000000 [ over hello-n + ] times ;
 
-: typecheck-main 0 hello boa foo 2drop ;
+: typecheck-main ( -- ) 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 0dfcc17c66491fb63c6c65747192306ec2c76f59..f408389e694d2a8630a5a4270324da094f236961 100644 (file)
@@ -3,10 +3,10 @@ IN: benchmark.typecheck2
 
 TUPLE: hello n ;
 
-: hello-n* dup tuple? [ 3 slot ] [ 3 throw ] if ;
+: hello-n* ( obj -- value ) dup tuple? [ 3 slot ] [ 3 throw ] if ;
 
-: foo 0 100000000 [ over hello-n* + ] times ;
+: foo ( obj -- obj n ) 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello boa foo 2drop ;
+: typecheck-main ( -- ) 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 3ca6a9f9e7b55136b1faea7d55678dc2981773d6..b15d81df566cfe6b699d6986d9953c21be6c74e7 100644 (file)
@@ -3,10 +3,10 @@ IN: benchmark.typecheck3
 
 TUPLE: hello n ;
 
-: hello-n* dup tag 2 eq? [ 3 slot ] [ 3 throw ] if ;
+: hello-n* ( obj -- val ) dup tag 2 eq? [ 3 slot ] [ 3 throw ] if ;
 
-: foo 0 100000000 [ over hello-n* + ] times ;
+: foo ( obj -- obj n ) 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello boa foo 2drop ;
+: typecheck-main ( -- ) 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index cc3310fef6c2b35e70a4106c7be0a2b0d1ecc6c3..a2595810be1358c16b45117f2beb2c1dc20c1a6b 100644 (file)
@@ -3,10 +3,10 @@ IN: benchmark.typecheck4
 
 TUPLE: hello n ;
 
-: hello-n* 3 slot ;
+: hello-n* ( obj -- val ) 3 slot ;
 
-: foo 0 100000000 [ over hello-n* + ] times ;
+: foo ( obj -- obj n ) 0 100000000 [ over hello-n* + ] times ;
 
-: typecheck-main 0 hello boa foo 2drop ;
+: typecheck-main ( -- ) 0 hello boa foo 2drop ;
 
 MAIN: typecheck-main
index 7fcec00e984a6dba2885adf55a269b7c974b0871..7d3ef8975942e10369cb7870046eaf94a45b21c1 100644 (file)
@@ -101,7 +101,7 @@ M: check< summary drop "Number exceeds upper bound" ;
         >ranges filter-pad [ define-setters ] 2keep define-accessors
     ] with-compilation-unit ;
 
-: parse-bitfield 
+: parse-bitfield ( -- )
     scan ";" parse-tokens parse-slots define-bitfield ;
 
 : BITFIELD:
index 9dd4fd04b25ffd3fa8806556e676479b9b28108a..e2a2288988f6f79ac161b4a118dbd0a7e0f68579 100755 (executable)
@@ -3,7 +3,7 @@ help.definitions io io.files kernel namespaces vocabs sequences
 parser vocabs.loader ;
 IN: bootstrap.help
 
-: load-help
+: load-help ( -- )
     "alien.syntax" require
     "compiler" require
 
index 29c9d5b072e0ab6ad3520e6a687fa95b925f7f4b..de13b4aed43fc28b2e6e0d2908b2cbbe5f7d06ee 100755 (executable)
@@ -12,9 +12,9 @@ SYMBOL: upload-images-destination
   "slava@factorcode.org:/var/www/factorcode.org/newsite/images/latest/"
   or ;
 
-: checksums "checksums.txt" temp-file ;
+: checksums ( -- temp ) "checksums.txt" temp-file ;
 
-: boot-image-names images [ boot-image-name ] map ;
+: boot-image-names ( -- seq ) images [ boot-image-name ] map ;
 
 : compute-checksums ( -- )
     checksums ascii [
index 8fef44a76a9a82e0cb8f4f38bd316a496b7fac68..b1f2f19d9c03fb6fce09d63c6147b3121615c9e8 100755 (executable)
@@ -38,9 +38,9 @@ IN: bunny.model
     ascii [ parse-model ] with-file-reader
     [ normals ] 2keep 3array ;
 
-: model-path "bun_zipper.ply" temp-file ;
+: model-path ( -- path ) "bun_zipper.ply" temp-file ;
 
-: model-url "http://factorcode.org/bun_zipper.ply" ;
+: model-url ( -- url ) "http://factorcode.org/bun_zipper.ply" ;
 
 : maybe-download ( -- path )
     model-path dup exists? [
index f5f4d3e9651bdad04d08103e4f0857fa1dc85527..c9fef618f8e9d5884c2d1a3734dde608d366a98d 100644 (file)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: sequences math opengl.gadgets kernel
 byte-arrays cairo.ffi cairo io.backend
-opengl.gl arrays ;
+ui.gadgets accessors opengl.gl
+arrays ;
 
 IN: cairo.gadgets
 
@@ -12,11 +13,23 @@ IN: cairo.gadgets
     >r first2 over width>stride
     [ * nip <byte-array> dup CAIRO_FORMAT_ARGB32 ]
     [ cairo_image_surface_create_for_data ] 3bi
-    r> with-cairo-from-surface ;
+    r> with-cairo-from-surface ; inline
 
-: <cairo-gadget> ( dim quot -- )
-    over 2^-bounds swap copy-cairo
-    GL_BGRA rot <texture-gadget> ;
+TUPLE: cairo-gadget < texture-gadget dim quot ;
+
+: <cairo-gadget> ( dim quot -- gadget )
+    cairo-gadget construct-gadget
+        swap >>quot
+        swap >>dim ;
+
+M: cairo-gadget cache-key* [ dim>> ] [ quot>> ] bi 2array ;
+
+: render-cairo ( dim quot -- bytes format )
+    >r 2^-bounds r> copy-cairo GL_BGRA ; inline
+
+! M: cairo-gadget render*
+!     [ dim>> dup ] [ quot>> ] bi
+!     render-cairo render-bytes* ;
 
 ! maybe also texture>png
 ! : cairo>png ( gadget path -- )
@@ -29,11 +42,16 @@ IN: cairo.gadgets
     cr swap 0 0 cairo_set_source_surface
     cr cairo_paint ;
 
-: <png-gadget> ( path -- gadget )
-    normalize-path cairo_image_surface_create_from_png
+TUPLE: png-gadget < texture-gadget path ;
+: <png> ( path -- gadget )
+    png-gadget construct-gadget
+        swap >>path ;
+
+M: png-gadget render*
+    path>> normalize-path cairo_image_surface_create_from_png
     [ cairo_image_surface_get_width ]
     [ cairo_image_surface_get_height 2array dup 2^-bounds ]
     [ [ copy-surface ] curry copy-cairo ] tri
-    GL_BGRA rot <texture-gadget> ;
-
+    GL_BGRA render-bytes* ;
 
+M: png-gadget cache-key* path>> ;
index 0e21876fe92bd7de8d54b198ca2f496e47f144a3..e3cf84910913162e26a5d9f7bdad2a70a71909f3 100755 (executable)
@@ -3,7 +3,8 @@
 
 USING: arrays kernel math math.functions namespaces sequences
 strings system vocabs.loader calendar.backend threads
-accessors combinators locals classes.tuple math.order ;
+accessors combinators locals classes.tuple math.order
+memoize ;
 IN: calendar
 
 TUPLE: timestamp year month day hour minute second gmt-offset ;
@@ -89,14 +90,14 @@ PRIVATE>
 : >time< ( timestamp -- hour minute second )
     [ hour>> ] [ minute>> ] [ second>> ] tri ;
 
-: instant ( -- dt ) 0 0 0 0 0 0 <duration> ;
-: years ( n -- dt ) instant swap >>year ;
-: months ( n -- dt ) instant swap >>month ;
-: days ( n -- dt ) instant swap >>day ;
+MEMO: instant ( -- dt ) 0 0 0 0 0 0 <duration> ;
+: years ( n -- dt ) instant clone swap >>year ;
+: months ( n -- dt ) instant clone swap >>month ;
+: days ( n -- dt ) instant clone swap >>day ;
 : weeks ( n -- dt ) 7 * days ;
-: hours ( n -- dt ) instant swap >>hour ;
-: minutes ( n -- dt ) instant swap >>minute ;
-: seconds ( n -- dt ) instant swap >>second ;
+: hours ( n -- dt ) instant clone swap >>hour ;
+: minutes ( n -- dt ) instant clone swap >>minute ;
+: seconds ( n -- dt ) instant clone swap >>second ;
 : milliseconds ( n -- dt ) 1000 / seconds ;
 
 GENERIC: leap-year? ( obj -- ? )
@@ -273,14 +274,15 @@ M: timestamp time-
 M: duration time-
     before time+ ;
 
-: <zero> 0 0 0 0 0 0 instant <timestamp> ;
+MEMO: <zero> ( -- timestamp )
+0 0 0 0 0 0 instant <timestamp> ;
 
 : valid-timestamp? ( timestamp -- ? )
     clone instant >>gmt-offset
     dup <zero> time- <zero> time+ = ;
 
-: unix-1970 ( -- timestamp )
-    1970 1 1 0 0 0 instant <timestamp> ; foldable
+MEMO: unix-1970 ( -- timestamp )
+    1970 1 1 0 0 0 instant <timestamp> ;
 
 : millis>timestamp ( n -- timestamp )
     >r unix-1970 r> milliseconds time+ ;
index ff1811e9d595aacc58b4ff4e9149b4c6b8323f81..15dee790066fa795173fcc9ed0462c5bafc22ce9 100755 (executable)
@@ -4,46 +4,46 @@ combinators accessors debugger
 calendar calendar.format.macros ;\r
 IN: calendar.format\r
 \r
-: pad-00 number>string 2 CHAR: 0 pad-left ;\r
+: pad-00 ( n -- str ) number>string 2 CHAR: 0 pad-left ;\r
 \r
-: pad-0000 number>string 4 CHAR: 0 pad-left ;\r
+: pad-0000 ( n -- str ) number>string 4 CHAR: 0 pad-left ;\r
 \r
-: pad-00000 number>string 5 CHAR: 0 pad-left ;\r
+: pad-00000 ( n -- str ) number>string 5 CHAR: 0 pad-left ;\r
 \r
-: write-00 pad-00 write ;\r
+: write-00 ( n -- ) pad-00 write ;\r
 \r
-: write-0000 pad-0000 write ;\r
+: write-0000 ( n -- ) pad-0000 write ;\r
 \r
-: write-00000 pad-00000 write ;\r
+: write-00000 ( n -- ) pad-00000 write ;\r
 \r
-: hh hour>> write-00 ;\r
+: hh ( time -- ) hour>> write-00 ;\r
 \r
-: mm minute>> write-00 ;\r
+: mm ( time -- ) minute>> write-00 ;\r
 \r
-: ss second>> >integer write-00 ;\r
+: ss ( time -- ) second>> >integer write-00 ;\r
 \r
-: D day>> number>string write ;\r
+: D ( time -- ) day>> number>string write ;\r
 \r
-: DD day>> write-00 ;\r
+: DD ( time -- ) day>> write-00 ;\r
 \r
-: DAY day-of-week day-abbreviations3 nth write ;\r
+: DAY ( time -- ) day-of-week day-abbreviations3 nth write ;\r
 \r
-: MM month>> write-00 ;\r
+: MM ( time -- ) month>> write-00 ;\r
 \r
-: MONTH month>> month-abbreviations nth write ;\r
+: MONTH ( time -- ) month>> month-abbreviations nth write ;\r
 \r
-: YYYY year>> write-0000 ;\r
+: YYYY ( time -- ) year>> write-0000 ;\r
 \r
-: YYYYY year>> write-00000 ;\r
+: YYYYY ( time -- ) year>> write-00000 ;\r
 \r
 : expect ( str -- )\r
     read1 swap member? [ "Parse error" throw ] unless ;\r
 \r
-: read-00 2 read string>number ;\r
+: read-00 ( -- n ) 2 read string>number ;\r
 \r
-: read-000 3 read string>number ;\r
+: read-000 ( -- n ) 3 read string>number ;\r
 \r
-: read-0000 4 read string>number ;\r
+: read-0000 ( -- n ) 4 read string>number ;\r
 \r
 GENERIC: day. ( obj -- )\r
 \r
@@ -261,7 +261,7 @@ ERROR: invalid-timestamp-format ;
 : timestamp>ymd ( timestamp -- str )\r
     [ (timestamp>ymd) ] with-string-writer ;\r
 \r
-: (timestamp>hms)\r
+: (timestamp>hms) ( timestamp -- )\r
     { hh ":" mm ":" ss } formatted ;\r
 \r
 : timestamp>hms ( timestamp -- str )\r
index 91a8f80894269561060aac03ac09167ce7318359..544332770f70cc6749eb382231eab15bd60d4308 100644 (file)
@@ -7,7 +7,8 @@ IN: calendar.format.macros
 
 [ { [ 1 throw ] } attempt-all-quots ] [ 1 = ] must-fail-with
 
-: compiled-test-1 { [ 1 throw ] [ 2 ] } attempt-all-quots ;
+: compiled-test-1 ( -- n )
+    { [ 1 throw ] [ 2 ] } attempt-all-quots ;
 
 \ compiled-test-1 must-infer
 
index a385f6d04f9303fcf8d7be148304fcef8df9b3fb..f0e0c71c19aa99ae6bc940741a504f6038c58ea7 100755 (executable)
@@ -1,7 +1,7 @@
 ! See http://www.faqs.org/rfcs/rfc1321.html
 
 USING: kernel io io.binary io.files io.streams.byte-array math
-math.functions math.parser namespaces splitting strings
+math.functions math.parser namespaces splitting grouping strings
 sequences crypto.common byte-arrays locals sequences.private
 io.encodings.binary symbols math.bitfields.lib checksums ;
 IN: checksums.md5
@@ -74,7 +74,7 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
 : S43 15 ; inline
 : S44 21 ; inline
 
-: (process-md5-block-F)
+: (process-md5-block-F) ( block -- block )
     dup S11 1  0  [ F ] ABCD
     dup S12 2  1  [ F ] DABC
     dup S13 3  2  [ F ] CDAB
@@ -92,7 +92,7 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
     dup S13 15 14 [ F ] CDAB
     dup S14 16 15 [ F ] BCDA ;
 
-: (process-md5-block-G)
+: (process-md5-block-G) ( block -- block )
     dup S21 17 1  [ G ] ABCD
     dup S22 18 6  [ G ] DABC
     dup S23 19 11 [ G ] CDAB
@@ -110,7 +110,7 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
     dup S23 31 7  [ G ] CDAB
     dup S24 32 12 [ G ] BCDA ;
 
-: (process-md5-block-H)
+: (process-md5-block-H) ( block -- block )
     dup S31 33 5  [ H ] ABCD
     dup S32 34 8  [ H ] DABC
     dup S33 35 11 [ H ] CDAB
@@ -128,7 +128,7 @@ SYMBOLS: a b c d old-a old-b old-c old-d ;
     dup S33 47 15 [ H ] CDAB
     dup S34 48 2  [ H ] BCDA ;
 
-: (process-md5-block-I)
+: (process-md5-block-I) ( block -- block )
     dup S41 49 0  [ I ] ABCD
     dup S42 50 7  [ I ] DABC
     dup S43 51 14 [ I ] CDAB
index e5f16c9c1191cde9e597f7e022a233f8b4f45832..6cf7914e6c25275a7e6e2d691fa94b642c278b66 100755 (executable)
@@ -1,5 +1,6 @@
-USING: crypto.common kernel splitting math sequences namespaces
-io.binary symbols math.bitfields.lib checksums ;
+USING: crypto.common kernel splitting grouping
+math sequences namespaces io.binary symbols
+math.bitfields.lib checksums ;
 IN: checksums.sha2
 
 <PRIVATE
index f917e20bc4d36dc462707c01b29708a4d4a33367..624a6d802ba749d6f6194510d8061b7abdcea2cf 100755 (executable)
@@ -4,7 +4,7 @@ USING: alien alien.c-types alien.strings alien.compiler
 arrays assocs combinators compiler inference.transforms kernel
 math namespaces parser prettyprint prettyprint.sections
 quotations sequences strings words cocoa.runtime io macros
-memoize debugger io.encodings.ascii ;
+memoize debugger io.encodings.ascii effects ;
 IN: cocoa.messages
 
 : make-sender ( method function -- quot )
@@ -196,7 +196,8 @@ H{
 : define-objc-class-word ( name quot -- )
     [
         over , , \ unless-defined , dup , \ objc-class ,
-    ] [ ] make >r "cocoa.classes" create r> define ;
+    ] [ ] make >r "cocoa.classes" create r>
+    (( -- class )) define-declared ;
 
 : import-objc-class ( name quot -- )
     2dup unless-defined
index 1f94e018c9d6829058f2f7d9e2c9695869eaa884..aa03d3d8ee0382326925f9fecd91868d56aa39da 100755 (executable)
@@ -84,7 +84,8 @@ M: linked-error error.
 \r
 C: <linked-error> linked-error\r
 \r
-: ?linked dup linked-error? [ rethrow ] when ;\r
+: ?linked ( message -- message )\r
+    dup linked-error? [ rethrow ] when ;\r
 \r
 TUPLE: linked-thread < thread supervisor ;\r
 \r
index 66c5e421fab01cf54ba2b85c6ce9ebcf077fa3be..e77760408c1f090bd5a18661001cd6627925f304 100755 (executable)
@@ -17,7 +17,7 @@ GENERIC: send ( message thread -- )
 M: thread send ( message thread -- )\r
     check-registered mailbox-of mailbox-put ;\r
 \r
-: my-mailbox self mailbox-of ;\r
+: my-mailbox ( -- mailbox ) self mailbox-of ;\r
 \r
 : receive ( -- message )\r
     my-mailbox mailbox-get ?linked ;\r
diff --git a/extra/cords/authors.txt b/extra/cords/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/cords/cords-tests.factor b/extra/cords/cords-tests.factor
new file mode 100644 (file)
index 0000000..0058c8f
--- /dev/null
@@ -0,0 +1,5 @@
+IN: cords.tests
+USING: cords strings tools.test kernel sequences ;
+
+[ "hello world" ] [ "hello" " world" cord-append dup like ] unit-test
+[ "hello world" ] [ { "he" "llo" " world" } cord-concat dup like ] unit-test
diff --git a/extra/cords/cords.factor b/extra/cords/cords.factor
new file mode 100644 (file)
index 0000000..f5cc89f
--- /dev/null
@@ -0,0 +1,70 @@
+! Copysecond (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs sequences sorting math math.order
+arrays combinators kernel ;
+IN: cords
+
+<PRIVATE
+
+TUPLE: simple-cord first second ;
+
+M: simple-cord length
+    [ first>> length ] [ second>> length ] bi + ;
+
+M: simple-cord virtual-seq first>> ;
+
+M: simple-cord virtual@
+    2dup first>> length <
+    [ first>> ] [ [ first>> length - ] [ second>> ] bi ] if ;
+
+TUPLE: multi-cord count seqs ;
+
+M: multi-cord length count>> ;
+
+M: multi-cord virtual@
+    dupd
+    seqs>> [ first <=> ] binsearch*
+    [ first - ] [ second ] bi ;
+
+M: multi-cord virtual-seq
+    seqs>> dup empty? [ drop f ] [ first second ] if ;
+
+: <cord> ( seqs -- cord )
+    dup length 2 = [
+        first2 simple-cord boa
+    ] [
+        [ 0 [ length + ] accumulate ] keep zip multi-cord boa
+    ] if ;
+
+PRIVATE>
+
+UNION: cord simple-cord multi-cord ;
+
+INSTANCE: cord virtual-sequence
+
+INSTANCE: multi-cord virtual-sequence
+
+: cord-append ( seq1 seq2 -- cord )
+    {
+        { [ over empty? ] [ nip ] }
+        { [ dup empty? ] [ drop ] }
+        { [ 2dup [ cord? ] both? ] [ [ seqs>> values ] bi@ append <cord> ] }
+        { [ over cord? ] [ [ seqs>> values ] dip suffix <cord> ] }
+        { [ dup cord? ] [ seqs>> values swap prefix <cord> ] }
+        [ 2array <cord> ]
+    } cond ;
+
+: cord-concat ( seqs -- cord )
+    {
+        { [ dup empty? ] [ drop f ] }
+        { [ dup length 1 = ] [ first ] }
+        [
+            [
+                {
+                    { [ dup cord? ] [ seqs>> values ] }
+                    { [ dup empty? ] [ drop { } ] }
+                    [ 1array ]
+                } cond
+            ] map concat <cord>
+        ]
+    } cond ;
diff --git a/extra/cords/summary.txt b/extra/cords/summary.txt
new file mode 100644 (file)
index 0000000..3c69862
--- /dev/null
@@ -0,0 +1 @@
+Virtual sequence concatenation
diff --git a/extra/cords/tags.txt b/extra/cords/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 261e1d045a801824c6d033689753b297979d4101..f14dba643377d94250b5cd7a93591ed4f8961ae5 100644 (file)
@@ -149,7 +149,8 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef
 
 SYMBOL: event-stream-callbacks
 
-: event-stream-counter \ event-stream-counter counter ;
+: event-stream-counter ( -- n )
+    \ event-stream-counter counter ;
 
 [
     event-stream-callbacks global
index f1af0ef15ef07366d165a744298b2b82547d79fd..b0ffb6ae544f56174e0878ac3202cb76555453dd 100755 (executable)
@@ -3,7 +3,7 @@
 !
 USING: kernel math sequences words arrays io io.files namespaces
 math.parser assocs quotations parser parser-combinators
-tools.time io.encodings.binary ;
+tools.time io.encodings.binary sequences.deep symbols combinators ;
 IN: cpu.8080.emulator
 
 TUPLE: cpu b c d e f h l a pc sp halted? last-interrupt cycles ram ;
@@ -563,29 +563,18 @@ SYMBOL: rom-root
     { "M" { flag-m?  } }
   } at ;
 
-SYMBOL: $1
-SYMBOL: $2
-SYMBOL: $3
-SYMBOL: $4
+SYMBOLS: $1 $2 $3 $4 ;
 
 : replace-patterns ( vector tree -- tree )
-  #! Copy the tree, replacing each occurence of 
-  #! $1, $2, etc with the relevant item from the 
-  #! given index.
-  dup quotation? over [ ] = not and [ ! vector tree
-    dup first swap rest ! vector car cdr
-    >r dupd replace-patterns ! vector v R: cdr
-    swap r> replace-patterns >r 1quotation r> append
-  ] [ ! vector value
-    dup $1 = [ drop 0 over nth  ] when 
-    dup $2 = [ drop 1 over nth  ] when 
-    dup $3 = [ drop 2 over nth  ] when 
-    dup $4 = [ drop 3 over nth  ] when 
-    nip
-  ] if ;
-
-: test-rp 
-  { 4 5 3 } [ 1 $2 [ $1 4 ] ] replace-patterns ;
+  [
+    {
+      { $1 [ first ] }
+      { $2 [ second ] }
+      { $3 [ third ] }
+      { $4 [ fourth ] }
+      [ nip ]
+    } case
+  ] with deep-map ;
 
 : (emulate-RST) ( n cpu -- )
   #! RST nn
@@ -766,7 +755,7 @@ SYMBOL: $4
   "H" token  <|>
   "L" token  <|> [ register-lookup ] <@ ;
 
-: all-flags
+: all-flags ( -- parser )
   #! A parser for 16-bit flags. 
   "NZ" token  
   "NC" token <|>
@@ -777,7 +766,7 @@ SYMBOL: $4
   "P" token <|> 
   "M" token <|> [ flag-lookup ] <@ ;
 
-: 16-bit-registers
+: 16-bit-registers ( -- parser )
   #! A parser for 16-bit registers. On a successfull parse the
   #! parse tree contains a vector. The first item in the vector
   #! is the getter word for that register with stack effect
@@ -1098,27 +1087,27 @@ SYMBOL: $4
   16-bit-registers indirect <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
   
-: LD-RR,NN-instruction
+: LD-RR,NN-instruction ( -- parser )
   #! LD BC,nn
   "LD-RR,NN" "LD" complex-instruction
   16-bit-registers sp <&>
   ",nn" token <& 
   just [ first2 swap curry ] <@ ;
 
-: LD-R,N-instruction
+: LD-R,N-instruction ( -- parser )
   #! LD B,n
   "LD-R,N" "LD" complex-instruction
   8-bit-registers sp <&>
   ",n" token <& 
   just [ first2 swap curry ] <@ ;
   
-: LD-(RR),N-instruction
+: LD-(RR),N-instruction ( -- parser )
   "LD-(RR),N" "LD" complex-instruction
   16-bit-registers indirect sp <&> 
   ",n" token <&
   just [ first2 swap curry ] <@ ;
 
-: LD-(RR),R-instruction
+: LD-(RR),R-instruction ( -- parser )
   #! LD (BC),A
   "LD-(RR),R" "LD" complex-instruction
   16-bit-registers indirect sp <&> 
@@ -1126,84 +1115,84 @@ SYMBOL: $4
   8-bit-registers <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: LD-R,R-instruction
+: LD-R,R-instruction ( -- parser )
   "LD-R,R" "LD" complex-instruction
   8-bit-registers sp <&> 
   "," token <&
   8-bit-registers <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: LD-RR,RR-instruction
+: LD-RR,RR-instruction ( -- parser )
   "LD-RR,RR" "LD" complex-instruction
   16-bit-registers sp <&> 
   "," token <&
   16-bit-registers <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: LD-R,(RR)-instruction
+: LD-R,(RR)-instruction ( -- parser )
   "LD-R,(RR)" "LD" complex-instruction
   8-bit-registers sp <&> 
   "," token <&
   16-bit-registers indirect <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: LD-(NN),RR-instruction
+: LD-(NN),RR-instruction ( -- parser )
   "LD-(NN),RR" "LD" complex-instruction
   "nn" token indirect sp <&
   "," token <&
   16-bit-registers <&>
   just [ first2 swap curry ] <@ ;
 
-: LD-(NN),R-instruction
+: LD-(NN),R-instruction ( -- parser )
   "LD-(NN),R" "LD" complex-instruction
   "nn" token indirect sp <&
   "," token <&
   8-bit-registers <&>
   just [ first2 swap curry ] <@ ;
 
-: LD-RR,(NN)-instruction
+: LD-RR,(NN)-instruction ( -- parser )
   "LD-RR,(NN)" "LD" complex-instruction
   16-bit-registers sp <&>
   "," token <&
   "nn" token indirect <&
   just [ first2 swap curry ] <@ ;
 
-: LD-R,(NN)-instruction
+: LD-R,(NN)-instruction ( -- parser )
   "LD-R,(NN)" "LD" complex-instruction
   8-bit-registers sp <&>
   "," token <&
   "nn" token indirect <&
   just [ first2 swap curry ] <@ ;
 
-: OUT-(N),R-instruction
+: OUT-(N),R-instruction ( -- parser )
   "OUT-(N),R" "OUT" complex-instruction
   "n" token indirect sp <&
   "," token <&
   8-bit-registers <&>
   just [ first2 swap curry ] <@ ;
 
-: IN-R,(N)-instruction
+: IN-R,(N)-instruction ( -- parser )
   "IN-R,(N)" "IN" complex-instruction
   8-bit-registers sp <&>
   "," token <&
   "n" token indirect <&
   just [ first2 swap curry ] <@ ;
 
-: EX-(RR),RR-instruction
+: EX-(RR),RR-instruction ( -- parser )
   "EX-(RR),RR" "EX" complex-instruction
   16-bit-registers indirect sp <&> 
   "," token <&
   16-bit-registers <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: EX-RR,RR-instruction
+: EX-RR,RR-instruction ( -- parser )
   "EX-RR,RR" "EX" complex-instruction
   16-bit-registers sp <&> 
   "," token <&
   16-bit-registers <&>
   just [ first2 swap first2 swap >r prepend r> curry ] <@ ;  
 
-: 8080-generator-parser
+: 8080-generator-parser ( -- parser )
   NOP-instruction 
   RST-0-instruction <|> 
   RST-8-instruction <|> 
@@ -1296,7 +1285,7 @@ SYMBOL: last-opcode
   #! that would implement that instruction.
   dup " " join instruction-quotations
   >r "_" join [ "emulate-" % % ] "" make create-in dup last-instruction global set-at  
-  r> define ;
+  r> (( cpu -- )) define-declared ;
 
 : INSTRUCTION: ";" parse-tokens parse-instructions ; parsing
 
index efe4653ebafef13209a83f27d9ffb9ba2de862fa..651bd51774164a7316a16239119557c7fcc7176a 100644 (file)
@@ -1,6 +1,6 @@
-USING: arrays kernel io io.binary sbufs splitting strings sequences
-namespaces math math.parser parser hints math.bitfields.lib
-assocs ;
+USING: arrays kernel io io.binary sbufs splitting grouping
+strings sequences namespaces math math.parser parser
+hints math.bitfields.lib assocs ;
 IN: crypto.common
 
 : w+ ( int int -- int ) + 32 bits ; inline
index 3686afa80cb167976cecd9ae8a2a041b71e8e4b7..4358d7f3de6d5de9a14f618235b7ac24797e95be 100755 (executable)
@@ -281,7 +281,7 @@ FUNCTION: void PQclear ( PGresult* res ) ;
 FUNCTION: void PQfreemem ( void* ptr ) ;
 
 ! Exists for backward compatibility.
-: PQfreeNotify PQfreemem ;
+: PQfreeNotify ( ptr -- ) PQfreemem ;
 
 !
 ! Make an empty PGresult with given status (some apps find this
index ebcc67374b4d74f7f8cb1ed534049cf981a6849f..e99bc414494abe5c44b5c39c4838d11a14cb1aa1 100755 (executable)
@@ -66,10 +66,10 @@ M: postgresql-result-null summary ( obj -- str )
 : param-types ( statement -- seq )
     in-params>> [ type>> type>oid ] map >c-uint-array ;
 
-: malloc-byte-array/length
+: malloc-byte-array/length ( byte-array -- alien length )
     [ malloc-byte-array &free ] [ length ] bi ;
 
-: default-param-value
+: default-param-value ( obj -- alien n )
     number>string* dup [ utf8 malloc-string &free ] when 0 ;
 
 : param-values ( statement -- seq seq2 )
index 82c6e370bd6dfd4456549be8dcb23d5839e63f2c..ae748731b12ae97065b6675ef9f3455d4b88ecb6 100755 (executable)
@@ -7,10 +7,10 @@ SYMBOLS: insert update delete select distinct columns from as
 where group-by having order-by limit offset is-null desc all
 any count avg table values ;
 
-: input-spec, 1, ;
-: output-spec, 2, ;
-: input, 3, ;
-: output, 4, ;
+: input-spec, ( obj -- ) 1, ;
+: output-spec, ( obj -- ) 2, ;
+: input, ( obj -- ) 3, ;
+: output, ( obj -- ) 4, ;
 
 DEFER: sql%
 
index bac141d6d28e634b49c31fb0febc739ed152c143..0fe2f3577e592ee7924b44b4c0094a3685ccdc31 100755 (executable)
@@ -149,6 +149,9 @@ M: retryable execute-statement* ( statement type -- )
 : select-tuples ( tuple -- tuples )
     dup dup class <select-by-slots-statement> do-select ;
 
+: count-tuples ( tuple -- n )
+    select-tuples length ;
+
 : select-tuple ( tuple -- tuple/f )
     dup dup class f f f 1 <advanced-select-statement>
     do-select ?first ;
index 1e83c15694bf81d590d0bd4b53befc510aeb58e1..81310c16c0715ab63d481d619a40371f06a05f65 100755 (executable)
@@ -12,8 +12,7 @@ PROTOCOL: sequence-protocol
 
 PROTOCOL: assoc-protocol
     at* assoc-size >alist set-at assoc-clone-like
-    { assoc-find 1 } delete-at clear-assoc new-assoc
-    assoc-like ;
+    delete-at clear-assoc new-assoc assoc-like ;
 
 PROTOCOL: input-stream-protocol
     stream-read1 stream-read stream-read-partial stream-readln
diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor
new file mode 100644 (file)
index 0000000..7c33265
--- /dev/null
@@ -0,0 +1,139 @@
+
+USING: kernel
+       combinators
+       sequences
+       math
+       io.sockets
+       unicode.case
+       accessors
+       combinators.cleave
+       newfx
+       dns ;
+
+IN: dns.server
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: records ( -- vector ) V{ } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: filter-by-name ( records name -- records ) swap [ name>> = ] with filter ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: {name-type-class} ( obj -- array )
+  { [ name>> >lower ] [ type>> ] [ class>> ] } <arr> ;
+
+: rr=query? ( obj obj -- ? ) [ {name-type-class} ] bi@ = ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: matching-rrs  ( query -- rrs ) records [ rr=query? ] with filter ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: matching-rrs? ( query -- query rrs/f ? ) dup matching-rrs dup empty? not ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: matching-cname? ( query -- query rr/f ? )
+  dup clone CNAME >>type matching-rrs
+  dup empty? [ drop f f ] [ 1st t ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+DEFER: query->rrs
+
+: query-canonical ( query rr -- rrs )
+  tuck [ clone ] [ rdata>> ] bi* >>name query->rrs prefix-on ;
+
+: query->rrs ( query -- rrs/f )
+    {
+      { [      matching-rrs?   ] [ nip ] }
+      { [ drop matching-cname? ] [ query-canonical ] }
+      { [ drop t               ] [ drop f ] }
+    }
+  cond ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: cdr-name ( name -- name ) dup CHAR: . index 1+ tail ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: delegate-servers? ( name -- name rrs ? )
+  dup NS IN query boa matching-rrs dup empty? not ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: delegate-servers ( name -- rrs )
+    {
+      { [ dup "" = ]          [ drop { } ] }
+      { [ delegate-servers? ] [ nip ] }
+      { [ drop t ]            [ cdr-name delegate-servers ] }
+    }
+  cond ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: delegate-addresses ( rrs-ns -- rrs-a )
+  [ rdata>> A IN query boa matching-rrs ] map concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: have-delegates? ( query -- query rrs-ns ? )
+  dup name>> delegate-servers dup empty? not ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: fill-additional ( message -- message )
+  dup authority-section>> delegate-addresses >>additional-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: no-records-with-name? ( query -- query ? )
+  dup name>> records [ name>> = ] with filter empty? ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: find-answer ( message -- message )
+  dup message-query                     ! message query
+    {
+      { [ dup query->rrs dup   ] [ nip >>answer-section 1 >>aa ] }
+      { [ drop have-delegates? ] [ nip >>authority-section fill-additional ] }
+      { [ drop no-records-with-name? ] [ drop NAME-ERROR >>rcode ] }
+      { [ drop t ] [ ] }
+    }
+  cond ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: (socket) ( -- vec ) V{ f } ;
+
+: socket ( -- socket ) (socket) 1st ;
+
+: init-socket-on-port ( port -- )
+  f swap <inet4> <datagram> 0 (socket) as-mutate ;
+
+: init-socket ( -- ) 53 init-socket-on-port ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: loop ( -- )
+  socket receive
+  swap
+  parse-message
+  find-answer
+  message->ba
+  swap
+  socket send
+  loop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: start ( -- ) init-socket loop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+MAIN: start
\ No newline at end of file
index 435a0aca55a16b330563c93ebe67ed2ab592c8f5..9e4802c2ef02242e95b1af7eb6eb2417142d7464 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2006, 2007 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays io kernel math models namespaces sequences strings
-splitting combinators unicode.categories math.order ;
+USING: accessors arrays io kernel math models namespaces
+sequences strings splitting combinators unicode.categories
+math.order ;
 IN: documents
 
 : +col ( loc n -- newloc ) >r first2 r> + 2array ;
@@ -20,9 +21,9 @@ TUPLE: document locs ;
     V{ "" } clone <model> V{ } clone
     { set-delegate set-document-locs } document construct ;
 
-: add-loc document-locs push ;
+: add-loc ( loc document -- ) locs>> push ;
 
-: remove-loc document-locs delete ;
+: remove-loc ( loc document -- ) locs>> delete ;
 
 : update-locs ( loc document -- )
     document-locs [ set-model ] with each ;
@@ -178,7 +179,7 @@ M: one-char-elt next-elt 2drop ;
     >r >r first2 swap r> doc-line r> call
     r> =col ; inline
 
-: ((word-elt)) [ ?nth blank? ] 2keep ;
+: ((word-elt)) ( n seq -- ? n seq ) [ ?nth blank? ] 2keep ;
 
 : break-detector ( ? -- quot )
     [ >r blank? r> xor ] curry ; inline
index a15a12830cb84eeae84594094c95b42e32a91e8f..ec8313363e0e1d97c20fc329bf857f96aa1d1d90 100755 (executable)
@@ -51,9 +51,7 @@ M: object find-parse-error
         [ file>> path>> ] [ line>> ] bi edit-location
     ] when* ;
 
-: fix ( word -- )
-    [ "Fixing " write pprint " and all usages..." print nl ]
-    [ [ usage ] keep prefix ] bi
+: edit-each ( seq -- )
     [
         [ "Editing " write . ]
         [
@@ -63,3 +61,8 @@ M: object find-parse-error
             readln
         ] bi
     ] all? drop ;
+
+: fix ( word -- )
+    [ "Fixing " write pprint " and all usages..." print nl ]
+    [ [ smart-usage ] keep prefix ] bi
+    edit-each ;
index f34bdc9920b6febe169f80685f23a077d72262e1..8572a8bd911cae03de725aa2acd5b0aba3bef21f 100755 (executable)
@@ -155,6 +155,16 @@ C-STRUCT: face
     { "face-size*" "size" }
     { "void*" "charmap" } ;
 
+C-STRUCT: FT_Bitmap
+    { "int" "rows" }
+    { "int" "width" }
+    { "int" "pitch" }
+    { "void*" "buffer" }
+    { "short" "num_grays" }
+    { "char" "pixel_mode" }
+    { "char" "palette_mode" }
+    { "void*" "palette" } ;
+
 FUNCTION: FT_Error FT_New_Face ( void* library, FT_Char* font, FT_Long index, face* face ) ;
 
 FUNCTION: FT_Error FT_New_Memory_Face ( void* library, FT_Byte* file_base, FT_Long file_size, FT_Long face_index, FT_Face* aface ) ;
@@ -170,6 +180,15 @@ C-ENUM:
     FT_RENDER_MODE_LCD
     FT_RENDER_MODE_LCD_V ;
 
+C-ENUM:
+    FT_PIXEL_MODE_NONE
+    FT_PIXEL_MODE_MONO
+    FT_PIXEL_MODE_GRAY
+    FT_PIXEL_MODE_GRAY2
+    FT_PIXEL_MODE_GRAY4
+    FT_PIXEL_MODE_LCD
+    FT_PIXEL_MODE_LCD_V ;
+
 FUNCTION: int FT_Render_Glyph ( glyph* slot, int render_mode ) ;
 
 FUNCTION: void FT_Done_Face ( face* face ) ;
@@ -177,3 +196,4 @@ FUNCTION: void FT_Done_Face ( face* face ) ;
 FUNCTION: void FT_Done_FreeType ( void* library ) ;
 
 FUNCTION: FT_Long FT_MulFix ( FT_Long a, FT_Long b ) ;
+
index 4581c048fdef3cc8390101fac80d8a90600ae7dd..f15a6b24c2e6c3f4b576f1d19cc1cf912649a3e1 100755 (executable)
@@ -5,9 +5,9 @@ quotations arrays namespaces qualified ;
 QUALIFIED: namespaces
 IN: fry
 
-: , "Only valid inside a fry" throw ;
-: @ "Only valid inside a fry" throw ;
-: _ "Only valid inside a fry" throw ;
+: , ( -- * ) "Only valid inside a fry" throw ;
+: @ ( -- * ) "Only valid inside a fry" throw ;
+: _ ( -- * ) "Only valid inside a fry" throw ;
 
 DEFER: (shallow-fry)
 
index 8aa0f92b97f1a2bae3bf5842f53a6fee26d4b46d..60a526fb247996f05a7ca0b91001628c50d28dc1 100755 (executable)
@@ -21,3 +21,21 @@ blah
     init-request
     { } "action-1" get call-responder
 ] unit-test
+
+<action>
+    "a" >>rest
+    [ "a" param string>number sq ] >>display
+"action-2" set
+
+STRING: action-request-test-2
+GET http://foo/bar/123 HTTP/1.1
+
+blah
+;
+
+[ 25 ] [
+    action-request-test-2 lf>crlf
+    [ read-request ] with-string-reader
+    init-request
+    { "5" } "action-2" get call-responder
+] unit-test
index 5e237b02a85e55027225affdce371ddbec0022cb..1cef8e24e513e3d714522d48bce0de74908fecff 100755 (executable)
@@ -2,20 +2,22 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors sequences kernel assocs combinators\r
 validators http hashtables namespaces fry continuations locals\r
-io arrays math boxes\r
+io arrays math boxes splitting urls\r
 xml.entities\r
 http.server\r
 http.server.responses\r
 furnace\r
+furnace.flash\r
 html.elements\r
 html.components\r
+html.components\r
 html.templates.chloe\r
 html.templates.chloe.syntax ;\r
 IN: furnace.actions\r
 \r
 SYMBOL: params\r
 \r
-SYMBOL: rest-param\r
+SYMBOL: rest\r
 \r
 : render-validation-messages ( -- )\r
     validation-messages get\r
@@ -27,7 +29,7 @@ SYMBOL: rest-param
 \r
 CHLOE: validation-messages drop render-validation-messages ;\r
 \r
-TUPLE: action rest-param init display validate submit ;\r
+TUPLE: action rest init display validate submit ;\r
 \r
 : new-action ( class -- action )\r
     new\r
@@ -39,47 +41,67 @@ TUPLE: action rest-param init display validate submit ;
 : <action> ( -- action )\r
     action new-action ;\r
 \r
+: flashed-variables ( -- seq )\r
+    { validation-messages named-validation-messages } ;\r
+\r
 : handle-get ( action -- response )\r
-    blank-values\r
-    [ init>> call ]\r
-    [ display>> call ]\r
-    bi ;\r
+    '[\r
+        ,\r
+        [ init>> call ]\r
+        [ drop flashed-variables restore-flash ]\r
+        [ display>> call ]\r
+        tri\r
+    ] with-exit-continuation ;\r
 \r
 : validation-failed ( -- * )\r
-    request get method>> "POST" =\r
-    [ action get display>> call ] [ <400> ] if exit-with ;\r
+    request get method>> "POST" = [ f ] [ <400> ] if exit-with ;\r
 \r
-: handle-post ( action -- response )\r
-    init-validation\r
-    blank-values\r
-    [ validate>> call ]\r
-    [ submit>> call ] bi ;\r
+: (handle-post) ( action -- response )\r
+    [ validate>> call ] [ submit>> call ] bi ;\r
 \r
-: handle-rest-param ( arg -- )\r
-    dup length 1 > action get rest-param>> not or\r
-    [ <404> exit-with ] [\r
-        action get rest-param>> associate rest-param set\r
-    ] if ;\r
+: param ( name -- value )\r
+    params get at ;\r
 \r
-M: action call-responder* ( path action -- response )\r
-    dup action set\r
-    '[\r
-        , dup empty? [ drop ] [ handle-rest-param ] if\r
+: revalidate-url-key "__u" ;\r
 \r
-        init-validation\r
-        ,\r
-        request get\r
-        [ request-params rest-param get assoc-union params set ]\r
-        [ method>> ] bi\r
-        {\r
-            { "GET" [ handle-get ] }\r
-            { "HEAD" [ handle-get ] }\r
-            { "POST" [ handle-post ] }\r
-        } case\r
-    ] with-exit-continuation ;\r
+: check-url ( url -- ? )\r
+    request get url>>\r
+    [ [ protocol>> ] [ host>> ] [ port>> ] tri 3array ] bi@ = ;\r
 \r
-: param ( name -- value )\r
-    params get at ;\r
+: revalidate-url ( -- url/f )\r
+    revalidate-url-key param dup [ >url dup check-url swap and ] when ;\r
+\r
+: handle-post ( action -- response )\r
+    '[\r
+        form-nesting-key params get at " " split\r
+        [ , (handle-post) ]\r
+        [ swap '[ , , nest-values ] ] reduce\r
+        call\r
+    ] with-exit-continuation\r
+    [\r
+        revalidate-url\r
+        [ flashed-variables <flash-redirect> ] [ <403> ] if*\r
+    ] unless* ;\r
+\r
+: handle-rest ( path action -- assoc )\r
+    rest>> dup [ [ "/" join ] dip associate ] [ 2drop f ] if ;\r
+\r
+: init-action ( path action -- )\r
+    blank-values\r
+    init-validation\r
+    handle-rest\r
+    request get request-params assoc-union params set ;\r
+\r
+M: action call-responder* ( path action -- response )\r
+    [ init-action ] keep\r
+    request get method>> {\r
+        { "GET" [ handle-get ] }\r
+        { "HEAD" [ handle-get ] }\r
+        { "POST" [ handle-post ] }\r
+    } case ;\r
+\r
+M: action modify-form\r
+    drop request get url>> revalidate-url-key hidden-form-field ;\r
 \r
 : check-validation ( -- )\r
     validation-failed? [ validation-failed ] when ;\r
diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor
new file mode 100644 (file)
index 0000000..f6b4e2c
--- /dev/null
@@ -0,0 +1,73 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors namespaces sequences arrays kernel
+assocs assocs.lib hashtables math.parser urls combinators
+furnace http http.server http.server.filters furnace.sessions
+html.elements html.templates.chloe.syntax ;
+IN: furnace.asides
+
+TUPLE: asides < filter-responder ;
+
+C: <asides> asides
+
+: begin-aside* ( -- id )
+    request get
+    [ url>> ] [ post-data>> ] [ method>> ] tri 3array
+    asides sget set-at-unique
+    session-changed ;
+
+: end-aside-post ( url post-data -- response )
+    request [
+        clone
+            swap >>post-data
+            swap >>url
+    ] change
+    request get url>> path>> split-path
+    asides get responder>> call-responder ;
+
+ERROR: end-aside-in-get-error ;
+
+: end-aside* ( url id -- response )
+    request get method>> "POST" = [ end-aside-in-get-error ] unless
+    asides sget at [
+        first3 {
+            { "GET" [ drop <redirect> ] }
+            { "HEAD" [ drop <redirect> ] }
+            { "POST" [ end-aside-post ] }
+        } case
+    ] [ <redirect> ] ?if ;
+
+SYMBOL: aside-id
+
+: aside-id-key "__a" ;
+
+: begin-aside ( -- )
+    begin-aside* aside-id set ;
+
+: end-aside ( default -- response )
+    aside-id [ f ] change end-aside* ;
+
+M: asides call-responder*
+    dup asides set
+    aside-id-key request get request-params at aside-id set
+    call-next-method ;
+
+M: asides init-session*
+    H{ } clone asides sset
+    call-next-method ;
+
+M: asides link-attr ( tag -- )
+    drop
+    "aside" optional-attr {
+        { "none" [ aside-id off ] }
+        { "begin" [ begin-aside ] }
+        { "current" [ ] }
+        { f [ ] }
+    } case ;
+
+M: asides modify-query ( query responder -- query' )
+    drop
+    aside-id get [ aside-id-key associate assoc-union ] when* ;
+
+M: asides modify-form ( responder -- )
+    drop aside-id get aside-id-key hidden-form-field ;
index 58ab47e3e1c6fb871b9cc995bb23afbe549123b5..d0c4e00953a3700c5e0df37982f1aed64895a8bb 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors quotations assocs kernel splitting\r
 combinators sequences namespaces hashtables sets\r
-fry arrays threads qualified random validators\r
+fry arrays threads qualified random validators words\r
 io\r
 io.sockets\r
 io.encodings.utf8\r
@@ -26,14 +26,29 @@ furnace.auth
 furnace.auth.providers\r
 furnace.auth.providers.db\r
 furnace.actions\r
-furnace.flows\r
+furnace.asides\r
+furnace.flash\r
 furnace.sessions\r
 furnace.boilerplate ;\r
 QUALIFIED: smtp\r
 IN: furnace.auth.login\r
 \r
+: word>string ( word -- string )\r
+    [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ;\r
+\r
+: words>strings ( seq -- seq' )\r
+    [ word>string ] map ;\r
+\r
+: string>word ( string -- word )\r
+    ":" split1 swap lookup ;\r
+\r
+: strings>words ( seq -- seq' )\r
+    [ string>word ] map ;\r
+\r
 TUPLE: login < dispatcher users checksum ;\r
 \r
+TUPLE: protected < filter-responder description capabilities ;\r
+\r
 : users ( -- provider )\r
     login get users>> ;\r
 \r
@@ -64,7 +79,7 @@ M: user-saver dispose
 \r
 ! ! ! Login\r
 : successful-login ( user -- response )\r
-    username>> set-uid URL" $login" end-flow ;\r
+    username>> set-uid URL" $login" end-aside ;\r
 \r
 : login-failed ( -- * )\r
     "invalid username or password" validation-error\r
@@ -72,6 +87,13 @@ M: user-saver dispose
 \r
 : <login-action> ( -- action )\r
     <page-action>\r
+        [\r
+            protected fget [\r
+                [ description>> "description" set-value ]\r
+                [ capabilities>> words>strings "capabilities" set-value ] bi\r
+            ] when*\r
+        ] >>init\r
+\r
         { login "login" } >>template\r
 \r
         [\r
@@ -177,7 +199,7 @@ M: user-saver dispose
 \r
             drop\r
 \r
-            URL" $login" end-flow\r
+            URL" $login" end-aside\r
         ] >>submit ;\r
 \r
 ! ! ! Password recovery\r
@@ -290,23 +312,23 @@ SYMBOL: lost-password-from
     <action>\r
         [\r
             f set-uid\r
-            URL" $login" end-flow\r
+            URL" $login" end-aside\r
         ] >>submit ;\r
 \r
 ! ! ! Authentication logic\r
-\r
-TUPLE: protected < filter-responder capabilities ;\r
-\r
-C: <protected> protected\r
+: <protected> ( responder -- protected )\r
+    protected new\r
+        swap >>responder ;\r
 \r
 : show-login-page ( -- response )\r
-    begin-flow\r
-    URL" $login/login" <redirect> ;\r
+    begin-aside\r
+    URL" $login/login" { protected } <flash-redirect> ;\r
 \r
 : check-capabilities ( responder user -- ? )\r
     [ capabilities>> ] bi@ subset? ;\r
 \r
 M: protected call-responder* ( path responder -- response )\r
+    dup protected set\r
     uid dup [\r
         users get-user 2dup check-capabilities [\r
             [ logged-in-user set ] [ save-user-after ] bi\r
@@ -337,7 +359,9 @@ M: login call-responder* ( path responder -- response )
 ! ! ! Configuration\r
 \r
 : allow-edit-profile ( login -- login )\r
-    <edit-profile-action> f <protected> <login-boilerplate>\r
+    <edit-profile-action> <protected>\r
+        "edit your profile" >>description\r
+    <login-boilerplate>\r
         "edit-profile" add-responder ;\r
 \r
 : allow-registration ( login -- login )\r
index a52aed59d7bb74bb7f8df2ec7fc8680d027b4412..a7ac92bf442b76a6a57bf562c4e9afd90e854fc6 100644 (file)
@@ -4,6 +4,19 @@
 
        <t:title>Login</t:title>
 
+       <t:if t:value="description">
+               <p>You must log in to <t:label t:name="description" />.</p>
+       </t:if>
+
+       <t:if t:value="capabilities">
+               <p>Your user must have the following capabilities:</p>
+               <ul>
+                       <t:each t:name="capabilities">
+                               <li><t:label t:name="value" /></li>
+                       </t:each>
+               </ul>
+       </t:if>
+
        <t:form t:action="login">
 
                <table>
index 90306e51817fa269aeef2ab5f709fac302c26b17..66c1b3ec99d3daef5e4e44c2c793d762da6b460f 100755 (executable)
@@ -18,7 +18,7 @@ user "USERS"
     { "deleted" "DELETED" INTEGER +not-null+ }
 } define-persistent
 
-: init-users-table user ensure-table ;
+: init-users-table ( -- ) user ensure-table ;
 
 SINGLETON: users-in-db
 
index 42f132ada1be6cfb00aca0bbc3a8965c70d73f0b..7c5b7a0c810750b15b0e9c28cd70053093e406b9 100644 (file)
@@ -10,7 +10,7 @@ IN: furnace.boilerplate
 
 TUPLE: boilerplate < filter-responder template ;
 
-: <boilerplate> f boilerplate boa ;
+: <boilerplate> ( responder -- boilerplate ) f boilerplate boa ;
 
 M:: boilerplate call-responder* ( path responder -- )
     path responder call-next-method
diff --git a/extra/furnace/flash/flash.factor b/extra/furnace/flash/flash.factor
new file mode 100644 (file)
index 0000000..21fd20c
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: namespaces assocs assocs.lib kernel sequences urls
+http http.server http.server.filters http.server.redirection
+furnace furnace.sessions ;
+IN: furnace.flash
+
+: flash-id-key "__f" ;
+
+TUPLE: flash-scopes < filter-responder ;
+
+C: <flash-scopes> flash-scopes
+
+SYMBOL: flash-scope
+
+: fget ( key -- value ) flash-scope get at ;
+
+M: flash-scopes call-responder*
+    flash-id-key
+    request get request-params at
+    flash-scopes sget at flash-scope set
+    call-next-method ;
+
+M: flash-scopes init-session*
+    H{ } clone flash-scopes sset
+    call-next-method ;
+
+: make-flash-scope ( seq -- id )
+    [ dup get ] H{ } map>assoc flash-scopes sget set-at-unique
+    session-changed ;
+
+: <flash-redirect> ( url seq -- response )
+    make-flash-scope
+    [ clone ] dip flash-id-key set-query-param
+    <redirect> ;
+
+: restore-flash ( seq -- )
+    [ flash-scope get key? ] filter [ [ fget ] keep set ] each ;
diff --git a/extra/furnace/flows/flows.factor b/extra/furnace/flows/flows.factor
deleted file mode 100644 (file)
index eb98c1a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors namespaces sequences arrays kernel
-assocs assocs.lib hashtables math.parser urls combinators
-furnace http http.server http.server.filters furnace.sessions
-html.elements html.templates.chloe.syntax ;
-IN: furnace.flows
-
-TUPLE: flows < filter-responder ;
-
-C: <flows> flows
-
-: begin-flow* ( -- id )
-    request get
-    [ url>> ] [ post-data>> ] [ method>> ] tri 3array
-    flows sget set-at-unique
-    session-changed ;
-
-: end-flow-post ( url post-data -- response )
-    request [
-        clone
-            "POST" >>method
-            swap >>post-data
-            swap >>url
-    ] change
-    request get url>> path>> split-path
-    flows get responder>> call-responder ;
-
-: end-flow* ( url id -- response )
-    flows sget at [
-        first3 {
-            { "GET" [ drop <redirect> ] }
-            { "HEAD" [ drop <redirect> ] }
-            { "POST" [ end-flow-post ] }
-        } case
-    ] [ <redirect> ] ?if ;
-
-SYMBOL: flow-id
-
-: flow-id-key "factorflowid" ;
-
-: begin-flow ( -- )
-    begin-flow* flow-id set ;
-
-: end-flow ( default -- response )
-    flow-id get end-flow* ;
-
-M: flows call-responder*
-    dup flows set
-    flow-id-key request get request-params at flow-id set
-    call-next-method ;
-
-M: flows init-session*
-    H{ } clone flows sset
-    call-next-method ;
-
-M: flows link-attr ( tag -- )
-    drop
-    "flow" optional-attr {
-        { "none" [ flow-id off ] }
-        { "begin" [ begin-flow ] }
-        { "current" [ ] }
-        { f [ ] }
-    } case ;
-
-M: flows modify-query ( query responder -- query' )
-    drop
-    flow-id get [ flow-id-key associate assoc-union ] when* ;
-
-M: flows hidden-form-field ( responder -- )
-    drop
-    flow-id get [
-        <input
-            "hidden" =type
-            flow-id-key =name
-            =value
-        input/>
-    ] when* ;
index 5cf2dad9ad76048df8a9a077b9f2c000d3f4d221..223b20455d644280099728a7ecbde47a6897fecd 100644 (file)
@@ -1,6 +1,7 @@
 IN: furnace.tests
 USING: http.server.dispatchers http.server.responses
-http.server furnace tools.test kernel namespaces accessors ;
+http.server furnace tools.test kernel namespaces accessors
+io.streams.string ;
 TUPLE: funny-dispatcher < dispatcher ;
 
 : <funny-dispatcher> funny-dispatcher new-dispatcher ;
@@ -28,3 +29,7 @@ M: base-path-check-responder call-responder*
     V{ } responder-nesting set
     "a/b/c" split-path main-responder get call-responder body>>
 ] unit-test
+
+[ "<input type='hidden' name='foo' value='&amp;&amp;&amp;'/>" ]
+[ [ "&&&" "foo" hidden-form-field ] with-string-writer ]
+unit-test
index 370c4f84a32b4793294265050df94b6718dd7f9c..99ccf33eec83b555c35c53de6e5f220557399a76 100644 (file)
@@ -2,12 +2,12 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel combinators assocs
 continuations namespaces sequences splitting words
-vocabs.loader classes
-fry urls multiline
+vocabs.loader classes strings
+fry urls multiline present
 xml
 xml.data
+xml.entities
 xml.writer
-xml.utilities
 html.components
 html.elements
 html.templates
@@ -19,6 +19,7 @@ http.server.redirection
 http.server.responses
 qualified ;
 QUALIFIED-WITH: assocs a
+EXCLUDE: xml.utilities => children>string ;
 IN: furnace
 
 : nested-responders ( -- seq )
@@ -51,12 +52,16 @@ GENERIC: modify-query ( query responder -- query' )
 
 M: object modify-query drop ;
 
-: adjust-url ( url -- url' )
+GENERIC: adjust-url ( url -- url' )
+
+M: url adjust-url
     clone
         [ [ modify-query ] each-responder ] change-query
         [ resolve-base-path ] change-path
     relative-to-request ;
 
+M: string adjust-url ;
+
 : <redirect> ( url -- response )
     adjust-url request get method>> {
         { "GET" [ <temporary-redirect> ] }
@@ -64,20 +69,25 @@ M: object modify-query drop ;
         { "POST" [ <permanent-redirect> ] }
     } case ;
 
-GENERIC: hidden-form-field ( responder -- )
+GENERIC: modify-form ( responder -- )
 
-M: object hidden-form-field drop ;
+M: object modify-form drop ;
 
 : request-params ( request -- assoc )
     dup method>> {
         { "GET" [ url>> query>> ] }
         { "HEAD" [ url>> query>> ] }
-        { "POST" [ post-data>> ] }
+        { "POST" [
+            post-data>>
+            dup content-type>> "application/x-www-form-urlencoded" =
+            [ content>> ] [ drop f ] if
+        ] }
     } case ;
 
 SYMBOL: exit-continuation
 
-: exit-with exit-continuation get continue-with ;
+: exit-with ( value -- )
+    exit-continuation get continue-with ;
 
 : with-exit-continuation ( quot -- )
     '[ exit-continuation set @ ] callcc1 exit-continuation off ;
@@ -88,7 +98,7 @@ SYMBOL: exit-continuation
     [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ;
 
 CHLOE: atom
-    [ "title" required-attr ]
+    [ children>string ]
     [ "href" required-attr ]
     [ "query" optional-attr parse-query-attr ] tri
     <url>
@@ -128,20 +138,34 @@ CHLOE: a
     [ drop </a> ]
     tri ;
 
+: hidden-form-field ( value name -- )
+    over [
+        <input
+            "hidden" =type
+            =name
+            present =value
+        input/>
+    ] [ 2drop ] if ;
+
+: form-nesting-key "__n" ;
+
+: form-magic ( tag -- )
+    [ modify-form ] each-responder
+    nested-values get " " join f like form-nesting-key hidden-form-field
+    "for" optional-attr [ "," split [ hidden render ] each ] when* ;
+
 : form-start-tag ( tag -- )
     [
         [
             <form
-            "POST" =method
-            [ link-attrs ]
-            [ "action" required-attr resolve-base-path =action ]
-            [ tag-attrs non-chloe-attrs-only print-attrs ]
-            tri
+                "POST" =method
+                [ link-attrs ]
+                [ "action" required-attr resolve-base-path =action ]
+                [ tag-attrs non-chloe-attrs-only print-attrs ]
+                tri
             form>
-        ] [
-            [ hidden-form-field ] each-responder
-            "for" optional-attr [ hidden render ] when*
-        ] bi
+        ]
+        [ form-magic ] bi
     ] with-scope ;
 
 CHLOE: form
@@ -167,17 +191,3 @@ CHLOE: button
         [ [ children>string 1array ] dip "button" tag-named set-tag-children ]
         [ nip ]
     } 2cleave process-chloe-tag ;
-
-: attr>word ( value -- word/f )
-    dup ":" split1 swap lookup
-    [ ] [ "No such word: " swap append throw ] ?if ;
-
-: attr>var ( value -- word/f )
-    attr>word dup symbol? [
-        "Must be a symbol: " swap append throw
-    ] unless ;
-
-: if-satisfied? ( tag -- ? )
-    "code" required-attr attr>word execute ;
-
-CHLOE: if dup if-satisfied? [ process-tag-children ] [ drop ] if ;
diff --git a/extra/furnace/rss/rss.factor b/extra/furnace/rss/rss.factor
deleted file mode 100644 (file)
index a94ef4f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel fry
-rss http.server.responses furnace.actions ;
-IN: furnace.rss
-
-: <feed-content> ( body -- response )
-    feed>xml "application/atom+xml" <content> ;
-
-TUPLE: feed-action < action feed ;
-
-: <feed-action> ( -- feed )
-    feed-action new-action
-        dup '[ , feed>> call <feed-content> ] >>display ;
index 5ea389c87eec62a5708eef24d222ce6306b8cc5b..b046ee40eb63c5691688bc62310c8c662553d8d0 100755 (executable)
@@ -25,7 +25,7 @@ session "SESSIONS"
 : get-session ( id -- session )
     dup [ <session> select-tuple ] when ;
 
-: init-sessions-table session ensure-table ;
+: init-sessions-table ( -- ) session ensure-table ;
 
 : start-expiring-sessions ( db seq -- )
     '[
@@ -109,14 +109,14 @@ M: session-saver dispose
     [ session set ] [ save-session-after ] bi
     sessions get responder>> call-responder ;
 
-: session-id-key "factorsessid" ;
+: session-id-key "__s" ;
 
 : cookie-session-id ( request -- id/f )
     session-id-key get-cookie
     dup [ value>> string>number ] when ;
 
 : post-session-id ( request -- id/f )
-    session-id-key swap post-data>> at string>number ;
+    session-id-key swap request-params at string>number ;
 
 : request-session-id ( -- id/f )
     request get dup method>> {
@@ -137,13 +137,8 @@ M: session-saver dispose
 : put-session-cookie ( response -- response' )
     session get id>> number>string <session-cookie> put-cookie ;
 
-M: sessions hidden-form-field ( responder -- )
-    drop
-    <input
-        "hidden" =type
-        session-id-key =name
-        session get id>> number>string =value
-    input/> ;
+M: sessions modify-form ( responder -- )
+    drop session get id>> session-id-key hidden-form-field ;
 
 M: sessions call-responder* ( path responder -- response )
     sessions set
diff --git a/extra/furnace/syndication/syndication.factor b/extra/furnace/syndication/syndication.factor
new file mode 100644 (file)
index 0000000..7f60bcc
--- /dev/null
@@ -0,0 +1,53 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel sequences fry sequences.lib
+combinators syndication
+http.server.responses http.server.redirection
+furnace furnace.actions ;
+IN: furnace.syndication
+
+GENERIC: feed-entry-title ( object -- string )
+
+GENERIC: feed-entry-date ( object -- timestamp )
+
+GENERIC: feed-entry-url ( object -- url )
+
+GENERIC: feed-entry-description ( object -- description )
+
+M: object feed-entry-description drop f ;
+
+GENERIC: >entry ( object -- entry )
+
+M: entry >entry ;
+
+M: object >entry
+    <entry>
+        swap {
+            [ feed-entry-title >>title ]
+            [ feed-entry-date >>date ]
+            [ feed-entry-url >>url ]
+            [ feed-entry-description >>description ]
+        } cleave ;
+
+: process-entries ( seq -- seq' )
+    20 short head-slice [
+        >entry clone
+        [ adjust-url relative-to-request ] change-url
+    ] map ;
+
+: <feed-content> ( body -- response )
+    feed>xml "application/atom+xml" <content> ;
+
+TUPLE: feed-action < action title url entries ;
+
+: <feed-action> ( -- action )
+    feed-action new-action
+        dup '[
+            feed new
+                ,
+                [ title>> call >>title ]
+                [ url>> call adjust-url relative-to-request >>url ]
+                [ entries>> call process-entries >>entries ]
+                tri
+            <feed-content>
+        ] >>display ;
index 5926dd596dcf6ff522bda689bd1b6259390c1fb7..06a84929bacdf6c4edfb3e8c799e2aaf7f2fdc5a 100644 (file)
@@ -4,9 +4,9 @@ math.parser math.vectors math.intervals interval-maps memoize
 csv accessors assocs strings math splitting ;
 IN: geo-ip
 
-: db-path "IpToCountry.csv" temp-file ;
+: db-path ( -- path ) "IpToCountry.csv" temp-file ;
 
-: db-url "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download" ;
+: db-url ( -- url ) "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download" ;
 
 : download-db ( -- path )
     db-path dup exists? [
index 4fa56bcf938410991ecc310a623a5920ed5a2f7e..c7d5413a4721d0d8aa6733cb77d5ad0e72ffb117 100755 (executable)
@@ -1,18 +1,22 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser-combinators regexp lazy-lists sequences kernel
+USING: parser-combinators regexp lists sequences kernel
 promises strings unicode.case ;
 IN: globs
 
 <PRIVATE
 
-: 'char' [ ",*?" member? not ] satisfy ;
+: 'char' ( -- parser )
+    [ ",*?" member? not ] satisfy ;
 
-: 'string' 'char' <+> [ >lower token ] <@ ;
+: 'string' ( -- parser )
+    'char' <+> [ >lower token ] <@ ;
 
-: 'escaped-char' "\\" token any-char-parser &> [ 1token ] <@ ;
+: 'escaped-char' ( -- parser )
+    "\\" token any-char-parser &> [ 1token ] <@ ;
 
-: 'escaped-string' 'string' 'escaped-char' <|> ;
+: 'escaped-string' ( -- parser )
+    'string' 'escaped-char' <|> ;
 
 DEFER: 'term'
 
@@ -23,7 +27,7 @@ DEFER: 'term'
     'glob' "," token nonempty-list-of "{" "}" surrounded-by
     [ <or-parser> ] <@ ;
 
-LAZY: 'term'
+LAZY: 'term' ( -- parser )
     'union'
     'character-class' <|>
     "?" token [ drop any-char-parser ] <@ <|>
@@ -32,7 +36,7 @@ LAZY: 'term'
 
 PRIVATE>
 
-: <glob> 'glob' just parse-1 just ;
+: <glob> ( string -- glob ) 'glob' just parse-1 just ;
 
 : glob-matches? ( input glob -- ? )
     [ >lower ] [ <glob> ] bi* parse nil? not ;
index 2599a33754635672ea80dff94f7e0655dbe88377..51af5c594977ada21bf40b8d52b20ade31d229cd 100755 (executable)
@@ -35,7 +35,8 @@ M: winnt total-virtual-mem ( -- n )
 M: winnt available-virtual-mem ( -- n )
     memory-status MEMORYSTATUSEX-ullAvailVirtual ;
 
-: pull-win32-string [ utf16n alien>string ] keep free ;
+: pull-win32-string ( alien -- string )
+    [ utf16n alien>string ] keep free ;
 
 : computer-name ( -- string )
     MAX_COMPUTERNAME_LENGTH 1+ [ malloc ] keep
index 709ecb1b5814165c775a40f113350fdde7b5ac2f..03b3db9cfdf7300a5160dc1ae81a612c6b16ed54 100644 (file)
@@ -1,6 +1,6 @@
 USE: io
 IN: hello-world
 
-: hello "Hello world" print ;
+: hello ( -- ) "Hello world" print ;
 
 MAIN: hello
index c2e12469c559c6fbc67d75aacf0f590208d8cc95..922866649108727df62f2ab35af71e8e39dd3929 100755 (executable)
@@ -11,7 +11,7 @@ $nl
 $nl
 "Factor evaluates code left to right, and stores intermediate values on a " { $emphasis "stack" } ". If you think of the stack as a pile of papers, then " { $emphasis "pushing" } " a value on the stack corresponds to placing a piece of paper at the top of the pile, while " { $emphasis "popping" } " a value corresponds to removing the topmost piece."
 $nl
-"Most words have a " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that a word takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output. Stack effect declarations can be viewed by browsing source code, or using tools such as " { $link see } ". See " { $link "effect-declaration" } "."
+"All words except those which only push literals on the stack must have a " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that a word takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output. Stack effect declarations can be viewed by browsing source code, or using tools such as " { $link see } "; they are also checked by the compiler. See " { $link "effect-declaration" } "."
 $nl
 "Coming back to the example in the beginning of this article, the following series of steps occurs as the code is evaluated:"
 { $table
@@ -41,7 +41,7 @@ ARTICLE: "cookbook-colon-defs" "Shuffle word and definition cookbook"
 "The " { $link dup } " word makes a copy of the value at the top of the stack:"
 { $example "5 dup * ." "25" }
 "The " { $link sq } " word is actually defined as follows:"
-{ $code ": sq dup * ;" }
+{ $code ": sq ( x -- y ) dup * ;" }
 "(You could have looked this up yourself by clicking on the " { $link sq } " word itself.)"
 $nl
 "Note the key elements in a word definition: The colon " { $link POSTPONE: : } " denotes the start of a word definition. The name of the new word must immediately follow. The word definition then continues on until the " { $link POSTPONE: ; } " token signifies the end of the definition. This type of word definition is called a " { $emphasis "compound definition." }
@@ -60,11 +60,13 @@ $nl
     "This syntax will be familiar to anybody who has used Forth before. However the behavior is slightly different. In most Forth systems, the below code prints 2, because the definition of " { $snippet "b" } " still refers to the previous definition of " { $snippet "a" } ":"
     { $code
         ": a 1 ;"
-        ": b a 1 + ;"
+        ": b ( -- x ) a 1 + ;"
         ": a 2 ;"
         "b ."
     }
     "In Factor, this example will print 3 since word redefinition is explicitly supported."
+    $nl
+    "Indeed, redefining a word twice in the same source file is an error; this is almost always a mistake since there's no way to call the first definition. See " { $link "definition-checking" } "."
 }
 { $references
     { "A whole slew of shuffle words can be used to rearrange the stack. There are forms of word definition other than colon definition, words can be defined entirely at runtime, and word definitions can be " { $emphasis "annotated" } " with tracing calls and breakpoints without modifying the source code." }
index 75a14e645bcd9940c80531b1096efad13f537e39..6c921fe0a2cf8fc0c69fdff8305e845c57af2165 100755 (executable)
@@ -46,12 +46,12 @@ M: predicate word-help* drop \ $predicate ;
 M: word article-name word-name ;
 
 M: word article-title
-    dup parsing? over symbol? or [
+    dup [ parsing-word? ] [ symbol? ] bi or [
         word-name
     ] [
-        dup word-name
-        swap stack-effect
-        [ effect>string " " swap 3append ] when*
+        [ word-name ]
+        [ stack-effect [ effect>string " " prepend ] [ "" ] if* ] bi
+        append
     ] if ;
 
 M: word article-content
@@ -114,15 +114,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
 : $about ( element -- )
     first vocab-help [ 1array $subsection ] when* ;
 
-: (:help-multi)
-    "This error has multiple delegates:" print
-    ($index) nl
-    "Use \\ ... help to get help about a specific delegate." print ;
-
-: (:help-none)
-    drop "No help for this error. " print ;
-
-: (:help-debugger)
+: :help-debugger ( -- )
     nl
     "Debugger commands:" print
     nl
@@ -135,12 +127,8 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
     ":vars - list all variables at error time" print ;
 
 : :help ( -- )
-    error get delegates [ error-help ] map sift
-    {
-        { [ dup empty? ] [ (:help-none) ] }
-        { [ dup length 1 = ] [ first help ] }
-        [ (:help-multi) ]
-    } cond (:help-debugger) ;
+    error get error-help [ help ] [ "No help for this error. " print ] if*
+    :help-debugger ;
 
 : remove-article ( name -- )
     dup articles get key? [
diff --git a/extra/help/html/html.factor b/extra/help/html/html.factor
new file mode 100644 (file)
index 0000000..b1bf895
--- /dev/null
@@ -0,0 +1,5 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: help.html
+
+
index 378dd1e2feb7d834c9f510acf3a6059e8f6b4a09..32e40841501051dda23a36595c105dda413adcb2 100755 (executable)
@@ -22,8 +22,8 @@ SYMBOL: span
 SYMBOL: block
 SYMBOL: table
 
-: last-span? last-element get span eq? ;
-: last-block? last-element get block eq? ;
+: last-span? ( -- ? ) last-element get span eq? ;
+: last-block? ( -- ? ) last-element get block eq? ;
 
 : ($span) ( quot -- )
     last-block? [ nl ] when
@@ -58,18 +58,23 @@ M: f print-element drop ;
 
 ! Some spans
 
-: $snippet [ snippet-style get print-element* ] ($span) ;
+: $snippet ( children -- )
+    [ snippet-style get print-element* ] ($span) ;
 
-: $emphasis [ emphasis-style get print-element* ] ($span) ;
+: $emphasis ( children -- )
+    [ emphasis-style get print-element* ] ($span) ;
 
-: $strong [ strong-style get print-element* ] ($span) ;
+: $strong ( children -- )
+    [ strong-style get print-element* ] ($span) ;
 
-: $url [ url-style get print-element* ] ($span) ;
+: $url ( children -- )
+    [ url-style get print-element* ] ($span) ;
 
-: $nl nl nl drop ;
+: $nl ( children -- )
+    nl nl drop ;
 
 ! Some blocks
-: ($heading)
+: ($heading) ( children quot -- )
     last-element get [ nl ] when ($block) ; inline
 
 : $heading ( element -- )
@@ -230,7 +235,7 @@ M: word ($instance)
 M: string ($instance)
     dup a/an write bl $snippet ;
 
-: $instance first ($instance) ;
+: $instance ( children -- ) first ($instance) ;
 
 : values-row ( seq -- seq )
     unclip \ $snippet swap ?word-name 2array
@@ -278,18 +283,18 @@ M: string ($instance)
     drop
     "Shuffle word. Re-arranges the stack according to the stack effect pattern." $description ;
 
-: $low-level-note
+: $low-level-note ( children -- )
     drop
     "Calling this word directly is not necessary in most cases. Higher-level words call it automatically." $notes ;
 
-: $values-x/y
+: $values-x/y ( children -- )
     drop { { "x" number } { "y" number } } $values ;
 
-: $io-error
+: $io-error ( children -- )
     drop
     "Throws an error if the I/O operation fails." $errors ;
 
-: $prettyprinting-note
+: $prettyprinting-note ( children -- )
     drop {
         "This word should only be called from inside the "
         { $link with-pprint } " combinator."
index 65120a5d01b977e57fc421c47744e04e861b0ca3..877de30748cb3d6577366d51f8b6e891f192b6fa 100755 (executable)
@@ -18,5 +18,5 @@ IN: help.syntax
 : ABOUT:
     scan-object
     in get vocab
-    dup changed-definition
+    dup +inlined+ changed-definition
     set-vocab-help ; parsing
index 468a8cf25362f6e99fd370e5f37e801d56c65c7f..f444f5a4f223f7909e2318267c9f259cc2521629 100644 (file)
@@ -1,5 +1,5 @@
 USING: arrays io io.streams.string kernel math math.parser namespaces
-    prettyprint sequences sequences.lib splitting strings ascii ;
+prettyprint sequences sequences.lib splitting grouping strings ascii ;
 IN: hexdump
 
 <PRIVATE
index 1f77768115fe4be1bfa17bef03b189bde8d85788..2ae120b527d9e1c5f331d5dc7f01692691d6e3ad 100644 (file)
@@ -17,8 +17,6 @@ TUPLE: color red green blue ;
 
 [ ] [ "jimmy" "red" set-value ] unit-test
 
-[ "123.5" ] [ 123.5 object>string ] unit-test
-
 [ "jimmy" ] [
     [
         "red" label render
index c013007a144b114b58e45167190b2cf98ea3e363..42d89811c1fd9e8ca156b5daddba9d27e3331e60 100644 (file)
@@ -5,16 +5,16 @@ classes.tuple words arrays sequences sequences.lib splitting
 mirrors hashtables combinators continuations math strings
 fry locals calendar calendar.format xml.entities validators
 html.elements html.streams xmode.code2html farkup inspector
-lcs.diff2html urls ;
+lcs.diff2html urls present ;
 IN: html.components
 
 SYMBOL: values
 
-: value values get at ;
+: value ( name -- value ) values get at ;
 
-: set-value values get set-at ;
+: set-value ( value name -- ) values get set-at ;
 
-: blank-values H{ } clone values set ;
+: blank-values ( -- ) H{ } clone values set ;
 
 : prepare-value ( name object -- value name object )
     [ [ value ] keep ] dip ; inline
@@ -29,22 +29,36 @@ SYMBOL: values
 : deposit-slots ( destination names -- )
     [ <mirror> ] dip deposit-values ;
 
-: with-each-index ( seq quot -- )
-    '[
+: with-each-value ( name quot -- )
+    [ value ] dip '[
         [
             values [ clone ] change
-            1+ "index" set-value @
+            1+ "index" set-value
+            "value" set-value
+            @
         ] with-scope
     ] each-index ; inline
 
-: with-each-value ( seq quot -- )
-    '[ "value" set-value @ ] with-each-index ; inline
+: with-each-object ( name quot -- )
+    [ value ] dip '[
+        [
+            blank-values
+            1+ "index" set-value
+            from-object
+            @
+        ] with-scope
+    ] each-index ; inline
 
-: with-each-object ( seq quot -- )
-    '[ from-object @ ] with-each-index ; inline
+SYMBOL: nested-values
 
-: with-values ( object quot -- )
-    '[ blank-values , from-object @ ] with-scope ; inline
+: with-values ( name quot -- )
+    '[
+        ,
+        [ nested-values [ swap prefix ] change ]
+        [ value blank-values from-object ]
+        bi
+        @
+    ] with-scope ; inline
 
 : nest-values ( name quot -- )
     swap [
@@ -67,13 +81,13 @@ GENERIC: render* ( value name render -- )
 <PRIVATE
 
 : render-input ( value name type -- )
-    <input =type =name object>string =value input/> ;
+    <input =type =name present =value input/> ;
 
 PRIVATE>
 
 SINGLETON: label
 
-M: label render* 2drop object>string escape-string write ;
+M: label render* 2drop present escape-string write ;
 
 SINGLETON: hidden
 
@@ -82,9 +96,9 @@ M: hidden render* drop "hidden" render-input ;
 : render-field ( value name size type -- )
     <input
         =type
-        [ object>string =size ] when*
+        [ present =size ] when*
         =name
-        object>string =value
+        present =value
     input/> ;
 
 TUPLE: field size ;
@@ -111,11 +125,11 @@ TUPLE: textarea rows cols ;
 
 M: textarea render*
     <textarea
-        [ rows>> [ object>string =rows ] when* ]
-        [ cols>> [ object>string =cols ] when* ] bi
+        [ rows>> [ present =rows ] when* ]
+        [ cols>> [ present =cols ] when* ] bi
         =name
     textarea>
-        object>string escape-string write
+        present escape-string write
     </textarea> ;
 
 ! Choice
@@ -126,7 +140,7 @@ TUPLE: choice size multiple choices ;
 
 : render-option ( text selected? -- )
     <option [ "true" =selected ] when option>
-        object>string escape-string write
+        present escape-string write
     </option> ;
 
 : render-options ( options selected -- )
@@ -135,7 +149,7 @@ TUPLE: choice size multiple choices ;
 M: choice render*
     <select
         swap =name
-        dup size>> [ object>string =size ] when*
+        dup size>> [ present =size ] when*
         dup multiple>> [ "true" =multiple ] when
     select>
         [ choices>> value ] [ multiple>> ] bi
@@ -162,12 +176,18 @@ M: checkbox render*
 GENERIC: link-title ( obj -- string )
 GENERIC: link-href ( obj -- url )
 
+M: string link-title ;
+M: string link-href ;
+
+M: url link-title ;
+M: url link-href ;
+
 SINGLETON: link
 
 M: link render*
     2drop
     <a dup link-href =href a>
-        link-title object>string escape-string write
+        link-title present escape-string write
     </a> ;
 
 ! XMode code component
index 8d92d9f4d74c076c9888290bc022c17ef06b58a0..5fc4bd19aea7054cfbb44b6bc9993122e11bdc31 100644 (file)
@@ -5,7 +5,7 @@
 
 USING: io kernel namespaces prettyprint quotations
 sequences strings words xml.entities compiler.units effects
-urls math math.parser combinators calendar calendar.format ;
+urls math math.parser combinators present ;
 
 IN: html.elements
 
@@ -65,52 +65,50 @@ SYMBOL: html
     #! dynamically creating words.
     >r >r elements-vocab create r> r> define-declared ;
 
-: <foo> "<" swap ">" 3append ;
-
-: empty-effect T{ effect f 0 0 } ;
+: <foo> ( str -- <str> ) "<" swap ">" 3append ;
 
 : def-for-html-word-<foo> ( name -- )
     #! Return the name and code for the <foo> patterned
     #! word.
     dup <foo> swap [ <foo> write-html ] curry
-    empty-effect html-word ;
+    (( -- )) html-word ;
 
-: <foo "<" prepend ;
+: <foo ( str -- <str ) "<" prepend ;
 
 : def-for-html-word-<foo ( name -- )
     #! Return the name and code for the <foo patterned
     #! word.
     <foo dup [ write-html ] curry
-    empty-effect html-word ;
+    (( -- )) html-word ;
 
-: foo> ">" append ;
+: foo> ( str -- foo> ) ">" append ;
 
 : def-for-html-word-foo> ( name -- )
     #! Return the name and code for the foo> patterned
     #! word.
-    foo> [ ">" write-html ] empty-effect html-word ;
+    foo> [ ">" write-html ] (( -- )) html-word ;
 
-: </foo> "</" swap ">" 3append ;
+: </foo> ( str -- </str> ) "</" swap ">" 3append ;
 
 : def-for-html-word-</foo> ( name -- )
     #! Return the name and code for the </foo> patterned
     #! word.
-    </foo> dup [ write-html ] curry empty-effect html-word ;
+    </foo> dup [ write-html ] curry (( -- )) html-word ;
 
-: <foo/> "<" swap "/>" 3append ;
+: <foo/> ( str -- <str/> ) "<" swap "/>" 3append ;
 
 : def-for-html-word-<foo/> ( name -- )
     #! Return the name and code for the <foo/> patterned
     #! word.
     dup <foo/> swap [ <foo/> write-html ] curry
-    empty-effect html-word ;
+    (( -- )) html-word ;
 
-: foo/> "/>" append ;
+: foo/> ( str -- str/> ) "/>" append ;
 
 : def-for-html-word-foo/> ( name -- )
     #! Return the name and code for the foo/> patterned
     #! word.
-    foo/> [ "/>" write-html ] empty-effect html-word ;
+    foo/> [ "/>" write-html ] (( -- )) html-word ;
 
 : define-closed-html-word ( name -- )
     #! Given an HTML tag name, define the words for
@@ -127,29 +125,16 @@ SYMBOL: html
     dup def-for-html-word-<foo
     def-for-html-word-foo/> ;
 
-: object>string ( object -- string )
-    #! Should this be generic and in the core?
-    {
-        { [ dup real? ] [ number>string ] }
-        { [ dup timestamp? ] [ timestamp>string ] }
-        { [ dup url? ] [ url>string ] }
-        { [ dup string? ] [ ] }
-        { [ dup word? ] [ word-name ] }
-        { [ dup not ] [ drop "" ] }
-    } cond ;
-
 : write-attr ( value name -- )
     " " write-html
     write-html
     "='" write-html
-    object>string escape-quoted-string write-html
+    present escape-quoted-string write-html
     "'" write-html ;
 
-: attribute-effect T{ effect f { "string" } 0 } ;
-
 : define-attribute-word ( name -- )
     dup "=" prepend swap
-    [ write-attr ] curry attribute-effect html-word ;
+    [ write-attr ] curry (( string -- )) html-word ;
 
 ! Define some closed HTML tags
 [
index e3f45e4c25b31e65951a3d156f0b76129d64923b..eae13f53ada60252c9c8469da01ff1000bc5f379 100755 (executable)
@@ -135,7 +135,7 @@ TUPLE: html-block-stream < html-sub-stream ;
 M: html-block-stream dispose ( quot style stream -- )
     end-sub-stream a-div format-html-div ;
 
-: border-spacing-css,
+: border-spacing-css, ( pair -- )
     "padding: " % first2 max 2 /i # "px; " % ;
 
 : table-style ( style -- str )
index d4c02061b2c5ef38c11d61308d5088a9561b66dc..6ca596f5035532b35a669756fc75569fc30106ed 100644 (file)
@@ -148,3 +148,35 @@ TUPLE: person first-name last-name ;
         "test9" test-template call-template
     ] run-template
 ] unit-test
+
+[ ] [ H{ { "a" H{ { "b" "c" } } } } values set ] unit-test
+
+[ "<form method='POST' action='foo'><input type='hidden' name='__n' value='a'/></form>" ] [
+    [
+        "test10" test-template call-template
+    ] run-template
+] unit-test
+
+[ ] [ blank-values ] unit-test
+
+[ ] [
+    H{ { "first-name" "RBaxter" } { "last-name" "Unknown" } } "person" set-value
+] unit-test
+
+[ "<table><tr><td>RBaxter</td><td>Unknown</td></tr></table>" ] [
+    [
+        "test11" test-template call-template
+    ] run-template [ blank? not ] filter
+] unit-test
+
+[ ] [
+    blank-values
+    { "a" "b" } "choices" set-value
+    "true" "b" set-value
+] unit-test
+
+[ "<input type='checkbox' name='a'>a</input><input type='checkbox' name='b' checked='true'>b</input>" ] [
+    [
+        "test12" test-template call-template
+    ] run-template
+] unit-test
index 9e0aa3fe1d533b55aa84c4ec3badcdf85577c36c..08d6b873fcffe52bb4c585798d786424ac7129d6 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors kernel sequences combinators kernel namespaces
 classes.tuple assocs splitting words arrays memoize
 io io.files io.encodings.utf8 io.streams.string
-unicode.case tuple-syntax mirrors fry math urls
+unicode.case tuple-syntax mirrors fry math urls present
 multiline xml xml.data xml.writer xml.utilities
 html.elements
 html.components
@@ -68,7 +68,7 @@ CHLOE: odd "index" value odd? [ process-tag-children ] [ drop ] if ;
 
 : (bind-tag) ( tag quot -- )
     [
-        [ "name" required-attr value ] keep
+        [ "name" required-attr ] keep
         '[ , process-tag-children ]
     ] dip call ; inline
 
@@ -85,6 +85,17 @@ CHLOE: comment drop ;
 
 CHLOE: call-next-template drop call-next-template ;
 
+: attr>word ( value -- word/f )
+    dup ":" split1 swap lookup
+    [ ] [ "No such word: " swap append throw ] ?if ;
+
+: if-satisfied? ( tag -- ? )
+    [ "code" optional-attr [ attr>word execute ] [ t ] if* ]
+    [ "value" optional-attr [ value ] [ t ] if* ]
+    bi and ;
+
+CHLOE: if dup if-satisfied? [ process-tag-children ] [ drop ] if ;
+
 CHLOE-SINGLETON: label
 CHLOE-SINGLETON: link
 CHLOE-SINGLETON: farkup
@@ -116,7 +127,7 @@ CHLOE-TUPLE: code
 : expand-attrs ( tag -- tag )
     dup [ tag? ] is? [
         clone [
-            [ "@" ?head [ value object>string ] when ] assoc-map
+            [ "@" ?head [ value present ] when ] assoc-map
         ] change-attrs
     ] when ;
 
diff --git a/extra/html/templates/chloe/test/test10.xml b/extra/html/templates/chloe/test/test10.xml
new file mode 100644 (file)
index 0000000..33fe200
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0"><t:bind t:name="a"><t:form t:action="foo"/></t:bind></t:chloe>
diff --git a/extra/html/templates/chloe/test/test11.xml b/extra/html/templates/chloe/test/test11.xml
new file mode 100644 (file)
index 0000000..f74256b
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <table>
+               <t:bind t:name="person">
+                       <tr>
+                               <td><t:label t:name="first-name"/></td>
+                               <td><t:label t:name="last-name"/></td>
+                       </tr>
+               </t:bind>
+       </table>
+
+</t:chloe>
diff --git a/extra/html/templates/chloe/test/test12.xml b/extra/html/templates/chloe/test/test12.xml
new file mode 100644 (file)
index 0000000..b26778c
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0"><t:each t:name="choices"><t:checkbox t:name="@value" t:label="@value" /></t:each></t:chloe>
index e6c8791e20e37f4253d98fb9e3320d12428b21f1..7b48bf93aff086c449ef026cfea499dd3a315921 100755 (executable)
@@ -22,7 +22,7 @@ DEFER: http-request
 SYMBOL: redirects
 
 : redirect-url ( request url -- request )
-    '[ , >url derive-url ensure-port ] change-url ;
+    '[ , >url ensure-port derive-url ensure-port ] change-url ;
 
 : do-redirect ( response data -- response data )
     over code>> 300 399 between? [
@@ -100,12 +100,11 @@ M: download-failed error.
 : download ( url -- )
     dup download-name download-to ;
 
-: <post-request> ( content-type content url -- request )
+: <post-request> ( post-data url -- request )
     <request>
         "POST" >>method
         swap >url ensure-port >>url
-        swap >>post-data
-        swap >>post-data-type ;
+        swap >>post-data ;
 
-: http-post ( content-type content url -- response data )
+: http-post ( post-data url -- response data )
     <post-request> http-request ;
index 471d7e276bcc03bde8e8dae04b5f2816faa2c390..c1d5b46aa450d5dad7cd37e8dfb82f57d57e78fb 100755 (executable)
@@ -1,15 +1,16 @@
 USING: http tools.test multiline tuple-syntax
 io.streams.string kernel arrays splitting sequences
-assocs io.sockets db db.sqlite continuations urls ;
+assocs io.sockets db db.sqlite continuations urls hashtables ;
 IN: http.tests
 
 : lf>crlf "\n" split "\r\n" join ;
 
 STRING: read-request-test-1
-GET http://foo/bar HTTP/1.1
+POST http://foo/bar HTTP/1.1
 Some-Header: 1
 Some-Header: 2
 Content-Length: 4
+Content-type: application/octet-stream
 
 blah
 ;
@@ -17,10 +18,10 @@ blah
 [
     TUPLE{ request
         url: TUPLE{ url protocol: "http" port: 80 path: "/bar" }
-        method: "GET"
+        method: "POST"
         version: "1.1"
-        header: H{ { "some-header" "1; 2" } { "content-length" "4" } }
-        post-data: "blah"
+        header: H{ { "some-header" "1; 2" } { "content-length" "4" } { "content-type" "application/octet-stream" } }
+        post-data: TUPLE{ post-data content: "blah" raw: "blah" content-type: "application/octet-stream" }
         cookies: V{ }
     }
 ] [
@@ -30,8 +31,9 @@ blah
 ] unit-test
 
 STRING: read-request-test-1'
-GET /bar HTTP/1.1
+POST /bar HTTP/1.1
 content-length: 4
+content-type: application/octet-stream
 some-header: 1; 2
 
 blah
@@ -87,7 +89,7 @@ blah
         code: 404
         message: "not found"
         header: H{ { "content-type" "text/html; charset=UTF8" } }
-        cookies: V{ }
+        cookies: { }
         content-type: "text/html"
         content-charset: "UTF8"
     }
@@ -172,7 +174,7 @@ test-db [
 [ ] [
     [
         <dispatcher>
-            <action> <protected>
+            <action> <protected>
             <login>
             <sessions>
             "" add-responder
@@ -219,3 +221,56 @@ test-db [
 [ "Hi" ] [ "http://localhost:1237/" http-get ] unit-test
 
 [ "Goodbye" ] [ "http://localhost:1237/quit" http-get ] unit-test
+
+USING: html.components html.elements xml xml.utilities validators
+furnace furnace.flash ;
+
+SYMBOL: a
+
+[ ] [
+    [
+        <dispatcher>
+            <action>
+                [ a get-global "a" set-value ] >>init
+                [ [ <html> "a" <field> render </html> ] "text/html" <content> ] >>display
+                [ { { "a" [ v-integer ] } } validate-params ] >>validate
+                [ "a" value a set-global URL" " <redirect> ] >>submit
+            <flash-scopes>
+            <sessions>
+            >>default
+            add-quit-action
+        test-db <db-persistence>
+        main-responder set
+
+        [ 1237 httpd ] "HTTPD test" spawn drop
+    ] with-scope
+] unit-test
+
+[ ] [ 100 sleep ] unit-test
+
+3 a set-global
+
+: test-a string>xml "input" tag-named "value" swap at ;
+
+[ "3" ] [
+    "http://localhost:1237/" http-get*
+    swap dup cookies>> "cookies" set session-id-key get-cookie
+    value>> "session-id" set test-a
+] unit-test
+
+[ "4" ] [
+    H{ { "a" "4" } { "__u" "http://localhost:1237/" } } "session-id" get session-id-key associate assoc-union
+    "http://localhost:1237/" <post-request> "cookies" get >>cookies http-request nip test-a
+] unit-test
+
+[ 4 ] [ a get-global ] unit-test
+
+! Test flash scope
+[ "xyz" ] [
+    H{ { "a" "xyz" } { "__u" "http://localhost:1237/" } } "session-id" get session-id-key associate assoc-union
+    "http://localhost:1237/" <post-request> "cookies" get >>cookies http-request nip test-a
+] unit-test
+
+[ 4 ] [ a get-global ] unit-test
+
+[ "Goodbye" ] [ "http://localhost:1237/quit" http-get ] unit-test
index e8f7189f7524b81a9835472d2176ea30d93391c7..04bebce9260698b6bc9aa997feb76e930d4017aa 100755 (executable)
@@ -4,19 +4,19 @@ USING: accessors kernel combinators math namespaces
 
 assocs sequences splitting sorting sets debugger
 strings vectors hashtables quotations arrays byte-arrays
-math.parser calendar calendar.format
+math.parser calendar calendar.format present
 
 io io.server io.sockets.secure
 
 unicode.case unicode.categories qualified
 
-urls html.templates ;
+urls html.templates xml xml.data xml.writer ;
 
 EXCLUDE: fry => , ;
 
 IN: http
 
-: crlf "\r\n" write ;
+: crlf ( -- ) "\r\n" write ;
 
 : add-header ( value key assoc -- )
     [ at dup [ "; " rot 3append ] [ drop ] if ] 2keep set-at ;
@@ -54,11 +54,9 @@ IN: http
 
 : header-value>string ( value -- string )
     {
-        { [ dup number? ] [ number>string ] }
         { [ dup timestamp? ] [ timestamp>http-string ] }
-        { [ dup url? ] [ url>string ] }
-        { [ dup string? ] [ ] }
-        { [ dup sequence? ] [ [ header-value>string ] map "; " join ] }
+        { [ dup array? ] [ [ header-value>string ] map "; " join ] }
+        [ present ]
     } cond ;
 
 : check-header-string ( str -- str )
@@ -132,13 +130,12 @@ url
 version
 header
 post-data
-post-data-type
 cookies ;
 
 : set-header ( request/response value key -- request/response )
     pick header>> set-at ;
 
-: <request>
+: <request> ( -- request )
     request new
         "1.1" >>version
         <url>
@@ -177,19 +174,27 @@ cookies ;
 : header ( request/response key -- value )
     swap header>> at ;
 
-SYMBOL: max-post-request
+TUPLE: post-data raw content content-type ;
 
-1024 256 * max-post-request set-global
+: <post-data> ( raw content-type -- post-data )
+    post-data new
+        swap >>content-type
+        swap >>raw ;
 
-: content-length ( header -- n )
-    "content-length" swap at string>number dup [
-        dup max-post-request get > [
-            "content-length > max-post-request" throw
-        ] when
-    ] when ;
+: parse-post-data ( post-data -- post-data )
+    [ ] [ raw>> ] [ content-type>> ] tri {
+        { "application/x-www-form-urlencoded" [ query>assoc ] }
+        { "text/xml" [ string>xml ] }
+        [ drop ]
+    } case >>content ;
 
 : read-post-data ( request -- request )
-    dup header>> content-length [ read >>post-data ] when* ;
+    dup method>> "POST" = [
+        [ ]
+        [ "content-length" header string>number read ]
+        [ "content-type" header ] tri
+        <post-data> parse-post-data >>post-data
+    ] when ;
 
 : extract-host ( request -- request )
     [ ] [ url>> ] [ "host" header parse-host ] tri
@@ -197,13 +202,6 @@ SYMBOL: max-post-request
     ensure-port
     drop ;
 
-: extract-post-data-type ( request -- request )
-    dup "content-type" header >>post-data-type ;
-
-: parse-post-data ( request -- request )
-    dup post-data-type>> "application/x-www-form-urlencoded" =
-    [ dup post-data>> query>assoc >>post-data ] when ;
-
 : extract-cookies ( request -- request )
     dup "cookie" header [ parse-cookies >>cookies ] when* ;
 
@@ -225,25 +223,17 @@ SYMBOL: max-post-request
     read-post-data
     detect-protocol
     extract-host
-    extract-post-data-type
-    parse-post-data
     extract-cookies ;
 
 : write-method ( request -- request )
     dup method>> write bl ;
 
 : write-request-url ( request -- request )
-    dup url>> relative-url url>string write bl ;
+    dup url>> relative-url present write bl ;
 
 : write-version ( request -- request )
     "HTTP/" write dup request-version write crlf ;
 
-: unparse-post-data ( request -- request )
-    dup post-data>> dup sequence? [ drop ] [
-        assoc>query >>post-data
-        "application/x-www-form-urlencoded" >>post-data-type
-    ] if ;
-
 : url-host ( url -- string )
     [ host>> ] [ port>> ] bi dup "http" protocol-port =
     [ drop ] [ ":" swap number>string 3append ] if ;
@@ -251,13 +241,33 @@ SYMBOL: max-post-request
 : write-request-header ( request -- request )
     dup header>> >hashtable
     over url>> host>> [ over url>> url-host "host" pick set-at ] when
-    over post-data>> [ length "content-length" pick set-at ] when*
-    over post-data-type>> [ "content-type" pick set-at ] when*
+    over post-data>> [
+        [ raw>> length "content-length" pick set-at ]
+        [ content-type>> "content-type" pick set-at ]
+        bi
+    ] when*
     over cookies>> f like [ unparse-cookies "cookie" pick set-at ] when*
     write-header ;
 
+GENERIC: >post-data ( object -- post-data )
+
+M: post-data >post-data ;
+
+M: string >post-data "application/octet-stream" <post-data> ;
+
+M: byte-array >post-data "application/octet-stream" <post-data> ;
+
+M: xml >post-data xml>string "text/xml" <post-data> ;
+
+M: assoc >post-data assoc>query "application/x-www-form-urlencoded" <post-data> ;
+
+M: f >post-data ;
+
+: unparse-post-data ( request -- request )
+    [ >post-data ] change-post-data ;
+
 : write-post-data ( request -- request )
-    dup post-data>> [ write ] when* ;
+    dup method>> "POST" = [ dup post-data>> raw>> write ] when ; 
 
 : write-request ( request -- )
     unparse-post-data
@@ -283,7 +293,7 @@ content-type
 content-charset
 body ;
 
-: <response>
+: <response> ( -- response )
     response new
         "1.1" >>version
         H{ } clone >>header
@@ -291,23 +301,23 @@ body ;
         now timestamp>http-string "date" set-header
         V{ } clone >>cookies ;
 
-: read-response-version
+: read-response-version ( response -- response )
     " \t" read-until
     [ "Bad response: version" throw ] unless
     parse-version
     >>version ;
 
-: read-response-code
+: read-response-code ( response -- response )
     " \t" read-until [ "Bad response: code" throw ] unless
     string>number [ "Bad response: code" throw ] unless*
     >>code ;
 
-: read-response-message
+: read-response-message ( response -- response )
     read-crlf >>message ;
 
-: read-response-header
+: read-response-header ( response -- response )
     read-header >>header
-    extract-cookies
+    dup "set-cookie" header parse-cookies >>cookies
     dup "content-type" header [
         parse-content-type [ >>content-type ] [ >>content-charset ] bi*
     ] when* ;
index cf8a35f141ce67d1de0f247d024837d0e23820b0..626cd78e14e20765f0aa5c036685fff63e08b2c5 100755 (executable)
@@ -5,7 +5,7 @@ combinators arrays io.launcher io http.server.static http.server
 http accessors sequences strings math.parser fry urls ;\r
 IN: http.server.cgi\r
 \r
-: post? request get method>> "POST" = ;\r
+: post? ( -- ? ) request get method>> "POST" = ;\r
 \r
 : cgi-variables ( script-path -- assoc )\r
     #! This needs some work.\r
@@ -35,8 +35,10 @@ IN: http.server.cgi
         request get "accept" header "HTTP_ACCEPT" set\r
 \r
         post? [\r
-            request get post-data-type>> "CONTENT_TYPE" set\r
-            request get post-data>> length number>string "CONTENT_LENGTH" set\r
+            request get post-data>> raw>>\r
+            [ "CONTENT_TYPE" set ]\r
+            [ length number>string "CONTENT_LENGTH" set ]\r
+            bi\r
         ] when\r
     ] H{ } make-assoc ;\r
 \r
@@ -51,7 +53,7 @@ IN: http.server.cgi
     "CGI output follows" >>message\r
     swap '[\r
         , output-stream get swap <cgi-process> <process-stream> [\r
-            post? [ request get post-data>> write flush ] when\r
+            post? [ request get post-data>> raw>> write flush ] when\r
             input-stream get swap (stream-copy)\r
         ] with-stream\r
     ] >>body ;\r
index 36eb447fc38526eaec24f52aaa300254e4f716f4..2da26959922b2087e6f0998026ce8e52962172a3 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces sequences assocs accessors
-http http.server http.server.responses ;
+USING: kernel namespaces sequences assocs accessors splitting
+unicode.case http http.server http.server.responses ;
 IN: http.server.dispatchers
 
 TUPLE: dispatcher default responders ;
@@ -31,8 +31,11 @@ TUPLE: vhost-dispatcher default responders ;
 : <vhost-dispatcher> ( -- dispatcher )
     vhost-dispatcher new-dispatcher ;
 
+: canonical-host ( host -- host' )
+    >lower "www." ?head drop "." ?tail drop ;
+
 : find-vhost ( dispatcher -- responder )
-    request get url>> host>> over responders>> at*
+    request get url>> host>> canonical-host over responders>> at*
     [ nip ] [ drop default>> ] if ;
 
 M: vhost-dispatcher call-responder* ( path dispatcher -- response )
index 0b882318559ef6f9e22f953f644d8f6442146d35..04af89ec98f300aadc372fbab378de0ea7ae73af 100644 (file)
@@ -1,6 +1,6 @@
 IN: http.server.redirection.tests
 USING: http http.server.redirection urls accessors
-namespaces tools.test ;
+namespaces tools.test present ;
 
 \ relative-to-request must-infer
 
@@ -15,34 +15,34 @@ namespaces tools.test ;
     request set
 
     [ "http://www.apple.com:80/xxx/bar" ] [ 
-        <url> relative-to-request url>string 
+        <url> relative-to-request present 
     ] unit-test
 
     [ "http://www.apple.com:80/xxx/baz" ] [
-        <url> "baz" >>path relative-to-request url>string
+        <url> "baz" >>path relative-to-request present
     ] unit-test
     
     [ "http://www.apple.com:80/xxx/baz?c=d" ] [
-        <url> "baz" >>path { { "c" "d" } } >>query relative-to-request url>string
+        <url> "baz" >>path { { "c" "d" } } >>query relative-to-request present
     ] unit-test
     
     [ "http://www.apple.com:80/xxx/bar?c=d" ] [
-        <url> { { "c" "d" } } >>query relative-to-request url>string
+        <url> { { "c" "d" } } >>query relative-to-request present
     ] unit-test
     
     [ "http://www.apple.com:80/flip" ] [
-        <url> "/flip" >>path relative-to-request url>string
+        <url> "/flip" >>path relative-to-request present
     ] unit-test
     
     [ "http://www.apple.com:80/flip?c=d" ] [
-        <url> "/flip" >>path { { "c" "d" } } >>query relative-to-request url>string
+        <url> "/flip" >>path { { "c" "d" } } >>query relative-to-request present
     ] unit-test
     
     [ "http://www.jedit.org:80/" ] [
-        "http://www.jedit.org" >url relative-to-request url>string
+        "http://www.jedit.org" >url relative-to-request present
     ] unit-test
     
     [ "http://www.jedit.org:80/?a=b" ] [
-        "http://www.jedit.org" >url { { "a" "b" } } >>query relative-to-request url>string
+        "http://www.jedit.org" >url { { "a" "b" } } >>query relative-to-request present
     ] unit-test
 ] with-scope
diff --git a/extra/http/server/server-tests.factor b/extra/http/server/server-tests.factor
new file mode 100644 (file)
index 0000000..c29912b
--- /dev/null
@@ -0,0 +1,4 @@
+USING: http http.server math sequences continuations tools.test ;
+IN: http.server.tests
+
+[ t ] [ [ \ + first ] [ <500> ] recover response? ] unit-test
index 02424ef97442e0dc9f13c7b323a512f5c683c4a4..fc50432030d8de719eefa1647334222f9a62d0e8 100755 (executable)
@@ -22,7 +22,7 @@ C: <trivial-responder> trivial-responder
 
 M: trivial-responder call-responder* nip response>> clone ;
 
-main-responder global [ <404> <trivial-responder> get-global or ] change-at
+main-responder global [ <404> <trivial-responder> or ] change-at
 
 : invert-slice ( slice -- slice' )
     dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ;
@@ -40,12 +40,17 @@ main-responder global [ <404> <trivial-responder> get-global or ] change-at
 
 : <500> ( error -- response )
     500 "Internal server error" <trivial-response>
-    development-mode get [ swap '[ , http-error. ] >>body ] [ drop ] if ;
+    swap development-mode get [ '[ , http-error. ] >>body ] [ drop ] if ;
 
 : do-response ( response -- )
     dup write-response
-    request get method>> "HEAD" =
-    [ drop ] [ '[ , write-response-body ] [ http-error. ] recover ] if ;
+    request get method>> "HEAD" = [ drop ] [
+        '[ , write-response-body ]
+        [
+            development-mode get
+            [ http-error. ] [ drop "Response error" ] if
+        ] recover
+    ] if ;
 
 LOG: httpd-hit NOTICE
 
index ca6f9d590553ac9cc3d6e610caa0494bbc56fbd0..d12d35a6d2eef41e3556d246489865ff020a7486 100755 (executable)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2007 Gavin Harrison
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math sequences kernel.private namespaces arrays io
-io.files splitting io.binary math.functions vectors quotations
-combinators io.encodings.binary ;
+io.files splitting grouping io.binary math.functions vectors
+quotations combinators io.encodings.binary ;
 IN: icfp.2006
 
 SYMBOL: regs
index a8cd1fea91df259f3848451ebf0867f270bf1565..d4e61223215ce131965bb05ec10859aa9bfb6f45 100755 (executable)
@@ -68,7 +68,7 @@ M: 8-bit decode-char
     decode>> decode-8-bit ;
 
 : make-8-bit ( word byte>ch ch>byte -- )
-    [ 8-bit boa ] 2curry dupd curry define ;
+    [ 2drop ] [ 8-bit boa ] 3bi [ ] curry define ;
 
 : define-8-bit-encoding ( name stream -- )
     >r in get create r> parse-file make-8-bit ;
index f98fa4b0d4574975c34541b318293f1aca4b9780..b519752e799847fc24eac58bca8a8e4bff843aba 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.encodings io.backend io.ports io.streams.duplex
-io splitting sequences sequences.lib namespaces kernel
+io splitting grouping sequences sequences.lib namespaces kernel
 destructors math concurrency.combinators accessors
 arrays continuations quotations ;
 IN: io.pipes
@@ -22,8 +22,11 @@ HOOK: (pipe) io-backend ( -- pipe )
 
 <PRIVATE
 
-: ?reader [ <input-port> &dispose ] [ input-stream get ] if* ;
-: ?writer [ <output-port> &dispose ] [ output-stream get ] if* ;
+: ?reader ( handle/f -- stream )
+    [ <input-port> &dispose ] [ input-stream get ] if* ;
+
+: ?writer ( handle/f -- stream )
+    [ <output-port> &dispose ] [ output-stream get ] if* ;
 
 GENERIC: run-pipeline-element ( input-fd output-fd obj -- quot )
 
index 549362ad0cc8cfca86ff906887e9fa7fb2de41bb..1cbbac7f2010ffd33f1125a89e65e6e5a003dfe3 100755 (executable)
@@ -3,7 +3,7 @@
 USING: math kernel io sequences io.buffers io.timeouts generic
 byte-vectors system io.encodings math.order io.backend
 continuations debugger classes byte-arrays namespaces splitting
-dlists assocs io.encodings.binary inspector accessors
+grouping dlists assocs io.encodings.binary inspector accessors
 destructors ;
 IN: io.ports
 
index c5dbded093422702cb129cef44b1714d322e1215..4efd30c65ed94d96abde5bf398bbb7872b585e8c 100755 (executable)
@@ -5,7 +5,8 @@ USING: generic kernel io.backend namespaces continuations
 sequences arrays io.encodings io.ports io.streams.duplex
 io.encodings.ascii alien.strings io.binary accessors destructors
 classes debugger byte-arrays system combinators parser
-alien.c-types math.parser splitting math assocs inspector ;
+alien.c-types math.parser splitting grouping
+math assocs inspector ;
 IN: io.sockets
 
 << {
@@ -80,7 +81,7 @@ M: inet4 make-sockaddr ( inet -- sockaddr )
 
 SYMBOL: port-override
 
-: (port) port-override get swap or ;
+: (port) ( port -- port' ) port-override get swap or ;
 
 PRIVATE>
 
index 3b9c8fc7af8ecefc7c29c57cf559082118b461dc..7f6b3396a1e5b2252bb822295b2a07fa1b254a16 100755 (executable)
@@ -62,7 +62,8 @@ USE: unix
         [ >r >r underlying-handle r> r> redirect ]
     } cond ;
 
-: ?closed dup +closed+ eq? [ drop "/dev/null" ] when ;
+: ?closed ( obj -- obj' )
+    dup +closed+ eq? [ drop "/dev/null" ] when ;
 
 : setup-redirection ( process -- process )
     dup stdin>> ?closed read-flags 0 redirect
index f3bb82343a70973dbf3066a152c1ba684a4a2ff5..e5e83ab4e9599e94fec6225f425ceb1f7174fdaa 100755 (executable)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: peg peg.parsers kernel sequences strings words
-memoize ;
+USING: peg peg.parsers kernel sequences strings words ;
 IN: io.unix.launcher.parser
 
 ! Our command line parser. Supported syntax:
@@ -9,20 +8,20 @@ IN: io.unix.launcher.parser
 ! foo\ bar -- escaping the space
 ! 'foo bar' -- quotation
 ! "foo bar" -- quotation
-MEMO: 'escaped-char' ( -- parser )
-    "\\" token [ drop t ] satisfy 2seq [ second ] action ;
+: 'escaped-char' ( -- parser )
+    "\\" token any-char 2seq [ second ] action ;
 
-MEMO: 'quoted-char' ( delimiter -- parser' )
+: 'quoted-char' ( delimiter -- parser' )
     'escaped-char'
     swap [ member? not ] curry satisfy
     2choice ; inline
 
-MEMO: 'quoted' ( delimiter -- parser )
+: 'quoted' ( delimiter -- parser )
     dup 'quoted-char' repeat0 swap dup surrounded-by ;
 
-MEMO: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ;
+: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ;
 
-MEMO: 'argument' ( -- parser )
+: 'argument' ( -- parser )
     "\"" 'quoted'
     "'" 'quoted'
     'unquoted' 3choice
index 4c0bf5daf9a1e49b6f7a838e319bf56ea6875dfc..a59d5dfb4d91a86c8362665ac3ebaee35fc2c9d2 100644 (file)
@@ -25,7 +25,7 @@ TUPLE: linux-monitor < monitor wd inotify watches disposed ;
 : <inotify> ( -- port/f )
     inotify_init dup 0 < [ drop f ] [ <fd> <input-port> ] if ;
 
-: inotify-fd inotify get handle>> handle-fd ;
+: inotify-fd ( -- fd ) inotify get handle>> handle-fd ;
 
 : check-existing ( wd -- )
     watches get key? [
@@ -41,7 +41,7 @@ TUPLE: linux-monitor < monitor wd inotify watches disposed ;
     [ (add-watch) ] [ drop ] 2bi r>
     <linux-monitor> [ ] [ ] [ wd>> ] tri watches get set-at ;
 
-: check-inotify
+: check-inotify ( -- )
     inotify get [
         "Calling <monitor> outside with-monitors" throw
     ] unless ;
index fea5f4e9ae8b8008fef282d975088725b66822b7..5f127995c57576f2083df5515d8c99ccbefa85f4 100755 (executable)
@@ -30,10 +30,10 @@ TUPLE: select-mx < mx read-fdset write-fdset ;
 : init-fdset ( fds fdset -- )
     [ >r t swap munge r> set-nth ] curry each ;
 
-: read-fdset/tasks
+: read-fdset/tasks ( mx -- seq fdset )
     [ reads>> keys ] [ read-fdset>> ] bi ;
 
-: write-fdset/tasks
+: write-fdset/tasks ( mx -- seq fdset )
     [ writes>> keys ] [ write-fdset>> ] bi ;
 
 : max-fd ( assoc -- n )
index ef3db0dcd1af1cc7c66c8bc782960a4c91bc289a..6787936f96752c9c8007330d1c6c0a8b6c6b4b22 100755 (executable)
@@ -146,7 +146,7 @@ SYMBOLS: +read-only+ +hidden+ +system+
 : win32-file-type ( n -- symbol )
     FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ;
 
-: WIN32_FIND_DATA>file-info
+: WIN32_FIND_DATA>file-info ( WIN32_FIND_DATA -- file-info )
     {
         [ WIN32_FIND_DATA-dwFileAttributes win32-file-type ]
         [
@@ -167,7 +167,7 @@ SYMBOLS: +read-only+ +hidden+ +system+
         FindClose win32-error=0/f
     ] keep ;
 
-: BY_HANDLE_FILE_INFORMATION>file-info
+: BY_HANDLE_FILE_INFORMATION>file-info ( HANDLE_FILE_INFORMATION -- file-info )
     {
         [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-type ]
         [
index 72dfca9df3d038b33af6b30717d0bb8cc36d1b06..660a4017be8e9fe1729271d3f897eee0ce5a789b 100755 (executable)
@@ -5,10 +5,10 @@ windows windows.advapi32 windows.kernel32 io.backend system
 accessors locals ;
 IN: io.windows.mmap
 
-: create-file-mapping
+: create-file-mapping ( hFile lpAttributes flProtect dwMaximumSizeHigh dwMaximumSizeLow lpName -- HANDLE )
     CreateFileMapping [ win32-error=0/f ] keep <win32-handle> ;
 
-: map-view-of-file
+: map-view-of-file ( hFileMappingObject dwDesiredAccess dwFileOffsetHigh dwFileOffsetLow dwNumberOfBytesToMap -- HANDLE )
     MapViewOfFile [ win32-error=0/f ] keep ;
 
 :: mmap-open ( path length access-mode create-mode protect access -- handle handle address )
index fffc97b4c69794af25604e60aece670b7a5ba789..4171c79a0aaf1829a68362d61f3de5d28b96cb76 100644 (file)
@@ -1,8 +1,6 @@
 ! Copyright (C) 2007 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types colors jamshred.game jamshred.oint
-jamshred.player jamshred.tunnel kernel math math.vectors opengl
-opengl.gl opengl.glu sequences ;
+USING: accessors alien.c-types colors jamshred.game jamshred.oint jamshred.player jamshred.tunnel kernel math math.constants math.functions math.vectors opengl opengl.gl opengl.glu sequences ;
 IN: jamshred.gl
 
 : min-vertices 6 ; inline
@@ -14,6 +12,35 @@ IN: jamshred.gl
 : 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 segment-color gl-color segment-vertex-and-normal
     gl-normal gl-vertex ;
index 078a23f5dbb5c25758c8a6d00a57c9f963f1cbaf..b7764894d10d42c813a5974b26dfaaf352be36ab 100755 (executable)
@@ -88,7 +88,7 @@ jamshred-gadget H{
     { T{ mouse-scroll } [ handle-mouse-scroll ] }
 } set-gestures
 
-: jamshred-window ( -- )
-    [ <jamshred> <jamshred-gadget> "Jamshred" open-window ] with-ui ;
+: jamshred-window ( -- jamshred )
+    [ <jamshred> dup <jamshred-gadget> "Jamshred" open-window ] with-ui ;
 
 MAIN: jamshred-window
index d50a93a3d2473500d1e155af1b86251af0e8e915..7a37646a6d7a50134e34ca5c1c2fcf3c3e159a55 100644 (file)
@@ -39,8 +39,11 @@ C: <oint> oint
 : 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>> v+ ] [ (>>location) ] tri ;
+    [ forward>> n*v ] [ location+ ] bi ;
 
 : distance-vector ( oint oint -- vector )
     [ location>> ] bi@ swap v- ;
@@ -62,3 +65,9 @@ C: <oint> oint
 :: 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 ;
index 8dc512514338cc80772e266fbf2b8ef8795bc17e..c40729e35b0541512e08c7396d76dcf7c6481dd0 100644 (file)
@@ -1,6 +1,7 @@
-! Copyright (C) 2007 Alex Chapman
+! Copyright (C) 2007, 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors colors combinators jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel math math.constants math.order math.ranges shuffle sequences system ;
+USING: accessors colors combinators jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel locals math math.constants math.order math.ranges math.vectors math.matrices shuffle sequences system ;
+USE: tools.walker
 IN: jamshred.player
 
 TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ;
@@ -30,6 +31,9 @@ TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ;
     [ 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 )
@@ -41,38 +45,82 @@ TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ;
 : multiply-player-speed ( n player -- )
     [ * speed-range clamp-to-range ] change-speed drop ; 
 
-: distance-to-move ( player -- distance )
-    [ speed>> ] [ last-move>> millis dup >r swap - 1000 / * r> ]
-    [ (>>last-move) ] tri ;
+: distance-to-move ( seconds-passed player -- distance )
+    speed>> * ;
 
-DEFER: (move-player)
+: bounce ( d-left player -- d-left' player )
+    {
+        [ dup nearest-segment>> bounce-off-wall ]
+        [ sounds>> bang ]
+        [ 3/4 swap multiply-player-speed ]
+        [ ]
+    } cleave ;
 
-: ?bounce ( distance-remaining player -- )
-    over 0 > [
-        {
-            [ dup nearest-segment>> bounce ]
-            [ sounds>> bang ]
-            [ 3/4 swap multiply-player-speed ]
-            [ (move-player) ]
-        } 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) ;
+
+: 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-distance ( distance-remaining player distance -- distance-remaining player )
-    pick min tuck over go-forward [ - ] dip ;
+:: 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 ] ;
 
-: (move-player) ( distance-remaining player -- )
-    over 0 <= [
-        2drop
-    ] [
-        dup dup nearest-segment>> distance-to-collision
-        move-player-distance ?bounce
-    ] if ;
+: move-toward-wall ( d-left player d-to-wall -- d-left' player )
+    over [ forward>> ] keep distance-to-heading-segment-area min
+    over forward>> move-player-on-heading ;
+
+: ?move-player-freely ( d-left player -- d-left' player )
+    over 0 > [
+        dup distance-to-collision dup 0.2 > [ ! bug! should be 0, not 0.2
+            move-toward-wall ?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 -- )
-    [ distance-to-move ] [ (move-player) ] [ update-nearest-segment ] tri ;
+    [ update-time ] [ distance-to-move ] [ (move-player) 2drop ] tri ;
 
 : update-player ( player -- )
-    dup move-player nearest-segment>>
-    white swap set-segment-color ;
+    [ move-player ] [ nearest-segment>> white swap (>>color) ] bi ;
index 903ff947391bbbc6b227696a85d2ef58ca4ab95d..722609851a9c4d063e2940e239a3fec5c8c2535e 100644 (file)
@@ -42,4 +42,4 @@ IN: jamshred.tunnel.tests
 [ { 0 1 0 } ] [ simple-collision-up sideways-heading ] unit-test
 [ { 0 0 0 } ] [ simple-collision-up sideways-relative-location ] unit-test
 [ { 0 1 0 } ]
-[ simple-collision-up collision-vector 0 bounce-offset 0 3array v+ ] unit-test
+[ simple-collision-up collision-vector 0 0 0 3array v+ ] unit-test
index 5cf1e33e64a8f19f1c32213aa70ea51c74edb54a..99c396bebde9199a3757039f8e265df7794176ae 100755 (executable)
@@ -1,6 +1,7 @@
-! Copyright (C) 2007 Alex Chapman
+! Copyright (C) 2007, 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays combinators float-arrays kernel jamshred.oint locals math math.functions math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ;
+USING: accessors arrays combinators float-arrays kernel jamshred.oint locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ;
+USE: tools.walker
 IN: jamshred.tunnel
 
 : n-segments ( -- n ) 5000 ; inline
@@ -8,21 +9,6 @@ IN: jamshred.tunnel
 TUPLE: segment < oint number color radius ;
 C: <segment> segment
 
-: segment-vertex ( theta segment -- vertex )
-     tuck 2dup up>> swap sin v*n
-     >r left>> swap cos v*n r> v+
-     swap location>> v+ ;
-
-: 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 ;
-
 : segment-number++ ( segment -- )
     [ number>> 1+ ] keep (>>number) ;
 
@@ -40,9 +26,7 @@ C: <segment> segment
 : (random-segments) ( segments n -- segments )
     dup 0 > [
         >r dup peek random-segment over push r> 1- (random-segments)
-    ] [
-        drop
-    ] if ;
+    ] [ drop ] if ;
 
 : default-segment-radius ( -- r ) 1 ;
 
@@ -66,7 +50,7 @@ C: <segment> segment
 : <straight-tunnel> ( -- segments )
     n-segments simple-segments ;
 
-: sub-tunnel ( from to sements -- 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> ;
@@ -97,6 +81,32 @@ C: <segment> segment
     [ nearest-segment-forward ] 3keep
     nearest-segment-backward r> nearer-segment ;
 
+: get-segment ( segments n -- segment )
+    over sequence-index-range clamp-to-range swap nth ;
+
+: next-segment ( segments current-segment -- segment )
+    number>> 1+ get-segment ;
+
+: previous-segment ( segments current-segment -- segment )
+    number>> 1- get-segment ;
+
+: heading-segment ( segments current-segment heading -- segment )
+    #! the next segment on the given heading
+    over forward>> v. 0 <=> {
+        { +gt+ [ next-segment ] }
+        { +lt+ [ previous-segment ] }
+        { +eq+ [ nip ] } ! current segment
+    } case ;
+
+:: distance-to-next-segment ( current next location heading -- distance )
+    [let | cf [ current forward>> ] |
+        cf next location>> v. cf location v. - cf heading v. / ] ;
+
+:: distance-to-next-segment-area ( current next location heading -- distance )
+    [let | cf [ current forward>> ]
+           h [ next current half-way-between-oints ] |
+        cf h v. cf location v. - cf heading v. / ] ;
+
 : vector-to-centre ( seg loc -- v )
     over location>> swap v- swap forward>> proj-perp ;
 
@@ -106,19 +116,25 @@ C: <segment> segment
 : wall-normal ( seg oint -- n )
     location>> vector-to-centre normalize ;
 
-: from ( seg loc -- radius d-f-c )
-    dupd location>> distance-from-centre [ radius>> ] dip ;
+: distant ( -- n ) 1000 ;
 
-: distance-from-wall ( seg loc -- distance ) from - ;
-: fraction-from-centre ( seg loc -- fraction ) from / ;
-: fraction-from-wall ( seg loc -- fraction )
-    fraction-from-centre 1 swap - ;
+: 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 )
-    [let* | a [ v dup v. ]
-            b [ v w v. 2 * ]
-            c [ w dup v. r sq - ] |
-        c b a quadratic max ] ;
+    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 ;
@@ -126,18 +142,12 @@ C: <segment> segment
 : sideways-relative-location ( oint segment -- loc )
     [ [ location>> ] bi@ v- ] keep forward>> proj-perp ;
 
-: bounce-offset 0.1 ; inline
-
-: bounce-radius ( segment -- r )
-    radius>> bounce-offset - ; ! bounce before we hit so that we can't see through the wall (hack?)
-
-: collision-vector ( oint segment -- v )
+: (distance-to-collision) ( oint segment -- distance )
     [ sideways-heading ] [ sideways-relative-location ]
-    [ bounce-radius ] 2tri
-    swap [ collision-coefficient ] dip forward>> n*v ;
+    [ nip radius>> ] 2tri collision-coefficient ;
 
-: distance-to-collision ( oint segment -- distance )
-    collision-vector norm ;
+: collision-vector ( oint segment -- v )
+    dupd (distance-to-collision) swap forward>> n*v ;
 
 : bounce-forward ( segment oint -- )
     [ wall-normal ] [ forward>> swap reflect ] [ (>>forward) ] tri ;
@@ -151,6 +161,6 @@ C: <segment> segment
     #! must be done after forward and left!
     nip [ forward>> ] [ left>> cross ] [ (>>up) ] tri ;
 
-: bounce ( oint segment -- )
+: bounce-off-wall ( oint segment -- )
     swap [ bounce-forward ] [ bounce-left ] [ bounce-up ] 2tri ;
 
index 5e6b16dc2f24a7a1da6c5fbf83366c75384cb1b4..6bd690580405f40a5007384cc713f3b5c446305e 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel parser-combinators namespaces sequences promises strings 
        assocs math math.parser math.vectors math.functions math.order
-       lazy-lists hashtables ascii ;
+       lists hashtables ascii ;
 IN: json.reader
 
 ! Grammar for JSON from RFC 4627
index 4194ff6609880903c59583c98e0467e5a3a39e04..7b636609b0301173b1e16d20c47d62d234164c95 100755 (executable)
@@ -7,7 +7,7 @@ splitting sorting shuffle symbols sets math.order ;
 IN: koszul
 
 ! Utilities
-: -1^ odd? -1 1 ? ;
+: -1^ ( m -- n ) odd? -1 1 ? ;
 
 : >alt ( obj -- vec )
     {
@@ -18,7 +18,7 @@ IN: koszul
         [ 1array >alt ]
     } cond ;
 
-: canonicalize
+: canonicalize ( assoc -- assoc' )
     [ nip zero? not ] assoc-filter ;
 
 SYMBOL: terms
@@ -207,8 +207,8 @@ DEFER: (d)
     [ v- ] 2map ;
 
 ! Laplacian
-: m.m' dup flip m. ;
-: m'.m dup flip swap m. ;
+: m.m' ( matrix -- matrix' ) dup flip m. ;
+: m'.m ( matrix -- matrix' ) dup flip swap m. ;
 
 : empty-matrix? ( matrix -- ? )
     dup empty? [ drop t ] [ first empty? ] if ;
diff --git a/extra/lazy-lists/authors.txt b/extra/lazy-lists/authors.txt
deleted file mode 100644 (file)
index f6ba9ba..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Chris Double
-Samuel Tardieu
-Matthew Willis
diff --git a/extra/lazy-lists/examples/authors.txt b/extra/lazy-lists/examples/authors.txt
deleted file mode 100755 (executable)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/lazy-lists/examples/examples-tests.factor b/extra/lazy-lists/examples/examples-tests.factor
deleted file mode 100644 (file)
index d4e3ed7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: lazy-lists.examples lazy-lists tools.test ;
-IN: lazy-lists.examples.tests
-
-[ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test
-[ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test
diff --git a/extra/lazy-lists/examples/examples.factor b/extra/lazy-lists/examples/examples.factor
deleted file mode 100644 (file)
index 844ae31..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! Rewritten by Matthew Willis, July 2006
-! Copyright (C) 2004 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: lazy-lists math kernel sequences quotations ;
-IN: lazy-lists.examples
-
-: naturals 0 lfrom ;
-: positives 1 lfrom ;
-: evens 0 [ 2 + ] lfrom-by ;
-: odds 1 lfrom [ 2 mod 1 = ] lfilter ;
-: powers-of-2 1 [ 2 * ] lfrom-by ;
-: ones 1 [ ] lfrom-by ;
-: squares naturals [ dup * ] lmap ;
-: first-five-squares 5 squares ltake list>array ;
diff --git a/extra/lazy-lists/lazy-lists-docs.factor b/extra/lazy-lists/lazy-lists-docs.factor
deleted file mode 100644 (file)
index b240b3f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-! Copyright (C) 2006 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: help.markup help.syntax sequences strings ;
-IN: lazy-lists 
-
-{ car cons cdr nil nil? list? uncons } related-words
-
-HELP: cons 
-{ $values { "car" "the head of the lazy list" } { "cdr" "the tail of the lazy list" } { "cons" "a cons object" } }
-{ $description "Constructs a cons cell." } ;
-
-HELP: car
-{ $values { "cons" "a cons object" } { "car" "the first item in the list" } }
-{ $description "Returns the first item in the list." } ;
-
-HELP: cdr
-{ $values { "cons" "a cons object" } { "cdr" "a cons object" } }
-{ $description "Returns the tail of the list." } ;
-
-HELP: nil 
-{ $values { "cons" "An empty cons" } }
-{ $description "Returns a representation of an empty list" } ;
-
-HELP: nil? 
-{ $values { "cons" "a cons object" } { "?" "a boolean" } }
-{ $description "Return true if the cons object is the nil cons." } ;
-
-HELP: list? ( object -- ? )
-{ $values { "object" "an object" } { "?" "a boolean" } }
-{ $description "Returns true if the object conforms to the list protocol." } ;
-
-{ 1list 2list 3list } related-words
-
-HELP: 1list
-{ $values { "obj" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 1 element." } ;
-
-HELP: 2list
-{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 2 elements." } ;
-
-HELP: 3list
-{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } }
-{ $description "Create a list with 3 elements." } ;
-
-HELP: lazy-cons
-{ $values { "car" "a quotation with stack effect ( -- X )" } { "cdr" "a quotation with stack effect ( -- cons )" } { "promise" "the resulting cons object" } }
-{ $description "Constructs a cons object for a lazy list from two quotations. The " { $snippet "car" } " quotation should return the head of the list, and the " { $snippet "cons" } " quotation the tail when called. When " { $link cons } " or " { $link cdr } " are called on the lazy-cons object then the appropriate quotation is called." } 
-{ $see-also cons car cdr nil nil? } ;
-
-{ 1lazy-list 2lazy-list 3lazy-list } related-words
-
-HELP: 1lazy-list
-{ $values { "a" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 1 element. The element is the result of calling the quotation. The quotation is only called when the list element is requested." } ;
-
-HELP: 2lazy-list
-{ $values { "a" "a quotation with stack effect ( -- X )" } { "b" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 2 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
-
-HELP: 3lazy-list
-{ $values { "a" "a quotation with stack effect ( -- X )" } { "b" "a quotation with stack effect ( -- X )" } { "c" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
-{ $description "Create a lazy list with 3 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
-
-HELP: <memoized-cons>
-{ $values { "cons" "a cons object" } { "memoized-cons" "the resulting memoized-cons object" } }
-{ $description "Constructs a cons object that wraps an existing cons object. Requests for the car, cdr and nil? will be remembered after the first call, and the previous result returned on subsequent calls." } 
-{ $see-also cons car cdr nil nil? } ;
-
-HELP: lnth
-{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } }
-{ $description "Outputs the nth element of the list." } 
-{ $see-also llength cons car cdr } ;
-
-HELP: llength
-{ $values { "list" "a cons object" } { "n" "a non-negative integer" } }
-{ $description "Outputs the length of the list. This should not be called on an infinite list." } 
-{ $see-also lnth cons car cdr } ;
-
-HELP: uncons
-{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } }
-{ $description "Put the head and tail of the list on the stack." } ;
-
-{ leach lreduce lmap lmap-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lreduce lwhile luntil } related-words
-
-HELP: leach
-{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } }
-{ $description "Call the quotation for each item in the list." } ;
-
-HELP: lreduce
-{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } }
-{ $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ;
-
-HELP: lmap
-{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- X )" } { "result" "resulting cons object" } }
-{ $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-map> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lmap-with
-{ $values { "value" "an object" } { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj elt -- X )" } { "result" "resulting cons object" } }
-{ $description "Variant of " { $link lmap } " which pushes a retained object on each invocation of the quotation." } ;
-
-HELP: ltake
-{ $values { "n" "a non negative integer" } { "list" "a cons object" } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first n items in the list. This is done a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-take> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lfilter
-{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( -- X )" } { "result" "resulting cons object" } }
-{ $description "Perform a similar functionality to that of the " { $link filter } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-filter> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: lwhile
-{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( X -- bool )" } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first items in the list as long as " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: luntil
-{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( X -- bool )" } { "result" "resulting cons object" } }
-{ $description "Outputs a lazy list containing the first items in the list until after " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
-
-HELP: list>vector
-{ $values { "list" "a cons object" } { "vector" "the list converted to a vector" } }
-{ $description "Convert a list to a vector. If the list is a lazy infinite list then this will enter an infinite loop." } 
-{ $see-also list>array } ;
-
-HELP: list>array
-{ $values { "list" "a cons object" } { "array" "the list converted to an array" } }
-{ $description "Convert a list to an array. If the list is a lazy infinite list then this will enter an infinite loop." } 
-{ $see-also list>vector } ;
-
-HELP: lappend
-{ $values { "list1" "a cons object" } { "list2" "a cons object" } { "result" "a lazy list of list2 appended to list1" } }
-{ $description "Perform a similar functionality to that of the " { $link append } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-append> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required. Successive calls to " { $link cdr } " will iterate through list1, followed by list2." } ;
-
-HELP: lfrom-by
-{ $values { "n" "an integer" } { "quot" "a quotation with stack effect ( -- int )" } { "list" "a lazy list of integers" } }
-{ $description "Return an infinite lazy list of values starting from n, with each successive value being the result of applying quot to n." } ;
-
-HELP: lfrom
-{ $values { "n" "an integer" } { "list" "a lazy list of integers" } }
-{ $description "Return an infinite lazy list of incrementing integers starting from n." } ;
-
-HELP: seq>list
-{ $values { "index" "an integer 0 or greater" } { "seq" "a sequence" } { "list" "a list" } }
-{ $description "Convert the sequence into a list, starting from the 'index' offset into the sequence." } 
-{ $see-also >list } ;
-
-HELP: >list
-{ $values { "object" "an object" } { "list" "a list" } }
-{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } 
-{ $see-also seq>list } ;
-
-HELP: lconcat
-{ $values { "list" "a list of lists" } { "result" "a list" } }
-{ $description "Concatenates a list of lists together into one list." } ;
-
-HELP: lcartesian-product
-{ $values { "list1" "a list" } { "list2" "a list" } { "result" "list of cartesian products" } }
-{ $description "Given two lists, return a list containing the cartesian product of those lists." } ;
-
-HELP: lcartesian-product*
-{ $values { "lists" "a list of lists" } { "result" "list of cartesian products" } }
-{ $description "Given a list of lists, return a list containing the cartesian product of those lists." } ;
-
-HELP: lcomp
-{ $values { "list" "a list of lists" } { "quot" "a quotation with stack effect ( seq -- X )" } { "result" "the resulting list" } }
-{ $description "Get the cartesian product of the lists in " { $snippet "list" } " and call " { $snippet "quot" } " call with each element from the cartesian product on the stack, the result of which is returned in the final " { $snippet "list" } "." } ;
-
-HELP: lcomp*
-{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" "a quotation with stack effect ( seq -- X )" } { "list" "the resulting list" } { "result" "a list" } }
-{ $description "Get the cartesian product of the lists in " { $snippet "list" } ", filter it by applying each guard quotation to it and call " { $snippet "quot" } " call with each element from the remaining cartesian product items on the stack, the result of which is returned in the final " { $snippet "list" } "." }
-{ $examples
-  { $code "{ 1 2 3 } >list { 4 5 6 } >list 2list { [ first odd? ] } [ first2 + ] lcomp*" }
-} ;
-
-HELP: lmerge
-{ $values { "list1" "a list" } { "list2" "a list" } { "result" "lazy list merging list1 and list2" } }
-{ $description "Return the result of merging the two lists in a lazy manner." } 
-{ $examples
-  { $example "USING: lazy-lists prettyprint ;" "{ 1 2 3 } >list { 4 5 6 } >list lmerge list>array ." "{ 1 4 2 5 3 6 }" }
-} ;
-
-HELP: lcontents
-{ $values { "stream" "a stream" } { "result" string } }
-{ $description "Returns a lazy list of all characters in the file. " { $link car } " returns the next character in the file, " { $link cdr } " returns the remaining characters as a lazy list. " { $link nil? } " indicates end of file." } 
-{ $see-also llines } ;
-
-HELP: llines
-{ $values { "stream" "a stream" } { "result" "a list" } }
-{ $description "Returns a lazy list of all lines in the file. " { $link car } " returns the next lines in the file, " { $link cdr } " returns the remaining lines as a lazy list. " { $link nil? } " indicates end of file." } 
-{ $see-also lcontents } ;
-
diff --git a/extra/lazy-lists/lazy-lists-tests.factor b/extra/lazy-lists/lazy-lists-tests.factor
deleted file mode 100644 (file)
index 302299b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-! Copyright (C) 2006 Matthew Willis and Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-!
-USING: lazy-lists tools.test kernel math io sequences ;
-IN: lazy-lists.tests
-
-[ { 1 2 3 4 } ] [
-  { 1 2 3 4 } >list list>array
-] unit-test
-
-[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
-  { 1 2 3 } >list { 4 5 } >list 2list lcartesian-product* list>array
-] unit-test
-
-[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
-  { 1 2 3 } >list { 4 5 } >list lcartesian-product list>array
-] unit-test
-
-[ { 5 6 6 7 7 8 } ] [ 
-  { 1 2 3 } >list { 4 5 } >list 2list [ first2 + ] lcomp list>array
-] unit-test
-
-[ { 5 6 7 8 } ] [ 
-  { 1 2 3 } >list { 4 5 } >list 2list { [ first odd? ] } [ first2 + ] lcomp* list>array
-] unit-test
-
-[ { 4 5 6 } ] [ 
-    3 { 1 2 3 } >list [ + ] lmap-with list>array
-] unit-test
diff --git a/extra/lazy-lists/lazy-lists.factor b/extra/lazy-lists/lazy-lists.factor
deleted file mode 100644 (file)
index 6db82ed..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-! Copyright (C) 2004 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-!
-! Updated by Matthew Willis, July 2006
-! Updated by Chris Double, September 2006
-!
-USING: kernel sequences math vectors arrays namespaces
-quotations promises combinators io ;
-IN: lazy-lists
-
-! Lazy List Protocol
-MIXIN: list
-GENERIC: car   ( cons -- car )
-GENERIC: cdr   ( cons -- cdr )
-GENERIC: nil?  ( cons -- ? )
-
-M: promise car ( promise -- car )
-  force car ;
-
-M: promise cdr ( promise -- cdr )
-  force cdr ;
-
-M: promise nil? ( cons -- bool )
-  force nil? ;
-
-TUPLE: cons car cdr ;
-
-C: cons cons
-
-M: cons car ( cons -- car )
-    cons-car ;
-
-M: cons cdr ( cons -- cdr )
-    cons-cdr ;
-
-: nil ( -- cons )
-  T{ cons f f f } ;
-
-M: cons nil? ( cons -- bool )
-    nil eq? ;
-
-: 1list ( obj -- cons )
-    nil cons ;
-
-: 2list ( a b -- cons )
-    nil cons cons ;
-
-: 3list ( a b c -- cons )
-    nil cons cons cons ;
-
-! Both 'car' and 'cdr' are promises
-TUPLE: lazy-cons car cdr ;
-
-: lazy-cons ( car cdr -- promise )
-    [ promise ] bi@ \ lazy-cons boa
-    T{ promise f f t f } clone
-    [ set-promise-value ] keep ;
-
-M: lazy-cons car ( lazy-cons -- car )
-    lazy-cons-car force ;
-
-M: lazy-cons cdr ( lazy-cons -- cdr )
-    lazy-cons-cdr force ;
-
-M: lazy-cons nil? ( lazy-cons -- bool )
-    nil eq? ;
-
-: 1lazy-list ( a -- lazy-cons )
-  [ nil ] lazy-cons ;
-
-: 2lazy-list ( a b -- lazy-cons )
-  1lazy-list 1quotation lazy-cons ;
-
-: 3lazy-list ( a b c -- lazy-cons )
-  2lazy-list 1quotation lazy-cons ;
-
-: lnth ( n list -- elt )
-  swap [ cdr ] times car ;
-
-: (llength) ( list acc -- n )
-  over nil? [ nip ] [ [ cdr ] dip 1+ (llength) ] if ;
-
-: llength ( list -- n )
-  0 (llength) ;
-
-: uncons ( cons -- car cdr )
-    #! Return the car and cdr of the lazy list
-    dup car swap cdr ;
-
-: leach ( list quot -- )
-  swap dup nil? [ 2drop ] [ uncons swapd over 2slip leach ] if ; inline
-
-: lreduce ( list identity quot -- result )
-  swapd leach ; inline
-
-TUPLE: memoized-cons original car cdr nil? ;
-
-: not-memoized ( -- obj )
-  { } ;
-
-: not-memoized? ( obj -- bool )
-  not-memoized eq? ;
-
-: <memoized-cons> ( cons -- memoized-cons )
-  not-memoized not-memoized not-memoized
-  memoized-cons boa ;
-
-M: memoized-cons car ( memoized-cons -- car )
-  dup memoized-cons-car not-memoized? [
-    dup memoized-cons-original car [ swap set-memoized-cons-car ] keep
-  ] [
-    memoized-cons-car
-  ] if ;
-
-M: memoized-cons cdr ( memoized-cons -- cdr )
-  dup memoized-cons-cdr not-memoized? [
-    dup memoized-cons-original cdr [ swap set-memoized-cons-cdr ] keep
-  ] [
-    memoized-cons-cdr
-  ] if ;
-
-M: memoized-cons nil? ( memoized-cons -- bool )
-  dup memoized-cons-nil? not-memoized? [
-    dup memoized-cons-original nil? [ swap set-memoized-cons-nil? ] keep
-  ] [
-    memoized-cons-nil?
-  ] if ;
-
-TUPLE: lazy-map cons quot ;
-
-C: <lazy-map> lazy-map
-
-: lmap ( list quot -- result )
-    over nil? [ 2drop nil ] [ <lazy-map> <memoized-cons> ] if ;
-
-M: lazy-map car ( lazy-map -- car )
-  [ lazy-map-cons car ] keep
-  lazy-map-quot call ;
-
-M: lazy-map cdr ( lazy-map -- cdr )
-  [ lazy-map-cons cdr ] keep
-  lazy-map-quot lmap ;
-
-M: lazy-map nil? ( lazy-map -- bool )
-  lazy-map-cons nil? ;
-
-: lmap-with ( value list quot -- result )
-  with lmap ;
-
-TUPLE: lazy-take n cons ;
-
-C: <lazy-take> lazy-take
-
-: ltake ( n list -- result )
-    over zero? [ 2drop nil ] [ <lazy-take> ] if ;
-
-M: lazy-take car ( lazy-take -- car )
-  lazy-take-cons car ;
-
-M: lazy-take cdr ( lazy-take -- cdr )
-  [ lazy-take-n 1- ] keep
-  lazy-take-cons cdr ltake ;
-
-M: lazy-take nil? ( lazy-take -- bool )
-  dup lazy-take-n zero? [
-    drop t
-  ] [
-    lazy-take-cons nil?
-  ] if ;
-
-TUPLE: lazy-until cons quot ;
-
-C: <lazy-until> lazy-until
-
-: luntil ( list quot -- result )
-  over nil? [ drop ] [ <lazy-until> ] if ;
-
-M: lazy-until car ( lazy-until -- car )
-   lazy-until-cons car ;
-
-M: lazy-until cdr ( lazy-until -- cdr )
-   [ lazy-until-cons uncons swap ] keep lazy-until-quot tuck call
-   [ 2drop nil ] [ luntil ] if ;
-
-M: lazy-until nil? ( lazy-until -- bool )
-   drop f ;
-
-TUPLE: lazy-while cons quot ;
-
-C: <lazy-while> lazy-while
-
-: lwhile ( list quot -- result )
-  over nil? [ drop ] [ <lazy-while> ] if ;
-
-M: lazy-while car ( lazy-while -- car )
-   lazy-while-cons car ;
-
-M: lazy-while cdr ( lazy-while -- cdr )
-   [ lazy-while-cons cdr ] keep lazy-while-quot lwhile ;
-
-M: lazy-while nil? ( lazy-while -- bool )
-   [ car ] keep lazy-while-quot call not ;
-
-TUPLE: lazy-filter cons quot ;
-
-C: <lazy-filter> lazy-filter
-
-: lfilter ( list quot -- result )
-    over nil? [ 2drop nil ] [ <lazy-filter> <memoized-cons> ] if ;
-
-: car-filter?  ( lazy-filter -- ? )
-  [ lazy-filter-cons car ] keep
-  lazy-filter-quot call ;
-
-: skip ( lazy-filter -- )
-  [ lazy-filter-cons cdr ] keep
-  set-lazy-filter-cons ;
-
-M: lazy-filter car ( lazy-filter -- car )
-  dup car-filter? [ lazy-filter-cons ] [ dup skip ] if car ;
-
-M: lazy-filter cdr ( lazy-filter -- cdr )
-  dup car-filter? [
-    [ lazy-filter-cons cdr ] keep
-    lazy-filter-quot lfilter
-  ] [
-    dup skip cdr
-  ] if ;
-
-M: lazy-filter nil? ( lazy-filter -- bool )
-  dup lazy-filter-cons nil? [
-    drop t
-  ] [
-    dup car-filter? [
-      drop f
-    ] [
-      dup skip nil?
-    ] if
-  ] if ;
-
-: list>vector ( list -- vector )
-  [ [ , ] leach ] V{ } make ;
-
-: list>array ( list -- array )
-  [ [ , ] leach ] { } make ;
-
-TUPLE: lazy-append list1 list2 ;
-
-C: <lazy-append> lazy-append
-
-: lappend ( list1 list2 -- result )
-  over nil? [ nip ] [ <lazy-append> ] if ;
-
-M: lazy-append car ( lazy-append -- car )
-  lazy-append-list1 car ;
-
-M: lazy-append cdr ( lazy-append -- cdr )
-  [ lazy-append-list1 cdr  ] keep
-  lazy-append-list2 lappend ;
-
-M: lazy-append nil? ( lazy-append -- bool )
-   drop f ;
-
-TUPLE: lazy-from-by n quot ;
-
-C: lfrom-by lazy-from-by ( n quot -- list )
-
-: lfrom ( n -- list )
-  [ 1+ ] lfrom-by ;
-
-M: lazy-from-by car ( lazy-from-by -- car )
-  lazy-from-by-n ;
-
-M: lazy-from-by cdr ( lazy-from-by -- cdr )
-  [ lazy-from-by-n ] keep
-  lazy-from-by-quot dup slip lfrom-by ;
-
-M: lazy-from-by nil? ( lazy-from-by -- bool )
-  drop f ;
-
-TUPLE: lazy-zip list1 list2 ;
-
-C: <lazy-zip> lazy-zip
-
-: lzip ( list1 list2 -- lazy-zip )
-    over nil? over nil? or
-    [ 2drop nil ] [ <lazy-zip> ] if ;
-
-M: lazy-zip car ( lazy-zip -- car )
-    [ lazy-zip-list1 car ] keep lazy-zip-list2 car 2array ;
-
-M: lazy-zip cdr ( lazy-zip -- cdr )
-    [ lazy-zip-list1 cdr ] keep lazy-zip-list2 cdr lzip ;
-
-M: lazy-zip nil? ( lazy-zip -- bool )
-    drop f ;
-
-TUPLE: sequence-cons index seq ;
-
-C: <sequence-cons> sequence-cons
-
-: seq>list ( index seq -- list )
-  2dup length >= [
-    2drop nil
-  ] [
-    <sequence-cons>
-  ] if ;
-
-M: sequence-cons car ( sequence-cons -- car )
-  [ sequence-cons-index ] keep
-  sequence-cons-seq nth ;
-
-M: sequence-cons cdr ( sequence-cons -- cdr )
-  [ sequence-cons-index 1+ ] keep
-  sequence-cons-seq seq>list ;
-
-M: sequence-cons nil? ( sequence-cons -- bool )
-    drop f ;
-
-: >list ( object -- list )
-  {
-    { [ dup sequence? ] [ 0 swap seq>list ] }
-    { [ dup list?     ] [ ] }
-    [ "Could not convert object to a list" throw ]
-  } cond ;
-
-TUPLE: lazy-concat car cdr ;
-
-C: <lazy-concat> lazy-concat
-
-DEFER: lconcat
-
-: (lconcat) ( car cdr -- list )
-  over nil? [
-    nip lconcat
-  ] [
-    <lazy-concat>
-  ] if ;
-
-: lconcat ( list -- result )
-  dup nil? [
-    drop nil
-  ] [
-    uncons (lconcat)
-  ] if ;
-
-M: lazy-concat car ( lazy-concat -- car )
-  lazy-concat-car car ;
-
-M: lazy-concat cdr ( lazy-concat -- cdr )
-  [ lazy-concat-car cdr ] keep lazy-concat-cdr (lconcat) ;
-
-M: lazy-concat nil? ( lazy-concat -- bool )
-  dup lazy-concat-car nil? [
-    lazy-concat-cdr nil?
-  ] [
-    drop f
-  ] if ;
-
-: lcartesian-product ( list1 list2 -- result )
-  swap [ swap [ 2array ] lmap-with ] lmap-with lconcat ;
-
-: lcartesian-product* ( lists -- result )
-  dup nil? [
-    drop nil
-  ] [
-    [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [
-      swap [ swap [ suffix ] lmap-with ] lmap-with lconcat
-    ] reduce
-  ] if ;
-
-: lcomp ( list quot -- result )
-  [ lcartesian-product* ] dip lmap ;
-
-: lcomp* ( list guards quot -- result )
-  [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lmap ;
-
-DEFER: lmerge
-
-: (lmerge) ( list1 list2 -- result )
-  over [ car ] curry -rot
-  [
-    dup [ car ] curry -rot
-    [
-      [ cdr ] bi@ lmerge
-    ] 2curry lazy-cons
-  ] 2curry lazy-cons ;
-
-: lmerge ( list1 list2 -- result )
-  {
-    { [ over nil? ] [ nip   ] }
-    { [ dup nil?  ]  [ drop ] }
-    { [ t         ]  [ (lmerge) ] }
-  } cond ;
-
-TUPLE: lazy-io stream car cdr quot ;
-
-C: <lazy-io> lazy-io
-
-: lcontents ( stream -- result )
-  f f [ stream-read1 ] <lazy-io> ;
-
-: llines ( stream -- result )
-  f f [ stream-readln ] <lazy-io> ;
-
-M: lazy-io car ( lazy-io -- car )
-  dup lazy-io-car dup [
-    nip
-  ] [
-    drop dup lazy-io-stream over lazy-io-quot call
-    swap dupd set-lazy-io-car
-  ] if ;
-
-M: lazy-io cdr ( lazy-io -- cdr )
-  dup lazy-io-cdr dup [
-    nip
-  ] [
-    drop dup
-    [ lazy-io-stream ] keep
-    [ lazy-io-quot ] keep
-    car [
-      [ f f ] dip <lazy-io> [ swap set-lazy-io-cdr ] keep
-    ] [
-      3drop nil
-    ] if
-  ] if ;
-
-M: lazy-io nil? ( lazy-io -- bool )
-  car not ;
-
-INSTANCE: cons list
-INSTANCE: sequence-cons list
-INSTANCE: memoized-cons list
-INSTANCE: promise list
-INSTANCE: lazy-io list
-INSTANCE: lazy-concat list
-INSTANCE: lazy-cons list
-INSTANCE: lazy-map list
-INSTANCE: lazy-take list
-INSTANCE: lazy-append list
-INSTANCE: lazy-from-by list
-INSTANCE: lazy-zip list
-INSTANCE: lazy-while list
-INSTANCE: lazy-until list
-INSTANCE: lazy-filter list
diff --git a/extra/lazy-lists/old-doc.html b/extra/lazy-lists/old-doc.html
deleted file mode 100644 (file)
index 4c04301..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-<html>
-  <head>
-    <title>Lazy Evaluation</title>
-    <link rel="stylesheet" type="text/css" href="style.css">
-      </head>
-  <body>
-    <h1>Lazy Evaluation</h1>
-<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
-    ability to describe infinite structures, and to delay execution of
-    expressions until they are actually used.</p>
-<p>Lazy lists, like normal lists, are composed of a head and tail. In
-    a lazy list the head and tail are something called a 'promise'. 
-    To convert a
-    'promise' into its actual value a word called 'force' is used. To
-    convert a value into a 'promise' the word to use is 'delay'.</p>
-<table border="1">
-<tr><td><a href="#delay">delay</a></td></tr>
-<tr><td><a href="#force">force</a></td></tr>
-</table>
-
-<p>Many of the lazy list words are named similar to the standard list
-    words but with an 'l' suffixed to it. Here are the commonly used
-    words and their equivalent list operation:</p>
-<table border="1">
-<tr><th>Lazy List</th><th>Normal List</th></tr>
-<tr><td><a href="#lnil">lnil</a></td><td>[ ]</td></tr>
-<tr><td><a href="#lnilp">lnil?</a></td><td>Test for nil value</td></tr>
-<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
-<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
-<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
-<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
-<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
-<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
-<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
-<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
-<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
-<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
-</table>
-<p>A few additional words specific to lazy lists are:</p>
-<table border="1">
-<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
-number of items from the lazy list.</td></tr>
-<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
-concatenate them together in a lazy manner, returning a single lazy
-list.</td></tr>
-<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
-that contains the same elements as the normal list.</td></tr>
-</table>
-<h2>Reference</h2>
-<!-- delay description -->
-<a name="delay">
-<h3>delay ( quot -- &lt;promise&gt; )</h3>
-<p>'delay' is used to convert a value or expression into a promise.
-   The word 'force' is used to convert that promise back to its
-   value, or to force evaluation of the expression to return a value.
-</p>
-<p>The value on the stack that 'delay' expects must be quoted. This is
-   a requirement to prevent it from being evaluated.
-</p>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
-       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
-  ( 2 ) <a href="#force">force</a> .
-       => 42
-</pre>
-
-<!-- force description -->
-<a name="force">
-<h3>force ( &lt;promise&gt; -- value )</h3>
-<p>'force' will evaluate a promises original expression
-   and leave the value of that expression on the stack.
-</p>
-<p>A promise can be forced multiple times but the expression
-   is only evaluated once. Future calls of 'force' on the promise
-   will returned the cached value of the original force. If the
-   expression contains side effects, such as i/o, then that i/o
-   will only occur on the first 'force'. See below for an example
-   (steps 3-5).
-</p>
-<p>If a promise is itself delayed, a force will evaluate all promises
-   until a value is returned. Due to this behaviour it is generally not
-   possible to delay a promise. The example below shows what happens
-   in this case.
-</p>
-<pre class="code">       
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
-       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
-  ( 2 ) <a href="#force">force</a> .
-       => 42
-       
-        #! Multiple forces on a promise returns cached value
-  ( 3 ) [ "hello" print 42 ] <a href="#delay">delay</a> dup .
-       => << promise [ ] [ "hello" print 42 ] [ ] [ ] >>
-  ( 4 ) dup <a href="#force">force</a> .
-       => hello
-          42
-  ( 5 ) <a href="#force">force</a> .
-       => 42
-
-        #! Forcing a delayed promise cascades up to return
-        #! original value, rather than the promise.
-  ( 6 ) [ [ 42 ] <a href="#delay">delay</a> ] <a href="#delay">delay</a> dup .
-       => << promise [ ] [ [ 42 ] delay ] [ ] [ ] >>
-  ( 7 ) <a href="#force">force</a> .
-       => 42
-</pre>
-
-<!-- lnil description -->
-<a name="lnil">
-<h3>lnil ( -- lcons )</h3>
-<p>Returns a value representing the empty lazy list.</p>
-<pre class="code">
-  ( 1 ) <a href="#lnil">lnil</a> .
-       => << promise [ ] [ [ ] ] t [ ] >>
-</pre>
-
-<!-- lnil description -->
-<a name="lnilp">
-<h3>lnil? ( lcons -- bool )</h3>
-<p>Returns true if the given lazy cons is the value representing 
-   the empty lazy list.</p>
-<pre class="code">
-  ( 1 ) <a href="#lnil">lnil</a> <a href="#lnilp">lnil?</a> .
-       => t
-  ( 2 ) [ 1 ] <a href="#list2llist">list&gt;llist</a> dup <a href="#lnilp">lnil?</a> .
-       => [ ]
-  ( 3 ) <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
-       => t
-</pre>
-
-<!-- lcons description -->
-<a name="lcons">
-<h3>lcons ( car-promise cdr-promise -- lcons )</h3>
-<p>Provides the same effect as 'cons' does for normal lists. 
-   Both values provided must be promises (ie. expressions that have
-   had <a href="#delay">delay</a> called on them).
-</p>
-<p>As the car and cdr passed on the stack are promises, they are not
-   evaluated until <a href="#lcar">lcar</a> or <a href="#lcdr">lcdr</a>
-   are called on the lazy cons.</p>
-<pre class="code">
-  ( 1 ) [ "car" ] <a href="#delay">delay</a> [ "cdr" ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) dup <a href="#lcar">lcar</a> .
-       => "car"
-  ( 3 ) dup <a href="#lcdr">lcdr</a> .
-       => "cdr"
-</pre>
-  
-<!-- lunit description -->
-<a name="lunit">
-<h3>lunit ( value-promise -- llist )</h3>
-<p>Provides the same effect as 'unit' does for normal lists. It
-creates a lazy list where the first element is the value given.</p>
-<p>Like <a href="#lcons">lcons</a>, the value on the stack must be
-   a promise and is not evaluated until the <a href="#lcar">lcar</a>
-   of the list is requested.</a>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) dup <a href="#lcar">lcar</a> .
-       => 42
-  ( 3 ) dup <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
-       => t
-  ( 4 ) [ . ] <a href="#leach">leach</a>
-       => 42
-</pre>
-
-<!-- lcar description -->
-<a name="lcar">
-<h3>lcar ( lcons -- value )</h3>
-<p>Provides the same effect as 'car' does for normal lists. It
-returns the first element in a lazy cons cell. This will force
-the evaluation of that element.</p>
-<pre class="code">
-  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcar">lcar</a> .
-       => 42
-</pre>
-
-<!-- lcdr description -->
-<a name="lcdr">
-<h3>lcdr ( lcons -- value )</h3>
-<p>Provides the same effect as 'cdr' does for normal lists. It
-returns the second element in a lazy cons cell and forces it. This
-causes that element to be evaluated immediately.</p>
-<pre class="code">
-  ( 1 ) [ 1 ] <a href="#delay">delay</a> [ 5 6 + ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcdr">lcdr</a> .
-       => 11
-</pre>
-
-<pre class="code">
-  ( 1 ) 5 <a href="#lfrom">lfrom</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 6
-  ( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 7
-  ( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
-       => 8
-</pre>
-
-<!-- lnth description -->
-<a name="lnth">
-<h3>lnth ( n llist -- value )</h3>
-<p>Provides the same effect as 'nth' does for normal lists. It
-returns the nth value in the lazy list. It causes all the values up to
-'n' to be evaluated.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) 5 swap <a href="#lnth">lnth</a> .
-       => 6
-</pre>
-
-<!-- luncons description -->
-<a name="luncons">
-<h3>luncons ( lcons -- car cdr )</h3>
-<p>Provides the same effect as 'uncons' does for normal lists. It
-returns the car and cdr of the lazy list.</p>
-<pre class="code">
-  ( 1 ) [ 5 ] <a href="#delay">delay</a> [ 6 ] <a  href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
-       => &lt;&lt; promise ... &gt;&gt;
-  ( 2 ) <a href="#luncons">luncons</a> . .
-       => 6
-          5
-</pre>
-
-<!-- lmap description -->
-<a name="lmap">
-<h3>lmap ( llist quot -- llist )</h3>
-<p>Lazily maps over a lazy list applying the quotation to each element.
-A new lazy list is returned which contains the results of the
-quotation.</p>
-<p>When intially called nothing in the original lazy list is
-evaluated. Only when <a href="#lcar">lcar</a> is called will the item
-in the list be evaluated and applied to the quotation. Ditto with <a
-href="#lcdr">lcdr</a>, thus allowing infinite lists to be mapped over.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
-       => < infinite list of numbers incrementing by 2 >
-  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 2 4 6 8 10 ]
-</pre>
-
-<!-- lsubset description -->
-<a name="lsubset">
-<h3>lsubset ( llist pred -- llist )</h3>
-<p>Provides the same effect as 'subset' does for normal lists. It
-lazily iterates over a lazy list applying the predicate quotation to each
-element. If that quotation returns true, the element will be included
-in the resulting lazy list. If it is false, the element will be skipped.
-A new lazy list is returned which contains  all elements where the
-predicate returned true.</p>
-<p>Like <a href="#lmap">lmap</a>, when initially called no evaluation
-will occur. A lazy list is returned that when values are retrieved
-from in then items are evaluated and checked against the predicate.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ <a href="#primep">prime?</a> ] <a href="#lsubset">lsubset</a>
-       => < infinite list of prime numbers >
-  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 2 3 5 7 11 ]
-</pre>
-
-<!-- leach description -->
-<a name="leach">
-<h3>leach ( llist quot --  )</h3>
-<p>Provides the same effect as 'each' does for normal lists. It
-lazily iterates over a lazy list applying the quotation to each
-element. If this operation is applied to an infinite list it will
-never return unless the quotation escapes out by calling a continuation.</p>
-<pre class="code">
-  ( 1 ) 1 <a href="#lfrom">lfrom</a>
-       => < infinite list of incrementing numbers >
-  ( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
-       => < infinite list of odd numbers >
-  ( 3 ) [ . ] <a href="#leach">leach</a> 
-       => 1
-          3
-          5
-          7
-          ... for ever ...
-</pre>
-
-<!-- ltake description -->
-<a name="ltake">
-<h3>ltake ( n llist -- llist )</h3>
-<p>Iterates over the lazy list 'n' times, appending each element to a
-lazy list. This provides a convenient way of getting elements out of
-an infinite lazy list.</p>
-<pre class="code">
-  ( 1 ) : ones [ 1 ] delay [ ones ] delay <a href="#lcons">lcons</a> ;
-  ( 2 ) 5 ones <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
-       => [ 1 1 1 1 1  ]
-</pre>
-
-<!-- lappend description -->
-<a name="lappend">
-<h3>lappend ( llist1 llist2 -- llist )</h3>
-<p>Lazily appends two lists together. The actual appending is done
-lazily on iteration rather than immediately so it works very fast no
-matter how large the list.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> <a href="#lappend">lappend</a>
-  ( 2 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-          4
-          5
-          6
-</pre>
-
-<!-- lappend* description -->
-<a name="lappendstar">
-<h3>lappend* ( llists -- llist )</h3>
-<p>Given a lazy list of lazy lists, concatenate them together in a
-lazy fashion. The actual appending is done lazily on iteration rather
-than immediately so it works very fast no matter how large the lists.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2>llist">list&gt;llist</a> 
-  ( 2 ) [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> 
-  ( 3 ) [ 7 8 9 ] <a href="#list2llist">list&gt;llist</a>
-  ( 4 ) 3list <a href="#list2llist">list&gt;llist</a> <a href="#lappendstar">lappend*</a>
-  ( 5 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-          4
-          5
-          6
-          7
-          8
-          9
-</pre>
-
-<!-- list>llist description -->
-<a name="list2llist">
-<h3>list&gt;llist ( list  -- llist )</h3>
-<p>Converts a normal list into a lazy list. This is done lazily so the
-initial list is not iterated through immediately.</p>
-<pre class="code">
-  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> 
-  ( 2 ) [ . ] <a href="#leach">leach</a>
-       => 1
-          2
-          3
-</pre>
-
-<p class="footer">
-News and updates to this software can be obtained from the authors
-weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
-<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
-</body> </html>
diff --git a/extra/lazy-lists/summary.txt b/extra/lazy-lists/summary.txt
deleted file mode 100644 (file)
index 5d2f302..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Lazy lists
diff --git a/extra/lazy-lists/tags.txt b/extra/lazy-lists/tags.txt
deleted file mode 100644 (file)
index dd23829..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-extensions
-collections
index 031208090742f0a20485361010733940027acb76..14b91aa58ba25972eeaa47267f766794d6e83d18 100644 (file)
@@ -1,17 +1,17 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lisp lisp.parser tools.test sequences math kernel parser ;
+USING: lisp lisp.parser tools.test sequences math kernel parser arrays ;
 
 IN: lisp.test
 
 [
     init-env
     
-    "#f" [ f ] lisp-define
-    "#t" [ t ] lisp-define
+    [ f ] "#f" lisp-define
+    [ t ] "#t" lisp-define
     
-    "+" "math" "+" define-primitve
-    "-" "math" "-" define-primitve
+    "+" "math" "+" define-primitive
+    "-" "math" "-" define-primitive
     
     { 5 } [
       [ 2 3 ] "+" <lisp-symbol> funcall
@@ -22,26 +22,35 @@ IN: lisp.test
     ] unit-test
     
     { 3 } [
-      "((lambda (x y) (+ x y)) 1 2)" lisp-string>factor call
+      "((lambda (x y) (+ x y)) 1 2)" lisp-eval
     ] unit-test
     
     { 42 } [
-      "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-string>factor call
+      "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval
+    ] unit-test
+    
+    { T{ lisp-symbol f "if" } } [
+        "(defmacro if (pred tr fl) (quasiquote (cond ((unquote pred) (unquote tr)) (#t (unquote fl)))))" lisp-eval
+    ] unit-test
+    
+    { t } [
+        T{ lisp-symbol f "if" } lisp-macro?
     ] unit-test
     
     { 1 } [
-      "(if #t 1 2)" lisp-string>factor call
+      "(if #t 1 2)" lisp-eval
     ] unit-test
     
     { "b" } [
-      "(cond (#f \"a\") (#t \"b\"))" lisp-string>factor call
+      "(cond (#f \"a\") (#t \"b\"))" lisp-eval
     ] unit-test
     
     { 5 } [
-      "(begin (+ 1 4))" lisp-string>factor call
+      "(begin (+ 1 4))" lisp-eval
     ] unit-test
     
     { 3 } [
-       "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-string>factor call
+       "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-eval
     ] unit-test
-] with-interactive-vocabs
\ No newline at end of file
+    
+] with-interactive-vocabs
index 82a331f2ca8e261c63c24e6d2d48ac71444741ec..425ee27bb75a74223b1f208f4edea39c66fc816c 100644 (file)
@@ -1,48 +1,47 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel peg sequences arrays strings combinators.lib
-namespaces combinators math bake locals locals.private accessors
-vectors syntax lisp.parser assocs parser sequences.lib words quotations
-fry ;
+namespaces combinators math locals locals.private accessors
+vectors syntax lisp.parser assocs parser sequences.lib words
+quotations fry lists inspector ;
 IN: lisp
 
 DEFER: convert-form
 DEFER: funcall
 DEFER: lookup-var
-
+DEFER: lookup-macro
+DEFER: lisp-macro?
+DEFER: macro-expand
+DEFER: define-lisp-macro
+    
 ! Functions to convert s-exps to quotations
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: convert-body ( s-exp -- quot )
-    [ ] [ convert-form compose ] reduce ; inline
-  
-: convert-if ( s-exp -- quot )
-    rest first3 [ convert-form ] tri@ '[ @ , , if ] ;
+: convert-body ( cons -- quot )
+    [ ] [ convert-form compose ] foldl ; inline
     
-: convert-begin ( s-exp -- quot )  
-    rest [ convert-form ] [ ] map-as '[ , [ funcall ] each ] ;
+: convert-begin ( cons -- quot )  
+    cdr [ convert-form ] [ ] lmap-as '[ , [ funcall ] each ] ;
     
-: convert-cond ( s-exp -- quot )  
-    rest [ body>> first2 [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ]
-    { } map-as '[ , cond ]  ;
+: convert-cond ( cons -- quot )  
+    cdr [ 2car [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ]
+    { } lmap-as '[ , cond ]  ;
     
-: convert-general-form ( s-exp -- quot )
-    unclip convert-form swap convert-body swap '[ , @ funcall ] ;
+: convert-general-form ( cons -- quot )
+    uncons [ convert-body ] [ convert-form ] bi* '[ , @ funcall ] ;
 
 ! words for convert-lambda  
 <PRIVATE  
 : localize-body ( assoc body -- assoc newbody )  
-    [ dup lisp-symbol? [ over dupd [ name>> ] dip at swap or ]
-                     [ dup s-exp? [ body>> localize-body <s-exp> ] when ] if
-                   ] map ;
-    
+    [ lisp-symbol? ] pick '[ [ name>> , at ] [ ] bi or ] traverse ;
+
 : localize-lambda ( body vars -- newbody newvars )
     make-locals dup push-locals swap
-    [ swap localize-body <s-exp> convert-form swap pop-locals ] dip swap ;
+    [ swap localize-body convert-form swap pop-locals ] dip swap ;
                    
-: split-lambda ( s-exp -- body vars )                   
-    first3 -rot nip [ body>> ] bi@ [ name>> ] map ; inline
+: split-lambda ( cons -- body-cons vars-seq )                   
+    3car -rot nip [ name>> ] lmap>array ; inline
     
-: rest-lambda ( body vars -- quot )  
+: rest-lambda ( body vars -- quot )
     "&rest" swap [ index ] [ remove ] 2bi
     localize-lambda <lambda>
     '[ , cut '[ @ , ] , compose ] ;
@@ -51,46 +50,94 @@ DEFER: lookup-var
     localize-lambda <lambda> '[ , compose ] ;
 PRIVATE>
     
-: convert-lambda ( s-exp -- quot )  
+: convert-lambda ( cons -- quot )  
     split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ;
     
-: convert-quoted ( s-exp -- quot )  
-    second 1quotation ;
-    
-: convert-list-form ( s-exp -- quot )  
-    dup first dup lisp-symbol?
-    [ name>>
-      { { "lambda" [ convert-lambda ] }
-        { "quote" [ convert-quoted ] }
-        { "if" [ convert-if ] }
-        { "begin" [ convert-begin ] }
-        { "cond" [ convert-cond ] }
-       [ drop convert-general-form ]
-      } case ]
-    [ drop convert-general-form ] if ;
+: convert-quoted ( cons -- quot )  
+    cdr 1quotation ;
+    
+: convert-unquoted ( cons -- quot )    
+    "unquote not valid outside of quasiquote!" throw ;
+    
+: convert-unquoted-splicing ( cons -- quot )    
+    "unquote-splicing not valid outside of quasiquote!" throw ;
+    
+<PRIVATE    
+: quasiquote-unquote ( cons -- newcons )
+    [ { [ dup list? ] [ car dup lisp-symbol? ] [ name>> "unquote" equal? dup ] } && nip ]
+    [ cadr ] traverse ;
+    
+: quasiquote-unquote-splicing ( cons -- newcons )    
+    [ { [ dup list? ] [ dup cdr [ cons? ] [ car cons? ] bi and ]
+        [ dup cadr car lisp-symbol? ] [ cadr car name>> "unquote-splicing" equal? dup ] } && nip ]
+    [ dup cadr cdr >>cdr ] traverse ;
+PRIVATE>
+
+: convert-quasiquoted ( cons -- newcons )
+    quasiquote-unquote quasiquote-unquote-splicing ;
+    
+: convert-defmacro ( cons -- quot )
+    cdr [ car ] keep [ convert-lambda ] [ car name>> ] bi define-lisp-macro 1quotation ;
+    
+: form-dispatch ( cons lisp-symbol -- quot )
+    name>>
+    { { "lambda" [ convert-lambda ] }
+      { "defmacro" [ convert-defmacro ] }
+      { "quote" [ convert-quoted ] }
+      { "unquote" [ convert-unquoted ] }
+      { "unquote-splicing" [ convert-unquoted-splicing ] }
+      { "quasiquote" [ convert-quasiquoted ] }
+      { "begin" [ convert-begin ] }
+      { "cond" [ convert-cond ] }
+     [ drop convert-general-form ]
+    } case ;
+    
+: convert-list-form ( cons -- quot )  
+    dup car
+    { { [ dup lisp-macro?  ] [ drop macro-expand ] }
+      { [ dup lisp-symbol? ] [ form-dispatch ] } 
+     [ drop convert-general-form ]
+    } cond ;
     
 : convert-form ( lisp-form -- quot )
-    { { [ dup s-exp? ] [ body>> convert-list-form ] }
-    { [ dup lisp-symbol? ] [ '[ , lookup-var ] ] }
-    [ 1quotation ]
+    {
+      { [ dup cons? ] [ convert-list-form ] }
+      { [ dup lisp-symbol? ] [ '[ , lookup-var ] ] }
+     [ 1quotation ]
     } cond ;
     
+: compile-form ( lisp-ast -- quot )
+    convert-form lambda-rewrite call ; inline
+    
+: macro-call ( lambda -- cons )
+    call ; inline
+    
+: macro-expand ( cons -- quot )
+    uncons [ list>seq [ ] like ] [ lookup-macro macro-call compile-form  ] bi* ;
+    
 : lisp-string>factor ( str -- quot )
-    lisp-expr parse-result-ast convert-form lambda-rewrite call ;
+    lisp-expr parse-result-ast compile-form ;
+    
+: lisp-eval ( str -- * )    
+  lisp-string>factor call ;
     
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 SYMBOL: lisp-env
-ERROR: no-such-var var ;
+SYMBOL: macro-env
+    
+ERROR: no-such-var variable-name ;
+M: no-such-var summary drop "No such variable" ;
 
 : init-env ( -- )
-    H{ } clone lisp-env set ;
+    H{ } clone lisp-env set
+    H{ } clone macro-env set ;
 
-: lisp-define ( name quot -- )
-    swap lisp-env get set-at ;
+: lisp-define ( quot name -- )
+    lisp-env get set-at ;
     
 : lisp-get ( name -- word )
-    dup lisp-env get at [ ] [ no-such-var throw ] ?if ;
+    dup lisp-env get at [ ] [ no-such-var ] ?if ;
     
 : lookup-var ( lisp-symbol -- quot )
     name>> lisp-get ;
@@ -98,5 +145,14 @@ ERROR: no-such-var var ;
 : funcall ( quot sym -- * )
     dup lisp-symbol?  [ lookup-var ] when call ; inline
     
-: define-primitve ( name vocab word -- )  
-    swap lookup 1quotation '[ , compose call ] lisp-define ;
\ No newline at end of file
+: define-primitive ( name vocab word -- )  
+    swap lookup 1quotation '[ , compose call ] swap lisp-define ;
+    
+: lookup-macro ( lisp-symbol -- lambda )
+    name>> macro-env get at ;
+    
+: define-lisp-macro ( quot name -- )
+    macro-env get set-at ;
+    
+: lisp-macro? ( car -- ? )
+    dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ;
index 98a6d2a6ba113523496b135d50e22cbe628492ed..4aa8154690d49607e07d32d4dec7088b4aad912d 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lisp.parser tools.test peg peg.ebnf ;
+USING: lisp.parser tools.test peg peg.ebnf lists ;
 
 IN: lisp.parser.tests
 
@@ -9,38 +9,60 @@ IN: lisp.parser.tests
 ] unit-test
 
 { -42  }  [
-  "-42" "atom" \ lisp-expr rule parse parse-result-ast
+    "-42" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { 37/52 } [
-  "37/52" "atom" \ lisp-expr rule parse parse-result-ast
+    "37/52" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { 123.98 } [
-  "123.98" "atom" \ lisp-expr rule parse parse-result-ast
+    "123.98" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { "" } [
-  "\"\"" "atom" \ lisp-expr rule parse parse-result-ast
+    "\"\"" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { "aoeu" } [
-  "\"aoeu\"" "atom" \ lisp-expr rule parse parse-result-ast
+    "\"aoeu\"" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { "aoeu\"de" } [
-  "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse parse-result-ast
+    "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { T{ lisp-symbol f "foobar" } } [
-  "foobar" "atom" \ lisp-expr rule parse parse-result-ast
+    "foobar" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
 { T{ lisp-symbol f "+" } } [
-  "+" "atom" \ lisp-expr rule parse parse-result-ast
+    "+" "atom" \ lisp-expr rule parse parse-result-ast
 ] unit-test
 
-{ T{ s-exp f
-     V{ T{ lisp-symbol f "foo" } 1 2 "aoeu" } } } [
-  "(foo 1 2 \"aoeu\")" lisp-expr parse-result-ast
+{ +nil+ } [
+    "()" lisp-expr parse-result-ast
+] unit-test
+
+{ T{
+    cons
+    f
+    T{ lisp-symbol f "foo" }
+    T{
+        cons
+        f
+        1
+        T{ cons f 2 T{ cons f "aoeu" +nil+ } }
+    } } } [
+    "(foo 1 2 \"aoeu\")" lisp-expr parse-result-ast
+] unit-test
+
+{ T{ cons f
+       1
+       T{ cons f
+           T{ cons f 3 T{ cons f 4 +nil+ } }
+           T{ cons f 2 +nil+ } }
+   }
+} [
+    "(1 (3 4) 2)" lisp-expr parse-result-ast
 ] unit-test
\ No newline at end of file
index cf5ff56331c8664363fcc505e828b4dd4be499ba..1e37193d3a0c2e6dba749a0a403efb73b8ed7522 100644 (file)
@@ -1,16 +1,13 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel peg.ebnf peg.expr math.parser sequences arrays strings
-combinators.lib math ;
+USING: kernel peg peg.ebnf peg.expr math.parser sequences arrays strings
+combinators.lib math fry accessors lists ;
 
 IN: lisp.parser
 
 TUPLE: lisp-symbol name ;
 C: <lisp-symbol> lisp-symbol
 
-TUPLE: s-exp body ;
-C: <s-exp> s-exp
-
 EBNF: lisp-expr
 _            = (" " | "\t" | "\n")*
 LPAREN       = "("
@@ -24,8 +21,9 @@ rational     = integer "/" (digit)+                      => [[ first3 nip string
 number       = float
               | rational
               | integer
-id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":" | "<" | "#"
-              | " =" | ">" | "?" | "^" | "_" | "~" | "+" | "-" | "." | "@"
+id-specials  = "!" | "$" | "%" | "&" | "*" | "/" | ":"
+              | "<" | "#" | " =" | ">" | "?" | "^" | "_"
+              | "~" | "+" | "-" | "." | "@"
 letters      = [a-zA-Z]                                  => [[ 1array >string ]]
 initials     = letters | id-specials
 numbers      = [0-9]                                     => [[ 1array >string ]]
@@ -36,6 +34,6 @@ string       = dquote ( escaped | !(dquote) . )*  dquote => [[ second >string ]]
 atom         = number
               | identifier
               | string
-list-item    = _ (atom|s-expression) _                   => [[ second ]]
-s-expression = LPAREN (list-item)* RPAREN                => [[ second <s-exp> ]]
+list-item    = _ ( atom | s-expression ) _               => [[ second ]]
+s-expression = LPAREN (list-item)* RPAREN                => [[ second seq>cons ]]
 ;EBNF
\ No newline at end of file
diff --git a/extra/lists/authors.txt b/extra/lists/authors.txt
new file mode 100644 (file)
index 0000000..4b7af4a
--- /dev/null
@@ -0,0 +1 @@
+James Cash
diff --git a/extra/lists/lazy/authors.txt b/extra/lists/lazy/authors.txt
new file mode 100644 (file)
index 0000000..f6ba9ba
--- /dev/null
@@ -0,0 +1,3 @@
+Chris Double
+Samuel Tardieu
+Matthew Willis
diff --git a/extra/lists/lazy/examples/authors.txt b/extra/lists/lazy/examples/authors.txt
new file mode 100755 (executable)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/extra/lists/lazy/examples/examples-tests.factor b/extra/lists/lazy/examples/examples-tests.factor
new file mode 100644 (file)
index 0000000..c088f1d
--- /dev/null
@@ -0,0 +1,5 @@
+USING: lists.lazy.examples lazy-lists tools.test ;
+IN: lists.lazy.examples.tests
+
+[ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test
+[ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test
diff --git a/extra/lists/lazy/examples/examples.factor b/extra/lists/lazy/examples/examples.factor
new file mode 100644 (file)
index 0000000..1d5bb49
--- /dev/null
@@ -0,0 +1,15 @@
+! Rewritten by Matthew Willis, July 2006
+! Copyright (C) 2004 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: lists.lazy math kernel sequences quotations ;
+IN: lists.lazy.examples
+
+: naturals ( -- list ) 0 lfrom ;
+: positives ( -- list ) 1 lfrom ;
+: evens ( -- list ) 0 [ 2 + ] lfrom-by ;
+: odds ( -- list ) 1 lfrom [ 2 mod 1 = ] lfilter ;
+: powers-of-2 ( -- list ) 1 [ 2 * ] lfrom-by ;
+: ones ( -- list ) 1 [ ] lfrom-by ;
+: squares ( -- list ) naturals [ dup * ] lazy-map ;
+: first-five-squares ( -- list ) 5 squares ltake list>array ;
diff --git a/extra/lists/lazy/lazy-docs.factor b/extra/lists/lazy/lazy-docs.factor
new file mode 100644 (file)
index 0000000..6a93590
--- /dev/null
@@ -0,0 +1,129 @@
+! Copyright (C) 2006 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: help.markup help.syntax sequences strings lists ;
+IN: lists.lazy 
+
+HELP: lazy-cons
+{ $values { "car" "a quotation with stack effect ( -- X )" } { "cdr" "a quotation with stack effect ( -- cons )" } { "promise" "the resulting cons object" } }
+{ $description "Constructs a cons object for a lazy list from two quotations. The " { $snippet "car" } " quotation should return the head of the list, and the " { $snippet "cons" } " quotation the tail when called. When " { $link cons } " or " { $link cdr } " are called on the lazy-cons object then the appropriate quotation is called." } 
+{ $see-also cons car cdr nil nil? } ;
+
+{ 1lazy-list 2lazy-list 3lazy-list } related-words
+
+HELP: 1lazy-list
+{ $values { "a" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 1 element. The element is the result of calling the quotation. The quotation is only called when the list element is requested." } ;
+
+HELP: 2lazy-list
+{ $values { "a" "a quotation with stack effect ( -- X )" } { "b" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 2 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
+
+HELP: 3lazy-list
+{ $values { "a" "a quotation with stack effect ( -- X )" } { "b" "a quotation with stack effect ( -- X )" } { "c" "a quotation with stack effect ( -- X )" } { "lazy-cons" "a lazy-cons object" } }
+{ $description "Create a lazy list with 3 elements. The elements are the result of calling the quotations. The quotations are only called when the list elements are requested." } ;
+
+HELP: <memoized-cons>
+{ $values { "cons" "a cons object" } { "memoized-cons" "the resulting memoized-cons object" } }
+{ $description "Constructs a cons object that wraps an existing cons object. Requests for the car, cdr and nil? will be remembered after the first call, and the previous result returned on subsequent calls." } 
+{ $see-also cons car cdr nil nil? } ;
+
+{ lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
+
+HELP: lazy-map
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- X )" } { "result" "resulting cons object" } }
+{ $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-map> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: lazy-map-with
+{ $values { "value" "an object" } { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj elt -- X )" } { "result" "resulting cons object" } }
+{ $description "Variant of " { $link lazy-map } " which pushes a retained object on each invocation of the quotation." } ;
+
+HELP: ltake
+{ $values { "n" "a non negative integer" } { "list" "a cons object" } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first n items in the list. This is done a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-take> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: lfilter
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( -- X )" } { "result" "resulting cons object" } }
+{ $description "Perform a similar functionality to that of the " { $link filter } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-filter> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: lwhile
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( X -- bool )" } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first items in the list as long as " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: luntil
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( X -- bool )" } { "result" "resulting cons object" } }
+{ $description "Outputs a lazy list containing the first items in the list until after " { $snippet "quot" } " evaluates to t. No evaluation of the list elements occurs initially but a " { $link <lazy-while> } " object is returned with conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ;
+
+HELP: list>vector
+{ $values { "list" "a cons object" } { "vector" "the list converted to a vector" } }
+{ $description "Convert a list to a vector. If the list is a lazy infinite list then this will enter an infinite loop." } 
+{ $see-also list>array } ;
+
+HELP: list>array
+{ $values { "list" "a cons object" } { "array" "the list converted to an array" } }
+{ $description "Convert a list to an array. If the list is a lazy infinite list then this will enter an infinite loop." } 
+{ $see-also list>vector } ;
+
+HELP: lappend
+{ $values { "list1" "a cons object" } { "list2" "a cons object" } { "result" "a lazy list of list2 appended to list1" } }
+{ $description "Perform a similar functionality to that of the " { $link append } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-append> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required. Successive calls to " { $link cdr } " will iterate through list1, followed by list2." } ;
+
+HELP: lfrom-by
+{ $values { "n" "an integer" } { "quot" "a quotation with stack effect ( -- int )" } { "list" "a lazy list of integers" } }
+{ $description "Return an infinite lazy list of values starting from n, with each successive value being the result of applying quot to n." } ;
+
+HELP: lfrom
+{ $values { "n" "an integer" } { "list" "a lazy list of integers" } }
+{ $description "Return an infinite lazy list of incrementing integers starting from n." } ;
+
+HELP: seq>list
+{ $values { "index" "an integer 0 or greater" } { "seq" "a sequence" } { "list" "a list" } }
+{ $description "Convert the sequence into a list, starting from the 'index' offset into the sequence." } 
+{ $see-also >list } ;
+
+HELP: >list
+{ $values { "object" "an object" } { "list" "a list" } }
+{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } 
+{ $see-also seq>list } ;
+    
+{ leach foldl lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
+
+HELP: lconcat
+{ $values { "list" "a list of lists" } { "result" "a list" } }
+{ $description "Concatenates a list of lists together into one list." } ;
+
+HELP: lcartesian-product
+{ $values { "list1" "a list" } { "list2" "a list" } { "result" "list of cartesian products" } }
+{ $description "Given two lists, return a list containing the cartesian product of those lists." } ;
+
+HELP: lcartesian-product*
+{ $values { "lists" "a list of lists" } { "result" "list of cartesian products" } }
+{ $description "Given a list of lists, return a list containing the cartesian product of those lists." } ;
+
+HELP: lcomp
+{ $values { "list" "a list of lists" } { "quot" "a quotation with stack effect ( seq -- X )" } { "result" "the resulting list" } }
+{ $description "Get the cartesian product of the lists in " { $snippet "list" } " and call " { $snippet "quot" } " call with each element from the cartesian product on the stack, the result of which is returned in the final " { $snippet "list" } "." } ;
+
+HELP: lcomp*
+{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" "a quotation with stack effect ( seq -- X )" } { "list" "the resulting list" } { "result" "a list" } }
+{ $description "Get the cartesian product of the lists in " { $snippet "list" } ", filter it by applying each guard quotation to it and call " { $snippet "quot" } " call with each element from the remaining cartesian product items on the stack, the result of which is returned in the final " { $snippet "list" } "." }
+{ $examples
+  { $code "{ 1 2 3 } >list { 4 5 6 } >list 2list { [ first odd? ] } [ first2 + ] lcomp*" }
+} ;
+
+HELP: lmerge
+{ $values { "list1" "a list" } { "list2" "a list" } { "result" "lazy list merging list1 and list2" } }
+{ $description "Return the result of merging the two lists in a lazy manner." } 
+{ $examples
+  { $example "USING: lists.lazy prettyprint ;" "{ 1 2 3 } >list { 4 5 6 } >list lmerge list>array ." "{ 1 4 2 5 3 6 }" }
+} ;
+
+HELP: lcontents
+{ $values { "stream" "a stream" } { "result" string } }
+{ $description "Returns a lazy list of all characters in the file. " { $link car } " returns the next character in the file, " { $link cdr } " returns the remaining characters as a lazy list. " { $link nil? } " indicates end of file." } 
+{ $see-also llines } ;
+
+HELP: llines
+{ $values { "stream" "a stream" } { "result" "a list" } }
+{ $description "Returns a lazy list of all lines in the file. " { $link car } " returns the next lines in the file, " { $link cdr } " returns the remaining lines as a lazy list. " { $link nil? } " indicates end of file." } 
+{ $see-also lcontents } ;
diff --git a/extra/lists/lazy/lazy-tests.factor b/extra/lists/lazy/lazy-tests.factor
new file mode 100644 (file)
index 0000000..5749f94
--- /dev/null
@@ -0,0 +1,29 @@
+! Copyright (C) 2006 Matthew Willis and Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+!
+USING: lists lists.lazy tools.test kernel math io sequences ;
+IN: lists.lazy.tests
+
+[ { 1 2 3 4 } ] [
+  { 1 2 3 4 } >list list>array
+] unit-test
+
+[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
+  { 1 2 3 } >list { 4 5 } >list 2list lcartesian-product* list>array
+] unit-test
+
+[ { { 1 4 } { 1 5 } { 2 4 } { 2 5 } { 3 4 } { 3 5 } } ] [
+  { 1 2 3 } >list { 4 5 } >list lcartesian-product list>array
+] unit-test
+
+[ { 5 6 6 7 7 8 } ] [ 
+  { 1 2 3 } >list { 4 5 } >list 2list [ first2 + ] lcomp list>array
+] unit-test
+
+[ { 5 6 7 8 } ] [ 
+  { 1 2 3 } >list { 4 5 } >list 2list { [ first odd? ] } [ first2 + ] lcomp* list>array
+] unit-test
+
+[ { 4 5 6 } ] [ 
+    3 { 1 2 3 } >list [ + ] lazy-map-with list>array
+] unit-test
diff --git a/extra/lists/lazy/lazy.factor b/extra/lists/lazy/lazy.factor
new file mode 100644 (file)
index 0000000..6beb6e4
--- /dev/null
@@ -0,0 +1,392 @@
+! Copyright (C) 2004 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+!
+! Updated by Matthew Willis, July 2006
+! Updated by Chris Double, September 2006
+! Updated by James Cash, June 2008
+!
+USING: kernel sequences math vectors arrays namespaces
+quotations promises combinators io lists accessors ;
+IN: lists.lazy
+
+M: promise car ( promise -- car )
+    force car ;
+
+M: promise cdr ( promise -- cdr )
+    force cdr ;
+
+M: promise nil? ( cons -- bool )
+    force nil? ;
+    
+! Both 'car' and 'cdr' are promises
+TUPLE: lazy-cons car cdr ;
+
+: lazy-cons ( car cdr -- promise )
+    [ promise ] bi@ \ lazy-cons boa
+    T{ promise f f t f } clone
+    [ set-promise-value ] keep ;
+
+M: lazy-cons car ( lazy-cons -- car )
+    car>> force ;
+
+M: lazy-cons cdr ( lazy-cons -- cdr )
+    cdr>> force ;
+
+M: lazy-cons nil? ( lazy-cons -- bool )
+    nil eq? ;
+
+: 1lazy-list ( a -- lazy-cons )
+    [ nil ] lazy-cons ;
+
+: 2lazy-list ( a b -- lazy-cons )
+    1lazy-list 1quotation lazy-cons ;
+
+: 3lazy-list ( a b c -- lazy-cons )
+    2lazy-list 1quotation lazy-cons ;
+
+TUPLE: memoized-cons original car cdr nil? ;
+
+: not-memoized ( -- obj )
+    { } ;
+
+: not-memoized? ( obj -- bool )
+    not-memoized eq? ;
+
+: <memoized-cons> ( cons -- memoized-cons )
+    not-memoized not-memoized not-memoized
+    memoized-cons boa ;
+
+M: memoized-cons car ( memoized-cons -- car )
+    dup car>> not-memoized? [
+        dup original>> car [ >>car drop ] keep
+    ] [
+        car>>
+    ] if ;
+
+M: memoized-cons cdr ( memoized-cons -- cdr )
+    dup cdr>> not-memoized? [
+        dup original>> cdr [ >>cdr drop ] keep
+    ] [
+        cdr>>
+    ] if ;
+
+M: memoized-cons nil? ( memoized-cons -- bool )
+    dup nil?>> not-memoized? [
+        dup original>> nil?  [ >>nil? drop ] keep
+    ] [
+        nil?>>
+    ] if ;
+
+TUPLE: lazy-map cons quot ;
+
+C: <lazy-map> lazy-map
+
+: lazy-map ( list quot -- result )
+    over nil? [ 2drop nil ] [ <lazy-map> <memoized-cons> ] if ;
+
+M: lazy-map car ( lazy-map -- car )
+    [ cons>> car ] keep
+    quot>> call ;
+
+M: lazy-map cdr ( lazy-map -- cdr )
+    [ cons>> cdr ] keep
+    quot>> lazy-map ;
+
+M: lazy-map nil? ( lazy-map -- bool )
+    cons>> nil? ;
+
+: lazy-map-with ( value list quot -- result )
+    with lazy-map ;
+
+TUPLE: lazy-take n cons ;
+
+C: <lazy-take> lazy-take
+
+: ltake ( n list -- result )
+        over zero? [ 2drop nil ] [ <lazy-take> ] if ;
+
+M: lazy-take car ( lazy-take -- car )
+    cons>> car ;
+
+M: lazy-take cdr ( lazy-take -- cdr )
+    [ n>> 1- ] keep
+    cons>> cdr ltake ;
+
+M: lazy-take nil? ( lazy-take -- bool )
+    dup n>> zero? [
+        drop t
+    ] [
+        cons>> nil?
+    ] if ;
+
+TUPLE: lazy-until cons quot ;
+
+C: <lazy-until> lazy-until
+
+: luntil ( list quot -- result )
+    over nil? [ drop ] [ <lazy-until> ] if ;
+
+M: lazy-until car ( lazy-until -- car )
+     cons>> car ;
+
+M: lazy-until cdr ( lazy-until -- cdr )
+     [ cons>> uncons ] keep quot>> tuck call
+     [ 2drop nil ] [ luntil ] if ;
+
+M: lazy-until nil? ( lazy-until -- bool )
+     drop f ;
+
+TUPLE: lazy-while cons quot ;
+
+C: <lazy-while> lazy-while
+
+: lwhile ( list quot -- result )
+    over nil? [ drop ] [ <lazy-while> ] if ;
+
+M: lazy-while car ( lazy-while -- car )
+     cons>> car ;
+
+M: lazy-while cdr ( lazy-while -- cdr )
+     [ cons>> cdr ] keep quot>> lwhile ;
+
+M: lazy-while nil? ( lazy-while -- bool )
+     [ car ] keep quot>> call not ;
+
+TUPLE: lazy-filter cons quot ;
+
+C: <lazy-filter> lazy-filter
+
+: lfilter ( list quot -- result )
+    over nil? [ 2drop nil ] [ <lazy-filter> <memoized-cons> ] if ;
+
+: car-filter? ( lazy-filter -- ? )
+    [ cons>> car ] [ quot>> ] bi call ;
+
+: skip ( lazy-filter -- )
+    dup cons>> cdr >>cons drop ;
+
+M: lazy-filter car ( lazy-filter -- car )
+    dup car-filter? [ cons>> ] [ dup skip ] if car ;
+
+M: lazy-filter cdr ( lazy-filter -- cdr )
+    dup car-filter? [
+        [ cons>> cdr ] [ quot>> ] bi lfilter
+    ] [
+        dup skip cdr
+    ] if ;
+
+M: lazy-filter nil? ( lazy-filter -- bool )
+    dup cons>> nil? [
+        drop t
+    ] [
+        dup car-filter? [
+            drop f
+        ] [
+            dup skip nil?
+        ] if
+    ] if ;
+
+: list>vector ( list -- vector )
+    [ [ , ] leach ] V{ } make ;
+
+: list>array ( list -- array )
+    [ [ , ] leach ] { } make ;
+
+TUPLE: lazy-append list1 list2 ;
+
+C: <lazy-append> lazy-append
+
+: lappend ( list1 list2 -- result )
+    over nil? [ nip ] [ <lazy-append> ] if ;
+
+M: lazy-append car ( lazy-append -- car )
+    list1>> car ;
+
+M: lazy-append cdr ( lazy-append -- cdr )
+    [ list1>> cdr    ] keep
+    list2>> lappend ;
+
+M: lazy-append nil? ( lazy-append -- bool )
+     drop f ;
+
+TUPLE: lazy-from-by n quot ;
+
+C: lfrom-by lazy-from-by ( n quot -- list )
+
+: lfrom ( n -- list )
+    [ 1+ ] lfrom-by ;
+
+M: lazy-from-by car ( lazy-from-by -- car )
+    n>> ;
+
+M: lazy-from-by cdr ( lazy-from-by -- cdr )
+    [ n>> ] keep
+    quot>> dup slip lfrom-by ;
+
+M: lazy-from-by nil? ( lazy-from-by -- bool )
+    drop f ;
+
+TUPLE: lazy-zip list1 list2 ;
+
+C: <lazy-zip> lazy-zip
+
+: lzip ( list1 list2 -- lazy-zip )
+        over nil? over nil? or
+        [ 2drop nil ] [ <lazy-zip> ] if ;
+
+M: lazy-zip car ( lazy-zip -- car )
+        [ list1>> car ] keep list2>> car 2array ;
+
+M: lazy-zip cdr ( lazy-zip -- cdr )
+        [ list1>> cdr ] keep list2>> cdr lzip ;
+
+M: lazy-zip nil? ( lazy-zip -- bool )
+        drop f ;
+
+TUPLE: sequence-cons index seq ;
+
+C: <sequence-cons> sequence-cons
+
+: seq>list ( index seq -- list )
+    2dup length >= [
+        2drop nil
+    ] [
+        <sequence-cons>
+    ] if ;
+
+M: sequence-cons car ( sequence-cons -- car )
+    [ index>> ] keep
+    seq>> nth ;
+
+M: sequence-cons cdr ( sequence-cons -- cdr )
+    [ index>> 1+ ] keep
+    seq>> seq>list ;
+
+M: sequence-cons nil? ( sequence-cons -- bool )
+    drop f ;
+
+: >list ( object -- list )
+    {
+        { [ dup sequence? ] [ 0 swap seq>list ] }
+        { [ dup list?         ] [ ] }
+        [ "Could not convert object to a list" throw ]
+    } cond ;
+
+TUPLE: lazy-concat car cdr ;
+
+C: <lazy-concat> lazy-concat
+
+DEFER: lconcat
+
+: (lconcat) ( car cdr -- list )
+    over nil? [
+        nip lconcat
+    ] [
+        <lazy-concat>
+    ] if ;
+
+: lconcat ( list -- result )
+    dup nil? [
+        drop nil
+    ] [
+        uncons swap (lconcat)
+    ] if ;
+
+M: lazy-concat car ( lazy-concat -- car )
+    car>> car ;
+
+M: lazy-concat cdr ( lazy-concat -- cdr )
+    [ car>> cdr ] keep cdr>> (lconcat) ;
+
+M: lazy-concat nil? ( lazy-concat -- bool )
+    dup car>> nil? [
+        cdr>> nil?
+    ] [
+        drop f
+    ] if ;
+
+: lcartesian-product ( list1 list2 -- result )
+    swap [ swap [ 2array ] lazy-map-with  ] lazy-map-with  lconcat ;
+
+: lcartesian-product* ( lists -- result )
+    dup nil? [
+        drop nil
+    ] [
+        [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [
+            swap [ swap [ suffix ] lazy-map-with  ] lazy-map-with  lconcat
+        ] reduce
+    ] if ;
+
+: lcomp ( list quot -- result )
+    [ lcartesian-product* ] dip lazy-map ;
+
+: lcomp* ( list guards quot -- result )
+    [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lazy-map ;
+
+DEFER: lmerge
+
+: (lmerge) ( list1 list2 -- result )
+    over [ car ] curry -rot
+    [
+        dup [ car ] curry -rot
+        [
+            [ cdr ] bi@ lmerge
+        ] 2curry lazy-cons
+    ] 2curry lazy-cons ;
+
+: lmerge ( list1 list2 -- result )
+    {
+        { [ over nil? ] [ nip     ] }
+        { [ dup nil?    ]    [ drop ] }
+        { [ t                 ]    [ (lmerge) ] }
+    } cond ;
+
+TUPLE: lazy-io stream car cdr quot ;
+
+C: <lazy-io> lazy-io
+
+: lcontents ( stream -- result )
+    f f [ stream-read1 ] <lazy-io> ;
+
+: llines ( stream -- result )
+    f f [ stream-readln ] <lazy-io> ;
+
+M: lazy-io car ( lazy-io -- car )
+    dup car>> dup [
+        nip
+    ] [
+        drop dup stream>> over quot>> call
+        swap dupd set-lazy-io-car
+    ] if ;
+
+M: lazy-io cdr ( lazy-io -- cdr )
+    dup cdr>> dup [
+        nip
+    ] [
+        drop dup
+        [ stream>> ] keep
+        [ quot>> ] keep
+        car [
+            [ f f ] dip <lazy-io> [ >>cdr drop ] keep
+        ] [
+            3drop nil
+        ] if
+    ] if ;
+
+M: lazy-io nil? ( lazy-io -- bool )
+    car not ;
+
+INSTANCE: sequence-cons list
+INSTANCE: memoized-cons list
+INSTANCE: promise list
+INSTANCE: lazy-io list
+INSTANCE: lazy-concat list
+INSTANCE: lazy-cons list
+INSTANCE: lazy-map list
+INSTANCE: lazy-take list
+INSTANCE: lazy-append list
+INSTANCE: lazy-from-by list
+INSTANCE: lazy-zip list
+INSTANCE: lazy-while list
+INSTANCE: lazy-until list
+INSTANCE: lazy-filter list
diff --git a/extra/lists/lazy/old-doc.html b/extra/lists/lazy/old-doc.html
new file mode 100644 (file)
index 0000000..4c04301
--- /dev/null
@@ -0,0 +1,361 @@
+<html>
+  <head>
+    <title>Lazy Evaluation</title>
+    <link rel="stylesheet" type="text/css" href="style.css">
+      </head>
+  <body>
+    <h1>Lazy Evaluation</h1>
+<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
+    ability to describe infinite structures, and to delay execution of
+    expressions until they are actually used.</p>
+<p>Lazy lists, like normal lists, are composed of a head and tail. In
+    a lazy list the head and tail are something called a 'promise'. 
+    To convert a
+    'promise' into its actual value a word called 'force' is used. To
+    convert a value into a 'promise' the word to use is 'delay'.</p>
+<table border="1">
+<tr><td><a href="#delay">delay</a></td></tr>
+<tr><td><a href="#force">force</a></td></tr>
+</table>
+
+<p>Many of the lazy list words are named similar to the standard list
+    words but with an 'l' suffixed to it. Here are the commonly used
+    words and their equivalent list operation:</p>
+<table border="1">
+<tr><th>Lazy List</th><th>Normal List</th></tr>
+<tr><td><a href="#lnil">lnil</a></td><td>[ ]</td></tr>
+<tr><td><a href="#lnilp">lnil?</a></td><td>Test for nil value</td></tr>
+<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
+<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
+<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
+<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
+<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
+<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
+<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
+<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
+<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
+<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
+</table>
+<p>A few additional words specific to lazy lists are:</p>
+<table border="1">
+<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
+number of items from the lazy list.</td></tr>
+<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
+concatenate them together in a lazy manner, returning a single lazy
+list.</td></tr>
+<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
+that contains the same elements as the normal list.</td></tr>
+</table>
+<h2>Reference</h2>
+<!-- delay description -->
+<a name="delay">
+<h3>delay ( quot -- &lt;promise&gt; )</h3>
+<p>'delay' is used to convert a value or expression into a promise.
+   The word 'force' is used to convert that promise back to its
+   value, or to force evaluation of the expression to return a value.
+</p>
+<p>The value on the stack that 'delay' expects must be quoted. This is
+   a requirement to prevent it from being evaluated.
+</p>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
+       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
+  ( 2 ) <a href="#force">force</a> .
+       => 42
+</pre>
+
+<!-- force description -->
+<a name="force">
+<h3>force ( &lt;promise&gt; -- value )</h3>
+<p>'force' will evaluate a promises original expression
+   and leave the value of that expression on the stack.
+</p>
+<p>A promise can be forced multiple times but the expression
+   is only evaluated once. Future calls of 'force' on the promise
+   will returned the cached value of the original force. If the
+   expression contains side effects, such as i/o, then that i/o
+   will only occur on the first 'force'. See below for an example
+   (steps 3-5).
+</p>
+<p>If a promise is itself delayed, a force will evaluate all promises
+   until a value is returned. Due to this behaviour it is generally not
+   possible to delay a promise. The example below shows what happens
+   in this case.
+</p>
+<pre class="code">       
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
+       => &lt;&lt; promise [ ] [ 42 ] [ ] [ ] &gt;&gt;
+  ( 2 ) <a href="#force">force</a> .
+       => 42
+       
+        #! Multiple forces on a promise returns cached value
+  ( 3 ) [ "hello" print 42 ] <a href="#delay">delay</a> dup .
+       => << promise [ ] [ "hello" print 42 ] [ ] [ ] >>
+  ( 4 ) dup <a href="#force">force</a> .
+       => hello
+          42
+  ( 5 ) <a href="#force">force</a> .
+       => 42
+
+        #! Forcing a delayed promise cascades up to return
+        #! original value, rather than the promise.
+  ( 6 ) [ [ 42 ] <a href="#delay">delay</a> ] <a href="#delay">delay</a> dup .
+       => << promise [ ] [ [ 42 ] delay ] [ ] [ ] >>
+  ( 7 ) <a href="#force">force</a> .
+       => 42
+</pre>
+
+<!-- lnil description -->
+<a name="lnil">
+<h3>lnil ( -- lcons )</h3>
+<p>Returns a value representing the empty lazy list.</p>
+<pre class="code">
+  ( 1 ) <a href="#lnil">lnil</a> .
+       => << promise [ ] [ [ ] ] t [ ] >>
+</pre>
+
+<!-- lnil description -->
+<a name="lnilp">
+<h3>lnil? ( lcons -- bool )</h3>
+<p>Returns true if the given lazy cons is the value representing 
+   the empty lazy list.</p>
+<pre class="code">
+  ( 1 ) <a href="#lnil">lnil</a> <a href="#lnilp">lnil?</a> .
+       => t
+  ( 2 ) [ 1 ] <a href="#list2llist">list&gt;llist</a> dup <a href="#lnilp">lnil?</a> .
+       => [ ]
+  ( 3 ) <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
+       => t
+</pre>
+
+<!-- lcons description -->
+<a name="lcons">
+<h3>lcons ( car-promise cdr-promise -- lcons )</h3>
+<p>Provides the same effect as 'cons' does for normal lists. 
+   Both values provided must be promises (ie. expressions that have
+   had <a href="#delay">delay</a> called on them).
+</p>
+<p>As the car and cdr passed on the stack are promises, they are not
+   evaluated until <a href="#lcar">lcar</a> or <a href="#lcdr">lcdr</a>
+   are called on the lazy cons.</p>
+<pre class="code">
+  ( 1 ) [ "car" ] <a href="#delay">delay</a> [ "cdr" ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) dup <a href="#lcar">lcar</a> .
+       => "car"
+  ( 3 ) dup <a href="#lcdr">lcdr</a> .
+       => "cdr"
+</pre>
+  
+<!-- lunit description -->
+<a name="lunit">
+<h3>lunit ( value-promise -- llist )</h3>
+<p>Provides the same effect as 'unit' does for normal lists. It
+creates a lazy list where the first element is the value given.</p>
+<p>Like <a href="#lcons">lcons</a>, the value on the stack must be
+   a promise and is not evaluated until the <a href="#lcar">lcar</a>
+   of the list is requested.</a>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) dup <a href="#lcar">lcar</a> .
+       => 42
+  ( 3 ) dup <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
+       => t
+  ( 4 ) [ . ] <a href="#leach">leach</a>
+       => 42
+</pre>
+
+<!-- lcar description -->
+<a name="lcar">
+<h3>lcar ( lcons -- value )</h3>
+<p>Provides the same effect as 'car' does for normal lists. It
+returns the first element in a lazy cons cell. This will force
+the evaluation of that element.</p>
+<pre class="code">
+  ( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcar">lcar</a> .
+       => 42
+</pre>
+
+<!-- lcdr description -->
+<a name="lcdr">
+<h3>lcdr ( lcons -- value )</h3>
+<p>Provides the same effect as 'cdr' does for normal lists. It
+returns the second element in a lazy cons cell and forces it. This
+causes that element to be evaluated immediately.</p>
+<pre class="code">
+  ( 1 ) [ 1 ] <a href="#delay">delay</a> [ 5 6 + ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcdr">lcdr</a> .
+       => 11
+</pre>
+
+<pre class="code">
+  ( 1 ) 5 <a href="#lfrom">lfrom</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 6
+  ( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 7
+  ( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
+       => 8
+</pre>
+
+<!-- lnth description -->
+<a name="lnth">
+<h3>lnth ( n llist -- value )</h3>
+<p>Provides the same effect as 'nth' does for normal lists. It
+returns the nth value in the lazy list. It causes all the values up to
+'n' to be evaluated.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) 5 swap <a href="#lnth">lnth</a> .
+       => 6
+</pre>
+
+<!-- luncons description -->
+<a name="luncons">
+<h3>luncons ( lcons -- car cdr )</h3>
+<p>Provides the same effect as 'uncons' does for normal lists. It
+returns the car and cdr of the lazy list.</p>
+<pre class="code">
+  ( 1 ) [ 5 ] <a href="#delay">delay</a> [ 6 ] <a  href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
+       => &lt;&lt; promise ... &gt;&gt;
+  ( 2 ) <a href="#luncons">luncons</a> . .
+       => 6
+          5
+</pre>
+
+<!-- lmap description -->
+<a name="lmap">
+<h3>lmap ( llist quot -- llist )</h3>
+<p>Lazily maps over a lazy list applying the quotation to each element.
+A new lazy list is returned which contains the results of the
+quotation.</p>
+<p>When intially called nothing in the original lazy list is
+evaluated. Only when <a href="#lcar">lcar</a> is called will the item
+in the list be evaluated and applied to the quotation. Ditto with <a
+href="#lcdr">lcdr</a>, thus allowing infinite lists to be mapped over.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
+       => < infinite list of numbers incrementing by 2 >
+  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 2 4 6 8 10 ]
+</pre>
+
+<!-- lsubset description -->
+<a name="lsubset">
+<h3>lsubset ( llist pred -- llist )</h3>
+<p>Provides the same effect as 'subset' does for normal lists. It
+lazily iterates over a lazy list applying the predicate quotation to each
+element. If that quotation returns true, the element will be included
+in the resulting lazy list. If it is false, the element will be skipped.
+A new lazy list is returned which contains  all elements where the
+predicate returned true.</p>
+<p>Like <a href="#lmap">lmap</a>, when initially called no evaluation
+will occur. A lazy list is returned that when values are retrieved
+from in then items are evaluated and checked against the predicate.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ <a href="#primep">prime?</a> ] <a href="#lsubset">lsubset</a>
+       => < infinite list of prime numbers >
+  ( 3 ) 5 swap <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 2 3 5 7 11 ]
+</pre>
+
+<!-- leach description -->
+<a name="leach">
+<h3>leach ( llist quot --  )</h3>
+<p>Provides the same effect as 'each' does for normal lists. It
+lazily iterates over a lazy list applying the quotation to each
+element. If this operation is applied to an infinite list it will
+never return unless the quotation escapes out by calling a continuation.</p>
+<pre class="code">
+  ( 1 ) 1 <a href="#lfrom">lfrom</a>
+       => < infinite list of incrementing numbers >
+  ( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
+       => < infinite list of odd numbers >
+  ( 3 ) [ . ] <a href="#leach">leach</a> 
+       => 1
+          3
+          5
+          7
+          ... for ever ...
+</pre>
+
+<!-- ltake description -->
+<a name="ltake">
+<h3>ltake ( n llist -- llist )</h3>
+<p>Iterates over the lazy list 'n' times, appending each element to a
+lazy list. This provides a convenient way of getting elements out of
+an infinite lazy list.</p>
+<pre class="code">
+  ( 1 ) : ones [ 1 ] delay [ ones ] delay <a href="#lcons">lcons</a> ;
+  ( 2 ) 5 ones <a href="#ltake">ltake</a> <a  href="#llist2list">llist&gt;list</a> .
+       => [ 1 1 1 1 1  ]
+</pre>
+
+<!-- lappend description -->
+<a name="lappend">
+<h3>lappend ( llist1 llist2 -- llist )</h3>
+<p>Lazily appends two lists together. The actual appending is done
+lazily on iteration rather than immediately so it works very fast no
+matter how large the list.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> <a href="#lappend">lappend</a>
+  ( 2 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+          4
+          5
+          6
+</pre>
+
+<!-- lappend* description -->
+<a name="lappendstar">
+<h3>lappend* ( llists -- llist )</h3>
+<p>Given a lazy list of lazy lists, concatenate them together in a
+lazy fashion. The actual appending is done lazily on iteration rather
+than immediately so it works very fast no matter how large the lists.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2>llist">list&gt;llist</a> 
+  ( 2 ) [ 4 5 6 ] <a href="#list2llist">list&gt;llist</a> 
+  ( 3 ) [ 7 8 9 ] <a href="#list2llist">list&gt;llist</a>
+  ( 4 ) 3list <a href="#list2llist">list&gt;llist</a> <a href="#lappendstar">lappend*</a>
+  ( 5 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+          4
+          5
+          6
+          7
+          8
+          9
+</pre>
+
+<!-- list>llist description -->
+<a name="list2llist">
+<h3>list&gt;llist ( list  -- llist )</h3>
+<p>Converts a normal list into a lazy list. This is done lazily so the
+initial list is not iterated through immediately.</p>
+<pre class="code">
+  ( 1 ) [ 1 2 3 ] <a href="#list2llist">list&gt;llist</a> 
+  ( 2 ) [ . ] <a href="#leach">leach</a>
+       => 1
+          2
+          3
+</pre>
+
+<p class="footer">
+News and updates to this software can be obtained from the authors
+weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
+<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
+</body> </html>
diff --git a/extra/lists/lazy/summary.txt b/extra/lists/lazy/summary.txt
new file mode 100644 (file)
index 0000000..5d2f302
--- /dev/null
@@ -0,0 +1 @@
+Lazy lists
diff --git a/extra/lists/lazy/tags.txt b/extra/lists/lazy/tags.txt
new file mode 100644 (file)
index 0000000..dd23829
--- /dev/null
@@ -0,0 +1,2 @@
+extensions
+collections
diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor
new file mode 100644 (file)
index 0000000..15faf8d
--- /dev/null
@@ -0,0 +1,104 @@
+! Copyright (C) 2006 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax ;
+
+IN: lists
+
+{ car cons cdr nil nil? list? uncons } related-words
+
+HELP: cons 
+{ $values { "car" "the head of the lazy list" } { "cdr" "the tail of the lazy list" } { "cons" "a cons object" } }
+{ $description "Constructs a cons cell." } ;
+
+HELP: car
+{ $values { "cons" "a cons object" } { "car" "the first item in the list" } }
+{ $description "Returns the first item in the list." } ;
+
+HELP: cdr
+{ $values { "cons" "a cons object" } { "cdr" "a cons object" } }
+{ $description "Returns the tail of the list." } ;
+    
+HELP: nil 
+{ $values { "symbol" "The empty cons (+nil+)" } }
+{ $description "Returns a symbol representing the empty list" } ;
+
+HELP: nil? 
+{ $values { "cons" "a cons object" } { "?" "a boolean" } }
+{ $description "Return true if the cons object is the nil cons." } ;
+
+HELP: list? ( object -- ? )
+{ $values { "object" "an object" } { "?" "a boolean" } }
+{ $description "Returns true if the object conforms to the list protocol." } ;
+
+{ 1list 2list 3list } related-words
+
+HELP: 1list
+{ $values { "obj" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 1 element." } ;
+
+HELP: 2list
+{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 2 elements." } ;
+
+HELP: 3list
+{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } }
+{ $description "Create a list with 3 elements." } ;
+    
+HELP: lnth
+{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } }
+{ $description "Outputs the nth element of the list." } 
+{ $see-also llength cons car cdr } ;
+
+HELP: llength
+{ $values { "list" "a cons object" } { "n" "a non-negative integer" } }
+{ $description "Outputs the length of the list. This should not be called on an infinite list." } 
+{ $see-also lnth cons car cdr } ;
+
+HELP: uncons
+{ $values { "cons" "a cons object" }  { "cdr" "the tail of the list" } { "car" "the head of the list" } }
+{ $description "Put the head and tail of the list on the stack." } ;
+
+{ leach foldl lmap>array } related-words
+
+HELP: leach
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } }
+{ $description "Call the quotation for each item in the list." } ;
+
+HELP: foldl
+{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } }
+{ $description "Combines successive elements of the list (in a left-assocative order) using a binary operation and outputs the final result." } ;
+
+HELP: foldr
+{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } }
+{ $description "Combines successive elements of the list (in a right-assocative order) using a binary operation, and outputs the final result." } ;
+
+HELP: lmap
+{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( old -- new )" } { "result" "the final result" } }
+{ $description "Applies the quotation to each element of the list in order, collecting the new elements into a new list." } ;
+    
+HELP: lreverse
+{ $values { "list" "a cons object" } { "newlist" "a new cons object" } }
+{ $description "Reverses the input list, outputing a new, reversed list" } ;
+    
+HELP: list>seq    
+{ $values { "list" "a cons object" } { "array" "an array object" } }
+{ $description "Turns the given cons object into an array, maintaing order." } ;
+    
+HELP: seq>list
+{ $values { "seq" "a sequence" } { "list" "a cons object" } }
+{ $description "Turns the given array into a cons object, maintaing order." } ;
+    
+HELP: cons>seq
+{ $values { "cons" "a cons object" } { "array" "an array object" } }
+{ $description "Recursively turns the given cons object into an array, maintaing order and also converting nested lists." } ;
+    
+HELP: seq>cons
+{ $values { "seq" "a sequence object" } { "cons" "a cons object" } }
+{ $description "Recursively turns the given sequence into a cons object, maintaing order and also converting nested lists." } ;
+    
+HELP: traverse    
+{ $values { "list"  "a cons object" } { "pred" "a quotation with stack effect ( list/elt -- ? )" }
+          { "quot" "a quotation with stack effect ( list/elt -- result)" }  { "result" "a new cons object" } }
+{ $description "Recursively traverses the list object, replacing any elements (which can themselves be sublists) that pred" 
+    " returns true for with the result of applying quot to." } ;
+    
diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor
new file mode 100644 (file)
index 0000000..cdc51b7
--- /dev/null
@@ -0,0 +1,66 @@
+! Copyright (C) 2008 James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test lists math ;
+
+IN: lists.tests
+
+{ { 3 4 5 6 7 } } [
+    { 1 2 3 4 5 } seq>list [ 2 + ] lmap list>seq 
+] unit-test
+
+{ { 3 4 5 6 } } [
+    T{ cons f 1       
+        T{ cons f 2 
+            T{ cons f 3
+                T{ cons f 4
+                +nil+ } } } } [ 2 + ] lmap>array
+] unit-test
+
+{ 10 } [
+    T{ cons f 1       
+        T{ cons f 2 
+            T{ cons f 3
+                T{ cons f 4
+                +nil+ } } } } 0 [ + ] foldl
+] unit-test
+    
+{ T{ cons f
+      1
+      T{ cons f
+          2
+          T{ cons f
+              T{ cons f
+                  3
+                  T{ cons f
+                      4
+                      T{ cons f
+                          T{ cons f 5 +nil+ }
+                          +nil+ } } }
+          +nil+ } } }
+} [
+    { 1 2 { 3 4 { 5 } } } seq>cons
+] unit-test
+    
+{ { 1 2 { 3 4 { 5 } } } } [
+  { 1 2 { 3 4 { 5 } } } seq>cons cons>seq
+] unit-test
+    
+{ T{ cons f 2 T{ cons f 3 T{ cons f 4 T{ cons f 5 +nil+ } } } } } [
+    { 1 2 3 4 } seq>cons [ 1+ ] lmap
+] unit-test
+    
+{ 15 } [
+ { 1 2 3 4 5 } seq>list 0 [ + ] foldr
+] unit-test
+    
+{ { 5 4 3 2 1 } } [
+    { 1 2 3 4 5 } seq>list lreverse list>seq
+] unit-test
+    
+{ 5 } [
+    { 1 2 3 4 5 } seq>list llength
+] unit-test
+    
+{ { 3 4 { 5 6 { 7 } } } } [
+  { 1 2 { 3 4 { 5 } } } seq>cons [ atom? ] [ 2 + ] traverse cons>seq
+] unit-test
\ No newline at end of file
diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor
new file mode 100644 (file)
index 0000000..13d77f7
--- /dev/null
@@ -0,0 +1,107 @@
+! Copyright (C) 2008 Chris Double & James Cash
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences accessors math arrays vectors classes words locals ;
+
+IN: lists
+
+! List Protocol
+MIXIN: list
+GENERIC: car   ( cons -- car )
+GENERIC: cdr   ( cons -- cdr )
+GENERIC: nil?  ( object -- ?   )
+    
+TUPLE: cons car cdr ;
+
+C: cons cons
+
+M: cons car ( cons -- car )
+    car>> ;
+
+M: cons cdr ( cons -- cdr )
+    cdr>> ;
+    
+SYMBOL: +nil+
+M: word nil? +nil+ eq? ;
+M: object nil? drop f ;
+    
+: atom? ( obj -- ? ) [ list? ] [ nil? ] bi or not ;
+
+: nil ( -- symbol ) +nil+ ; 
+    
+: uncons ( cons -- cdr car )
+    [ cdr ] [ car ] bi ;
+    
+: 1list ( obj -- cons )
+    nil cons ;
+    
+: 2list ( a b -- cons )
+    nil cons cons ;
+
+: 3list ( a b c -- cons )
+    nil cons cons cons ;
+    
+: cadr ( cons -- elt )    
+    cdr car ;
+    
+: 2car ( cons -- car caar )    
+    [ car ] [ cdr car ] bi ;
+    
+: 3car ( cons -- car caar caaar )    
+    [ car ] [ cdr car ] [ cdr cdr car ] tri ;
+
+: lnth ( n list -- elt )
+    swap [ cdr ] times car ;
+    
+: (leach) ( list quot -- cdr quot )
+    [ [ car ] dip call ] [ [ cdr ] dip ] 2bi ; inline
+
+: leach ( list quot -- )
+    over nil? [ 2drop ] [ (leach) leach ] if ; inline
+
+: lmap ( list quot -- result )
+    over nil? [ drop ] [ (leach) lmap cons ] if ; inline
+
+: foldl ( list identity quot -- result ) swapd leach ; inline
+
+: foldr ( list identity quot -- result )
+    pick nil? [ [ drop ] [ ] [ drop ] tri* ] [
+        [ [ cdr ] 2dip foldr ] [ nip [ car ] dip ] 3bi
+        call
+    ] if ; inline
+
+: llength ( list -- n )
+    0 [ drop 1+ ] foldl ;
+    
+: lreverse ( list -- newlist )    
+    nil [ swap cons ] foldl ;
+    
+: seq>list ( seq -- list )    
+    <reversed> nil [ swap cons ] reduce ;
+    
+: same? ( obj1 obj2 -- ? ) 
+    [ class ] bi@ = ;
+    
+: seq>cons ( seq -- cons )
+    [ <reversed> ] keep nil [ tuck same? [ seq>cons ] when f cons swap >>cdr ] with reduce ;
+    
+: (lmap>array) ( acc cons quot -- newcons )
+    over nil? [ 2drop ]
+    [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap>array) ] if ; inline
+    
+: lmap>array ( cons quot -- newcons )
+    { } -rot (lmap>array) ; inline
+    
+: lmap-as ( cons quot exemplar -- seq )
+    [ lmap>array ] dip like ;
+    
+: cons>seq ( cons -- array )    
+    [ dup cons? [ cons>seq ] when ] lmap>array ;
+    
+: list>seq ( list -- array )    
+    [ ] lmap>array ;
+    
+: traverse ( list pred quot -- result )
+    [ 2over call [ tuck [ call ] 2dip ] when
+      pick list? [ traverse ] [ 2drop ] if ] 2curry lmap ;
+    
+INSTANCE: cons list
\ No newline at end of file
diff --git a/extra/lists/summary.txt b/extra/lists/summary.txt
new file mode 100644 (file)
index 0000000..60a1886
--- /dev/null
@@ -0,0 +1 @@
+Implementation of lisp-style linked lists
diff --git a/extra/lists/tags.txt b/extra/lists/tags.txt
new file mode 100644 (file)
index 0000000..e44334b
--- /dev/null
@@ -0,0 +1,3 @@
+cons
+lists
+sequences
index 41caa87fae49545d768c41537ab9bbf76ad34e3b..935271450947509a8c54105b7ab4ceaf265bf2ab 100644 (file)
@@ -5,34 +5,35 @@ USING: tools.test locals.backend kernel arrays ;
 
 [ 4 ] [ 3 4 >r >r 2 get-local 2 drop-locals ] unit-test
 
-: get-local-test-1 3 >r 1 get-local r> drop ;
+: get-local-test-1 ( -- x ) 3 >r 1 get-local r> drop ;
 
-{ 0 1 } [ get-local-test-1 ] must-infer-as
+\ get-local-test-1 must-infer
 
 [ 3 ] [ get-local-test-1 ] unit-test
 
-: get-local-test-2 3 4 >r >r 2 get-local 2 drop-locals ;
+: get-local-test-2 ( -- x ) 3 4 >r >r 2 get-local 2 drop-locals ;
 
-{ 0 1 } [ get-local-test-2 ] must-infer-as
+\ get-local-test-2 must-infer
 
 [ 4 ] [ get-local-test-2 ] unit-test
 
-: get-local-test-3 3 4 >r >r 2 get-local r> r> 2array ;
+: get-local-test-3 ( -- a b ) 3 4 >r >r 2 get-local r> r> 2array ;
 
-{ 0 2 } [ get-local-test-3 ] must-infer-as
+\ get-local-test-3 must-infer
 
 [ 4 { 3 4 } ] [ get-local-test-3 ] unit-test
 
-: get-local-test-4 3 4 >r >r r> r> dup swap >r swap >r r> r> 2array ;
+: get-local-test-4 ( -- a b )
+    3 4 >r >r r> r> dup swap >r swap >r r> r> 2array ;
 
-{ 0 2 } [ get-local-test-4 ] must-infer-as
+\ get-local-test-4 must-infer
 
 [ 4 { 3 4 } ] [ get-local-test-4 ] unit-test
 
 [ 1 2 ] [ 1 2 2 load-locals r> r> ] unit-test
 
-: load-locals-test-1 1 2 2 load-locals r> r> ;
+: load-locals-test-1 ( -- a b ) 1 2 2 load-locals r> r> ;
 
-{ 0 2 } [ load-locals-test-1 ] must-infer-as
+\ load-locals-test-1 must-infer
 
 [ 1 2 ] [ load-locals-test-1 ] unit-test
index e74d0b60784cf410ffcb29ae057f779b72642343..028502560f6691e4bc68610e5000c26d977fe149 100755 (executable)
@@ -146,7 +146,7 @@ GENERIC: lambda-rewrite* ( obj -- )
 
 GENERIC: local-rewrite* ( obj -- )
 
-: lambda-rewrite
+: lambda-rewrite ( quot -- quot' )
     [ local-rewrite* ] [ ] make
     [ [ lambda-rewrite* ] each ] [ ] make ;
 
@@ -273,7 +273,7 @@ M: wlet local-rewrite*
     let-rewrite ;
 
 : parse-locals ( -- vars assoc )
-    parse-effect
+    ")" parse-effect
     word [ over "declared-effect" set-word-prop ] when*
     effect-in make-locals dup push-locals ;
 
@@ -282,9 +282,9 @@ M: wlet local-rewrite*
     2dup "lambda" set-word-prop
     lambda-rewrite first ;
 
-: (::) CREATE-WORD parse-locals-definition ;
+: (::) ( -- word def ) CREATE-WORD parse-locals-definition ;
 
-: (M::)
+: (M::) ( -- word def )
     CREATE-METHOD
     [ parse-locals-definition ] with-method-definition ;
 
index cd1429ac53485d9f332c6c2cc0e626026eac1c5c..a074ccd1b9072ebbb44f44b4283faf9b7d2f439f 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: kernel sequences namespaces words assocs logging sorting\r
-prettyprint io io.styles strings logging.parser calendar.format ;\r
+prettyprint io io.styles strings logging.parser calendar.format\r
+combinators ;\r
 IN: logging.analysis\r
 \r
 SYMBOL: word-names\r
@@ -41,12 +42,14 @@ SYMBOL: message-histogram
         ] curry assoc-each\r
     ] tabular-output ;\r
 \r
-: log-entry.\r
+: log-entry. ( entry -- )\r
     "====== " write\r
-    dup first (timestamp>string) bl\r
-    dup second pprint bl\r
-    dup third write nl\r
-    fourth "\n" join print ;\r
+    {\r
+        [ first (timestamp>string) bl ]\r
+        [ second pprint bl ]\r
+        [ third write nl ]\r
+        [ fourth "\n" join print ]\r
+    } cleave ;\r
 \r
 : errors. ( errors -- )\r
     [ log-entry. ] each ;\r
index df03bf320b7fbc4ccd9115dcbc820ec0487502b8..6fb7ebd6b13a54b6f2352436cb816dc292e3f037 100755 (executable)
@@ -42,7 +42,7 @@ SYMBOL: log-service
 \r
 <PRIVATE\r
 \r
-: one-string?\r
+: one-string? ( obj -- ? )\r
     {\r
         [ dup array? ]\r
         [ dup length 1 = ]\r
@@ -77,7 +77,7 @@ PRIVATE>
         3drop\r
     ] if ; inline\r
 \r
-: input# stack-effect in>> length ;\r
+: input# ( word -- n ) stack-effect in>> length ;\r
 \r
 : input-logging-quot ( quot word level -- quot' )\r
     rot [ [ input# ] keep ] 2dip '[ , , , log-stack @ ] ;\r
@@ -85,7 +85,7 @@ PRIVATE>
 : add-input-logging ( word level -- )\r
     [ input-logging-quot ] (define-logging) ;\r
 \r
-: output# stack-effect out>> length ;\r
+: output# ( word -- n ) stack-effect out>> length ;\r
 \r
 : output-logging-quot ( quot word level -- quot' )\r
     [ [ output# ] keep ] dip '[ @ , , , log-stack ] ;\r
@@ -121,4 +121,4 @@ PRIVATE>
     #! Syntax: name level\r
     CREATE-WORD dup scan-word\r
     '[ 1array stack>message , , log-message ]\r
-    define ; parsing\r
+    (( message -- )) define-declared ; parsing\r
index c6b073e50199d2215bc20e779f63b8819acd194a..326661fee5df5403e32e3c1d087c7367da914c51 100755 (executable)
@@ -6,31 +6,31 @@ namespaces combinators combinators.lib logging.server
 calendar calendar.format ;\r
 IN: logging.parser\r
 \r
-: string-of satisfy <!*> [ >string ] <@ ;\r
+: string-of ( quot -- parser ) satisfy <!*> [ >string ] <@ ;\r
 \r
 SYMBOL: multiline\r
 \r
-: 'date'\r
+: 'date' ( -- parser )\r
     [ "]" member? not ] string-of [\r
         dup multiline-header =\r
         [ drop multiline ] [ rfc3339>timestamp ] if\r
     ] <@\r
     "[" "]" surrounded-by ;\r
 \r
-: 'log-level'\r
+: 'log-level' ( -- parser )\r
     log-levels [\r
         [ word-name token ] keep [ nip ] curry <@\r
     ] map <or-parser> ;\r
 \r
-: 'word-name'\r
+: 'word-name' ( -- parser )\r
     [ " :" member? not ] string-of ;\r
 \r
 SYMBOL: malformed\r
 \r
-: 'malformed-line'\r
+: 'malformed-line' ( -- parser )\r
     [ drop t ] string-of [ malformed swap 2array ] <@ ;\r
 \r
-: 'log-message'\r
+: 'log-message' ( -- parser )\r
     [ drop t ] string-of [ 1vector ] <@ ;\r
 \r
 MEMO: 'log-line' ( -- parser )\r
@@ -49,7 +49,7 @@ MEMO: 'log-line' ( -- parser )
 : multiline? ( line -- ? )\r
     first multiline eq? ;\r
 \r
-: malformed-line\r
+: malformed-line ( line -- )\r
     "Warning: malformed log line:" print\r
     second print ;\r
 \r
index 2a4e34e01599c3d03e6efc71ed528b35247322fa..f4ad8144bed9f9dbd80989ac63cf6fc297ce363c 100755 (executable)
@@ -67,7 +67,7 @@ SYMBOL: log-files
 : ?delete-file ( path -- )\r
     dup exists? [ delete-file ] [ drop ] if ;\r
 \r
-: delete-oldest keep-logs log# ?delete-file ;\r
+: delete-oldest ( service -- ) keep-logs log# ?delete-file ;\r
 \r
 : ?move-file ( old new -- )\r
     over exists? [ move-file ] [ 2drop ] if ;\r
index 88bfd01fbec29b244243476f0cc8ea5f2cd50465..ccfc93240614b72a134c2bbbd40a51c03bd8afcb 100755 (executable)
@@ -30,6 +30,6 @@ M: macro reset-word
 
 : n*quot ( n seq -- seq' ) <repetition> concat >quotation ;
 
-: saver \ >r <repetition> >quotation ;
+: saver ( n -- quot ) \ >r <repetition> >quotation ;
 
-: restorer \ r> <repetition> >quotation ;
+: restorer ( n -- quot ) \ r> <repetition> >quotation ;
index c5a063ab983e36b0df0c3ec03bc07cc44146914e..8a174034baa0bdd6b4dda21574e709c8bc3c06ac 100755 (executable)
@@ -3,7 +3,7 @@
 !
 ! Based on pattern matching code from Paul Graham's book 'On Lisp'.
 USING: parser kernel words namespaces sequences classes.tuple
-combinators macros assocs math ;
+combinators macros assocs math effects ;
 IN: match
 
 SYMBOL: _
@@ -11,7 +11,7 @@ SYMBOL: _
 : define-match-var ( name -- )
     create-in
     dup t "match-var" set-word-prop
-    dup [ get ] curry define ;
+    dup [ get ] curry (( -- value )) define-declared ;
 
 : define-match-vars ( seq -- )
     [ define-match-var ] each ;
index 9244fa62e2f18182b28d2f6fa329332e9ecde8aa..041cb8dc3af6e1c89f7843b9b2fb816051a06883 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lazy-lists math.erato tools.test ;
+USING: lists.lazy math.erato tools.test ;
 IN: math.erato.tests
 
 [ { 2 3 5 7 11 13 17 19 } ] [ 20 lerato list>array ] unit-test
index 40de92e3b1d322866b2bfa86f31f9ebb463fd4f7..b9d997c038ac5215427a918e8dd56a071aeaacfb 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: bit-arrays kernel lazy-lists math math.functions math.primes.list
+USING: bit-arrays kernel lists.lazy math math.functions math.primes.list
        math.ranges sequences ;
 IN: math.erato
 
index 4d4068158e2f8354256aa594abc10ccf1a88a47c..682d2a49dbbb35d3ba0daad2e48b3994fe1cc0a3 100644 (file)
@@ -1,7 +1,7 @@
 ! Fast Fourier Transform, copyright (C) 2007 Hans Schmid
 ! http://dressguardmeister.blogspot.com/2007/01/fft.html
 USING: arrays sequences math math.vectors math.constants
-math.functions kernel splitting columns ;
+math.functions kernel splitting grouping columns ;
 IN: math.fft
 
 : n^v ( n v -- w ) [ ^ ] with map ;
index 6176c12d21a0e476485b87aa4ab7ddb9b28cecfb..f2d26e330db5eca836ceea5f12da4ca569c9c8a1 100755 (executable)
@@ -44,7 +44,10 @@ IN: math.functions.tests
 
 [ t ] [ 10 asin sin 10 1.e-10 ~ ] unit-test
 [ t ] [ -1 sqrt neg dup acos cos 1.e-10 ~ ] unit-test
+[ t ] [ -100 atan tan -100 1.e-10 ~ ] unit-test
 [ t ] [ 10 asinh sinh 10 1.e-10 ~ ] unit-test
+[ t ] [ 10 atanh tanh 10 1.e-10 ~ ] unit-test
+[ t ] [ 0.5 atanh tanh 0.5 1.e-10 ~ ] unit-test
 
 [ 100 ] [ 100 100 gcd nip ] unit-test
 [ 100 ] [ 1000 100 gcd nip ] unit-test
@@ -70,7 +73,7 @@ IN: math.functions.tests
     gcd nip
 ] unit-test
 
-: verify-gcd
+: verify-gcd ( a b -- ? )
     2dup gcd
     >r rot * swap rem r> = ; 
 
index bb43e4a72166228611f9cd67c81817a83677e90f..4dcb21513883de5edd415e2420f4c83293641fc2 100755 (executable)
@@ -182,17 +182,17 @@ M: number (^)
 : coth ( x -- y ) tanh recip ; inline
 
 : acosh ( x -- y )
-    dup >=1? [ facosh ] [ dup sq 1- sqrt + log ] if ; inline
+    dup sq 1- sqrt + log ; inline
 
 : asech ( x -- y ) recip acosh ; inline
 
 : asinh ( x -- y )
-    dup complex? [ dup sq 1+ sqrt + log ] [ fasinh ] if ; inline
+    dup sq 1+ sqrt + log ; inline
 
 : acosech ( x -- y ) recip asinh ; inline
 
 : atanh ( x -- y )
-    dup [-1,1]? [ fatanh ] [ dup 1+ swap 1- neg / log 2 / ] if ; inline
+    dup 1+ swap 1- neg / log 2 / ; inline
 
 : acoth ( x -- y ) recip atanh ; inline
 
index 9254fd0ce7d09106fd3f5202078bc56db9ac4bec..f1bf87161ce2a7e9aa3c1b96ca05f5ae68fdec8b 100644 (file)
@@ -1,5 +1,5 @@
 ! Haar wavelet transform -- http://dmr.ath.cx/gfx/haar/
-USING: sequences math kernel splitting columns ;
+USING: sequences math kernel splitting grouping columns ;
 IN: math.haar
 
 : averages ( seq -- seq )
old mode 100644 (file)
new mode 100755 (executable)
index f70c8d2..8bda6a6
@@ -15,18 +15,6 @@ IN: math.libm
     "double" "libm" "atan" { "double" } alien-invoke ;
     foldable
 
-: facosh ( x -- y )
-    "double" "libm" "acosh" { "double" } alien-invoke ;
-    foldable
-
-: fasinh ( x -- y )
-    "double" "libm" "asinh" { "double" } alien-invoke ;
-    foldable
-
-: fatanh ( x -- y )
-    "double" "libm" "atanh" { "double" } alien-invoke ;
-    foldable
-
 : fatan2 ( x y -- z )
     "double" "libm" "atan2" { "double" "double" } alien-invoke ;
     foldable
@@ -70,3 +58,16 @@ IN: math.libm
 : fsqrt ( x -- y )
     "double" "libm" "sqrt" { "double" } alien-invoke ;
     foldable
+    
+! Windows doesn't have these...
+: facosh ( x -- y )
+    "double" "libm" "acosh" { "double" } alien-invoke ;
+    foldable
+
+: fasinh ( x -- y )
+    "double" "libm" "asinh" { "double" } alien-invoke ;
+    foldable
+
+: fatanh ( x -- y )
+    "double" "libm" "atanh" { "double" } alien-invoke ;
+    foldable
index 7638550129d2404c613299fc4940201e5d3127b3..a902eda6f78c99587e4cb1e5f74f5bd373a7aef7 100755 (executable)
@@ -69,7 +69,8 @@ SYMBOL: matrix
 : echelon ( matrix -- matrix' )
     [ 0 0 (echelon) ] with-matrix ;
 
-: nonzero-rows [ [ zero? ] all? not ] filter ;
+: nonzero-rows ( matrix -- matrix' )
+    [ [ zero? ] all? not ] filter ;
 
 : null/rank ( matrix -- null rank )
     echelon dup length swap nonzero-rows length [ - ] keep ;
index 294cd6278a7533b2073a1ae0ba33542335a93fa9..529ddb083a9ca9e0ddb2962cea05cf9b5c37bbd6 100755 (executable)
@@ -35,13 +35,13 @@ IN: math.matrices
 
 <PRIVATE
 
-: x first ; inline
-: y second ; inline
-: z third ; inline
+: x ( seq -- elt ) first ; inline
+: y ( seq -- elt ) second ; inline
+: z ( seq -- elt ) third ; inline
 
-: i [ [ y ] [ z ] bi* * ] [ [ z ] [ y ] bi* * ] 2bi - ;
-: j [ [ z ] [ x ] bi* * ] [ [ x ] [ z ] bi* * ] 2bi - ;
-: k [ [ y ] [ x ] bi* * ] [ [ x ] [ y ] bi* * ] 2bi - ;
+: 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>
 
index 842c4c7f50a2b845ad3f2546a38ed14e2a007e35..e3adf2277d1b9cf609b9c9f84b3db67092089610 100644 (file)
@@ -54,7 +54,7 @@ PRIVATE>
     #! divide the last two numbers in the sequences
     [ peek ] bi@ / ;
 
-: (p/mod)
+: (p/mod) ( p p -- p p )
     2dup /-last
     2dup , n*p swapd
     p- >vector
index 2f70ab24b474b959ddf95a2a952c0b636f2a54a1..aba7e90bc906da5b1cf6cd7ed7e93742dc649ca2 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel lazy-lists math math.primes namespaces sequences ;
+USING: arrays kernel lists math math.primes namespaces sequences ;
 IN: math.primes.factors
 
 <PRIVATE
@@ -17,7 +17,7 @@ IN: math.primes.factors
     dup empty? [ drop ] [ first , ] if ;
 
 : (factors) ( quot list n -- )
-    dup 1 > [ swap uncons >r pick call r> swap (factors) ] [ 3drop ] if ;
+    dup 1 > [ swap uncons swap >r pick call r> swap (factors) ] [ 3drop ] if ;
 
 : (decompose) ( n quot -- seq )
     [ lprimes rot (factors) ] { } make ;
index b1bcf79a49b7efdeeb6b994da3c25d6f0d8a700a..186acc9b1127d3b3808e2fe6221b00bbbaa30ecd 100644 (file)
@@ -1,4 +1,4 @@
-USING: arrays math.primes tools.test lazy-lists ;
+USING: arrays math.primes tools.test lists.lazy ;
 
 { 1237 } [ 1234 next-prime ] unit-test
 { f t } [ 1234 prime? 1237 prime? ] unit-test
index 2eeaca6c921314532e9bf209754a2a1099ece686..59aebbf0dd632cf9f1797542c1b9f63d7c1481d0 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel lazy-lists math math.functions math.miller-rabin
+USING: combinators kernel lists.lazy math math.functions math.miller-rabin
        math.order math.primes.list math.ranges sequences sorting ;
 IN: math.primes
 
index cba8c283101c49afbcab602ad69961687c8cd9af..3030f28d04100d350b2d81f5ae9962dfbad45c20 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.lib kernel math math.functions math.parser namespaces
-    sequences splitting sequences.lib ;
+    sequences splitting grouping sequences.lib ;
 IN: math.text.english
 
 <PRIVATE
index 1c0491a7ab0e62ada99e9f0bc223a913dfecb472..aa6ebb532c9e4b9f56677febf790d8a426ed46bd 100755 (executable)
@@ -59,5 +59,5 @@ M: memoized reset-word
 : reset-memoized ( word -- )
     "memoize" word-prop clear-assoc ;
 
-: invalidate-memoized ! ( inputs... word )
+: invalidate-memoized ( inputs... word -- )
     [ #in packer call ] [ "memoize" word-prop delete-at ] bi ;
index 19cdcab2fbabfc8075cb2f7a225c1e8dc639df7a..25bad4061adc7fc63773cc5dc40c6976b63ea976 100755 (executable)
@@ -177,6 +177,6 @@ IN: minneapolis-talk
     { $slide "Questions?" }
 } ;
 
-: minneapolis-talk minneapolis-slides slides-window ;
+: minneapolis-talk ( -- ) minneapolis-slides slides-window ;
 
 MAIN: minneapolis-talk
index 7a0b4b532aa414bb595e2792f8ca33400489da44..2caf6e9940c2db0158518e058bf8eb42169a77d7 100755 (executable)
@@ -156,7 +156,7 @@ TUPLE: history back forward ;
 : <history> ( value -- history )
     history construct-model dup reset-history ;
 
-: (add-history)
+: (add-history) ( history to -- )
     swap model-value dup [ swap push ] [ 2drop ] if ;
 
 : go-back/forward ( history to from -- )
index 52cdc47ac6a6e8063b5a50253ccea788f23e837b..d0014b5abe7ca38c26df52199f9cb70dbf2ce82d 100644 (file)
@@ -1,4 +1,4 @@
-USING: tools.test monads math kernel sequences lazy-lists promises ;
+USING: tools.test monads math kernel sequences lists promises ;
 IN: monads.tests
 
 [ 5 ] [ 1 identity-monad return [ 4 + ] fmap run-identity ] unit-test
index 0f4138c9853a87299d1db0a073fa37424d1ad069..e110cb38d3397690b146bffe1cbc98412998df18 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel sequences sequences.deep splitting
-accessors fry locals combinators namespaces lazy-lists
+accessors fry locals combinators namespaces lists lists.lazy
 shuffle ;
 IN: monads
 
@@ -14,7 +14,7 @@ GENERIC# fmap 1 ( functor quot -- functor' ) inline
 MIXIN: monad
 
 GENERIC: monad-of ( mvalue -- singleton )
-GENERIC: return ( string singleton -- mvalue )
+GENERIC: return ( value singleton -- mvalue )
 GENERIC: fail ( value singleton -- mvalue )
 GENERIC: >>= ( mvalue -- quot )
 
@@ -62,7 +62,7 @@ INSTANCE:  maybe-monad monad
 SINGLETON: nothing
 
 TUPLE: just value ;
-: just \ just boa ;
+: just ( value -- just ) \ just boa ;
 
 UNION: maybe just nothing ;
 INSTANCE: maybe monad
@@ -83,10 +83,10 @@ SINGLETON: either-monad
 INSTANCE:  either-monad monad
 
 TUPLE: left value ;
-: left \ left boa ;
+: left ( value -- left ) \ left boa ;
 
 TUPLE: right value ;
-: right \ right boa ;
+: right ( value -- right ) \ right boa ;
 
 UNION: either left right ;
 INSTANCE: either monad
@@ -124,14 +124,14 @@ M: list-monad fail   2drop nil ;
 
 M: list monad-of drop list-monad ;
 
-M: list >>= '[ , _ lmap lconcat ] ;
+M: list >>= '[ , _ lazy-map lconcat ] ;
 
 ! State
 SINGLETON: state-monad
 INSTANCE:  state-monad monad
 
 TUPLE: state quot ;
-: state \ state boa ;
+: state ( quot -- state ) \ state boa ;
 
 INSTANCE: state monad
 
@@ -140,7 +140,7 @@ M: state monad-of drop state-monad ;
 M: state-monad return drop '[ , 2array ] state ;
 M: state-monad fail   "Fail" throw ;
 
-: mcall quot>> call ;
+: mcall ( state -- ) quot>> call ;
 
 M: state >>= '[ , _ '[ , mcall first2 @ mcall ] state ] ;
 
@@ -149,14 +149,14 @@ M: state >>= '[ , _ '[ , mcall first2 @ mcall ] state ] ;
 
 : run-st ( state initial -- ) swap mcall second ;
 
-: return-st state-monad return ;
+: return-st ( value -- mvalue ) state-monad return ;
 
 ! Reader
 SINGLETON: reader-monad
 INSTANCE:  reader-monad monad
 
 TUPLE: reader quot ;
-: reader \ reader boa ;
+: reader ( quot -- reader ) \ reader boa ;
 INSTANCE: reader monad
 
 M: reader monad-of drop reader-monad ;
@@ -176,7 +176,7 @@ SINGLETON: writer-monad
 INSTANCE:  writer-monad monad
 
 TUPLE: writer value log ;
-: writer \ writer boa ;
+: writer ( value log -- writer ) \ writer boa ;
 
 M: writer monad-of drop writer-monad ;
 
index 1fd0a665556ccde033eb104ba29acd5dc1f720f8..54c53e9bec2656a6eef1267b02b6b43e143d8b34 100644 (file)
@@ -1,6 +1,6 @@
 USING: io kernel math math.functions math.parser parser
-namespaces sequences splitting combinators continuations
-sequences.lib ;
+namespaces sequences splitting grouping combinators
+continuations sequences.lib ;
 IN: money
 
 : dollars/cents ( dollars -- dollars cents )
index 9d335896be8c9d5ec66a7bab2f1c8671e112c1fc..591915b31756b8e8dffc521607bbf863a47dc3f8 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007, 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs combinators hashtables kernel lazy-lists math namespaces openal parser-combinators promises sequences strings symbols synth synth.buffers unicode.case ;
+USING: accessors assocs combinators hashtables kernel lists math namespaces openal parser-combinators promises sequences strings symbols synth synth.buffers unicode.case ;
 IN: morse
 
 <PRIVATE
index 6173669ad031e7fc93cc964bc835e2eaf093e0bf..3a4dc6fefb746f10fe55ecc3a475252ad23feff1 100644 (file)
@@ -1,6 +1,6 @@
 
 USING: kernel io parser words namespaces quotations arrays assocs sequences
-       splitting math shuffle ;
+       splitting grouping math shuffle ;
 
 IN: mortar
 
index 46ad6fc58e93014e396210166d0688ba89cff466..e2a18e2f78b4f248f6e01fec15bdf49b53d1104c 100755 (executable)
@@ -187,7 +187,8 @@ M: method-body crossref?
         drop [ <method> dup ] 2keep reveal-method
     ] if ;
 
-: niceify-method [ dup \ f eq? [ drop f ] when ] map ;
+: niceify-method ( seq -- seq )
+    [ dup \ f eq? [ drop f ] when ] map ;
 
 M: no-method error.
     "Type check error" print
@@ -229,10 +230,10 @@ M: no-method error.
 : create-method-in ( specializer generic -- method )
     create-method dup save-location f set-word ;
 
-: CREATE-METHOD
+: CREATE-METHOD ( -- method )
     scan-word scan-object swap create-method-in ;
 
-: (METHOD:) CREATE-METHOD parse-definition ;
+: (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
 
 : METHOD: (METHOD:) define ; parsing
 
index 851f60d126ebd039c8130e27a58ab9803a582d84..9ad8978bf34e26099b84f23360c12a3c0c06e79c 100755 (executable)
@@ -22,25 +22,25 @@ SYMBOL: building-seq
 : get-building-seq ( n -- seq )
     building-seq get nth ;
 
-: n, get-building-seq push ;
-: n% get-building-seq push-all ;
-: n# >r number>string r> n% ;
-
-: 0, 0 n, ;
-: 0% 0 n% ;
-: 0# 0 n# ;
-: 1, 1 n, ;
-: 1% 1 n% ;
-: 1# 1 n# ;
-: 2, 2 n, ;
-: 2% 2 n% ;
-: 2# 2 n# ;
-: 3, 3 n, ;
-: 3% 3 n% ;
-: 3# 3 n# ;
-: 4, 4 n, ;
-: 4% 4 n% ;
-: 4# 4 n# ;
+: n, ( obj n -- ) get-building-seq push ;
+: n% ( seq n -- ) get-building-seq push-all ;
+: n# ( num n -- ) >r number>string r> n% ;
+
+: 0, ( obj -- ) 0 n, ;
+: 0% ( seq -- ) 0 n% ;
+: 0# ( num -- ) 0 n# ;
+: 1, ( obj -- ) 1 n, ;
+: 1% ( seq -- ) 1 n% ;
+: 1# ( num -- ) 1 n# ;
+: 2, ( obj -- ) 2 n, ;
+: 2% ( seq -- ) 2 n% ;
+: 2# ( num -- ) 2 n# ;
+: 3, ( obj -- ) 3 n, ;
+: 3% ( seq -- ) 3 n% ;
+: 3# ( num -- ) 3 n# ;
+: 4, ( obj -- ) 4 n, ;
+: 4% ( seq -- ) 4 n% ;
+: 4# ( num -- ) 4 n# ;
 
 MACRO:: nmake ( quot exemplars -- )
     [let | n [ exemplars length ] |
index 51eb129b34c7fe6e7fd685eff855448038278e2e..b074e85f3b1c8876ef2ce1d49635c52e0b013a0b 100644 (file)
@@ -2,7 +2,7 @@ USING: ui.gadgets.buttons ui.gadgets.packs ui.gadgets ui
 nehe.2 nehe.3 nehe.4 nehe.5 kernel ;
 IN: nehe
 
-: nehe-window
+: nehe-window ( -- )
     [
         [
             "Nehe 2" [ drop run2 ] <bevel-button> gadget,
index 9336aa6b5b2eb52ce082c97b58c9f1b3472ac4ed..ccfe958fe017cf2ee824aaedf922d90e38602173 100644 (file)
@@ -3,12 +3,12 @@ IN: numbers-game
 
 : read-number ( -- n ) readln string>number ;
 
-: guess-banner
+: guess-banner ( -- )
     "I'm thinking of a number between 0 and 100." print ;
-: guess-prompt "Enter your guess: " write ;
-: too-high "Too high" print ;
-: too-low "Too low" print ;
-: correct "Correct - you win!" print ;
+: guess-prompt ( -- ) "Enter your guess: " write ;
+: too-high ( -- ) "Too high" print ;
+: too-low ( -- ) "Too low" print ;
+: correct ( -- ) "Correct - you win!" print ;
 
 : inexact-guess ( actual guess -- )
      < [ too-high ] [ too-low ] if ;
@@ -22,6 +22,6 @@ IN: numbers-game
     dup guess-prompt read-number judge-guess
     [ numbers-game-loop ] [ drop ] if ;
 
-: numbers-game number-to-guess numbers-game-loop ;
+: numbers-game ( -- ) number-to-guess numbers-game-loop ;
 
 MAIN: numbers-game
index 38d61a88230865db461b22ae6293f62691741ec4..2a8959b4a08e16e2823124b599eecae173e90d96 100644 (file)
@@ -245,7 +245,7 @@ SYMBOL: init
     f init set-global
   ] unless ;
 
-: <uint-array> "ALuint" <c-array> ;
+: <uint-array> ( n -- byte-array ) "ALuint" <c-array> ;
 
 : gen-sources ( size -- seq )
   dup <uint-array> 2dup alGenSources swap c-uint-array> ;
diff --git a/extra/opengl/gadgets/gadgets-tests.factor b/extra/opengl/gadgets/gadgets-tests.factor
new file mode 100644 (file)
index 0000000..499ec97
--- /dev/null
@@ -0,0 +1,4 @@
+IN: opengl.gadgets.tests
+USING: tools.test opengl.gadgets ;
+
+\ render* must-infer
index 1a15283048fc585042254e8416975809b9778770..9e670c04ab675278edd5491ec9de89be828c3d7e 100644 (file)
@@ -2,10 +2,57 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: locals math.functions math namespaces
 opengl.gl accessors kernel opengl ui.gadgets
+fry assocs
 destructors sequences ui.render colors ;
 IN: opengl.gadgets
 
-TUPLE: texture-gadget bytes format dim tex ;
+TUPLE: texture-gadget ;
+
+GENERIC: render* ( gadget -- texture dims )
+GENERIC: cache-key* ( gadget -- key )
+
+M: texture-gadget cache-key* ;
+
+SYMBOL: textures
+SYMBOL: refcounts
+
+: init-cache ( symbol -- )
+    dup get [ drop ] [ H{ } clone swap set-global ] if ;
+
+textures init-cache
+refcounts init-cache
+
+: refcount-change ( gadget quot -- )
+    >r cache-key* refcounts get
+    [ [ 0 ] unless* ] r> compose change-at ;
+
+TUPLE: cache-entry tex dims ;
+C: <entry> cache-entry
+
+: make-entry ( gadget -- entry )
+    dup render* <entry>
+    [ swap cache-key* textures get set-at ] keep ;
+
+: get-entry ( gadget -- {texture,dims} )
+    dup cache-key* textures get at
+    [ nip ] [ make-entry ] if* ;
+
+: get-dims ( gadget -- dims )
+    get-entry dims>> ;
+
+: get-texture ( gadget -- texture )
+    get-entry tex>> ;
+
+: release-texture ( gadget -- )
+    cache-key* textures get delete-at*
+    [ tex>> delete-texture ] [ drop ] if ;
+
+M: texture-gadget graft* ( gadget -- ) [ 1+ ] refcount-change ;
+
+M: texture-gadget ungraft* ( gadget -- )
+    dup [ 1- ] refcount-change
+    dup cache-key* refcounts get at
+    zero? [ release-texture ] [ drop ] if ;
 
 : 2^-ceil ( x -- y )
     dup 2 < [ 2 * ] [ 1- log2 1+ 2^ ] if ; foldable flushable
@@ -13,29 +60,29 @@ TUPLE: texture-gadget bytes format dim tex ;
 : 2^-bounds ( dim -- dim' )
     [ 2^-ceil ] map ; foldable flushable
 
-: <texture-gadget> ( bytes format dim -- gadget )
-    texture-gadget construct-gadget
-        swap >>dim
-        swap >>format
-        swap >>bytes ;
-
-:: render ( gadget -- )
+:: (render-bytes) ( dims bytes format texture -- )
     GL_ENABLE_BIT [
         GL_TEXTURE_2D glEnable
-        GL_TEXTURE_2D gadget tex>> glBindTexture
+        GL_TEXTURE_2D texture glBindTexture
         GL_TEXTURE_2D
         0
         GL_RGBA
-        gadget dim>> 2^-bounds first2
+        dims 2^-bounds first2
         0
-        gadget format>>
+        format
         GL_UNSIGNED_BYTE
-        gadget bytes>>
+        bytes
         glTexImage2D
         init-texture
         GL_TEXTURE_2D 0 glBindTexture
     ] do-attribs ;
 
+: render-bytes ( dims bytes format -- texture )
+    gen-texture [ (render-bytes) ] keep ;
+
+: render-bytes* ( dims bytes format -- texture dims )
+    pick >r render-bytes r> ;
+
 :: four-corners ( dim -- )
     [let* | w [ dim first ]
             h [ dim second ]
@@ -54,19 +101,12 @@ M: texture-gadget draw-gadget* ( gadget -- )
             white gl-color
             1.0 -1.0 glPixelZoom
             GL_TEXTURE_2D glEnable
-            GL_TEXTURE_2D over tex>> glBindTexture
+            GL_TEXTURE_2D over get-texture glBindTexture
             GL_QUADS [
-                dim>> four-corners
+                get-dims four-corners
             ] do-state
             GL_TEXTURE_2D 0 glBindTexture
         ] do-attribs
     ] with-translation ;
 
-M: texture-gadget graft* ( gadget -- )
-    gen-texture >>tex [ render ]
-    [ f >>bytes f >>format drop ] bi ;
-
-M: texture-gadget ungraft* ( gadget -- )
-    tex>> delete-texture ;
-
-M: texture-gadget pref-dim* ( gadget -- dim ) dim>> ;
+M: texture-gadget pref-dim* ( gadget -- dim ) get-dims ;
index 79470131f3f4514842c0e4c71e3c9cb30fd08769..5fed70925349b75da2a11516ff98aabbec83abde 100755 (executable)
@@ -8,9 +8,11 @@ math.parser opengl.gl opengl.glu combinators arrays sequences
 splitting words byte-arrays assocs combinators.lib ;
 IN: opengl
 
-: coordinates [ first2 ] bi@ ;
+: coordinates ( point1 point2 -- x1 y2 x2 y2 )
+    [ first2 ] bi@ ;
 
-: fix-coordinates [ first2 [ >fixnum ] bi@ ] bi@ ;
+: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 )
+    [ first2 [ >fixnum ] bi@ ] bi@ ;
 
 : gl-color ( color -- ) first4 glColor4d ; inline
 
@@ -73,7 +75,8 @@ MACRO: all-enabled-client-state ( seq quot -- )
     >r { 0.5 0.5 } v+ r> { 0.5 0.5 } v- gl-fill-rect
     GL_FRONT_AND_BACK GL_FILL glPolygonMode ;
 
-: (gl-poly) [ [ gl-vertex ] each ] do-state ;
+: (gl-poly) ( points state -- )
+    [ [ gl-vertex ] each ] do-state ;
 
 : gl-fill-poly ( points -- )
     dup length 2 > GL_POLYGON GL_LINES ? (gl-poly) ;
@@ -81,13 +84,17 @@ MACRO: all-enabled-client-state ( seq quot -- )
 : gl-poly ( points -- )
     GL_LINE_LOOP (gl-poly) ;
 
-: circle-steps dup length v/n 2 pi * v*n ;
+: circle-steps ( steps -- angles )
+    dup length v/n 2 pi * v*n ;
 
-: unit-circle dup [ sin ] map swap [ cos ] map ;
+: unit-circle ( angles -- points1 points2 )
+    [ [ sin ] map ] [ [ cos ] map ] bi ;
 
-: adjust-points [ [ 1 + 0.5 * ] map ] bi@ ;
+: adjust-points ( points1 points2 -- points1' points2' )
+    [ [ 1 + 0.5 * ] map ] bi@ ;
 
-: scale-points zip [ v* ] with map [ v+ ] with map ;
+: scale-points ( loc dim points1 points2 -- points )
+    zip [ v* ] with map [ v+ ] with map ;
 
 : circle-points ( loc dim steps -- points )
     circle-steps unit-circle adjust-points scale-points ;
@@ -161,9 +168,9 @@ TUPLE: sprite loc dim dim2 dlist texture ;
 : <sprite> ( loc dim dim2 -- sprite )
     f f sprite boa ;
 
-: sprite-size2 sprite-dim2 first2 ;
+: sprite-size2 ( sprite -- w h ) sprite-dim2 first2 ;
 
-: sprite-width sprite-dim first ;
+: sprite-width ( sprite -- w ) sprite-dim first ;
 
 : gray-texture ( sprite pixmap -- id )
     gen-texture [
index 03343820db648539bf6a3e9945c5a7cbacdd46d7..b2dbda7d2e48ece3126a7630fe50f8713321b7a0 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors byte-arrays kernel debugger sequences namespaces math
 math.order combinators init alien alien.c-types alien.strings libc
-continuations destructors debugger inspector
+continuations destructors debugger inspector splitting
 locals unicode.case
 openssl.libcrypto openssl.libssl
 io.backend io.ports io.files io.encodings.8-bit io.sockets.secure
@@ -105,7 +105,7 @@ TUPLE: openssl-context < secure-context aliens ;
 
 TUPLE: bio handle disposed ;
 
-: <bio> f bio boa ;
+: <bio> ( handle -- bio ) f bio boa ;
 
 M: bio dispose* handle>> BIO_free ssl-error ;
 
@@ -121,7 +121,7 @@ M: bio dispose* handle>> BIO_free ssl-error ;
 
 TUPLE: rsa handle disposed ;
 
-: <rsa> f rsa boa ;
+: <rsa> ( handle -- rsa ) f rsa boa ;
 
 M: rsa dispose* handle>> RSA_free ;
 
@@ -188,8 +188,12 @@ M: ssl-handle dispose*
     [ 256 X509_NAME_get_text_by_NID ] keep
     swap -1 = [ drop f ] [ latin1 alien>string ] if ;
 
+: common-names-match? ( expected actual -- ? )
+    [ >lower ] bi@ "*." ?head [ tail? ] [ = ] if ;
+
 : check-common-name ( host ssl-handle -- )
-    SSL_get_peer_certificate common-name 2dup [ >lower ] bi@ =
+    SSL_get_peer_certificate common-name
+    2dup common-names-match?
     [ 2drop ] [ common-name-verify-error ] if ;
 
 M: openssl check-certificate ( host ssl -- )
index fa35534439c0d3f67bd93c4d700cc87fe0645dfc..ac7080d4517d60f8b9a1e51e44864fe7d2480e25 100755 (executable)
@@ -4,7 +4,7 @@ USING: classes inference inference.dataflow io kernel
 kernel.private math.parser namespaces optimizer prettyprint
 prettyprint.backend sequences words arrays match macros
 assocs sequences.private optimizer.specializers generic
-combinators sorting math quotations ;
+combinators sorting math quotations accessors ;
 IN: optimizer.debugger
 
 ! A simple tool for turning dataflow IR into quotations, for
@@ -33,11 +33,11 @@ M: comment pprint*
 
 : effect-str ( node -- str )
     [
-        " " over node-in-d values%
-        " r: " over node-in-r values%
+        " " over in-d>> values%
+        " r: " over in-r>> values%
         " --" %
-        " " over node-out-d values%
-        " r: " swap node-out-r values%
+        " " over out-d>> values%
+        " r: " swap out-r>> values%
     ] "" make rest ;
 
 MACRO: match-choose ( alist -- )
@@ -63,18 +63,19 @@ MATCH-VARS: ?a ?b ?c ;
     } match-choose ;
 
 M: #shuffle node>quot
-    dup node-in-d over node-out-d pretty-shuffle
+    dup [ in-d>> ] [ out-d>> ] bi pretty-shuffle
     [ , ] [ >r drop t r> ] if*
     dup effect-str "#shuffle: " prepend comment, ;
 
-: pushed-literals node-out-d [ value-literal literalize ] map ;
+: pushed-literals ( node -- seq )
+    out-d>> [ value-literal literalize ] map ;
 
 M: #push node>quot nip pushed-literals % ;
 
 DEFER: dataflow>quot
 
 : #call>quot ( ? node -- )
-    dup node-param dup ,
+    dup param>> dup ,
     [ dup effect-str ] [ "empty call" ] if comment, ;
 
 M: #call node>quot #call>quot ;
@@ -83,38 +84,38 @@ M: #call-label node>quot #call>quot ;
 
 M: #label node>quot
     [
-        dup node-param literalize ,
+        dup param>> literalize ,
         dup #label-loop? "#loop: " "#label: " ?
-        over node-param word-name append comment,
+        over param>> word-name append comment,
     ] 2keep
     node-child swap dataflow>quot , \ call ,  ;
 
 M: #if node>quot
     [ "#if" comment, ] 2keep
-    node-children swap [ dataflow>quot ] curry map %
+    children>> swap [ dataflow>quot ] curry map %
     \ if , ;
 
 M: #dispatch node>quot
     [ "#dispatch" comment, ] 2keep
-    node-children swap [ dataflow>quot ] curry map ,
+    children>> swap [ dataflow>quot ] curry map ,
     \ dispatch , ;
 
-M: #>r node>quot nip node-in-d length \ >r <array> % ;
+M: #>r node>quot nip in-d>> length \ >r <array> % ;
 
-M: #r> node>quot nip node-out-d length \ r> <array> % ;
+M: #r> node>quot nip out-d>> length \ r> <array> % ;
 
 M: object node>quot
     [
         dup class word-name %
         " " %
-        dup node-param unparse %
+        dup param>> unparse %
         " " %
         dup effect-str %
     ] "" make comment, ;
 
 : (dataflow>quot) ( ? node -- )
     dup [
-        2dup node>quot node-successor (dataflow>quot)
+        2dup node>quot successor>> (dataflow>quot)
     ] [
         2drop
     ] if ;
@@ -145,7 +146,7 @@ SYMBOL: node-count
         0 swap [
             >r 1+ r>
             dup #call? [
-                node-param {
+                param>> {
                     { [ dup "intrinsics" word-prop over "if-intrinsics" word-prop or ] [ intrinsics-called ] }
                     { [ dup generic? ] [ generics-called ] }
                     { [ dup method-body? ] [ methods-called ] }
index 60b83819d5ee911debb97440549833eb7b26739d..865ece333c53ec34a225661032e692065dc6c3f8 100755 (executable)
@@ -7,7 +7,7 @@ IN: optimizer.report
     >r optimize-1\r
     [ r> 1+ count-optimization-passes ] [ drop r> ] if ;\r
 \r
-: results\r
+: results ( seq -- )\r
     [ [ second ] prepose compare ] curry sort 20 tail*\r
     print\r
     standard-table-style\r
@@ -15,7 +15,7 @@ IN: optimizer.report
         [ [ [ pprint-cell ] each ] with-row ] each\r
     ] tabular-output ;\r
 \r
-: optimizer-report\r
+: optimizer-report ( -- )\r
     all-words [ compiled? ] filter\r
     [\r
         dup [\r
index 729dcba56a6f592aa27b35373827147d7add518c..7a32fdbf50944a3acfc76bcabde281dee58c29e3 100644 (file)
@@ -1,7 +1,7 @@
 
 USING: kernel namespaces
        math math.constants math.functions math.matrices math.vectors
-       sequences splitting self math.trig ;
+       sequences splitting grouping self math.trig ;
 
 IN: ori
 
index 889052c3857606dc8c2a479db8b5a96f6844153b..1ff5328ee024585f7157c17aa578480126403f0b 100644 (file)
@@ -4,12 +4,13 @@
 ! pangocairo bindings, from pango/pangocairo.h
 USING: cairo.ffi alien.c-types math
 alien.syntax system combinators alien
+memoize
 arrays pango pango.fonts ;
 IN: pango.cairo
 
 << "pangocairo" {
-!    { [ os winnt? ] [ "libpangocairo-1.dll" ] }
-!    { [ os macosx? ] [ "libpangocairo.dylib" ] }
+    { [ os winnt? ] [ "libpangocairo-1.0-0.dll" ] }
+    { [ os macosx? ] [ "libpangocairo-1.0.0.dylib" ] }
     { [ os unix? ] [ "libpangocairo-1.0.so" ] }
 } cond "cdecl" add-library >>
 
@@ -92,40 +93,26 @@ pango_cairo_error_underline_path ( cairo_t* cr, double x, double y, double width
 ! Higher level words and combinators
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-USING: destructors accessors namespaces kernel cairo ;
-
-TUPLE: pango-layout alien ;
-C: <pango-layout> pango-layout
-M: pango-layout dispose ( alien -- ) alien>> g_object_unref ;
-
-: layout ( -- pango-layout ) pango-layout get ;
+USING: pango.layouts
+destructors accessors namespaces kernel cairo ;
 
 : (with-pango) ( layout quot -- )
     >r alien>> pango-layout r> with-variable ; inline
 
-: with-pango ( quot -- )
-    cr pango_cairo_create_layout <pango-layout> swap
-    [ (with-pango) ] curry with-disposal ; inline
+: with-pango-cairo ( quot -- )
+    cr pango_cairo_create_layout swap with-layout ; inline
 
-: pango-layout-get-pixel-size ( layout -- width height )
-    0 <int> 0 <int> [ pango_layout_get_pixel_size ] 2keep
-    [ *int ] bi@ ;
+MEMO: dummy-cairo ( -- cr )
+    CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create cairo_create ;
 
 : dummy-pango ( quot -- )
-    >r CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create
-    r> [ with-pango ] curry with-cairo-from-surface ; inline
+    >r dummy-cairo cairo r> [ with-pango-cairo ] curry with-variable ; inline
 
 : layout-size ( quot -- dim )
     [ layout pango-layout-get-pixel-size 2array ] compose dummy-pango ; inline
 
-: layout-font ( str -- )
-    pango_font_description_from_string
-    dup zero? [ "pango: not a valid font." throw ] when
-    layout over pango_layout_set_font_description
-    pango_font_description_free ;
-
-: layout-text ( str -- )
-    layout swap -1 pango_layout_set_text ;
+: show-layout ( -- )
+    cr layout pango_cairo_show_layout ;
 
 : families ( -- families )
     pango_cairo_font_map_get_default list-families ;
index 9e8a99515e42167ef510844ab551a33bfebb78fa..a21affc36472ab4e205284d5b34cf4262dd82986 100644 (file)
@@ -1,30 +1,27 @@
 ! Copyright (C) 2008 Matthew Willis.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: pango.cairo cairo cairo.ffi cairo.gadgets
-alien.c-types kernel math ;
+USING: pango.cairo pango.gadgets
+cairo.gadgets arrays namespaces
+fry accessors ui.gadgets
+sequences opengl.gadgets
+kernel pango.layouts ;
+
 IN: pango.cairo.gadgets
 
-: (pango-gadget) ( setup show -- gadget )
-    [ drop layout-size ]
-    [ compose [ with-pango ] curry <cairo-gadget> ] 2bi ;
+TUPLE: pango-cairo-gadget < pango-gadget ;
 
-: <pango-gadget> ( quot -- gadget )
-    [ cr layout pango_cairo_show_layout ] (pango-gadget) ;
+SINGLETON: pango-cairo-backend
+pango-cairo-backend pango-backend set-global
 
-USING: prettyprint sequences ui.gadgets.panes
-threads io.backend io.encodings.utf8 io.files ;
-: hello-pango ( -- )
-    50 [ 6 + ] map [
-        "Sans " swap unparse append
-        [ 
-            cr 0 1 0.2 0.6 cairo_set_source_rgba
-            layout-font "今日は、 Pango!" layout-text
-        ] curry
-        <pango-gadget> gadget. yield
-    ] each
-    [ 
-        "resource:extra/pango/cairo/gadgets/gadgets.factor"
-        normalize-path utf8 file-contents layout-text
-    ] <pango-gadget> gadget. ;
+M: pango-cairo-backend construct-pango
+    pango-cairo-gadget construct-gadget ;
 
-MAIN: hello-pango
+: setup-layout ( gadget -- quot )
+    [ font>> ] [ text>> ] bi
+    '[ , layout-font , layout-text ] ; inline
+
+M: pango-cairo-gadget render* ( gadget -- ) 
+    setup-layout [ layout-size dup ]
+    [ 
+        '[ [ @ show-layout ] with-pango-cairo ]
+    ] bi render-cairo render-bytes* ;
diff --git a/extra/pango/cairo/samples/samples.factor b/extra/pango/cairo/samples/samples.factor
new file mode 100644 (file)
index 0000000..f081650
--- /dev/null
@@ -0,0 +1,18 @@
+! Copyright (C) 2008 Matthew Willis.
+! See http://factorcode.org/license.txt for BSD license.
+USING: prettyprint sequences ui.gadgets.panes
+pango.cairo.gadgets math kernel cairo cairo.ffi
+pango.cairo pango.gadgets tools.time namespaces assocs
+threads io.backend io.encodings.utf8 io.files ;
+
+IN: pango.cairo.samples
+
+: hello-pango ( -- )
+    "monospace 10" "resource:extra/pango/cairo/gadgets/gadgets.factor"
+    normalize-path utf8 file-contents
+    <pango> gadget. ;
+
+: time-pango ( -- )
+    [ hello-pango ] time ;
+
+MAIN: time-pango
diff --git a/extra/pango/ft2/ft2.factor b/extra/pango/ft2/ft2.factor
new file mode 100644 (file)
index 0000000..5ce59c7
--- /dev/null
@@ -0,0 +1,56 @@
+USING: alien alien.c-types
+math kernel byte-arrays freetype
+opengl.gadgets accessors pango
+ui.gadgets memoize
+arrays sequences libc opengl.gl
+system combinators alien.syntax
+pango.layouts ;
+IN: pango.ft2
+
+<< "pangoft2" {
+    { [ os winnt? ] [ "libpangocairo-1.0-0.dll" ] }
+    { [ os macosx? ] [ "libpangocairo-1.0.0.dylib" ] }
+    { [ os unix? ] [ "libpangoft2-1.0.so" ] }
+} cond "cdecl" add-library >>
+
+LIBRARY: pangoft2
+
+FUNCTION: PangoFontMap*
+pango_ft2_font_map_new ( ) ;
+
+FUNCTION: PangoContext*
+pango_ft2_font_map_create_context ( PangoFT2FontMap* fontmap ) ;
+
+FUNCTION: void
+pango_ft2_render_layout ( FT_Bitmap* bitmap, PangoLayout* layout, int x, int y ) ;
+
+: 4*-ceil ( n -- k*4 )
+    3 + 4 /i 4 * ;
+
+: <ft-bitmap> ( width height -- ft-bitmap )
+    swap dup
+    2dup * 4*-ceil
+    "uchar" malloc-array
+    256
+    FT_PIXEL_MODE_GRAY
+    "FT_Bitmap" <c-object> dup >r
+    {
+        set-FT_Bitmap-rows
+        set-FT_Bitmap-width
+        set-FT_Bitmap-pitch
+        set-FT_Bitmap-buffer
+        set-FT_Bitmap-num_grays
+        set-FT_Bitmap-pixel_mode
+    } set-slots r> ;
+
+: render-layout ( layout -- dims alien )
+    [ 
+        pango-layout-get-pixel-size
+        2array dup 2^-bounds first2 <ft-bitmap> dup
+    ] [ 0 0 pango_ft2_render_layout ] bi FT_Bitmap-buffer ;
+
+MEMO: ft2-context ( -- PangoContext* )
+    pango_ft2_font_map_new pango_ft2_font_map_create_context ;
+
+: with-ft2-layout ( quot -- )
+    ft2-context pango_layout_new swap with-layout ; inline
diff --git a/extra/pango/ft2/gadgets/gadgets.factor b/extra/pango/ft2/gadgets/gadgets.factor
new file mode 100644 (file)
index 0000000..43ddc95
--- /dev/null
@@ -0,0 +1,20 @@
+! Copyright (C) 2008 Matthew Willis.
+! See http://factorcode.org/license.txt for BSD license.
+USING: pango.ft2 pango.gadgets opengl.gadgets
+accessors kernel opengl.gl libc
+sequences namespaces ui.gadgets pango.layouts ;
+IN: pango.ft2.gadgets
+
+TUPLE: pango-ft2-gadget < pango-gadget ;
+
+SINGLETON: pango-ft2-backend
+pango-ft2-backend pango-backend set-global
+
+M: pango-ft2-backend construct-pango
+    pango-ft2-gadget construct-gadget ;
+
+M: pango-ft2-gadget render*
+    [
+        [ text>> layout-text ] [ font>> layout-font ] bi
+        layout render-layout
+    ] with-ft2-layout [ GL_ALPHA render-bytes* ] keep free ;
diff --git a/extra/pango/gadgets/gadgets.factor b/extra/pango/gadgets/gadgets.factor
new file mode 100644 (file)
index 0000000..f9442a4
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Matthew Willis.
+! See http://factorcode.org/license.txt for BSD license.
+USING: opengl.gadgets kernel
+arrays
+accessors ;
+
+IN: pango.gadgets
+
+TUPLE: pango-gadget < texture-gadget text font ;
+
+M: pango-gadget cache-key* [ font>> ] [ text>> ] bi 2array ;
+
+SYMBOL: pango-backend
+HOOK: construct-pango pango-backend ( -- gadget )
+
+: <pango> ( font text -- gadget )
+    construct-pango
+        swap >>text
+        swap >>font ;
diff --git a/extra/pango/layouts/layouts.factor b/extra/pango/layouts/layouts.factor
new file mode 100644 (file)
index 0000000..71317ce
--- /dev/null
@@ -0,0 +1,30 @@
+USING: alien alien.c-types 
+math
+destructors accessors namespaces
+pango kernel ;
+IN: pango.layouts
+
+: pango-layout-get-pixel-size ( layout -- width height )
+    0 <int> 0 <int> [ pango_layout_get_pixel_size ] 2keep
+    [ *int ] bi@ ;
+
+TUPLE: pango-layout alien ;
+C: <pango-layout> pango-layout
+M: pango-layout dispose ( alien -- ) alien>> g_object_unref ;
+
+: layout ( -- pango-layout ) pango-layout get ;
+
+: (with-layout) ( pango-layout quot -- )
+    >r alien>> pango-layout r> with-variable ; inline
+
+: with-layout ( layout quot -- )
+    >r <pango-layout> r> [ (with-layout) ] curry with-disposal ; inline
+
+: layout-font ( str -- )
+    pango_font_description_from_string
+    dup zero? [ "pango: not a valid font." throw ] when
+    layout over pango_layout_set_font_description
+    pango_font_description_free ;
+
+: layout-text ( str -- )
+    layout swap -1 pango_layout_set_text ;
index 3549d9abb4a4fd705bc1b84be971326ed11766f9..be5c257cb0c581f52ae30f617a95749cf68ec603 100644 (file)
@@ -9,8 +9,8 @@ IN: pango
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 << "pango" {
-!    { [ os winnt? ] [ "libpango-1.dll" ] }
-!    { [ os macosx? ] [ "libpango.dylib" ] }
+    { [ os winnt? ] [ "libpango-1.0-0.dll" ] }
+    { [ os macosx? ] [ "libpango-1.0.0.dylib" ] }
     { [ os unix? ] [ "libpango-1.0.so" ] }
 } cond "cdecl" add-library >>
 
@@ -18,6 +18,9 @@ LIBRARY: pango
 
 : PANGO_SCALE 1024 ;
 
+FUNCTION: PangoLayout*
+pango_layout_new ( PangoContext* context ) ;
+
 FUNCTION: void
 pango_layout_set_text ( PangoLayout* layout, char* text, int length ) ;
 
index 41171ce822618d08f6718c0093840e19f83684bb..c08243d17dba80712815e35b2a9df94f6d662c0d 100755 (executable)
@@ -23,4 +23,4 @@ HELP: any-char-parser
     "from the input string. The value consumed is the "
     "result of the parse." }
 { $examples
-{ $example "USING: lazy-lists parser-combinators prettyprint ;" "\"foo\" any-char-parser parse-1 ." "102" } } ;
+{ $example "USING: lists.lazy parser-combinators prettyprint ;" "\"foo\" any-char-parser parse-1 ." "102" } } ;
index 2dd3fd911cf348a8207b449ea68bad169894abf4..70698daa0bf73bc8fe501b69980d853b8c590d5a 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel lazy-lists tools.test strings math
+USING: kernel lists.lazy tools.test strings math
 sequences parser-combinators arrays math.parser unicode.categories ;
 IN: parser-combinators.tests
 
index 9537a0c88c7d4cb5afb9e389de2c1dab83d025c9..2414c1ced38ab4d91123f32b4e89ecc18490a407 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2004 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lazy-lists promises kernel sequences strings math
+USING: lists lists.lazy promises kernel sequences strings math
 arrays splitting quotations combinators namespaces
 unicode.case unicode.categories sequences.deep ;
 IN: parser-combinators
@@ -147,8 +147,8 @@ TUPLE: and-parser parsers ;
             >r parse-result-parsed r>
             [ parse-result-parsed 2array ] keep
             parse-result-unparsed <parse-result>
-        ] lmap-with
-    ] lmap-with lconcat ;
+        ] lazy-map-with
+    ] lazy-map-with lconcat ;
 
 M: and-parser parse ( input parser -- list )
     #! Parse 'input' by sequentially combining the
@@ -171,7 +171,7 @@ M: or-parser parse ( input parser1 -- list )
     #! of parser1 and parser2 being applied to the same
     #! input. This implements the choice parsing operator.
     or-parser-parsers 0 swap seq>list
-    [ parse ] lmap-with lconcat ;
+    [ parse ] lazy-map-with lconcat ;
 
 : left-trim-slice ( string -- string )
     #! Return a new string without any leading whitespace
@@ -216,7 +216,7 @@ M: apply-parser parse ( input parser -- result )
     -rot parse [
         [ parse-result-parsed swap call ] keep
         parse-result-unparsed <parse-result>
-    ] lmap-with ;
+    ] lazy-map-with ;
 
 TUPLE: some-parser p1 ;
 
index 78b731f5b0e0089e12b3bd2b3bebcd50181be3f9..fdf32bddb14c06c6481e3d41da12f9a0f561e4bf 100755 (executable)
@@ -11,7 +11,7 @@ HELP: 'digit'
     "the input string. The numeric value of the digit "
     " consumed is the result of the parse." }
 { $examples
-{ $example "USING: lazy-lists parser-combinators parser-combinators.simple prettyprint ;" "\"123\" 'digit' parse-1 ." "1" } } ;
+{ $example "USING: lists.lazy parser-combinators parser-combinators.simple prettyprint ;" "\"123\" 'digit' parse-1 ." "1" } } ;
 
 HELP: 'integer'
 { $values 
@@ -21,7 +21,7 @@ HELP: 'integer'
     "the input string. The numeric value of the integer "
     " consumed is the result of the parse." }
 { $examples
-{ $example "USING: lazy-lists parser-combinators parser-combinators.simple prettyprint ;" "\"123\" 'integer' parse-1 ." "123" } } ;
+{ $example "USING: lists.lazy parser-combinators parser-combinators.simple prettyprint ;" "\"123\" 'integer' parse-1 ." "123" } } ;
 HELP: 'string'
 { $values 
   { "parser" "a parser object" } }
@@ -30,7 +30,7 @@ HELP: 'string'
     "quotations from the input string. The string value "
     " consumed is the result of the parse." }
 { $examples
-{ $example "USING: lazy-lists parser-combinators parser-combinators.simple prettyprint ;" "\"\\\"foo\\\"\" 'string' parse-1 ." "\"foo\"" } } ;
+{ $example "USING: lists.lazy parser-combinators parser-combinators.simple prettyprint ;" "\"\\\"foo\\\"\" 'string' parse-1 ." "\"foo\"" } } ;
 
 HELP: 'bold'
 { $values 
@@ -62,6 +62,6 @@ HELP: comma-list
     "'element' should be a parser that can parse the elements. The "
     "result of the parser is a sequence of the parsed elements." }
 { $examples
-{ $example "USING: lazy-lists parser-combinators parser-combinators.simple prettyprint ;" "\"1,2,3,4\" 'integer' comma-list parse-1 ." "{ 1 2 3 4 }" } } ;
+{ $example "USING: lists.lazy parser-combinators parser-combinators.simple prettyprint ;" "\"1,2,3,4\" 'integer' comma-list parse-1 ." "{ 1 2 3 4 }" } } ;
 
 { $see-also 'digit' 'integer' 'string' 'bold' 'italic' comma-list } related-words
index 745442610cc3cbab4bfb12d61182d877c8c03676..f7a696ca35cd1ac269d324d7f2cefc8f2e9b494b 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2006 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel strings math sequences lazy-lists words
+USING: kernel strings math sequences lists.lazy words
 math.parser promises parser-combinators unicode.categories ;
 IN: parser-combinators.simple
 
diff --git a/extra/persistent-vectors/authors.txt b/extra/persistent-vectors/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/persistent-vectors/persistent-vectors-docs.factor b/extra/persistent-vectors/persistent-vectors-docs.factor
new file mode 100644 (file)
index 0000000..dc9222c
--- /dev/null
@@ -0,0 +1,53 @@
+USING: help.markup help.syntax kernel math sequences ;
+IN: persistent-vectors
+
+HELP: new-nth
+{ $values { "val" object } { "i" integer } { "seq" sequence } { "seq'" sequence } }
+{ $contract "Persistent analogue of " { $link set-nth } ". Outputs a new sequence with the " { $snippet "i" } "th element replaced by " { $snippet "val" } "." }
+{ $notes "This operation runs in " { $snippet "O(log_32 n)" } " time on " { $link persistent-vector } " instances and " { $snippet "O(n)" } " time on all other sequences." } ;
+
+HELP: ppush
+{ $values { "val" object } { "seq" sequence } { "seq'" sequence } }
+{ $contract "Persistent analogue of " { $link push } ". Outputs a new sequence with all elements of " { $snippet "seq" } " together with " { $snippet "val" } " added at the end." }
+{ $notes "This operation runs in amortized " { $snippet "O(1)" } " time on " { $link persistent-vector } " instances and " { $snippet "O(n)" } " time on all other sequences." } ;
+
+HELP: ppop
+{ $values { "seq" sequence } { "seq'" sequence } }
+{ $contract "Persistent analogue of " { $link pop* } ". Outputs a new sequence with all elements of " { $snippet "seq" } " except for the final element." }
+{ $notes "This operation runs in amortized " { $snippet "O(1)" } " time on " { $link persistent-vector } " instances and " { $snippet "O(n)" } " time on all other sequences." } ;
+
+HELP: PV{
+{ $syntax "elements... }" }
+{ $description "Parses a literal " { $link persistent-vector } "." } ;
+
+HELP: >persistent-vector
+{ $values { "seq" sequence } { "pvec" persistent-vector } }
+{ $description "Creates a " { $link persistent-vector } " with the same elements as " { $snippet "seq" } "." } ;
+
+HELP: persistent-vector
+{ $class-description "The class of persistent vectors." } ;
+
+HELP: pempty
+{ $values { "pvec" persistent-vector } }
+{ $description "Outputs an empty " { $link persistent-vector } "." } ;
+
+ARTICLE: "persistent-vectors" "Persistent vectors"
+"A " { $emphasis "persistent vector" } " differs from an ordinary vector (" { $link "vectors" } ") in that it is immutable, and all operations yield new persistent vectors instead of modifying inputs. Unlike immutable operations on ordinary sequences, persistent vector operations are efficient and run in sub-linear time."
+$nl
+"The class of persistent vectors:"
+{ $subsection persistent-vector }
+"Persistent vectors support the immutable sequence protocol, namely as " { $link length } " and " { $link nth } ", and so can be used with most sequence words (" { $link "sequences" } ")."
+$nl
+"In addition to standard sequence operations, persistent vectors implement efficient operations specific to them. They run in sub-linear time on persistent vectors, and degrate to linear-time algorithms on ordinary sequences:"
+{ $subsection new-nth }
+{ $subsection ppush }
+{ $subsection ppop }
+"The empty persistent vector, used for building up all other persistent vectors:"
+{ $subsection pempty }
+"Converting a sequence into a persistent vector:"
+{ $subsection >persistent-vector }
+"Persistent vectors have a literal syntax:"
+{ $subsection POSTPONE: PV{ }
+"This implementation of persistent vectors is based on the " { $snippet "clojure.lang.PersistentVector" } " class from Rich Hickey's Clojure language for the JVM (" { $url "http://clojure.org" } ")." ;
+
+ABOUT: "persistent-vectors"
diff --git a/extra/persistent-vectors/persistent-vectors-tests.factor b/extra/persistent-vectors/persistent-vectors-tests.factor
new file mode 100644 (file)
index 0000000..f871c95
--- /dev/null
@@ -0,0 +1,63 @@
+IN: persistent-vectors.tests
+USING: tools.test persistent-vectors sequences kernel arrays
+random namespaces vectors math math.order ;
+
+\ new-nth must-infer
+\ ppush must-infer
+\ ppop must-infer
+
+[ 0 ] [ pempty length ] unit-test
+
+[ 1 ] [ 3 pempty ppush length ] unit-test
+
+[ 3 ] [ 3 pempty ppush first ] unit-test
+
+[ PV{ 3 1 3 3 7 } ] [
+    pempty { 3 1 3 3 7 } [ swap ppush ] each
+] unit-test
+
+[ { 3 1 3 3 7 } ] [
+    pempty { 3 1 3 3 7 } [ swap ppush ] each >array
+] unit-test
+
+{ 100 1060 2000 10000 100000 1000000 } [
+    [ t ] swap [ dup >persistent-vector sequence= ] curry unit-test
+] each
+
+[ ] [ 10000 [ drop 16 random-bits ] PV{ } map-as "1" set ] unit-test
+[ ] [ "1" get >vector "2" set ] unit-test
+
+[ t ] [
+    3000 [
+        drop
+        16 random-bits 10000 random
+        [ "1" [ new-nth ] change ]
+        [ "2" [ new-nth ] change ] 2bi
+        "1" get "2" get sequence=
+    ] all?
+] unit-test
+
+[ PV{ } ppop ] [ empty-error? ] must-fail-with
+
+[ t ] [ PV{ 3 } ppop empty? ] unit-test
+
+[ PV{ 3 7 } ] [ PV{ 3 7 6 } ppop ] unit-test
+
+[ PV{ 3 7 6 5 } ] [ 5 PV{ 3 7 6 } ppush ] unit-test
+
+[ ] [ PV{ } "1" set ] unit-test
+[ ] [ V{ } clone "2" set ] unit-test
+
+[ t ] [
+    100 [
+        drop
+        100 random [
+            16 random-bits [ "1" [ ppush ] change ] [ "2" get push ] bi
+        ] times
+        100 random "1" get length min [
+            "1" [ ppop ] change
+            "2" get pop*
+        ] times
+        "1" get "2" get sequence=
+    ] all?
+] unit-test
diff --git a/extra/persistent-vectors/persistent-vectors.factor b/extra/persistent-vectors/persistent-vectors.factor
new file mode 100644 (file)
index 0000000..f9f4b68
--- /dev/null
@@ -0,0 +1,183 @@
+! Based on Clojure's PersistentVector by Rich Hickey.
+
+USING: math accessors kernel sequences.private sequences arrays
+combinators parser prettyprint.backend ;
+IN: persistent-vectors
+
+ERROR: empty-error pvec ;
+
+GENERIC: ppush ( val seq -- seq' )
+
+M: sequence ppush swap suffix ;
+
+GENERIC: ppop ( seq -- seq' )
+
+M: sequence ppop 1 head* ;
+
+GENERIC: new-nth ( val i seq -- seq' )
+
+M: sequence new-nth clone [ set-nth ] keep ;
+
+TUPLE: persistent-vector count root tail ;
+
+M: persistent-vector length count>> ;
+
+<PRIVATE
+
+TUPLE: node children level ;
+
+: node-size 32 ; inline
+
+: node-mask node-size mod ; inline
+
+: node-shift -5 * shift ; inline
+
+: node-nth ( i node -- obj )
+    [ node-mask ] [ children>> ] bi* nth ; inline
+
+: body-nth ( i node -- i node' )
+    dup level>> [
+        dupd [ level>> node-shift ] keep node-nth
+    ] times ; inline
+
+: tail-offset ( pvec -- n )
+    [ count>> ] [ tail>> children>> length ] bi - ;
+
+M: persistent-vector nth-unsafe
+    2dup tail-offset >=
+    [ tail>> ] [ root>> body-nth ] if
+    node-nth ;
+
+: node-add ( val node -- node' )
+    clone [ ppush ] change-children ;
+
+: ppush-tail ( val pvec -- pvec' )
+    [ node-add ] change-tail ;
+
+: full? ( node -- ? )
+    children>> length node-size = ;
+
+: 1node ( val level -- node )
+    node new
+        swap >>level
+        swap 1array >>children ;
+
+: 2node ( first second -- node )
+    [ 2array ] [ drop level>> 1+ ] 2bi node boa ;
+
+: new-child ( new-child node -- node' expansion/f )
+    dup full? [ tuck level>> 1node ] [ node-add f ] if ;
+
+: new-last ( val seq -- seq' )
+    [ length 1- ] keep new-nth ;
+
+: node-set-last ( child node -- node' )
+    clone [ new-last ] change-children ;
+
+: (ppush-new-tail) ( tail node -- node' expansion/f )
+    dup level>> 1 = [
+        new-child
+    ] [
+        tuck children>> peek (ppush-new-tail)
+        [ swap new-child ] [ swap node-set-last f ] ?if
+    ] if ;
+
+: do-expansion ( pvec root expansion/f -- pvec )
+    [ 2node ] when* >>root ;
+
+: ppush-new-tail ( val pvec -- pvec' )
+    [ ] [ tail>> ] [ root>> ] tri
+    (ppush-new-tail) do-expansion
+    swap 0 1node >>tail ;
+
+M: persistent-vector ppush ( val pvec -- pvec' )
+    clone
+    dup tail>> full?
+    [ ppush-new-tail ] [ ppush-tail ] if
+    [ 1+ ] change-count ;
+
+: node-set-nth ( val i node -- node' )
+    clone [ new-nth ] change-children ;
+
+: node-change-nth ( i node quot -- node' )
+    [ clone ] dip [
+        [ clone ] dip [ change-nth ] 2keep drop
+    ] curry change-children ; inline
+
+: (new-nth) ( val i node -- node' )
+    dup level>> 0 = [
+        [ node-mask ] dip node-set-nth
+    ] [
+        [ dupd level>> node-shift node-mask ] keep
+        [ (new-nth) ] node-change-nth
+    ] if ;
+
+M: persistent-vector new-nth ( obj i pvec -- pvec' )
+    2dup count>> = [ nip ppush ] [
+        clone
+        2dup tail-offset >= [
+            [ node-mask ] dip
+            [ node-set-nth ] change-tail
+        ] [
+            [ (new-nth) ] change-root
+        ] if
+    ] if ;
+
+: (ppop-contraction) ( node -- node' tail' )
+    clone [ unclip-last swap ] change-children swap ;
+
+: ppop-contraction ( node -- node' tail' )
+    [ (ppop-contraction) ] [ level>> 1 = ] bi swap and ;
+
+: (ppop-new-tail) ( root -- root' tail' )
+    dup level>> 1 > [
+        dup children>> peek (ppop-new-tail) over children>> empty?
+        [ 2drop ppop-contraction ] [ [ swap node-set-last ] dip ] if
+    ] [
+        ppop-contraction
+    ] if ;
+
+: ppop-tail ( pvec -- pvec' )
+    [ clone [ ppop ] change-children ] change-tail ;
+
+: ppop-new-tail ( pvec -- pvec' )
+    dup root>> (ppop-new-tail)
+    [
+        dup [ level>> 1 > ] [ children>> length 1 = ] bi and 
+        [ children>> first ] when
+    ] dip
+    [ >>root ] [ >>tail ] bi* ;
+
+PRIVATE>
+
+: pempty ( -- pvec )
+    T{ persistent-vector f 0 T{ node f { } 1 } T{ node f { } 0 } } ; inline
+
+M: persistent-vector ppop ( pvec -- pvec' )
+    dup count>> {
+        { 0 [ empty-error ] }
+        { 1 [ drop pempty ] }
+        [
+            [
+                clone
+                dup tail>> children>> length 1 >
+                [ ppop-tail ] [ ppop-new-tail ] if
+            ] dip 1- >>count
+        ]
+    } case ;
+
+M: persistent-vector like
+    drop pempty [ swap ppush ] reduce ;
+
+M: persistent-vector equal?
+    over persistent-vector? [ sequence= ] [ 2drop f ] if ;
+
+: >persistent-vector ( seq -- pvec ) pempty like ; inline
+
+: PV{ \ } [ >persistent-vector ] parse-literal ; parsing
+
+M: persistent-vector pprint-delims drop \ PV{ \ } ;
+
+M: persistent-vector >pprint-sequence ;
+
+INSTANCE: persistent-vector immutable-sequence
diff --git a/extra/persistent-vectors/summary.txt b/extra/persistent-vectors/summary.txt
new file mode 100644 (file)
index 0000000..19f3f66
--- /dev/null
@@ -0,0 +1 @@
+Immutable vectors with O(log_32 n) random access and amortized O(1) push/pop
diff --git a/extra/persistent-vectors/tags.txt b/extra/persistent-vectors/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/extra/present/present.factor b/extra/present/present.factor
new file mode 100644 (file)
index 0000000..d3aec20
--- /dev/null
@@ -0,0 +1,17 @@
+USING: math math.parser calendar calendar.format strings words
+kernel effects ;
+IN: present
+
+GENERIC: present ( object -- string )
+
+M: real present number>string ;
+
+M: timestamp present timestamp>string ;
+
+M: string present ;
+
+M: word present word-name ;
+
+M: effect present effect>string ;
+
+M: f present drop "" ;
index 93754b69d1d95cc392850da38eb6df9ae3df940e..04686a8328766d133f6ab69558870f3e972e06a7 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lazy-lists math math.primes ;
+USING: lists math math.primes ;
 IN: project-euler.007
 
 ! http://projecteuler.net/index.php?section=problems&id=7
index 322c361ee0105c4555ab6fd04b8fb46abd98dfa3..a55c3ac1242a849874dd9a801ee8e88361137a46 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces project-euler.common sequences splitting ;
+USING: kernel namespaces project-euler.common sequences
+splitting grouping ;
 IN: project-euler.011
 
 ! http://projecteuler.net/index.php?section=problems&id=11
index dceb01bd16837ac2224dfa5cb774826c8c8d8b35..63a8e3e2c4a288b271683c9fecd0a60dedaf2993 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays ascii assocs hashtables io.encodings.ascii io.files kernel math
     math.parser namespaces sequences sequences.lib sequences.private sorting
-    splitting strings sets ;
+    splitting grouping strings sets ;
 IN: project-euler.059
 
 ! http://projecteuler.net/index.php?section=problems&id=59
index 11af1960ed9f09341f51b16cc6d4865eacc9351a..4e54a18f197794c4ce1e84f9f145dfc1abaf5fed 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel lazy-lists math.algebra math math.functions
+USING: arrays kernel lists lists.lazy math.algebra math math.functions
     math.order math.primes math.ranges project-euler.common sequences ;
 IN: project-euler.134
 
@@ -39,7 +39,7 @@ IN: project-euler.134
 PRIVATE>
 
 : euler134 ( -- answer )
-    0 5 lprimes-from uncons [ 1000000 > ] luntil
+    0 5 lprimes-from uncons swap [ 1000000 > ] luntil
     [ [ s + ] keep ] leach drop ;
 
 ! [ euler134 ] 10 ave-time
index 3ce6d3081951ac17b893aa10a2003a93f4c198aa..5810a03f80f6be65438e703f6e39857080389b52 100644 (file)
@@ -15,7 +15,7 @@ IN: qualified
     #! Syntax: QUALIFIED-WITH: vocab prefix
     scan scan define-qualified ; parsing
 
-: expect=> scan "=>" assert= ;
+: expect=> ( -- ) scan "=>" assert= ;
 
 : partial-vocab ( words name -- assoc )
     dupd [
index c882dd2b4d8f989577557e3517ad5a1bd8ce60e5..2a1af5323275ceac03db2578bd89b5bacd98e2dc 100644 (file)
@@ -1,5 +1,6 @@
 USING: kernel math tools.test namespaces random
-random.blum-blum-shub alien.c-types sequences splitting ;
+random.blum-blum-shub alien.c-types sequences splitting
+grouping ;
 IN: blum-blum-shub.tests
 
 [ 887708070 ] [
index 78ffaf5eeb9663ead1e016a56772849d81123b25..99e6b887c8706d35c1c00fcf315ec595c7916ba7 100755 (executable)
@@ -1,4 +1,4 @@
-USING: arrays combinators kernel lazy-lists math math.parser
+USING: arrays combinators kernel lists math math.parser
 namespaces parser parser-combinators parser-combinators.simple
 promises quotations sequences combinators.lib strings math.order
 assocs prettyprint.backend memoize unicode.case unicode.categories ;
@@ -23,9 +23,9 @@ SYMBOL: ignore-case?
 : or-predicates ( quots -- quot )
     [ \ dup prefix ] map [ [ t ] ] f short-circuit \ nip suffix ;
 
-: <@literal [ nip ] curry <@ ;
+: <@literal ( parser obj -- action ) [ nip ] curry <@ ;
 
-: <@delay [ curry ] curry <@ ;
+: <@delay ( parser quot -- action ) [ curry ] curry <@ ;
 
 PRIVATE>
 
@@ -135,10 +135,10 @@ PRIVATE>
     'posix-character-class' <|>
     'simple-escape' <|> &> ;
 
-: 'any-char'
+: 'any-char' ( -- parser )
     "." token [ drop t ] <@literal ;
 
-: 'char'
+: 'char' ( -- parser )
     'any-char' 'escape' 'ordinary-char' <|> <|> [ satisfy ] <@ ;
 
 DEFER: 'regexp'
diff --git a/extra/regexp2/regexp2-tests.factor b/extra/regexp2/regexp2-tests.factor
deleted file mode 100644 (file)
index 1fb3f61..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: kernel peg regexp2 sequences tools.test ;
-IN: regexp2.tests
-
-[ T{ parse-result f T{ slice f 3 3 "056" } 46 } ]
-    [ "056" 'octal' parse ] unit-test
diff --git a/extra/regexp2/regexp2.factor b/extra/regexp2/regexp2.factor
deleted file mode 100644 (file)
index f7023c7..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-USING: assocs combinators.lib kernel math math.parser
-namespaces peg unicode.case sequences unicode.categories
-memoize peg.parsers math.order ;
-USE: io
-USE: tools.walker
-IN: regexp2
-
-<PRIVATE
-    
-SYMBOL: ignore-case?
-
-: char=-quot ( ch -- quot )
-    ignore-case? get
-    [ ch>upper [ swap ch>upper = ] ] [ [ = ] ] if
-    curry ;
-    
-: char-between?-quot ( ch1 ch2 -- quot )
-    ignore-case? get
-    [ [ ch>upper ] bi@ [ >r >r ch>upper r> r> between? ] ]
-    [ [ between? ] ]
-    if 2curry ;
-    
-: or-predicates ( quots -- quot )
-    [ \ dup prefix ] map [ [ t ] ] f short-circuit \ nip suffix ;
-
-: literal-action [ nip ] curry action ;
-
-: delay-action [ curry ] curry action ;
-    
-PRIVATE>
-
-: ascii? ( n -- ? )
-    0 HEX: 7f between? ;
-    
-: octal-digit? ( n -- ? ) 
-    CHAR: 0 CHAR: 7 between? ;
-
-: hex-digit? ( n -- ? )
-    {
-        [ dup digit? ]
-        [ dup CHAR: a CHAR: f between? ]
-        [ dup CHAR: A CHAR: F between? ]
-    } || nip ;
-
-: control-char? ( n -- ? )
-    { [ dup 0 HEX: 1f between? ] [ dup HEX: 7f = ] } || nip ;
-
-: punct? ( n -- ? )
-    "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" member? ;
-
-: c-identifier-char? ( ch -- ? )
-    { [ dup alpha? ] [ dup CHAR: _ = ] } || nip ;
-
-: java-blank? ( n -- ? )
-    {
-        CHAR: \s
-        CHAR: \t CHAR: \n CHAR: \r
-        HEX: c HEX: 7 HEX: 1b
-    } member? ;
-
-: java-printable? ( n -- ? )
-    { [ dup alpha? ] [ dup punct? ] } || nip ;
-
-MEMO: 'ordinary-char' ( -- parser )
-    [ "\\^*+?|(){}[$" member? not ] satisfy
-    [ char=-quot ] action ;
-
-MEMO: 'octal-digit' ( -- parser ) [ octal-digit? ] satisfy ;
-
-MEMO: 'octal' ( -- parser )
-    "0" token hide 'octal-digit' 1 3 from-m-to-n 2seq
-    [ first oct> ] action ;
-
-MEMO: 'hex-digit' ( -- parser ) [ hex-digit? ] satisfy ;
-
-MEMO: 'hex' ( -- parser )
-    "x" token hide 'hex-digit' 2 exactly-n 2seq
-    "u" token hide 'hex-digit' 6 exactly-n 2seq 2choice
-    [ first hex> ] action ;
-
-: satisfy-tokens ( assoc -- parser )
-    [ >r token r> literal-action ] { } assoc>map choice ;
-
-MEMO: 'simple-escape-char' ( -- parser )
-    {
-        { "\\" CHAR: \\ }
-        { "t"  CHAR: \t }
-        { "n"  CHAR: \n }
-        { "r"  CHAR: \r }
-        { "f"  HEX: c   }
-        { "a"  HEX: 7   }
-        { "e"  HEX: 1b  }
-    } [ char=-quot ] assoc-map satisfy-tokens ;
-
-MEMO: 'predefined-char-class' ( -- parser )
-    {   
-        { "d" [ digit? ] } 
-        { "D" [ digit? not ] }
-        { "s" [ java-blank? ] } 
-        { "S" [ java-blank? not ] }
-        { "w" [ c-identifier-char? ] } 
-        { "W" [ c-identifier-char? not ] }
-    } satisfy-tokens ;
-
-MEMO: 'posix-character-class' ( -- parser )
-    {   
-        { "Lower" [ letter? ] }
-        { "Upper" [ LETTER? ] }
-        { "ASCII" [ ascii? ] }
-        { "Alpha" [ Letter? ] }
-        { "Digit" [ digit? ] }
-        { "Alnum" [ alpha? ] }
-        { "Punct" [ punct? ] }
-        { "Graph" [ java-printable? ] }
-        { "Print" [ java-printable? ] }
-        { "Blank" [ " \t" member? ] }
-        { "Cntrl" [ control-char? ] }
-        { "XDigit" [ hex-digit? ] }
-        { "Space" [ java-blank? ] }
-    } satisfy-tokens "p{" "}" surrounded-by ;
-
-MEMO: 'simple-escape' ( -- parser )
-    [
-        'octal' ,
-        'hex' ,
-        "c" token hide [ LETTER? ] satisfy 2seq ,
-        any-char ,
-    ] choice* [ char=-quot ] action ;
-
-MEMO: 'escape' ( -- parser )
-    "\\" token hide [
-        'simple-escape-char' ,
-        'predefined-char-class' ,
-        'posix-character-class' ,
-        'simple-escape' ,
-    ] choice* 2seq ;
-
-MEMO: 'any-char' ( -- parser )
-    "." token [ drop t ] literal-action ;
-
-MEMO: 'char' ( -- parser )
-    'any-char' 'escape' 'ordinary-char' 3choice [ satisfy ] action ;
-
-DEFER: 'regexp'
-
-TUPLE: group-result str ;
-
-C: <group-result> group-result
-
-MEMO: 'non-capturing-group' ( -- parser )
-    "?:" token hide 'regexp' ;
-
-MEMO: 'positive-lookahead-group' ( -- parser )
-    "?=" token hide 'regexp' [ ensure ] action ;
-
-MEMO: 'negative-lookahead-group' ( -- parser )
-    "?!" token hide 'regexp' [ ensure-not ] action ;
-
-MEMO: 'simple-group' ( -- parser )
-    'regexp' [ [ <group-result> ] action ] action ;
-
-MEMO: 'group' ( -- parser )
-    [
-        'non-capturing-group' ,
-        'positive-lookahead-group' ,
-        'negative-lookahead-group' ,
-        'simple-group' ,
-    ] choice* "(" ")" surrounded-by ;
-
-MEMO: 'range' ( -- parser )
-    any-char "-" token hide any-char 3seq
-    [ first2 char-between?-quot ] action ;
-
-MEMO: 'character-class-term' ( -- parser )
-    'range'
-    'escape'
-    [ "\\]" member? not ] satisfy [ char=-quot ] action
-    3choice ;
-
-MEMO: 'positive-character-class' ( -- parser )
-    ! todo
-    "]" token [ CHAR: ] = ] literal-action 'character-class-term' repeat0 2seq 
-    'character-class-term' repeat1 2choice [ or-predicates ] action ;
-
-MEMO: 'negative-character-class' ( -- parser )
-    "^" token hide 'positive-character-class' 2seq
-    [ [ not ] append ] action ;
-
-MEMO: 'character-class' ( -- parser )
-    'negative-character-class' 'positive-character-class' 2choice
-    "[" "]" surrounded-by [ satisfy ] action ;
-
-MEMO: 'escaped-seq' ( -- parser )
-    any-char repeat1
-    [ ignore-case? get token ] action "\\Q" "\\E" surrounded-by ;
-    
-MEMO: 'break' ( quot -- parser )
-    satisfy ensure
-    epsilon just 2choice ;
-    
-MEMO: 'break-escape' ( -- parser )
-    "$" token [ "\r\n" member? ] 'break' literal-action
-    "\\b" token [ blank? ] 'break' literal-action
-    "\\B" token [ blank? not ] 'break' literal-action
-    "\\z" token epsilon just literal-action 4choice ;
-    
-MEMO: 'simple' ( -- parser )
-    [
-        'escaped-seq' ,
-        'break-escape' ,
-        'group' ,
-        'character-class' ,
-        'char' ,
-    ] choice* ;
-
-MEMO: 'exactly-n' ( -- parser )
-    'integer' [ exactly-n ] delay-action ;
-
-MEMO: 'at-least-n' ( -- parser )
-    'integer' "," token hide 2seq [ at-least-n ] delay-action ;
-
-MEMO: 'at-most-n' ( -- parser )
-    "," token hide 'integer' 2seq [ at-most-n ] delay-action ;
-
-MEMO: 'from-m-to-n' ( -- parser )
-    'integer' "," token hide 'integer' 3seq
-    [ first2 from-m-to-n ] delay-action ;
-
-MEMO: 'greedy-interval' ( -- parser )
-    'exactly-n' 'at-least-n' 'at-most-n' 'from-m-to-n' 4choice ;
-
-MEMO: 'interval' ( -- parser )
-    'greedy-interval'
-    'greedy-interval' "?" token hide 2seq [ "reluctant {}" print ] action
-    'greedy-interval' "+" token hide 2seq [ "possessive {}" print ] action
-    3choice "{" "}" surrounded-by ;
-
-MEMO: 'repetition' ( -- parser )
-    [
-        ! Possessive
-        ! "*+" token [ <!*> ] literal-action ,
-        ! "++" token [ <!+> ] literal-action ,
-        ! "?+" token [ <!?> ] literal-action ,
-        ! Reluctant
-        ! "*?" token [ <(*)> ] literal-action ,
-        ! "+?" token [ <(+)> ] literal-action ,
-        ! "??" token [ <(?)> ] literal-action ,
-        ! Greedy
-        "*" token [ repeat0 ] literal-action ,
-        "+" token [ repeat1 ] literal-action ,
-        "?" token [ optional ] literal-action ,
-    ] choice* ;
-
-MEMO: 'dummy' ( -- parser )
-    epsilon [ ] literal-action ;
-
-! todo -- check the action
-! MEMO: 'term' ( -- parser )
-    ! 'simple'
-    ! 'repetition' 'interval' 'dummy' 3choice 2seq [ first2 call ] action
-    ! <!+> [ <and-parser> ] action ;
-
index f94c774943350e0799906cad2e200218f776c3ff..3537d2e719de6fb38af72b1ce17efa40aad9201a 100755 (executable)
@@ -85,7 +85,7 @@ IN: reports.noise
         { spread 2 }\r
     } at 0 or ;\r
 \r
-: vsum { 0 0 } [ v+ ] reduce ;\r
+: vsum ( pairs -- pair ) { 0 0 } [ v+ ] reduce ;\r
 \r
 GENERIC: noise ( obj -- pair )\r
 \r
@@ -105,7 +105,7 @@ M: quotation noise [ noise ] map vsum { 1/4 1/2 } v+ ;
 \r
 M: array noise [ noise ] map vsum ;\r
 \r
-: noise-factor / 100 * >integer ;\r
+: noise-factor ( x y -- z ) / 100 * >integer ;\r
 \r
 : quot-noise-factor ( quot -- n )\r
     #! For very short words, noise doesn't count so much\r
diff --git a/extra/rss/atom.xml b/extra/rss/atom.xml
deleted file mode 100644 (file)
index d019566..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-   <feed xmlns="http://www.w3.org/2005/Atom">
-     <title type="text">dive into mark</title>
-     <subtitle type="html">
-       A &lt;em&gt;lot&lt;/em&gt; of effort
-       went into making this effortless
-     </subtitle>
-     <updated>2005-07-31T12:29:29Z</updated>
-     <id>tag:example.org,2003:3</id>
-     <link rel="alternate" type="text/html"
-      hreflang="en" href="http://example.org/"/>
-     <link rel="self" type="application/atom+xml"
-      href="http://example.org/feed.atom"/>
-     <rights>Copyright (c) 2003, Mark Pilgrim</rights>
-     <generator uri="http://www.example.com/" version="1.0">
-       Example Toolkit
-     </generator>
-     <entry>
-       <title>Atom draft-07 snapshot</title>
-       <link rel="alternate" type="text/html"
-        href="http://example.org/2005/04/02/atom"/>
-       <link rel="enclosure" type="audio/mpeg" length="1337"
-        href="http://example.org/audio/ph34r_my_podcast.mp3"/>
-       <id>tag:example.org,2003:3.2397</id>
-       <updated>2005-07-31T12:29:29Z</updated>
-       <published>2003-12-13T08:29:29-04:00</published>
-       <author>
-         <name>Mark Pilgrim</name>
-         <uri>http://example.org/</uri>
-         <email>f8dy@example.com</email>
-       </author>
-       <contributor>
-         <name>Sam Ruby</name>
-       </contributor>
-       <contributor>
-         <name>Joe Gregorio</name>
-       </contributor>
-       <content type="xhtml" xml:lang="en"
-        xml:base="http://diveintomark.org/">
-         <div xmlns="http://www.w3.org/1999/xhtml">
-           <p><i>[Update: The Atom draft is finished.]</i></p>
-         </div>
-       </content>
-     </entry>
-   </feed>
diff --git a/extra/rss/authors.txt b/extra/rss/authors.txt
deleted file mode 100755 (executable)
index f990dd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Daniel Ehrenberg
diff --git a/extra/rss/readme.txt b/extra/rss/readme.txt
deleted file mode 100644 (file)
index 2e64b0d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-This library is a simple RSS2 parser and RSS reader web
-application. To run the web application you'll need to make sure you
-have the sqlite library working. This can be tested with
-
-  "contrib/sqlite" require
-  "contrib/sqlite" test-module
-
-Remember that to use "sqlite" you need to have done the following
-somewhere:
-
-  USE: alien
-  "sqlite" "/usr/lib/libsqlite3.so" "cdecl" add-library
-
-Replacing "libsqlite3.so" with the path to the sqlite shared library
-or DLL. I put this in my ~/.factor-rc.
-
-The RSS reader web application creates a database file called
-'rss-reader.db' in the same directory as the Factor executable when
-first started. This database contains all the feed information.
-
-To load the web application use:
-
-  "contrib/rss" require
-
-Fire up the web server and navigate to the URL:
-
-  http://localhost:8888/responder/maintain-feeds
-
-Add any RSS2 compatible feed. Use 'Update Feeds' to retrieve them and
-update the sqlite database with the feed contains. Use 'Database' to
-view the entries from the database for that feed.
-
diff --git a/extra/rss/rss-tests.factor b/extra/rss/rss-tests.factor
deleted file mode 100755 (executable)
index 0e6bb0b..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-USING: rss io kernel io.files tools.test io.encodings.utf8
-calendar ;
-IN: rss.tests
-
-: load-news-file ( filename -- feed )
-    #! Load an news syndication file and process it, returning
-    #! it as an feed tuple.
-    utf8 file-contents read-feed ;
-
-[ T{
-    feed
-    f
-    "Meerkat"
-    "http://meerkat.oreillynet.com"
-    {
-        T{
-            entry
-            f
-            "XML: A Disruptive Technology"
-            "http://c.moreover.com/click/here.pl?r123"
-            "\n      XML is placing increasingly heavy loads on the existing technical\n      infrastructure of the Internet.\n    "
-            f
-        }
-    }
-} ] [ "resource:extra/rss/rss1.xml" load-news-file ] unit-test
-[ T{
-    feed
-    f
-    "dive into mark"
-    "http://example.org/"
-    {
-        T{
-            entry
-            f
-            "Atom draft-07 snapshot"
-            "http://example.org/2005/04/02/atom"
-            "\n         <div xmlns=\"http://www.w3.org/1999/xhtml\">\n           <p><i>[Update: The Atom draft is finished.]</i></p>\n         </div>\n       "
-
-            T{ timestamp f 2003 12 13 8 29 29 T{ duration f 0 0 0 -4 0 0 } }
-        }
-    }
-} ] [ "resource:extra/rss/atom.xml" load-news-file ] unit-test
diff --git a/extra/rss/rss.factor b/extra/rss/rss.factor
deleted file mode 100644 (file)
index 5183af5..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-! Copyright (C) 2006 Chris Double, Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: xml.utilities kernel assocs xml.generator math.order
-    strings sequences xml.data xml.writer
-    io.streams.string combinators xml xml.entities io.files io
-    http.client namespaces xml.generator hashtables
-    calendar.format accessors continuations urls ;
-IN: rss
-
-: any-tag-named ( tag names -- tag-inside )
-    f -rot [ tag-named nip dup ] with find 2drop ;
-
-TUPLE: feed title link entries ;
-
-C: <feed> feed
-
-TUPLE: entry title link description pub-date ;
-
-C: <entry> entry
-
-: try-parsing-timestamp ( string -- timestamp )
-    [ rfc822>timestamp ] [ drop rfc3339>timestamp ] recover ;
-
-: rss1.0-entry ( tag -- entry )
-    {
-        [ "title" tag-named children>string ]
-        [ "link" tag-named children>string ]
-        [ "description" tag-named children>string ]
-        [
-            f "date" "http://purl.org/dc/elements/1.1/" <name>
-            tag-named dup [ children>string try-parsing-timestamp ] when
-        ]
-    } cleave <entry> ;
-
-: rss1.0 ( xml -- feed )
-    [
-        "channel" tag-named
-        [ "title" tag-named children>string ]
-        [ "link" tag-named children>string ] bi
-    ] [ "item" tags-named [ rss1.0-entry ] map ] bi
-    <feed> ;
-
-: rss2.0-entry ( tag -- entry )
-    {
-        [ "title" tag-named children>string ]
-        [ { "link" "guid" } any-tag-named children>string ]
-        [ "description" tag-named children>string ]
-        [
-            { "date" "pubDate" } any-tag-named
-            children>string try-parsing-timestamp
-        ]
-    } cleave <entry> ;
-
-: rss2.0 ( xml -- feed )
-    "channel" tag-named 
-    [ "title" tag-named children>string ]
-    [ "link" tag-named children>string ]
-    [ "item" tags-named [ rss2.0-entry ] map ]
-    tri <feed> ;
-
-: atom1.0-entry ( tag -- entry )
-    {
-        [ "title" tag-named children>string ]
-        [ "link" tag-named "href" swap at ]
-        [
-            { "content" "summary" } any-tag-named
-            dup tag-children [ string? not ] contains?
-            [ tag-children [ write-chunk ] with-string-writer ]
-            [ children>string ] if
-        ]
-        [
-            { "published" "updated" "issued" "modified" } 
-            any-tag-named children>string try-parsing-timestamp
-        ]
-    } cleave <entry> ;
-
-: atom1.0 ( xml -- feed )
-    [ "title" tag-named children>string ]
-    [ "link" tag-named "href" swap at ]
-    [ "entry" tags-named [ atom1.0-entry ] map ]
-    tri <feed> ;
-
-: xml>feed ( xml -- feed )
-    dup name-tag {
-        { "RDF" [ rss1.0 ] }
-        { "rss" [ rss2.0 ] }
-        { "feed" [ atom1.0 ] }
-    } case ;
-
-: read-feed ( string -- feed )
-    [ string>xml xml>feed ] with-html-entities ;
-
-: download-feed ( url -- feed )
-    #! Retrieve an news syndication file, return as a feed tuple.
-    http-get read-feed ;
-
-! Atom generation
-: simple-tag, ( content name -- )
-    [ , ] tag, ;
-
-: simple-tag*, ( content name attrs -- )
-    [ , ] tag*, ;
-
-: entry, ( entry -- )
-    "entry" [
-        dup title>> "title" { { "type" "html" } } simple-tag*,
-        "link" over link>> dup url? [ url>string ] when "href" associate contained*,
-        dup pub-date>> timestamp>rfc3339 "published" simple-tag,
-        description>> [ "content" { { "type" "html" } } simple-tag*, ] when*
-    ] tag, ;
-
-: feed>xml ( feed -- xml )
-    "feed" { { "xmlns" "http://www.w3.org/2005/Atom" } } [
-        dup title>> "title" simple-tag,
-        "link" over link>> dup url? [ url>string ] when "href" associate contained*,
-        entries>> [ entry, ] each
-    ] make-xml* ;
diff --git a/extra/rss/rss1.xml b/extra/rss/rss1.xml
deleted file mode 100644 (file)
index 78a253b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> 
-
-<rdf:RDF 
-  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
-  xmlns:dc="http://purl.org/dc/elements/1.1/"
-  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
-  xmlns:co="http://purl.org/rss/1.0/modules/company/"
-  xmlns:ti="http://purl.org/rss/1.0/modules/textinput/"
-  xmlns="http://purl.org/rss/1.0/"
-> 
-
-  <channel rdf:about="http://meerkat.oreillynet.com/?_fl=rss1.0">
-    <title>Meerkat</title>
-    <link>http://meerkat.oreillynet.com</link>
-    <description>Meerkat: An Open Wire Service</description>
-    <dc:publisher>The O'Reilly Network</dc:publisher>
-    <dc:creator>Rael Dornfest (mailto:rael@oreilly.com)</dc:creator>
-    <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
-    <dc:date>2000-01-01T12:00+00:00</dc:date>
-    <sy:updatePeriod>hourly</sy:updatePeriod>
-    <sy:updateFrequency>2</sy:updateFrequency>
-    <sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
-
-    <image rdf:resource="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg" />
-
-    <items>
-      <rdf:Seq>
-        <rdf:li resource="http://c.moreover.com/click/here.pl?r123" />
-      </rdf:Seq>
-    </items>
-
-    <textinput rdf:resource="http://meerkat.oreillynet.com" />
-
-  </channel>
-
-  <image rdf:about="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg">
-    <title>Meerkat Powered!</title>
-    <url>http://meerkat.oreillynet.com/icons/meerkat-powered.jpg</url>
-    <link>http://meerkat.oreillynet.com</link>
-  </image>
-
-  <item rdf:about="http://c.moreover.com/click/here.pl?r123">
-    <title>XML: A Disruptive Technology</title> 
-    <link>http://c.moreover.com/click/here.pl?r123</link>
-    <dc:description>
-      XML is placing increasingly heavy loads on the existing technical
-      infrastructure of the Internet.
-    </dc:description>
-    <dc:publisher>The O'Reilly Network</dc:publisher>
-    <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
-    <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
-    <dc:subject>XML</dc:subject>
-    <co:name>XML.com</co:name>
-    <co:market>NASDAQ</co:market>
-    <co:symbol>XML</co:symbol>
-  </item> 
-
-  <textinput rdf:about="http://meerkat.oreillynet.com">
-    <title>Search Meerkat</title>
-    <description>Search Meerkat's RSS Database...</description>
-    <name>s</name>
-    <link>http://meerkat.oreillynet.com/</link>
-    <ti:function>search</ti:function>
-    <ti:inputType>regex</ti:inputType>
-  </textinput>
-
-</rdf:RDF>
diff --git a/extra/rss/summary.txt b/extra/rss/summary.txt
deleted file mode 100755 (executable)
index b65787a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-RSS 1.0, 2.0 and Atom feed parser
index 5c34b7315b10b64d620451e1689fa82e3727e58a..265cd5b59220b170023ca6298f13200a5f52dfeb 100755 (executable)
@@ -102,9 +102,9 @@ MACRO: firstn ( n -- )
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: ,, building get peek push ;
-: v, V{ } clone , ;
-: ,v building get dup peek empty? [ dup pop* ] when drop ;
+: ,, ( obj -- ) building get peek push ;
+: v, ( -- ) V{ } clone , ;
+: ,v ( -- ) building get dup peek empty? [ dup pop* ] when drop ;
 
 : monotonic-split ( seq quot -- newseq )
     [
index b58253381cb1085eac99a0c82ff8818a0d70be11..1c8b4fcbb30b76df5006af3a194256c11575c3c8 100755 (executable)
@@ -53,7 +53,7 @@ IN: slides
         gadget.
     ] ($block) ;
 
-: page-theme
+: page-theme ( gadget -- )
     T{ gradient f { { 0.8 0.8 1.0 1.0 } { 0.8 1.0 1.0 1.0 } } }
     swap set-gadget-interior ;
 
index 8fdc0e07a4cf04cdf61a9a2429accc93c856276a..16a13eafe851dddebd4276a8bdc17511663efa71 100755 (executable)
@@ -23,7 +23,7 @@ LOG: log-smtp-connection NOTICE ( addrspec -- )
         call
     ] with-client ; inline
 
-: crlf "\r\n" write ;
+: crlf ( -- ) "\r\n" write ;
 
 : command ( string -- ) write crlf flush ;
 
index 3f1d91d84cff6066a0df901b6dccd9909aba3946..4c83c646416fced30f47fa64de190707baa7a40f 100755 (executable)
@@ -11,8 +11,8 @@ IN: state-machine
 
 TUPLE: state place data ;
 
-TUPLE: missing-state ;
-: missing-state \ missing-state new throw ;
+ERROR: missing-state ;
+
 M: missing-state error.
     drop "Missing state" print ;
 
index b41d7f5023865356dca6406d6c0bafae6eb1bb87..af005b4abe43c9cd20b4e372a22f074b78c83fbf 100644 (file)
@@ -48,7 +48,7 @@ M: expected summary ( obj -- str )
     ] with-string-writer ;\r
 \r
 TUPLE: unexpected-end < parsing-error ;\r
-: unexpected-end \ unexpected-end parsing-error throw ;\r
+: unexpected-end ( -- * ) \ unexpected-end parsing-error throw ;\r
 M: unexpected-end summary ( obj -- str )\r
     [\r
         call-next-method write\r
@@ -56,7 +56,7 @@ M: unexpected-end summary ( obj -- str )
     ] with-string-writer ;\r
 \r
 TUPLE: missing-close < parsing-error ;\r
-: missing-close \ missing-close parsing-error throw ;\r
+: missing-close ( -- * ) \ missing-close parsing-error throw ;\r
 M: missing-close summary ( obj -- str )\r
     [\r
         call-next-method write\r
@@ -111,7 +111,7 @@ SYMBOL: prolog-data
     [ dup get-char = ] take-until nip ;\r
 \r
 TUPLE: not-enough-characters < parsing-error ;\r
-: not-enough-characters\r
+: not-enough-characters ( -- * )\r
     \ not-enough-characters parsing-error throw ;\r
 M: not-enough-characters summary ( obj -- str )\r
     [\r
index 1cb82253b1d5ef884be8b856be4d4e2debf0918b..93b1804e36dc8856e032ef93231ad632103208ee 100644 (file)
@@ -6,12 +6,12 @@ IN: sudoku
 SYMBOL: solutions
 SYMBOL: board
 
-: pair+ swapd + >r + r> ;
+: pair+ ( a b c d -- a+b c+d ) swapd + >r + r> ;
 
-: row board get nth ;
-: board> row nth ;
-: >board row set-nth ;
-: f>board f -rot >board ;
+: row ( n -- row ) board get nth ;
+: board> ( m n -- x ) row nth ;
+: >board ( row m n -- ) row set-nth ;
+: f>board ( m n -- ) f -rot >board ;
 
 : row-contains? ( n y -- ? ) row member? ;
 : col-contains? ( n x -- ? ) board get swap <column> member? ;
diff --git a/extra/syndication/authors.txt b/extra/syndication/authors.txt
new file mode 100755 (executable)
index 0000000..89b32ce
--- /dev/null
@@ -0,0 +1,3 @@
+Daniel Ehrenberg
+Chris Double
+Slava Pestov
diff --git a/extra/syndication/readme.txt b/extra/syndication/readme.txt
new file mode 100644 (file)
index 0000000..2e64b0d
--- /dev/null
@@ -0,0 +1,32 @@
+This library is a simple RSS2 parser and RSS reader web
+application. To run the web application you'll need to make sure you
+have the sqlite library working. This can be tested with
+
+  "contrib/sqlite" require
+  "contrib/sqlite" test-module
+
+Remember that to use "sqlite" you need to have done the following
+somewhere:
+
+  USE: alien
+  "sqlite" "/usr/lib/libsqlite3.so" "cdecl" add-library
+
+Replacing "libsqlite3.so" with the path to the sqlite shared library
+or DLL. I put this in my ~/.factor-rc.
+
+The RSS reader web application creates a database file called
+'rss-reader.db' in the same directory as the Factor executable when
+first started. This database contains all the feed information.
+
+To load the web application use:
+
+  "contrib/rss" require
+
+Fire up the web server and navigate to the URL:
+
+  http://localhost:8888/responder/maintain-feeds
+
+Add any RSS2 compatible feed. Use 'Update Feeds' to retrieve them and
+update the sqlite database with the feed contains. Use 'Database' to
+view the entries from the database for that feed.
+
diff --git a/extra/syndication/summary.txt b/extra/syndication/summary.txt
new file mode 100755 (executable)
index 0000000..b65787a
--- /dev/null
@@ -0,0 +1 @@
+RSS 1.0, 2.0 and Atom feed parser
diff --git a/extra/syndication/syndication-tests.factor b/extra/syndication/syndication-tests.factor
new file mode 100755 (executable)
index 0000000..73541e7
--- /dev/null
@@ -0,0 +1,45 @@
+USING: syndication io kernel io.files tools.test io.encodings.utf8
+calendar urls ;
+IN: syndication.tests
+
+\ download-feed must-infer
+\ feed>xml must-infer
+
+: load-news-file ( filename -- feed )
+    #! Load an news syndication file and process it, returning
+    #! it as an feed tuple.
+    utf8 file-contents read-feed ;
+
+[ T{
+    feed
+    f
+    "Meerkat"
+    URL" http://meerkat.oreillynet.com"
+    {
+        T{
+            entry
+            f
+            "XML: A Disruptive Technology"
+            URL" http://c.moreover.com/click/here.pl?r123"
+            "\n      XML is placing increasingly heavy loads on the existing technical\n      infrastructure of the Internet.\n    "
+            f
+        }
+    }
+} ] [ "resource:extra/syndication/test/rss1.xml" load-news-file ] unit-test
+[ T{
+    feed
+    f
+    "dive into mark"
+    URL" http://example.org/"
+    {
+        T{
+            entry
+            f
+            "Atom draft-07 snapshot"
+            URL" http://example.org/2005/04/02/atom"
+            "\n         <div xmlns=\"http://www.w3.org/1999/xhtml\">\n           <p><i>[Update: The Atom draft is finished.]</i></p>\n         </div>\n       "
+
+            T{ timestamp f 2003 12 13 8 29 29 T{ duration f 0 0 0 -4 0 0 } }
+        }
+    }
+} ] [ "resource:extra/syndication/test/atom.xml" load-news-file ] unit-test
diff --git a/extra/syndication/syndication.factor b/extra/syndication/syndication.factor
new file mode 100644 (file)
index 0000000..12beaf4
--- /dev/null
@@ -0,0 +1,135 @@
+! Copyright (C) 2006 Chris Double, Daniel Ehrenberg.
+! Portions copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: xml.utilities kernel assocs xml.generator math.order
+    strings sequences xml.data xml.writer
+    io.streams.string combinators xml xml.entities io.files io
+    http.client namespaces xml.generator hashtables
+    calendar.format accessors continuations urls present ;
+IN: syndication
+
+: any-tag-named ( tag names -- tag-inside )
+    f -rot [ tag-named nip dup ] with find 2drop ;
+
+TUPLE: feed title url entries ;
+
+: <feed> ( -- feed ) feed new ;
+
+TUPLE: entry title url description date ;
+
+: set-entries ( feed entries -- feed )
+    [ dup url>> ] dip
+    [ [ derive-url ] change-url ] with map
+    >>entries ;
+
+: <entry> ( -- entry ) entry new ;
+
+: try-parsing-timestamp ( string -- timestamp )
+    [ rfc822>timestamp ] [ drop rfc3339>timestamp ] recover ;
+
+: rss1.0-entry ( tag -- entry )
+    entry new
+    swap {
+        [ "title" tag-named children>string >>title ]
+        [ "link" tag-named children>string >url >>url ]
+        [ "description" tag-named children>string >>description ]
+        [
+            f "date" "http://purl.org/dc/elements/1.1/" <name>
+            tag-named dup [ children>string try-parsing-timestamp ] when
+            >>date
+        ]
+    } cleave ;
+
+: rss1.0 ( xml -- feed )
+    feed new
+    swap [
+        "channel" tag-named
+        [ "title" tag-named children>string >>title ]
+        [ "link" tag-named children>string >url >>url ] bi
+    ] [ "item" tags-named [ rss1.0-entry ] map set-entries ] bi ;
+
+: rss2.0-entry ( tag -- entry )
+    entry new
+    swap {
+        [ "title" tag-named children>string >>title ]
+        [ { "link" "guid" } any-tag-named children>string >url >>url ]
+        [ "description" tag-named children>string >>description ]
+        [
+            { "date" "pubDate" } any-tag-named
+            children>string try-parsing-timestamp >>date
+        ]
+    } cleave ;
+
+: rss2.0 ( xml -- feed )
+    feed new
+    swap
+    "channel" tag-named 
+    [ "title" tag-named children>string >>title ]
+    [ "link" tag-named children>string >url >>url ]
+    [ "item" tags-named [ rss2.0-entry ] map set-entries ]
+    tri ;
+
+: atom1.0-entry ( tag -- entry )
+    entry new
+    swap {
+        [ "title" tag-named children>string >>title ]
+        [ "link" tag-named "href" swap at >url >>url ]
+        [
+            { "content" "summary" } any-tag-named
+            dup tag-children [ string? not ] contains?
+            [ tag-children [ write-chunk ] with-string-writer ]
+            [ children>string ] if >>description
+        ]
+        [
+            { "published" "updated" "issued" "modified" } 
+            any-tag-named children>string try-parsing-timestamp
+            >>date
+        ]
+    } cleave ;
+
+: atom1.0 ( xml -- feed )
+    feed new
+    swap
+    [ "title" tag-named children>string >>title ]
+    [ "link" tag-named "href" swap at >url >>url ]
+    [ "entry" tags-named [ atom1.0-entry ] map set-entries ]
+    tri ;
+
+: xml>feed ( xml -- feed )
+    dup name-tag {
+        { "RDF" [ rss1.0 ] }
+        { "rss" [ rss2.0 ] }
+        { "feed" [ atom1.0 ] }
+    } case ;
+
+: read-feed ( string -- feed )
+    [ string>xml xml>feed ] with-html-entities ;
+
+: download-feed ( url -- feed )
+    #! Retrieve an news syndication file, return as a feed tuple.
+    http-get read-feed ;
+
+! Atom generation
+: simple-tag, ( content name -- )
+    [ , ] tag, ;
+
+: simple-tag*, ( content name attrs -- )
+    [ , ] tag*, ;
+
+: entry, ( entry -- )
+    "entry" [
+        {
+            [ title>> "title" { { "type" "html" } } simple-tag*, ]
+            [ url>> present "href" associate "link" swap contained*, ]
+            [ date>> timestamp>rfc3339 "published" simple-tag, ]
+            [ description>> [ "content" { { "type" "html" } } simple-tag*, ] when* ]
+        } cleave
+    ] tag, ;
+
+: feed>xml ( feed -- xml )
+    "feed" { { "xmlns" "http://www.w3.org/2005/Atom" } } [
+        [ title>> "title" simple-tag, ]
+        [ url>> present "href" associate "link" swap contained*, ]
+        [ entries>> [ entry, ] each ]
+        tri
+    ] make-xml* ;
diff --git a/extra/syndication/tags.txt b/extra/syndication/tags.txt
new file mode 100644 (file)
index 0000000..c077218
--- /dev/null
@@ -0,0 +1 @@
+web
diff --git a/extra/syndication/test/atom.xml b/extra/syndication/test/atom.xml
new file mode 100644 (file)
index 0000000..d019566
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+   <feed xmlns="http://www.w3.org/2005/Atom">
+     <title type="text">dive into mark</title>
+     <subtitle type="html">
+       A &lt;em&gt;lot&lt;/em&gt; of effort
+       went into making this effortless
+     </subtitle>
+     <updated>2005-07-31T12:29:29Z</updated>
+     <id>tag:example.org,2003:3</id>
+     <link rel="alternate" type="text/html"
+      hreflang="en" href="http://example.org/"/>
+     <link rel="self" type="application/atom+xml"
+      href="http://example.org/feed.atom"/>
+     <rights>Copyright (c) 2003, Mark Pilgrim</rights>
+     <generator uri="http://www.example.com/" version="1.0">
+       Example Toolkit
+     </generator>
+     <entry>
+       <title>Atom draft-07 snapshot</title>
+       <link rel="alternate" type="text/html"
+        href="http://example.org/2005/04/02/atom"/>
+       <link rel="enclosure" type="audio/mpeg" length="1337"
+        href="http://example.org/audio/ph34r_my_podcast.mp3"/>
+       <id>tag:example.org,2003:3.2397</id>
+       <updated>2005-07-31T12:29:29Z</updated>
+       <published>2003-12-13T08:29:29-04:00</published>
+       <author>
+         <name>Mark Pilgrim</name>
+         <uri>http://example.org/</uri>
+         <email>f8dy@example.com</email>
+       </author>
+       <contributor>
+         <name>Sam Ruby</name>
+       </contributor>
+       <contributor>
+         <name>Joe Gregorio</name>
+       </contributor>
+       <content type="xhtml" xml:lang="en"
+        xml:base="http://diveintomark.org/">
+         <div xmlns="http://www.w3.org/1999/xhtml">
+           <p><i>[Update: The Atom draft is finished.]</i></p>
+         </div>
+       </content>
+     </entry>
+   </feed>
diff --git a/extra/syndication/test/rss1.xml b/extra/syndication/test/rss1.xml
new file mode 100644 (file)
index 0000000..78a253b
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?> 
+
+<rdf:RDF 
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+  xmlns:dc="http://purl.org/dc/elements/1.1/"
+  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+  xmlns:co="http://purl.org/rss/1.0/modules/company/"
+  xmlns:ti="http://purl.org/rss/1.0/modules/textinput/"
+  xmlns="http://purl.org/rss/1.0/"
+> 
+
+  <channel rdf:about="http://meerkat.oreillynet.com/?_fl=rss1.0">
+    <title>Meerkat</title>
+    <link>http://meerkat.oreillynet.com</link>
+    <description>Meerkat: An Open Wire Service</description>
+    <dc:publisher>The O'Reilly Network</dc:publisher>
+    <dc:creator>Rael Dornfest (mailto:rael@oreilly.com)</dc:creator>
+    <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
+    <dc:date>2000-01-01T12:00+00:00</dc:date>
+    <sy:updatePeriod>hourly</sy:updatePeriod>
+    <sy:updateFrequency>2</sy:updateFrequency>
+    <sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
+
+    <image rdf:resource="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg" />
+
+    <items>
+      <rdf:Seq>
+        <rdf:li resource="http://c.moreover.com/click/here.pl?r123" />
+      </rdf:Seq>
+    </items>
+
+    <textinput rdf:resource="http://meerkat.oreillynet.com" />
+
+  </channel>
+
+  <image rdf:about="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg">
+    <title>Meerkat Powered!</title>
+    <url>http://meerkat.oreillynet.com/icons/meerkat-powered.jpg</url>
+    <link>http://meerkat.oreillynet.com</link>
+  </image>
+
+  <item rdf:about="http://c.moreover.com/click/here.pl?r123">
+    <title>XML: A Disruptive Technology</title> 
+    <link>http://c.moreover.com/click/here.pl?r123</link>
+    <dc:description>
+      XML is placing increasingly heavy loads on the existing technical
+      infrastructure of the Internet.
+    </dc:description>
+    <dc:publisher>The O'Reilly Network</dc:publisher>
+    <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
+    <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
+    <dc:subject>XML</dc:subject>
+    <co:name>XML.com</co:name>
+    <co:market>NASDAQ</co:market>
+    <co:symbol>XML</co:symbol>
+  </item> 
+
+  <textinput rdf:about="http://meerkat.oreillynet.com">
+    <title>Search Meerkat</title>
+    <description>Search Meerkat's RSS Database...</description>
+    <name>s</name>
+    <link>http://meerkat.oreillynet.com/</link>
+    <ti:function>search</ti:function>
+    <ti:inputType>regex</ti:inputType>
+  </textinput>
+
+</rdf:RDF>
index 1f4eb556dc09ce6bf83e39ab4e152c3b9ff0893e..5522dd9bcbded816d3d89ac7ada9c6be254388c1 100644 (file)
@@ -54,7 +54,7 @@ TUPLE: tax-table single married ;
 : <tax-table> ( single married class -- obj )
     >r tax-table boa r> construct-delegate ;
 
-: tax-bracket-range dup second swap first - ;
+: tax-bracket-range ( pair -- n ) dup second swap first - ;
 
 : tax-bracket ( tax salary triples -- tax salary )
     [ [ tax-bracket-range min ] keep third * + ] 2keep
index 644a9be1b52e829b4bc022f255cfc67ecbf32b93..90df619ff7be3db9b6356f88c2137969ea0927e4 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2007 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences math math.functions tetris.board
-tetris.piece tetris.tetromino lazy-lists combinators system ;
+tetris.piece tetris.tetromino lists combinators system ;
 IN: tetris.game
 
 TUPLE: tetris pieces last-update update-interval rows score game-state paused? running? ;
index 981b509bfa15c7d95fc901d4533d29a1a89bcef4..55215dbf6ad6eb0ed8789d876eeb58d878c957f9 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2007 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel arrays tetris.tetromino math math.vectors 
-sequences quotations lazy-lists ;
+sequences quotations lists.lazy ;
 IN: tetris.piece
 
 #! A piece adds state to the tetromino that is the piece's delegate. The
index f4515a9ebeed2250c5c2c31ac409880f078cada3..3ff22cb0c659257f974f8a42d8752dc7be5cc1ca 100755 (executable)
@@ -7,7 +7,7 @@ sorting hashtables vocabs parser source-files ;
 IN: tools.crossref
 
 : usage. ( word -- )
-    usage sorted-definitions. ;
+    smart-usage sorted-definitions. ;
 
 : words-matching ( str -- seq )
     all-words [ dup word-name ] { } map>assoc completions ;
index 6c5f7e7775f2a12d23bfcbd16e98b8dc20b87bbf..8973b2ea2a3547fbbfc1aa9e01c240b54ce48747 100755 (executable)
@@ -40,16 +40,14 @@ IN: tools.deploy.backend
     my-boot-image-name resource-path exists?
     [ my-arch make-image ] unless ;
 
-: ?, [ , ] [ drop ] if ;
-
 : bootstrap-profile ( -- profile )
-    [
-        "math" deploy-math? get ?,
-        "compiler" deploy-compiler? get ?,
-        "ui" deploy-ui? get ?,
-        "io" native-io? ?,
-        "random" deploy-random? get ?,
-    ] { } make ;
+    {
+        { "math"     deploy-math?     }
+        { "compiler" deploy-compiler? }
+        { "ui"       deploy-ui?       }
+        { "random"   deploy-random?   }
+    } [ nip get ] assoc-filter keys
+    native-io? [ "io" suffix ] when ;
 
 : staging-image-name ( profile -- name )
     "staging."
index 589d6c613b54218f33396ef0552c1805569031c2..065db4d8c1250f900353e8417e19c0c4d29f6c0a 100755 (executable)
@@ -22,9 +22,9 @@ SYMBOL: deploy-io
         { 3 "Level 3 - Non-blocking streams and networking" }
     } ;
 
-: strip-io? deploy-io get 1 = ;
+: strip-io? ( -- ? ) deploy-io get 1 = ;
 
-: native-io? deploy-io get 3 = ;
+: native-io? ( -- ? ) deploy-io get 3 = ;
 
 SYMBOL: deploy-reflection
 
@@ -38,11 +38,11 @@ SYMBOL: deploy-reflection
         { 6 "Level 6 - Full environment" }
     } ;
 
-: strip-word-names? deploy-reflection get 2 < ;
-: strip-prettyprint? deploy-reflection get 3 < ;
-: strip-debugger? deploy-reflection get 4 < ;
-: strip-dictionary? deploy-reflection get 5 < ;
-: strip-globals? deploy-reflection get 6 < ;
+: strip-word-names? ( -- ? ) deploy-reflection get 2 < ;
+: strip-prettyprint? ( -- ? ) deploy-reflection get 3 < ;
+: strip-debugger? ( -- ? ) deploy-reflection get 4 < ;
+: strip-dictionary? ( -- ? ) deploy-reflection get 5 < ;
+: strip-globals? ( -- ? ) deploy-reflection get 6 < ;
 
 SYMBOL: deploy-word-props?
 SYMBOL: deploy-word-defs?
index 0bf8b10d0cb369690d692695e2807c4e83ba606f..0ca85bca8ce9c0a4493047fd7dd99cc8584af643 100755 (executable)
@@ -1,6 +1,6 @@
 IN: tools.deploy.test.1\r
 USING: threads ;\r
 \r
-: deploy-test-1 1000 sleep ;\r
+: deploy-test-1 ( -- ) 1000 sleep ;\r
 \r
 MAIN: deploy-test-1\r
index e029e3050a9c590c9a2cd65da2138d63e7adf93f..afd83f510e5c77a1b7fa118e5038fc78a291b4f1 100755 (executable)
@@ -1,6 +1,6 @@
 IN: tools.deploy.test.2\r
 USING: calendar calendar.format ;\r
 \r
-: deploy-test-2 now (timestamp>string) ;\r
+: deploy-test-2 ( -- ) now (timestamp>string) ;\r
 \r
 MAIN: deploy-test-2\r
index 2f07f4ede519c641214c162bb8c208fa67940fde..69287db4e21c454d7b19eed5bb9ff71f41b51bfa 100755 (executable)
@@ -1,7 +1,7 @@
 IN: tools.deploy.test.3\r
 USING: io.encodings.ascii io.files kernel ;\r
 \r
-: deploy-test-3\r
+: deploy-test-3 ( -- )\r
     "resource:extra/tools/deploy/test/3/3.factor"\r
     ascii file-contents drop ;\r
 \r
index 39ee85b07a343eb4871191a9fe59d50b2d719935..a7d9da4840823ec769da209c95fc4ddf5a8e558b 100755 (executable)
@@ -6,9 +6,9 @@ system math generator.fixup io.encodings.ascii accessors
 generic ;
 IN: tools.disassembler
 
-: in-file "gdb-in.txt" temp-file ;
+: in-file ( -- path ) "gdb-in.txt" temp-file ;
 
-: out-file "gdb-out.txt" temp-file ;
+: out-file ( -- path ) "gdb-out.txt" temp-file ;
 
 GENERIC: make-disassemble-cmd ( obj -- )
 
index 9628b218e9c9a08ca7592096cc19791508345d10..83da7f22a8300482ee2f6770ab765aeafa41d4ed 100644 (file)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences vectors arrays generic assocs io math
 namespaces parser prettyprint strings io.styles vectors words
-system sorting splitting math.parser classes memory combinators ;
+system sorting splitting grouping math.parser classes memory
+combinators ;
 IN: tools.memory
 
 <PRIVATE
index 50bbc527d1d760f86aa1feb38a1a1fbab6621c52..69edf1a7e0f6cabd5afe21adef663048ff281870 100755 (executable)
@@ -44,7 +44,7 @@ HELP: vocab-profile.
 HELP: usage-profile.
 { $values { "word" word } }
 { $description "Prints a table of call counts from the most recent invocation of " { $link profile } ", for words which directly call " { $snippet "word" } " only." }
-{ $notes "This word obtains the list of static usages with the " { $link usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." }
+{ $notes "This word obtains the list of static usages with the " { $link smart-usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." }
 { $examples { $code "\\ + usage-profile." } } ;
 
 HELP: vocabs-profile.
index 450a024a1e90d8fc8fed10b0d686555060c3d9a0..335733d1092199255c673b0c0333a3530aff0c7c 100755 (executable)
@@ -20,9 +20,9 @@ alien tools.profiler.private sequences ;
 
 [ ] [ \ + usage-profile. ] unit-test
 
-: callback-test "void" { } "cdecl" [ ] alien-callback ;
+: callback-test ( -- callback ) "void" { } "cdecl" [ ] alien-callback ;
 
-: indirect-test "void" { } "cdecl" alien-indirect ;
+: indirect-test ( callback -- ) "void" { } "cdecl" alien-indirect ;
 
 : foobar ;
 
index 6a5fce6281e955ef0460a8342962a412a5d39b9e..4ae3666829429dfb7b0810f46e915297286f3d49 100755 (executable)
@@ -58,7 +58,7 @@ M: method-body (profile.)
     "Call counts for words which call " write
     dup pprint
     ":" print
-    usage [ word? ] filter counters counters. ;
+    smart-usage [ word? ] filter counters counters. ;
 
 : vocabs-profile. ( -- )
     "Call counts for all vocabularies:" print
index 82d3491743cb774b7b9b8ffa96389680854a2145..3078f40e1acf5b5878f928094668b788f182114d 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.vectors memory io io.styles prettyprint
-namespaces system sequences splitting assocs strings ;
+namespaces system sequences splitting grouping assocs strings ;
 IN: tools.time
 
 : benchmark ( quot -- runtime )
index 2417e7ac3930ab33af266a7a4025f1839bbdbf42..41f9f8066db33352877db9884cb2c59ec9389607 100755 (executable)
@@ -64,9 +64,9 @@ M: object add-breakpoint ;
 
 : (step-into-quot) ( quot -- ) add-breakpoint call ;
 
-: (step-into-if) ? (step-into-quot) ;
+: (step-into-if) ( true false ? -- ) ? (step-into-quot) ;
 
-: (step-into-dispatch) nth (step-into-quot) ;
+: (step-into-dispatch) ( array n -- ) nth (step-into-quot) ;
 
 : (step-into-execute) ( word -- )
     {
@@ -80,7 +80,7 @@ M: object add-breakpoint ;
 
 \ (step-into-execute) t "step-into?" set-word-prop
 
-: (step-into-continuation)
+: (step-into-continuation) ( -- )
     continuation callstack >>call break ;
 
 ! Messages sent to walker thread
@@ -260,4 +260,4 @@ SYMBOL: +stopped+
 ! For convenience
 IN: syntax
 
-: B break ;
+: B ( -- ) break ;
index ef5fcf8ca68ffc5eb31f5b208a5b63f2cd2f7749..923df4b6e3e3e628f47f1fc7eb65b5e2fef32028 100755 (executable)
@@ -84,7 +84,7 @@ DEFER: (splay)
 : get-largest ( node -- node )
     dup [ dup node-right [ nip get-largest ] when* ] when ;
 
-: splay-largest
+: splay-largest ( node -- node )
     dup [ dup get-largest node-key swap splay-at ] when ;
 
 : splay-join ( n2 n1 -- node )
index 3b0ab016660f122d300a3105a2780c472c7f2a30..d22dfdb7f1dc7486fce019762a2bc83205992b7f 100755 (executable)
@@ -101,23 +101,15 @@ M: tree set-at ( value key tree -- )
 
 : valid-tree? ( tree -- ? ) root>> valid-node? ;
 
-: tree-call ( node call -- )
-    >r [ node-key ] keep node-value r> call ; inline
-: find-node ( node quot -- key value ? )
-    {
-        { [ over not ] [ 2drop f f f ] }
-        { [ [
-              >r left>> r> find-node
-            ] 2keep rot ]
-          [ 2drop t ] }
-        { [ >r 2nip r> [ tree-call ] 2keep rot ]
-          [ drop [ node-key ] keep node-value t ] }
-        [ >r right>> r> find-node ]
-    } cond ; inline
-
-M: tree assoc-find ( tree quot -- key value ? )
-    >r root>> r> find-node ;
+: (node>alist) ( node -- )
+    [
+        [ left>> (node>alist) ]
+        [ [ node-key ] [ node-value ] bi 2array , ]
+        [ right>> (node>alist) ]
+        tri
+    ] when* ;
+
+M: tree >alist [ root>> (node>alist) ] { } make ;
 
 M: tree clear-assoc
     0 >>count
index 2936c390701bbd39cc458554f09801521cf539ab..d4b1a34e76701bfecc8ce866dc160507ffceed3d 100644 (file)
@@ -6,6 +6,6 @@ IN: tty-server
     "tty-server"
     utf8 [ listener ] with-server ;
 
-: default-tty-server 9999 tty-server ;
+: default-tty-server ( -- ) 9999 tty-server ;
 
 MAIN: default-tty-server
index d6949eaeac6ea568d6cbb5d3e9a44ae524d91947..d0c86986fd9c2eee08c22ffc4526004f8e4937ec 100644 (file)
@@ -2,8 +2,8 @@ USING: help.syntax help.markup splitting kernel ;
 IN: tuple-arrays
 
 HELP: tuple-array
-{ $description "The class of packed homogeneous tuple arrays. They are created with " { $link <tuple-array> } ". All elements are of the same tuple class. Mutations done to an element are not copied back to the packed array unless it is explicitly written back. Packed follows the sequence protocol and is implemented using the " { $link groups } " class." } ;
+{ $description "The class of packed homogeneous tuple arrays. They are created with " { $link <tuple-array> } ". All elements are of the same tuple class. Mutations done to an element are not copied back to the packed array unless it is explicitly written back.." } ;
 
 HELP: <tuple-array>
 { $values { "example" tuple } { "length" "a non-negative integer" } { "tuple-array" tuple-array } }
-{ $description "Creates an instance of the " { $link <tuple-array> } " class with the given length and containing the given tuple class. The tuple class is specified in the form of an example tuple. If the example tuple has a delegate, the tuple array will store a delegate for each element. Otherwise, the delegate will be assumed to be f." } ;
+{ $description "Creates an instance of the " { $link <tuple-array> } " class with the given length and containing the given tuple class. The tuple class is specified in the form of an example tuple. If the example tuple has a delegate, the tuple array will store a delegate for each element. Otherwise, the delegate will be assumed to be " { $link f } "." } ;
index 680610fbced9cab07946c846a5a69a2a101ac0b7..6a31dac808de82e4524ae4a01ce3b71a06658201 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: splitting classes.tuple classes math kernel sequences
-arrays ;
+USING: splitting grouping classes.tuple classes math kernel
+sequences arrays ;
 IN: tuple-arrays
 
 TUPLE: tuple-array example ;
index 0dc90d8cf5a5219e57daa5afd83d2d3fb2896be9..f5b510237bd6954f05918d66673cb1c0038c944c 100644 (file)
@@ -59,12 +59,12 @@ SYMBOL: tape
     dup state-dir position [ + ] change
     state-next state set ;
 
-: c
+: c ( -- )
     #! Print current turing machine state.
     state get .
     tape get .
     2 position get 2 * + CHAR: \s <string> write "^" print ;
 
-: n
+: n ( -- )
     #! Do one step and print new state.
     turing-step c ;
index ab6cc35d8ca1d97f31d184c164ecde164f42cc7d..4ee54cd833617cb09f63b8391e1e2fff9eb724bd 100644 (file)
@@ -5,7 +5,7 @@ IN: ui.clipboards
 
 ! Two text transfer buffers
 TUPLE: clipboard contents ;
-: <clipboard> "" clipboard boa ;
+: <clipboard> ( -- clipboard ) "" clipboard boa ;
 
 GENERIC: paste-clipboard ( gadget clipboard -- )
 
@@ -26,6 +26,6 @@ SYMBOL: selection
         2drop
     ] if ;
 
-: com-copy clipboard get gadget-copy ;
+: com-copy ( gadget -- ) clipboard get gadget-copy ;
 
-: com-copy-selection selection get gadget-copy ;
+: com-copy-selection ( gadget -- ) selection get gadget-copy ;
index 5ff0752c19ca6c91a27cdc1a7f5ab202d318c8a6..83628cc17140e5ccc74dfc6804eb43dbcbb18385 100644 (file)
@@ -3,13 +3,17 @@ hashtables quotations words classes sequences namespaces
 arrays assocs ;
 IN: ui.commands
 
-: command-map-row
+: command-map-row ( children -- seq )
     [
-        dup first gesture>string ,
-        second dup command-name ,
-        dup command-word \ $link swap 2array ,
-        command-description ,
-    ] [ ] make ;
+        [ first gesture>string , ]
+        [
+            second
+            [ command-name , ]
+            [ command-word \ $link swap 2array , ]
+            [ command-description , ]
+            tri
+        ] bi
+    ] { } make ;
 
 : command-map. ( command-map -- )
     [ command-map-row ] map
@@ -18,10 +22,11 @@ IN: ui.commands
     $table ;
 
 : $command-map ( element -- )
-    first2
-    dup (command-name) " commands" append $heading
-    swap command-map
-    dup command-map-blurb print-element command-map. ;
+    [ second (command-name) " commands" append $heading ]
+    [
+        first2 swap command-map
+        [ command-map-blurb print-element ] [ command-map. ] bi
+    ] bi ;
 
 : $command ( element -- )
     reverse first3 command-map value-at gesture>string $snippet ;
index 9910082ebfd89ca57690b5d46690621f0dab70a8..e452e6c4559c8f649d52115e4c508d43ce2c3f6e 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays ui.commands ui.gadgets ui.gadgets.borders
+USING: accessors arrays ui.commands ui.gadgets ui.gadgets.borders
 ui.gadgets.labels ui.gadgets.theme
 ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures
 ui.render kernel math models namespaces sequences strings
@@ -48,7 +48,8 @@ TUPLE: button-paint plain rollover pressed selected ;
 
 C: <button-paint> button-paint
 
-: find-button [ [ button? ] is? ] find-parent ;
+: find-button ( gadget -- button )
+    [ [ button? ] is? ] find-parent ;
 
 : button-paint ( button paint -- button paint )
     over find-button {
@@ -126,10 +127,11 @@ M: checkmark-paint draw-interior
 : toggle-model ( model -- )
     [ not ] change-model ;
 
-: checkbox-theme
-    f over set-gadget-interior
-    { 5 5 } over set-pack-gap
-    1/2 swap set-pack-align ;
+: checkbox-theme ( gadget -- )
+    f >>interior
+    { 5 5 } >>gap
+    1/2 >>align
+    drop ;
 
 TUPLE: checkbox ;
 
@@ -187,16 +189,18 @@ M: radio-control model-changed
     #! quot has stack effect ( value model label -- )
     swapd [ swapd call gadget, ] 2curry assoc-each ; inline
 
-: radio-button-theme
-    { 5 5 } over set-pack-gap 1/2 swap set-pack-align ;
+: radio-button-theme ( gadget -- )
+    { 5 5 } >>gap
+    1/2 >>align
+    drop ;
 
 : <radio-button> ( value model label -- gadget )
     <radio-knob> label-on-right
     [ <button> ] <radio-control>
     dup radio-button-theme ;
 
-: radio-buttons-theme
-    { 5 5 } swap set-pack-gap ;
+: radio-buttons-theme ( gadget -- )
+    { 5 5 } >>gap drop ;
 
 : <radio-buttons> ( model assoc -- gadget )
     [ [ <radio-button> ] <radio-controls> ] make-filled-pile
index c4a808bb2df3b99c8a6ce1d2995c90a955aaac92..3b8db0228ae0cba53fad422d026b83ce7a947660 100755 (executable)
@@ -211,13 +211,13 @@ M: editor draw-gadget*
 M: editor pref-dim*
     dup editor-font* swap control-value text-dim ;
 
-: contents-changed
+: contents-changed ( model editor -- )
     editor-self swap
     over editor-caret [ over validate-loc ] (change-model)
     over editor-mark [ over validate-loc ] (change-model)
     drop relayout ;
 
-: caret/mark-changed
+: caret/mark-changed ( model editor -- )
     nip editor-self dup relayout-1 scroll>caret ;
 
 M: editor model-changed
@@ -325,19 +325,25 @@ M: editor gadget-text* editor-string % ;
     [ drop dup extend-selection dup editor-mark click-loc ]
     [ select-elt ] if ;
 
-: insert-newline "\n" swap user-input ;
+: insert-newline ( editor -- ) "\n" swap user-input ;
 
-: delete-next-character T{ char-elt } editor-delete ;
+: delete-next-character ( editor -- ) 
+    T{ char-elt } editor-delete ;
 
-: delete-previous-character T{ char-elt } editor-backspace ;
+: delete-previous-character ( editor -- ) 
+    T{ char-elt } editor-backspace ;
 
-: delete-previous-word T{ word-elt } editor-delete ;
+: delete-previous-word ( editor -- ) 
+    T{ word-elt } editor-delete ;
 
-: delete-next-word T{ word-elt } editor-backspace ;
+: delete-next-word ( editor -- ) 
+    T{ word-elt } editor-backspace ;
 
-: delete-to-start-of-line T{ one-line-elt } editor-delete ;
+: delete-to-start-of-line ( editor -- ) 
+    T{ one-line-elt } editor-delete ;
 
-: delete-to-end-of-line T{ one-line-elt } editor-backspace ;
+: delete-to-end-of-line ( editor -- ) 
+    T{ one-line-elt } editor-backspace ;
 
 editor "general" f {
     { T{ key-down f f "DELETE" } delete-next-character }
@@ -350,11 +356,11 @@ editor "general" f {
     { T{ key-down f { A+ } "BACKSPACE" } delete-to-end-of-line }
 } define-command-map
 
-: paste clipboard get paste-clipboard ;
+: paste ( editor -- ) clipboard get paste-clipboard ;
 
-: paste-selection selection get paste-clipboard ;
+: paste-selection ( editor -- ) selection get paste-clipboard ;
 
-: cut clipboard get editor-cut ;
+: cut ( editor -- ) clipboard get editor-cut ;
 
 editor "clipboard" f {
     { T{ paste-action } paste }
@@ -380,17 +386,17 @@ editor "clipboard" f {
         T{ char-elt } editor-next
     ] if ;
 
-: previous-line T{ line-elt } editor-prev ;
+: previous-line ( editor -- ) T{ line-elt } editor-prev ;
 
-: next-line T{ line-elt } editor-next ;
+: next-line ( editor -- ) T{ line-elt } editor-next ;
 
-: previous-word T{ word-elt } editor-prev ;
+: previous-word ( editor -- ) T{ word-elt } editor-prev ;
 
-: next-word T{ word-elt } editor-next ;
+: next-word ( editor -- ) T{ word-elt } editor-next ;
 
-: start-of-line T{ one-line-elt } editor-prev ;
+: start-of-line ( editor -- ) T{ one-line-elt } editor-prev ;
 
-: end-of-line T{ one-line-elt } editor-next ;
+: end-of-line ( editor -- ) T{ one-line-elt } editor-next ;
 
 editor "caret-motion" f {
     { T{ button-down } position-caret }
@@ -406,36 +412,46 @@ editor "caret-motion" f {
     { T{ key-down f { C+ } "END" } end-of-document }
 } define-command-map
 
-: select-all T{ doc-elt } select-elt ;
+: select-all ( editor -- ) T{ doc-elt } select-elt ;
 
-: select-line T{ one-line-elt } select-elt ;
+: select-line ( editor -- ) T{ one-line-elt } select-elt ;
 
-: select-word T{ one-word-elt } select-elt ;
+: select-word ( editor -- ) T{ one-word-elt } select-elt ;
 
 : selected-word ( editor -- string )
     dup gadget-selection?
     [ dup select-word ] unless
     gadget-selection ;
 
-: select-previous-character T{ char-elt } editor-select-prev ;
+: select-previous-character ( editor -- ) 
+    T{ char-elt } editor-select-prev ;
 
-: select-next-character T{ char-elt } editor-select-next ;
+: select-next-character ( editor -- ) 
+    T{ char-elt } editor-select-next ;
 
-: select-previous-line T{ line-elt } editor-select-prev ;
+: select-previous-line ( editor -- ) 
+    T{ line-elt } editor-select-prev ;
 
-: select-next-line T{ line-elt } editor-select-next ;
+: select-next-line ( editor -- ) 
+    T{ line-elt } editor-select-next ;
 
-: select-previous-word T{ word-elt } editor-select-prev ;
+: select-previous-word ( editor -- ) 
+    T{ word-elt } editor-select-prev ;
 
-: select-next-word T{ word-elt } editor-select-next ;
+: select-next-word ( editor -- ) 
+    T{ word-elt } editor-select-next ;
 
-: select-start-of-line T{ one-line-elt } editor-select-prev ;
+: select-start-of-line ( editor -- ) 
+    T{ one-line-elt } editor-select-prev ;
 
-: select-end-of-line T{ one-line-elt } editor-select-next ;
+: select-end-of-line ( editor -- ) 
+    T{ one-line-elt } editor-select-next ;
 
-: select-start-of-document T{ doc-elt } editor-select-prev ;
+: select-start-of-document ( editor -- ) 
+    T{ doc-elt } editor-select-prev ;
 
-: select-end-of-document T{ doc-elt } editor-select-next ;
+: select-end-of-document ( editor -- ) 
+    T{ doc-elt } editor-select-next ;
 
 editor "selection" f {
     { T{ button-down f { S+ } } extend-selection }
index 4990254778d9396017a8beff9b547087e5022b19..a288f74f64b0d687ad98e6fbbed985b7a1243865 100644 (file)
@@ -1,5 +1,5 @@
 
-USING: kernel alien.c-types combinators sequences splitting
+USING: kernel alien.c-types combinators sequences splitting grouping
        opengl.gl ui.gadgets ui.render
        math math.vectors accessors ;
 
index 28fefbe1ae77c9ec5ebdb9477042c3e672e1a401..3e38f60627f7fd8ce2fbad227cecc004c2094793 100644 (file)
@@ -1,14 +1,14 @@
 ! Copyright (C) 2005, 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays generic kernel math namespaces sequences words
-splitting math.vectors ui.gadgets.grids ui.gadgets ;
+splitting grouping math.vectors ui.gadgets.grids ui.gadgets ;
 IN: ui.gadgets.frames
 
 ! A frame arranges gadgets in a 3x3 grid, where the center
 ! gadgets gets left-over space.
 TUPLE: frame ;
 
-: <frame-grid> 9 [ drop <gadget> ] map 3 group ;
+: <frame-grid> ( -- grid ) 9 [ drop <gadget> ] map 3 group ;
 
 : @center 1 1 ;
 : @left 0 1 ;
index 411552cc32080463177e9d1f1161b00729a84c93..db750d924d6f5921b6718055207cde2ecea09da6 100755 (executable)
@@ -204,9 +204,9 @@ DEFER: relayout
     dup gadget-layout-state
     [ drop ] [ dup invalidate layout-later ] if ;
 
-: show-gadget t swap set-gadget-visible? ;
+: show-gadget ( gadget -- ) t swap set-gadget-visible? ;
 
-: hide-gadget f swap set-gadget-visible? ;
+: hide-gadget ( gadget -- ) f swap set-gadget-visible? ;
 
 : (set-rect-dim) ( dim gadget quot -- )
     >r 2dup rect-dim =
@@ -249,7 +249,7 @@ M: gadget layout* drop ;
         dup [ layout ] each-child
     ] when drop ;
 
-: graft-queue \ graft-queue get ;
+: graft-queue ( -- dlist ) \ graft-queue get ;
 
 : unqueue-graft ( gadget -- )
     graft-queue over gadget-graft-node delete-node
@@ -308,7 +308,7 @@ M: gadget ungraft* drop ;
 
 SYMBOL: in-layout?
 
-: not-in-layout
+: not-in-layout ( -- )
     in-layout? get
     [ "Cannot add/remove gadgets in layout*" throw ] when ;
 
index 99512562495faf382cdbb1af5a0df45ee9dd5fa8..90b6a54def28cbf45727948a029fe7030abf911d 100644 (file)
@@ -27,7 +27,7 @@ TUPLE: grid children gap fill? ;
 : pref-dim-grid ( grid -- dims )
     grid-children [ [ pref-dim ] map ] map ;
 
-: (compute-grid) [ max-dim ] map ;
+: (compute-grid) ( grid -- seq ) [ max-dim ] map ;
 
 : compute-grid ( grid -- horiz vert )
     pref-dim-grid dup flip (compute-grid) swap (compute-grid) ;
index 111a78b215c6a49931fcfc2a71f2207c1b7f901b..63ab2f1d6f3df955b0b2a1730efd1394e2ffbaf0 100755 (executable)
@@ -36,7 +36,7 @@ M: labelled-gadget focusable-child* labelled-gadget-content ;
         { 0.65 0.45 1.0 1.0 }
     } } swap set-gadget-interior ;
 
-: <title-label> <label> dup title-theme ;
+: <title-label> ( text -- label ) <label> dup title-theme ;
 
 : <title-bar> ( title quot -- gadget )
     [
index 2b83e7db717062951bc662e6ebc524660a0b6508..880fb4450eae0aa37cedc7c287b877dfe93b860a 100755 (executable)
@@ -16,19 +16,22 @@ TUPLE: pane output current prototype scrolls?
 selection-color caret mark selecting? ;
 
 : clear-selection ( pane -- )
-    f over set-pane-caret
-    f swap set-pane-mark ;
+    f >>caret
+    f >>mark
+    drop ;
 
-: add-output 2dup set-pane-output add-gadget ;
+: add-output ( current pane -- )
+    [ set-pane-output ] [ add-gadget ] 2bi ;
 
-: add-current 2dup set-pane-current add-gadget ;
+: add-current ( current pane -- )
+    [ set-pane-current ] [ add-gadget ] 2bi ;
 
 : prepare-line ( pane -- )
-    dup clear-selection
-    dup pane-prototype clone swap add-current ;
+    [ clear-selection ]
+    [ [ pane-prototype clone ] keep add-current ] bi ;
 
 : pane-caret&mark ( pane -- caret mark )
-    dup pane-caret swap pane-mark ;
+    [ caret>> ] [ mark>> ] bi ;
 
 : selected-children ( pane -- seq )
     [ pane-caret&mark sort-pair ] keep gadget-subtree ;
@@ -39,17 +42,18 @@ M: pane gadget-selection
     selected-children gadget-text ;
 
 : pane-clear ( pane -- )
-    dup clear-selection
-    dup pane-output clear-incremental
-    pane-current clear-gadget ;
+    [ clear-selection ]
+    [ pane-output clear-incremental ]
+    [ pane-current clear-gadget ]
+    tri ;
 
-: pane-theme ( editor -- )
-    selection-color swap set-pane-selection-color ;
+: pane-theme ( pane -- )
+    selection-color >>selection-color drop ;
 
 : <pane> ( -- pane )
     pane new
     <pile> over set-delegate
-    <shelf> over set-pane-prototype
+    <shelf> >>prototype
     <pile> <incremental> over add-output
     dup prepare-line
     dup pane-theme ;
index 9f375d01269cd95dafd148f47d619a64393cebad..2ef261b61383fb6763479672192ad6e2a317a72f 100644 (file)
@@ -30,7 +30,7 @@ SYMBOL: margin
 
 : overrun? ( width -- ? ) x get + margin get > ;
 
-: zero-vars [ 0 swap set ] each ;
+: zero-vars ( seq -- ) [ 0 swap set ] each ;
 
 : wrap-line ( -- )
     line-height get y +@
index ce2bf40db8ee2d0f3766a3a76f03a3eb428f80d9..e513853d276de43f4a42bd65988ccfe9ad259535 100755 (executable)
@@ -11,13 +11,13 @@ TUPLE: scroller viewport x y follows ;
 : find-scroller ( gadget -- scroller/f )
     [ [ scroller? ] is? ] find-parent ;
 
-: scroll-up-page scroller-y -1 swap slide-by-page ;
+: scroll-up-page ( scroller -- ) y>> -1 swap slide-by-page ;
 
-: scroll-down-page scroller-y 1 swap slide-by-page ;
+: scroll-down-page ( scroller -- ) y>> 1 swap slide-by-page ;
 
-: scroll-up-line scroller-y -1 swap slide-by-line ;
+: scroll-up-line ( scroller -- ) y>> -1 swap slide-by-line ;
 
-: scroll-down-line scroller-y 1 swap slide-by-line ;
+: scroll-down-line ( scroller -- ) y>> 1 swap slide-by-line ;
 
 : do-mouse-scroll ( scroller -- )
     scroll-direction get-global first2
@@ -35,9 +35,9 @@ scroller H{
 : <scroller-model> ( -- model )
     0 0 0 0 <range> 0 0 0 0 <range> 2array <compose> ;
 
-: x-model g gadget-model model-dependencies first ;
+: x-model ( -- model ) g gadget-model model-dependencies first ;
 
-: y-model g gadget-model model-dependencies second ;
+: y-model ( -- model ) g gadget-model model-dependencies second ;
 
 : <scroller> ( gadget -- scroller )
     <scroller-model> <frame> scroller construct-control [
index 4d2c423445fa6843c444a9a10cebdc1f2e3924b0..c781a9167d66b3af9dac736e14206f8df8c0ce02 100755 (executable)
@@ -22,13 +22,13 @@ TUPLE: slider elevator thumb saved line ;
 
 : min-thumb-dim 15 ;
 
-: slider-value gadget-model range-value >fixnum ;
+: slider-value ( gadget -- n ) gadget-model range-value >fixnum ;
 
-: slider-page gadget-model range-page-value ;
+: slider-page ( gadget -- n ) gadget-model range-page-value ;
 
-: slider-max gadget-model range-max-value ;
+: slider-max ( gadget -- n ) gadget-model range-max-value ;
 
-: slider-max* gadget-model range-max-value* ;
+: slider-max* ( gadget -- n ) gadget-model range-max-value* ;
 
 : thumb-dim ( slider -- h )
     dup slider-page over slider-max 1 max / 1 min
@@ -43,9 +43,9 @@ TUPLE: slider elevator thumb saved line ;
     dup elevator-length over thumb-dim - 1 max
     swap slider-max* 1 max / ;
 
-: slider>screen slider-scale * ;
+: slider>screen ( m scale -- n ) slider-scale * ;
 
-: screen>slider slider-scale / ;
+: screen>slider ( m scale -- n ) slider-scale / ;
 
 M: slider model-changed nip slider-elevator relayout-1 ;
 
@@ -141,8 +141,11 @@ M: elevator layout*
     swap <thumb> g-> set-slider-thumb over add-gadget
     @center frame, ;
 
-: <left-button> { 0 1 } arrow-left -1 <slide-button> ;
-: <right-button> { 0 1 } arrow-right 1 <slide-button> ;
+: <left-button> ( -- button )
+    { 0 1 } arrow-left -1 <slide-button> ;
+
+: <right-button> ( -- button )
+    { 0 1 } arrow-right 1 <slide-button> ;
 
 : build-x-slider ( slider -- )
     [
@@ -151,8 +154,11 @@ M: elevator layout*
         <right-button> @right frame,
     ] with-gadget ;
 
-: <up-button> { 1 0 } arrow-up -1 <slide-button> ;
-: <down-button> { 1 0 } arrow-down 1 <slide-button> ;
+: <up-button> ( -- button )
+    { 1 0 } arrow-up -1 <slide-button> ;
+
+: <down-button> ( -- button )
+    { 1 0 } arrow-down 1 <slide-button> ;
 
 : build-y-slider ( slider -- )
     [
index 77e9375d90c01ee2da58b253de0adc5f17e698c5..f0884f9486f25192c60b5fe2bf547a671a6e1d3b 100644 (file)
@@ -1,17 +1,20 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! Copyright (C) 2006, 2007 Alex Chapman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel sequences io.styles ui.gadgets ui.render
 colors ;
 IN: ui.gadgets.theme
 
-: solid-interior <solid> swap set-gadget-interior ;
+: solid-interior ( gadget color -- )
+    <solid> swap set-gadget-interior ;
 
-: solid-boundary <solid> swap set-gadget-boundary ;
+: solid-boundary ( gadget color -- )
+    <solid> swap set-gadget-boundary ;
 
-: faint-boundary gray solid-boundary ;
+: faint-boundary ( gadget -- )
+    gray solid-boundary ;
 
-: selection-color light-purple ;
+: selection-color ( -- color ) light-purple ;
 
 : plain-gradient
     T{ gradient f {
index 7dd95d542d040908c9d4328021e09632edfe8e02..9d732b55db6d0fec922329450c0c5170aaf2e558 100755 (executable)
@@ -8,7 +8,8 @@ kernel math namespaces sequences models math.vectors ;
 
 TUPLE: viewport ;
 
-: find-viewport [ viewport? ] find-parent ;
+: find-viewport ( gadget -- viewport )
+    [ viewport? ] find-parent ;
 
 : viewport-dim ( viewport -- dim )
     gadget-child pref-dim viewport-gap 2 v*n v+ ;
index b63e7f9d2e5fdbca7707ded01f3c481dd73b49b5..2895dd07ccd5e5f8f02bf4c7d2c8b1f3e7a98f64 100755 (executable)
@@ -12,7 +12,7 @@ title status
 fonts handle
 loc ;
 
-: find-world [ world? ] find-parent ;
+: find-world ( gadget -- world ) [ world? ] find-parent ;
 
 M: f world-status ;
 
index d33a789fe7389ddf71662ab3468d41bf14bc5847..8f40bec1c3cab84fb5486d73b3f49fcfdbe097fe 100644 (file)
@@ -93,7 +93,7 @@ TUPLE: solid color ;
 C: <solid> solid
 
 ! Solid pen
-: (solid)
+: (solid) ( gadget paint -- loc dim )
     solid-color gl-color rect-dim >r origin get dup r> v+ ;
 
 M: solid draw-interior (solid) gl-fill-rect ;
index b8a6f7ec2c94074a97f6057e036d46f3f6714f37..50a3b6134356c6ecb9e9d3bcb6390ea05aaf1aa1 100755 (executable)
@@ -3,22 +3,21 @@
 USING: debugger ui.tools.workspace help help.topics kernel
 models ui.commands ui.gadgets ui.gadgets.panes
 ui.gadgets.scrollers ui.gadgets.tracks ui.gestures
-ui.gadgets.buttons compiler.units assocs words vocabs ;
+ui.gadgets.buttons compiler.units assocs words vocabs
+accessors ;
 IN: ui.tools.browser
 
 TUPLE: browser-gadget pane history ;
 
 : show-help ( link help -- )
-    dup browser-gadget-history add-history
-    >r >link r> browser-gadget-history set-model ;
+    dup history>> add-history
+    >r >link r> history>> set-model ;
 
 : <help-pane> ( browser-gadget -- gadget )
-    browser-gadget-history
-    [ [ dup help ] try drop ] <pane-control> ;
+    history>> [ [ dup help ] try drop ] <pane-control> ;
 
 : init-history ( browser-gadget -- )
-    "handbook" >link <history>
-    swap set-browser-gadget-history ;
+    "handbook" >link <history> >>history drop ;
 
 : <browser-gadget> ( -- gadget )
     browser-gadget new
@@ -31,7 +30,7 @@ TUPLE: browser-gadget pane history ;
 M: browser-gadget call-tool* show-help ;
 
 M: browser-gadget tool-scroller
-    browser-gadget-pane find-scroller ;
+    pane>> find-scroller ;
 
 M: browser-gadget graft*
     dup add-definition-observer
@@ -48,24 +47,24 @@ M: browser-gadget ungraft*
     or or ;
 
 M: browser-gadget definitions-changed ( assoc browser -- )
-    browser-gadget-history
+    history>>
     dup model-value rot showing-definition?
     [ notify-connections ] [ drop ] if ;
 
 : help-action ( browser-gadget -- link )
-    browser-gadget-history model-value >link ;
+    history>> model-value >link ;
 
-: com-follow browser-gadget call-tool ;
+: com-follow ( link -- ) browser-gadget call-tool ;
 
-: com-back browser-gadget-history go-back ;
+: com-back ( browser -- ) history>> go-back ;
 
-: com-forward browser-gadget-history go-forward ;
+: com-forward ( browser -- ) history>> go-forward ;
 
-: com-documentation "handbook" swap show-help ;
+: com-documentation ( browser -- ) "handbook" swap show-help ;
 
-: com-vocabularies "vocab-index" swap show-help ;
+: com-vocabularies ( browser -- ) "vocab-index" swap show-help ;
 
-: browser-help "ui-browser" help-window ;
+: browser-help ( -- ) "ui-browser" help-window ;
 
 \ browser-help H{ { +nullary+ t } } define-command
 
index 8cb581b1c22b8468fa9aec8b81cdd8f9adf8d346..5491e4c93cf98e4ffdbd89273955d4fbbecd4796 100644 (file)
@@ -46,7 +46,7 @@ debugger "gestures" f {
     { T{ button-down } request-focus }
 } define-command-map
 
-: com-traceback error-continuation get traceback-window ;
+: com-traceback ( -- ) error-continuation get traceback-window ;
 
 \ com-traceback H{ { +nullary+ t } } define-command
 
index d01f7ab1398fe1a8683842cab7c7937615328d3c..f0454f5cc26c1fa70e1796b21cd1f3ba56c55249 100755 (executable)
@@ -5,7 +5,7 @@ models sequences ui.gadgets.buttons
 ui.gadgets.packs ui.gadgets.labels tools.deploy.config
 namespaces ui.gadgets.editors ui.gadgets.borders ui.gestures
 ui.commands assocs ui.gadgets.tracks ui ui.tools.listener
-tools.deploy vocabs ui.tools.workspace system ;
+tools.deploy vocabs ui.tools.workspace system accessors ;
 IN: ui.tools.deploy
 
 TUPLE: deploy-gadget vocab settings ;
@@ -40,9 +40,10 @@ TUPLE: deploy-gadget vocab settings ;
     deploy-word-defs? get "Retain all word definitions" <checkbox> gadget,
     deploy-c-types? get "Retain all C types" <checkbox> gadget, ;
 
-: deploy-settings-theme
-    { 10 10 } over set-pack-gap
-    1 swap set-pack-fill ;
+: deploy-settings-theme ( gadget -- )
+    { 10 10 } >>gap
+    1 >>fill
+    drop ;
 
 : <deploy-settings> ( vocab -- control )
     default-config [ <model> ] assoc-map [
@@ -57,16 +58,16 @@ TUPLE: deploy-gadget vocab settings ;
         namespace <mapping> over set-gadget-model
     ] bind ;
 
-: find-deploy-gadget
+: find-deploy-gadget ( gadget -- deploy-gadget )
     [ deploy-gadget? ] find-parent ;
 
-: find-deploy-vocab
+: find-deploy-vocab ( gadget -- vocab )
     find-deploy-gadget deploy-gadget-vocab ;
 
-: find-deploy-config
+: find-deploy-config ( gadget -- config )
     find-deploy-vocab deploy-config ;
 
-: find-deploy-settings
+: find-deploy-settings ( gadget -- settings )
     find-deploy-gadget deploy-gadget-settings ;
 
 : com-revert ( gadget -- )
@@ -100,7 +101,7 @@ deploy-gadget "toolbar" f {
     { T{ key-down f f "RET" } com-deploy }
 } define-command-map
 
-: buttons,
+: buttons, ( -- )
     g <toolbar> { 10 10 } over set-pack-gap gadget, ;
 
 : <deploy-gadget> ( vocab -- gadget )
index e4079a331edc0ffe095b75fadecf385d23c931d6..03c601bcab09ff0e4d26cfcb93c3070c1daed6a4 100644 (file)
@@ -31,7 +31,7 @@ TUPLE: inspector-gadget object pane ;
 
 \ globals H{ { +nullary+ t } { +listener+ t } } define-command
 
-: inspector-help "ui-inspector" help-window ;
+: inspector-help ( -- ) "ui-inspector" help-window ;
 
 \ inspector-help H{ { +nullary+ t } } define-command
 
index 013bc57584ab9ca673dc54a88918a948727affd9..48bf01af37b627b75f4a5da3c3f5306f71912782 100755 (executable)
@@ -172,7 +172,7 @@ M: stack-display tool-scroller
     listener-gadget new dup init-listener
     [ listener-output, listener-input, ] { 0 1 } build-track ;
 
-: listener-help "ui-listener" help-window ;
+: listener-help ( -- ) "ui-listener" help-window ;
 
 \ listener-help H{ { +nullary+ t } } define-command
 
index 51a545db47693d37a48b3f3b1499c0bb4751f7c5..bd9dd351a422b36025d4197a513b56895457c33a 100755 (executable)
@@ -8,7 +8,7 @@ namespaces parser prettyprint quotations tools.annotations
 editors tools.profiler tools.test tools.time tools.walker
 ui.commands ui.gadgets.editors ui.gestures ui.operations
 ui.tools.deploy vocabs vocabs.loader words sequences
-tools.vocabs classes compiler.units ;
+tools.vocabs classes compiler.units accessors ;
 IN: ui.tools.operations
 
 V{ } clone operations set-global
@@ -19,25 +19,25 @@ V{ } clone operations set-global
     { +listener+ t }
 } define-operation
 
-: com-prettyprint . ;
+: com-prettyprint ( obj -- ) . ;
 
 [ drop t ] \ com-prettyprint H{
     { +listener+ t }
 } define-operation
 
-: com-push ;
+: com-push ( obj -- obj ) ;
 
 [ drop t ] \ com-push H{
     { +listener+ t }
 } define-operation
 
-: com-unparse unparse listener-input ;
+: com-unparse ( obj -- ) unparse listener-input ;
 
 [ drop t ] \ com-unparse H{ } define-operation
 
 ! Input
 
-: com-input input-string listener-input ;
+: com-input ( obj -- ) string>> listener-input ;
 
 [ input? ] \ com-input H{
     { +primary+ t }
@@ -58,7 +58,7 @@ V{ } clone operations set-global
 } define-operation
 
 ! Pathnames
-: edit-file edit ;
+: edit-file ( pathname -- ) edit ;
 
 [ pathname? ] \ edit-file H{
     { +keyboard+ T{ key-down f { C+ } "E" } }
@@ -116,21 +116,22 @@ M: word com-stack-effect word-def com-stack-effect ;
 } define-operation
 
 ! Vocabularies
-: com-vocab-words get-workspace swap show-vocab-words ;
+: com-vocab-words ( vocab -- )
+    get-workspace swap show-vocab-words ;
 
 [ vocab? ] \ com-vocab-words H{
     { +secondary+ t }
     { +keyboard+ T{ key-down f { C+ } "B" } }
 } define-operation
 
-: com-enter-in vocab-name set-in ;
+: com-enter-in ( vocab -- ) vocab-name set-in ;
 
 [ vocab? ] \ com-enter-in H{
     { +keyboard+ T{ key-down f { C+ } "I" } }
     { +listener+ t }
 } define-operation
 
-: com-use-vocab vocab-name use+ ;
+: com-use-vocab ( vocab -- ) vocab-name use+ ;
 
 [ vocab-spec? ] \ com-use-vocab H{
     { +secondary+ t }
@@ -165,7 +166,8 @@ M: word com-stack-effect word-def com-stack-effect ;
     { +listener+ t }
 } define-operation
 
-: com-show-profile profiler-gadget call-tool ;
+: com-show-profile ( workspace -- )
+    profiler-gadget call-tool ;
 
 : com-profile ( quot -- ) profile f com-show-profile ;
 
index 8b8d2c07a3d314b9c53e146558789abac584d4ec..cb68630a0851359b1cea1aff9d98fda7cfc0ec01 100755 (executable)
@@ -27,7 +27,7 @@ TUPLE: profiler-gadget pane ;
 : com-method-profile ( gadget -- )
     [ method-profile. ] with-profiler-pane ;
 
-: profiler-help "ui-profiler" help-window ;
+: profiler-help ( -- ) "ui-profiler" help-window ;
 
 \ profiler-help H{ { +nullary+ t } } define-command
 
index b18c0c1ad689af4cdace8cbf6a1dbad25817e579..af1d2633519c6e24280f4950ca85af5d347e502d 100755 (executable)
@@ -27,9 +27,11 @@ M: live-search handle-gesture* ( gadget gesture delegate -- ? )
         2drop t
     ] if ;
 
-: find-live-search [ [ live-search? ] is? ] find-parent ;
+: find-live-search ( gadget -- search )
+    [ [ live-search? ] is? ] find-parent ;
 
-: find-search-list find-live-search live-search-list ;
+: find-search-list ( gadget -- list )
+    find-live-search live-search-list ;
 
 TUPLE: search-field ;
 
@@ -94,7 +96,7 @@ M: live-search pref-dim* drop { 400 200 } ;
     "Words in " rot vocab-name append show-titled-popup ;
 
 : show-word-usage ( workspace word -- )
-    "" over usage f <definition-search>
+    "" over smart-usage f <definition-search>
     "Words and methods using " rot word-name append
     show-titled-popup ;
 
index 494e9d67370af23fa086bc45f802eb9d12528122..24622d0e97b00471a08851a03bbdaeafadfcbfdb 100755 (executable)
@@ -55,13 +55,13 @@ M: workspace model-changed
 
 [ workspace-window ] ui-hook set-global
 
-: com-listener stack-display select-tool ;
+: com-listener ( workspace -- ) stack-display select-tool ;
 
-: com-browser browser-gadget select-tool ;
+: com-browser ( workspace -- ) browser-gadget select-tool ;
 
-: com-inspector inspector-gadget select-tool ;
+: com-inspector ( workspace -- ) inspector-gadget select-tool ;
 
-: com-profiler profiler-gadget select-tool ;
+: com-profiler ( workspace -- ) profiler-gadget select-tool ;
 
 workspace "tool-switching" f {
     { T{ key-down f { A+ } "1" } com-listener }
index edf4a5bb869d74ffc83957df2444d6acb437c782..8d205daebf39c60e567126681b9f6cf8de54c747 100755 (executable)
@@ -62,7 +62,7 @@ M: walker-gadget focusable-child*
         g walker-gadget-traceback 1 track,
     ] { 0 1 } build-track ;
 
-: walker-help "ui-walker" help-window ;
+: walker-help ( -- ) "ui-walker" help-window ;
 
 \ walker-help H{ { +nullary+ t } } define-command
 
index 5a334ab56b62efe604b16573eb9088dfe0e65d3a..5b663aef47f9e2a246ada8a0762cdbdb1556ba82 100755 (executable)
@@ -10,7 +10,8 @@ IN: ui.tools.workspace
 
 TUPLE: workspace book listener popup ;
 
-: find-workspace [ workspace? ] find-parent ;
+: find-workspace ( gadget -- workspace )
+    [ workspace? ] find-parent ;
 
 SYMBOL: workspace-window-hook
 
index 6b2abcbd7618148ca4fcfbc3f0db311ca86c966b..3fc5d4abcd8fac94968ff0095a5fe47b507d6fd4 100755 (executable)
@@ -3,7 +3,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings arrays assocs ui
 ui.gadgets ui.backend ui.clipboards ui.gadgets.worlds
-ui.gestures io kernel math math.vectors namespaces prettyprint
+ui.gestures io kernel math math.vectors namespaces
 sequences strings vectors words windows.kernel32 windows.gdi32
 windows.user32 windows.opengl32 windows.messages windows.types
 windows.nt windows threads libc combinators continuations
@@ -13,8 +13,11 @@ IN: ui.windows
 
 SINGLETON: windows-ui-backend
 
-: crlf>lf CHAR: \r swap remove ;
-: lf>crlf [ [ dup CHAR: \n = [ CHAR: \r , ] when , ] each ] "" make ;
+: crlf>lf ( str -- str' )
+    CHAR: \r swap remove ;
+
+: lf>crlf ( str -- str' )
+    [ [ dup CHAR: \n = [ CHAR: \r , ] when , ] each ] "" make ;
 
 : enum-clipboard ( -- seq )
     0
@@ -127,7 +130,7 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
         { 123 "F12" }
     } ;
 
-: key-state-down?
+: key-state-down? ( key -- ? )
     GetKeyState 16 bit? ;
 
 : left-shift? ( -- ? ) VK_LSHIFT key-state-down? ;
@@ -380,7 +383,7 @@ SYMBOL: trace-messages?
     "uint" { "void*" "uint" "long" "long" } "stdcall" [
         [
             pick
-            trace-messages? get-global [ dup windows-message-name . ] when
+            trace-messages? get-global [ dup windows-message-name word-name print flush ] when
             wm-handlers get-global at* [ call ] [ drop DefWindowProc ] if
         ] ui-try
      ] alien-callback ;
index 16ac50d5a960ea660104461ea5d44078bc0543b8..5de90d238d4a5f2bb7830bf75b443d394ece1c0c 100755 (executable)
@@ -1,6 +1,6 @@
-USING: io io.files splitting unicode.collation sequences kernel\r
-io.encodings.utf8 math.parser math.order tools.test assocs\r
-io.streams.null words combinators.lib ;\r
+USING: io io.files splitting grouping unicode.collation\r
+sequences kernel io.encodings.utf8 math.parser math.order\r
+tools.test assocs io.streams.null words combinators.lib ;\r
 IN: unicode.collation.tests\r
 \r
 : parse-test ( -- strings )\r
index f9e56679477fcef0408453c036af6f4977bef590..e3dd15558b8afefa85cb0fb11a39716bf937d1ee 100755 (executable)
@@ -1,5 +1,5 @@
 USING: assocs math kernel sequences io.files hashtables
-quotations splitting arrays math.parser hash2 math.order
+quotations splitting grouping arrays math.parser hash2 math.order
 byte-arrays words namespaces words compiler.units parser
 io.encodings.ascii values interval-maps ascii sets assocs.lib
 combinators.lib combinators locals math.ranges sorting ;
@@ -46,11 +46,11 @@ VALUE: properties
 
 : (process-data) ( index data -- newdata )
     filter-comments
-    [ [ nth ] keep first swap 2array ] with map
+    [ [ nth ] keep first swap ] with { } map>assoc
     [ >r hex> r> ] assoc-map ;
 
 : process-data ( index data -- hash )
-    (process-data) [ hex> ] assoc-map >hashtable ;
+    (process-data) [ hex> ] assoc-map [ nip ] assoc-filter >hashtable ;
 
 : (chain-decomposed) ( hash value -- newvalue )
     [
index 9029d6bd3532b1a928725bede7fbd717e1777f94..66f7c1e7a7e7d1c8ba4b31e4f4aa68cf380deb28 100644 (file)
@@ -26,17 +26,17 @@ IN: units.si
 : cd ( n -- dimensioned ) { cd } { } <dimensioned> ;
 
 ! SI derived units
-: m^2 { m m } { } <dimensioned> ;
-: m^3 { m m m } { } <dimensioned> ;
-: m/s { m } { s } <dimensioned> ;
-: m/s^2 { m } { s s } <dimensioned> ;
-: 1/m { } { m } <dimensioned> ;
-: kg/m^3 { kg } { m m m } <dimensioned> ;
-: A/m^2 { A } { m m } <dimensioned> ;
-: A/m { A } { m } <dimensioned> ;
-: mol/m^3 { mol } { m m m } <dimensioned> ;
-: cd/m^2 { cd } { m m } <dimensioned> ;
-: kg/kg { kg } { kg } <dimensioned> ;
+: m^2 ( n -- dimensioned ) { m m } { } <dimensioned> ;
+: m^3 ( n -- dimensioned ) { m m m } { } <dimensioned> ;
+: m/s ( n -- dimensioned ) { m } { s } <dimensioned> ;
+: m/s^2 ( n -- dimensioned ) { m } { s s } <dimensioned> ;
+: 1/m ( n -- dimensioned ) { } { m } <dimensioned> ;
+: kg/m^3 ( n -- dimensioned ) { kg } { m m m } <dimensioned> ;
+: A/m^2 ( n -- dimensioned ) { A } { m m } <dimensioned> ;
+: A/m ( n -- dimensioned ) { A } { m } <dimensioned> ;
+: mol/m^3 ( n -- dimensioned ) { mol } { m m m } <dimensioned> ;
+: cd/m^2 ( n -- dimensioned ) { cd } { m m } <dimensioned> ;
+: kg/kg ( n -- dimensioned ) { kg } { kg } <dimensioned> ;
 
 ! Radians are really m/m, and steradians are m^2/m^2
 ! but they need to be in reduced form here.
@@ -65,9 +65,9 @@ IN: units.si
 : kat ( n -- katal ) { mol } { s } <dimensioned> ;
 
 ! Extensions to the SI
-: arc-deg pi 180 / * radians ;
-: arc-min pi 10800 / * radians ;
-: arc-sec pi 648000 / * radians ;
+: arc-deg ( n -- x ) pi 180 / * radians ;
+: arc-min ( n -- x ) pi 10800 / * radians ;
+: arc-sec ( n -- x ) pi 648000 / * radians ;
 : L ( n -- liter ) 1/1000 * m^3 ;
 : tons ( n -- metric-ton ) 1000 * kg ;
 : Np ( n -- neper ) { } { } <dimensioned> ;
@@ -83,43 +83,43 @@ IN: units.si
 : bar ( n -- bar ) 100000 * Pa ;
 : b ( n -- barn ) 1/10000000000000000000000000000 * m^2 ;
 : Ci ( n -- curie ) 37000000000 * Bq ;
-: R 258/10000 { s A } { kg } <dimensioned> ;
-: rad 100 / Gy ;
+: R ( -- dimensioned ) 258/10000 { s A } { kg } <dimensioned> ;
+: rad ( n -- dimensioned ) 100 / Gy ;
 
 ! roentgen equivalent man, equal to one roentgen of X-rays
-: roentgen-equivalent-man 100 / Sv ;
+: roentgen-equivalent-man ( n -- dimensioned ) 100 / Sv ;
 
 ! inaccurate, use calendar where possible
-: minutes 60 * s ;
-: hours 60 * minutes ;
-: days 24 * hours ;
+: minutes ( n -- dimensioned ) 60 * s ;
+: hours ( n -- dimensioned ) 60 * minutes ;
+: days ( n -- dimensioned ) 24 * hours ;
 
 ! Y Z E P T G M k h da 1 d c m mu n p f a z y
-: yotta 1000000000000000000000000 * ;
-: zetta 1000000000000000000000 * ;
-: exa   1000000000000000000 * ;
-: peta  1000000000000000 * ;
-: tera  1000000000000 * ;
-: giga  1000000000 * ;
-: mega  1000000 * ;
-: kilo  1000 * ;
-: hecto 100 * ;
-: deca  10 * ;
-: deci  10 / ;
-: centi 100 / ;
-: milli 1000 / ;
-: micro 1000000 / ;
-: nano  1000000000 / ;
-: pico  1000000000000 / ;
-: femto 1000000000000000 / ;
-: atto  1000000000000000000 / ;
-: zepto 1000000000000000000000 / ;
-: yocto 1000000000000000000000000 / ;
-
-: km kilo m ;
-: cm centi m ;
-: mm milli m ;
-: nm nano m ;
-: g milli kg ;
-: ms milli s ;
-: angstrom 10 / nm ;
+: yotta ( n -- x ) 1000000000000000000000000 * ;
+: zetta ( n -- x ) 1000000000000000000000 * ;
+: exa   ( n -- x ) 1000000000000000000 * ;
+: peta  ( n -- x ) 1000000000000000 * ;
+: tera  ( n -- x ) 1000000000000 * ;
+: giga  ( n -- x ) 1000000000 * ;
+: mega  ( n -- x ) 1000000 * ;
+: kilo  ( n -- x ) 1000 * ;
+: hecto ( n -- x ) 100 * ;
+: deca  ( n -- x ) 10 * ;
+: deci  ( n -- x ) 10 / ;
+: centi ( n -- x ) 100 / ;
+: milli ( n -- x ) 1000 / ;
+: micro ( n -- x ) 1000000 / ;
+: nano  ( n -- x ) 1000000000 / ;
+: pico  ( n -- x ) 1000000000000 / ;
+: femto ( n -- x ) 1000000000000000 / ;
+: atto  ( n -- x ) 1000000000000000000 / ;
+: zepto ( n -- x ) 1000000000000000000000 / ;
+: yocto ( n -- x ) 1000000000000000000000000 / ;
+
+: km ( n -- dimensioned ) kilo m ;
+: cm ( n -- dimensioned ) centi m ;
+: mm ( n -- dimensioned ) milli m ;
+: nm ( n -- dimensioned ) nano m ;
+: g ( n -- dimensioned ) milli kg ;
+: ms ( n -- dimensioned ) milli s ;
+: angstrom ( n -- dimensioned ) 10 / nm ;
index 32baf9e7ed3e27612c3e33752dd354672abe8aaa..f7330c14327b795324c2d0d7ba199d24e7ebd311 100755 (executable)
@@ -40,12 +40,12 @@ M: dimensions-not-equal summary drop "Dimensions do not match" ;
     [ dimensions 2array ] bi@ =
     [ dimensions-not-equal ] unless ;
 
-: 2values [ dimensioned-value ] bi@ ;
+: 2values ( dim dim -- val val ) [ dimensioned-value ] bi@ ;
 
-: <dimension-op
+: <dimension-op ( dim dim -- top bot val val )
     2dup check-dimensions dup dimensions 2swap 2values ;
 
-: dimension-op>
+: dimension-op> ( top bot val -- dim )
     -rot <dimensioned> ;
 
 : d+ ( d d -- d ) <dimension-op + dimension-op> ;
index b7b721efc7618ac2c1df3a1d9e605f3f0ddf2f24..f94dc74ab9b8278d76ed8840f82f71e6fb89c5e1 100644 (file)
@@ -28,8 +28,8 @@ C-STRUCT: inotify-event
 : IN_Q_OVERFLOW HEX: 4000 ; inline  ! Event queued overflowed\r
 : IN_IGNORED HEX: 8000 ; inline     ! File was ignored\r
 \r
-: IN_CLOSE IN_CLOSE_WRITE IN_CLOSE_NOWRITE bitor ; inline ! close\r
-: IN_MOVE IN_MOVED_FROM IN_MOVED_TO bitor ; inline        ! moves\r
+: IN_CLOSE ( -- n ) IN_CLOSE_WRITE IN_CLOSE_NOWRITE bitor ; inline ! close\r
+: IN_MOVE ( -- n ) IN_MOVED_FROM IN_MOVED_TO bitor ; inline        ! moves\r
 \r
 : IN_ONLYDIR HEX: 1000000 ; inline     ! only watch the path if it is a directory\r
 : IN_DONT_FOLLOW HEX: 2000000 ; inline ! don't follow a sym link\r
@@ -37,14 +37,14 @@ C-STRUCT: inotify-event
 : IN_ISDIR HEX: 40000000 ; inline      ! event occurred against dir\r
 : IN_ONESHOT HEX: 80000000 ; inline    ! only send event once\r
 \r
-: IN_CHANGE_EVENTS\r
+: IN_CHANGE_EVENTS ( -- n )\r
     {\r
         IN_MODIFY IN_ATTRIB IN_MOVED_FROM\r
         IN_MOVED_TO IN_DELETE IN_CREATE IN_DELETE_SELF\r
         IN_MOVE_SELF\r
     } flags ; foldable\r
 \r
-: IN_ALL_EVENTS\r
+: IN_ALL_EVENTS ( -- n )\r
     {\r
         IN_ACCESS IN_MODIFY IN_ATTRIB IN_CLOSE_WRITE\r
         IN_CLOSE_NOWRITE IN_OPEN IN_MOVED_FROM\r
index 552547442acd6429d96fb7518a8c582bdd912241..4d84e3839950ed9cefff75bec4a87e5a2647e365 100644 (file)
@@ -28,6 +28,6 @@ C-STRUCT: stat
 FUNCTION: int stat  ( char* pathname, stat* buf ) ;
 FUNCTION: int lstat ( char* pathname, stat* buf ) ;
 
-: stat-st_atim stat-st_atimespec ;
-: stat-st_mtim stat-st_mtimespec ;
-: stat-st_ctim stat-st_ctimespec ;
+: stat-st_atim ( stat -- timespec ) stat-st_atimespec ;
+: stat-st_mtim ( stat -- timespec ) stat-st_mtimespec ;
+: stat-st_ctim ( stat -- timespec ) stat-st_ctimespec ;
index 080352449b99231f1fe19c053ce6a069e96e9c20..87c9b91950d0e7d7b0eef2b4653cce67cac2bf89 100644 (file)
@@ -1,5 +1,7 @@
 IN: urls.tests
-USING: urls tools.test tuple-syntax arrays kernel assocs ;
+USING: urls urls.private tools.test
+tuple-syntax arrays kernel assocs
+present accessors ;
 
 [ "hello%20world" ] [ "hello world" url-encode ] unit-test
 [ "hello world" ] [ "hello%20world" url-decode ] unit-test
@@ -110,7 +112,7 @@ urls [
 ] assoc-each
 
 urls [
-    swap [ 1array ] [ [ url>string ] curry ] bi* unit-test
+    swap [ 1array ] [ [ present ] curry ] bi* unit-test
 ] assoc-each
 
 [ "b" ] [ "a" "b" url-append-path ] unit-test
@@ -222,3 +224,5 @@ urls [
 [ "a" ] [
     <url> "a" "b" set-query-param "b" query-param
 ] unit-test
+
+[ "foo#3" ] [ URL" foo" clone 3 >>anchor present ] unit-test
index 5c89205d5bfc8ed3a33a1c89f281447ea654a65c..7e74fd1115914a543786d21114480206a1ff37fe 100644 (file)
@@ -4,7 +4,7 @@ USING: kernel unicode.categories combinators sequences splitting
 fry namespaces assocs arrays strings io.sockets
 io.sockets.secure io.encodings.string io.encodings.utf8
 math math.parser accessors mirrors parser
-prettyprint.backend hashtables ;
+prettyprint.backend hashtables present ;
 IN: urls
 
 : url-quotable? ( ch -- ? )
@@ -14,19 +14,25 @@ IN: urls
         { [ dup letter? ] [ t ] }
         { [ dup LETTER? ] [ t ] }
         { [ dup digit? ] [ t ] }
-        { [ dup "/_-.:" member? ] [ t ] }
+        { [ dup "/_-." member? ] [ t ] }
         [ f ]
     } cond nip ; foldable
 
+<PRIVATE
+
 : push-utf8 ( ch -- )
     1string utf8 encode
     [ CHAR: % , >hex 2 CHAR: 0 pad-left % ] each ;
 
+PRIVATE>
+
 : url-encode ( str -- str )
     [
         [ dup url-quotable? [ , ] [ push-utf8 ] if ] each
     ] "" make ;
 
+<PRIVATE
+
 : url-decode-hex ( index str -- )
     2dup length 2 - >= [
         2drop
@@ -51,9 +57,13 @@ IN: urls
         ] if url-decode-iter
     ] if ;
 
+PRIVATE>
+
 : url-decode ( str -- str )
     [ 0 swap url-decode-iter ] "" make utf8 decode ;
 
+<PRIVATE
+
 : add-query-param ( value key assoc -- )
     [
         at [
@@ -65,6 +75,8 @@ IN: urls
         ] when*
     ] 2keep set-at ;
 
+PRIVATE>
+
 : query>assoc ( query -- assoc )
     dup [
         "&" split H{ } clone [
@@ -77,11 +89,7 @@ IN: urls
 
 : assoc>query ( hash -- str )
     [
-        {
-            { [ dup number? ] [ number>string 1array ] }
-            { [ dup string? ] [ 1array ] }
-            { [ dup sequence? ] [ ] }
-        } cond
+        dup array? [ [ present ] map ] [ present 1array ] if
     ] assoc-map
     [
         [
@@ -108,6 +116,8 @@ TUPLE: url protocol username password host port path query anchor ;
         ] when
     ] bi* ;
 
+<PRIVATE
+
 : parse-host-part ( url protocol rest -- url string' )
     [ >>protocol ] [
         "//" ?head [ "Invalid URL" throw ] unless
@@ -121,6 +131,8 @@ TUPLE: url protocol username password host port path query anchor ;
         ] [ "/" prepend ] bi*
     ] bi* ;
 
+PRIVATE>
+
 GENERIC: >url ( obj -- url )
 
 M: url >url ;
@@ -135,6 +147,8 @@ M: string >url
     ]
     [ url-decode >>anchor ] bi* ;
 
+<PRIVATE
+
 : unparse-username-password ( url -- )
     dup username>> dup [
         % password>> [ ":" % % ] when* "@" %
@@ -150,13 +164,13 @@ M: string >url
         [ path>> "/" head? [ "/" % ] unless ]
     } cleave ;
 
-: url>string ( url -- string )
+M: url present
     [
         {
             [ dup protocol>> dup [ unparse-host-part ] [ 2drop ] if ]
             [ path>> url-encode % ]
             [ query>> dup assoc-empty? [ drop ] [ "?" % assoc>query % ] if ]
-            [ anchor>> [ "#" % url-encode % ] when* ]
+            [ anchor>> [ "#" % present url-encode % ] when* ]
         } cleave
     ] "" make ;
 
@@ -169,6 +183,8 @@ M: string >url
         [ [ "/" last-split1 drop "/" ] dip 3append ]
     } cond ;
 
+PRIVATE>
+
 : derive-url ( base url -- url' )
     [ clone dup ] dip
     2dup [ path>> ] bi@ url-append-path
@@ -199,4 +215,4 @@ M: string >url
 ! Literal syntax
 : URL" lexer get skip-blank parse-string >url parsed ; parsing
 
-M: url pprint* dup url>string "URL\" " "\"" pprint-string ;
+M: url pprint* dup present "URL\" " "\"" pprint-string ;
index 0d1ea3bc04b9853847ea7553661d5e1bad3c8beb..6f050fc8f88ebe1a7fe626ab402f0a544323295d 100755 (executable)
@@ -1,8 +1,9 @@
-USING: kernel parser sequences words ;
+USING: kernel parser sequences words effects ;
 IN: values
 
 : VALUE:
-    CREATE-WORD { f } clone [ first ] curry define ; parsing
+    CREATE-WORD { f } clone [ first ] curry
+    (( -- value )) define-declared ; parsing
 
 : set-value ( value word -- )
     word-def first set-first ;
index 8c024ce7758db9444cb1f8164839062f992854f6..5942215a699b6473735d5288236b7a633a37a637 100644 (file)
@@ -2,27 +2,29 @@
 
 ! Thanks to Mackenzie Straight for the idea
 
-USING: compiler.units kernel parser words namespaces
-sequences quotations ;
+USING: kernel parser words namespaces sequences quotations ;
 
 IN: vars
 
-: define-var-symbol ( str -- ) create-in define-symbol ;
+: define-var-getter ( word -- )
+    [ word-name ">" append create-in ] [ [ get ] curry ] bi
+    (( -- value )) define-declared ;
 
-: define-var-getter ( str -- )
-dup ">" append create-in swap in get lookup [ get ] curry define ;
+: define-var-setter ( word -- )
+    [ word-name ">" prepend create-in ] [ [ set ] curry ] bi
+    (( value -- )) define-declared ;
 
-: define-var-setter ( str -- )
-">" over append create-in swap in get lookup [ set ] curry define ;
-
-: define-var ( str -- ) [
-dup define-var-symbol dup define-var-getter define-var-setter
-] with-compilation-unit ;
+: define-var ( str -- )
+    create-in
+    [ define-symbol ]
+    [ define-var-getter ]
+    [ define-var-setter ] tri ;
 
 : VAR: ! var
     scan define-var ; parsing
 
-: define-vars ( seq -- ) [ define-var ] each ;
+: define-vars ( seq -- )
+    [ define-var ] each ;
 
 : VARS: ! vars ...
-";" parse-tokens define-vars ; parsing
+    ";" parse-tokens define-vars ; parsing
diff --git a/extra/webapps/blogs/blogs-common.xml b/extra/webapps/blogs/blogs-common.xml
new file mode 100644 (file)
index 0000000..965f059
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:atom t:href="$blogs/posts.atom">Recent Posts</t:atom>
+
+       <t:style t:include="resource:extra/webapps/blogs/blogs.css" />
+
+       <div class="navbar">
+
+                 <t:a t:href="$blogs/">All Posts</t:a>
+               | <t:a t:href="$blogs/by">My Posts</t:a>
+               | <t:a t:href="$blogs/new-post">New Post</t:a>
+
+               <t:if t:code="furnace.sessions:uid">
+
+                       <t:if t:code="furnace.auth.login:allow-edit-profile?">
+                               | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
+                       </t:if>
+
+                       | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
+
+               </t:if>
+
+       </div>
+
+       <h1><t:write-title /></h1>
+
+       <t:call-next-template />
+
+</t:chloe>
diff --git a/extra/webapps/blogs/blogs.css b/extra/webapps/blogs/blogs.css
new file mode 100644 (file)
index 0000000..6667679
--- /dev/null
@@ -0,0 +1,15 @@
+.post-form {
+       border: 2px solid #666;
+       padding: 10px;
+       background: #eee;
+}
+
+.post-title {
+       background-color:#f5f5ff;
+       padding: 3px;
+}
+
+.post-footer {
+       text-align: right;
+       font-size:90%;
+}
diff --git a/extra/webapps/blogs/blogs.factor b/extra/webapps/blogs/blogs.factor
new file mode 100644 (file)
index 0000000..8dbf7db
--- /dev/null
@@ -0,0 +1,253 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors sequences sorting math.order math.parser
+urls validators html.components db.types db.tuples calendar
+http.server.dispatchers
+furnace furnace.actions furnace.auth.login furnace.boilerplate
+furnace.sessions furnace.syndication ;
+IN: webapps.blogs
+
+TUPLE: blogs < dispatcher ;
+
+: view-post-url ( id -- url )
+    number>string "$blogs/post/" prepend >url ;
+
+: view-comment-url ( parent id -- url )
+    [ view-post-url ] dip >>anchor ;
+
+: list-posts-url ( -- url )
+    URL" $blogs/" ;
+
+: user-posts-url ( author -- url )
+    "$blogs/by/" prepend >url ;
+
+TUPLE: entity id author date content ;
+
+GENERIC: entity-url ( entity -- url )
+
+M: entity feed-entry-url entity-url ;
+
+entity f {
+    { "id" "ID" INTEGER +db-assigned-id+ }
+    { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid
+    { "date" "DATE" TIMESTAMP +not-null+ }
+    { "content" "CONTENT" TEXT +not-null+ }
+} define-persistent
+
+M: entity feed-entry-date date>> ;
+
+TUPLE: post < entity title comments ;
+
+M: post feed-entry-title
+    [ author>> ] [ drop ": " ] [ title>> ] tri 3append ;
+
+M: post entity-url
+    id>> view-post-url ;
+
+\ post "BLOG_POSTS" {
+    { "title" "TITLE" { VARCHAR 256 } +not-null+ }
+} define-persistent
+
+: <post> ( id -- post ) \ post new swap >>id ;
+
+: init-posts-table ( -- ) \ post ensure-table ;
+
+TUPLE: comment < entity parent ;
+
+comment "COMMENTS" {
+    { "parent" "PARENT" INTEGER +not-null+ } ! post id
+} define-persistent
+
+M: comment feed-entry-title
+    author>> "Comment by " prepend ;
+
+M: comment entity-url
+    [ parent>> ] [ id>> ] bi view-comment-url ;
+
+: <comment> ( parent id -- post )
+    comment new
+        swap >>id
+        swap >>parent ;
+
+: init-comments-table ( -- ) comment ensure-table ;
+
+: post ( id -- post )
+    [ <post> select-tuple ] [ f <comment> select-tuples ] bi
+    >>comments ;
+
+: reverse-chronological-order ( seq -- sorted )
+    [ [ date>> ] compare invert-comparison ] sort ;
+
+: validate-author ( -- )
+    { { "author" [ [ v-username ] v-optional ] } } validate-params ;
+
+: list-posts ( -- posts )
+    f <post> "author" value >>author
+    select-tuples [ dup id>> f <comment> count-tuples >>comments ] map
+    reverse-chronological-order ;
+
+: <list-posts-action> ( -- action )
+    <page-action>
+        [
+            list-posts "posts" set-value
+        ] >>init
+
+        { blogs "list-posts" } >>template ;
+
+: <list-posts-feed-action> ( -- action )
+    <feed-action>
+        [ "Recent Posts" ] >>title
+        [ list-posts ] >>entries
+        [ list-posts-url ] >>url ;
+
+: <user-posts-action> ( -- action )
+    <page-action>
+        "author" >>rest
+        [
+            validate-author
+            list-posts "posts" set-value
+        ] >>init
+        { blogs "user-posts" } >>template ;
+
+: <user-posts-feed-action> ( -- action )
+    <feed-action>
+        [ validate-author ] >>init
+        [ "Recent Posts by " "author" value append ] >>title
+        [ list-posts ] >>entries
+        [ "author" value user-posts-url ] >>url ;
+
+: <post-feed-action> ( -- action )
+    <feed-action>
+        [ validate-integer-id "id" value post "post" set-value ] >>init
+        [ "post" value feed-entry-title ] >>title
+        [ "post" value entity-url ] >>url
+        [ "post" value comments>> ] >>entries ;
+
+: <view-post-action> ( -- action )
+    <page-action>
+        "id" >>rest
+
+        [
+            validate-integer-id
+            "id" value post from-object
+
+            "id" value
+            "new-comment" [
+                "parent" set-value
+            ] nest-values
+        ] >>init
+
+        { blogs "view-post" } >>template ;
+
+: validate-post ( -- )
+    {
+        { "title" [ v-one-line ] }
+        { "content" [ v-required ] }
+    } validate-params ;
+
+: <new-post-action> ( -- action )
+    <page-action>
+        [
+            validate-post
+            uid "author" set-value
+        ] >>validate
+
+        [
+            f <post>
+                dup { "title" "content" } deposit-slots
+                uid >>author
+                now >>date
+            [ insert-tuple ] [ entity-url <redirect> ] bi
+        ] >>submit
+
+        { blogs "new-post" } >>template ;
+
+: <edit-post-action> ( -- action )
+    <page-action>
+        [
+            validate-integer-id
+            "id" value <post> select-tuple from-object
+        ] >>init
+
+        [
+            validate-integer-id
+            validate-post
+        ] >>validate
+
+        [
+            "id" value <post> select-tuple
+                dup { "title" "content" } deposit-slots
+            [ update-tuple ] [ entity-url <redirect> ] bi
+        ] >>submit
+
+        { blogs "edit-post" } >>template ;
+    
+: <delete-post-action> ( -- action )
+    <action>
+        [
+            validate-integer-id
+            { { "author" [ v-username ] } } validate-params
+        ] >>validate
+        [
+            "id" value <post> delete-tuples
+            "author" value user-posts-url <redirect>
+        ] >>submit ;
+
+: validate-comment ( -- )
+    {
+        { "parent" [ v-integer ] }
+        { "content" [ v-required ] }
+    } validate-params ;
+
+: <new-comment-action> ( -- action )
+    <action>
+
+        [
+            validate-comment
+            uid "author" set-value
+        ] >>validate
+
+        [
+            "parent" value f <comment>
+                "content" value >>content
+                uid >>author
+                now >>date
+            [ insert-tuple ] [ entity-url <redirect> ] bi
+        ] >>submit ;
+    
+: <delete-comment-action> ( -- action )
+    <action>
+        [
+            validate-integer-id
+            { { "parent" [ v-integer ] } } validate-params
+        ] >>validate
+        [
+            f "id" value <comment> delete-tuples
+            "parent" value view-post-url <redirect>
+        ] >>submit ;
+    
+: <blogs> ( -- dispatcher )
+    blogs new-dispatcher
+        <list-posts-action> "" add-responder
+        <list-posts-feed-action> "posts.atom" add-responder
+        <user-posts-action> "by" add-responder
+        <user-posts-feed-action> "by.atom" add-responder
+        <view-post-action> "post" add-responder
+        <post-feed-action> "post.atom" add-responder
+        <new-post-action> <protected>
+            "make a new blog post" >>description
+            "new-post" add-responder
+        <edit-post-action> <protected>
+            "edit a blog post" >>description
+            "edit-post" add-responder
+        <delete-post-action> <protected>
+            "delete a blog post" >>description
+            "delete-post" add-responder
+        <new-comment-action> <protected>
+            "make a comment" >>description
+            "new-comment" add-responder
+        <delete-comment-action> <protected>
+            "delete a comment" >>description
+            "delete-comment" add-responder
+    <boilerplate>
+        { blogs "blogs-common" } >>template ;
diff --git a/extra/webapps/blogs/edit-post.xml b/extra/webapps/blogs/edit-post.xml
new file mode 100644 (file)
index 0000000..da88a78
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>Edit: <t:label t:name="title" /></t:title>
+
+       <div class="post-form">
+               <t:form t:action="$blogs/edit-post" t:for="id">
+
+                       <p>Title: <t:field t:name="title" t:size="60" /></p>
+                       <p><t:textarea t:name="content" t:rows="30" t:cols="80" /></p>
+                       <input type="SUBMIT" value="Done" />
+               </t:form>
+       </div>
+
+       <div class="posting-footer">
+               Post by
+               <t:a t:href="$blogs/" t:query="author">
+                       <t:label t:name="author" />
+               </t:a>
+               on
+               <t:label t:name="date" />
+               |
+               <t:a t:href="$blogs/post" t:for="id">View Post</t:a>
+               |
+               <t:button t:action="$blogs/delete-post" t:for="id,author" class="link-button link">Delete Post</t:button>
+       </div>
+
+</t:chloe>
diff --git a/extra/webapps/blogs/list-posts.xml b/extra/webapps/blogs/list-posts.xml
new file mode 100644 (file)
index 0000000..9c9685f
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>Recent Posts</t:title>
+
+       <t:bind-each t:name="posts">
+
+               <h2 class="post-title">
+                       <t:a t:href="$blogs/post" t:query="id">
+                               <t:label t:name="title" />
+                       </t:a>
+               </h2>
+
+               <p class="posting-body">
+                       <t:farkup t:name="content" />
+               </p>
+
+               <div class="posting-footer">
+                       Post by
+                       <t:a t:href="$blogs/by" t:query="author">
+                               <t:label t:name="author" />
+                       </t:a>
+                       on
+                       <t:label t:name="date" />
+                       |
+                       <t:a t:href="$blogs/post" t:query="id">
+                               <t:label t:name="comments" />
+                               comments.
+                       </t:a>
+               </div>
+
+       </t:bind-each>
+
+</t:chloe>
diff --git a/extra/webapps/blogs/new-post.xml b/extra/webapps/blogs/new-post.xml
new file mode 100644 (file)
index 0000000..9cb0250
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>New Post</t:title>
+
+       <div class="post-form">
+               <t:form t:action="$blogs/new-post">
+       
+                       <p>Title: <t:field t:name="title" t:size="60" /></p>
+                       <p><t:textarea t:name="content" t:rows="30" t:cols="80" /></p>
+                       <input type="SUBMIT" value="Done" />
+               </t:form>
+       </div>
+
+       <t:validation-messages />
+</t:chloe>
diff --git a/extra/webapps/blogs/user-posts.xml b/extra/webapps/blogs/user-posts.xml
new file mode 100644 (file)
index 0000000..95fae23
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:atom t:href="$blogs/by" t:query="author">
+               Recent Posts by <t:label t:name="author" />
+       </t:atom>
+
+       <t:title>
+               Recent Posts by <t:label t:name="author" />
+       </t:title>
+
+       <t:bind-each t:name="posts">
+
+               <h2 class="post-title">
+                       <t:a t:href="$blogs/post" t:query="id">
+                               <t:label t:name="title" />
+                       </t:a>
+               </h2>
+
+               <p class="posting-body">
+                       <t:farkup t:name="content" />
+               </p>
+
+               <div class="posting-footer">
+                       Post by
+                       <t:a t:href="$blogs/by" t:query="author">
+                               <t:label t:name="author" />
+                       </t:a>
+                       on
+                       <t:label t:name="date" />
+                       |
+                       <t:a t:href="$blogs/post" t:query="id">
+                               <t:label t:name="comments" />
+                               comments.
+                       </t:a>
+               </div>
+
+       </t:bind-each>
+
+</t:chloe>
diff --git a/extra/webapps/blogs/view-post.xml b/extra/webapps/blogs/view-post.xml
new file mode 100644 (file)
index 0000000..23bf513
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:atom t:href="$blogs/post.atom" t:query="id">
+               <t:label t:name="author" />: <t:label t:name="title" />
+       </t:atom>
+
+       <t:atom t:href="$blogs/by.atom" t:query="author">
+               Recent Posts by <t:label t:name="author" />
+       </t:atom>
+
+       <t:title> <t:label t:name="author" />: <t:label t:name="title" /> </t:title>
+
+       <p class="posting-body">
+               <t:farkup t:name="content" />
+       </p>
+
+       <div class="posting-footer">
+               Post by
+               <t:a t:href="$blogs/" t:query="author">
+                       <t:label t:name="author" />
+               </t:a>
+               on
+               <t:label t:name="date" />
+               |
+               <t:a t:href="$blogs/edit-post" t:query="id">Edit Post</t:a>
+               |
+               <t:button t:action="$blogs/delete-post" t:for="id,author" class="link-button link">Delete Post</t:button>
+       </div>
+
+       <t:bind-each t:name="comments">
+               <hr/>
+
+               <p class="comment-header">
+                       Comment by <t:label t:name="author" /> on <t:label t:name="date" />:
+               </p>
+
+               <p class="posting-body">
+                       <t:farkup t:name="content" />
+               </p>
+               
+               <t:button t:action="$blogs/delete-comment" t:for="id,parent" class="link-button link">Delete Comment</t:button>
+
+       </t:bind-each>
+
+       <t:bind t:name="new-comment">
+
+               <h2>New Comment</h2>
+
+               <div class="post-form">
+                       <t:form t:action="$blogs/new-comment" t:for="parent">
+                               <p><t:textarea t:name="content" t:rows="20" t:cols="60" /></p>
+                               <p><input type="SUBMIT" value="Done" /></p>
+                       </t:form>
+               </div>
+
+       </t:bind>
+
+</t:chloe>
index 853af6e84520bf2b9687545f8e47de0e53d28411..f56a9b5c6f01a0f786bb4e392cb29f7668b90cec 100644 (file)
@@ -6,19 +6,22 @@ namespaces db db.sqlite smtp
 http.server
 http.server.dispatchers
 furnace.db
-furnace.flows
+furnace.asides
+furnace.flash
 furnace.sessions
 furnace.auth.login
 furnace.auth.providers.db
 furnace.boilerplate
+webapps.blogs
 webapps.pastebin
 webapps.planet
 webapps.todo
 webapps.wiki
+webapps.wee-url
 webapps.user-admin ;
 IN: webapps.factor-website
 
-: test-db "resource:test.db" sqlite-db ;
+: test-db ( -- db params ) "resource:test.db" sqlite-db ;
 
 : init-factor-db ( -- )
     test-db [
@@ -35,16 +38,23 @@ IN: webapps.factor-website
 
         init-articles-table
         init-revisions-table
+
+        init-postings-table
+        init-comments-table
+
+        init-short-url-table
     ] with-db ;
 
 TUPLE: factor-website < dispatcher ;
 
 : <factor-website> ( -- responder )
-    factor-website new-dispatcher 
+    factor-website new-dispatcher
+        <blogs> "blogs" add-responder
         <todo-list> "todo" add-responder
         <pastebin> "pastebin" add-responder
         <planet-factor> "planet" add-responder
         <wiki> "wiki" add-responder
+        <wee-url> "wee-url" add-responder
         <user-admin> "user-admin" add-responder
     <login>
         users-in-db >>users
@@ -53,8 +63,7 @@ TUPLE: factor-website < dispatcher ;
         allow-edit-profile
     <boilerplate>
         { factor-website "page" } >>template
-    <flows>
-    <sessions>
+    <asides> <flash-scopes> <sessions>
     test-db <db-persistence> ;
 
 : init-factor-website ( -- )
index 9f35d83fd8d4e18f583c87723f27d0062ab3b6ff..1c138fc8c0835ebd534fb77863d152e03b2b5633 100644 (file)
@@ -2,7 +2,9 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:title="This paste" t:href="$pastebin/paste.atom" t:query="id" />
+       <t:atom t:href="$pastebin/paste.atom" t:query="id">
+               Paste: <t:label t:name="summary" />
+       </t:atom>
 
        <t:title>Paste: <t:label t:name="summary" /></t:title>
 
@@ -28,7 +30,7 @@
 
                <pre class="description"><t:code t:name="contents" t:mode="mode"/></pre>
 
-               <t:button t:action="$pastebin/delete-annotation" t:for="aid" class="link-button link">Delete Annotation</t:button>
+               <t:button t:action="$pastebin/delete-annotation" t:for="id" class="link-button link">Delete Annotation</t:button>
 
        </t:bind-each>
 
 
                <h2>New Annotation</h2>
 
-               <t:form t:action="$pastebin/new-annotation" t:for="id">
+               <t:form t:action="$pastebin/new-annotation" t:for="parent">
 
                        <table>
                                <tr><th class="field-label">Summary: </th><td><t:field t:name="summary" /></td></tr>
                                <tr><th class="field-label">Author: </th><td><t:field t:name="author" /></td></tr>
                                <tr><th class="field-label">Mode: </th><td><t:choice t:name="mode" t:choices="modes" /></td></tr>
-                               <tr><th class="field-label big-field-label">Body:</th><td><t:textarea t:name="contents" t:rows="20" t:cols="60" /></td></tr>
+                               <tr><th class="field-label big-field-label">Body: </th><td><t:textarea t:name="contents" t:rows="20" t:cols="60" /></td></tr>
                                <tr><th class="field-label">Captcha: </th><td><t:field t:name="captcha" /></td></tr>
                                <tr>
                                <td></td>
@@ -51,6 +53,7 @@
                        </table>
 
                        <input type="SUBMIT" value="Done" />
+
                </t:form>
 
        </t:bind>
index 5ef44ad6ce2e57916aa46625c874632b66d0a230..47f7666b2234076142483fd3c1c3ba3ea0949f27 100644 (file)
@@ -2,7 +2,7 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:title="Pastebin" t:href="$pastebin/list.atom" />
+       <t:atom t:href="$pastebin/list.atom">Pastebin</t:atom>
 
        <t:style t:include="resource:extra/webapps/pastebin/pastebin.css" />
 
                <t:if t:code="furnace.sessions:uid">
 
                        <t:if t:code="furnace.auth.login:allow-edit-profile?">
-                               | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                               | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
                        </t:if>
 
-                       | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+                       | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
 
                </t:if>
 
index 69650b4d73f83d45962406eaf4ed85a7b6af429b..2fbe5b4816ce610a2b94007539759a8a0ce69d1c 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces assocs sorting sequences kernel accessors
 hashtables sequences.lib db.types db.tuples db combinators
-calendar calendar.format math.parser rss urls xml.writer
+calendar calendar.format math.parser syndication urls xml.writer
 xmode.catalog validators
 html.components
 html.templates.chloe
@@ -14,7 +14,7 @@ furnace.actions
 furnace.auth
 furnace.auth.login
 furnace.boilerplate
-furnace.rss ;
+furnace.syndication ;
 IN: webapps.pastebin
 
 TUPLE: pastebin < dispatcher ;
@@ -35,6 +35,14 @@ entity f
     { "contents" "CONTENTS" TEXT +not-null+ }
 } define-persistent
 
+GENERIC: entity-url ( entity -- url )
+
+M: entity feed-entry-title summary>> ;
+
+M: entity feed-entry-date date>> ;
+
+M: entity feed-entry-url entity-url ;
+
 TUPLE: paste < entity annotations ;
 
 \ paste "PASTES" { } define-persistent
@@ -58,39 +66,31 @@ annotation "ANNOTATIONS"
         swap >>id
         swap >>parent ;
 
-: fetch-annotations ( paste -- paste )
-    dup annotations>> [
-        dup id>> f <annotation> select-tuples >>annotations
-    ] unless ;
-
 : paste ( id -- paste )
-    <paste> select-tuple fetch-annotations ;
+    [ <paste> select-tuple ]
+    [ f <annotation> select-tuples ]
+    bi >>annotations ;
 
 ! ! !
 ! LINKS, ETC
 ! ! !
 
-: pastebin-link ( -- url )
+: pastebin-url ( -- url )
     URL" $pastebin/list" ;
 
-GENERIC: entity-link ( entity -- url )
-
-: paste-link ( id -- url )
-    <url>
-        "$pastebin/paste" >>path
-        swap "id" set-query-param ;
+: paste-url ( id -- url )
+    "$pastebin/paste" >url swap "id" set-query-param ;
 
-M: paste entity-link
-    id>> paste-link ;
+M: paste entity-url
+    id>> paste-url ;
 
-: annotation-link ( parent id -- url )
-    <url>
-        "$pastebin/paste" >>path
+: annotation-url ( parent id -- url )
+    "$pastebin/paste" >url
         swap number>string >>anchor
         swap "id" set-query-param ;
 
-M: annotation entity-link
-    [ parent>> ] [ id>> ] bi annotation-link ;
+M: annotation entity-url
+    [ parent>> ] [ id>> ] bi annotation-url ;
 
 ! ! !
 ! PASTE LIST
@@ -101,24 +101,11 @@ M: annotation entity-link
         [ pastes "pastes" set-value ] >>init
         { pastebin "pastebin" } >>template ;
 
-: pastebin-feed-entries ( seq -- entries )
-    <reversed> 20 short head [
-        entry new
-            swap
-            [ summary>> >>title ]
-            [ date>> >>pub-date ]
-            [ entity-link adjust-url relative-to-request >>link ]
-            tri
-    ] map ;
-
-: pastebin-feed ( -- feed )
-    feed new
-        "Factor Pastebin" >>title
-        pastebin-link >>link
-        pastes pastebin-feed-entries >>entries ;
-
 : <pastebin-feed-action> ( -- action )
-    <feed-action> [ pastebin-feed ] >>feed ;
+    <feed-action>
+        [ pastebin-url ] >>url
+        [ "Factor Pastebin" ] >>title
+        [ pastes <reversed> ] >>entries ;
 
 ! ! !
 ! PASTES
@@ -132,7 +119,7 @@ M: annotation entity-link
 
             "id" value
             "new-annotation" [
-                "id" set-value
+                "parent" set-value
                 mode-names "modes" set-value
                 "factor" "mode" set-value
             ] nest-values
@@ -140,21 +127,12 @@ M: annotation entity-link
 
         { pastebin "paste" } >>template ;
 
-: paste-feed-entries ( paste -- entries )
-    fetch-annotations annotations>> pastebin-feed-entries ;
-
-: paste-feed ( paste -- feed )
-    feed new
-        swap
-        [ "Paste " swap id>> number>string append >>title ]
-        [ entity-link adjust-url relative-to-request >>link ]
-        [ paste-feed-entries >>entries ]
-        tri ;
-
 : <paste-feed-action> ( -- action )
     <feed-action>
         [ validate-integer-id ] >>init
-        [ "id" value paste paste-feed ] >>feed ;
+        [ "id" value paste-url ] >>url
+        [ "Paste " "id" value number>string append ] >>title
+        [ "id" value f <annotation> select-tuples ] >>entries ;
 
 : validate-entity ( -- )
     {
@@ -186,7 +164,7 @@ M: annotation entity-link
             f <paste>
             [ deposit-entity-slots ]
             [ insert-tuple ]
-            [ id>> paste-link <redirect> ]
+            [ id>> paste-url <redirect> ]
             tri
         ] >>submit ;
 
@@ -207,20 +185,15 @@ M: annotation entity-link
 : <new-annotation-action> ( -- action )
     <action>
         [
-            { { "id" [ v-integer ] } } validate-params
-            "id" value paste-link <redirect>
-        ] >>display
-
-        [
-            { { "id" [ v-integer ] } } validate-params
+            { { "parent" [ v-integer ] } } validate-params
             validate-entity
         ] >>validate
 
         [
-            "id" value f <annotation>
+            "parent" value f <annotation>
             [ deposit-entity-slots ]
             [ insert-tuple ]
-            [ entity-link <redirect> ]
+            [ entity-url <redirect> ]
             tri
         ] >>submit ;
 
@@ -231,7 +204,7 @@ M: annotation entity-link
         [
             f "id" value <annotation> select-tuple
             [ delete-tuples ]
-            [ parent>> paste-link <redirect> ]
+            [ parent>> paste-url <redirect> ]
             bi
         ] >>submit ;
 
@@ -246,12 +219,16 @@ can-delete-pastes? define-capability
         <paste-action> "paste" add-responder
         <paste-feed-action> "paste.atom" add-responder
         <new-paste-action> "new-paste" add-responder
-        <delete-paste-action> { can-delete-pastes? } <protected> "delete-paste" add-responder
+        <delete-paste-action> <protected>
+            "delete pastes" >>description
+            { can-delete-pastes? } >>capabilities "delete-paste" add-responder
         <new-annotation-action> "new-annotation" add-responder
-        <delete-annotation-action> { can-delete-pastes? } <protected> "delete-annotation" add-responder
+        <delete-annotation-action> <protected>
+            "delete annotations" >>description
+            { can-delete-pastes? } >>capabilities "delete-annotation" add-responder
     <boilerplate>
         { pastebin "pastebin-common" } >>template ;
 
-: init-pastes-table \ paste ensure-table ;
+: init-pastes-table ( -- ) \ paste ensure-table ;
 
-: init-annotations-table annotation ensure-table ;
+: init-annotations-table ( -- ) annotation ensure-table ;
index 26a3e6f2066824330fb4638c0bdb7607421027c0..192592489e35a04065d65d7b67b59059bcd02f88 100644 (file)
@@ -14,9 +14,9 @@
                </t:bind-each>
        </ul>
 
-       <p>
+       <div>
                <t:a t:href="$planet-factor/admin/new-blog">Add Blog</t:a>
                | <t:button t:action="$planet-factor/admin/update" class="link-button link">Update</t:button>
-       </p>
+       </div>
 
 </t:chloe>
diff --git a/extra/webapps/planet/entry-summary.xml b/extra/webapps/planet/entry-summary.xml
deleted file mode 100644 (file)
index 70274d6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version='1.0' ?>
-
-<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
-
-       <p class="news">
-               <strong><t:view t:component="title" /></strong> <br/>
-               <t:a value="link" class="more">Read More...</t:a>
-       </p>
-
-</t:chloe>
diff --git a/extra/webapps/planet/entry.xml b/extra/webapps/planet/entry.xml
deleted file mode 100644 (file)
index 01fda67..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version='1.0' ?>
-
-<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
-
-       <h2 class="posting-title">
-               <t:a t:value="link"><t:view t:component="title" /></t:a>
-       </h2>
-
-       <p class="posting-body">
-               <t:view t:component="description" />
-       </p>
-
-       <p class="posting-date">
-               <t:a t:value="link"><t:view t:component="pub-date" /></t:a>
-       </p>
-
-</t:chloe>
index 8de7216b0e98d8c6ab78cf5c2c27e71d652e2933..661c2dc0f7d9ff416c1e3b1a644a0620177353a4 100644 (file)
@@ -5,7 +5,7 @@
        <t:bind-each t:name="postings">
 
                <p class="news">
-                       <strong><t:view t:component="title" /></strong> <br/>
+                       <strong><t:label t:name="title" /></strong> <br/>
                        <t:a value="link" class="more">Read More...</t:a>
                </p>
 
index e92f88c2c22b55ae93b5200cd7863f393f45a527..34ee73da677feb9b69a48a8462f46a72e32a3bcb 100644 (file)
 
                <t:if t:code="furnace.sessions:uid">
                        <t:if t:code="furnace.auth.login:allow-edit-profile?">
-                               | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                               | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
                        </t:if>
        
-                       | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+                       | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
                </t:if>
        </div>
 
index c5fa5e25d44bcd3ca22a2e861fa35c29919aa121..3e780132b4e04cfc8ba096359f17f5ffb8bef243 100755 (executable)
@@ -4,7 +4,7 @@ USING: kernel accessors sequences sorting math math.order
 calendar alarms logging concurrency.combinators namespaces
 sequences.lib db.types db.tuples db fry locals hashtables
 html.components
-rss urls xml.writer
+syndication urls xml.writer
 validators
 http.server
 http.server.dispatchers
@@ -13,7 +13,7 @@ furnace.actions
 furnace.boilerplate
 furnace.auth.login
 furnace.auth
-furnace.rss ;
+furnace.syndication ;
 IN: webapps.planet
 
 TUPLE: planet-factor < dispatcher ;
@@ -34,21 +34,20 @@ blog "BLOGS"
     { "feed-url" "FEEDURL" { VARCHAR 256 } +not-null+ }
 } define-persistent
 
-! TUPLE: posting < entry id ;
-TUPLE: posting id title link description pub-date ;
+TUPLE: posting < entry id ;
 
 posting "POSTINGS"
 {
     { "id" "ID" INTEGER +db-assigned-id+ }
     { "title" "TITLE" { VARCHAR 256 } +not-null+ }
-    { "link" "LINK" { VARCHAR 256 } +not-null+ }
+    { "url" "LINK" { VARCHAR 256 } +not-null+ }
     { "description" "DESCRIPTION" TEXT +not-null+ }
-    { "pub-date" "DATE" TIMESTAMP +not-null+ }
+    { "date" "DATE" TIMESTAMP +not-null+ }
 } define-persistent
 
-: init-blog-table blog ensure-table ;
+: init-blog-table ( -- ) blog ensure-table ;
 
-: init-postings-table posting ensure-table ;
+: init-postings-table ( -- ) posting ensure-table ;
 
 : <blog> ( id -- todo )
     blog new
@@ -60,7 +59,7 @@ posting "POSTINGS"
 
 : postings ( -- seq )
     posting new select-tuples
-    [ [ pub-date>> ] compare invert-comparison ] sort ;
+    [ [ date>> ] compare invert-comparison ] sort ;
 
 : <edit-blogroll-action> ( -- action )
     <page-action>
@@ -76,21 +75,18 @@ posting "POSTINGS"
 
         { planet-factor "planet" } >>template ;
 
-: planet-feed ( -- feed )
-    feed new
-        "Planet Factor" >>title
-        "http://planet.factorcode.org" >>link
-        postings >>entries ;
-
 : <planet-feed-action> ( -- action )
-    <feed-action> [ planet-feed ] >>feed ;
+    <feed-action>
+        [ "Planet Factor" ] >>title
+        [ URL" $planet-factor" ] >>url
+        [ postings ] >>entries ;
 
 :: <posting> ( entry name -- entry' )
     posting new
         name ": " entry title>> 3append >>title
-        entry link>> >>link
+        entry url>> >>url
         entry description>> >>description
-        entry pub-date>> >>pub-date ;
+        entry date>> >>date ;
 
 : fetch-feed ( url -- feed )
     download-feed entries>> ;
@@ -102,7 +98,7 @@ posting "POSTINGS"
     [ '[ , <posting> ] map ] 2map concat ;
 
 : sort-entries ( entries -- entries' )
-    [ [ pub-date>> ] compare invert-comparison ] sort ;
+    [ [ date>> ] compare invert-comparison ] sort ;
 
 : update-cached-postings ( -- )
     blogroll fetch-blogroll sort-entries 8 short head [
@@ -197,8 +193,11 @@ can-administer-planet-factor? define-capability
 : <planet-factor> ( -- responder )
     planet-factor new-dispatcher
         <planet-action> "list" add-main-responder
-        <feed-action> "feed.xml" add-responder
-        <planet-factor-admin> { can-administer-planet-factor? } <protected> "admin" add-responder
+        <planet-feed-action> "feed.xml" add-responder
+        <planet-factor-admin> <protected>
+            "administer Planet Factor" >>description
+            { can-administer-planet-factor? } >>capabilities
+        "admin" add-responder
     <boilerplate>
         { planet-factor "planet-common" } >>template ;
 
index 213c314d7a756bb95e167a9b6e4024593775061e..fe4d23bd3bbc74feca29736f4ff4d42c305c7b8f 100644 (file)
@@ -11,7 +11,7 @@
                                <t:bind-each t:name="postings">
 
                                        <h2 class="posting-title">
-                                               <t:a t:value="link"><t:label t:name="title" /></t:a>
+                                               <t:a t:value="url"><t:label t:name="title" /></t:a>
                                        </h2>
 
                                        <p class="posting-body">
@@ -19,7 +19,7 @@
                                        </p>
 
                                        <p class="posting-date">
-                                               <t:a t:value="link"><t:label t:name="pub-date" /></t:a>
+                                               <t:a t:value="url"><t:label t:name="date" /></t:a>
                                        </p>
 
                                </t:bind-each>
index 3600e2f874b58fce996735bf7fe0d310d3a5bd29..7cad1eb6ae960f29edb2e84295e7d3f61cdea810 100755 (executable)
@@ -28,7 +28,7 @@ todo "TODO"
     { "description" "DESCRIPTION" { VARCHAR 256 } }
 } define-persistent
 
-: init-todo-table todo ensure-table ;
+: init-todo-table ( -- ) todo ensure-table ;
 
 : <todo> ( id -- todo )
     todo new
@@ -51,6 +51,9 @@ todo "TODO"
         { "description" [ v-required ] }
     } validate-params ;
 
+: view-todo-url ( id -- url )
+    <url> "$todo-list/view" >>path swap "id" set-query-param ;
+
 : <new-action> ( -- action )
     <page-action>
         [ 0 "priority" set-value ] >>init
@@ -62,14 +65,7 @@ todo "TODO"
         [
             f <todo>
                 dup { "summary" "priority" "description" } deposit-slots
-            [ insert-tuple ]
-            [
-                <url>
-                    "$todo-list/view" >>path
-                    swap id>> "id" set-query-param
-                <redirect>
-            ]
-            bi
+            [ insert-tuple ] [ id>> view-todo-url <redirect> ] bi
         ] >>submit ;
 
 : <edit-action> ( -- action )
@@ -89,23 +85,19 @@ todo "TODO"
         [
             f <todo>
                 dup { "id" "summary" "priority" "description" } deposit-slots
-            [ update-tuple ]
-            [
-                <url>
-                    "$todo-list/view" >>path
-                    swap id>> "id" set-query-param
-                <redirect>
-            ]
-            bi
+            [ update-tuple ] [ id>> view-todo-url <redirect> ] bi
         ] >>submit ;
 
+: todo-list-url ( -- url )
+    URL" $todo-list/list" ;
+
 : <delete-action> ( -- action )
     <action>
         [ validate-integer-id ] >>validate
 
         [
             "id" get <todo> delete-tuples
-            URL" $todo-list/list" <redirect>
+            todo-list-url <redirect>
         ] >>submit ;
 
 : <list-action> ( -- action )
@@ -122,4 +114,5 @@ todo "TODO"
         <delete-action> "delete" add-responder
     <boilerplate>
         { todo-list "todo" } >>template
-    f <protected> ;
+    <protected>
+        "view your todo list" >>description ;
index 3dd0b9a7d13b279b1a0938f50219d8017ddb2508..e087fbfcfc2b4fd58ed85a0bfaae6c7f6e291faf 100644 (file)
@@ -9,10 +9,10 @@
                | <t:a t:href="$todo-list/new">Add Item</t:a>
 
                <t:if t:code="furnace.auth.login:allow-edit-profile?">
-                       | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                       | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
                </t:if>
 
-               | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+               | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
        </div>
 
        <h1><t:write-title /></h1>
index b8687274f095a744f149adac11f12915714b58be..19153e13541b7d41ca25859a4987e708555f6f2a 100644 (file)
@@ -18,18 +18,6 @@ IN: webapps.user-admin
 
 TUPLE: user-admin < dispatcher ;
 
-: word>string ( word -- string )
-    [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ;
-
-: words>strings ( seq -- seq' )
-    [ word>string ] map ;
-
-: string>word ( string -- word )
-    ":" split1 swap lookup ;
-
-: strings>words ( seq -- seq' )
-    [ string>word ] map ;
-
 : <user-list-action> ( -- action )
     <page-action>
         [ f <user> select-tuples "users" set-value ] >>init
@@ -95,7 +83,7 @@ TUPLE: user-admin < dispatcher ;
             [ from-object ]
             [ capabilities>> [ "true" swap word>string set-value ] each ] bi
 
-            capabilities get words>strings "capabilities" set-value
+            init-capabilities
         ] >>init
 
         { user-admin "edit-user" } >>template
@@ -156,7 +144,9 @@ can-administer-users? define-capability
         <delete-user-action> "delete" add-responder
     <boilerplate>
         { user-admin "user-admin" } >>template
-    { can-administer-users? } <protected> ;
+    <protected>
+        "administer users" >>description
+        { can-administer-users? } >>capabilities ;
 
 : make-admin ( username -- )
     <user>
index 93a701a6963734cb60eb26166f333a7959597bb0..9cb9ef0a0acabc87d2af8c3985993ef425f1884b 100644 (file)
@@ -7,10 +7,10 @@
                | <t:a t:href="$user-admin/new">Add User</t:a>
 
                <t:if t:code="furnace.auth.login:allow-edit-profile?">
-                       | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                       | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
                </t:if>
 
-               | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+               | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
        </div>
 
        <h1><t:write-title /></h1>
diff --git a/extra/webapps/wee-url/shorten.xml b/extra/webapps/wee-url/shorten.xml
new file mode 100644 (file)
index 0000000..8df7774
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+        <t:form t:action="$wee-url">
+               <p>Shorten URL: <t:field t:name="url" t:size="40" /></p>
+               <input type="submit" value="Shorten" />
+       </t:form>
+
+</t:chloe>
diff --git a/extra/webapps/wee-url/show.xml b/extra/webapps/wee-url/show.xml
new file mode 100644 (file)
index 0000000..ba44629
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <p>The URL:</p>
+       <blockquote><t:link t:name="url" /></blockquote>
+       <p>has been shortened to:</p>
+       <blockquote><t:link t:name="short" /></blockquote>
+       <p>enjoy!</p>
+
+</t:chloe>
diff --git a/extra/webapps/wee-url/wee-url.factor b/extra/webapps/wee-url/wee-url.factor
new file mode 100644 (file)
index 0000000..afdacf9
--- /dev/null
@@ -0,0 +1,74 @@
+! Copyright (C) 2007 Doug Coleman.
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math.ranges sequences random accessors combinators.lib
+kernel namespaces fry db.types db.tuples urls validators
+html.components http http.server.dispatchers furnace
+furnace.actions furnace.boilerplate ;
+IN: webapps.wee-url
+
+TUPLE: wee-url < dispatcher ;
+
+TUPLE: short-url short url ;
+
+short-url "SHORT_URLS" {
+    { "short" "SHORT" TEXT +user-assigned-id+ }
+    { "url" "URL" TEXT +not-null+ }
+} define-persistent
+
+: init-short-url-table ( -- )
+    short-url ensure-table ;
+
+: letter-bank ( -- seq )
+    CHAR: a CHAR: z [a,b]
+    CHAR: A CHAR: Z [a,b]
+    CHAR: 1 CHAR: 0 [a,b]
+    3append ; foldable
+
+: random-url ( -- string )
+    1 6 [a,b] random [ drop letter-bank random ] "" map-as ;
+
+: insert-short-url ( short-url -- short-url )
+    '[ , dup random-url >>short insert-tuple ] 10 retry ;
+
+: shorten ( url -- short )
+    short-url new swap >>url dup select-tuple
+    [ ] [ insert-short-url ] ?if short>> ;
+
+: short>url ( short -- url )
+    "$wee-url/go/" prepend >url adjust-url ;
+
+: expand-url ( string -- url )
+    short-url new swap >>short select-tuple url>> ;
+
+: <shorten-action> ( -- action )
+    <page-action>
+        { wee-url "shorten" } >>template
+        [ { { "url" [ v-url ] } } validate-params ] >>validate
+        [
+            "$wee-url/show/" "url" value shorten append >url <redirect>
+        ] >>submit ;
+
+: <show-action> ( -- action )
+    <page-action>
+        "short" >>rest
+        [
+            { { "short" [ v-one-word ] } } validate-params
+            "short" value expand-url "url" set-value
+            "short" value short>url "short" set-value
+        ] >>init
+        { wee-url "show" } >>template ;
+
+: <go-action> ( -- action )
+    <action>
+        "short" >>rest
+        [ { { "short" [ v-one-word ] } } validate-params ] >>init
+        [ "short" value expand-url <redirect> ] >>display ;
+
+: <wee-url> ( -- wee-url )
+    wee-url new-dispatcher
+        <shorten-action> "" add-responder
+        <show-action> "show" add-responder
+        <go-action> "go" add-responder
+    <boilerplate>
+        { wee-url "wee-url" } >>template ;
diff --git a/extra/webapps/wee-url/wee-url.xml b/extra/webapps/wee-url/wee-url.xml
new file mode 100644 (file)
index 0000000..98d1095
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>WeeURL!</t:title>
+
+       <div class="navbar"><t:a t:href="$wee-url">Shorten URL</t:a></div>
+
+       <h1><t:write-title /></h1>
+
+        <t:call-next-template />
+
+</t:chloe>
index 95fb0de2feb89392132965d2db5234d0097036ea..5b3e9de2c4f914a292087228a0d7b114055d07cd 100644 (file)
@@ -7,7 +7,7 @@
        <ul>
                <t:bind-each t:name="changes">
                        <li>
-                               <t:a t:href="title" t:query="title"><t:label t:name="title" /></t:a>
+                               <t:a t:href="view" t:query="title"><t:label t:name="title" /></t:a>
                                on
                                <t:a t:href="revision" t:query="id"><t:label t:name="date" /></t:a>
                                by
index 1d4b5073208362e714215e519260befd455a9dc6..675cb8cd65747bee5fe119ce9c7a03d07d788dcb 100644 (file)
@@ -2,6 +2,10 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
+       <t:atom t:href="$wiki/revisions.atom" t:query="title">
+               Revisions of <t:label t:name="title" />
+       </t:atom>
+
        <t:call-next-template />
 
        <div class="navbar">
index 61809802d99bfa1af980e4a0648d688390360d67..6f22982f126265d269970ec124d3cc967f8898ac 100644 (file)
@@ -2,6 +2,10 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
+       <t:atom t:href="$wiki/user-edits.atom" t:query="author">
+               Edits by <t:label t:name="author" />
+       </t:atom>
+
        <t:title>Edits by <t:label t:name="author" /></t:title>
 
        <ul>
index 67a5b91c934d3c873130d6d050abbf3cde7f815c..4c6d1a5b5c63ddcab18e4d20e66d877fc712d662 100644 (file)
@@ -2,6 +2,10 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
+       <t:atom t:href="$wiki/changes.atom">
+               Recent Changes
+       </t:atom>
+
        <t:style t:include="resource:extra/webapps/wiki/wiki.css" />
 
        <div class="navbar">
                <t:if t:code="furnace.sessions:uid">
 
                        <t:if t:code="furnace.auth.login:allow-edit-profile?">
-                               | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                               | <t:a t:href="$login/edit-profile" t:aside="begin">Edit Profile</t:a>
                        </t:if>
 
-                       | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+                       | <t:button t:action="$login/logout" t:aside="begin" class="link-button link">Logout</t:button>
 
                </t:if>
 
index 6dcf89e208514eb547d7f1bf10842e248eaad77f..21a983fc7b4f6a51f918186b16a94f4a17d493e2 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel hashtables calendar
 namespaces splitting sequences sorting math.order
-html.components
+html.components syndication
 http.server
 http.server.dispatchers
 furnace
@@ -10,10 +10,26 @@ furnace.actions
 furnace.auth
 furnace.auth.login
 furnace.boilerplate
+furnace.syndication
 validators
 db.types db.tuples lcs farkup urls ;
 IN: webapps.wiki
 
+: view-url ( title -- url )
+    "$wiki/view/" prepend >url ;
+
+: edit-url ( title -- url )
+    "$wiki/edit" >url swap "title" set-query-param ;
+
+: revisions-url ( title -- url )
+    "$wiki/revisions" >url swap "title" set-query-param ;
+
+: revision-url ( id -- url )
+    "$wiki/revision" >url swap "id" set-query-param ;
+
+: user-edits-url ( author -- url )
+    "$wiki/user-edits" >url swap "author" set-query-param ;
+
 TUPLE: wiki < dispatcher ;
 
 TUPLE: article title revision ;
@@ -27,7 +43,7 @@ article "ARTICLES" {
 
 : <article> ( title -- article ) article new swap >>title ;
 
-: init-articles-table article ensure-table ;
+: init-articles-table ( -- ) article ensure-table ;
 
 TUPLE: revision id title author date content ;
 
@@ -39,26 +55,34 @@ revision "REVISIONS" {
     { "content" "CONTENT" TEXT +not-null+ }
 } define-persistent
 
+M: revision feed-entry-title
+    [ title>> ] [ drop " by " ] [ author>> ] tri 3append ;
+
+M: revision feed-entry-date date>> ;
+
+M: revision feed-entry-url id>> revision-url ;
+
+: reverse-chronological-order ( seq -- sorted )
+    [ [ date>> ] compare invert-comparison ] sort ;
+
 : <revision> ( id -- revision )
     revision new swap >>id ;
 
-: init-revisions-table revision ensure-table ;
+: init-revisions-table ( -- ) revision ensure-table ;
 
 : validate-title ( -- )
     { { "title" [ v-one-line ] } } validate-params ;
 
+: validate-author ( -- )
+    { { "author" [ v-username ] } } validate-params ;
+
 : <main-article-action> ( -- action )
     <action>
-        [
-            <url>
-                "$wiki/view" >>path
-                "Front Page" "title" set-query-param
-            <redirect>
-        ] >>display ;
+        [ "Front Page" view-url <redirect> ] >>display ;
 
 : <view-article-action> ( -- action )
     <action>
-        "title" >>rest-param
+        "title" >>rest
 
         [
             validate-title
@@ -70,19 +94,17 @@ revision "REVISIONS" {
                 revision>> <revision> select-tuple from-object
                 { wiki "view" } <chloe-content>
             ] [
-                <url>
-                    "$wiki/edit" >>path
-                    swap "title" set-query-param
-                <redirect>
+                edit-url <redirect>
             ] ?if
         ] >>display ;
 
 : <view-revision-action> ( -- action )
     <page-action>
         [
-            { { "id" [ v-integer ] } } validate-params
+            validate-integer-id
             "id" value <revision>
             select-tuple from-object
+            "view?title=" relative-link-prefix set
         ] >>init
 
         { wiki "view" } >>template ;
@@ -117,53 +139,53 @@ revision "REVISIONS" {
                 now >>date
                 logged-in-user get username>> >>author
                 "content" value >>content
-            [ add-revision ]
-            [
-                <url>
-                    "$wiki/view" >>path
-                    swap title>> "title" set-query-param
-                <redirect>
-            ] bi
+            [ add-revision ] [ title>> view-url <redirect> ] bi
         ] >>submit ;
 
+: list-revisions ( -- seq )
+    f <revision> "title" value >>title select-tuples
+    reverse-chronological-order ;
+
 : <list-revisions-action> ( -- action )
     <page-action>
         [
             validate-title
-            f <revision> "title" value >>title select-tuples
-            [ [ date>> ] compare invert-comparison ] sort
-            "revisions" set-value
+            list-revisions "revisions" set-value
         ] >>init
-
         { wiki "revisions" } >>template ;
 
+: <list-revisions-feed-action> ( -- action )
+    <feed-action>
+        [ validate-title ] >>init
+        [ "Revisions of " "title" value append ] >>title
+        [ "title" value revisions-url ] >>url
+        [ list-revisions ] >>entries ;
+
 : <rollback-action> ( -- action )
     <action>
-        [
-            { { "id" [ v-integer ] } } validate-params
-        ] >>validate
-        
+        [ validate-integer-id ] >>validate
+
         [
             "id" value <revision> select-tuple clone f >>id
-            [ add-revision ]
-            [
-                <url>
-                    "$wiki/view" >>path
-                    swap title>> "title" set-query-param
-                <redirect>
-            ] bi
+            [ add-revision ] [ title>> view-url <redirect> ] bi
         ] >>submit ;
 
+: list-changes ( -- seq )
+    "id" value <revision> select-tuples
+    reverse-chronological-order ;
+
 : <list-changes-action> ( -- action )
     <page-action>
-        [
-            f <revision> select-tuples
-            [ [ date>> ] compare invert-comparison ] sort
-            "changes" set-value
-        ] >>init
+        [ list-changes "changes" set-value ] >>init
 
         { wiki "changes" } >>template ;
 
+: <list-changes-feed-action> ( -- action )
+    <feed-action>
+        [ URL" $wiki/changes" ] >>url
+        [ "All changes" ] >>title
+        [ list-changes ] >>entries ;
+
 : <delete-action> ( -- action )
     <action>
         [ validate-title ] >>validate
@@ -204,32 +226,53 @@ revision "REVISIONS" {
 
         { wiki "articles" } >>template ;
 
+: list-user-edits ( -- seq )
+    f <revision> "author" value >>author select-tuples
+    reverse-chronological-order ;
+
 : <user-edits-action> ( -- action )
     <page-action>
         [
-            { { "author" [ v-username ] } } validate-params
-            f <revision> "author" value >>author
-            select-tuples "user-edits" set-value
+            validate-author
+            list-user-edits "user-edits" set-value
         ] >>init
-
         { wiki "user-edits" } >>template ;
 
+: <user-edits-feed-action> ( -- action )
+    <feed-action>
+        [ validate-author ] >>init
+        [ "Edits by " "author" value append ] >>title
+        [ "author" value user-edits-url ] >>url
+        [ list-user-edits ] >>entries ;
+
+SYMBOL: can-delete-wiki-articles?
+
+can-delete-wiki-articles? define-capability
+
+: <article-boilerplate> ( responder -- responder' )
+    <boilerplate>
+        { wiki "page-common" } >>template ;
+
 : <wiki> ( -- dispatcher )
     wiki new-dispatcher
-        <dispatcher>
-            <main-article-action> "" add-responder
-            <view-article-action> "view" add-responder
-            <view-revision-action> "revision" add-responder
-            <list-revisions-action> "revisions" add-responder
-            <diff-action> "diff" add-responder
-            <edit-article-action> { } <protected> "edit" add-responder
-        <boilerplate>
-            { wiki "page-common" } >>template
-        >>default
+        <main-article-action> <article-boilerplate> "" add-responder
+        <view-article-action> <article-boilerplate> "view" add-responder
+        <view-revision-action> <article-boilerplate> "revision" add-responder
+        <list-revisions-action> <article-boilerplate> "revisions" add-responder
+        <list-revisions-feed-action> "revisions.atom" add-responder
+        <diff-action> <article-boilerplate> "diff" add-responder
+        <edit-article-action> <article-boilerplate> <protected>
+            "edit wiki articles" >>description
+            "edit" add-responder
         <rollback-action> "rollback" add-responder
         <user-edits-action> "user-edits" add-responder
         <list-articles-action> "articles" add-responder
         <list-changes-action> "changes" add-responder
-        <delete-action> { } <protected> "delete" add-responder
+        <user-edits-feed-action> "user-edits.atom" add-responder
+        <list-changes-feed-action> "changes.atom" add-responder
+        <delete-action> <protected>
+            "delete wiki articles" >>description
+            { can-delete-wiki-articles? } >>capabilities
+        "delete" add-responder
     <boilerplate>
         { wiki "wiki-common" } >>template ;
old mode 100644 (file)
new mode 100755 (executable)
index 0d2f164..b738196
@@ -1,4 +1,4 @@
-USING: alien.syntax kernel math windows.types math.bitfields ;
+USING: alias alien.syntax kernel math windows.types math.bitfields ;
 IN: windows.advapi32
 LIBRARY: advapi32
 
@@ -164,9 +164,9 @@ TYPEDEF: ACCESS_ALLOWED_CALLBACK_ACE* PACCESS_ALLOWED_CALLBACK_ACE
 : TOKEN_QUERY                  HEX: 0008 ; inline
 : TOKEN_QUERY_SOURCE           HEX: 0010 ; inline
 : TOKEN_ADJUST_DEFAULT         HEX: 0080 ; inline
-: TOKEN_READ STANDARD_RIGHTS_READ TOKEN_QUERY bitor ;
+: TOKEN_READ ( -- n ) STANDARD_RIGHTS_READ TOKEN_QUERY bitor ;
 
-: TOKEN_WRITE
+: TOKEN_WRITE ( -- n )
     {
         STANDARD_RIGHTS_WRITE
         TOKEN_ADJUST_PRIVILEGES
@@ -174,7 +174,7 @@ TYPEDEF: ACCESS_ALLOWED_CALLBACK_ACE* PACCESS_ALLOWED_CALLBACK_ACE
         TOKEN_ADJUST_DEFAULT
     } flags ; foldable
 
-: TOKEN_ALL_ACCESS
+: TOKEN_ALL_ACCESS ( -- n )
     {
         STANDARD_RIGHTS_REQUIRED
         TOKEN_ASSIGN_PRIMARY
@@ -336,7 +336,8 @@ FUNCTION: BOOL CryptAcquireContextW ( HCRYPTPROV* phProv,
                                       DWORD dwProvType,
                                       DWORD dwFlags ) ;
 
-: CryptAcquireContext CryptAcquireContextW ;
+ALIAS: CryptAcquireContext CryptAcquireContextW
+
 ! : CryptContextAddRef ;
 ! : CryptCreateHash ;
 ! : CryptDecrypt ;
@@ -496,7 +497,7 @@ FUNCTION: BOOL CryptReleaseContext ( HCRYPTPROV hProv, DWORD dwFlags ) ;
 
 ! : GetUserNameA ;
 FUNCTION: BOOL GetUserNameW ( LPCTSTR lpBuffer, LPDWORD lpnSize ) ;
-: GetUserName GetUserNameW ;
+ALIAS: GetUserName GetUserNameW
 
 ! : GetWindowsAccountDomainSid ;
 ! : I_ScIsSecurityProcess ;
@@ -541,7 +542,7 @@ FUNCTION: BOOL InitializeAcl ( PACL pAcl, DWORD nAclLength, DWORD dwAclRevision
 FUNCTION: BOOL LookupPrivilegeValueW ( LPCTSTR lpSystemName,
                                LPCTSTR lpName,
                                PLUID lpLuid ) ;
-: LookupPrivilegeValue LookupPrivilegeValueW ;
+ALIAS: LookupPrivilegeValue LookupPrivilegeValueW
 
 ! : LookupSecurityDescriptorPartsA ;
 ! : LookupSecurityDescriptorPartsW ;
index b63a5c333796eda71cf87e071ac4bcf13ef82f07..ac2b5122c045a477c3a6adad3461ded38ba09c24 100755 (executable)
@@ -1,6 +1,7 @@
 USING: alien alien.c-types kernel windows.ole32 combinators.lib
-parser splitting sequences.lib sequences namespaces assocs
-quotations shuffle accessors words macros alien.syntax fry ;
+parser splitting grouping sequences.lib sequences namespaces
+assocs quotations shuffle accessors words macros alien.syntax
+fry ;
 IN: windows.com.syntax
 
 <PRIVATE
old mode 100644 (file)
new mode 100755 (executable)
index b1f9d8a..b9ba518
@@ -1,7 +1,7 @@
 ! FUNCTION: AbortDoc
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax kernel windows.types ;
+USING: alien alien.syntax kernel windows.types alias ;
 IN: windows.gdi32
 
 ! Stock Logical Objects
old mode 100644 (file)
new mode 100755 (executable)
index 36f8b51..0ac41a1
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax kernel windows.types ;
+USING: alien alien.syntax kernel windows.types alias ;
 IN: windows.kernel32
 
 : MAX_PATH 260 ; inline
@@ -594,7 +594,7 @@ FUNCTION: BOOL ConnectNamedPipe ( HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped )
 ! FUNCTION: CopyFileExA
 ! FUNCTION: CopyFileExW
 FUNCTION: BOOL CopyFileW ( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists ) ;
-: CopyFile CopyFileW ; inline
+ALIAS: CopyFile CopyFileW
 ! FUNCTION: CopyLZFile
 ! FUNCTION: CreateActCtxA
 ! FUNCTION: CreateActCtxW
@@ -603,7 +603,7 @@ FUNCTION: BOOL CopyFileW ( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BO
 ! FUNCTION: CreateDirectoryExA
 ! FUNCTION: CreateDirectoryExW
 FUNCTION: BOOL CreateDirectoryW ( LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttribytes ) ;
-: CreateDirectory CreateDirectoryW ; inline
+ALIAS: CreateDirectory CreateDirectoryW
 
 ! FUNCTION: CreateEventA
 ! FUNCTION: CreateEventW
@@ -612,7 +612,7 @@ FUNCTION: BOOL CreateDirectoryW ( LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSe
 
 
 FUNCTION: HANDLE CreateFileW ( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttribures, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) ;
-: CreateFile CreateFileW ; inline
+ALIAS: CreateFile CreateFileW
 
 FUNCTION: HANDLE  CreateFileMappingW ( HANDLE hFile,
                                        LPSECURITY_ATTRIBUTES lpAttributes,
@@ -620,7 +620,7 @@ FUNCTION: HANDLE  CreateFileMappingW ( HANDLE hFile,
                                        DWORD dwMaximumSizeHigh,
                                        DWORD dwMaximumSizeLow,
                                        LPCTSTR lpName ) ;
-: CreateFileMapping CreateFileMappingW ;
+ALIAS: CreateFileMapping CreateFileMappingW
 
 ! FUNCTION: CreateHardLinkA
 ! FUNCTION: CreateHardLinkW
@@ -636,7 +636,7 @@ FUNCTION: HANDLE CreateIoCompletionPort ( HANDLE hFileHandle, HANDLE hExistingCo
 ! FUNCTION: CreateMutexW
 ! FUNCTION: CreateNamedPipeA
 FUNCTION: HANDLE CreateNamedPipeW ( LPCTSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes ) ;
-: CreateNamedPipe CreateNamedPipeW ;
+ALIAS: CreateNamedPipe CreateNamedPipeW
 
 ! FUNCTION: CreateNlsSecurityDescriptor
 FUNCTION: BOOL CreatePipe ( PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize ) ;
@@ -675,7 +675,7 @@ FUNCTION: BOOL CreateProcessW ( LPCTSTR lpApplicationname,
                                 LPCTSTR lpCurrentDirectory,
                                 LPSTARTUPINFO lpStartupInfo,
                                 LPPROCESS_INFORMATION lpProcessInformation ) ;
-: CreateProcess CreateProcessW ;
+ALIAS: CreateProcess CreateProcessW
 ! FUNCTION: CreateProcessInternalA
 ! FUNCTION: CreateProcessInternalW
 ! FUNCTION: CreateProcessInternalWSecure
@@ -713,7 +713,7 @@ FUNCTION: HANDLE CreateRemoteThread ( HANDLE hProcess,
 ! FUNCTION: DeleteFiber
 ! FUNCTION: DeleteFileA
 FUNCTION: BOOL DeleteFileW ( LPCTSTR lpFileName ) ;
-: DeleteFile DeleteFileW ;
+ALIAS: DeleteFile DeleteFileW
 ! FUNCTION: DeleteTimerQueue
 ! FUNCTION: DeleteTimerQueueEx
 ! FUNCTION: DeleteTimerQueueTimer
@@ -804,12 +804,12 @@ FUNCTION: BOOL FindCloseChangeNotification ( HANDLE hChangeHandle ) ;
 FUNCTION: HANDLE FindFirstChangeNotificationW ( LPCTSTR lpPathName,
                                         BOOL bWatchSubtree,
                                         DWORD dwNotifyFilter ) ;
-: FindFirstChangeNotification FindFirstChangeNotificationW ;
+ALIAS: FindFirstChangeNotification FindFirstChangeNotificationW
 ! FUNCTION: FindFirstFileA
 ! FUNCTION: FindFirstFileExA
 ! FUNCTION: FindFirstFileExW
 FUNCTION: HANDLE FindFirstFileW ( LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData ) ;
-: FindFirstFile FindFirstFileW ;
+ALIAS: FindFirstFile FindFirstFileW
 ! FUNCTION: FindFirstVolumeA
 ! FUNCTION: FindFirstVolumeMountPointA
 ! FUNCTION: FindFirstVolumeMountPointW
@@ -817,7 +817,7 @@ FUNCTION: HANDLE FindFirstFileW ( LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFi
 FUNCTION: BOOL FindNextChangeNotification ( HANDLE hChangeHandle ) ;
 ! FUNCTION: FindNextFileA
 FUNCTION: BOOL FindNextFileW ( HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData ) ;
-: FindNextFile FindNextFileW ;
+ALIAS: FindNextFile FindNextFileW
 ! FUNCTION: FindNextVolumeA
 ! FUNCTION: FindNextVolumeMountPointA
 ! FUNCTION: FindNextVolumeMountPointW
@@ -867,7 +867,7 @@ FUNCTION: BOOL FindNextFileW ( HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileDat
 FUNCTION: BOOL GetComputerNameW ( LPTSTR lpBuffer, LPDWORD lpnSize ) ;
 ! FUNCTION: GetComputerNameExW
 ! FUNCTION: GetComputerNameW
-: GetComputerName GetComputerNameW ;
+ALIAS: GetComputerName GetComputerNameW
 ! FUNCTION: GetConsoleAliasA
 ! FUNCTION: GetConsoleAliasesA
 ! FUNCTION: GetConsoleAliasesLengthA
@@ -902,7 +902,7 @@ FUNCTION: BOOL GetComputerNameW ( LPTSTR lpBuffer, LPDWORD lpnSize ) ;
 ! FUNCTION: GetConsoleScreenBufferInfo
 ! FUNCTION: GetConsoleSelectionInfo
 FUNCTION: DWORD GetConsoleTitleW ( LPWSTR lpConsoleTitle, DWORD nSize ) ;
-: GetConsoleTitle GetConsoleTitleW ; inline
+ALIAS: GetConsoleTitle GetConsoleTitleW
 ! FUNCTION: GetConsoleWindow
 ! FUNCTION: GetCPFileNameFromRegistry
 ! FUNCTION: GetCPInfo
@@ -914,7 +914,7 @@ FUNCTION: DWORD GetConsoleTitleW ( LPWSTR lpConsoleTitle, DWORD nSize ) ;
 ! FUNCTION: GetCurrentConsoleFont
 ! FUNCTION: GetCurrentDirectoryA
 FUNCTION: BOOL GetCurrentDirectoryW ( DWORD len, LPTSTR buf ) ;
-: GetCurrentDirectory GetCurrentDirectoryW ; inline
+ALIAS: GetCurrentDirectory GetCurrentDirectoryW
 FUNCTION: HANDLE GetCurrentProcess ( ) ;
 FUNCTION: DWORD GetCurrentProcessId ( ) ;
 FUNCTION: HANDLE GetCurrentThread ( ) ;
@@ -951,7 +951,7 @@ FUNCTION: DWORD GetFileAttributesW ( LPCTSTR lpFileName ) ;
 
 FUNCTION: BOOL GetFileAttributesExW ( LPCTSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation ) ;
 
-: GetFileAttributesEx GetFileAttributesExW ;
+ALIAS: GetFileAttributesEx GetFileAttributesExW
 
 FUNCTION: BOOL GetFileInformationByHandle ( HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation ) ;
 FUNCTION: DWORD GetFileSize ( HANDLE hFile, LPDWORD lpFileSizeHigh ) ;
@@ -962,7 +962,7 @@ FUNCTION: DWORD GetFileType ( HANDLE hFile ) ;
 ! FUNCTION: GetFirmwareEnvironmentVariableW
 ! FUNCTION: GetFullPathNameA
 FUNCTION: DWORD GetFullPathNameW ( LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR* lpFilePart ) ;
-: GetFullPathName GetFullPathNameW ;
+ALIAS: GetFullPathName GetFullPathNameW
 
 !  clear "license.txt" 32768 "char[32768]" <c-object> f over >r GetFullPathName r> swap 2 * head >string .
 
@@ -985,7 +985,7 @@ FUNCTION: DWORD GetLastError ( ) ;
 ! FUNCTION: GetModuleFileNameA
 ! FUNCTION: GetModuleFileNameW
 FUNCTION: HMODULE GetModuleHandleW ( LPCWSTR lpModuleName ) ;
-: GetModuleHandle GetModuleHandleW ; inline
+ALIAS: GetModuleHandle GetModuleHandleW
 ! FUNCTION: GetModuleHandleExA
 ! FUNCTION: GetModuleHandleExW
 ! FUNCTION: GetNamedPipeHandleStateA
@@ -1051,7 +1051,7 @@ FUNCTION: HANDLE GetStdHandle ( DWORD nStdHandle ) ;
 ! FUNCTION: GetSystemDefaultUILanguage
 ! FUNCTION: GetSystemDirectoryA
 FUNCTION: UINT GetSystemDirectoryW ( LPTSTR lpBuffer, UINT uSize ) ;
-: GetSystemDirectory GetSystemDirectoryW ; inline
+ALIAS: GetSystemDirectory GetSystemDirectoryW
 FUNCTION: void GetSystemInfo ( LPSYSTEM_INFO lpSystemInfo ) ;
 ! FUNCTION: GetSystemPowerStatus
 ! FUNCTION: GetSystemRegistryQuota
@@ -1061,7 +1061,7 @@ FUNCTION: void GetSystemTimeAsFileTime ( LPFILETIME lpSystemTimeAsFileTime ) ;
 ! FUNCTION: GetSystemTimes
 ! FUNCTION: GetSystemWindowsDirectoryA
 FUNCTION: UINT GetSystemWindowsDirectoryW ( LPTSTR lpBuffer, UINT uSize ) ;
-: GetSystemWindowsDirectory GetSystemWindowsDirectoryW ; inline
+ALIAS: GetSystemWindowsDirectory GetSystemWindowsDirectoryW
 ! FUNCTION: GetSystemWow64DirectoryA
 ! FUNCTION: GetSystemWow64DirectoryW
 ! FUNCTION: GetTapeParameters
@@ -1089,7 +1089,7 @@ FUNCTION: DWORD GetTimeZoneInformation ( LPTIME_ZONE_INFORMATION lpTimeZoneInfor
 ! FUNCTION: GetVDMCurrentDirectories
 FUNCTION: DWORD GetVersion ( ) ;
 FUNCTION: BOOL GetVersionExW ( LPOSVERSIONINFO lpVersionInfo ) ;
-: GetVersionEx GetVersionExW ;
+ALIAS: GetVersionEx GetVersionExW
 ! FUNCTION: GetVolumeInformationA
 ! FUNCTION: GetVolumeInformationW
 ! FUNCTION: GetVolumeNameForVolumeMountPointA
@@ -1100,7 +1100,7 @@ FUNCTION: BOOL GetVersionExW ( LPOSVERSIONINFO lpVersionInfo ) ;
 ! FUNCTION: GetVolumePathNameW
 ! FUNCTION: GetWindowsDirectoryA
 FUNCTION: UINT GetWindowsDirectoryW ( LPTSTR lpBuffer, UINT uSize ) ;
-: GetWindowsDirectory GetWindowsDirectoryW ; inline
+ALIAS: GetWindowsDirectory GetWindowsDirectoryW
 ! FUNCTION: GetWriteWatch
 ! FUNCTION: GlobalAddAtomA
 ! FUNCTION: GlobalAddAtomW
@@ -1252,7 +1252,7 @@ FUNCTION: LPVOID MapViewOfFileEx ( HANDLE hFileMappingObject,
 ! FUNCTION: MoveFileExA
 ! FUNCTION: MoveFileExW
 FUNCTION: BOOL MoveFileW ( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName ) ;
-: MoveFile MoveFileW ;
+ALIAS: MoveFile MoveFileW
 ! FUNCTION: MoveFileWithProgressA
 ! FUNCTION: MoveFileWithProgressW
 ! FUNCTION: MulDiv
@@ -1270,7 +1270,7 @@ FUNCTION: BOOL MoveFileW ( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName ) ;
 FUNCTION: HANDLE OpenFileMappingW ( DWORD dwDesiredAccess,
                                     BOOL bInheritHandle,
                                     LPCTSTR lpName ) ;
-: OpenFileMapping OpenFileMappingW ;
+ALIAS: OpenFileMapping OpenFileMappingW
 ! FUNCTION: OpenJobObjectA
 ! FUNCTION: OpenJobObjectW
 ! FUNCTION: OpenMutexA
@@ -1340,7 +1340,7 @@ FUNCTION: BOOL ReadProcessMemory ( HANDLE hProcess, void* lpBaseAddress, void* l
 ! FUNCTION: ReleaseSemaphore
 ! FUNCTION: RemoveDirectoryA
 FUNCTION: BOOL RemoveDirectoryW ( LPCTSTR lpPathName ) ;
-: RemoveDirectory RemoveDirectoryW ;
+ALIAS: RemoveDirectory RemoveDirectoryW
 ! FUNCTION: RemoveLocalAlternateComputerNameA
 ! FUNCTION: RemoveLocalAlternateComputerNameW
 ! FUNCTION: RemoveVectoredExceptionHandler
@@ -1404,13 +1404,13 @@ FUNCTION: BOOL RemoveDirectoryW ( LPCTSTR lpPathName ) ;
 ! FUNCTION: SetConsoleScreenBufferSize
 FUNCTION: BOOL SetConsoleTextAttribute ( HANDLE hConsoleOutput, WORD wAttributes ) ;
 FUNCTION: BOOL SetConsoleTitleW ( LPCWSTR lpConsoleTitle ) ;
-: SetConsoleTitle SetConsoleTitleW ;
+ALIAS: SetConsoleTitle SetConsoleTitleW
 ! FUNCTION: SetConsoleWindowInfo
 ! FUNCTION: SetCPGlobal
 ! FUNCTION: SetCriticalSectionSpinCount
 ! FUNCTION: SetCurrentDirectoryA
 FUNCTION: BOOL SetCurrentDirectoryW ( LPCWSTR lpDirectory ) ;
-: SetCurrentDirectory SetCurrentDirectoryW ; inline
+ALIAS: SetCurrentDirectory SetCurrentDirectoryW
 ! FUNCTION: SetDefaultCommConfigA
 ! FUNCTION: SetDefaultCommConfigW
 ! FUNCTION: SetDllDirectoryA
old mode 100644 (file)
new mode 100755 (executable)
index c38579c..ca2206e
@@ -71,7 +71,7 @@ IN: windows.opengl32
 : WGL_SWAP_UNDERLAY14     HEX: 20000000 ; inline
 : WGL_SWAP_UNDERLAY15     HEX: 40000000 ; inline
 
-: pfd-dwFlags
+: pfd-dwFlags ( -- n )
     { PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL PFD_DOUBLEBUFFER } flags ;
 
 ! TODO: compare to http://www.nullterminator.net/opengl32.html
old mode 100644 (file)
new mode 100755 (executable)
index e3e8a23..49a04dc
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.syntax parser namespaces kernel math
-windows.types shuffle math.bitfields ;
+windows.types shuffle math.bitfields alias ;
 IN: windows.user32
 
 ! HKL for ActivateKeyboardLayout
@@ -32,7 +32,7 @@ IN: windows.user32
 : WS_MAXIMIZEBOX      HEX: 00010000 ; inline
 
 ! Common window styles
-: WS_OVERLAPPEDWINDOW
+: WS_OVERLAPPEDWINDOW ( -- n )
     {
         WS_OVERLAPPED
         WS_CAPTION
@@ -42,7 +42,7 @@ IN: windows.user32
         WS_MAXIMIZEBOX
     } flags ; foldable
 
-: WS_POPUPWINDOW
+: WS_POPUPWINDOW ( -- n )
     { WS_POPUP WS_BORDER WS_SYSMENU } flags ; foldable
 
 : WS_CHILDWINDOW      WS_CHILD ; inline
@@ -50,7 +50,7 @@ IN: windows.user32
 : WS_TILED            WS_OVERLAPPED ; inline
 : WS_ICONIC           WS_MINIMIZE ; inline
 : WS_SIZEBOX          WS_THICKFRAME ; inline
-: WS_TILEDWINDOW      WS_OVERLAPPEDWINDOW ; inline
+: WS_TILEDWINDOW WS_OVERLAPPEDWINDOW ; inline
 
 ! Extended window styles
 
@@ -606,14 +606,14 @@ FUNCTION: BOOL CloseClipboard ( ) ;
 ! FUNCTION: CloseWindowStation
 ! FUNCTION: CopyAcceleratorTableA
 FUNCTION: int CopyAcceleratorTableW ( HACCEL hAccelSrc, LPACCEL lpAccelDst, int cAccelEntries ) ;
-: CopyAcceleratorTable CopyAcceleratorTableW ; inline
+ALIAS: CopyAcceleratorTable CopyAcceleratorTableW
 ! FUNCTION: CopyIcon
 ! FUNCTION: CopyImage
 ! FUNCTION: CopyRect
 ! FUNCTION: CountClipboardFormats
 ! FUNCTION: CreateAcceleratorTableA
 FUNCTION: HACCEL CreateAcceleratorTableW ( LPACCEL lpaccl, int cEntries ) ;
-: CreateAcceleratorTable CreateAcceleratorTableW ; inline
+ALIAS: CreateAcceleratorTable CreateAcceleratorTableW
 ! FUNCTION: CreateCaret
 ! FUNCTION: CreateCursor
 ! FUNCTION: CreateDesktopA
@@ -647,9 +647,9 @@ FUNCTION: HWND CreateWindowExW (
                 HINSTANCE hInstance,
                 LPVOID lpParam ) ;
 
-: CreateWindowEx CreateWindowExW ; inline
+ALIAS: CreateWindowEx CreateWindowExW
 
-: CreateWindow 0 12 -nrot CreateWindowEx ;
+: CreateWindow 0 12 -nrot CreateWindowEx ; inline
 
 
 ! FUNCTION: CreateWindowStationA
@@ -698,7 +698,7 @@ FUNCTION: HWND CreateWindowExW (
 ! FUNCTION: DefMDIChildProcW
 ! FUNCTION: DefRawInputProc
 FUNCTION: LRESULT DefWindowProcW ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) ;
-: DefWindowProc DefWindowProcW ; inline
+ALIAS: DefWindowProc DefWindowProcW
 ! FUNCTION: DeleteMenu
 ! FUNCTION: DeregisterShellHookWindow
 FUNCTION: BOOL DestroyAcceleratorTable ( HACCEL hAccel ) ;
@@ -717,7 +717,7 @@ FUNCTION: BOOL DestroyWindow ( HWND hWnd ) ;
 ! FUNCTION: DisableProcessWindowsGhosting
 
 FUNCTION: LONG DispatchMessageW ( MSG* lpMsg ) ;
-: DispatchMessage DispatchMessageW ; inline
+ALIAS: DispatchMessage DispatchMessageW
 
 ! FUNCTION: DisplayExitWindowsWarnings
 ! FUNCTION: DlgDirListA
@@ -808,14 +808,14 @@ FUNCTION: HWND GetCapture ( ) ;
 ! FUNCTION: GetCaretBlinkTime
 ! FUNCTION: GetCaretPos
 FUNCTION: BOOL GetClassInfoW ( HINSTANCE hInst, LPCWSTR lpszClass, LPWNDCLASS lpwcx ) ;
-: GetClassInfo GetClassInfoW ;
+ALIAS: GetClassInfo GetClassInfoW
 
 FUNCTION: BOOL GetClassInfoExW ( HINSTANCE hInst, LPCWSTR lpszClass, LPWNDCLASSEX lpwcx ) ;
-: GetClassInfoEx GetClassInfoExW ; inline
+ALIAS: GetClassInfoEx GetClassInfoExW
 
 FUNCTION: ULONG_PTR GetClassLongW ( HWND hWnd, int nIndex ) ;
-: GetClassLong GetClassLongW ; inline
-: GetClassLongPtr GetClassLongW ; inline
+ALIAS: GetClassLong GetClassLongW
+ALIAS: GetClassLongPtr GetClassLongW
 
 
 ! FUNCTION: GetClassNameA
@@ -884,7 +884,7 @@ FUNCTION: SHORT GetKeyState ( int nVirtKey ) ;
 ! FUNCTION: GetMenuStringW
 
 FUNCTION: BOOL GetMessageW ( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax ) ;
-: GetMessage GetMessageW ; inline
+ALIAS: GetMessage GetMessageW
 
 ! FUNCTION: GetMessageExtraInfo
 ! FUNCTION: GetMessagePos
@@ -1020,11 +1020,11 @@ FUNCTION: HACCEL LoadAcceleratorsW ( HINSTANCE hInstance, LPCTSTR lpTableName )
 
 ! FUNCTION: HCURSOR LoadCursorW ( HINSTANCE hInstance, LPCWSTR lpCursorName ) ;
 FUNCTION: HCURSOR LoadCursorW ( HINSTANCE hInstance, ushort lpCursorName ) ;
-: LoadCursor LoadCursorW ; inline
+ALIAS: LoadCursor LoadCursorW
 
 ! FUNCTION: HICON LoadIconA ( HINSTANCE hInstance, LPCTSTR lpIconName ) ;
 FUNCTION: HICON LoadIconW ( HINSTANCE hInstance, LPCTSTR lpIconName ) ;
-: LoadIcon LoadIconW ; inline
+ALIAS: LoadIcon LoadIconW
 
 ! FUNCTION: LoadImageA
 ! FUNCTION: LoadImageW
@@ -1048,10 +1048,10 @@ FUNCTION: HICON LoadIconW ( HINSTANCE hInstance, LPCTSTR lpIconName ) ;
 ! FUNCTION: MapDialogRect
 
 FUNCTION: UINT MapVirtualKeyW ( UINT uCode, UINT uMapType ) ;
-: MapVirtualKey MapVirtualKeyW ; inline
+ALIAS: MapVirtualKey MapVirtualKeyW
 
 FUNCTION: UINT MapVirtualKeyExW ( UINT uCode, UINT uMapType, HKL dwhkl ) ;
-: MapVirtualKeyEx MapVirtualKeyExW ; inline
+ALIAS: MapVirtualKeyEx MapVirtualKeyExW
 
 ! FUNCTION: MapWindowPoints
 ! FUNCTION: MB_GetString
@@ -1093,9 +1093,9 @@ FUNCTION: int MessageBoxExW (
 ! FUNCTION: int MessageBoxIndirectW ( MSGBOXPARAMSW* params ) ;
 
 
-: MessageBox MessageBoxW ;
+ALIAS: MessageBox MessageBoxW
 
-: MessageBoxEx MessageBoxExW ;
+ALIAS: MessageBoxEx MessageBoxExW
 
 ! : MessageBoxIndirect
     ! \ MessageBoxIndirectW \ MessageBoxIndirectA unicode-exec ;
@@ -1140,7 +1140,7 @@ FUNCTION: BOOL OpenClipboard ( HWND hWndNewOwner ) ;
 ! FUNCTION: PaintMenuBar
 FUNCTION: BOOL PeekMessageA ( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ) ;
 FUNCTION: BOOL PeekMessageW ( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ) ;
-: PeekMessage PeekMessageW ;
+ALIAS: PeekMessage PeekMessageW
 
 ! FUNCTION: PostMessageA
 ! FUNCTION: PostMessageW
@@ -1166,13 +1166,13 @@ FUNCTION: void PostQuitMessage ( int nExitCode ) ;
 ! FUNCTION: RecordShutdownReason
 ! FUNCTION: RedrawWindow
 
-FUNCTION: ATOM RegisterClassA ( WNDCLASS* lpWndClass) ;
+FUNCTION: ATOM RegisterClassA ( WNDCLASS* lpWndClass ) ;
 FUNCTION: ATOM RegisterClassW ( WNDCLASS* lpWndClass ) ;
 FUNCTION: ATOM RegisterClassExA ( WNDCLASSEX* lpwcx ) ;
 FUNCTION: ATOM RegisterClassExW ( WNDCLASSEX* lpwcx ) ;
 
-: RegisterClass RegisterClassW ;
-: RegisterClassEx RegisterClassExW ;
+ALIAS: RegisterClass RegisterClassW
+ALIAS: RegisterClassEx RegisterClassExW
 
 ! FUNCTION: RegisterClipboardFormatA
 ! FUNCTION: RegisterClipboardFormatW
@@ -1208,7 +1208,7 @@ FUNCTION: int ReleaseDC ( HWND hWnd, HDC hDC ) ;
 ! FUNCTION: SendIMEMessageExW
 ! FUNCTION: UINT SendInput ( UINT nInputs, LPINPUT pInputs, int cbSize ) ;
 FUNCTION: LRESULT SendMessageW ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) ;
-: SendMessage SendMessageW ;
+ALIAS: SendMessage SendMessageW
 ! FUNCTION: SendMessageCallbackA
 ! FUNCTION: SendMessageCallbackW
 ! FUNCTION: SendMessageTimeoutA
@@ -1221,8 +1221,8 @@ FUNCTION: HWND SetCapture ( HWND hWnd ) ;
 ! FUNCTION: SetCaretPos
 
 FUNCTION: ULONG_PTR SetClassLongW ( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) ;
-: SetClassLongPtr SetClassLongW ;
-: SetClassLong SetClassLongW ;
+ALIAS: SetClassLongPtr SetClassLongW
+ALIAS: SetClassLong SetClassLongW
 
 ! FUNCTION: SetClassWord
 FUNCTION: HANDLE SetClipboardData ( UINT uFormat, HANDLE hMem ) ;
@@ -1243,7 +1243,7 @@ FUNCTION: BOOL SetForegroundWindow ( HWND hWnd ) ;
 ! FUNCTION: SetKeyboardState
 ! type is ignored
 FUNCTION: void SetLastErrorEx ( DWORD dwErrCode, DWORD dwType ) ; 
-: SetLastError 0 SetLastErrorEx ;
+: SetLastError 0 SetLastErrorEx ; inline
 ! FUNCTION: SetLayeredWindowAttributes
 ! FUNCTION: SetLogonNotifyWindow
 ! FUNCTION: SetMenu
@@ -1330,7 +1330,7 @@ FUNCTION: BOOL TrackMouseEvent ( LPTRACKMOUSEEVENT lpEventTrack ) ;
 ! FUNCTION: TranslateAccelerator
 ! FUNCTION: TranslateAcceleratorA
 FUNCTION: int TranslateAcceleratorW ( HWND hWnd, HACCEL hAccTable, LPMSG lpMsg ) ;
-: TranslateAccelerator TranslateAcceleratorW ; inline
+ALIAS: TranslateAccelerator TranslateAcceleratorW
 
 ! FUNCTION: TranslateMDISysAccel
 FUNCTION: BOOL TranslateMessage ( MSG* lpMsg ) ;
@@ -1343,7 +1343,7 @@ FUNCTION: BOOL TranslateMessage ( MSG* lpMsg ) ;
 ! FUNCTION: UnlockWindowStation
 ! FUNCTION: UnpackDDElParam
 FUNCTION: BOOL UnregisterClassW ( LPCWSTR lpClassName, HINSTANCE hInstance ) ;
-: UnregisterClass UnregisterClassW ;
+ALIAS: UnregisterClass UnregisterClassW
 ! FUNCTION: UnregisterDeviceNotification
 ! FUNCTION: UnregisterHotKey
 ! FUNCTION: UnregisterMessagePumpHook
index 3e7520d4063a33a23b3399813ad071328d32dd64..2fc1dbf12207a86d857c20c27046d94a93f01b62 100644 (file)
@@ -40,7 +40,7 @@ FUNCTION: void* error_message ( DWORD id ) ;
         win32-error-string throw
     ] when ;
 
-: expected-io-errors
+: expected-io-errors ( -- seq )
     ERROR_SUCCESS
     ERROR_IO_INCOMPLETE
     ERROR_IO_PENDING
index 57181d27048e1d0ce34b32ebc0f66f50c75fbbdc..303aefeb5f0638ce5e7ef894bfede05fe0664e55 100755 (executable)
@@ -2,7 +2,7 @@
 
 USING: alien alien.c-types alien.strings alien.syntax arrays
 byte-arrays kernel math sequences windows.types windows.kernel32
-windows.errors structs windows math.bitfields ;
+windows.errors structs windows math.bitfields alias ;
 IN: windows.winsock
 
 USE: libc
@@ -74,7 +74,7 @@ TYPEDEF: void* SOCKET
 : AI_PASSIVE     1 ; inline
 : AI_CANONNAME   2 ; inline
 : AI_NUMERICHOST 4 ; inline
-: AI_MASK { AI_PASSIVE AI_CANONNAME AI_NUMERICHOST } flags ;
+: AI_MASK ( -- n ) { AI_PASSIVE AI_CANONNAME AI_NUMERICHOST } flags ;
 
 : NI_NUMERICHOST 1 ;
 : NI_NUMERICSERV 2 ;
@@ -138,7 +138,7 @@ C-STRUCT: addrinfo
     { "sockaddr*" "addr" }
     { "addrinfo*" "next" } ;
 
-: hostent-addr hostent-addr-list *void* ; ! *uint ;
+: hostent-addr ( hostent -- addr ) hostent-addr-list *void* ; ! *uint ;
 
 LIBRARY: winsock
 
@@ -365,7 +365,7 @@ FUNCTION: SOCKET WSASocketW ( int af,
                              LPWSAPROTOCOL_INFOW lpProtocolInfo,
                              GROUP g,
                              DWORD flags ) ;
-: WSASocket WSASocketW ;
+ALIAS: WSASocket WSASocketW
 
 FUNCTION: DWORD WSAWaitForMultipleEvents ( DWORD cEvents,
                                            WSAEVENT* lphEvents,
@@ -384,7 +384,7 @@ FUNCTION: void GetAcceptExSockaddrs ( void* a, int b, int c, int d, void* e, voi
 
 : SIO_GET_EXTENSION_FUNCTION_POINTER -939524090 ; inline
 
-: WSAID_CONNECTEX
+: WSAID_CONNECTEX ( -- GUID )
     "GUID" <c-object>
     HEX: 25a207b9 over set-GUID-Data1
     HEX: ddf3 over set-GUID-Data2
index 9e1e0ef92021c149d717b7fab8793e0f74812ead..cbe3c633fc54185135d768ebba3f73863007c7e3 100755 (executable)
@@ -8,9 +8,9 @@ IN: x11.clipboard
 ! This code was based on by McCLIM's Backends/CLX/port.lisp
 ! and http://common-lisp.net/~crhodes/clx/demo/clipboard.lisp.
 
-: XA_CLIPBOARD "CLIPBOARD" x-atom ;
+: XA_CLIPBOARD ( -- atom ) "CLIPBOARD" x-atom ;
 
-: XA_UTF8_STRING "UTF8_STRING" x-atom ;
+: XA_UTF8_STRING ( -- atom ) "UTF8_STRING" x-atom ;
 
 TUPLE: x-clipboard atom contents ;
 
index 5781fdc806a646a55cb2c409f219b35d38fb2d15..fcce09380fdd2deeb44b000b8900430e6a98d717 100644 (file)
@@ -45,7 +45,7 @@ TYPEDEF: uchar KeyCode
 ! with button names below.
 
 
-: AnyModifier           1 15 shift ; ! used in GrabButton, GrabKey
+: AnyModifier          ( -- n ) 15 2^ ; ! used in GrabButton, GrabKey
 
 ! button names. Used as arguments to GrabButton and as detail in ButtonPress
 ! and ButtonRelease events.  Not to be confused with button masks above.
@@ -128,8 +128,8 @@ TYPEDEF: uchar KeyCode
 
 ! Used in SetInputFocus, GetInputFocus
 
-: RevertToNone          None ;
-: RevertToPointerRoot   PointerRoot ;
+: RevertToNone         ( -- n ) None ;
+: RevertToPointerRoot  ( -- n ) PointerRoot ;
 : RevertToParent        2 ;
 
 ! *****************************************************************
@@ -307,9 +307,9 @@ TYPEDEF: uchar KeyCode
 
 ! Flags used in StoreNamedColor, StoreColors
 
-: DoRed         1 0 shift ;
-: DoGreen       1 1 shift ;
-: DoBlue        1 2 shift ;
+: DoRed        ( -- n ) 0 2^ ;
+: DoGreen      ( -- n ) 1 2^ ;
+: DoBlue       ( -- n ) 2 2^ ;
 
 ! *****************************************************************
 ! * CURSOR STUFF
@@ -334,14 +334,14 @@ TYPEDEF: uchar KeyCode
 
 ! masks for ChangeKeyboardControl
 
-: KBKeyClickPercent     1 0 shift ;
-: KBBellPercent         1 1 shift ;
-: KBBellPitch           1 2 shift ;
-: KBBellDuration        1 3 shift ;
-: KBLed                 1 4 shift ;
-: KBLedMode             1 5 shift ;
-: KBKey                 1 6 shift ;
-: KBAutoRepeatMode      1 7 shift ;
+: KBKeyClickPercent    ( -- n ) 0 2^ ;
+: KBBellPercent        ( -- n ) 1 2^ ;
+: KBBellPitch          ( -- n ) 2 2^ ;
+: KBBellDuration       ( -- n ) 3 2^ ;
+: KBLed                ( -- n ) 4 2^ ;
+: KBLedMode            ( -- n ) 5 2^ ;
+: KBKey                ( -- n ) 6 2^ ;
+: KBAutoRepeatMode     ( -- n ) 7 2^ ;
 
 : MappingSuccess        0 ;
 : MappingBusy           1 ;
index 154bf4d6ffe196dfb8d67017f1db2cb4b37a8d62..3c0ae24a70d8fdab7653a4a7870b854e534a2c81 100755 (executable)
@@ -1079,17 +1079,17 @@ FUNCTION: Status XWithdrawWindow (
 
 ! 17.1.7 - Setting and Reading the WM_NORMAL_HINTS Property
 
-: USPosition    1 0 shift ; inline
-: USSize        1 1 shift ; inline
-: PPosition     1 2 shift ; inline
-: PSize         1 3 shift ; inline
-: PMinSize      1 4 shift ; inline
-: PMaxSize      1 5 shift ; inline
-: PResizeInc    1 6 shift ; inline
-: PAspect       1 7 shift ; inline
-: PBaseSize     1 8 shift ; inline
-: PWinGravity   1 9 shift ; inline
-: PAllHints 
+: USPosition   ( -- n ) 0 2^ ; inline
+: USSize       ( -- n ) 1 2^ ; inline
+: PPosition    ( -- n ) 2 2^ ; inline
+: PSize        ( -- n ) 3 2^ ; inline
+: PMinSize     ( -- n ) 4 2^ ; inline
+: PMaxSize     ( -- n ) 5 2^ ; inline
+: PResizeInc   ( -- n ) 6 2^ ; inline
+: PAspect      ( -- n ) 7 2^ ; inline
+: PBaseSize    ( -- n ) 8 2^ ; inline
+: PWinGravity  ( -- n ) 9 2^ ; inline
+: PAllHints    ( -- n )
     { PPosition PSize PMinSize PMaxSize PResizeInc PAspect } flags ; foldable
 
 C-STRUCT: XSizeHints
@@ -1366,7 +1366,7 @@ SYMBOL: root
 
 : x-atom ( string -- atom ) dpy get swap 0 XInternAtom ;
 
-: check-display
+: check-display ( alien -- alien' )
     [
         "Cannot connect to X server - check $DISPLAY" throw
     ] unless* ;
index 0223dfde699e9b98c1c842dc106a524208e3c085..836a85d52de6fb5716569da1a83fc9393f41e216 100644 (file)
@@ -22,6 +22,6 @@ USING: kernel hashtables xml-rpc xml calendar sequences
     put-http-response ;
 
 : test-rpc-arith
-    "add" { 1 2 } <rpc-method> send-rpc xml>string
-    "text/xml" swap "http://localhost:8080/responder/rpc/"
+    "add" { 1 2 } <rpc-method> send-rpc
+    "http://localhost:8080/responder/rpc/"
     http-post ;
index d41f66739cb0469a378d7acb2f46065848f7fcec..4b96d1331603e55128bf7e82a67cbb9023d37519 100755 (executable)
@@ -158,8 +158,7 @@ TAG: array xml>item
 
 : post-rpc ( rpc url -- rpc )
     ! This needs to do something in the event of an error
-    >r "text/xml" swap send-rpc xml>string r> http-post
-    2nip string>xml receive-rpc ;
+    >r send-rpc r> http-post nip string>xml receive-rpc ;
 
 : invoke-method ( params method url -- )
     >r swap <rpc-method> r> post-rpc ;
index 53f2046a544c77019cbc2c03ad56078e417ac3dc..58c27cabe7cdf088c88327ae147412e8bed08b27 100644 (file)
@@ -40,7 +40,7 @@ M: xml-string-error summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: mismatched < parsing-error open close ;
-: <mismatched>
+: <mismatched> ( open close -- error )
     \ mismatched parsing-error swap >>close swap >>open ;
 M: mismatched summary ( obj -- str )
     [
@@ -111,7 +111,7 @@ M: extra-attrs summary ( obj -- str )
     ] with-string-writer ;
 
 TUPLE: bad-version < parsing-error num ;
-: <bad-version>
+: <bad-version> ( num -- error )
     \ bad-version parsing-error swap >>num ;
 M: bad-version summary ( obj -- str )
     [
index f78620986562f70ae993a7548ca09377194825a7..6a9913b35e86af38e7104796993c75317791a1f7 100644 (file)
@@ -1,5 +1,5 @@
-USING: kernel strings assocs sequences hashtables sorting
-       unicode.case unicode.categories sets ;
+USING: accessors kernel strings assocs sequences hashtables
+sorting unicode.case unicode.categories sets ;
 IN: xmode.keyword-map
 
 ! Based on org.gjt.sp.jedit.syntax.KeywordMap
@@ -9,7 +9,7 @@ TUPLE: keyword-map no-word-sep ignore-case? ;
     H{ } clone { set-keyword-map-ignore-case? set-delegate }
     keyword-map construct ;
 
-: invalid-no-word-sep f swap set-keyword-map-no-word-sep ;
+: invalid-no-word-sep ( keyword-map -- ) f >>no-word-sep drop ;
 
 : handle-case ( key keyword-map -- key assoc )
     [ keyword-map-ignore-case? [ >upper ] when ] keep
@@ -25,7 +25,7 @@ M: keyword-map clear-assoc
 
 M: keyword-map >alist delegate >alist ;
 
-: (keyword-map-no-word-sep)
+: (keyword-map-no-word-sep) ( assoc -- str )
     keys concat [ alpha? not ] filter prune natural-sort ;
 
 : keyword-map-no-word-sep* ( keyword-map -- str )
index 68b2c85a7db0207e704d0f7ecb42b52e97993406..5cf367594136a5afa7d57f9ef8a23f8a7b434932 100755 (executable)
@@ -49,7 +49,8 @@ TAG: KEYWORDS ( rule-set tag -- key value )
 
 TAGS>
 
-: ?<regexp> dup [ ignore-case? get <regexp> ] when ;
+: ?<regexp> ( string/f -- regexp/f )
+    dup [ ignore-case? get <regexp> ] when ;
 
 : (parse-rules-tag) ( tag -- rule-set )
     <rule-set>
index c754db61c86725adede478261124f87be1eab965..175c8ed22f2dff2ea652c5781899eeb38288e7a4 100644 (file)
@@ -24,7 +24,7 @@ SYMBOL: ignore-case?
         [ string>token ]
     } case ;
 
-: string>rule-set-name "MAIN" or ;
+: string>rule-set-name ( string -- name ) "MAIN" or ;
 
 ! PROP, PROPS
 : parse-prop-tag ( tag -- key value )
@@ -48,30 +48,30 @@ SYMBOL: ignore-case?
     dup children>string ignore-case? get <regexp>
     swap position-attrs <matcher> ;
 
-: shared-tag-attrs
+: shared-tag-attrs ( -- )
     { "TYPE" string>token set-rule-body-token } , ; inline
 
-: delegate-attr
+: delegate-attr ( -- )
     { "DELEGATE" f set-rule-delegate } , ;
 
-: regexp-attr
+: regexp-attr ( -- )
     { "HASH_CHAR" f set-rule-chars } , ;
 
-: match-type-attr
+: match-type-attr ( -- )
     { "MATCH_TYPE" string>match-type set-rule-match-token } , ;
 
-: span-attrs
+: span-attrs ( -- )
     { "NO_LINE_BREAK" string>boolean set-rule-no-line-break? } ,
     { "NO_WORD_BREAK" string>boolean set-rule-no-word-break? } ,
     { "NO_ESCAPE" string>boolean set-rule-no-escape? } , ;
 
-: literal-start
+: literal-start ( -- )
     [ parse-literal-matcher swap set-rule-start ] , ;
 
-: regexp-start
+: regexp-start ( -- )
     [ parse-regexp-matcher swap set-rule-start ] , ;
 
-: literal-end
+: literal-end ( -- )
     [ parse-literal-matcher swap set-rule-end ] , ;
 
 ! SPAN's children
@@ -87,15 +87,15 @@ TAG: END
 
 TAGS>
 
-: parse-begin/end-tags
+: parse-begin/end-tags ( -- )
     [
         ! XXX: handle position attrs on span tag itself
         child-tags [ parse-begin/end-tag ] with each
     ] , ;
 
-: init-span-tag [ drop init-span ] , ;
+: init-span-tag ( -- ) [ drop init-span ] , ;
 
-: init-eol-span-tag [ drop init-eol-span ] , ;
+: init-eol-span-tag ( -- ) [ drop init-eol-span ] , ;
 
 : parse-keyword-tag ( tag keyword-map -- )
     >r dup name-tag string>token swap children>string r> set-at ;
index 91ccd43907affbda8e222ef0357e6cd1b23f6386..a921e6a022b79f62b2d04ba25c9027280559415b 100755 (executable)
@@ -189,7 +189,7 @@ M: mark-previous-rule handle-rule-start
     dup rule-body-token prev-token,
     rule-match-token* next-token, ;
 
-: do-escaped
+: do-escaped ( -- )
     escaped? get [
         escaped? off
         ! ...
index db59465b7b559e937e5aa5585821d5d55945cc72..0321974c9ed6edd585821058d07bd87cb3b74330 100644 (file)
@@ -45,7 +45,7 @@ SYMBOL: tag-handler-word
     CREATE tag-handler-word set
     H{ } clone tag-handlers set ; parsing
 
-: (TAG:) swap tag-handlers get set-at ;
+: (TAG:) ( name quot -- ) swap tag-handlers get set-at ;
 
 : TAG:
     f set-word
@@ -55,4 +55,4 @@ SYMBOL: tag-handler-word
 : TAGS>
     tag-handler-word get
     tag-handlers get >alist [ >r dup name-tag r> case ] curry
-    define ; parsing
+    (( tag -- )) define-declared ; parsing
index b5603103e135fa17497d8cb66a553352ad918b0c..1758d62029483822df1e85a6e52b31f5c78f957a 100644 (file)
@@ -2,5 +2,5 @@ USING: help.syntax help.markup ;
 IN: yahoo
 
 HELP: search-yahoo
-{ $values { "search" "a string" } { "num" "a positive integer" } { "seq" "sequence of arrays of length 3" } }
-{ $description "Uses Yahoo's REST API to search for the query specified in the search string, getting the number of answers specified. Returns a sequence of 3arrays, { title url summary }, each of which is a string." } ;
+{ $values { "search" search } { "seq" "sequence of arrays of length 3" } }
+{ $description "Uses Yahoo's REST API to search for the specified query, getting the number of answers specified. Returns a sequence of " { $link result } " instances." } ;
index 9d90fb68f92ec46f19f15541f5cdd66fed343261..300c95c430ae2cc289dbc718d0c33bfa0de9926d 100644 (file)
     "SYMBOLS:"
 ))
 
+(defun factor-indent-line ()
+  "Indent current line as Factor code"
+  (indent-line-to (+ (current-indentation) 4)))
+
 (defun factor-mode ()
   "A mode for editing programs written in the Factor programming language."
   (interactive)
   (setq font-lock-defaults
        '(factor-font-lock-keywords nil nil nil nil))
   (set-syntax-table factor-mode-syntax-table)
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'factor-indent-line)
   (run-hooks 'factor-mode-hook))
 
 (add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode))