]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'json' of git://github.com/rictic/factor
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 15 Nov 2008 02:30:22 +0000 (20:30 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 15 Nov 2008 02:30:22 +0000 (20:30 -0600)
413 files changed:
basis/alias/alias-docs.factor
basis/bootstrap/image/image.factor
basis/bootstrap/stage2.factor
basis/compiler/cfg/builder/builder.factor
basis/compiler/cfg/instructions/instructions.factor
basis/compiler/cfg/linearization/linearization.factor
basis/compiler/cfg/rpo/rpo.factor
basis/compiler/cfg/stacks/stacks.factor
basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/constants/constants.factor
basis/compiler/tests/codegen.factor [new file with mode: 0644]
basis/compiler/tests/templates.factor [deleted file]
basis/compiler/tree/builder/builder.factor
basis/compiler/tree/checker/checker.factor
basis/compiler/tree/cleanup/cleanup-tests.factor
basis/compiler/tree/cleanup/cleanup.factor
basis/compiler/tree/dead-code/branches/branches.factor
basis/compiler/tree/dead-code/simple/simple.factor
basis/compiler/tree/debugger/debugger.factor
basis/compiler/tree/def-use/def-use.factor
basis/compiler/tree/escape-analysis/allocations/allocations.factor
basis/compiler/tree/escape-analysis/escape-analysis-tests.factor
basis/compiler/tree/finalization/finalization.factor
basis/compiler/tree/identities/identities.factor
basis/compiler/tree/normalization/renaming/renaming.factor
basis/compiler/tree/propagation/branches/branches.factor
basis/compiler/tree/propagation/constraints/constraints.factor
basis/compiler/tree/propagation/info/info-tests.factor
basis/compiler/tree/propagation/info/info.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/propagation/propagation.factor
basis/compiler/tree/propagation/recursive/recursive.factor
basis/compiler/tree/tree.factor
basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/ppc/linux/linux.factor
basis/cpu/ppc/macosx/macosx.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/64.factor
basis/cpu/x86/64/bootstrap.factor
basis/cpu/x86/64/unix/tags.txt [new file with mode: 0644]
basis/cpu/x86/64/unix/unix.factor
basis/cpu/x86/64/winnt/tags.txt [new file with mode: 0644]
basis/cpu/x86/64/winnt/winnt.factor
basis/cpu/x86/bootstrap.factor
basis/cpu/x86/x86.factor
basis/dlists/dlists-tests.factor
basis/dlists/dlists.factor
basis/editors/emacs/emacs.factor
basis/editors/etexteditor/authors.txt [new file with mode: 0755]
basis/editors/etexteditor/etexteditor.factor [new file with mode: 0755]
basis/editors/etexteditor/summary.txt [new file with mode: 0755]
basis/editors/etexteditor/tags.txt [new file with mode: 0755]
basis/fry/fry.factor
basis/furnace/actions/actions-docs.factor [new file with mode: 0644]
basis/furnace/actions/actions.factor
basis/furnace/alloy/alloy-docs.factor [new file with mode: 0644]
basis/furnace/asides/asides-docs.factor [new file with mode: 0644]
basis/furnace/auth/features/edit-profile/edit-profile.xml
basis/furnace/auth/features/recover-password/recover-3.xml
basis/furnace/auth/features/registration/register.xml
basis/furnace/auth/login/login.xml
basis/furnace/boilerplate/boilerplate-docs.factor [new file with mode: 0644]
basis/furnace/conversations/conversations-docs.factor [new file with mode: 0644]
basis/furnace/db/db-docs.factor [new file with mode: 0644]
basis/furnace/furnace-docs.factor [new file with mode: 0644]
basis/furnace/furnace.factor
basis/furnace/json/json-docs.factor [new file with mode: 0644]
basis/furnace/redirection/redirection-docs.factor [new file with mode: 0644]
basis/furnace/referrer/referrer-docs.factor [new file with mode: 0644]
basis/furnace/sessions/sessions-docs.factor [new file with mode: 0644]
basis/furnace/syndication/syndication-docs.factor [new file with mode: 0644]
basis/grouping/authors.txt [new file with mode: 0644]
basis/grouping/grouping-docs.factor [new file with mode: 0644]
basis/grouping/grouping-tests.factor [new file with mode: 0644]
basis/grouping/grouping.factor [new file with mode: 0644]
basis/grouping/summary.txt [new file with mode: 0644]
basis/grouping/tags.txt [new file with mode: 0644]
basis/heaps/heaps.factor
basis/help/handbook/handbook.factor
basis/help/tutorial/tutorial.factor
basis/html/forms/forms-docs.factor
basis/html/forms/forms.factor
basis/html/templates/chloe/chloe-docs.factor
basis/html/templates/chloe/chloe.factor
basis/io/encodings/string/string-docs.factor
basis/io/files/listing/authors.txt [new file with mode: 0644]
basis/io/files/listing/listing-docs.factor [new file with mode: 0644]
basis/io/files/listing/listing-tests.factor [new file with mode: 0644]
basis/io/files/listing/listing.factor [new file with mode: 0755]
basis/io/files/listing/tags.txt [new file with mode: 0644]
basis/io/files/listing/unix/authors.txt [new file with mode: 0755]
basis/io/files/listing/unix/tags.txt [new file with mode: 0644]
basis/io/files/listing/unix/unix.factor [new file with mode: 0755]
basis/io/files/listing/windows/authors.txt [new file with mode: 0755]
basis/io/files/listing/windows/tags.txt [new file with mode: 0644]
basis/io/files/listing/windows/windows.factor [new file with mode: 0755]
basis/io/servers/connection/connection-docs.factor
basis/io/unix/files/files.factor
basis/io/unix/launcher/parser/parser.factor
basis/io/windows/files/files.factor [changed mode: 0644->0755]
basis/linked-assocs/authors.txt [new file with mode: 0644]
basis/linked-assocs/linked-assocs-docs.factor [new file with mode: 0644]
basis/linked-assocs/linked-assocs-tests.factor [new file with mode: 0644]
basis/linked-assocs/linked-assocs.factor [new file with mode: 0644]
basis/linked-assocs/summary.txt [new file with mode: 0644]
basis/linked-assocs/tags.txt [new file with mode: 0644]
basis/locals/locals-docs.factor
basis/locals/locals.factor
basis/macros/expander/expander.factor
basis/macros/macros.factor
basis/math/bitwise/bitwise-docs.factor
basis/math/bitwise/bitwise-tests.factor
basis/math/bitwise/bitwise.factor
basis/math/functions/functions-tests.factor
basis/math/functions/functions.factor
basis/math/intervals/intervals-tests.factor
basis/math/intervals/intervals.factor
basis/math/ratios/ratios-docs.factor
basis/math/ratios/ratios.factor
basis/opengl/opengl-docs.factor
basis/opengl/opengl.factor
basis/peg/ebnf/ebnf.factor
basis/persistent/hashtables/hashtables.factor
basis/persistent/sequences/sequences.factor
basis/prettyprint/backend/backend.factor
basis/prettyprint/prettyprint-docs.factor
basis/qualified/qualified-docs.factor
basis/qualified/qualified-tests.factor
basis/qualified/qualified.factor
basis/random/mersenne-twister/mersenne-twister.factor
basis/random/random.factor
basis/sorting/human/tags.txt
basis/sorting/insertion/tags.txt
basis/stack-checker/backend/backend-tests.factor [new file with mode: 0644]
basis/stack-checker/backend/backend.factor
basis/stack-checker/branches/branches.factor
basis/stack-checker/errors/errors.factor
basis/stack-checker/inlining/inlining.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/recursive-state/recursive-state.factor [new file with mode: 0644]
basis/stack-checker/recursive-state/tree/tree.factor [new file with mode: 0644]
basis/stack-checker/stack-checker-docs.factor
basis/stack-checker/state/state.factor
basis/stack-checker/transforms/transforms.factor
basis/stack-checker/values/values.factor [new file with mode: 0644]
basis/stack-checker/visitor/dummy/dummy.factor
basis/stack-checker/visitor/visitor.factor
basis/suffix-arrays/authors.txt [new file with mode: 0755]
basis/suffix-arrays/suffix-arrays-docs.factor [new file with mode: 0755]
basis/suffix-arrays/suffix-arrays-tests.factor [new file with mode: 0755]
basis/suffix-arrays/suffix-arrays.factor [new file with mode: 0755]
basis/suffix-arrays/summary.txt [new file with mode: 0755]
basis/suffix-arrays/tags.txt [new file with mode: 0755]
basis/suffix-arrays/words/words.factor [new file with mode: 0755]
basis/tools/crossref/crossref-docs.factor
basis/tools/deploy/windows/windows.factor
basis/tools/hexdump/authors.txt [new file with mode: 0644]
basis/tools/hexdump/hexdump-docs.factor [new file with mode: 0644]
basis/tools/hexdump/hexdump-tests.factor [new file with mode: 0644]
basis/tools/hexdump/hexdump.factor [new file with mode: 0644]
basis/tools/hexdump/summary.txt [new file with mode: 0644]
basis/tools/profiler/profiler-tests.factor
basis/tools/scaffold/scaffold.factor
basis/tools/test/test-docs.factor
basis/ui/freetype/freetype.factor
basis/ui/gadgets/buttons/buttons.factor
basis/ui/gadgets/editors/editors.factor
basis/ui/gadgets/grid-lines/grid-lines.factor
basis/ui/gadgets/labelled/labelled.factor
basis/ui/gadgets/labels/labels.factor
basis/ui/gadgets/lists/lists.factor
basis/ui/gadgets/panes/panes.factor
basis/ui/gadgets/scrollers/scrollers.factor
basis/ui/gadgets/theme/theme.factor
basis/ui/render/render-docs.factor
basis/ui/render/render.factor
basis/ui/tools/listener/listener.factor
basis/unix/groups/groups-tests.factor
basis/unix/statfs/linux/32/32.factor
basis/unix/statfs/linux/64/64.factor
basis/unix/statfs/linux/linux.factor
basis/unix/statfs/macosx/macosx.factor
basis/unix/statfs/statfs.factor
basis/unix/users/users-docs.factor
basis/unix/users/users-tests.factor
basis/unix/users/users.factor
basis/validators/validators.factor
basis/vlists/vlists-tests.factor [new file with mode: 0644]
basis/vlists/vlists.factor [new file with mode: 0644]
basis/windows/kernel32/kernel32.factor
build-support/factor.sh
core/byte-vectors/byte-vectors-tests.factor
core/combinators/combinators.factor
core/generic/generic-docs.factor
core/generic/generic.factor
core/generic/math/math.factor
core/generic/standard/engines/tag/tag.factor
core/generic/standard/engines/tuple/tuple.factor
core/generic/standard/standard-docs.factor
core/grouping/authors.txt [deleted file]
core/grouping/grouping-docs.factor [deleted file]
core/grouping/grouping-tests.factor [deleted file]
core/grouping/grouping.factor [deleted file]
core/grouping/summary.txt [deleted file]
core/grouping/tags.txt [deleted file]
core/hashtables/hashtables.factor
core/io/encodings/encodings-docs.factor
core/io/files/files-docs.factor
core/io/files/files.factor
core/kernel/kernel-docs.factor
core/namespaces/namespaces-docs.factor
core/parser/parser-docs.factor
core/parser/parser.factor
core/sbufs/sbufs.factor
core/sequences/sequences-docs.factor
core/slots/slots-tests.factor
core/slots/slots.factor
core/sorting/tags.txt
core/strings/strings.factor
core/words/words.factor
extra/advice/advice-docs.factor
extra/advice/advice-tests.factor
extra/advice/advice.factor
extra/advice/tags.txt
extra/automata/ui/ui.factor
extra/boids/ui/deploy.factor
extra/builder/build/build.factor [deleted file]
extra/builder/builder.factor [deleted file]
extra/builder/child/child.factor [deleted file]
extra/builder/cleanup/cleanup.factor [deleted file]
extra/builder/common/common.factor [deleted file]
extra/builder/email/email.factor [deleted file]
extra/builder/release/archive/archive.factor [deleted file]
extra/builder/release/branch/branch.factor [deleted file]
extra/builder/release/release.factor [deleted file]
extra/builder/release/tidy/tidy.factor [deleted file]
extra/builder/release/upload/upload.factor [deleted file]
extra/builder/report/report.factor [deleted file]
extra/builder/test/test.factor [deleted file]
extra/builder/updates/updates.factor [deleted file]
extra/builder/util/util.factor [deleted file]
extra/bunny/model/model.factor
extra/bunny/outlined/outlined.factor
extra/cairo-demo/authors.txt [new file with mode: 0755]
extra/cairo-demo/cairo-demo.factor [new file with mode: 0644]
extra/cairo/authors.txt [new file with mode: 0644]
extra/cairo/cairo.factor [new file with mode: 0755]
extra/cairo/ffi/ffi.factor [new file with mode: 0644]
extra/cairo/gadgets/gadgets.factor [new file with mode: 0644]
extra/cairo/samples/samples.factor [new file with mode: 0644]
extra/cairo/summary.txt [new file with mode: 0644]
extra/cairo/tags.txt [new file with mode: 0644]
extra/cfdg/cfdg.factor
extra/coroutines/authors.txt
extra/coroutines/coroutines-docs.factor
extra/coroutines/coroutines-tests.factor
extra/coroutines/coroutines.factor
extra/ftp/client/client.factor
extra/ftp/client/listing-parser/authors.txt [new file with mode: 0644]
extra/ftp/client/listing-parser/listing-parser.factor [new file with mode: 0644]
extra/ftp/ftp.factor
extra/ftp/server/server.factor
extra/graphics/bitmap/bitmap.factor
extra/hexdump/authors.txt [deleted file]
extra/hexdump/hexdump-docs.factor [deleted file]
extra/hexdump/hexdump-tests.factor [deleted file]
extra/hexdump/hexdump.factor [deleted file]
extra/hexdump/summary.txt [deleted file]
extra/jamshred/gl/gl.factor
extra/mason/release/branch/branch-tests.factor
extra/mason/release/tidy/tidy.factor
extra/math/algebra/algebra.factor
extra/math/analysis/analysis-docs.factor [new file with mode: 0644]
extra/math/combinatorics/combinatorics.factor
extra/math/compare/compare-docs.factor
extra/math/compare/compare-tests.factor
extra/math/compare/compare.factor
extra/math/derivatives/derivatives-tests.factor [new file with mode: 0644]
extra/math/derivatives/derivatives.factor
extra/math/erato/erato.factor
extra/math/erato/summary.txt
extra/math/fft/authors.txt [deleted file]
extra/math/fft/fft.factor [deleted file]
extra/math/fft/summary.txt [deleted file]
extra/math/finance/finance.factor
extra/math/floating-point/floating-point.factor
extra/math/function-tools/function-tools.factor
extra/math/haar/haar.factor [deleted file]
extra/math/haar/summary.txt [deleted file]
extra/math/matrices/elimination/elimination.factor
extra/math/matrices/matrices.factor
extra/math/miller-rabin/miller-rabin.factor
extra/math/newtons-method/newtons-method.factor
extra/math/polynomials/polynomials.factor
extra/math/primes/factors/factors.factor
extra/math/primes/primes.factor
extra/math/quaternions/quaternions.factor
extra/math/secant-method/secant-method.factor
extra/math/statistics/statistics.factor
extra/math/text/english/english.factor
extra/math/transforms/fft/authors.txt [new file with mode: 0644]
extra/math/transforms/fft/fft-docs.factor [new file with mode: 0644]
extra/math/transforms/fft/fft.factor [new file with mode: 0644]
extra/math/transforms/fft/summary.txt [new file with mode: 0644]
extra/math/transforms/haar/authors.txt [new file with mode: 0644]
extra/math/transforms/haar/haar-docs.factor [new file with mode: 0644]
extra/math/transforms/haar/haar-tests.factor [new file with mode: 0644]
extra/math/transforms/haar/haar.factor [new file with mode: 0644]
extra/math/transforms/haar/summary.txt [new file with mode: 0644]
extra/math/transforms/summary.txt [new file with mode: 0644]
extra/maze/maze.factor
extra/nehe/2/2.factor
extra/nehe/3/3.factor
extra/nehe/4/4.factor
extra/nehe/5/5.factor
extra/opengl/demo-support/demo-support.factor
extra/opengl/gadgets/gadgets.factor
extra/pack/pack.factor
extra/processing/shapes/shapes.factor
extra/project-euler/001/001.factor
extra/project-euler/004/004.factor
extra/project-euler/014/014.factor
extra/project-euler/019/019.factor
extra/project-euler/043/043.factor
extra/project-euler/047/047.factor
extra/project-euler/052/052.factor
extra/project-euler/071/071-tests.factor [new file with mode: 0644]
extra/project-euler/071/071.factor [new file with mode: 0644]
extra/project-euler/073/073-tests.factor [new file with mode: 0644]
extra/project-euler/073/073.factor [new file with mode: 0644]
extra/project-euler/203/203-tests.factor [new file with mode: 0644]
extra/project-euler/203/203.factor [new file with mode: 0644]
extra/project-euler/215/215-tests.factor [new file with mode: 0644]
extra/project-euler/215/215.factor [new file with mode: 0644]
extra/project-euler/common/common.factor
extra/project-euler/project-euler.factor
extra/roman/roman-docs.factor
extra/sequences/lib/lib.factor
extra/size-of/size-of.factor [deleted file]
extra/spheres/spheres.factor
extra/springies/ui/ui.factor
extra/suffix-arrays/authors.txt [deleted file]
extra/suffix-arrays/suffix-arrays-docs.factor [deleted file]
extra/suffix-arrays/suffix-arrays-tests.factor [deleted file]
extra/suffix-arrays/suffix-arrays.factor [deleted file]
extra/suffix-arrays/summary.txt [deleted file]
extra/suffix-arrays/tags.txt [deleted file]
extra/suffix-arrays/words/words.factor [deleted file]
extra/tar/tar.factor
extra/tetris/gl/gl.factor
extra/time-server/authors.txt [new file with mode: 0644]
extra/time-server/time-server-tests.factor [new file with mode: 0644]
extra/time-server/time-server.factor [new file with mode: 0644]
extra/update/backup/backup.factor
extra/update/latest/latest.factor
extra/update/update.factor
extra/update/util/util.factor [new file with mode: 0644]
extra/webapps/blogs/new-post.xml
extra/webapps/user-admin/edit-user.xml
extra/webapps/user-admin/new-user.xml
misc/factor.el
unmaintained/cairo-demo/authors.txt [deleted file]
unmaintained/cairo-demo/cairo-demo.factor [deleted file]
unmaintained/cairo/authors.txt [deleted file]
unmaintained/cairo/cairo.factor [deleted file]
unmaintained/cairo/ffi/ffi.factor [deleted file]
unmaintained/cairo/gadgets/gadgets.factor [deleted file]
unmaintained/cairo/samples/samples.factor [deleted file]
unmaintained/cairo/summary.txt [deleted file]
unmaintained/cairo/tags.txt [deleted file]
unmaintained/size-of/size-of.factor [new file with mode: 0644]
vm/alien.c
vm/alien.h
vm/callstack.c
vm/callstack.h
vm/code_gc.c
vm/code_gc.h
vm/code_heap.c
vm/code_heap.h
vm/cpu-x86.32.S
vm/cpu-x86.64.S
vm/cpu-x86.S
vm/data_gc.c
vm/data_gc.h
vm/debug.c
vm/debug.h
vm/errors.c
vm/errors.h
vm/image.c
vm/image.h
vm/io.c
vm/io.h
vm/math.c
vm/math.h
vm/os-unix.c
vm/os-windows-ce.c
vm/os-windows.c
vm/primitives.h
vm/profiler.c
vm/profiler.h
vm/quotations.c
vm/quotations.h
vm/run.c
vm/run.h
vm/types.c
vm/types.h

index 4dcf1a77387a44013c79972d2a2d558ec7c55ef2..3f2eee64600645c35b195151460298cf4bfbfadb 100644 (file)
@@ -16,7 +16,7 @@ HELP: ALIAS:
     }
 } ;
 
-ARTICLE: "alias" "Alias"
+ARTICLE: "alias" "Word aliasing"
 "The " { $vocab-link "alias" } " vocabulary implements a way to make many different names for the same word. Although creating new names for words is generally frowned upon, aliases are useful for the Win32 API and other cases where words need to be renamed for symmetry." $nl 
 "Make a new word that aliases another word:"
 { $subsection define-alias }
index 3a3ae341d1095e823a08f39747844540fd438740..c0fafdc0f53ac0b7d2b624b45cd368d86bc5ee5f 100644 (file)
@@ -14,8 +14,8 @@ IN: bootstrap.image
 
 : arch ( os cpu -- arch )
     {
-        { "ppc" [ name>> "-ppc" append ] }
-        { "x86.64" [ name>> "winnt" = "winnt" "unix" ? "-x86.64" append ] }
+        { "ppc" [ "-ppc" append ] }
+        { "x86.64" [ "winnt" = "winnt" "unix" ? "-x86.64" append ] }
         [ nip ]
     } case ;
 
@@ -134,6 +134,7 @@ SYMBOL: jit-epilog
 SYMBOL: jit-return
 SYMBOL: jit-profiling
 SYMBOL: jit-declare-word
+SYMBOL: jit-save-stack
 
 ! Default definition for undefined words
 SYMBOL: undefined-quot
@@ -158,6 +159,7 @@ SYMBOL: undefined-quot
         { jit-profiling 35 }
         { jit-push-immediate 36 }
         { jit-declare-word 42 }
+        { jit-save-stack 43 }
         { undefined-quot 60 }
     } at header-size + ;
 
@@ -459,6 +461,7 @@ M: quotation '
         jit-return
         jit-profiling
         jit-declare-word
+        jit-save-stack
         undefined-quot
     } [ emit-userenv ] each ;
 
index 3b6c04329c313d601ab98a29256d0ee4a2ad320c..d25394e978ba5122f6425aa4684b59e06bec64cf 100644 (file)
@@ -8,6 +8,8 @@ definitions assocs compiler.errors compiler.units
 math.parser generic sets debugger command-line ;
 IN: bootstrap.stage2
 
+SYMBOL: core-bootstrap-time
+
 SYMBOL: bootstrap-time
 
 : default-image-name ( -- string )
@@ -30,11 +32,15 @@ SYMBOL: bootstrap-time
 : count-words ( pred -- )
     all-words swap count number>string write ;
 
-: print-report ( time -- )
+: print-time ( time -- )
     1000 /i
     60 /mod swap
-    "Bootstrap completed in " write number>string write
-    " minutes and " write number>string write " seconds." print
+    number>string write
+    " minutes and " write number>string write " seconds." print ;
+
+: print-report ( -- )
+    "Core bootstrap completed in " write core-bootstrap-time get print-time
+    "Bootstrap completed in "      write bootstrap-time      get print-time
 
     [ compiled>> ] count-words " compiled words" print
     [ symbol? ] count-words " symbol words" print
@@ -46,7 +52,7 @@ SYMBOL: bootstrap-time
 
 [
     ! We time bootstrap
-    millis >r
+    millis
 
     default-image-name "output-image" set-global
 
@@ -71,6 +77,8 @@ SYMBOL: bootstrap-time
     [
         load-components
 
+        millis over - core-bootstrap-time set-global
+
         run-bootstrap-init
     ] with-compiler-errors
     :errors
@@ -92,7 +100,7 @@ SYMBOL: bootstrap-time
             ] [ print-error 1 exit ] recover
         ] set-boot-quot
 
-        millis r> - dup bootstrap-time set-global
+        millis swap - bootstrap-time set-global
         print-report
 
         "output-image" get save-image-and-exit
index 93daa601fe8353dbd2631cff0d78ee7919ff8ea5..7bad44f7a60cacc18839d1760c002c5edd5e9fb2 100755 (executable)
@@ -171,6 +171,7 @@ M: #if emit-node
             [
                 V{ } clone node-stack set
                 ##prologue
+                begin-basic-block
                 emit-nodes
                 basic-block get [
                     ##epilogue
@@ -189,7 +190,7 @@ M: #if emit-node
 
 : emit-dispatch ( node -- )
     ##epilogue
-    ds-pop ^^offset>slot i ##dispatch
+    ds-pop ^^offset>slot i ##dispatch
     dispatch-branches ;
 
 : <dispatch-block> ( -- word )
@@ -220,21 +221,14 @@ M: #push emit-node
     literal>> ^^load-literal ds-push iterate-next ;
 
 ! #shuffle
-: emit-shuffle ( effect -- )
-    [ out>> ] [ in>> dup length ds-load zip ] bi
-    '[ _ at ] map ds-store ;
-
 M: #shuffle emit-node
-    shuffle-effect emit-shuffle iterate-next ;
-
-M: #>r emit-node
-    [ in-d>> length ] [ out-r>> empty? ] bi
-    [ neg ##inc-d ] [ ds-load rs-store ] if
-    iterate-next ;
-
-M: #r> emit-node
-    [ in-r>> length ] [ out-d>> empty? ] bi
-    [ neg ##inc-r ] [ rs-load ds-store ] if
+    dup
+    H{ } clone
+    [ [ in-d>> [ length ds-load ] keep ] dip '[ _ set-at ] 2each ]
+    [ [ in-r>> [ length rs-load ] keep ] dip '[ _ set-at ] 2each ]
+    [ nip ] 2tri
+    [ [ [ out-d>> ] [ mapping>> ] bi ] dip '[ _ at _ at ] map ds-store ]
+    [ [ [ out-r>> ] [ mapping>> ] bi ] dip '[ _ at _ at ] map rs-store ] 2bi
     iterate-next ;
 
 ! #return
index c39f517671bc21912cf6dd623229a54687c4aa7c..b2c752e6121ec07c61e8529aec04c29eed859e5b 100644 (file)
@@ -62,7 +62,7 @@ INSN: ##jump word ;
 INSN: ##return ;
 
 ! Jump tables
-INSN: ##dispatch src temp ;
+INSN: ##dispatch src temp offset ;
 INSN: ##dispatch-label label ;
 
 ! Slot access
index d397c9d448b683ff02c1feee0834837f8ed7880d..7433df9617cbab44cbfe28c660f25f457e17c9df 100644 (file)
@@ -43,8 +43,8 @@ M: ##branch linearize-insn
 
 : binary-conditional ( basic-block insn -- basic-block successor label2 src1 src2 cc )
     [ (binary-conditional) ]
-    [ drop dup successors>> first useless-branch? ] 2bi
-    [ [ number>> ] 3dip negate-cc ] [ [ swap number>> ] 3dip ] if ;
+    [ drop dup successors>> second useless-branch? ] 2bi
+    [ [ swap number>> ] 3dip ] [ [ number>> ] 3dip negate-cc ] if ;
 
 M: ##compare-branch linearize-insn
     binary-conditional _compare-branch emit-branch ;
index 7f4b09e68fddb3d0f768df8213f5ae2714c70552..158903b4bf4be368cbcdc1044e2c48bb93a1716c 100644 (file)
@@ -9,7 +9,10 @@ SYMBOL: visited
 : post-order-traversal ( bb -- )
     dup id>> visited get key? [ drop ] [
         dup id>> visited get conjoin
-        [ successors>> [ post-order-traversal ] each ] [ , ] bi
+        [
+            successors>> <reversed>
+            [ post-order-traversal ] each
+        ] [ , ] bi
     ] if ;
 
 : post-order ( bb -- blocks )
index f138f673e0c10fb6b5e423864dfb1f4dc4c21186..c8fcae87c0ac985547ba15e2b28fb3dcb7b8202c 100755 (executable)
@@ -15,16 +15,28 @@ IN: compiler.cfg.stacks
     1 ##inc-d D 0 ##replace ;
 
 : ds-load ( n -- vregs )
-    [ <reversed> [ <ds-loc> ^^peek ] map ] [ neg ##inc-d ] bi ;
+    dup 0 =
+    [ drop f ]
+    [ [ <reversed> [ <ds-loc> ^^peek ] map ] [ neg ##inc-d ] bi ] if ;
 
 : ds-store ( vregs -- )
-    <reversed> [ length ##inc-d ] [ [ <ds-loc> ##replace ] each-index ] bi ;
+    [
+        <reversed>
+        [ length ##inc-d ]
+        [ [ <ds-loc> ##replace ] each-index ] bi
+    ] unless-empty ;
 
 : rs-load ( n -- vregs )
-    [ <reversed> [ <rs-loc> ^^peek ] map ] [ neg ##inc-r ] bi ;
+    dup 0 =
+    [ drop f ]
+    [ [ <reversed> [ <rs-loc> ^^peek ] map ] [ neg ##inc-r ] bi ] if ;
 
 : rs-store ( vregs -- )
-    <reversed> [ length ##inc-r ] [ [ <rs-loc> ##replace ] each-index ] bi ;
+    [
+        <reversed>
+        [ length ##inc-r ]
+        [ [ <rs-loc> ##replace ] each-index ] bi
+    ] unless-empty ;
 
 : 2inputs ( -- vreg1 vreg2 )
     D 1 ^^peek D 0 ^^peek -2 ##inc-d ;
index 94c3f0d6f9b32bd128dcc927775c4ea1ec6a9cc3..5f67f8097eec07db89e594f179ed39f60e4333ed 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences layouts accessors combinators namespaces
-math
+math fry
 compiler.cfg.instructions
 compiler.cfg.value-numbering.graph
 compiler.cfg.value-numbering.simplify
@@ -113,4 +113,18 @@ M: ##compare-imm rewrite
         ] when
     ] when ;
 
+: dispatch-offset ( expr -- n )
+    [ in2>> vn>constant tag-bits get neg shift ] [ op>> ] bi
+    \ ##sub-imm eq? [ neg ] when ;
+
+: add-dispatch-offset? ( insn -- expr ? )
+    src>> vreg>expr dup op>> { ##add-imm ##sub-imm } memq? ; inline
+
+M: ##dispatch rewrite
+    dup add-dispatch-offset? [
+        [ clone ] dip
+        [ in1>> vn>vreg >>src ]
+        [ dispatch-offset '[ _ + ] change-offset ] bi
+    ] [ drop ] if ;
+
 M: insn rewrite ;
index d3be68c3c9036b9e4a7629afb0ad386284f4dc38..b73736ed1427be93f6a73bd899496cece7ce8d20 100644 (file)
@@ -34,7 +34,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ;
 [ t ] [
     {
         T{ ##peek f V int-regs 1 D 0 }
-        T{ ##dispatch f V int-regs 1 V int-regs 2 }
+        T{ ##dispatch f V int-regs 1 V int-regs 2 }
     } dup value-numbering =
 ] unit-test
 
index cab86dcb54220c16c02018d90d7a5a40aed97651..0d45b281262d74c925bea8b5ceb97e0c48105267 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces make math math.parser sequences accessors
+USING: namespaces make math math.order math.parser sequences accessors
 kernel kernel.private layouts assocs words summary arrays
 combinators classes.algebra alien alien.c-types alien.structs
 alien.strings alien.arrays sets threads libc continuations.private
@@ -93,7 +93,7 @@ M: ##return generate-insn drop %return ;
 M: ##dispatch-label generate-insn label>> %dispatch-label ;
 
 M: ##dispatch generate-insn
-    [ src>> register ] [ temp>> register ] bi %dispatch ;
+    [ src>> register ] [ temp>> register ] [ offset>> ] tri %dispatch ;
 
 : >slot<
     {
@@ -234,13 +234,26 @@ M: float-regs reg-class-variable drop float-regs ;
 
 GENERIC: inc-reg-class ( register-class -- )
 
-M: reg-class inc-reg-class
-    dup reg-class-variable inc
-    fp-shadows-int? [ reg-size stack-params +@ ] [ drop ] if ;
+: ?dummy-stack-params ( reg-class -- )
+    dummy-stack-params? [ reg-size stack-params +@ ] [ drop ] if ;
+
+: ?dummy-int-params ( reg-class -- )
+    dummy-int-params? [ reg-size cell /i 1 max int-regs +@ ] [ drop ] if ;
+
+: ?dummy-fp-params ( reg-class -- )
+    drop dummy-fp-params? [ float-regs inc ] when ;
+
+M: int-regs inc-reg-class
+    [ reg-class-variable inc ]
+    [ ?dummy-stack-params ]
+    [ ?dummy-fp-params ]
+    tri ;
 
 M: float-regs inc-reg-class
-    dup call-next-method
-    fp-shadows-int? [ reg-size cell /i int-regs +@ ] [ drop ] if ;
+    [ reg-class-variable inc ]
+    [ ?dummy-stack-params ]
+    [ ?dummy-int-params ]
+    tri ;
 
 GENERIC: reg-class-full? ( class -- ? )
 
index fe270f4410618cb34be04a064c253af8df732de8..b25f1fa8fe7da8b29cbf8caec42e565cdea871cb 100755 (executable)
@@ -72,8 +72,8 @@ SYMBOL: literal-table
 : rel-this ( class -- )
     0 swap rt-label rel-fixup ;
 
-: rel-here ( class -- )
-    0 swap rt-here rel-fixup ;
+: rel-here ( offset class -- )
+    rt-here rel-fixup ;
 
 : init-fixup ( -- )
     BV{ } clone relocation-table set
index cd68602768ded9ea3bb6a6097a0c212bac08a409..86c1f6504900f359cd84fd0c89a7f328ed853921 100644 (file)
@@ -37,14 +37,15 @@ IN: compiler.constants
 : rc-indirect-arm-pc  8 ; inline
 
 ! Relocation types
-: rt-primitive 0 ; inline
-: rt-dlsym     1 ; inline
-: rt-literal   2 ; inline
-: rt-dispatch  3 ; inline
-: rt-xt        4 ; inline
-: rt-here      5 ; inline
-: rt-label     6 ; inline
-: rt-immediate 7 ; inline
+: rt-primitive   0 ; inline
+: rt-dlsym       1 ; inline
+: rt-literal     2 ; inline
+: rt-dispatch    3 ; inline
+: rt-xt          4 ; inline
+: rt-here        5 ; inline
+: rt-label       6 ; inline
+: rt-immediate   7 ; inline
+: rt-stack-chain 8 ; inline
 
 : rc-absolute? ( n -- ? )
     [ rc-absolute-ppc-2/2 = ]
diff --git a/basis/compiler/tests/codegen.factor b/basis/compiler/tests/codegen.factor
new file mode 100644 (file)
index 0000000..a56ee55
--- /dev/null
@@ -0,0 +1,243 @@
+USING: generalizations accessors arrays compiler kernel
+kernel.private math hashtables.private math.private namespaces
+sequences sequences.private tools.test namespaces.private
+slots.private sequences.private byte-arrays alien
+alien.accessors layouts words definitions compiler.units io
+combinators vectors float-arrays ;
+IN: compiler.tests
+
+! Originally, this file did black box testing of templating
+! optimization. We now have a different codegen, but the tests
+! in here are still useful.
+
+! Oops!
+[ 5000 ] [ [ 5000 ] compile-call ] unit-test
+[ "hi" ] [ [ "hi" ] compile-call ] unit-test
+
+[ 1 2 3 4 ] [ [ 1 2 3 4 ] compile-call ] unit-test
+
+[ 1 1 ] [ 1 [ dup ] compile-call ] unit-test
+[ 0 ] [ 3 [ tag ] compile-call ] unit-test
+[ 0 3 ] [ 3 [ [ tag ] keep ] compile-call ] unit-test
+
+[ 2 3 ] [ 3 [ 2 swap ] compile-call ] unit-test
+
+[ 2 1 3 4 ] [ 1 2 [ swap 3 4 ] compile-call ] unit-test
+
+[ 2 3 4 ] [ 3 [ 2 swap 4 ] compile-call ] unit-test
+
+[ { 1 2 3 } { 1 4 3 } 3 3 ]
+[ { 1 2 3 } { 1 4 3 } [ over tag over tag ] compile-call ]
+unit-test
+
+! Test literals in either side of a shuffle
+[ 4 1 ] [ 1 [ [ 3 fixnum+ ] keep ] compile-call ] unit-test
+
+[ 2 ] [ 1 2 [ swap fixnum/i ] compile-call ] unit-test
+
+: foo ( -- ) ;
+
+[ 5 5 ]
+[ 1.2 [ tag [ foo ] keep ] compile-call ]
+unit-test
+
+[ 1 2 2 ]
+[ { 1 2 } [ dup 2 slot swap 3 slot [ foo ] keep ] compile-call ]
+unit-test
+
+[ 3 ]
+[
+    global [ 3 \ foo set ] bind
+    \ foo [ global >n get ndrop ] compile-call
+] unit-test
+
+: blech drop ;
+
+[ 3 ]
+[
+    global [ 3 \ foo set ] bind
+    \ foo [ global [ get ] swap blech call ] compile-call
+] unit-test
+
+[ 3 ]
+[
+    global [ 3 \ foo set ] bind
+    \ foo [ global [ get ] swap >n call ndrop ] compile-call
+] unit-test
+
+[ 3 ]
+[
+    global [ 3 \ foo set ] bind
+    \ foo [ global [ get ] bind ] compile-call
+] unit-test
+
+[ 12 13 ] [
+    -12 -13 [ [ 0 swap fixnum-fast ] bi@ ] compile-call
+] unit-test
+
+[ -1 2 ] [ 1 2 [ >r 0 swap fixnum- r> ] compile-call ] unit-test
+
+[ 12 13 ] [
+    -12 -13 [ [ 0 swap fixnum- ] bi@ ] compile-call
+] unit-test
+
+[ 1 ] [
+    SBUF" " [ 1 slot 1 [ slot ] keep ] compile-call nip
+] unit-test
+
+! Test slow shuffles
+[ 3 1 2 3 4 5 6 7 8 9 ] [
+    1 2 3 4 5 6 7 8 9
+    [ >r >r >r >r >r >r >r >r >r 3 r> r> r> r> r> r> r> r> r> ]
+    compile-call
+] unit-test
+
+[ 2 2 2 2 2 2 2 2 2 2 1 ] [
+    1 2
+    [ swap >r dup dup dup dup dup dup dup dup dup r> ] compile-call
+] unit-test
+
+[ ] [ [ 9 [ ] times ] compile-call ] unit-test
+
+[ ] [
+    [
+        [ 200 dup [ 200 3array ] curry map drop ] times
+    ] [ define-temp ] with-compilation-unit drop
+] unit-test
+
+! Test how dispatch handles the end of a basic block
+: try-breaking-dispatch ( n a b -- x str )
+    float+ swap { [ "hey" ] [ "bye" ] } dispatch ;
+
+: try-breaking-dispatch-2 ( -- ? )
+    1 1.0 2.5 try-breaking-dispatch "bye" = >r 3.5 = r> and ;
+
+[ t ] [
+    10000000 [ drop try-breaking-dispatch-2 ] all?
+] unit-test
+
+! Regression
+: (broken) ( x -- y ) ;
+
+[ 2.0 { 2.0 0.0 } ] [
+    2.0 1.0
+    [ float/f 0.0 [ drop (broken) ] 2keep 2array ] compile-call
+] unit-test
+
+! Regression
+: hellish-bug-1 ( a b -- ) 2drop ;
+
+: hellish-bug-2 ( i array x -- x ) 
+    2dup 1 slot eq? [ 2drop ] [ 
+        2dup array-nth tombstone? [ 
+            [
+                [ array-nth ] 2keep >r 1 fixnum+fast r> array-nth
+                pick 2dup hellish-bug-1 3drop
+            ] 2keep
+        ] unless >r 2 fixnum+fast r> hellish-bug-2
+    ] if ; inline recursive
+
+: hellish-bug-3 ( hash array -- ) 
+    0 swap hellish-bug-2 drop ;
+
+[ ] [
+    H{ { 1 2 } { 3 4 } } dup array>>
+    [ 0 swap hellish-bug-2 drop ] compile-call
+] unit-test
+
+! Regression
+: foox ( obj -- obj )
+    dup not
+    [ drop 3 ] [ dup tuple? [ drop 4 ] [ drop 5 ] if ] if ;
+
+[ 3 ] [ f foox ] unit-test
+
+TUPLE: my-tuple ;
+
+[ 4 ] [ T{ my-tuple } foox ] unit-test
+
+[ 5 ] [ "hi" foox ] unit-test
+
+! Making sure we don't needlessly unbox/rebox
+[ t 3.0 ] [ 1.0 dup [ dup 2.0 float+ >r eq? r> ] compile-call ] unit-test
+
+[ t 3.0 ] [ 1.0 dup [ dup 2.0 float+ ] compile-call >r eq? r> ] unit-test
+
+[ t ] [ 1.0 dup [ [ 2.0 float+ ] keep ] compile-call nip eq? ] unit-test
+
+[ 1 B{ 1 2 3 4 } ] [
+    B{ 1 2 3 4 } [
+        { byte-array } declare
+        [ 0 alien-unsigned-1 ] keep
+    ] compile-call
+] unit-test
+
+[ 1 t ] [
+    B{ 1 2 3 4 } [
+        { c-ptr } declare
+        [ 0 alien-unsigned-1 ] keep hi-tag
+    ] compile-call byte-array type-number =
+] unit-test
+
+[ t ] [
+    B{ 1 2 3 4 } [
+        { c-ptr } declare
+        0 alien-cell hi-tag
+    ] compile-call alien type-number =
+] unit-test
+
+[ 2 1 ] [
+    2 1
+    [ 2dup fixnum< [ >r die r> ] when ] compile-call
+] unit-test
+
+! Regression
+: a-dummy ( a -- ) drop "hi" print ;
+
+[ ] [
+    1 [
+        dup 0 2 3dup pick >= [ >= ] [ 2drop f ] if [
+            drop - >fixnum {
+                [ a-dummy ]
+                [ a-dummy ]
+                [ a-dummy ]
+            } dispatch
+        ] [ 2drop no-case ] if
+    ] compile-call
+] unit-test
+
+! Regression
+: dispatch-alignment-regression ( -- c )
+    { tuple vector } 3 slot { word } declare
+    dup 1 slot 0 fixnum-bitand { [ ] } dispatch ;
+
+[ t ] [ \ dispatch-alignment-regression compiled>> ] unit-test
+
+[ vector ] [ dispatch-alignment-regression ] unit-test
+
+! Regression
+: bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f <array> ;
+
+[ { f f f } ] [ t bad-value-bug ] unit-test
+
+! PowerPC regression
+TUPLE: id obj ;
+
+: (gc-check-bug) ( a b -- c )
+    { [ id boa ] [ id boa ] } dispatch ;
+
+: gc-check-bug ( -- )
+    10000000 [ "hi" 0 (gc-check-bug) drop ] times ;
+
+[ ] [ gc-check-bug ] unit-test
+
+! New optimization
+: test-1 ( a -- b ) 8 fixnum-fast { [ "a" ] [ "b" ] } dispatch ;
+
+[ "a" ] [ 8 test-1 ] unit-test
+[ "b" ] [ 9 test-1 ] unit-test
+
+: test-2 ( a -- b ) 1 fixnum-fast { [ "a" ] [ "b" ] } dispatch ;
+
+[ "a" ] [ 1 test-2 ] unit-test
+[ "b" ] [ 2 test-2 ] unit-test
diff --git a/basis/compiler/tests/templates.factor b/basis/compiler/tests/templates.factor
deleted file mode 100644 (file)
index de87ad8..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-USING: generalizations accessors arrays compiler kernel
-kernel.private math hashtables.private math.private namespaces
-sequences sequences.private tools.test namespaces.private
-slots.private sequences.private byte-arrays alien
-alien.accessors layouts words definitions compiler.units io
-combinators vectors float-arrays ;
-IN: compiler.tests
-
-! Originally, this file did black box testing of templating
-! optimization. We now have a different codegen, but the tests
-! in here are still useful.
-
-! Oops!
-[ 5000 ] [ [ 5000 ] compile-call ] unit-test
-[ "hi" ] [ [ "hi" ] compile-call ] unit-test
-
-[ 1 2 3 4 ] [ [ 1 2 3 4 ] compile-call ] unit-test
-
-[ 1 1 ] [ 1 [ dup ] compile-call ] unit-test
-[ 0 ] [ 3 [ tag ] compile-call ] unit-test
-[ 0 3 ] [ 3 [ [ tag ] keep ] compile-call ] unit-test
-
-[ 2 3 ] [ 3 [ 2 swap ] compile-call ] unit-test
-
-[ 2 1 3 4 ] [ 1 2 [ swap 3 4 ] compile-call ] unit-test
-
-[ 2 3 4 ] [ 3 [ 2 swap 4 ] compile-call ] unit-test
-
-[ { 1 2 3 } { 1 4 3 } 3 3 ]
-[ { 1 2 3 } { 1 4 3 } [ over tag over tag ] compile-call ]
-unit-test
-
-! Test literals in either side of a shuffle
-[ 4 1 ] [ 1 [ [ 3 fixnum+ ] keep ] compile-call ] unit-test
-
-[ 2 ] [ 1 2 [ swap fixnum/i ] compile-call ] unit-test
-
-: foo ( -- ) ;
-
-[ 5 5 ]
-[ 1.2 [ tag [ foo ] keep ] compile-call ]
-unit-test
-
-[ 1 2 2 ]
-[ { 1 2 } [ dup 2 slot swap 3 slot [ foo ] keep ] compile-call ]
-unit-test
-
-[ 3 ]
-[
-    global [ 3 \ foo set ] bind
-    \ foo [ global >n get ndrop ] compile-call
-] unit-test
-
-: blech drop ;
-
-[ 3 ]
-[
-    global [ 3 \ foo set ] bind
-    \ foo [ global [ get ] swap blech call ] compile-call
-] unit-test
-
-[ 3 ]
-[
-    global [ 3 \ foo set ] bind
-    \ foo [ global [ get ] swap >n call ndrop ] compile-call
-] unit-test
-
-[ 3 ]
-[
-    global [ 3 \ foo set ] bind
-    \ foo [ global [ get ] bind ] compile-call
-] unit-test
-
-[ 12 13 ] [
-    -12 -13 [ [ 0 swap fixnum-fast ] bi@ ] compile-call
-] unit-test
-
-[ -1 2 ] [ 1 2 [ >r 0 swap fixnum- r> ] compile-call ] unit-test
-
-[ 12 13 ] [
-    -12 -13 [ [ 0 swap fixnum- ] bi@ ] compile-call
-] unit-test
-
-[ 1 ] [
-    SBUF" " [ 1 slot 1 [ slot ] keep ] compile-call nip
-] unit-test
-
-! Test slow shuffles
-[ 3 1 2 3 4 5 6 7 8 9 ] [
-    1 2 3 4 5 6 7 8 9
-    [ >r >r >r >r >r >r >r >r >r 3 r> r> r> r> r> r> r> r> r> ]
-    compile-call
-] unit-test
-
-[ 2 2 2 2 2 2 2 2 2 2 1 ] [
-    1 2
-    [ swap >r dup dup dup dup dup dup dup dup dup r> ] compile-call
-] unit-test
-
-[ ] [ [ 9 [ ] times ] compile-call ] unit-test
-
-[ ] [
-    [
-        [ 200 dup [ 200 3array ] curry map drop ] times
-    ] [ define-temp ] with-compilation-unit drop
-] unit-test
-
-! Test how dispatch handles the end of a basic block
-: try-breaking-dispatch ( n a b -- x str )
-    float+ swap { [ "hey" ] [ "bye" ] } dispatch ;
-
-: try-breaking-dispatch-2 ( -- ? )
-    1 1.0 2.5 try-breaking-dispatch "bye" = >r 3.5 = r> and ;
-
-[ t ] [
-    10000000 [ drop try-breaking-dispatch-2 ] all?
-] unit-test
-
-! Regression
-: (broken) ( x -- y ) ;
-
-[ 2.0 { 2.0 0.0 } ] [
-    2.0 1.0
-    [ float/f 0.0 [ drop (broken) ] 2keep 2array ] compile-call
-] unit-test
-
-! Regression
-: hellish-bug-1 ( a b -- ) 2drop ;
-
-: hellish-bug-2 ( i array x -- x ) 
-    2dup 1 slot eq? [ 2drop ] [ 
-        2dup array-nth tombstone? [ 
-            [
-                [ array-nth ] 2keep >r 1 fixnum+fast r> array-nth
-                pick 2dup hellish-bug-1 3drop
-            ] 2keep
-        ] unless >r 2 fixnum+fast r> hellish-bug-2
-    ] if ; inline recursive
-
-: hellish-bug-3 ( hash array -- ) 
-    0 swap hellish-bug-2 drop ;
-
-[ ] [
-    H{ { 1 2 } { 3 4 } } dup array>>
-    [ 0 swap hellish-bug-2 drop ] compile-call
-] unit-test
-
-! Regression
-: foox ( obj -- obj )
-    dup not
-    [ drop 3 ] [ dup tuple? [ drop 4 ] [ drop 5 ] if ] if ;
-
-[ 3 ] [ f foox ] unit-test
-
-TUPLE: my-tuple ;
-
-[ 4 ] [ T{ my-tuple } foox ] unit-test
-
-[ 5 ] [ "hi" foox ] unit-test
-
-! Making sure we don't needlessly unbox/rebox
-[ t 3.0 ] [ 1.0 dup [ dup 2.0 float+ >r eq? r> ] compile-call ] unit-test
-
-[ t 3.0 ] [ 1.0 dup [ dup 2.0 float+ ] compile-call >r eq? r> ] unit-test
-
-[ t ] [ 1.0 dup [ [ 2.0 float+ ] keep ] compile-call nip eq? ] unit-test
-
-[ 1 B{ 1 2 3 4 } ] [
-    B{ 1 2 3 4 } [
-        { byte-array } declare
-        [ 0 alien-unsigned-1 ] keep
-    ] compile-call
-] unit-test
-
-[ 1 t ] [
-    B{ 1 2 3 4 } [
-        { c-ptr } declare
-        [ 0 alien-unsigned-1 ] keep hi-tag
-    ] compile-call byte-array type-number =
-] unit-test
-
-[ t ] [
-    B{ 1 2 3 4 } [
-        { c-ptr } declare
-        0 alien-cell hi-tag
-    ] compile-call alien type-number =
-] unit-test
-
-[ 2 1 ] [
-    2 1
-    [ 2dup fixnum< [ >r die r> ] when ] compile-call
-] unit-test
-
-! Regression
-: a-dummy ( a -- ) drop "hi" print ;
-
-[ ] [
-    1 [
-        dup 0 2 3dup pick >= [ >= ] [ 2drop f ] if [
-            drop - >fixnum {
-                [ a-dummy ]
-                [ a-dummy ]
-                [ a-dummy ]
-            } dispatch
-        ] [ 2drop no-case ] if
-    ] compile-call
-] unit-test
-
-! Regression
-: dispatch-alignment-regression ( -- c )
-    { tuple vector } 3 slot { word } declare
-    dup 1 slot 0 fixnum-bitand { [ ] } dispatch ;
-
-[ t ] [ \ dispatch-alignment-regression compiled>> ] unit-test
-
-[ vector ] [ dispatch-alignment-regression ] unit-test
-
-! Regression
-: bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f <array> ;
-
-[ { f f f } ] [ t bad-value-bug ] unit-test
index 19d80ec14fce4062ad7896a6b28f2cd894dd6a87..c2ec6552cd6219e06304b6c2dd108f58b993ea0b 100644 (file)
@@ -1,9 +1,13 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry accessors quotations kernel sequences namespaces
-assocs words arrays vectors hints combinators stack-checker
-stack-checker.state stack-checker.visitor stack-checker.errors
-stack-checker.backend compiler.tree ;
+assocs words arrays vectors hints combinators compiler.tree
+stack-checker
+stack-checker.state
+stack-checker.errors
+stack-checker.visitor
+stack-checker.backend
+stack-checker.recursive-state ;
 IN: compiler.tree.builder
 
 : with-tree-builder ( quot -- nodes )
@@ -12,12 +16,13 @@ IN: compiler.tree.builder
 
 : build-tree ( quot -- nodes )
     #! Not safe to call from inference transforms.
-    [ f infer-quot ] with-tree-builder nip ;
+    [ f initial-recursive-state infer-quot ] with-tree-builder nip ;
 
 : build-tree-with ( in-stack quot -- nodes out-stack )
     #! Not safe to call from inference transforms.
     [
-        [ >vector meta-d set ] [ f infer-quot ] bi*
+        [ >vector meta-d set ]
+        [ f initial-recursive-state infer-quot ] bi*
     ] with-tree-builder nip
     unclip-last in-d>> ;
 
@@ -32,10 +37,10 @@ IN: compiler.tree.builder
     dup
     [ "inline" word-prop ]
     [ "recursive" word-prop ] bi and [
-        1quotation f infer-quot
+        1quotation f initial-recursive-state infer-quot
     ] [
-        [ specialized-def ]
-        [ dup 2array 1array ] bi infer-quot
+        [ specialized-def ] [ initial-recursive-state ] bi
+        infer-quot
     ] if ;
 
 : check-cannot-infer ( word -- )
index b712a6e354accd0e92fd1b7cc7aa2ae0025f2551..4f99fa015d83f7f5ab4cedba19593191a26ecd91 100644 (file)
@@ -22,8 +22,8 @@ ERROR: check-use-error value message ;
 GENERIC: check-node* ( node -- )
 
 M: #shuffle check-node*
-    [ [ mapping>> values ] [ in-d>> ] bi subset? [ "Bad mapping inputs" throw ] unless ]
-    [ [ mapping>> keys ] [ out-d>> ] bi set= [ "Bad mapping outputs" throw ] unless ]
+    [ [ mapping>> values ] [ [ in-d>> ] [ in-r>> ] bi append ] bi subset? [ "Bad mapping inputs" throw ] unless ]
+    [ [ mapping>> keys ] [ [ out-d>> ] [ out-r>> ] bi append ] bi set= [ "Bad mapping outputs" throw ] unless ]
     bi ;
 
 : check-lengths ( seq -- )
@@ -31,13 +31,6 @@ M: #shuffle check-node*
 
 M: #copy check-node* inputs/outputs 2array check-lengths ;
 
-: check->r/r> ( node -- )
-    inputs/outputs [ drop ] [ 2array check-lengths ] if-empty ;
-
-M: #>r check-node* check->r/r> ;
-
-M: #r> check-node* check->r/r> ;
-
 M: #return-recursive check-node* inputs/outputs 2array check-lengths ;
 
 M: #phi check-node*
@@ -113,11 +106,8 @@ M: #push check-stack-flow* check-out-d ;
 
 M: #call check-stack-flow* [ check-in-d ] [ check-out-d ] bi ;
 
-M: #shuffle check-stack-flow* [ check-in-d ] [ check-out-d ] bi ;
-
-M: #>r check-stack-flow* [ check-in-d ] [ check-out-r ] bi ;
-
-M: #r> check-stack-flow* [ check-in-r ] [ check-out-d ] bi ;
+M: #shuffle check-stack-flow*
+    { [ check-in-d ] [ check-in-r ] [ check-out-d ] [ check-out-r ] } cleave ;
 
 : assert-datastack-empty ( -- )
     datastack get empty? [ "Data stack not empty" throw ] unless ;
index b77a27800fa285404e33c0a5d2eaf985fd4401b4..4a6198db37d99a4a5a79360d0dc0a3c2d34639d8 100644 (file)
@@ -5,7 +5,7 @@ strings sbufs sequences.private slots.private combinators
 definitions system layouts vectors math.partial-dispatch
 math.order math.functions accessors hashtables classes assocs
 io.encodings.utf8 io.encodings.ascii io.encodings fry slots
-sorting.private combinators.short-circuit
+sorting.private combinators.short-circuit grouping prettyprint
 compiler.tree
 compiler.tree.combinators
 compiler.tree.cleanup
@@ -500,3 +500,13 @@ cell-bits 32 = [
     [ { array-capacity } declare 1 fixnum+ ] cleaned-up-tree
     [ { [ #call? ] [ node-input-infos second literal>> 1 = ] } 1&& ] contains?
 ] unit-test
+
+[ ] [
+    [ { null } declare [ 1 ] [ 2 ] if ]
+    build-tree normalize propagate cleanup check-nodes
+] unit-test
+
+[ t ] [
+    [ { array } declare 2 <groups> [ . . ] assoc-each ]
+    \ nth-unsafe inlined?
+] unit-test
index 4ca058b2e393bdaef2f07ab46aaa572bd36b58dd..becac01cd5355a957e857d47849dc68c912c71e4 100644 (file)
@@ -102,7 +102,7 @@ M: #declare cleanup* drop f ;
     #! If only one branch is live we don't need to branch at
     #! all; just drop the condition value.
     dup live-children sift dup length {
-        { 0 [ 2drop f ] }
+        { 0 [ drop in-d>> #drop ] }
         { 1 [ first swap in-d>> #drop prefix ] }
         [ 2drop ]
     } case ;
index 719c80f911120c6985d32fffc2699bbd737a5921..eba82384ab362b2fa8b9171bbbbefb4055458ba2 100644 (file)
@@ -39,7 +39,7 @@ M: #branch remove-dead-code*
     [ drop filter-live ] [ swap nths ] 2bi
     [ make-values ] keep
     [ drop ] [ zip ] 2bi
-    #shuffle ;
+    #data-shuffle ;
 
 : insert-drops ( nodes values indices -- nodes' )
     '[
index addb13ced3a2e8462e012899631aeca39545daeb..185c776c4e37590fe8446a9bc2a1341e573e8ea7 100644 (file)
@@ -39,12 +39,6 @@ M: #copy compute-live-values*
 
 M: #call compute-live-values* nip look-at-inputs ;
 
-M: #>r compute-live-values*
-    [ out-r>> ] [ in-d>> ] bi look-at-mapping ;
-
-M: #r> compute-live-values*
-    [ out-d>> ] [ in-r>> ] bi look-at-mapping ;
-
 M: #shuffle compute-live-values*
     mapping>> at look-at-value ;
 
@@ -61,7 +55,7 @@ M: #alien-indirect compute-live-values* nip look-at-inputs ;
     zip filter-mapping values ;
 
 : filter-live ( values -- values' )
-    [ live-value? ] filter ;
+    dup empty? [ [ live-value? ] filter ] unless ;
 
 :: drop-values ( inputs outputs mapping-keys mapping-values -- #shuffle )
     inputs
@@ -69,7 +63,7 @@ M: #alien-indirect compute-live-values* nip look-at-inputs ;
     outputs
     mapping-keys
     mapping-values
-    filter-corresponding zip #shuffle ; inline
+    filter-corresponding zip #data-shuffle ; inline
 
 :: drop-dead-values ( outputs -- #shuffle )
     [let* | new-outputs [ outputs make-values ]
@@ -95,16 +89,6 @@ M: #alien-indirect compute-live-values* nip look-at-inputs ;
 M: #introduce remove-dead-code* ( #introduce -- nodes )
     maybe-drop-dead-outputs ;
 
-M: #>r remove-dead-code*
-    [ filter-live ] change-out-r
-    [ filter-live ] change-in-d
-    dup in-d>> empty? [ drop f ] when ;
-
-M: #r> remove-dead-code*
-    [ filter-live ] change-out-d
-    [ filter-live ] change-in-r
-    dup in-r>> empty? [ drop f ] when ;
-
 M: #push remove-dead-code*
     dup out-d>> first live-value? [ drop f ] unless ;
 
@@ -125,12 +109,14 @@ M: #call remove-dead-code*
 M: #shuffle remove-dead-code*
     [ filter-live ] change-in-d
     [ filter-live ] change-out-d
+    [ filter-live ] change-in-r
+    [ filter-live ] change-out-r
     [ filter-mapping ] change-mapping
-    dup in-d>> empty? [ drop f ] when ;
+    dup [ in-d>> empty? ] [ in-r>> empty? ] bi and [ drop f ] when ;
 
 M: #copy remove-dead-code*
     [ in-d>> ] [ out-d>> ] bi
-    2dup swap zip #shuffle
+    2dup swap zip #data-shuffle
     remove-dead-code* ;
 
 M: #terminate remove-dead-code*
index 59a028a4f42ea31b038c290143e13e80922cf613..a1d87734843f14af03f258b551c4a51b68d0dad4 100644 (file)
@@ -3,7 +3,7 @@
 USING: kernel assocs match fry accessors namespaces make effects
 sequences sequences.private quotations generic macros arrays
 prettyprint prettyprint.backend prettyprint.sections math words
-combinators io sorting hints qualified
+combinators combinators.short-circuit io sorting hints qualified
 compiler.tree
 compiler.tree.recursive
 compiler.tree.normalization
@@ -57,9 +57,41 @@ TUPLE: shuffle-node { effect effect } ;
 
 M: shuffle-node pprint* effect>> effect>string text ;
  
+: (shuffle-effect) ( in out #shuffle -- effect )
+    mapping>> '[ _ at ] map <effect> ;
+
+: shuffle-effect ( #shuffle -- effect )
+    [ in-d>> ] [ out-d>> ] [ ] tri (shuffle-effect) ;
+
+: #>r? ( #shuffle -- ? )
+    {
+        [ in-d>> length 1 = ]
+        [ out-r>> length 1 = ]
+        [ in-r>> empty? ]
+        [ out-d>> empty? ]
+    } 1&& ;
+
+: #r>? ( #shuffle -- ? )
+    {
+        [ in-d>> empty? ]
+        [ out-r>> empty? ]
+        [ in-r>> length 1 = ]
+        [ out-d>> length 1 = ]
+    } 1&& ;
+
 M: #shuffle node>quot
-    shuffle-effect dup pretty-shuffle
-    [ % ] [ shuffle-node boa , ] ?if ;
+    {
+        { [ dup #>r? ] [ drop \ >r , ] }
+        { [ dup #r>? ] [ drop \ r> , ] }
+        {
+            [ dup [ in-r>> empty? ] [ out-r>> empty? ] bi and ]
+            [
+                shuffle-effect dup pretty-shuffle
+                [ % ] [ shuffle-node boa , ] ?if
+            ]
+        }
+        [ drop "COMPLEX SHUFFLE" , ]
+    } cond ;
 
 M: #push node>quot literal>> , ;
 
@@ -82,16 +114,6 @@ M: #if node>quot
 M: #dispatch node>quot
     children>> [ nodes>quot ] map , \ dispatch , ;
 
-M: #>r node>quot
-    [ in-d>> length ] [ out-r>> empty? \ drop \ >r ? ] bi
-    <repetition> % ;
-
-DEFER: rdrop
-
-M: #r> node>quot
-    [ in-r>> length ] [ out-d>> empty? \ rdrop \ r> ? ] bi
-    <repetition> % ;
-
 M: #alien-invoke node>quot params>> , \ #alien-invoke , ;
 
 M: #alien-indirect node>quot params>> , \ #alien-indirect , ;
index 2379f3918d46b76404d7bf075c8a6155584a0ccb..9be9f13043fea79970f2eda4439753d3d365c6f5 100644 (file)
@@ -38,16 +38,16 @@ GENERIC: node-uses-values ( node -- values )
 
 M: #introduce node-uses-values drop f ;
 M: #push node-uses-values drop f ;
-M: #r> node-uses-values in-r>> ;
 M: #phi node-uses-values phi-in-d>> concat remove-bottom prune ;
 M: #declare node-uses-values declaration>> keys ;
 M: #terminate node-uses-values [ in-d>> ] [ in-r>> ] bi append ;
+M: #shuffle node-uses-values [ in-d>> ] [ in-r>> ] bi append ;
 M: #alien-callback node-uses-values drop f ;
 M: node node-uses-values in-d>> ;
 
 GENERIC: node-defs-values ( node -- values )
 
-M: #>r node-defs-values out-r>> ;
+M: #shuffle node-defs-values [ out-d>> ] [ out-r>> ] bi append ;
 M: #branch node-defs-values drop f ;
 M: #declare node-defs-values drop f ;
 M: #return node-defs-values drop f ;
index 4c197d7fc03d6613763baaf191749ac852003fce..5d34eaad1561b9e8a8dcb08e0b799d716f2f5646 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs namespaces sequences kernel math
-combinators sets disjoint-sets fry stack-checker.state ;
+combinators sets disjoint-sets fry stack-checker.values ;
 IN: compiler.tree.escape-analysis.allocations
 
 ! A map from values to one of the following:
index 4ed194e81dacc592404abfb1f8b76a3b31806bd3..9a226b954f7d1c3077d181c9873598009be7383e 100644 (file)
@@ -8,6 +8,7 @@ math.private kernel tools.test accessors slots.private
 quotations.private prettyprint classes.tuple.private classes
 classes.tuple namespaces
 compiler.tree.propagation.info stack-checker.errors
+compiler.tree.checker
 kernel.private ;
 
 \ escape-analysis must-infer
@@ -34,6 +35,7 @@ M: node count-unboxed-allocations* drop ;
     propagate
     cleanup
     escape-analysis
+    dup check-nodes
     0 swap [ count-unboxed-allocations* ] each-node ;
 
 [ 0 ] [ [ [ + ] curry ] count-unboxed-allocations ] unit-test
@@ -307,7 +309,7 @@ C: <ro-box> ro-box
 : bleach-node ( quot: ( node -- ) -- )
     [ bleach-node ] curry [ ] compose impeach-node ; inline recursive
 
-[ 2 ] [ [ [ ] bleach-node ] count-unboxed-allocations ] unit-test
+[ 3 ] [ [ [ ] bleach-node ] count-unboxed-allocations ] unit-test
 
 [ 0 ] [
     [ dup -1 over >= [ 0 >= [ "A" throw ] unless ] [ drop ] if ]
index 2d2e42999461c3292e47d45a9122e602a9b2b01b..16a27e020a13dfa6b8aab38619ba74638d1eedc5 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences words memoize classes.builtin
+fry assocs
 compiler.tree
 compiler.tree.combinators
 compiler.tree.propagation.info
@@ -27,9 +28,10 @@ GENERIC: finalize* ( node -- nodes )
 M: #copy finalize* drop f ;
 
 M: #shuffle finalize*
-    dup shuffle-effect
-    [ in>> ] [ out>> ] bi sequence=
-    [ drop f ] when ;
+    dup
+    [ [ in-d>> ] [ out-d>> ] [ mapping>> ] tri '[ _ at ] map sequence= ]
+    [ [ in-r>> ] [ out-r>> ] [ mapping>> ] tri '[ _ at ] map sequence= ]
+    bi and [ drop f ] when ;
 
 : builtin-predicate? ( #call -- ? )
     word>> "predicating" word-prop builtin-class? ;
index d6ed59cbaa3cca1946fca5e71e04571b30e95434..00632ec6f6bc5af37025a151d3f635db802e60c8 100644 (file)
@@ -79,7 +79,7 @@ GENERIC: apply-identities* ( node -- node )
 
 : select-input ( node n -- #shuffle )
     [ [ in-d>> ] [ out-d>> ] bi ] dip
-    pick nth over first associate #shuffle ;
+    pick nth over first associate #data-shuffle ;
 
 M: #call apply-identities*
     dup word>> "identities" word-prop [
index 3050df2611397859fc2dbf9c847aa231d98f8c5f..9d68f4a733bf5f9df42a165b86516bc14f4a1562 100644 (file)
@@ -10,7 +10,7 @@ SYMBOL: rename-map
     [ rename-map get at ] keep or ;
 
 : rename-values ( values -- values' )
-    rename-map get '[ [ _ at ] keep or ] map ;
+    dup empty? [ rename-map get '[ [ _ at ] keep or ] map ] unless ;
 
 : add-renamings ( old new -- )
     [ rename-values ] dip
@@ -22,13 +22,11 @@ M: #introduce rename-node-values* ;
 
 M: #shuffle rename-node-values*
     [ rename-values ] change-in-d
+    [ rename-values ] change-in-r
     [ [ rename-value ] assoc-map ] change-mapping ;
 
 M: #push rename-node-values* ;
 
-M: #r> rename-node-values*
-    [ rename-values ] change-in-r ;
-
 M: #terminate rename-node-values*
     [ rename-values ] change-in-d
     [ rename-values ] change-in-r ;
index c76217f8aed6bd171359baa33f7cd3253ee4ec18..424cd8a01c404c25ace5a54047621ee9764b4779 100644 (file)
@@ -40,8 +40,8 @@ M: #dispatch live-branches
 SYMBOL: infer-children-data
 
 : copy-value-info ( -- )
-    value-infos [ clone ] change
-    constraints [ clone ] change ;
+    value-infos [ H{ } clone suffix ] change
+    constraints [ H{ } clone suffix ] change ;
 
 : no-value-info ( -- )
     value-infos off
index cfdf7f51697ab8cfe2364247834c8c1ca48c61e6..2652547aaddb46eb524788216009f82e8f1a5d08 100644 (file)
@@ -32,7 +32,7 @@ TUPLE: true-constraint value ;
 
 M: true-constraint assume*
     [ \ f class-not <class-info> swap value>> refine-value-info ]
-    [ constraints get at [ assume ] when* ]
+    [ constraints get assoc-stack [ assume ] when* ]
     bi ;
 
 M: true-constraint satisfied?
@@ -44,7 +44,7 @@ TUPLE: false-constraint value ;
 
 M: false-constraint assume*
     [ \ f <class-info> swap value>> refine-value-info ]
-    [ constraints get at [ assume ] when* ]
+    [ constraints get assoc-stack [ assume ] when* ]
     bi ;
 
 M: false-constraint satisfied?
@@ -83,7 +83,7 @@ TUPLE: implication p q ;
 C: --> implication
 
 : assume-implication ( p q -- )
-    [ constraints get [ swap suffix ] change-at ]
+    [ constraints get [ assoc-stack swap suffix ] 2keep peek set-at ]
     [ satisfied? [ assume ] [ drop ] if ] 2bi ;
 
 M: implication assume*
index 24f4ca59dcfc6df0f616e72a0964d565305c8fc9..2c3314994b53afd9499db4a7773a81523722a706 100644 (file)
@@ -70,3 +70,7 @@ TUPLE: test-tuple { x read-only } ;
     f f 3 <literal-info> 3array test-tuple <tuple-info> dup
     object-info value-info-intersect =
 ] unit-test
+
+[ t ] [
+    null-info 3 <literal-info> value-info<=
+] unit-test
index d1d8189f7a9eee76c72484f26206b4b5b1af05e1..e89a9c62118a83b3d155456b61a372479a03efe2 100644 (file)
@@ -34,7 +34,7 @@ slots ;
 
 : null-info T{ value-info f null empty-interval } ; inline
 
-: object-info T{ value-info f object T{ interval f { -1.0/0.0 t } { 1.0/0.0 t } } } ; inline
+: object-info T{ value-info f object full-interval } ; inline
 
 : class-interval ( class -- interval )
     dup real class<=
@@ -43,7 +43,7 @@ slots ;
 : interval>literal ( class interval -- literal literal? )
     #! If interval has zero length and the class is sufficiently
     #! precise, we can turn it into a literal
-    dup empty-interval eq? [
+    dup special-interval? [
         2drop f f
     ] [
         dup from>> first {
@@ -243,7 +243,7 @@ DEFER: (value-info-union)
 : literals<= ( info1 info2 -- ? )
     {
         { [ dup literal?>> not ] [ 2drop t ] }
-        { [ over literal?>> not ] [ 2drop f ] }
+        { [ over literal?>> not ] [ drop class>> null-class? ] }
         [ [ literal>> ] bi@ eql? ]
     } cond ;
 
@@ -262,17 +262,19 @@ DEFER: (value-info-union)
         ]
     } cond ;
 
-! Current value --> info mapping
+! Assoc stack of current value --> info mapping
 SYMBOL: value-infos
 
 : value-info ( value -- info )
-    resolve-copy value-infos get at null-info or ;
+    resolve-copy value-infos get assoc-stack null-info or ;
 
 : set-value-info ( info value -- )
-    resolve-copy value-infos get set-at ;
+    resolve-copy value-infos get peek set-at ;
 
 : refine-value-info ( info value -- )
-    resolve-copy value-infos get [ value-info-intersect ] change-at ;
+    resolve-copy value-infos get
+    [ assoc-stack value-info-intersect ] 2keep
+    peek set-at ;
 
 : value-literal ( value -- obj ? )
     value-info >literal< ;
index 101320f92cdc88a92d66bd27ab58f86dc3452b30..760ff167aa8072e9cbb6be08bc3999a056e5d5a6 100644 (file)
@@ -8,7 +8,7 @@ math.functions math.private strings layouts
 compiler.tree.propagation.info compiler.tree.def-use
 compiler.tree.debugger compiler.tree.checker
 slots.private words hashtables classes assocs locals
-float-arrays system ;
+float-arrays system sorting ;
 IN: compiler.tree.propagation.tests
 
 \ propagate must-infer
@@ -592,6 +592,8 @@ MIXIN: empty-mixin
 
 [ V{ t } ] [ [ netbsd unix? ] final-literals ] unit-test
 
+[ V{ array } ] [ [ [ <=> ] sort [ <=> ] sort ] final-classes ] unit-test
+
 ! [ V{ string } ] [
 !     [ dup string? t xor [ "A" throw ] [ ] if ] final-classes
 ! ] unit-test
index d82ebed43379b3d805526969cfd5bb6d0caff4d6..b9822d2c6bfa1d595b537ad20703fee724ef94f9 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel sequences namespaces hashtables
+USING: accessors kernel sequences namespaces hashtables arrays
 compiler.tree
 compiler.tree.propagation.copy
 compiler.tree.propagation.info
@@ -17,7 +17,7 @@ IN: compiler.tree.propagation
 
 : propagate ( node -- node )
     H{ } clone copies set
-    H{ } clone constraints set
-    H{ } clone value-infos set
+    H{ } clone 1array value-infos set
+    H{ } clone 1array constraints set
     dup count-nodes
     dup (propagate) ;
index 53dce813a3874624a1b760f83705ef1583cfe040..7f10f870165fca82fd201948aa17f9f2d4e23c03 100644 (file)
@@ -17,9 +17,12 @@ IN: compiler.tree.propagation.recursive
     [ value-info<= ] 2all?
     [ drop ] [ label>> f >>fixed-point drop ] if ;
 
+: latest-input-infos ( node -- infos )
+    in-d>> [ value-info ] map ;
+
 : recursive-stacks ( #enter-recursive -- stacks initial )
     [ label>> calls>> [ node-input-infos ] map flip ]
-    [ in-d>> [ value-info ] map ] bi ;
+    [ latest-input-infos ] bi ;
 
 : generalize-counter-interval ( interval initial-interval -- interval' )
     {
@@ -46,14 +49,13 @@ IN: compiler.tree.propagation.recursive
     ] if ;
 
 : propagate-recursive-phi ( #enter-recursive -- )
-    [ ] [ recursive-stacks unify-recursive-stacks ] [ ] tri
-    [ node-output-infos check-fixed-point ]
-    [ out-d>> set-value-infos drop ]
-    3bi ;
+    [ recursive-stacks unify-recursive-stacks ] keep
+    out-d>> set-value-infos ;
 
 M: #recursive propagate-around ( #recursive -- )
+    constraints [ H{ } clone suffix ] change
     [
-        constraints [ clone ] change
+        constraints [ but-last H{ } clone suffix ] change
 
         child>>
         [ first compute-copy-equiv ]
@@ -62,6 +64,9 @@ M: #recursive propagate-around ( #recursive -- )
         tri
     ] until-fixed-point ;
 
+: recursive-phi-infos ( node -- infos )
+    label>> enter-recursive>> node-output-infos ;
+
 : generalize-return-interval ( info -- info' )
     dup [ literal?>> ] [ class>> null-class? ] bi or
     [ clone [-inf,inf] >>interval ] unless ;
@@ -70,12 +75,25 @@ M: #recursive propagate-around ( #recursive -- )
     [ generalize-return-interval ] map ;
 
 : return-infos ( node -- infos )
-    label>> [ return>> node-input-infos ] [ loop?>> ] bi
-    [ generalize-return ] unless ;
+    label>> return>> node-input-infos generalize-return ;
+
+: save-return-infos ( node infos -- )
+    swap out-d>> set-value-infos ;
+
+: unless-loop ( node quot -- )
+    [ dup label>> loop?>> [ drop ] ] dip if ; inline
 
 M: #call-recursive propagate-before ( #call-recursive -- )
-    [ ] [ return-infos ] [ node-output-infos ] tri
-    [ check-fixed-point ] [ drop swap out-d>> set-value-infos ] 3bi ;
+    [
+        [ ] [ latest-input-infos ] [ recursive-phi-infos ] tri
+        check-fixed-point
+    ]
+    [
+        [
+            [ ] [ return-infos ] [ node-output-infos ] tri
+            [ check-fixed-point ] [ drop save-return-infos ] 3bi
+        ] unless-loop
+    ] bi ;
 
 M: #call-recursive annotate-node
     dup [ in-d>> ] [ out-d>> ] bi append (annotate-node) ;
@@ -83,5 +101,11 @@ M: #call-recursive annotate-node
 M: #enter-recursive annotate-node
     dup out-d>> (annotate-node) ;
 
+M: #return-recursive propagate-before ( #return-recursive -- )
+    [
+        [ ] [ latest-input-infos ] [ node-input-infos ] tri
+        check-fixed-point
+    ] unless-loop ;
+
 M: #return-recursive annotate-node
     dup in-d>> (annotate-node) ;
index 05f33902ecd805b6d52c90a14e16f52d181e871f..9f9a43df6460043c8064149ab4a486b7dffc6172 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry arrays generic assocs kernel math namespaces parser
-sequences words vectors math.intervals effects classes
+sequences words vectors math.intervals classes
 accessors combinators stack-checker.state stack-checker.visitor
 stack-checker.inlining ;
 IN: compiler.tree
@@ -42,30 +42,21 @@ TUPLE: #push < node literal out-d ;
 
 TUPLE: #renaming < node ;
 
-TUPLE: #shuffle < #renaming mapping in-d out-d ;
+TUPLE: #shuffle < #renaming mapping in-d out-d in-r out-r ;
 
-: #shuffle ( inputs outputs mapping -- node )
+: #shuffle ( in-d out-d in-r out-r mapping -- node )
     \ #shuffle new
         swap >>mapping
-        swap >>out-d
-        swap >>in-d ;
-
-: #drop ( inputs -- node )
-    { } { } #shuffle ;
-
-TUPLE: #>r < #renaming in-d out-r ;
-
-: #>r ( inputs outputs -- node )
-    \ #>r new
         swap >>out-r
+        swap >>in-r
+        swap >>out-d
         swap >>in-d ;
 
-TUPLE: #r> < #renaming in-r out-d ;
+: #data-shuffle ( in-d out-d mapping -- node )
+    [ f f ] dip #shuffle ; inline
 
-: #r> ( inputs outputs -- node )
-    \ #r> new
-        swap >>out-d
-        swap >>in-r ;
+: #drop ( inputs -- node )
+    { } { } #data-shuffle ;
 
 TUPLE: #terminate < node in-d in-r ;
 
@@ -171,16 +162,9 @@ TUPLE: #alien-callback < #alien-node ;
 GENERIC: inputs/outputs ( #renaming -- inputs outputs )
 
 M: #shuffle inputs/outputs mapping>> unzip swap ;
-M: #>r inputs/outputs [ in-d>> ] [ out-r>> ] bi ;
-M: #r> inputs/outputs [ in-r>> ] [ out-d>> ] bi ;
 M: #copy inputs/outputs [ in-d>> ] [ out-d>> ] bi ;
 M: #return-recursive inputs/outputs [ in-d>> ] [ out-d>> ] bi ;
 
-: shuffle-effect ( #shuffle -- effect )
-    [ in-d>> ] [ out-d>> ] [ mapping>> ] tri
-    '[ _ at ] map
-    <effect> ;
-
 : recursive-phi-in ( #enter-recursive -- seq )
     [ label>> calls>> [ in-d>> ] map ] [ in-d>> ] bi suffix ;
 
@@ -193,8 +177,8 @@ M: vector #call, #call node, ;
 M: vector #push, #push node, ;
 M: vector #shuffle, #shuffle node, ;
 M: vector #drop, #drop node, ;
-M: vector #>r, #>r node, ;
-M: vector #r>, #r> node, ;
+M: vector #>r, [ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
+M: vector #r>, [ swap [ f swap ] dip f ] [ swap zip ] 2bi #shuffle, ;
 M: vector #return, #return node, ;
 M: vector #enter-recursive, #enter-recursive node, ;
 M: vector #return-recursive, #return-recursive node, ;
index 8e07c081942ca79c7de040bbc0f0e111e77e8748..52903fce8de3064ba14d6fc322f3b908720488de 100644 (file)
@@ -42,7 +42,7 @@ M: #push unbox-tuples* ( #push -- nodes )
     [ dup unboxed-allocation [ (flatten-values) ] [ ] ?if ] map ;
 
 : flatten-values ( values -- values' )
-    (flatten-values) flatten ;
+    dup empty? [ (flatten-values) flatten ] unless ;
 
 : prepare-slot-access ( #call -- tuple-values outputs slot-values )
     [ in-d>> flatten-values ]
@@ -54,7 +54,7 @@ M: #push unbox-tuples* ( #push -- nodes )
     ] tri ;
 
 : slot-access-shuffle ( tuple-values outputs slot-values -- #shuffle )
-    [ drop ] [ zip ] 2bi #shuffle ;
+    [ drop ] [ zip ] 2bi #data-shuffle ;
 
 : unbox-slot-access ( #call -- nodes )
     dup out-d>> first unboxed-slot-access? [
@@ -77,17 +77,11 @@ M: #copy unbox-tuples*
     [ flatten-values ] change-in-d
     [ flatten-values ] change-out-d ;
 
-M: #>r unbox-tuples*
-    [ flatten-values ] change-in-d
-    [ flatten-values ] change-out-r ;
-
-M: #r> unbox-tuples*
-    [ flatten-values ] change-in-r
-    [ flatten-values ] change-out-d ;
-
 M: #shuffle unbox-tuples*
     [ flatten-values ] change-in-d
     [ flatten-values ] change-out-d
+    [ flatten-values ] change-in-r
+    [ flatten-values ] change-out-r
     [ unzip [ flatten-values ] bi@ zip ] change-mapping ;
 
 M: #terminate unbox-tuples*
index e4fa9419f061e97fbb3f8758cab6ba7009a89b02..96dd577c10be6615a5e9c2eaa1d04b79bffaf7c8 100644 (file)
@@ -50,7 +50,7 @@ HOOK: %call cpu ( word -- )
 HOOK: %jump-label cpu ( label -- )
 HOOK: %return cpu ( -- )
 
-HOOK: %dispatch cpu ( src temp -- )
+HOOK: %dispatch cpu ( src temp offset -- )
 HOOK: %dispatch-label cpu ( word -- )
 
 HOOK: %slot cpu ( dst obj slot tag temp -- )
@@ -146,8 +146,14 @@ HOOK: struct-small-enough? cpu ( heap-size -- ? )
 ! Do we pass value structs by value or hidden reference?
 HOOK: value-structs? cpu ( -- ? )
 
-! If t, fp parameters are shadowed by dummy int parameters
-HOOK: fp-shadows-int? cpu ( -- ? )
+! If t, all parameters are shadowed by dummy stack parameters
+HOOK: dummy-stack-params? cpu ( -- ? )
+
+! If t, all FP parameters are shadowed by dummy int parameters
+HOOK: dummy-int-params? cpu ( -- ? )
+
+! If t, all int parameters are shadowed by dummy FP parameters
+HOOK: dummy-fp-params? cpu ( -- ? )
 
 HOOK: %prepare-unbox cpu ( -- )
 
index 9bf88185c5d8a0c156f7723468fb64707cef5c1d..aee0f3f4f38c66f6c2f603846e11e02f975b2e31 100644 (file)
@@ -57,7 +57,12 @@ big-endian on
 \r
 [\r
     0 6 LOAD32\r
-    4 1 MR\r
+    7 6 0 LWZ\r
+    1 7 0 STW\r
+] rc-absolute-ppc-2/2 rt-stack-chain 1 jit-save-stack jit-define\r
+\r
+[\r
+    0 6 LOAD32\r
     6 MTCTR\r
     BCTR\r
 ] rc-absolute-ppc-2/2 rt-primitive 1 jit-primitive jit-define\r
index d92709a39992f28a417cd1c34fdf324c2411efea..090495aa11b92782b1544eaa196fce00eb12129d 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ;
+USING: accessors system kernel layouts
+alien.c-types cpu.architecture cpu.ppc ;
 IN: cpu.ppc.linux
 
 <<
@@ -8,12 +9,16 @@ t "longlong" c-type (>>stack-align?)
 t "ulonglong" c-type (>>stack-align?)
 >>
 
-M: linux reserved-area-size 2 ;
+M: linux reserved-area-size 2 cells ;
 
-M: linux lr-save 1 ;
+M: linux lr-save 1 cells ;
 
-M: float-regs param-regs { 1 2 3 4 5 6 7 8 } ;
+M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ;
 
-M: ppc value-structs? drop f ;
+M: ppc value-structs? f ;
 
-M: ppc fp-shadows-int? drop f ;
+M: ppc dummy-stack-params? f ;
+
+M: ppc dummy-int-params? f ;
+
+M: ppc dummy-fp-params? f ;
index 1e0a6caca00f1e0f3a9ac67c388bfe43afe0409f..877fb37d31dc8e5cadfb6b984b76f20e5717eef6 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ;
+USING: accessors system kernel layouts
+alien.c-types cpu.architecture cpu.ppc ;
 IN: cpu.ppc.macosx
 
 <<
@@ -9,12 +10,16 @@ IN: cpu.ppc.macosx
 4 "double" c-type (>>align)
 >>
 
-M: macosx reserved-area-size 6 ;
+M: macosx reserved-area-size 6 cells ;
 
-M: macosx lr-save 2 ;
+M: macosx lr-save 2 cells ;
 
-M: float-regs param-regs { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
+M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
 
-M: ppc value-structs? drop t ;
+M: ppc value-structs? t ;
 
-M: ppc fp-shadows-int? drop t ;
+M: ppc dummy-stack-params? t ;
+
+M: ppc dummy-int-params? t ;
+
+M: ppc dummy-fp-params? f ;
index d2d1e263965adf32002a530a6454220d156c332a..c656ae4d89aaadcf86afe1aa5f7b08614b5f0c33 100644 (file)
@@ -4,7 +4,8 @@ USING: accessors assocs sequences kernel combinators make math
 math.order math.ranges system namespaces locals layouts words
 alien alien.c-types cpu.architecture cpu.ppc.assembler
 compiler.cfg.registers compiler.cfg.instructions
-compiler.constants compiler.codegen compiler.codegen.fixup ;
+compiler.constants compiler.codegen compiler.codegen.fixup
+compiler.cfg.intrinsics compiler.cfg.stack-frame ;
 IN: cpu.ppc
 
 ! PowerPC register assignments:
@@ -15,15 +16,19 @@ IN: cpu.ppc
 ! f0-f29: float vregs
 ! f30, f31: float scratch
 
+enable-float-intrinsics
+
+<< \ ##integer>float t frame-required? set-word-prop
+\ ##float>integer t frame-required? set-word-prop >>
+
 M: ppc machine-registers
     {
         { int-regs T{ range f 2 26 1 } }
-        { double-float-regs T{ range f 0 28 1 } }
+        { double-float-regs T{ range f 0 29 1 } }
     } ;
 
 : scratch-reg 28 ; inline
-: fp-scratch-reg-1 29 ; inline
-: fp-scratch-reg-2 30 ; inline
+: fp-scratch-reg 30 ; inline
 
 M: ppc two-operand? f ;
 
@@ -54,8 +59,16 @@ M: ppc %inc-d ( n -- ) ds-reg (%inc) ;
 M: ppc %inc-r ( n -- ) rs-reg (%inc) ;
 
 HOOK: reserved-area-size os ( -- n )
-HOOK: lr-save os ( -- n )
 
+! The start of the stack frame contains the size of this frame
+! as well as the currently executing XT
+: factor-area-size ( -- n ) 2 cells ; foldable
+: next-save ( n -- i ) cell - ;
+: xt-save ( n -- i ) 2 cells - ;
+
+! Next, we have the spill area as well as the FFI parameter area.
+! They overlap, since basic blocks with FFI calls will never
+! spill.
 : param@ ( n -- x ) reserved-area-size + ; inline
 
 : param-save-size ( -- n ) 8 cells ; foldable
@@ -63,19 +76,34 @@ HOOK: lr-save os ( -- n )
 : local@ ( n -- x )
     reserved-area-size param-save-size + + ; inline
 
-: factor-area-size ( -- n ) 2 cells ; foldable
+: spill-integer-base ( -- n )
+    stack-frame get spill-counts>> double-float-regs swap at
+    double-float-regs reg-size * ;
 
-: next-save ( n -- i ) cell - ;
+: spill-integer@ ( n -- offset )
+    cells spill-integer-base + param@ ;
 
-: xt-save ( n -- i ) 2 cells - ;
+: spill-float@ ( n -- offset )
+    double-float-regs reg-size * param@ ;
+
+! Some FP intrinsics need a temporary scratch area in the stack
+! frame, 8 bytes in size
+: scratch@ ( n -- offset )
+    stack-frame get total-size>>
+    factor-area-size -
+    param-save-size -
+    + ;
+
+! Finally we have the linkage area
+HOOK: lr-save os ( -- n )
 
 M: ppc stack-frame-size ( stack-frame -- i )
     [ spill-counts>> [ swap reg-size * ] { } assoc>map sum ]
     [ params>> ]
     [ return>> ]
     tri + +
-    reserved-area-size +
     param-save-size +
+    reserved-area-size +
     factor-area-size +
     4 cells align ;
 
@@ -83,10 +111,10 @@ M: ppc %call ( label -- ) BL ;
 M: ppc %jump-label ( label -- ) B ;
 M: ppc %return ( -- ) BLR ;
 
-M:: ppc %dispatch ( src temp -- )
-    0 temp LOAD32 rc-absolute-ppc-2/2 rel-here
-    temp temp src ADD
-    temp temp 5 cells LWZ
+M:: ppc %dispatch ( src temp offset -- )
+    0 temp LOAD32
+    4 offset + cells rc-absolute-ppc-2/2 rel-here
+    temp temp src LWZX
     temp MTCTR
     BCTR ;
 
@@ -198,19 +226,19 @@ M: ppc %div-float FDIV ;
 
 M:: ppc %integer>float ( dst src -- )
     HEX: 4330 scratch-reg LIS
-    scratch-reg 1 0 param@ STW
+    scratch-reg 1 0 scratch@ STW
     scratch-reg src MR
     scratch-reg dup HEX: 8000 XORIS
-    scratch-reg 1 cell param@ STW
-    fp-scratch-reg-2 1 0 param@ LFD
+    scratch-reg 1 4 scratch@ STW
+    dst 1 0 scratch@ LFD
     scratch-reg 4503601774854144.0 %load-indirect
-    fp-scratch-reg-2 scratch-reg float-offset LFD
-    fp-scratch-reg-2 fp-scratch-reg-2 fp-scratch-reg-2 FSUB ;
+    fp-scratch-reg scratch-reg float-offset LFD
+    dst dst fp-scratch-reg FSUB ;
 
 M:: ppc %float>integer ( dst src -- )
-    fp-scratch-reg-1 src FCTIWZ
-    fp-scratch-reg-2 1 0 param@ STFD
-    dst 1 4 param@ LWZ ;
+    fp-scratch-reg src FCTIWZ
+    fp-scratch-reg 1 0 scratch@ STFD
+    dst 1 4 scratch@ LWZ ;
 
 M: ppc %copy ( dst src -- ) MR ;
 
@@ -218,6 +246,10 @@ M: ppc %copy-float ( dst src -- ) FMR ;
 
 M: ppc %unbox-float ( dst src -- ) float-offset LFD ;
 
+M:: ppc %box-float ( dst src temp -- )
+    dst 16 float temp %allot
+    src dst float-offset STFD ;
+
 M:: ppc %unbox-any-c-ptr ( dst src temp -- )
     [
         { "is-byte-array" "end" "start" } [ define-label ] each
@@ -349,12 +381,12 @@ M: ppc %gc
     "end" resolve-label ;
 
 M: ppc %prologue ( n -- )
-    0 scratch-reg LOAD32 rc-absolute-ppc-2/2 rel-this
+    0 11 LOAD32 rc-absolute-ppc-2/2 rel-this
     0 MFLR
     1 1 pick neg ADDI
-    scratch-reg 1 pick xt-save STW
-    dup scratch-reg LI
-    scratch-reg 1 pick next-save STW
+    11 1 pick xt-save STW
+    dup 11 LI
+    11 1 pick next-save STW
     0 1 rot lr-save + STW ;
 
 M: ppc %epilogue ( n -- )
@@ -405,32 +437,11 @@ M: ppc %compare-branch (%compare) %branch ;
 M: ppc %compare-imm-branch (%compare-imm) %branch ;
 M: ppc %compare-float-branch (%compare-float) %branch ;
 
-: spill-integer-base ( stack-frame -- n )
-    [ params>> ] [ return>> ] bi + ;
-
-: stack@ 1 swap ; inline
-
-: spill-integer@ ( n -- reg offset )
-    cells
-    stack-frame get spill-integer-base
-    + stack@ ;
-
-: spill-float-base ( stack-frame -- n )
-    [ spill-counts>> int-regs swap at int-regs reg-size * ]
-    [ params>> ]
-    [ return>> ]
-    tri + + ;
-
-: spill-float@ ( n -- reg offset )
-    double-float-regs reg-size *
-    stack-frame get spill-float-base
-    + stack@ ;
-
-M: ppc %spill-integer ( src n -- ) spill-integer@ STW ;
-M: ppc %reload-integer ( dst n -- ) spill-integer@ LWZ ;
+M: ppc %spill-integer ( src n -- ) spill-integer@ 1 swap STW ;
+M: ppc %reload-integer ( dst n -- ) spill-integer@ 1 swap LWZ ;
 
-M: ppc %spill-float ( src n -- ) spill-float@ STFD ;
-M: ppc %reload-float ( dst n -- ) spill-float@ LFD ;
+M: ppc %spill-float ( src n -- ) spill-float@ 1 swap STFD ;
+M: ppc %reload-float ( dst n -- ) spill-float@ 1 swap LFD ;
 
 M: ppc %loop-entry ;
 
index 82fa7a012e3a76a698845ff0aa225ede7cdb77ae..f892271fd5b2d22254b0288ed1409568b9043d83 100644 (file)
@@ -6,7 +6,7 @@ accessors init combinators command-line cpu.x86.assembler
 cpu.x86 cpu.architecture compiler compiler.units
 compiler.constants compiler.alien compiler.codegen
 compiler.codegen.fixup compiler.cfg.instructions
-compiler.cfg.builder compiler.cfg.intrinsics ;
+compiler.cfg.builder compiler.cfg.intrinsics make ;
 IN: cpu.x86.32
 
 ! We implement the FFI for Linux, OS X and Windows all at once.
@@ -26,6 +26,18 @@ M: x86.32 stack-reg ESP ;
 M: x86.32 temp-reg-1 EAX ;
 M: x86.32 temp-reg-2 ECX ;
 
+M:: x86.32 %dispatch ( src temp offset -- )
+    ! Load jump table base.
+    src HEX: ffffffff ADD
+    offset cells rc-absolute-cell rel-here
+    ! Go
+    src HEX: 7f [+] JMP
+    ! Fix up the displacement above
+    cell code-alignment
+    [ 7 + building get dup pop* push ]
+    [ align-code ]
+    bi ;
+
 M: x86.32 reserved-area-size 0 ;
 
 M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ;
@@ -274,6 +286,12 @@ M: x86.32 %callback-return ( n -- )
         [ drop 0 ]
     } cond RET ;
 
+M: x86.32 dummy-stack-params? f ;
+
+M: x86.32 dummy-int-params? f ;
+
+M: x86.32 dummy-fp-params? f ;
+
 os windows? [
     cell "longlong" c-type (>>align)
     cell "ulonglong" c-type (>>align)
index 44f840e66aa2179264d44172f92f5698f3ca07a7..ba963ab477d2f087df299394f8fb1319255558f9 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
-cpu.x86.assembler layouts vocabs parser ;
+cpu.x86.assembler layouts vocabs parser compiler.constants ;
 IN: bootstrap.x86
 
 4 \ cell set
@@ -19,5 +19,14 @@ IN: bootstrap.x86
 : fixnum>slot@ ( -- ) arg0 1 SAR ;
 : rex-length ( -- n ) 0 ;
 
+[
+    arg0 0 [] MOV                              ! load stack_chain
+    arg0 [] stack-reg MOV                      ! save stack pointer
+] rc-absolute-cell rt-stack-chain 2 jit-save-stack jit-define
+
+[
+    (JMP) drop
+] rc-relative rt-primitive 1 jit-primitive jit-define
+
 << "resource:basis/cpu/x86/bootstrap.factor" parse-file parsed >>
 call
index d45dd098b8c4cb83b524195a9e6b2f66154262d5..75c808b50a405bec492dd04d46375825289a02e5 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel math namespaces make sequences
 system layouts alien alien.c-types alien.accessors alien.structs
-slots splitting assocs combinators cpu.x86.assembler
+slots splitting assocs combinators make locals cpu.x86.assembler
 cpu.x86 cpu.architecture compiler.constants
 compiler.codegen compiler.codegen.fixup
 compiler.cfg.instructions compiler.cfg.builder
@@ -24,8 +24,22 @@ M: x86.64 stack-reg RSP ;
 M: x86.64 temp-reg-1 RAX ;
 M: x86.64 temp-reg-2 RCX ;
 
+M:: x86.64 %dispatch ( src temp offset -- )
+    ! Load jump table base.
+    temp HEX: ffffffff MOV
+    offset cells rc-absolute-cell rel-here
+    ! Add jump table base
+    src temp ADD
+    src HEX: 7f [+] JMP
+    ! Fix up the displacement above
+    cell code-alignment
+    [ 15 + building get dup pop* push ]
+    [ align-code ]
+    bi ;
+
 : param-reg-1 int-regs param-regs first ; inline
 : param-reg-2 int-regs param-regs second ; inline
+: param-reg-3 int-regs param-regs third ; inline
 
 M: int-regs return-reg drop RAX ;
 M: float-regs return-reg drop XMM0 ;
@@ -40,13 +54,13 @@ M: x86.64 %prologue ( n -- )
 
 M: stack-params %load-param-reg
     drop
-    >r R11 swap stack@ MOV
-    r> stack@ R11 MOV ;
+    >r R11 swap param@ MOV
+    r> param@ R11 MOV ;
 
 M: stack-params %save-param-reg
     drop
     R11 swap next-stack@ MOV
-    stack@ R11 MOV ;
+    param@ R11 MOV ;
 
 : with-return-regs ( quot -- )
     [
@@ -55,37 +69,6 @@ M: stack-params %save-param-reg
         call
     ] with-scope ; inline
 
-! The ABI for passing structs by value is pretty messed up
-<< "void*" c-type clone "__stack_value" define-primitive-type
-stack-params "__stack_value" c-type (>>reg-class) >>
-
-: struct-types&offset ( struct-type -- pairs )
-    fields>> [
-        [ type>> ] [ offset>> ] bi 2array
-    ] map ;
-
-: split-struct ( pairs -- seq )
-    [
-        [ 8 mod zero? [ t , ] when , ] assoc-each
-    ] { } make { t } split harvest ;
-
-: flatten-small-struct ( c-type -- seq )
-    struct-types&offset split-struct [
-        [ c-type c-type-reg-class ] map
-        int-regs swap member? "void*" "double" ? c-type
-    ] map ;
-
-: flatten-large-struct ( c-type -- seq )
-    heap-size cell align
-    cell /i "__stack_value" c-type <repetition> ;
-
-M: struct-type flatten-value-type ( type -- seq )
-    dup heap-size 16 > [
-        flatten-large-struct
-    ] [
-        flatten-small-struct
-    ] if ;
-
 M: x86.64 %prepare-unbox ( -- )
     ! First parameter is top of stack
     param-reg-1 R14 [] MOV
@@ -102,7 +85,7 @@ M: x86.64 %unbox-long-long ( n func -- )
 
 : %unbox-struct-field ( c-type i -- )
     ! Alien must be in param-reg-1.
-    param-reg-1 swap cells [+] swap reg-class>> {
+    R11 swap cells [+] swap reg-class>> {
         { int-regs [ int-regs get pop swap MOV ] }
         { double-float-regs [ float-regs get pop swap MOVSD ] }
     } case ;
@@ -110,20 +93,20 @@ M: x86.64 %unbox-long-long ( n func -- )
 M: x86.64 %unbox-small-struct ( c-type -- )
     ! Alien must be in param-reg-1.
     "alien_offset" f %alien-invoke
-    ! Move alien_offset() return value to param-reg-1 so that we don't
+    ! Move alien_offset() return value to R11 so that we don't
     ! clobber it.
-    param-reg-1 RAX MOV
+    R11 RAX MOV
     [
-        flatten-small-struct [ %unbox-struct-field ] each-index
+        flatten-value-type [ %unbox-struct-field ] each-index
     ] with-return-regs ;
 
 M: x86.64 %unbox-large-struct ( n c-type -- )
     ! Source is in param-reg-1
     heap-size
     ! Load destination address
-    param-reg-2 rot stack@ LEA
+    param-reg-2 rot param@ LEA
     ! Load structure size
-    RDX swap MOV
+    param-reg-3 swap MOV
     ! Copy the struct to the C stack
     "to_value_struct" f %alien-invoke ;
 
@@ -142,10 +125,7 @@ M: x86.64 %box ( n reg-class func -- )
 M: x86.64 %box-long-long ( n func -- )
     int-regs swap %box ;
 
-M: x86.64 struct-small-enough? ( size -- ? )
-    heap-size 2 cells <= ;
-
-: box-struct-field@ ( i -- operand ) 1+ cells stack@ ;
+: box-struct-field@ ( i -- operand ) 1+ cells param@ ;
 
 : %box-struct-field ( c-type i -- )
     box-struct-field@ swap reg-class>> {
@@ -156,15 +136,15 @@ M: x86.64 struct-small-enough? ( size -- ? )
 M: x86.64 %box-small-struct ( c-type -- )
     #! Box a <= 16-byte struct.
     [
-        [ flatten-small-struct [ %box-struct-field ] each-index ]
-        [ RDX swap heap-size MOV ] bi
+        [ flatten-value-type [ %box-struct-field ] each-index ]
+        [ param-reg-3 swap heap-size MOV ] bi
         param-reg-1 0 box-struct-field@ MOV
         param-reg-2 1 box-struct-field@ MOV
         "box_small_struct" f %alien-invoke
     ] with-return-regs ;
 
 : struct-return@ ( n -- operand )
-    [ stack-frame get params>> ] unless* stack@ ;
+    [ stack-frame get params>> ] unless* param@ ;
 
 M: x86.64 %box-large-struct ( n c-type -- )
     ! Struct size is parameter 2
@@ -178,7 +158,7 @@ M: x86.64 %prepare-box-struct ( -- )
     ! Compute target address for value struct return
     RAX f struct-return@ LEA
     ! Store it as the first parameter
-    0 stack@ RAX MOV ;
+    0 param@ RAX MOV ;
 
 M: x86.64 %prepare-var-args RAX RAX XOR ;
 
index acac8b55bc14f7df5418de33fd24d7bc456aea9e..83a72d6dd308ade8135c68a27ce0f883033a6721 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
-cpu.x86.assembler layouts vocabs parser ;
+cpu.x86.assembler layouts vocabs parser compiler.constants math ;
 IN: bootstrap.x86
 
 8 \ cell set
@@ -16,5 +16,16 @@ IN: bootstrap.x86
 : fixnum>slot@ ( -- ) ;
 : rex-length ( -- n ) 1 ;
 
+[
+    arg0 0 MOV                                 ! load stack_chain
+    arg0 arg0 [] MOV
+    arg0 [] stack-reg MOV                      ! save stack pointer
+] rc-absolute-cell rt-stack-chain 1 rex-length + jit-save-stack jit-define
+
+[
+    arg1 0 MOV                                 ! load XT
+    arg1 JMP                                   ! go
+] rc-absolute-cell rt-primitive 1 rex-length + jit-primitive jit-define
+
 << "resource:basis/cpu/x86/bootstrap.factor" parse-file parsed >>
 call
diff --git a/basis/cpu/x86/64/unix/tags.txt b/basis/cpu/x86/64/unix/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index abbd0cf21b4f6852a038a0173abfcf664f299b2d..ddb412873a60be0e136f177befa93b41d0b80b1f 100644 (file)
@@ -1,7 +1,9 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel layouts system compiler.cfg.registers
-cpu.architecture cpu.x86.assembler cpu.x86 ;
+USING: accessors arrays sequences math splitting make assocs
+kernel layouts system alien.c-types alien.structs
+cpu.architecture cpu.x86.assembler cpu.x86
+compiler.codegen compiler.cfg.registers ;
 IN: cpu.x86.64.unix
 
 M: int-regs param-regs drop { RDI RSI RDX RCX R8 R9 } ;
@@ -10,3 +12,43 @@ M: float-regs param-regs
     drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
 
 M: x86.64 reserved-area-size 0 ;
+
+! The ABI for passing structs by value is pretty messed up
+<< "void*" c-type clone "__stack_value" define-primitive-type
+stack-params "__stack_value" c-type (>>reg-class) >>
+
+: struct-types&offset ( struct-type -- pairs )
+    fields>> [
+        [ type>> ] [ offset>> ] bi 2array
+    ] map ;
+
+: split-struct ( pairs -- seq )
+    [
+        [ 8 mod zero? [ t , ] when , ] assoc-each
+    ] { } make { t } split harvest ;
+
+: flatten-small-struct ( c-type -- seq )
+    struct-types&offset split-struct [
+        [ c-type c-type-reg-class ] map
+        int-regs swap member? "void*" "double" ? c-type
+    ] map ;
+
+: flatten-large-struct ( c-type -- seq )
+    heap-size cell align
+    cell /i "__stack_value" c-type <repetition> ;
+
+M: struct-type flatten-value-type ( type -- seq )
+    dup heap-size 16 > [
+        flatten-large-struct
+    ] [
+        flatten-small-struct
+    ] if ;
+
+M: x86.64 struct-small-enough? ( size -- ? )
+    heap-size 2 cells <= ;
+
+M: x86.64 dummy-stack-params? f ;
+
+M: x86.64 dummy-int-params? f ;
+
+M: x86.64 dummy-fp-params? f ;
diff --git a/basis/cpu/x86/64/winnt/tags.txt b/basis/cpu/x86/64/winnt/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index d4c092f63d1626f30cc8757e401656ef15a81d3d..0124c408779bce315d99b8dbe41c61eb45c3cf1d 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel layouts system alien.c-types compiler.cfg.registers
-cpu.architecture cpu.x86.assembler cpu.x86 ;
+USING: kernel layouts system math alien.c-types
+compiler.cfg.registers cpu.architecture cpu.x86.assembler cpu.x86 ;
 IN: cpu.x86.64.winnt
 
 M: int-regs param-regs drop { RCX RDX R8 R9 } ;
@@ -10,6 +10,15 @@ M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ;
 
 M: x86.64 reserved-area-size 4 cells ;
 
+M: x86.64 struct-small-enough? ( size -- ? )
+    heap-size cell <= ;
+
+M: x86.64 dummy-stack-params? f ;
+
+M: x86.64 dummy-int-params? t ;
+
+M: x86.64 dummy-fp-params? t ;
+
 <<
 "longlong" "ptrdiff_t" typedef
 "int" "long" typedef
index 6dadbc096cbd868bee902ad8b84e34fa6b217c19..1ee74a434b0bc611aeb82399ab53325dfc17d46f 100644 (file)
@@ -44,12 +44,6 @@ big-endian off
     ds-reg [] arg0 MOV                         ! store literal on datastack
 ] rc-absolute-cell rt-immediate 1 rex-length + jit-push-immediate jit-define
 
-[
-    arg0 0 MOV                                 ! load XT
-    arg1 stack-reg MOV                         ! pass callstack pointer as arg 2
-    arg0 JMP                                   ! go
-] rc-absolute-cell rt-primitive 1 rex-length + jit-primitive jit-define
-
 [
     (JMP) drop
 ] rc-relative rt-xt 1 jit-word-jump jit-define
index 55675a5e42401fc205bf2a00f730af5c5eb82ea4..dfe3d3e55e55fc59cc4294dafb8129e7224e79a8 100644 (file)
@@ -60,19 +60,6 @@ M: x86 %return ( -- ) 0 RET ;
 : align-code ( n -- )
     0 <repetition> % ;
 
-M:: x86 %dispatch ( src temp -- )
-    ! Load jump table base. We use a temporary register
-    ! since on AMD64 we have to load a 64-bit immediate. On
-    ! x86, this is redundant.
-    ! Add jump table base
-    temp HEX: ffffffff MOV rc-absolute-cell rel-here
-    src temp ADD
-    src HEX: 7f [+] JMP
-    ! Fix up the displacement above
-    cell code-alignment dup bootstrap-cell 8 = 15 9 ? +
-    building get dup pop* push
-    align-code ;
-
 M: x86 %dispatch-label ( word -- )
     0 cell, rc-absolute-cell rel-word ;
 
@@ -467,6 +454,8 @@ M: x86 %compare-float-branch ( label cc src1 src2 -- )
 
 : stack@ ( n -- op ) stack-reg swap [+] ;
 
+: param@ ( n -- op ) reserved-area-size + stack@ ;
+
 : spill-integer-base ( stack-frame -- n )
     [ params>> ] [ return>> ] bi + reserved-area-size + ;
 
@@ -493,16 +482,16 @@ M: x86 %reload-float ( dst n -- ) spill-float@ MOVSD ;
 
 M: x86 %loop-entry 16 code-alignment [ NOP ] times ;
 
-M: int-regs %save-param-reg drop >r stack@ r> MOV ;
-M: int-regs %load-param-reg drop swap stack@ MOV ;
+M: int-regs %save-param-reg drop >r param@ r> MOV ;
+M: int-regs %load-param-reg drop swap param@ MOV ;
 
 GENERIC: MOVSS/D ( dst src reg-class -- )
 
 M: single-float-regs MOVSS/D drop MOVSS ;
 M: double-float-regs MOVSS/D drop MOVSD ;
 
-M: float-regs %save-param-reg >r >r stack@ r> r> MOVSS/D ;
-M: float-regs %load-param-reg >r swap stack@ r> MOVSS/D ;
+M: float-regs %save-param-reg >r >r param@ r> r> MOVSS/D ;
+M: float-regs %load-param-reg >r swap param@ r> MOVSS/D ;
 
 GENERIC: push-return-reg ( reg-class -- )
 GENERIC: load-return-reg ( n reg-class -- )
@@ -518,8 +507,6 @@ M: x86 %prepare-alien-invoke
     temp-reg-1 2 cells [+] ds-reg MOV
     temp-reg-1 3 cells [+] rs-reg MOV ;
 
-M: x86 fp-shadows-int? ( -- ? ) f ;
-
 M: x86 value-structs? t ;
 
 M: x86 small-enough? ( n -- ? )
index 15022452eedeea2c905c47452a1a67326a96674e..92b141dca8608e1aa387315ab5c5a4cfc55ce9ee 100644 (file)
@@ -77,3 +77,10 @@ IN: dlists.tests
 [ f ] [ <dlist> 3 over push-front 4 over push-back -1 swap deque-member? ] unit-test
 
 [ f ] [ <dlist> 0 swap deque-member? ] unit-test
+
+! Make sure clone does the right thing
+[ V{ 2 1 } V{ 2 1 3 } ] [
+    <dlist> 1 over push-front 2 over push-front
+    dup clone 3 over push-back
+    [ dlist>seq ] bi@
+] unit-test
index 3b3cae28200a24182baef4913918929ed4ad29e0..5072c3edfd94b8a99327cabebd19563c67b88c07 100644 (file)
@@ -154,6 +154,14 @@ M: dlist clear-deque ( dlist -- )
 : dlist-each ( dlist quot -- )
     [ obj>> ] prepose dlist-each-node ; inline
 
+: dlist>seq ( dlist -- seq )
+    [ ] pusher [ dlist-each ] dip ;
+
 : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 
+M: dlist clone
+    <dlist> [
+        [ push-back ] curry dlist-each
+    ] keep ;
+
 INSTANCE: dlist deque
index 1d9f72f8c35eea4540b465963c6edf1a19202f13..1550fccc0b3ae3f132058000bea721d18b8876c5 100644 (file)
@@ -4,7 +4,7 @@ IN: editors.emacs
 
 : emacsclient ( file line -- )
     [
-        "emacsclient" ,
+        \ emacsclient get "emacsclient" or ,
         "--no-wait" ,
         "+" swap number>string append ,
         ,
diff --git a/basis/editors/etexteditor/authors.txt b/basis/editors/etexteditor/authors.txt
new file mode 100755 (executable)
index 0000000..7b1e3b7
--- /dev/null
@@ -0,0 +1 @@
+Kibleur Christophe
\ No newline at end of file
diff --git a/basis/editors/etexteditor/etexteditor.factor b/basis/editors/etexteditor/etexteditor.factor
new file mode 100755 (executable)
index 0000000..316bd24
--- /dev/null
@@ -0,0 +1,18 @@
+! Copyright (C) 2008 Kibleur Christophe.
+! See http://factorcode.org/license.txt for BSD license.
+USING: editors io.files io.launcher kernel math.parser
+namespaces sequences windows.shell32 make ;
+IN: editors.etexteditor
+
+: etexteditor-path ( -- str )
+    \ etexteditor-path get-global [
+        program-files "e\\e.exe" append-path
+    ] unless* ;
+
+: etexteditor ( file line -- )
+    [
+        etexteditor-path ,
+        [ , ] [ "--line" , number>string , ] bi*
+    ] { } make run-detached drop ;
+
+[ etexteditor ] edit-hook set-global
diff --git a/basis/editors/etexteditor/summary.txt b/basis/editors/etexteditor/summary.txt
new file mode 100755 (executable)
index 0000000..4653700
--- /dev/null
@@ -0,0 +1 @@
+etexteditor integration
diff --git a/basis/editors/etexteditor/tags.txt b/basis/editors/etexteditor/tags.txt
new file mode 100755 (executable)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index 395d5c3cafda80e4607c852cd7d321d5066f8c92..87c59e18a083b976238ac7300775abc54be32abb 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences combinators parser splitting math
-quotations arrays make qualified words ;
+quotations arrays make words ;
 IN: fry
 
 : _ ( -- * ) "Only valid inside a fry" throw ;
diff --git a/basis/furnace/actions/actions-docs.factor b/basis/furnace/actions/actions-docs.factor
new file mode 100644 (file)
index 0000000..509e0bc
--- /dev/null
@@ -0,0 +1,170 @@
+USING: assocs classes help.markup help.syntax io.streams.string
+http http.server.dispatchers http.server.responses
+furnace.redirection strings multiline ;
+IN: furnace.actions
+
+HELP: <action>
+{ $values { "action" action } }
+{ $description "Creates a new action." } ;
+
+HELP: <chloe-content>
+{ $values
+     { "path" "a pathname string" }
+     { "response" response }
+}
+{ $description "Creates an HTTP response which serves a Chloe template. See " { $link "html.templates.chloe" } "." } ;
+
+HELP: <page-action>
+{ $values { "page" action } }
+{ $description "Creates a new action which serves a Chloe template when servicing a GET request." } ;
+
+HELP: action
+{ $description "The class of Furnace actions. New instances are created with " { $link <action> } ". New instances of subclasses can be created with " { $link new-action } ". The " { $link page-action } " class is a useful subclass."
+$nl
+"Action slots are documented in " { $link "furnace.actions.config" } "." } ;
+
+HELP: new-action
+{ $values
+     { "class" class }
+     { "action" action }
+}
+{ $description "Constructs a subclass of " { $link action } "." } ;
+
+HELP: page-action
+{ $description "The class of Chloe page actions. These are actions whose " { $slot "display" } " slot is pre-set to serve the Chloe template stored in the " { $slot "page" } " slot." } ;
+
+HELP: param
+{ $values
+     { "name" string }
+     { "value" string }
+}
+{ $description "Outputs the value of a query parameter (if the current request is a GET or HEAD request) or a POST parameter (if the current request is a POST request)." }
+{ $notes "Instead of using this word, it is better to use " { $link validate-params } " and then access parameters via " { $link "html.forms.values" } " words." } ;
+
+HELP: params
+{ $var-description "A variable holding an assoc of query parameters (if the current request is a GET or HEAD request) or POST parameters (if the current request is a POST request)." }
+{ $notes "Instead of using this word, it is better to use " { $link validate-params } " and then access parameters via " { $link "html.forms.values" } " words." } ;
+
+HELP: validate-integer-id
+{ $description "A utility word which validates an integer parameter named " { $snippet "id" } "." }
+{ $examples
+    { $code
+        "<action>"
+        "    ["
+        "        validate-integer-id"
+        "        \"id\" value <person> select-tuple from-object"
+        "    ] >>init"
+    }
+} ;
+
+HELP: validate-params
+{ $values
+     { "validators" "an association list mapping parameter names to validator quotations" }
+}
+{ $description "Validates query or POST parameters, depending on the request type, and stores them in " { $link "html.forms.values" } ". The validator quotations can execute " { $link "validators" } "." }
+{ $examples
+    "A simple validator from " { $vocab-link "webapps.todo" } "; this word is invoked from the " { $slot "validate" } " quotation of action for editing a todo list item:"
+    { $code
+        <" : validate-todo ( -- )
+    {
+        { "summary" [ v-one-line ] }
+        { "priority" [ v-integer 0 v-min-value 10 v-max-value ] }
+        { "description" [ v-required ] }
+    } validate-params ;">
+    }
+} ;
+
+HELP: validation-failed
+{ $description "Stops processing the current request and takes action depending on the type of the current request:"
+    { $list
+        { "For GET or HEAD requests, the client receives a " { $link <400> } " response." }
+        { "For POST requests, the client is sent back to the page containing the form submission, with current form values and validation errors passed in a " { $link "furnace.conversations" } "." }
+    }
+"This word is called by " { $link validate-params } " and can also be called directly. For more details, see " { $link "furnace.actions.lifecycle" } "." } ;
+
+ARTICLE: "furnace.actions.page.example" "Furnace page action example"
+"The " { $vocab-link "webapps.counter" } " vocabulary defines a subclass of " { $link dispatcher } ":"
+{ $code "TUPLE: counter-app < dispatcher ;" }
+"The " { $snippet "<counter-app>" } " constructor word creates a new instance of the " { $snippet "counter-app" } " class, and adds a " { $link page-action } " instance to the dispatcher. This " { $link page-action } " has its " { $slot "template" } " slot set as follows,"
+{ $code "{ counter-app \"counter\" } >>template" }
+"This means the action will serve the Chloe template located at " { $snippet "resource:extra/webapps/counter/counter.xml" } " upon receiving a GET request." ;
+
+ARTICLE: "furnace.actions.page" "Furnace page actions"
+"Page actions implement the common case of an action that simply serves a Chloe template in response to a GET request."
+{ $subsection page-action }
+{ $subsection <page-action> }
+"When using a page action, instead of setting the " { $slot "display" } " slot, the " { $slot "template" } " slot is set instead. The " { $slot "init" } ", " { $slot "authorize" } ", " { $slot "validate" } " and " { $slot "submit" } " slots can still be set as usual."
+$nl
+"The " { $slot "template" } " slot of a " { $link page-action } " contains a pair with shape " { $snippet "{ responder name }" } ", where " { $snippet "responder" } " is a responder class, usually a subclass of " { $link dispatcher } ", and " { $snippet "name" } " is the name of a template file, without the " { $snippet ".xml" } " extension, relative to the directory containing the responder's vocabulary source file."
+{ $subsection "furnace.actions.page.example" } ;
+
+ARTICLE: "furnace.actions.config" "Furnace action configuration"
+"Actions have the following slots:"
+{ $table
+    { { $slot "rest" } { "A parameter name to map the rest of the URL, after the action name, to. If this is not set, then navigating to a URL where the action is not the last path component will return to the client with an error." } }
+    { { $slot "init" } { "A quotation called at the beginning of a GET or HEAD request. Typically this quotation configures " { $link "html.forms" } " and parses query parameters." } }
+    { { $slot "authorize" } { "A quotation called at the beginning of a GET, HEAD or POST request. In GET requests, it is called after the " { $slot "init" } " quotation; in POST requests, it is called after the " { $slot "validate" } " quotation. By convention, this quotation performs custom authorization checks which depend on query parameters or POST parameters." } }
+    { { $slot "display" } { "A quotation called after the " { $slot "init" } " quotation in a GET request. This quotation must return an HTTP " { $link response } "." } }
+    { { $slot "validate" } { "A quotation called at the beginning of a POST request to validate POST parameters." } }
+    { { $slot "submit" } { "A quotation called after the " { $slot "validate" } " quotation in a POST request. This quotation must return an HTTP " { $link response } "." } }
+}
+"At least one of the " { $slot "display" } " and " { $slot "submit" } " slots must be set, otherwise the action will be useless." ;
+
+ARTICLE: "furnace.actions.validation" "Form validation with actions"
+"The action code is set up so that the " { $slot "init" } " quotation can validate query parameters, and the " { $slot "validate" } " quotation can validate POST parameters."
+$nl
+"A word to validate parameters and make them available as HTML form values (see " { $link "html.forms.values" } "); typically this word is invoked from the " { $slot "init" } " and " { $slot "validate" } " quotations:"
+{ $subsection validate-params }
+"The above word expects an association list mapping parameter names to validator quotations; validator quotations can use the words in the " 
+"Custom validation logic can invoke a word when validation fails; " { $link validate-params } " invokes this word for you:"
+{ $subsection validation-failed }
+"If validation fails, no more action code is executed, and the client is redirected back to the originating page, where validation errors can be displayed. Note that validation errors are rendered automatically by the " { $link "html.components" } " words, and in particular, " { $link "html.templates.chloe" } " use these words." ;
+
+ARTICLE: "furnace.actions.lifecycle" "Furnace action lifecycle"
+{ $heading "GET request lifecycle" }
+"A GET request results in the following sequence of events:"
+{ $list
+    { "The " { $snippet "init" } " quotation is called." }
+    { "The " { $snippet "authorize" } " quotation is called." }
+    { "If the GET request was generated as a result of form validation failing during a POST, then the form values entered by the user, along with validation errors, are stored in " { $link "html.forms.values" } "." }
+    { "The " { $snippet "display" } " quotation is called; it is expected to output an HTTP " { $link response } " on the stack." }
+}
+"Any one of the above steps can perform validation; if " { $link validation-failed } " is called during a GET request, the client receives a " { $link <400> } " error."
+{ $heading "HEAD request lifecycle" }
+"A HEAD request proceeds exactly like a GET request. The only difference is that the " { $slot "body" } " slot of the " { $link response } " object is never rendered."
+{ $heading "POST request lifecycle" }
+"A POST request results in the following sequence of events:"
+{ $list
+    { "The " { $snippet "validate" } " quotation is called." }
+    { "The " { $snippet "authorize" } " quotation is called." }
+    { "The " { $snippet "submit" } " quotation is called; it is expected to output an HTTP " { $link response } " on the stack. By convention, this response should be a " { $link <redirect> } "." }
+}
+"Any one of the above steps can perform validation; if " { $link validation-failed } " is called during a POST request, the client is sent back to the page containing the form submission, with current form values and validation errors passed in a " { $link "furnace.conversations" } "." ;
+
+ARTICLE: "furnace.actions.impl" "Furnace actions implementation"
+"The following words are used by the action implementation and there is rarely any reason to call them directly:"
+{ $subsection new-action }
+{ $subsection param }
+{ $subsection params } ;
+
+ARTICLE: "furnace.actions" "Furnace actions"
+"The " { $vocab-link "furnace.actions" } " vocabulary implements a type of responder, called an " { $emphasis "action" } ", which handles the form validation lifecycle."
+$nl
+"Other than form validation capability, actions are also often simpler to use than implementing new responders directly, since creating a new class is not required, and the action dispatches on the request type (GET, HEAD, or POST)."
+$nl
+"The class of actions:"
+{ $subsection action }
+"Creating a new action:"
+{ $subsection <action> }
+"Once created, an action needs to be configured; typically the creation and configuration of an action is encapsulated into a single word:"
+{ $subsection "furnace.actions.config" }
+"Validating forms with actions:"
+{ $subsection "furnace.actions.validation" }
+"More about the form validation lifecycle:"
+{ $subsection "furnace.actions.lifecycle" }
+"A convenience class:"
+{ $subsection "furnace.actions.page" }
+"Low-level features:"
+{ $subsection "furnace.actions.impl" } ;
+
+ABOUT: "furnace.actions"
index 7505b3c6126f7588be4bdfc0fac0db318cb71546..6c56a8ad7babe82ad3d98a762c6ab59381e352eb 100644 (file)
@@ -22,18 +22,7 @@ SYMBOL: params
 \r
 SYMBOL: rest\r
 \r
-: render-validation-messages ( -- )\r
-    form get errors>>\r
-    [\r
-        <ul "errors" =class ul>\r
-            [ <li> escape-string write </li> ] each\r
-        </ul>\r
-    ] unless-empty ;\r
-\r
-CHLOE: validation-messages\r
-    drop [ render-validation-messages ] [code] ;\r
-\r
-TUPLE: action rest authorize init display validate submit ;\r
+TUPLE: action rest init authorize display validate submit ;\r
 \r
 : new-action ( class -- action )\r
     new [ ] >>init [ ] >>validate [ ] >>authorize ; inline\r
diff --git a/basis/furnace/alloy/alloy-docs.factor b/basis/furnace/alloy/alloy-docs.factor
new file mode 100644 (file)
index 0000000..f108428
--- /dev/null
@@ -0,0 +1,42 @@
+IN: furnace.alloy
+USING: help.markup help.syntax db multiline ;
+
+HELP: init-furnace-tables
+{ $description "Initializes database tables used by asides, conversations and session management. This word must be invoked inside a " { $link with-db } " scope." } ;
+
+HELP: <alloy>
+{ $values { "responder" "a responder" } { "db" db } { "responder'" "an alloy responder" } }
+{ $description "Wraps the responder with support for asides, conversations, sessions and database persistence." }
+{ $examples
+    "The " { $vocab-link "webapps.counter" } " vocabulary uses an alloy to configure the counter:"
+    { $code
+        <" : counter-db ( -- db ) "counter.db" <sqlite-db> ;
+
+: run-counter ( -- )
+    <counter-app>
+        counter-db <alloy>
+        main-responder set-global
+    8080 httpd ;">
+    }
+} ;
+
+HELP: start-expiring
+{ $values { "db" db } }
+{ $description "Starts a timer which expires old session state from the given database." } ;
+
+ARTICLE: "furnace.alloy" "Furnace alloy responder"
+"The " { $vocab-link "furnace.alloy" } " vocabulary implements a convenience responder which combines several Furnace features into one easy-to-use wrapper:"
+{ $list
+    { $link "furnace.asides" }
+    { $link "furnace.conversations" }
+    { $link "furnace.sessions" }
+    { $link "furnace.db" }
+}
+"A word to wrap a responder in an alloy:"
+{ $subsection <alloy> }
+"Initializing database tables for asides, conversations and sessions:"
+{ $subsection init-furnace-tables }
+"Start a timer to expire asides, conversations and sessions:"
+{ $subsection start-expiring } ;
+
+ABOUT: "furnace.alloy"
diff --git a/basis/furnace/asides/asides-docs.factor b/basis/furnace/asides/asides-docs.factor
new file mode 100644 (file)
index 0000000..b977474
--- /dev/null
@@ -0,0 +1,33 @@
+USING: help.markup help.syntax io.streams.string urls
+furnace.redirection http furnace.sessions furnace.db ;
+IN: furnace.asides
+
+HELP: <asides>
+{ $values
+     { "responder" "a responder" }
+     { "responder'" asides }
+}
+{ $description "Creates a new " { $link asides } " responder wrapping an existing responder." } ;
+
+HELP: begin-aside
+{ $values { "url" url } }
+{ $description "Begins an aside. When the current action returns a " { $link <redirect> } ", the redirect will have query parameters which reference the current page via an opaque handle." } ;
+
+HELP: end-aside
+{ $values { "default" url } { "response" response } }
+{ $description "Ends an aside. If an aside is currently active, the response redirects the client " } ;
+
+ARTICLE: "furnace.asides" "Furnace asides"
+"The " { $vocab-link "furnace.asides" } " vocabulary provides support for sending a user to a page which can then return to the former location."
+$nl
+"To use asides, wrap your responder in an aside responder:"
+{ $subsection <asides> }
+"The aside responder must be wrapped inside a session responder (" { $link <sessions> } "), which in turn must be wrapped inside a database persistence responder (" { $link <db-persistence> } "). The " { $vocab-link "furnace.alloy" } " vocabulary combines all of these responders into one."
+$nl
+"Saving the current page in an aside which propagates through " { $link <redirect> } " responses:"
+{ $subsection begin-aside }
+"Returning from an aside:"
+{ $subsection end-aside }
+"Asides are used by " { $vocab-link "furnace.auth.login" } "; when the client requests a protected page, an aside begins and the client is redirected to a login page. Upon a successful login, the aside ends and the client returns to the protected page. If the client directly visits the login page and logs in, there is no current aside, so the client is sent to the default URL passed to " { $link end-aside } ", which in the case of login is the root URL." ;
+
+ABOUT: "furnace.asides"
index f486f4e246cf10bfddad3055651a0fe7df2741e4..878bdd64fb5fb73a2239546c8e416d716f809280 100644 (file)
@@ -62,7 +62,7 @@
 
        <p>
                <button>Update</button>
-               <t:validation-messages />
+               <t:validation-errors />
        </p>
 
        </t:form>
index a8ea635a1f9826e05306c832d2b6335b8c8b12e1..2df400ffe23ef1b00a068af96924f270d8e6c14f 100644 (file)
@@ -32,7 +32,7 @@
 
                <p>
                        <button>Set password</button>
-                       <t:validation-messages />
+                       <t:validation-errors />
                </p>
 
        </t:form>
index b0d6971d1bfac7fcd3e7e85769b021b9460e4173..45c090905e8e0bc6db0c22911406c359b5606836 100644 (file)
@@ -63,7 +63,7 @@
                <p>
 
                        <button>Register</button>
-                       <t:validation-messages />
+                       <t:validation-errors />
 
                </p>
 
index 766c097ca5fa5b39d8999bdd6d9cac4010b4cd24..917c182fb305d7d06fa5f0f6f4814d10a7240072 100644 (file)
@@ -36,7 +36,7 @@
                <p>
 
                        <button>Log in</button>
-                       <t:validation-messages />
+                       <t:validation-errors />
 
                </p>
 
diff --git a/basis/furnace/boilerplate/boilerplate-docs.factor b/basis/furnace/boilerplate/boilerplate-docs.factor
new file mode 100644 (file)
index 0000000..5594928
--- /dev/null
@@ -0,0 +1,27 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string ;
+IN: furnace.boilerplate
+
+HELP: <boilerplate>
+{ $values
+     { "responder" null }
+     { "boilerplate" null }
+}
+{ $description "" } ;
+
+HELP: boilerplate
+{ $description "" } ;
+
+HELP: wrap-boilerplate?
+{ $values
+     { "response" null }
+     { "?" "a boolean" }
+}
+{ $description "" } ;
+
+ARTICLE: "furnace.boilerplate" "Furnace boilerplate support"
+{ $vocab-link "furnace.boilerplate" }
+;
+
+ABOUT: "furnace.boilerplate"
diff --git a/basis/furnace/conversations/conversations-docs.factor b/basis/furnace/conversations/conversations-docs.factor
new file mode 100644 (file)
index 0000000..5e161f2
--- /dev/null
@@ -0,0 +1,6 @@
+USING: help.markup help.syntax ;
+IN: furnace.conversations
+
+ARTICLE: "furnace.conversations" "Furnace conversation scope"
+
+;
diff --git a/basis/furnace/db/db-docs.factor b/basis/furnace/db/db-docs.factor
new file mode 100644 (file)
index 0000000..a7ef02b
--- /dev/null
@@ -0,0 +1,16 @@
+USING: help.markup help.syntax db http.server ;
+IN: furnace.db
+
+HELP: <db-persistence>
+{ $values
+     { "responder" "a responder" } { "db" db }
+     { "responder'" db-persistence }
+}
+{ $description "Wraps a responder with database persistence support. The responder's " { $link call-responder* } " method will run in a " { $link with-db } " scope." } ;
+
+ARTICLE: "furnace.db" "Furnace database support"
+"The " { $vocab-link "furnace.db" } " vocabulary implements a responder which maintains a database connection pool and runs each request in a " { $link with-db } " scope."
+{ $subsection <db-persistence> }
+"The " { $vocab-link "furnace.alloy" } " vocabulary combines database persistence with several other features." ;
+
+ABOUT: "furnace.db"
diff --git a/basis/furnace/furnace-docs.factor b/basis/furnace/furnace-docs.factor
new file mode 100644 (file)
index 0000000..0e2e6c1
--- /dev/null
@@ -0,0 +1,189 @@
+USING: assocs help.markup help.syntax io.streams.string quotations sequences strings urls ;
+IN: furnace
+
+HELP: adjust-redirect-url
+{ $values
+     { "url" url }
+     { "url'" url }
+}
+{ $description "" } ;
+
+HELP: adjust-url
+{ $values
+     { "url" url }
+     { "url'" url }
+}
+{ $description "" } ;
+
+HELP: base-path
+{ $values
+     { "string" string }
+     { "pair" null }
+}
+{ $description "" } ;
+
+HELP: client-state
+{ $values
+     { "key" null }
+     { "value/f" null }
+}
+{ $description "" } ;
+
+HELP: cookie-client-state
+{ $values
+     { "key" null } { "request" null }
+     { "value/f" null }
+}
+{ $description "" } ;
+
+HELP: each-responder
+{ $values
+     { "quot" quotation }
+}
+{ $description "" } ;
+
+HELP: exit-continuation
+{ $description "" } ;
+
+HELP: exit-with
+{ $values
+     { "value" null }
+}
+{ $description "" } ;
+
+HELP: hidden-form-field
+{ $values
+     { "value" null } { "name" null }
+}
+{ $description "" } ;
+
+HELP: link-attr
+{ $values
+     { "tag" null } { "responder" null }
+}
+{ $description "" } ;
+
+HELP: modify-form
+{ $values
+     { "responder" null }
+}
+{ $description "" } ;
+
+HELP: modify-query
+{ $values
+     { "query" null } { "responder" null }
+     { "query'" null }
+}
+{ $description "" } ;
+
+HELP: modify-redirect-query
+{ $values
+     { "query" null } { "responder" null }
+     { "query'" null }
+}
+{ $description "" } ;
+
+HELP: nested-forms-key
+{ $description "" } ;
+
+HELP: nested-responders
+{ $values
+    
+     { "seq" sequence }
+}
+{ $description "" } ;
+
+HELP: post-client-state
+{ $values
+     { "key" null } { "request" null }
+     { "value/f" null }
+}
+{ $description "" } ;
+
+HELP: referrer
+{ $values
+    
+     { "referrer/f" null }
+}
+{ $description "" } ;
+
+HELP: request-params
+{ $values
+     { "request" null }
+     { "assoc" assoc }
+}
+{ $description "" } ;
+
+HELP: resolve-base-path
+{ $values
+     { "string" string }
+     { "string'" string }
+}
+{ $description "" } ;
+
+HELP: resolve-template-path
+{ $values
+     { "pair" null }
+     { "path" "a pathname string" }
+}
+{ $description "" } ;
+
+HELP: same-host?
+{ $values
+     { "url" url }
+     { "?" "a boolean" }
+}
+{ $description "" } ;
+
+HELP: user-agent
+{ $values
+    
+     { "user-agent" null }
+}
+{ $description "" } ;
+
+HELP: vocab-path
+{ $values
+     { "vocab" "a vocabulary specifier" }
+     { "path" "a pathname string" }
+}
+{ $description "" } ;
+
+HELP: with-exit-continuation
+{ $values
+     { "quot" quotation }
+}
+{ $description "" } ;
+
+ARTICLE: "furnace" "Furnace web framework"
+"The " { $vocab-link "furnace" } " vocabulary implements a full-featured web framework on top of the " { $link "http.server" } ". Some of its features include:"
+{ $list
+    "Session management capable of load-balancing and fail-over"
+    "Form components and validation"
+    "Authentication system with basic authentication or login pages, and pluggable authentication backends"
+    "Easy Atom feed syndication"
+    "Conversation scope and asides for complex page flow"
+}
+"Major functionality:"
+{ $subsection "furnace.actions" }
+{ $subsection "furnace.syndication" }
+{ $subsection "furnace.boilerplate" }
+{ $subsection "furnace.db" }
+"Server-side state:"
+{ $subsection "furnace.sessions" }
+{ $subsection "furnace.conversations" }
+{ $subsection "furnace.asides" }
+"HTML components:"
+{ $subsection "html.components" }
+{ $subsection "html.forms" }
+"Content templates:"
+{ $subsection "html.templates" }
+{ $subsection "html.templates.chloe" }
+{ $subsection "html.templates.fhtml" }
+"Utilities:"
+{ $subsection "furnace.alloy" }
+{ $subsection "furnace.json" }
+{ $subsection "furnace.redirection" }
+{ $subsection "furnace.referrer" } ;
+
+ABOUT: "furnace"
index 7285c436bcbd658822b0b0afb94d7be9e1b6c545..a77b0d28c708f7241b20b021297c484a9ebf71c6 100644 (file)
@@ -128,4 +128,27 @@ SYMBOL: exit-continuation
 : with-exit-continuation ( quot -- )
     '[ exit-continuation set @ ] callcc1 exit-continuation off ;
 
+USE: vocabs.loader
+"furnace.actions" require
+"furnace.alloy" require
+"furnace.asides" require
+"furnace.auth" require
+"furnace.auth.basic" require
+"furnace.auth.features.deactivate-user" require
+"furnace.auth.features.edit-profile" require
+"furnace.auth.features.recover-password" require
+"furnace.auth.features.registration" require
+"furnace.auth.login" require
+"furnace.auth.providers.assoc" require
+"furnace.auth.providers.db" require
+"furnace.auth.providers.null" require
+"furnace.boilerplate" require
 "furnace.chloe-tags" require
+"furnace.conversations" require
+"furnace.db" require
+"furnace.json" require
+"furnace.redirection" require
+"furnace.referrer" require
+"furnace.scopes" require
+"furnace.sessions" require
+"furnace.syndication" require
diff --git a/basis/furnace/json/json-docs.factor b/basis/furnace/json/json-docs.factor
new file mode 100644 (file)
index 0000000..c20c2e6
--- /dev/null
@@ -0,0 +1,12 @@
+USING: kernel http.server help.markup help.syntax http ;
+IN: furnace.json
+
+HELP: <json-content>
+{ $values { "body" object } { "response" response } }
+{ $description "Creates an HTTP response which serves a serialized JSON object to the client." } ;
+
+ARTICLE: "furnace.json" "Furnace JSON support"
+"The " { $vocab-link "furnace.json" } " vocabulary provides a utility word for serving HTTP responses with JSON content."
+{ $subsection <json-content> } ;
+
+ABOUT: "furnace.json"
diff --git a/basis/furnace/redirection/redirection-docs.factor b/basis/furnace/redirection/redirection-docs.factor
new file mode 100644 (file)
index 0000000..fd3671f
--- /dev/null
@@ -0,0 +1,59 @@
+USING: help.markup help.syntax io.streams.string quotations urls
+http.server http ;
+IN: furnace.redirection
+
+HELP: <redirect-responder>
+{ $values { "url" url } { "responder" "a responder" } }
+{ $description "Creates a responder which unconditionally redirects the client to the given URL." } ;
+
+HELP: <redirect>
+{ $values { "url" url } { "response" response } }
+{ $description "Creates a response which redirects the client to the given URL." } ;
+
+HELP: <secure-only> ( responder -- responder' )
+{ $values { "responder" "a responder" } { "responder'" "a responder" } }
+{ $description "Creates a new responder which ensures that the client is connecting via HTTPS before delegating to the underlying responder. If the client is connecting via HTTP, a redirect is sent instead." } ;
+
+HELP: <secure-redirect>
+{ $values
+     { "url" url }
+     { "response" response }
+}
+{ $description "Creates a responder which unconditionally redirects the client to the given URL after setting its protocol to HTTPS." }
+{ $notes "This word is intended to be used with a relative URL. The client is redirected to the relative URL, but with HTTPS instead of HTTP." } ;
+
+HELP: >secure-url
+{ $values
+     { "url" url }
+     { "url'" url }
+}
+{ $description "Sets the protocol of a URL to HTTPS." } ;
+
+HELP: if-secure
+{ $values
+     { "quot" quotation }
+     { "response" response }
+}
+{ $description "Runs a quotation if the current request was made over HTTPS, otherwise returns a redirect to have the client request the current page again via HTTPS." } ;
+
+ARTICLE: "furnace.redirection.secure" "Secure redirection"
+"The words in this section help with implementing sites which require SSL/TLS for additional security."
+$nl
+"Converting a HTTP URL into an HTTPS URL:"
+{ $subsection >secure-url }
+"Redirecting the client to an HTTPS URL:"
+{ $subsection <secure-redirect> }
+"Tools for writing responders which require SSL/TLS connections:"
+{ $subsection if-secure }
+{ $subsection <secure-only> } ;
+
+ARTICLE: "furnace.redirection" "Furnace redirection support"
+"The " { $vocab-link "furnace.redirection" } " vocabulary builds additional functionality on top of " { $vocab-link "http.server.redirection" } ", and integrates with various Furnace features such as " { $link "furnace.asides" } " and " { $link "furnace.conversations" } "."
+$nl
+"A redirection response which takes asides and conversations into account:"
+{ $subsection <redirect> }
+"A responder which unconditionally redirects the client to another URL:"
+{ $subsection <redirect-responder> }
+{ $subsection "furnace.redirection.secure" } ;
+
+ABOUT: "furnace.redirection"
diff --git a/basis/furnace/referrer/referrer-docs.factor b/basis/furnace/referrer/referrer-docs.factor
new file mode 100644 (file)
index 0000000..5deebbe
--- /dev/null
@@ -0,0 +1,15 @@
+USING: help.markup help.syntax io.streams.string ;
+IN: furnace.referrer
+
+HELP: <check-form-submissions>
+{ $values
+     { "responder" "a responder" }
+     { "responder'" "a responder" }
+}
+{ $description "Wraps the responder in a filter responder which ensures that form submissions originate from a page on the same server. Any submissions which do not are sent back with a 403 error." } ;
+
+ARTICLE: "furnace.referrer" "Form submission referrer checking"
+"The " { $vocab-link "furnace.referrer" } " implements a simple security measure which can be used to thwart cross-site scripting attacks."
+{ $subsection <check-form-submissions> } ;
+
+ABOUT: "furnace.referrer"
diff --git a/basis/furnace/sessions/sessions-docs.factor b/basis/furnace/sessions/sessions-docs.factor
new file mode 100644 (file)
index 0000000..6ec77e0
--- /dev/null
@@ -0,0 +1,149 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string quotations strings ;
+IN: furnace.sessions
+
+HELP: <session-cookie>
+{ $values
+    
+     { "cookie" null }
+}
+{ $description "" } ;
+
+HELP: <session>
+{ $values
+     { "id" null }
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: <sessions>
+{ $values
+     { "responder" null }
+     { "responder'" null }
+}
+{ $description "" } ;
+
+HELP: begin-session
+{ $values
+    
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: check-session
+{ $values
+     { "state/f" null }
+     { "state/f" null }
+}
+{ $description "" } ;
+
+HELP: empty-session
+{ $values
+    
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: existing-session
+{ $values
+     { "path" "a pathname string" } { "session" null }
+     { "response" null }
+}
+{ $description "" } ;
+
+HELP: get-session
+{ $values
+     { "id" null }
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: init-session
+{ $values
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: init-session*
+{ $values
+     { "responder" null }
+}
+{ $description "" } ;
+
+HELP: put-session-cookie
+{ $values
+     { "response" null }
+     { "response'" null }
+}
+{ $description "" } ;
+
+HELP: remote-host
+{ $values
+    
+     { "string" string }
+}
+{ $description "" } ;
+
+HELP: request-session
+{ $values
+    
+     { "session/f" null }
+}
+{ $description "" } ;
+
+HELP: save-session-after
+{ $values
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: schange
+{ $values
+     { "key" null } { "quot" quotation }
+}
+{ $description "" } ;
+
+HELP: session
+{ $description "" } ;
+
+HELP: session-changed
+{ $description "" } ;
+
+HELP: session-id-key
+{ $description "" } ;
+
+HELP: sessions
+{ $description "" } ;
+
+HELP: sget
+{ $values
+     { "key" null }
+     { "value" null }
+}
+{ $description "" } ;
+
+HELP: sset
+{ $values
+     { "value" null } { "key" null }
+}
+{ $description "" } ;
+
+HELP: touch-session
+{ $values
+     { "session" null }
+}
+{ $description "" } ;
+
+HELP: verify-session
+{ $values
+     { "session" null }
+     { "session" null }
+}
+{ $description "" } ;
+
+ARTICLE: "furnace.sessions" "Furnace sessions"
+{ $vocab-link "furnace.sessions" }
+;
+
+ABOUT: "furnace.sessions"
diff --git a/basis/furnace/syndication/syndication-docs.factor b/basis/furnace/syndication/syndication-docs.factor
new file mode 100644 (file)
index 0000000..7a9ec57
--- /dev/null
@@ -0,0 +1,69 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string kernel sequences strings urls ;
+IN: furnace.syndication
+
+HELP: <feed-action>
+{ $values
+    
+     { "action" null }
+}
+{ $description "" } ;
+
+HELP: <feed-content>
+{ $values
+     { "body" null }
+     { "response" null }
+}
+{ $description "" } ;
+
+HELP: >entry
+{ $values
+     { "object" object }
+     { "entry" null }
+}
+{ $description "" } ;
+
+HELP: feed-action
+{ $description "" } ;
+
+HELP: feed-entry-date
+{ $values
+     { "object" object }
+     { "timestamp" null }
+}
+{ $description "" } ;
+
+HELP: feed-entry-description
+{ $values
+     { "object" object }
+     { "description" null }
+}
+{ $description "" } ;
+
+HELP: feed-entry-title
+{ $values
+     { "object" object }
+     { "string" string }
+}
+{ $description "" } ;
+
+HELP: feed-entry-url
+{ $values
+     { "object" object }
+     { "url" url }
+}
+{ $description "" } ;
+
+HELP: process-entries
+{ $values
+     { "seq" sequence }
+     { "seq'" sequence }
+}
+{ $description "" } ;
+
+ARTICLE: "furnace.syndication" "Furnace Atom syndication support"
+{ $vocab-link "furnace.syndication" }
+;
+
+ABOUT: "furnace.syndication"
diff --git a/basis/grouping/authors.txt b/basis/grouping/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/grouping/grouping-docs.factor b/basis/grouping/grouping-docs.factor
new file mode 100644 (file)
index 0000000..3b3a98e
--- /dev/null
@@ -0,0 +1,104 @@
+USING: help.markup help.syntax sequences strings ;
+IN: grouping
+
+ARTICLE: "grouping" "Groups and clumps"
+"Splitting a sequence into disjoint, fixed-length subsequences:"
+{ $subsection group }
+"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
+{ $subsection groups }
+{ $subsection <groups> }
+{ $subsection <sliced-groups> }
+"Splitting a sequence into overlapping, fixed-length subsequences:"
+{ $subsection clump }
+"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: grouping 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 grouping ;"
+        "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 grouping ;"
+        "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: grouping 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: grouping 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/basis/grouping/grouping-tests.factor b/basis/grouping/grouping-tests.factor
new file mode 100644 (file)
index 0000000..dc3d970
--- /dev/null
@@ -0,0 +1,14 @@
+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
+
+[ { { 1 2 } { 2 3 } } ] [ { 1 2 3 } 2 <sliced-clumps> [ >array ] map ] unit-test
diff --git a/basis/grouping/grouping.factor b/basis/grouping/grouping.factor
new file mode 100644 (file)
index 0000000..4a1b8c7
--- /dev/null
@@ -0,0 +1,88 @@
+! Copyright (C) 2005, 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.order strings arrays vectors sequences
+sequences.private accessors ;
+IN: grouping
+
+<PRIVATE
+
+TUPLE: chunking-seq { seq read-only } { n read-only } ;
+
+: check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
+
+: new-groups ( seq n class -- groups )
+    >r check-groups r> boa ; inline
+
+GENERIC: group@ ( n groups -- from to seq )
+
+M: chunking-seq set-nth group@ <slice> 0 swap copy ;
+
+M: chunking-seq like drop { } like ;
+
+INSTANCE: chunking-seq sequence
+
+MIXIN: subseq-chunking
+
+M: subseq-chunking nth group@ subseq ;
+
+MIXIN: slice-chunking
+
+M: slice-chunking nth group@ <slice> ;
+
+M: slice-chunking nth-unsafe group@ slice boa ;
+
+TUPLE: abstract-groups < chunking-seq ;
+
+M: abstract-groups length
+    [ seq>> length ] [ n>> ] bi [ + 1- ] keep /i ;
+
+M: abstract-groups set-length
+    [ n>> * ] [ seq>> ] bi set-length ;
+
+M: abstract-groups group@
+    [ n>> [ * dup ] keep + ] [ seq>> ] bi [ length min ] keep ;
+
+TUPLE: abstract-clumps < chunking-seq ;
+
+M: abstract-clumps length
+    [ seq>> length ] [ n>> ] bi - 1+ ;
+
+M: abstract-clumps set-length
+    [ n>> + 1- ] [ seq>> ] bi set-length ;
+
+M: abstract-clumps group@
+    [ n>> over + ] [ seq>> ] bi ;
+
+PRIVATE>
+
+TUPLE: groups < abstract-groups ;
+
+: <groups> ( seq n -- groups )
+    groups new-groups ; inline
+
+INSTANCE: groups subseq-chunking
+
+TUPLE: sliced-groups < abstract-groups ;
+
+: <sliced-groups> ( seq n -- groups )
+    sliced-groups new-groups ; inline
+
+INSTANCE: sliced-groups slice-chunking
+
+TUPLE: clumps < abstract-clumps ;
+
+: <clumps> ( seq n -- clumps )
+    clumps new-groups ; inline
+
+INSTANCE: clumps subseq-chunking
+
+TUPLE: sliced-clumps < abstract-clumps ;
+
+: <sliced-clumps> ( seq n -- clumps )
+    sliced-clumps new-groups ; inline
+
+INSTANCE: sliced-clumps slice-chunking
+
+: group ( seq n -- array ) <groups> { } like ;
+
+: clump ( seq n -- array ) <clumps> { } like ;
diff --git a/basis/grouping/summary.txt b/basis/grouping/summary.txt
new file mode 100644 (file)
index 0000000..3695129
--- /dev/null
@@ -0,0 +1 @@
+Grouping sequence elements into subsequences
diff --git a/basis/grouping/tags.txt b/basis/grouping/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
index 6c387632ed526e202e9d6fbfb855ca2842cabfe5..92146755d9db30cb2060510961b220340a825a00 100644 (file)
@@ -62,7 +62,7 @@ M: heap heap-size ( heap -- n )
 
 : data-set-nth ( entry n heap -- )
     >r [ >>index drop ] 2keep r>
-    data>> set-nth-unsafe ;
+    data>> set-nth-unsafe ; inline
 
 : data-push ( entry heap -- n )
     dup heap-size [
index 5b60102e467062b3a3cc2e7a10157fef21629a43..d1d9ca049a2708ed5bd6e3523ed0ab9d265a2d01 100644 (file)
@@ -166,16 +166,16 @@ ARTICLE: "io" "Input and output"
 { $heading "Encodings" }
 { $subsection "encodings-introduction" }
 { $subsection "io.encodings" }
-"Wrapper streams:"
+{ $heading "Wrapper streams" }
 { $subsection "io.streams.duplex" }
 { $subsection "io.streams.plain" }
 { $subsection "io.streams.string" }
 { $subsection "io.streams.byte-array" }
-"Utilities:"
+{ $heading "Utilities" }
 { $subsection "stream-binary" }
 { $subsection "styles" }
 { $subsection "checksums" }
-"Implementation:"
+{ $heading "Implementation" }
 { $subsection "io.streams.c" }
 { $subsection "io.ports" }
 { $see-also "destructors" } ;
index cafa758c7e80adb62cf2d5bce0a3a49dee968069..afa16bbf8a966a610950614bdc51c0d9c64aae53 100644 (file)
@@ -1,29 +1,24 @@
 USING: help.markup help.syntax ui.commands ui.operations
 ui.tools.search ui.tools.workspace editors vocabs.loader
 kernel sequences prettyprint tools.test tools.vocabs strings
-unicode.categories unicode.case ;
+unicode.categories unicode.case ui.tools.browser ;
 IN: help.tutorial
 
 ARTICLE: "first-program-start" "Creating a vocabulary for your first program"
 "Factor source code is organized into " { $link "vocabularies" } ". Before we can write our first program, we must create a vocabulary for it."
 $nl
-"Start by asking Factor for the path to your ``work'' directory, where you will place your own code:"
+"Start by loading the scaffold tool:"
+{ $code "USE: tools.scaffold" }
+"Then, ask the scaffold tool to create a new vocabulary named " { $snippet "palindrome" } ":"
+{ $code "\"resource:work\" \"palindrome\" scaffold-vocab" }
+"If you look at the output, you will see that a few files were created in your ``work'' directory. The following phrase will print the full path of your work directory:"
 { $code "\"work\" resource-path ." }
-"Open the work directory in your file manager, and create a subdirectory named " { $snippet "palindrome" } ". Inside this directory, create a file named " { $snippet "palindrome.factor" } " using your favorite text editor. Leave the file empty for now."
+"Open the work directory in your file manager, and open the subdirectory named " { $snippet "palindrome" } ". Inside this subdirectory you will see a file named " { $snippet "palindrome.factor" } ". We will be editing this file."
 $nl
-"Inside the Factor listener, type"
-{ $code "USE: palindrome" }
-"The source file should now load. Since it is empty, it does nothing. If you get an error message, make sure you created the directory and the file in the right place and gave them the right names."
-$nl
-"Now, we will start filling out this source file. Go back to your editor, and type:"
-{ $code
-    "! Copyright (C) 2008 <your name here>"
-    "! See http://factorcode.org/license.txt for BSD license."
-}
-"This is the standard header for Factor source files; it consists of two " { $link "syntax-comments" } "."
-$nl
-"Now, we tell Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:"
+"Notice that the file ends with an " { $link POSTPONE: IN: } " form telling Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:"
 { $code "IN: palindrome" }
+"We will add new definitions after the " { $link POSTPONE: IN: } " form."
+$nl
 "You are now ready to go on to the next section: " { $link "first-program-logic" } "." ;
 
 ARTICLE: "first-program-logic" "Writing some logic in your first program"
@@ -43,20 +38,16 @@ $nl
 $nl
 "When you do this, you will get an error about the " { $link dup } " word not being found. This is because this word is part of the " { $vocab-link "kernel" } " vocabulary, but this vocabulary is not part of the source file's " { $link "vocabulary-search" } ". You must explicitly list dependencies in source files. This allows Factor to automatically load required vocabularies and makes larger programs easier to maintain."
 $nl
-"To add the word to the search path, first convince yourself that this word is in the " { $vocab-link "kernel" } " vocabulary by entering the following in the listener:"
-{ $code "\\ dup see" }
-"This shows the definition of " { $link dup } ", along with an " { $link POSTPONE: IN: } " form."
+"To add the word to the search path, first convince yourself that this word is in the " { $vocab-link "kernel" } " vocabulary. Enter " { $snippet "dup" } " in the listener's input area, and press " { $operation com-follow } ". This will open the documentation browser tool, viewing the help for the " { $link dup } " word. One of the subheadings in the help article will mention the word's vocabulary."
 $nl
-"Now, add the following at the start of the source file:"
+"So now, add the following at the start of the source file:"
 { $code "USING: kernel ;" }
-"Next, find out what vocabulary " { $link reverse } " lives in:"
-{ $code "\\ reverse see" }
+"Next, find out what vocabulary " { $link reverse } " lives in; type the word name " { $snippet "reverse" } " in the workspace listener's input area, and press " { $operation com-follow } "."
+$nl
 "It lives in the " { $vocab-link "sequences" } " vocabulary, so we add that to the search path:"
 { $code "USING: kernel sequences ;" }
-"Finally, check what vocabulary " { $link = } " lives in:"
-{ $code "\\ = see" }
-"It's in the " { $vocab-link "kernel" } " vocabulary, which we've already added to the search path."
-
+"Finally, check what vocabulary " { $link = } " lives in, and confirm that it's in the " { $vocab-link "kernel" } " vocabulary, which we've already added to the search path."
+$nl
 "Now press " { $command workspace "workflow" refresh-all } " again, and the source file should reload without any errors. You can now go on and learn about " { $link "first-program-test" } "." ;
 
 ARTICLE: "first-program-test" "Testing your first program"
@@ -81,9 +72,9 @@ $nl
 { $code "." }
 "What we just did is called " { $emphasis "interactive testing" } ". A more advanced technique which comes into play with larger programs is " { $link "tools.test" } "."
 $nl
-"Create a file named " { $snippet "palindrome-tests.factor" } " in the same directory as " { $snippet "palindrome.factor" } ". Now, we can run unit tests from the listener:"
-{ $code "\"palindrome\" test" }
-"We will add some unit tests corresponding to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
+"Open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool."
+$nl
+"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
 $nl
 "Add the following three lines to " { $snippet "palindrome-tests.factor" } ":"
 { $code
@@ -145,7 +136,7 @@ $nl
 ARTICLE: "first-program" "Your first program"
 "In this tutorial, we will write a simple Factor program which prompts the user to enter a word, and tests if it is a palindrome (that is, the word is spelled the same backwards and forwards)."
 $nl
-"In this tutorial, you will learn about basic Factor development tools, as well as application deployment."
+"In this tutorial, you will learn about basic Factor development tools. You may want to open a second workspace window by pressing " { $command workspace "workflow" workspace-window } "; this will allow you to read this tutorial and browse other documentation at the same time."
 { $subsection "first-program-start" }
 { $subsection "first-program-logic" }
 { $subsection "first-program-test" }
index 6556d2eac2cf4767e9dd1b9978ca021eb5f27666..089a516072dec0030ff4807cf3ca40024b70c8ab 100644 (file)
@@ -85,6 +85,14 @@ HELP: validate-values
 { $values { "assoc" assoc } { "validators" "an assoc mapping value names to quotations" } }
 { $description "Validates values in the assoc by looking up the corresponding validation quotation, and storing the results in named values of the current form." } ;
 
+HELP: validation-error
+{ $values { "message" string } }
+{ $description "Reports a validation error not associated with a specific form field." }
+{ $notes "Such errors can be rendered by calling the " { $link render-validation-errors } " word." } ;
+
+HELP: render-validation-errors
+{ $description "Renders any validation errors reported by calls to the " { $link validation-error } " word." } ;
+
 ARTICLE: "html.forms.forms" "HTML form infrastructure"
 "The below words are used to implement the " { $vocab-link "furnace.actions" } " vocabulary. Calling them directly is rarely necessary."
 $nl
index c1c1aa3def13e4e21cd49d4ac2d9161006a7644e..f92f8d0764036ea58777f3bbdc6ce59376450569 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors strings namespaces assocs hashtables
-mirrors math fry sequences words continuations ;
+USING: kernel accessors strings namespaces assocs hashtables io
+mirrors math fry sequences words continuations html.elements
+xml.entities ;
 IN: html.forms
 
 TUPLE: form errors values validation-failed ;
@@ -104,3 +105,11 @@ C: <validation-error> validation-error
 
 : validate-values ( assoc validators -- )
     swap '[ [ dup _ at ] dip validate-value ] assoc-each ;
+
+: render-validation-errors ( -- )
+    form get errors>>
+    [
+        <ul "errors" =class ul>
+            [ <li> escape-string write </li> ] each
+        </ul>
+    ] unless-empty ;
index f390aad23824b17e13865a2b0401e529786c77b1..402b6e68a92ed4fe43d6f06f0dd5579120fcb7f9 100644 (file)
@@ -154,6 +154,9 @@ ARTICLE: "html.templates.chloe.tags.form" "Chloe link and form tags"
             "</t:button>"
         }
     } }
+    { { $snippet "t:validation-errors" } {
+        "Renders validation errors in the current form which are not associated with any field. Such errors are reported by invoking " { $link validation-error } "."
+    } }
 } ;
 
 ARTICLE: "html.templates.chloe.tags" "Standard Chloe tags"
index 1bc4684d5c41488e16c78c7bd40bdc2615783363..da3f80e9a5d9c54440cab55f48b3066cb0f9db8c 100644 (file)
@@ -65,6 +65,9 @@ CHLOE: comment drop ;
 CHLOE: call-next-template
     drop reset-buffer \ call-next-template , ;
 
+CHLOE: validation-errors
+    drop [ render-validation-errors ] [code] ;
+
 : attr>word ( value -- word/f )
     ":" split1 swap lookup ;
 
index 0a35eee272176b8cba8d6a200ef7f1f8bb6136cc..dc0f547301e7275ce4483f0a7088ee90f2a501d9 100644 (file)
@@ -4,7 +4,8 @@ USING: help.markup help.syntax byte-arrays strings ;
 IN: io.encodings.string
 
 ARTICLE: "io.encodings.string" "Encoding and decoding strings"
-"Strings can be encoded or decoded to and from byte arrays through an encoding with the following words:"
+"Strings can be encoded or decoded to and from byte arrays through an encoding by passing "
+{ $link "encodings-descriptors" } " to the following words:"
 { $subsection encode }
 { $subsection decode } ;
 
diff --git a/basis/io/files/listing/authors.txt b/basis/io/files/listing/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/io/files/listing/listing-docs.factor b/basis/io/files/listing/listing-docs.factor
new file mode 100644 (file)
index 0000000..6b19e9b
--- /dev/null
@@ -0,0 +1,17 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string strings ;
+IN: io.files.listing
+
+HELP: directory.
+{ $values
+     { "path" "a pathname string" }
+}
+{ $description "Prints information about all files in a directory to the output stream in a cross-platform way similar to the Unix " { $snippet "ls" } " command." } ;
+
+ARTICLE: "io.files.listing" "Listing files"
+"The " { $vocab-link "io.files.listing" } " vocabulary implements directory file listing in a cross-platform way." $nl
+"Listing a directory:"
+{ $subsection directory. } ;
+
+ABOUT: "io.files.listing"
diff --git a/basis/io/files/listing/listing-tests.factor b/basis/io/files/listing/listing-tests.factor
new file mode 100644 (file)
index 0000000..a2347c8
--- /dev/null
@@ -0,0 +1,6 @@
+! Copyright (C) 2008 Your name.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test io.files.listing strings kernel ;
+IN: io.files.listing.tests
+
+[ ] [ "" directory. ] unit-test
diff --git a/basis/io/files/listing/listing.factor b/basis/io/files/listing/listing.factor
new file mode 100755 (executable)
index 0000000..f88fcec
--- /dev/null
@@ -0,0 +1,39 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays combinators io io.files kernel
+math.parser sequences system vocabs.loader calendar ;
+
+IN: io.files.listing
+
+<PRIVATE
+
+: ls-time ( timestamp -- string )
+    [ hour>> ] [ minute>> ] bi
+    [ number>string 2 CHAR: 0 pad-left ] bi@ ":" swap 3append ;
+
+: ls-timestamp ( timestamp -- string )
+    [ month>> month-abbreviation ]
+    [ day>> number>string 2 CHAR: \s pad-left ]
+    [
+        dup year>> dup now year>> =
+        [ drop ls-time ] [ nip number>string ] if
+        5 CHAR: \s pad-left
+    ] tri 3array " " join ;
+
+: read>string ( ? -- string ) "r" "-" ? ; inline
+
+: write>string ( ? -- string ) "w" "-" ? ; inline
+
+: execute>string ( ? -- string ) "x" "-" ? ; inline
+
+HOOK: (directory.) os ( path -- lines )
+
+PRIVATE>
+
+: directory. ( path -- )
+    [ (directory.) ] with-directory-files [ print ] each ;
+
+{
+    { [ os unix? ] [ "io.files.listing.unix" ] }
+    { [ os windows? ] [ "io.files.listing.windows" ] }
+} cond require
diff --git a/basis/io/files/listing/tags.txt b/basis/io/files/listing/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/files/listing/unix/authors.txt b/basis/io/files/listing/unix/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/io/files/listing/unix/tags.txt b/basis/io/files/listing/unix/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/files/listing/unix/unix.factor b/basis/io/files/listing/unix/unix.factor
new file mode 100755 (executable)
index 0000000..313ce1f
--- /dev/null
@@ -0,0 +1,48 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators kernel system unicode.case
+io.unix.files io.files.listing generalizations strings
+arrays sequences io.files math.parser unix.groups unix.users
+io.files.listing.private ;
+IN: io.files.listing.unix
+
+<PRIVATE
+
+: unix-execute>string ( str bools -- str' )
+    swap {
+        { { t t } [ >lower ] }
+        { { t f } [ >upper ] }
+        { { f t } [ drop "x" ] }
+        [ 2drop "-" ]
+    } case ;
+
+: permissions-string ( permissions -- str )
+    {
+        [ type>> file-type>ch 1string ]
+        [ user-read? read>string ]
+        [ user-write? write>string ]
+        [ [ uid? ] [ user-execute? ] bi 2array "s" unix-execute>string ]
+        [ group-read? read>string ]
+        [ group-write? write>string ]
+        [ [ gid? ] [ group-execute? ] bi 2array "s" unix-execute>string ]
+        [ other-read? read>string ]
+        [ other-write? write>string ]
+        [ [ sticky? ] [ other-execute? ] bi 2array "t" unix-execute>string ]
+    } cleave 10 narray concat ;
+
+M: unix (directory.) ( path -- lines )
+    [ [
+        [
+            dup file-info
+            {
+                [ permissions-string ]
+                [ nlink>> number>string 3 CHAR: \s pad-left ]
+                ! [ uid>> ]
+                ! [ gid>> ]
+                [ size>> number>string 15 CHAR: \s pad-left ]
+                [ modified>> ls-timestamp ]
+            } cleave 4 narray swap suffix " " join
+        ] map
+    ] with-group-cache ] with-user-cache ;
+
+PRIVATE>
diff --git a/basis/io/files/listing/windows/authors.txt b/basis/io/files/listing/windows/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/io/files/listing/windows/tags.txt b/basis/io/files/listing/windows/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/io/files/listing/windows/windows.factor b/basis/io/files/listing/windows/windows.factor
new file mode 100755 (executable)
index 0000000..33ab47a
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors calendar.format combinators io.files
+kernel math.parser sequences splitting system io.files.listing
+generalizations io.files.listing.private ;
+IN: io.files.listing.windows
+
+<PRIVATE
+
+: directory-or-size ( file-info -- str )
+    dup directory? [
+        drop "<DIR>" 20 CHAR: \s pad-right
+    ] [
+        size>> number>string 20 CHAR: \s pad-left
+    ] if ;
+
+M: windows (directory.) ( entries -- lines )
+    [
+        dup file-info {
+            [ modified>> timestamp>ymdhms ]
+            [ directory-or-size ]
+        } cleave 2 narray swap suffix " " join
+    ] map ;
+
+PRIVATE>
index 00711ce22614985e65a101c177d2b60ab9c8a81a..22c40da3d7a7bcc9ec8df8d83a1d456bef206c97 100644 (file)
@@ -45,15 +45,20 @@ ARTICLE: "server-config-handler" "Client handler quotation"
 $nl
 "The two methods are equivalent, representing a functional versus an object-oriented approach to the problem." ;
 
+ARTICLE: "server-examples" "Threaded server examples"
+"The " { $vocab-link "time-server" } " vocabulary implements a simple threaded server which sends the current time to the client. The " { $vocab-link "concurrency.distributed" } ", " { $vocab-link "ftp.server" } ", and " { $vocab-link "http.server" } " vocabularies demonstrate more complex usage of the threaded server library." ;
+
 ARTICLE: "io.servers.connection" "Threaded servers"
 "The " { $vocab-link "io.servers.connection" } " vocabulary implements a generic server abstraction for " { $link "network-connection" } ". A set of threads listen for connections, and additional threads are spawned for each client connection. In addition to this basic functionality, it provides some advanced features such as logging, connection limits and secure socket support."
-{ $subsection threaded-server }
-{ $subsection "server-config" }
+{ $subsection "server-examples" }
 "Creating threaded servers with client handler quotations:"
 { $subsection <threaded-server> }
 "Client handlers can also be implemented by subclassing a threaded server; see " { $link "server-config-handler" } " for details:"
+{ $subsection threaded-server }
 { $subsection new-threaded-server }
 { $subsection handle-client* }
+"The server must be configured before it can be started." 
+{ $subsection "server-config" }
 "Starting the server:"
 { $subsection start-server }
 { $subsection start-server* }
index 9ebfdaaa5a6b2ea9d2ac42552478a5cf291afe16..3f254e771341d203b8ab76dc23f972883d55a8a5 100644 (file)
@@ -172,6 +172,30 @@ M: unix (directory-entries) ( path -- seq )
 
 PRIVATE>
 
+: ch>file-type ( ch -- type )
+    {
+        { CHAR: b [ +block-device+ ] }
+        { CHAR: c [ +character-device+ ] }   
+        { CHAR: d [ +directory+ ] }
+        { CHAR: l [ +symbolic-link+ ] }
+        { CHAR: s [ +socket+ ] }
+        { CHAR: p [ +fifo+ ] }
+        { CHAR: - [ +regular-file+ ] }
+        [ drop +unknown+ ]
+    } case ;
+
+: file-type>ch ( type -- string )
+    {
+        { +block-device+ [ CHAR: b ] }
+        { +character-device+ [ CHAR: c ] }
+        { +directory+ [ CHAR: d ] }
+        { +symbolic-link+ [ CHAR: l ] }
+        { +socket+ [ CHAR: s ] }
+        { +fifo+ [ CHAR: p ] }
+        { +regular-file+ [ CHAR: - ] }
+        [ drop CHAR: - ]
+    } case ;
+
 : UID           OCT: 0004000 ; inline
 : GID           OCT: 0002000 ; inline
 : STICKY        OCT: 0001000 ; inline
index e5e83ab4e9599e94fec6225f425ceb1f7174fdaa..276ed45f27802c7721ba9964fcf31575ac0d4f9f 100644 (file)
@@ -29,5 +29,5 @@ IN: io.unix.launcher.parser
 
 PEG: tokenize-command ( command -- ast/f )
     'argument' " " token repeat1 list-of
-    " " token repeat0 swap over pack
+    " " token repeat0 tuck pack
     just ;
old mode 100644 (file)
new mode 100755 (executable)
index 3fb8029..d0409ce
@@ -149,35 +149,39 @@ SYMBOLS: +read-only+ +hidden+ +system+
 +sparse-file+ +reparse-point+ +compressed+ +offline+
 +not-content-indexed+ +encrypted+ ;
 
-: win32-file-attribute ( n attr symbol -- n )
-    >r dupd mask? r> swap [ , ] [ drop ] if ;
+TUPLE: windows-file-info < file-info attributes ;
+
+: win32-file-attribute ( n attr symbol -- )
+    rot mask? [ , ] [ drop ] if ;
 
 : win32-file-attributes ( n -- seq )
     [
-        FILE_ATTRIBUTE_READONLY +read-only+ win32-file-attribute
-        FILE_ATTRIBUTE_HIDDEN +hidden+ win32-file-attribute
-        FILE_ATTRIBUTE_SYSTEM +system+ win32-file-attribute
-        FILE_ATTRIBUTE_DIRECTORY +directory+ win32-file-attribute
-        FILE_ATTRIBUTE_ARCHIVE +archive+ win32-file-attribute
-        FILE_ATTRIBUTE_DEVICE +device+ win32-file-attribute
-        FILE_ATTRIBUTE_NORMAL +normal+ win32-file-attribute
-        FILE_ATTRIBUTE_TEMPORARY +temporary+ win32-file-attribute
-        FILE_ATTRIBUTE_SPARSE_FILE +sparse-file+ win32-file-attribute
-        FILE_ATTRIBUTE_REPARSE_POINT +reparse-point+ win32-file-attribute
-        FILE_ATTRIBUTE_COMPRESSED +compressed+ win32-file-attribute
-        FILE_ATTRIBUTE_OFFLINE +offline+ win32-file-attribute
-        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED +not-content-indexed+ win32-file-attribute
-        FILE_ATTRIBUTE_ENCRYPTED +encrypted+ win32-file-attribute
-        drop
+        {
+            [ +read-only+ FILE_ATTRIBUTE_READONLY win32-file-attribute ]
+            [ +hidden+ FILE_ATTRIBUTE_HIDDEN win32-file-attribute ]
+            [ +system+ FILE_ATTRIBUTE_SYSTEM win32-file-attribute ]
+            [ +directory+ FILE_ATTRIBUTE_DIRECTORY win32-file-attribute ]
+            [ +archive+ FILE_ATTRIBUTE_ARCHIVE win32-file-attribute ]
+            [ +device+ FILE_ATTRIBUTE_DEVICE win32-file-attribute ]
+            [ +normal+ FILE_ATTRIBUTE_NORMAL win32-file-attribute ]
+            [ +temporary+ FILE_ATTRIBUTE_TEMPORARY win32-file-attribute ]
+            [ +sparse-file+ FILE_ATTRIBUTE_SPARSE_FILE win32-file-attribute ]
+            [ +reparse-point+ FILE_ATTRIBUTE_REPARSE_POINT win32-file-attribute ]
+            [ +compressed+ FILE_ATTRIBUTE_COMPRESSED win32-file-attribute ]
+            [ +offline+ FILE_ATTRIBUTE_OFFLINE win32-file-attribute ]
+            [ +not-content-indexed+ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED win32-file-attribute ]
+            [ +encrypted+ FILE_ATTRIBUTE_ENCRYPTED win32-file-attribute ]
+        } cleave
     ] { } make ;
 
 : win32-file-type ( n -- symbol )
     FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ;
 
 : WIN32_FIND_DATA>file-info ( WIN32_FIND_DATA -- file-info )
-    [ \ file-info new ] dip
+    [ \ windows-file-info new ] dip
     {
         [ WIN32_FIND_DATA-dwFileAttributes win32-file-type >>type ]
+        [ WIN32_FIND_DATA-dwFileAttributes win32-file-attributes >>attributes ]
         [
             [ WIN32_FIND_DATA-nFileSizeLow ]
             [ WIN32_FIND_DATA-nFileSizeHigh ] bi >64bit >>size
@@ -196,9 +200,10 @@ SYMBOLS: +read-only+ +hidden+ +system+
     ] keep ;
 
 : BY_HANDLE_FILE_INFORMATION>file-info ( HANDLE_FILE_INFORMATION -- file-info )
-    [ \ file-info new ] dip
+    [ \ windows-file-info new ] dip
     {
         [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-type >>type ]
+        [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-attributes >>attributes ]
         [
             [ BY_HANDLE_FILE_INFORMATION-nFileSizeLow ]
             [ BY_HANDLE_FILE_INFORMATION-nFileSizeHigh ] bi >64bit >>size
@@ -276,18 +281,31 @@ M: winnt file-system-info ( path -- file-system-info )
         swap >>type
         swap >>mount-point ;
 
-: find-first-volume ( word -- string handle )
+: volume>paths ( string -- array )
+    16384 "ushort" <c-array> tuck dup length
+    0 <uint> dup [ GetVolumePathNamesForVolumeName 0 = ] dip swap [
+        win32-error-string throw
+    ] [
+        *uint "ushort" heap-size * head
+        utf16n alien>string CHAR: \0 split
+    ] if ;
+
+: find-first-volume ( -- string handle )
     MAX_PATH 1+ <byte-array> dup length
     dupd
     FindFirstVolume dup win32-error=0/f
     [ utf16n alien>string ] dip ;
 
-: find-next-volume ( handle -- string )
+: find-next-volume ( handle -- string/f )
     MAX_PATH 1+ <byte-array> dup length
-    [ FindNextVolume win32-error=0/f ] 2keep drop
-    utf16n alien>string ;
+    over [ FindNextVolume ] dip swap 0 = [
+        GetLastError ERROR_NO_MORE_FILES =
+        [ drop f ] [ win32-error ] if
+    ] [
+        utf16n alien>string
+    ] if ;
 
-: mounted ( -- array )
+: find-volumes ( -- array )
     find-first-volume
     [
         '[
@@ -298,6 +316,13 @@ M: winnt file-system-info ( path -- file-system-info )
         ]
     ] [ '[ _ FindVolumeClose win32-error=0/f ] ] bi [ ] cleanup ;
 
+M: winnt file-systems ( -- array )
+    find-volumes [ volume>paths ] map
+    concat [
+        [ file-system-info ]
+        [ drop winnt-file-system-info new swap >>mount-point ] recover
+    ] map ;
+
 : file-times ( path -- timestamp timestamp timestamp )
     [
         normalize-path open-existing &dispose handle>>
diff --git a/basis/linked-assocs/authors.txt b/basis/linked-assocs/authors.txt
new file mode 100644 (file)
index 0000000..35a4db1
--- /dev/null
@@ -0,0 +1,2 @@
+Slava Pestov
+James Cash
diff --git a/basis/linked-assocs/linked-assocs-docs.factor b/basis/linked-assocs/linked-assocs-docs.factor
new file mode 100644 (file)
index 0000000..6fd4295
--- /dev/null
@@ -0,0 +1,23 @@
+IN: linked-assocs
+USING: help.markup help.syntax assocs ;
+
+HELP: linked-assoc
+{ $class-description "The class of linked assocs. Linked assoc are implemented by combining an assoc with a dlist.  The assoc is used for lookup and retrieval of single values, while the dlist is used for getting lists of keys/values, which will be in insertion order." } ;
+
+HELP: <linked-assoc>
+{ $values { "exemplar" "an exemplar assoc" } { "assoc" linked-assoc } }
+{ $description "Creates an empty linked assoc backed by a new instance of the same type as the exemplar." } ;
+
+HELP: <linked-hash>
+{ $values { "assoc" linked-assoc } }
+{ $description "Creates an empty linked assoc backed by a hashtable." } ;
+
+ARTICLE: "linked-assocs" "Linked assocs"
+"A " { $emphasis "linked assoc" } " is an assoc which combines an underlying assoc with a dlist to form a structure which has the insertion and retrieval characteristics of the underlying assoc (typically a hashtable), but with the ability to get the entries in insertion order by calling " { $link >alist } "."
+$nl
+"Linked assocs are implemented in the " { $vocab-link "linked-assocs" } " vocabulary."
+{ $subsection linked-assoc }
+{ $subsection <linked-hash> }
+{ $subsection <linked-assoc> } ;
+
+ABOUT: "linked-assocs"
\ No newline at end of file
diff --git a/basis/linked-assocs/linked-assocs-tests.factor b/basis/linked-assocs/linked-assocs-tests.factor
new file mode 100644 (file)
index 0000000..7a259ee
--- /dev/null
@@ -0,0 +1,57 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences assocs tools.test linked-assocs math ;
+IN: linked-assocs.test
+
+{ { 1 2 3 } } [
+    <linked-hash> 1 "b" pick set-at
+                  2 "c" pick set-at
+                  3 "a" pick set-at
+    values
+] unit-test
+
+{ 2 t } [
+    <linked-hash> 1 "b" pick set-at
+                  2 "c" pick set-at
+                  3 "a" pick set-at
+    "c" swap at*
+] unit-test
+
+{ { 2 3 4 } { "c" "a" "d" } 3 } [
+    <linked-hash> 1 "a" pick set-at
+                  2 "c" pick set-at
+                  3 "a" pick set-at
+                  4 "d" pick set-at
+    [ values ] [ keys ] [ assoc-size ] tri
+] unit-test 
+
+{ f 1 } [
+    <linked-hash> 1 "c" pick set-at
+                  2 "b" pick set-at
+    "c" over delete-at
+    "c" over at swap assoc-size
+] unit-test 
+
+{ { } 0 } [
+    <linked-hash> 1 "a" pick set-at
+                  2 "c" pick set-at
+                  3 "a" pick set-at
+                  4 "d" pick set-at
+    dup clear-assoc [ keys ] [ assoc-size ] bi
+] unit-test
+
+{ { } { 1 2 3 } } [
+    <linked-hash> dup clone
+    1 "c" pick set-at
+    2 "q" pick set-at
+    3 "a" pick set-at
+    [ values ] bi@
+] unit-test
+
+{ 9 } [
+    <linked-hash>
+    { [ 3 * ] [ 1- ] }          "first"   pick set-at
+    { [ [ 1- ] bi@ ] [ 2 / ] }  "second"  pick set-at
+    4 6 pick values [ first call ] each
+    + swap values <reversed> [ second call ] each
+] unit-test
\ No newline at end of file
diff --git a/basis/linked-assocs/linked-assocs.factor b/basis/linked-assocs/linked-assocs.factor
new file mode 100644 (file)
index 0000000..7330ac1
--- /dev/null
@@ -0,0 +1,44 @@
+! Copyright (C) 2008 Slava Pestov, James Cash.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs arrays kernel deques dlists sequences fry ;
+IN: linked-assocs
+
+TUPLE: linked-assoc assoc dlist ;
+
+: <linked-assoc> ( exemplar -- assoc )
+    0 swap new-assoc <dlist> linked-assoc boa ;
+
+: <linked-hash> ( -- assoc )
+    H{ } <linked-assoc> ;
+
+M: linked-assoc assoc-size assoc>> assoc-size ;
+
+M: linked-assoc at* assoc>> at* [ [ obj>> second ] when ] keep ;
+
+M: linked-assoc delete-at
+    [ [ assoc>> ] [ dlist>> ] bi [ at ] dip '[ _ delete-node ] when* ]
+    [ assoc>> delete-at ] 2bi ;
+
+<PRIVATE
+: add-to-dlist ( value key lassoc -- node )
+    [ swap 2array ] dip dlist>> push-back* ;
+PRIVATE>
+
+M: linked-assoc set-at
+    [ 2dup assoc>> key? [ 2dup delete-at ] when add-to-dlist ] 2keep
+    assoc>> set-at ;
+
+: dlist>seq ( dlist -- seq )
+    [ ] pusher [ dlist-each ] dip ;
+
+M: linked-assoc >alist
+    dlist>> dlist>seq ;
+
+M: linked-assoc clear-assoc
+    [ assoc>> clear-assoc ] [ dlist>> clear-deque ] bi ;
+
+M: linked-assoc clone 
+    [ assoc>> clone ] [ dlist>> clone ] bi
+    linked-assoc boa ;
+
+INSTANCE: linked-assoc assoc
diff --git a/basis/linked-assocs/summary.txt b/basis/linked-assocs/summary.txt
new file mode 100644 (file)
index 0000000..54b0d14
--- /dev/null
@@ -0,0 +1 @@
+Assocs that yield items in insertion order
diff --git a/basis/linked-assocs/tags.txt b/basis/linked-assocs/tags.txt
new file mode 100644 (file)
index 0000000..031765c
--- /dev/null
@@ -0,0 +1 @@
+assocs
index eb368936d408e0c7e3301a807d2a2ff9d2c04a3c..35e0536530a19b2b38501b05d1e5328a1b985f47 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.syntax help.markup kernel macros prettyprint
-memoize ;
+memoize combinators arrays ;
 IN: locals
 
 HELP: [|
@@ -84,6 +84,39 @@ HELP: MEMO::
 
 { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words
 
+ARTICLE: "locals-literals" "Locals in array and hashtable literals"
+"Certain data type literals are permitted to contain free variables. Any such literals are written into code which constructs an instance of the type with the free variable values spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables."
+$nl
+"The data types which receive this special handling are the following:"
+{ $list
+    { $link "arrays" }
+    { $link "hashtables" }
+    { $link "vectors" }
+    { $link "tuples" }
+}
+"This feature changes the semantics of literal object identity. An ordinary word containing a literal pushes the same literal on the stack every time it is invoked:"
+{ $example
+    "IN: scratchpad"
+    "TUPLE: person first-name last-name ;"
+    ": ordinary-word-test ( -- tuple )"
+    "    T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
+    "ordinary-word-test ordinary-word-test eq? ."
+    "t"
+}
+"In a word with locals, literals expand into code which constructs the literal, and so every invocation pushes a new object:"
+{ $example
+    "IN: scratchpad"
+    "TUPLE: person first-name last-name ;"
+    ":: ordinary-word-test ( -- tuple )"
+    "    T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
+    "ordinary-word-test ordinary-word-test eq? ."
+    "f"
+}
+"One exception to the above rule is that array instances containing no free variables do retain identity. This allows macros such as " { $link cond } " to recognize that the array is constant and expand at compile-time."
+$nl
+"For example, here is an implementation of the " { $link 3array } " word which uses this feature:"
+{ $code ":: 3array ( x y z -- array ) { x y z } ;" } ;
+
 ARTICLE: "locals-mutable" "Mutable locals"
 "In the list of bindings supplied to " { $link POSTPONE: :: } ", " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } " or " { $link POSTPONE: [| } ", a mutable binding may be introduced by suffixing its named with " { $snippet "!" } ". Mutable bindings are read by giving their name as usual; the suffix is not part of the binding's name. To write to a mutable binding, use the binding's name with the " { $snippet "!" } " suffix."
 $nl
@@ -139,6 +172,7 @@ $nl
 "Lambda abstractions:"
 { $subsection POSTPONE: [| }
 "Additional topics:"
+{ $subsection "locals-literals" }
 { $subsection "locals-mutable" }
 { $subsection "locals-limitations" }
 "Locals complement dynamically scoped variables implemented in the " { $vocab-link "namespaces" } " vocabulary." ;
index c588269284ebd5b27a31b8b4aefa79c8f7aebe10..e74ecf3dc9fa55da59eb939a2c144ae79138f4bb 100644 (file)
@@ -6,8 +6,7 @@ quotations debugger macros arrays macros splitting combinators
 prettyprint.backend definitions prettyprint hashtables
 prettyprint.sections sets sequences.private effects
 effects.parser generic generic.parser compiler.units accessors
-locals.backend memoize macros.expander lexer classes
-stack-checker.known-words ;
+locals.backend memoize macros.expander lexer classes ;
 IN: locals
 
 ! Inspired by
@@ -49,8 +48,7 @@ PREDICATE: local < word "local?" word-prop ;
 : <local> ( name -- word )
     #! Create a local variable identifier
     f <word>
-    dup t "local?" set-word-prop
-    dup { } { object } define-primitive ;
+    dup t "local?" set-word-prop ;
 
 PREDICATE: local-word < word "local-word?" word-prop ;
 
@@ -61,14 +59,12 @@ PREDICATE: local-reader < word "local-reader?" word-prop ;
 
 : <local-reader> ( name -- word )
     f <word>
-    dup t "local-reader?" set-word-prop
-    dup { } { object } define-primitive ;
+    dup t "local-reader?" set-word-prop ;
 
 PREDICATE: local-writer < word "local-writer?" word-prop ;
 
 : <local-writer> ( reader -- word )
     dup name>> "!" append f <word> {
-        [ nip { object } { } define-primitive ]
         [ nip t "local-writer?" set-word-prop ]
         [ swap "local-reader" set-word-prop ]
         [ "local-writer" set-word-prop ]
index c2fceffae69da82fda726b4855767e2a581bb21c..3666fa2423c7e2d579ae772caaeeacd17a57e183 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences sequences.private namespaces make
 quotations accessors words continuations vectors effects math
-generalizations stack-checker.transforms fry ;
+generalizations fry ;
 IN: macros.expander
 
 GENERIC: expand-macros ( quot -- quot' )
index 0a6621f044b4ce27158f857ff22d873565994b22..794d523d006c11504c32aeb16db8ea3950d3cfd7 100644 (file)
@@ -1,21 +1,18 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser kernel sequences words effects
-stack-checker.transforms combinators assocs definitions
-quotations namespaces memoize accessors ;
+USING: parser kernel sequences words effects combinators assocs
+definitions quotations namespaces memoize accessors ;
 IN: macros
 
 : real-macro-effect ( word -- effect' )
     "declared-effect" word-prop in>> 1 <effect> ;
 
 : define-macro ( word definition -- )
-    over "declared-effect" word-prop in>> length >r
-    2dup "macro" set-word-prop
-    2dup over real-macro-effect memoize-quot [ call ] append define
-    r> define-transform ;
+    [ "macro" set-word-prop ]
+    [ over real-macro-effect memoize-quot [ call ] append define ]
+    2bi ;
 
-: MACRO:
-    (:) define-macro ; parsing
+: MACRO: (:) define-macro ; parsing
 
 PREDICATE: macro < word "macro" word-prop >boolean ;
 
index 247523369b9ce728e7db7107c4f720044d790c17..4f2606bda0ef8540cb6f6fdc7a43186d92ced564 100644 (file)
@@ -1,12 +1,8 @@
-USING: help.markup help.syntax math ;
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax math sequences ;
 IN: math.bitwise
 
-ARTICLE: "math-bitfields" "Constructing bit fields"
-"Some applications, such as binary communication protocols and assemblers, need to construct integers from elaborate bit field specifications. Hand-coding this using " { $link shift } " and " { $link bitor } " results in repetitive code. A higher-level facility exists to factor out this repetition:"
-{ $subsection bitfield } ;
-
-ABOUT: "math-bitfields"
-
 HELP: bitfield
 { $values { "values..." "a series of objects" } { "bitspec" "an array" } { "n" integer } }
 { $description "Constructs an integer from a series of values on the stack together with a bit field specifier, which is an array whose elements have one of the following shapes:"
@@ -42,9 +38,307 @@ HELP: bits
 { $example "USING: math.bitwise prettyprint ;" "HEX: 123abcdef 16 bits .h" "cdef" } ;
 
 HELP: bitroll
-{ $values { "x" "an integer (input)" } { "s" "an integer (shift)" } { "w" "an integer (wrap)" } { "y" integer } }
+{ $values { "x" integer } { "s" "a shift integer" } { "w" "a wrap integer" } { "y" integer }
+}
 { $description "Roll n by s bits to the left, wrapping around after w bits." }
 { $examples
     { $example "USING: math.bitwise prettyprint ;" "1 -1 32 bitroll .b" "10000000000000000000000000000000" }
     { $example "USING: math.bitwise prettyprint ;" "HEX: ffff0000 8 32 bitroll .h" "ff0000ff" }
 } ;
+
+HELP: bit-clear?
+{ $values
+     { "x" integer } { "n" integer }
+     { "?" "a boolean" }
+}
+{ $description "Returns " { $link t } " if the nth bit is set to zero." }
+{ $examples 
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: ff 8 bit-clear? ."
+               "t"
+    }
+    { $example "" "USING: math.bitwise prettyprint ;"
+               "HEX: ff 7 bit-clear? ."
+               "f"
+    }
+} ;
+
+{ bit? bit-clear? set-bit clear-bit } related-words
+
+HELP: bit-count
+{ $values
+     { "x" integer }
+     { "n" integer }
+}
+{ $description "Returns the number of set bits as an integer." }
+{ $examples 
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: f0 bit-count ."
+               "4"
+    }
+    { $example "USING: math.bitwise prettyprint ;"
+               "-7 bit-count ."
+               "2"
+    }
+} ;
+
+HELP: bitroll-32
+{ $values
+     { "n" integer } { "s" integer }
+     { "n'" integer }
+}     
+{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 32 bits." }
+{ $examples 
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: 1 10 bitroll-32 .h"
+               "400"
+    }
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: 1 -10 bitroll-32 .h"
+               "400000"
+    }
+} ;
+
+HELP: bitroll-64
+{ $values
+     { "n" integer } { "s" "a shift integer" }
+     { "n'" integer }
+}
+{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 64 bits." }
+{ $examples 
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: 1 10 bitroll-64 .h"
+               "400"
+    }
+    { $example "USING: math.bitwise prettyprint ;"
+               "HEX: 1 -10 bitroll-64 .h"
+               "40000000000000"
+    }
+} ;
+
+{ bitroll bitroll-32 bitroll-64 } related-words
+
+HELP: clear-bit
+{ $values
+     { "x" integer } { "n" integer }
+     { "y" integer }
+}
+{ $description "Sets the nth bit of " { $snippet "x" } " to zero." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ff 7 clear-bit .h"
+        "7f"
+    }
+} ;
+
+HELP: flags
+{ $values
+     { "values" sequence }
+}
+{ $description "Constructs a constant flag value from a sequence of integers or words that output integers. The resulting constant is computed at compile-time, which makes this word as efficient as using a literal integer." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "IN: scratchpad"
+        ": MY-CONSTANT HEX: 1 ; inline"
+        "{ HEX: 20 MY-CONSTANT BIN: 100 } flags .h"
+        "25"
+    }
+} ;
+
+HELP: mask
+{ $values
+     { "x" integer } { "n" integer }
+     { "?" "a boolean" }
+}
+{ $description "After the operation, only the bits that were set in both the mask and the original number are set." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "BIN: 11111111 BIN: 101 mask .b"
+        "101"
+    }
+} ;
+
+HELP: mask-bit
+{ $values
+     { "m" integer } { "n" integer }
+     { "m'" integer }
+}
+{ $description "Turns off all bits besides the nth bit." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ff 2 mask-bit .b"
+        "100"
+    }
+} ;
+
+HELP: mask?
+{ $values
+     { "x" integer } { "n" integer }
+     { "?" "a boolean" }
+}
+{ $description "Returns true if all of the bits in the mask " { $snippet "n" } " are set in the integer input " { $snippet "x" } "." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ff HEX: f mask? ."
+        "t"
+    }
+
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: f0 HEX: 1 mask? ."
+        "f"
+    }
+} ;
+
+HELP: on-bits
+{ $values
+     { "n" integer }
+     { "m" integer }
+}
+{ $description "Returns an integer with " { $snippet "n" } " bits set." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "6 on-bits .h"
+        "3f"
+    }
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "64 on-bits .h"
+        "ffffffffffffffff"
+    }
+}
+;
+
+HELP: set-bit
+{ $values
+     { "x" integer } { "n" integer }
+     { "y" integer }
+}
+{ $description "Sets the nth bit of " { $snippet "x" } "." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "0 5 set-bit .h"
+        "20"
+    }
+} ;
+
+HELP: shift-mod
+{ $values
+     { "n" integer } { "s" integer } { "w" integer }
+     { "n" integer }
+}
+{ $description "" } ;
+
+HELP: unmask
+{ $values
+     { "x" integer } { "n" integer }
+     { "?" "a boolean" }
+}
+{ $description "Clears the bits in " { $snippet "x" } " if they are set in the mask " { $snippet "n" } "." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ff  HEX: 0f unmask .h"
+        "f0"
+    }
+} ;
+
+HELP: unmask?
+{ $values
+     { "x" integer } { "n" integer }
+     { "?" "a boolean" }
+}
+{ $description "Tests whether unmasking the bits in " { $snippet "x" } " would return an integer greater than zero." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ff  HEX: 0f unmask? ."
+        "t"
+    }
+} ;
+
+HELP: w*
+{ $values
+     { "int" integer } { "int" integer }
+     { "int" integer }
+}
+{ $description "Multiplies two integers and wraps the result to 32 bits." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ffffffff HEX: 2 w* ."
+        "4294967294"
+    }
+} ;
+
+HELP: w+
+{ $values
+     { "int" integer } { "int" integer }
+     { "int" integer }
+}
+{ $description "Adds two integers and wraps the result to 32 bits." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: ffffffff HEX: 2 w+ ."
+        "1"
+    }
+} ;
+
+HELP: w-
+{ $values
+     { "int" integer } { "int" integer }
+     { "int" integer }
+}
+{ $description "Subtracts two integers and wraps the result to 32 bits." }
+{ $examples
+    { $example "USING: math.bitwise kernel prettyprint ;"
+        "HEX: 0 HEX: ff w- ."
+        "4294967041"
+    }
+} ;
+
+HELP: wrap
+{ $values
+     { "m" integer } { "n" integer }
+     { "m'" integer }
+}
+{ $description "Wraps an integer " { $snippet "m" } " by modding it by " { $snippet "n" } ". This word is uses bitwise arithmetic and does not actually call the modulus word, and as such can only mod by powers of two." }
+{ $examples "Equivalent to modding by 8:"
+    { $example 
+        "USING: math.bitwise prettyprint ;"
+        "HEX: ffff 8 wrap .h"
+        "7"
+    }
+} ;
+
+ARTICLE: "math-bitfields" "Constructing bit fields"
+"Some applications, such as binary communication protocols and assemblers, need to construct integers from elaborate bit field specifications. Hand-coding this using " { $link shift } " and " { $link bitor } " results in repetitive code. A higher-level facility exists to factor out this repetition:"
+{ $subsection bitfield } ;
+
+ARTICLE: "math.bitwise" "Bitwise arithmetic"
+"The " { $vocab-link "math.bitwise" } " vocabulary can implements bitwise arithmetic words that are useful for efficiency, low-level programming, and interfacing with C libraries." $nl
+"Setting and clearing bits:"
+{ $subsection set-bit }
+{ $subsection clear-bit }
+"Testing if bits are set or clear:"
+{ $subsection bit? }
+{ $subsection bit-clear? }
+"Operations with bitmasks:"
+{ $subsection mask }
+{ $subsection unmask }
+{ $subsection mask? }
+{ $subsection unmask? }
+"Generating an integer with n set bits:"
+{ $subsection on-bits }
+"Counting the number of set bits:"
+{ $subsection bit-count }
+"More efficient modding by powers of two:"
+{ $subsection wrap }
+"Bit-rolling:"
+{ $subsection bitroll }
+{ $subsection bitroll-32 }
+{ $subsection bitroll-64 }
+"32-bit arithmetic:"
+{ $subsection w+ }
+{ $subsection w- }
+{ $subsection w* }
+"Bitfields:"
+{ $subsection flags }
+{ $subsection "math-bitfields" } ;
+
+ABOUT: "math.bitwise"
index 8b13cb23b3acf143b12570f01b29d21bc42bfdfe..442299295633dfa3e7f2134a9f8236faa5f46551 100644 (file)
@@ -27,3 +27,5 @@ IN: math.bitwise.tests
 [ 3 ] [ foo ] unit-test
 [ 3 ] [ { a b } flags ] unit-test
 \ foo must-infer
+
+[ 1 ] [ { 1 } flags ] unit-test
index 871f40e74c9d7b9a58ccf9513c3e4717c245bb8f..ad1907fcb0ad97c3dae0f0430b76c090c177b18f 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel math math.functions sequences
 sequences.private words namespaces macros hints
@@ -8,28 +8,29 @@ IN: math.bitwise
 ! utilities
 : clear-bit ( x n -- y ) 2^ bitnot bitand ; inline
 : set-bit ( x n -- y ) 2^ bitor ; inline
-: bit-clear? ( x n -- ? ) 2^ bitand zero? ; inline
+: bit-clear? ( x n -- ? ) 2^ bitand 0 = ; inline
 : unmask ( x n -- ? ) bitnot bitand ; inline
 : unmask? ( x n -- ? ) unmask 0 > ; inline
 : mask ( x n -- ? ) bitand ; inline
 : mask? ( x n -- ? ) mask 0 > ; inline
 : wrap ( m n -- m' ) 1- bitand ; inline
 : bits ( m n -- m' ) 2^ wrap ; inline
-: mask-bit ( m n -- m' ) 1- 2^ mask ; inline
+: mask-bit ( m n -- m' ) 2^ mask ; inline
+: on-bits ( n -- m ) 2^ 1- ; inline
 
 : shift-mod ( n s w -- n )
-    >r shift r> 2^ wrap ; inline
+    [ shift ] dip 2^ wrap ; inline
 
 : bitroll ( x s w -- y )
-     [ wrap ] keep
-     [ shift-mod ]
-     [ [ - ] keep shift-mod ] 3bi bitor ; inline
+    [ wrap ] keep
+    [ shift-mod ]
+    [ [ - ] keep shift-mod ] 3bi bitor ; inline
 
-: bitroll-32 ( n s -- n' ) 32 bitroll ;
+: bitroll-32 ( n s -- n' ) 32 bitroll ; inline
 
 HINTS: bitroll-32 bignum fixnum ;
 
-: bitroll-64 ( n s -- n' ) 64 bitroll ;
+: bitroll-64 ( n s -- n' ) 64 bitroll ; inline
 
 HINTS: bitroll-64 bignum fixnum ;
 
@@ -40,7 +41,7 @@ HINTS: bitroll-64 bignum fixnum ;
 
 ! flags
 MACRO: flags ( values -- )
-    [ 0 ] [ [ execute bitor ] curry compose ] reduce ;
+    [ 0 ] [ [ dup word? [ execute ] when bitor ] curry compose ] reduce ;
 
 ! bitfield
 <PRIVATE
@@ -51,7 +52,7 @@ M: integer (bitfield-quot) ( spec -- quot )
     [ swapd shift bitor ] curry ;
 
 M: pair (bitfield-quot) ( spec -- quot )
-    first2 over word? [ >r swapd execute r> ] [ ] ?
+    first2 over word? [ [ swapd execute ] dip ] [ ] ?
     [ shift bitor ] append 2curry ;
 
 PRIVATE>
@@ -91,4 +92,4 @@ M: bignum (bit-count)
 PRIVATE>
 
 : bit-count ( x -- n )
-    dup 0 >= [ (bit-count) ] [ bitnot (bit-count) ] if ; inline
+    dup 0 < [ bitnot ] when (bit-count) ; inline
index cbaf37daf817452cbff3211252247d9eabcbd5be..a06a67e4a11facbd5026aacf71f27594d70a587e 100644 (file)
@@ -134,3 +134,6 @@ IN: math.functions.tests
 [ -4.0 ] [ -4.4 round ] unit-test
 [ 5.0 ] [ 4.5 round ] unit-test
 [ 4.0 ] [ 4.4 round ] unit-test
+
+[ 6 59967 ] [ 3837888 factor-2s ] unit-test
+[ 6 -59967 ] [ -3837888 factor-2s ] unit-test
index 8516292e9d19467586cb12d4a8ec9de1ddc9d115..43efc35c275179925e56a209333c95b1807edd23 100644 (file)
@@ -1,9 +1,12 @@
-! Copyright (C) 2004, 2007 Slava Pestov.
+! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math kernel math.constants math.private
-math.libm combinators math.order ;
+math.libm combinators math.order sequences ;
 IN: math.functions
 
+: >fraction ( a/b -- a b )
+    [ numerator ] [ denominator ] bi ; inline
+
 <PRIVATE
 
 : (rect>) ( x y -- z )
@@ -30,14 +33,35 @@ M: real sqrt
         2dup >r >r >r odd? r> call r> 2/ r> each-bit
     ] if ; inline recursive
 
-: ^n ( z w -- z^w )
-    1 swap [
-        [ dupd * ] when >r sq r>
-    ] each-bit nip ; inline
+: map-bits ( n quot: ( ? -- obj ) -- seq )
+    accumulator [ each-bit ] dip ; inline
+
+: factor-2s ( n -- r s )
+    #! factor an integer into 2^r * s
+    dup 0 = [ 1 ] [
+        0 swap [ dup even? ] [ [ 1+ ] [ 2/ ] bi* ] [ ] while
+    ] if ; inline
+
+<PRIVATE
+
+GENERIC# ^n 1 ( z w -- z^w )
+
+: (^n) 1 swap [ [ dupd * ] when [ sq ] dip ] each-bit nip ; inline
+
+M: integer ^n
+    [ factor-2s ] dip [ (^n) ] keep rot * shift ;
+
+M: ratio ^n
+    [ >fraction ] dip tuck [ ^n ] 2bi@ / ;
+
+M: float ^n
+    (^n) ;
 
 : integer^ ( x y -- z )
     dup 0 > [ ^n ] [ neg ^n recip ] if ; inline
 
+PRIVATE>
+
 : >rect ( z -- x y )
     [ real-part ] [ imaginary-part ] bi ; inline
 
@@ -52,6 +76,8 @@ M: real sqrt
 
 : polar> ( abs arg -- z ) cis * ; inline
 
+<PRIVATE
+
 : ^mag ( w abs arg -- magnitude )
     >r >r >float-rect swap r> swap fpow r> rot * fexp /f ;
     inline
@@ -68,6 +94,8 @@ M: real sqrt
 : 0^ ( x -- z )
     dup zero? [ drop 0./0. ] [ 0 < 1./0. 0 ? ] if ; inline
 
+PRIVATE>
+
 : ^ ( x y -- z )
     {
         { [ over zero? ] [ nip 0^ ] }
index 0fdcb51291ca9e8bdab1ff9bfcb461fac015a5fd..8c29171a57dd31a153383d4cd16668a70498abfd 100644 (file)
@@ -95,6 +95,10 @@ IN: math.intervals.tests
 
 [ empty-interval ] [ 0 5 (a,b] empty-interval interval-intersect ] unit-test
 
+[ t ] [
+    0 1 (a,b) full-interval interval-intersect 0 1 (a,b) =
+] unit-test
+
 [ t ] [
     empty-interval empty-interval interval-subset?
 ] unit-test
@@ -209,22 +213,28 @@ IN: math.intervals.tests
 
 ! Interval random tester
 : random-element ( interval -- n )
-    dup to>> first over from>> first tuck - random +
-    2dup swap interval-contains? [
-        nip
+    dup full-interval eq? [
+        drop 32 random-bits 31 2^ -
     ] [
-        drop random-element
+        dup to>> first over from>> first tuck - random +
+        2dup swap interval-contains? [
+            nip
+        ] [
+            drop random-element
+        ] if
     ] if ;
 
 : random-interval ( -- interval )
-    2000 random 1000 - dup 2 1000 random + +
-    1 random zero? [ [ neg ] bi@ swap ] when
-    4 random {
-        { 0 [ [a,b] ] }
-        { 1 [ [a,b) ] }
-        { 2 [ (a,b) ] }
-        { 3 [ (a,b] ] }
-    } case ;
+    10 random 0 = [ full-interval ] [
+        2000 random 1000 - dup 2 1000 random + +
+        1 random zero? [ [ neg ] bi@ swap ] when
+        4 random {
+            { 0 [ [a,b] ] }
+            { 1 [ [a,b) ] }
+            { 2 [ (a,b) ] }
+            { 3 [ (a,b] ] }
+        } case
+    ] if ;
 
 : random-unary-op ( -- pair )
     {
@@ -263,7 +273,7 @@ IN: math.intervals.tests
         { bitand interval-bitand }
         { bitor interval-bitor }
         { bitxor interval-bitxor }
-        { shift interval-shift }
+        { shift interval-shift }
         { min interval-min }
         { max interval-max }
     }
index 33430e83c3fb9161b8cfe39d268ff7aabf8cb0e6..54ee0ac894c78c4e502f44ceb83f5bf25c70f82a 100644 (file)
@@ -7,6 +7,8 @@ IN: math.intervals
 
 SYMBOL: empty-interval
 
+SYMBOL: full-interval
+
 TUPLE: interval { from read-only } { to read-only } ;
 
 : <interval> ( from to -- int )
@@ -46,8 +48,7 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : (a,inf] ( a -- interval ) 1./0. (a,b] ; inline
 
-: [-inf,inf] ( -- interval )
-    T{ interval f { -1./0. t } { 1./0. t } } ; inline
+: [-inf,inf] ( -- interval ) full-interval ; inline
 
 : compare-endpoints ( p1 p2 quot -- ? )
     >r over first over first r> call [
@@ -99,8 +100,10 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : do-empty-interval ( i1 i2 quot -- i3 )
     {
-        { [ pick empty-interval eq? ] [ drop drop ] }
+        { [ pick empty-interval eq? ] [ 2drop ] }
         { [ over empty-interval eq? ] [ drop nip ] }
+        { [ pick full-interval eq? ] [ 2drop ] }
+        { [ over full-interval eq? ] [ drop nip ] }
         [ call ]
     } cond ; inline
 
@@ -112,8 +115,10 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : interval-intersect ( i1 i2 -- i3 )
     {
-        { [ dup empty-interval eq? ] [ nip ] }
         { [ over empty-interval eq? ] [ drop ] }
+        { [ dup empty-interval eq? ] [ nip ] }
+        { [ over full-interval eq? ] [ nip ] }
+        { [ dup full-interval eq? ] [ drop ] }
         [
             [ interval>points ] bi@ swapd
             [ [ swap endpoint< ] most ]
@@ -127,8 +132,10 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : interval-union ( i1 i2 -- i3 )
     {
-        { [ dup empty-interval eq? ] [ drop ] }
         { [ over empty-interval eq? ] [ nip ] }
+        { [ dup empty-interval eq? ] [ drop ] }
+        { [ over full-interval eq? ] [ drop ] }
+        { [ dup full-interval eq? ] [ nip ] }
         [ [ interval>points 2array ] bi@ append points>interval ]
     } cond ;
 
@@ -137,9 +144,11 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : interval-contains? ( x int -- ? )
     dup empty-interval eq? [ 2drop f ] [
-        [ from>> first2 [ >= ] [ > ] if ]
-        [ to>>   first2 [ <= ] [ < ] if ]
-        2bi and
+        dup full-interval eq? [ 2drop t ] [
+            [ from>> first2 [ >= ] [ > ] if ]
+            [ to>>   first2 [ <= ] [ < ] if ]
+            2bi and
+        ] if
     ] if ;
 
 : interval-zero? ( int -- ? )
@@ -160,8 +169,11 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : interval-sq ( i1 -- i2 ) dup interval* ;
 
+: special-interval? ( interval -- ? )
+    { empty-interval full-interval } memq? ;
+
 : interval-singleton? ( int -- ? )
-    dup empty-interval eq? [
+    dup special-interval? [
         drop f
     ] [
         interval>points
@@ -173,6 +185,7 @@ TUPLE: interval { from read-only } { to read-only } ;
 : interval-length ( int -- n )
     {
         { [ dup empty-interval eq? ] [ drop 0 ] }
+        { [ dup full-interval eq? ] [ drop 1/0. ] }
         [ interval>points [ first ] bi@ swap - ]
     } cond ;
 
@@ -211,7 +224,7 @@ TUPLE: interval { from read-only } { to read-only } ;
     [ [ interval-closure ] bi@ [ min ] interval-op ] do-empty-interval ;
 
 : interval-interior ( i1 -- i2 )
-    dup empty-interval eq? [
+    dup special-interval? [
         interval>points [ first ] bi@ (a,b)
     ] unless ;
 
@@ -249,6 +262,7 @@ TUPLE: interval { from read-only } { to read-only } ;
 : interval-abs ( i1 -- i2 )
     {
         { [ dup empty-interval eq? ] [ ] }
+        { [ dup full-interval eq? ] [ drop 0 [a,inf] ] }
         { [ 0 over interval-contains? ] [ (interval-abs) { 0 t } suffix points>interval ] }
         [ (interval-abs) points>interval ]
     } cond ;
@@ -292,7 +306,7 @@ SYMBOL: incomparable
 
 : interval< ( i1 i2 -- ? )
     {
-        { [ 2dup [ empty-interval eq? ] either? ] [ incomparable ] }
+        { [ 2dup [ special-interval? ] either? ] [ incomparable ] }
         { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] }
         { [ 2dup left-endpoint-< ] [ f ] }
         { [ 2dup right-endpoint-< ] [ f ] }
@@ -307,7 +321,7 @@ SYMBOL: incomparable
 
 : interval<= ( i1 i2 -- ? )
     {
-        { [ 2dup [ empty-interval eq? ] either? ] [ incomparable ] }
+        { [ 2dup [ special-interval? ] either? ] [ incomparable ] }
         { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] }
         { [ 2dup right-endpoint-<= ] [ t ] }
         [ incomparable ]
@@ -360,27 +374,27 @@ SYMBOL: incomparable
     interval-bitor ;
 
 : assume< ( i1 i2 -- i3 )
-    dup empty-interval eq? [ drop ] [
+    dup special-interval? [ drop ] [
         to>> first [-inf,a) interval-intersect
     ] if ;
 
 : assume<= ( i1 i2 -- i3 )
-    dup empty-interval eq? [ drop ] [
+    dup special-interval? [ drop ] [
         to>> first [-inf,a] interval-intersect
     ] if ;
 
 : assume> ( i1 i2 -- i3 )
-    dup empty-interval eq? [ drop ] [
+    dup special-interval? [ drop ] [
         from>> first (a,inf] interval-intersect
     ] if ;
 
 : assume>= ( i1 i2 -- i3 )
-    dup empty-interval eq? [ drop ] [
+    dup special-interval? [ drop ] [
         from>> first [a,inf] interval-intersect
     ] if ;
 
 : integral-closure ( i1 -- i2 )
-    dup empty-interval eq? [
+    dup special-interval? [
         [ from>> first2 [ 1+ ] unless ]
         [ to>> first2 [ 1- ] unless ]
         bi [a,b]
index 903017e371dbcd0b9a516890b105d743089125a5..7b6393dabe06f9a1939f48f2d73e4901ee3db6cb 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax math math.private
-math.ratios.private ;
+math.ratios.private math.functions ;
 IN: math.ratios
 
 ARTICLE: "rationals" "Rational numbers"
index 5dde4fbb99213d593c1b2ab1ad2718367e24f680..d9dea22b7bd84dc9118873ae0504a52e08925135 100644 (file)
@@ -3,9 +3,6 @@
 USING: accessors kernel kernel.private math math.functions math.private ;
 IN: math.ratios
 
-: >fraction ( a/b -- a b )
-    dup numerator swap denominator ; inline
-
 : 2>fraction ( a/b c/d -- a c b d )
     [ >fraction ] bi@ swapd ; inline
 
index 87981789a7875c1acb40482eaa9d3128735dccfb..b1ea89178bf22f2e09ab3473ec7ef06cd1dc049a 100644 (file)
@@ -9,14 +9,6 @@ HELP: gl-color
 HELP: gl-error
 { $description "If the most recent OpenGL call resulted in an error, print the error to " { $link output-stream } "." } ;
 
-HELP: do-state
-  {
-    $values
-      { "mode" { "One of the " { $link "opengl-geometric-primitives" } } }
-      { "quot" quotation }
-  }
-{ $description "Wraps a quotation in " { $link glBegin } "/" { $link glEnd } " calls." } ;
-
 HELP: do-enabled
 { $values { "what" integer } { "quot" quotation } }
 { $description "Wraps a quotation in " { $link glEnable } "/" { $link glDisable } " calls." } ;
@@ -25,37 +17,17 @@ HELP: do-matrix
 { $values { "mode" { $link GL_MODELVIEW } " or " { $link GL_PROJECTION } } { "quot" quotation } }
 { $description "Saves and restores the matrix specified by " { $snippet "mode" } " before and after calling the quotation." } ;
 
-HELP: gl-vertex
-{ $values { "point" "a pair of integers" } }
-{ $description "Wrapper for " { $link glVertex2d } " taking a point object." } ;
-
 HELP: gl-line
 { $values { "a" "a pair of integers" } { "b" "a pair of integers" } }
 { $description "Draws a line between two points." } ;
 
 HELP: gl-fill-rect
-{ $values { "loc" "a pair of integers" } { "ext" "a pair of integers" } }
-{ $description "Draws a filled rectangle with top-left corner " { $snippet "loc" } " and bottom-right corner " { $snippet "ext" } "." } ;
+{ $values { "dim" "a pair of integers" } }
+{ $description "Draws a filled rectangle with the top-left corner at the origin and the given dimensions." } ;
 
 HELP: gl-rect
-{ $values { "loc" "a pair of integers" } { "ext" "a pair of integers" } }
-{ $description "Draws the outline of a rectangle with top-left corner " { $snippet "loc" } " and bottom-right corner " { $snippet "ext" } "." } ;
-
-HELP: rect-vertices
-{ $values { "lower-left" "A pair of numbers indicating the lower-left coordinates of the rectangle." } { "upper-right" "The upper-right coordinates of the rectangle." } }
-{ $description "Emits" { $link glVertex2d } " calls outlining the axis-aligned rectangle from " { $snippet "lower-left" } " to " { $snippet "upper-right" } " on the z=0 plane in counterclockwise order." } ;
-
-HELP: gl-fill-poly
-{ $values { "points" "a sequence of pairs of integers" } }
-{ $description "Draws a filled polygon." } ;
-
-HELP: gl-poly
-{ $values { "points" "a sequence of pairs of integers" } }
-{ $description "Draws the outline of a polygon." } ;
-
-HELP: gl-gradient
-{ $values { "direction" "an orientation specifier" } { "colors" "a sequence of color specifiers" } { "dim" "a pair of integers" } }
-{ $description "Draws a rectangle with top-left corner " { $snippet "{ 0 0 }" } " and dimensions " { $snippet "dim" } ", filled with a smoothly shaded transition between the colors in " { $snippet "colors" } "." } ;
+{ $values { "dim" "a pair of integers" } }
+{ $description "Draws the outline of a rectangle with the top-left corner at the origin and the given dimensions." } ;
 
 HELP: gen-texture
 { $values { "id" integer } }
@@ -131,12 +103,10 @@ $nl
 { $subsection "opengl-low-level" }
 "Wrappers:"
 { $subsection gl-color }
-{ $subsection gl-vertex }
 { $subsection gl-translate }
 { $subsection gen-texture }
 { $subsection bind-texture-unit }
 "Combinators:"
-{ $subsection do-state }
 { $subsection do-enabled }
 { $subsection do-attribs }
 { $subsection do-matrix }
@@ -146,9 +116,6 @@ $nl
 { $subsection gl-line }
 { $subsection gl-fill-rect }
 { $subsection gl-rect }
-{ $subsection gl-fill-poly }
-{ $subsection gl-poly }
-{ $subsection gl-gradient }
 ;
 
 ABOUT: "gl-utilities"
index bae05f4244b1bbda9a55c6ddedbf7687f15bb32b..64326f340eaf9e9e5b1c327299533fae5b416625 100644 (file)
@@ -2,44 +2,31 @@
 ! Portions copyright (C) 2007 Eduardo Cavazos.
 ! Portions copyright (C) 2008 Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
-
 USING: alien alien.c-types continuations kernel libc math macros
-       namespaces math.vectors math.constants math.functions
-       math.parser opengl.gl opengl.glu combinators arrays sequences
-       splitting words byte-arrays assocs colors accessors ;
-
+namespaces math.vectors math.constants math.functions
+math.parser opengl.gl opengl.glu combinators arrays sequences
+splitting words byte-arrays assocs colors accessors
+generalizations locals memoize ;
 IN: opengl
 
-: coordinates ( point1 point2 -- x1 y2 x2 y2 )
-    [ first2 ] bi@ ;
-
-: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 )
-    [ first2 [ >fixnum ] bi@ ] bi@ ;
+: color>raw ( object -- r g b a )
+    >rgba { [ red>> ] [ green>> ] [ blue>> ] [ alpha>> ] } cleave ; inline
 
-: gl-color ( color -- ) first4 glColor4d ; inline
+: gl-color ( color -- ) color>raw glColor4d ; inline
 
-: gl-clear-color ( color -- )
-    first4 glClearColor ;
+: gl-clear-color ( color -- ) color>raw glClearColor ;
 
 : gl-clear ( color -- )
     gl-clear-color GL_COLOR_BUFFER_BIT glClear ;
 
-: color>raw ( object -- r g b a )
-    >rgba { [ red>> ] [ green>> ] [ blue>> ] [ alpha>> ] } cleave ;
-
-: set-color ( object -- ) color>raw glColor4d ;
-: set-clear-color ( object -- ) color>raw glClearColor ;
-
 : gl-error ( -- )
     glGetError dup zero? [
         "GL error: " over gluErrorString append throw
     ] unless drop ;
 
-: do-state ( mode quot -- )
-    swap glBegin call glEnd ; inline
-
 : do-enabled ( what quot -- )
     over glEnable dip glDisable ; inline
+
 : do-enabled-client-state ( what quot -- )
     over glEnableClientState dip glDisableClientState ; inline
 
@@ -48,6 +35,7 @@ IN: opengl
 
 : (all-enabled) ( seq quot -- )
     over [ glEnable ] each dip [ glDisable ] each ; inline
+
 : (all-enabled-client-state) ( seq quot -- )
     [ dup [ glEnableClientState ] each ] dip
     dip
@@ -55,6 +43,7 @@ IN: opengl
 
 MACRO: all-enabled ( seq quot -- )
     >r words>values r> [ (all-enabled) ] 2curry ;
+
 MACRO: all-enabled-client-state ( seq quot -- )
     >r words>values r> [ (all-enabled-client-state) ] 2curry ;
 
@@ -62,37 +51,57 @@ MACRO: all-enabled-client-state ( seq quot -- )
     swap [ glMatrixMode glPushMatrix call ] keep
     glMatrixMode glPopMatrix ; inline
 
-: gl-vertex ( point -- )
-    dup length {
-        { 2 [ first2 glVertex2d ] }
-        { 3 [ first3 glVertex3d ] }
-        { 4 [ first4 glVertex4d ] }
-    } case ;
-
-: gl-normal ( normal -- ) first3 glNormal3d ;
-
 : gl-material ( face pname params -- )
     >c-float-array glMaterialfv ;
 
+: gl-vertex-pointer ( seq -- )
+    [ 2 GL_FLOAT 0 ] dip glVertexPointer ; inline
+
+: gl-color-pointer ( seq -- )
+    [ 4 GL_FLOAT 0 ] dip glColorPointer ; inline
+
+: gl-texture-coord-pointer ( seq -- )
+    [ 2 GL_FLOAT 0 ] dip glTexCoordPointer ; inline
+
+: line-vertices ( a b -- )
+    append >c-float-array gl-vertex-pointer ;
+
 : gl-line ( a b -- )
-    GL_LINES [ gl-vertex gl-vertex ] do-state ;
+    line-vertices GL_LINES 0 2 glDrawArrays ;
 
-: gl-fill-rect ( loc ext -- )
-    coordinates glRectd ;
+: (rect-vertices) ( dim -- vertices )
+    {
+        [ drop 0 1 ]
+        [ first 1- 1 ]
+        [ [ first 1- ] [ second ] bi ]
+        [ second 0 swap ]
+    } cleave 8 narray >c-float-array ;
 
-: gl-rect ( loc ext -- )
-    GL_FRONT_AND_BACK GL_LINE glPolygonMode
-    >r { 0.5 0.5 } v+ r> { 0.5 0.5 } v- gl-fill-rect
-    GL_FRONT_AND_BACK GL_FILL glPolygonMode ;
+: rect-vertices ( dim -- )
+    (rect-vertices) gl-vertex-pointer ;
 
-: (gl-poly) ( points state -- )
-    [ [ gl-vertex ] each ] do-state ;
+: (gl-rect) ( -- )
+    GL_LINE_LOOP 0 4 glDrawArrays ;
 
-: gl-fill-poly ( points -- )
-    dup length 2 > GL_POLYGON GL_LINES ? (gl-poly) ;
+: gl-rect ( dim -- )
+    rect-vertices (gl-rect) ;
 
-: gl-poly ( points -- )
-    GL_LINE_LOOP (gl-poly) ;
+: (fill-rect-vertices) ( dim -- vertices )
+    {
+        [ drop 0 0 ]
+        [ first 0 ]
+        [ first2 ]
+        [ second 0 swap ]
+    } cleave 8 narray >c-float-array ;
+
+: fill-rect-vertices ( dim -- )
+    (fill-rect-vertices) gl-vertex-pointer ;
+
+: (gl-fill-rect) ( -- )
+    GL_QUADS 0 4 glDrawArrays ;
+
+: gl-fill-rect ( dim -- )
+    fill-rect-vertices (gl-fill-rect) ;
 
 : circle-steps ( steps -- angles )
     dup length v/n 2 pi * v*n ;
@@ -109,35 +118,24 @@ MACRO: all-enabled-client-state ( seq quot -- )
 : circle-points ( loc dim steps -- points )
     circle-steps unit-circle adjust-points scale-points ;
 
-: gl-circle ( loc dim steps -- )
-    circle-points gl-poly ;
-
-: gl-fill-circle ( loc dim steps -- )
-    circle-points gl-fill-poly ;
-
-: prepare-gradient ( direction dim -- v1 v2 )
-    tuck v* [ v- ] keep ;
-
-: gl-gradient ( direction colors dim -- )
-    GL_QUAD_STRIP [
-        swap >r prepare-gradient r>
-        [ length dup 1- v/n ] keep [
-            >r >r 2dup r> r> set-color v*n
-            dup gl-vertex v+ gl-vertex
-        ] 2each 2drop
-    ] do-state ;
+: circle-vertices ( loc dim steps -- vertices )
+    circle-points concat >c-float-array ;
 
 : (gen-gl-object) ( quot -- id )
     >r 1 0 <uint> r> keep *uint ; inline
+
 : gen-texture ( -- id )
     [ glGenTextures ] (gen-gl-object) ;
+
 : gen-gl-buffer ( -- id )
     [ glGenBuffers ] (gen-gl-object) ;
 
 : (delete-gl-object) ( id quot -- )
     >r 1 swap <uint> r> call ; inline
+
 : delete-texture ( id -- )
     [ glDeleteTextures ] (delete-gl-object) ;
+
 : delete-gl-buffer ( id -- )
     [ glDeleteBuffers ] (delete-gl-object) ;
 
@@ -205,35 +203,21 @@ TUPLE: sprite loc dim dim2 dlist texture ;
 
 : gl-translate ( point -- ) first2 0.0 glTranslated ;
 
-<PRIVATE
-
-: top-left drop 0 0 glTexCoord2i 0.0 0.0 glVertex2d ; inline
-
-: top-right 1 0 glTexCoord2i first 0.0 glVertex2d ; inline
-
-: bottom-left 0 1 glTexCoord2i second 0.0 swap glVertex2d ; inline
-
-: bottom-right 1 1 glTexCoord2i gl-vertex ; inline
+MEMO: (rect-texture-coords) ( -- seq )
+    { 0 0 1 0 1 1 0 1 } >c-float-array ;
 
-PRIVATE>
-
-: four-sides ( dim -- )
-    dup top-left dup top-right dup bottom-right bottom-left ;
+: rect-texture-coords ( -- )
+    (rect-texture-coords) gl-texture-coord-pointer ;
 
 : draw-sprite ( sprite -- )
-    dup loc>> gl-translate
-    GL_TEXTURE_2D over texture>> glBindTexture
-    init-texture
-    GL_QUADS [ dim2>> four-sides ] do-state
-    GL_TEXTURE_2D 0 glBindTexture ;
-
-: rect-vertices ( lower-left upper-right -- )
-    GL_QUADS [
-        over first2 glVertex2d
-        dup first pick second glVertex2d
-        dup first2 glVertex2d
-        swap first swap second glVertex2d
-    ] do-state ;
+    GL_TEXTURE_COORD_ARRAY [
+        dup loc>> gl-translate
+        GL_TEXTURE_2D over texture>> glBindTexture
+        init-texture rect-texture-coords
+        dim2>> fill-rect-vertices
+        (gl-fill-rect)
+        GL_TEXTURE_2D 0 glBindTexture
+    ] do-enabled-client-state ;
 
 : make-sprite-dlist ( sprite -- id )
     GL_MODELVIEW [
@@ -256,6 +240,9 @@ PRIVATE>
 : with-translation ( loc quot -- )
     GL_MODELVIEW [ >r gl-translate r> call ] do-matrix ; inline
 
+: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 )
+    [ first2 [ >fixnum ] bi@ ] bi@ ;
+
 : gl-set-clip ( loc dim -- )
     fix-coordinates glScissor ;
 
index 776450ccd98443db593f7028236df5af3082b9b2..ccae0fec930aff5a9bfe746adcc95ea06aca77cf 100644 (file)
@@ -487,7 +487,7 @@ M: ebnf-terminal (transform) ( ast -- parser )
 M: ebnf-foreign (transform) ( ast -- parser )\r
   dup word>> search\r
   [ "Foreign word '" swap word>> append "' not found" append throw ] unless*\r
-  swap rule>> [ main ] unless* dupd swap rule [\r
+  swap rule>> [ main ] unless* over rule [\r
     nip\r
   ] [\r
     execute\r
index a867dbb2e31859e059f01b1e92f5ebc6fa5684bb..e50fd52c1051eb52391929295546f852deb2475b 100644 (file)
@@ -53,3 +53,6 @@ M: persistent-hash clone ;
 M: persistent-hash pprint-delims drop \ PH{ \ } ;
 M: persistent-hash >pprint-sequence >alist ;
 M: persistent-hash pprint* pprint-object ;
+
+: passociate ( value key -- phash )
+    T{ persistent-hash } new-at ; inline
index 961e8bfce748508f5256b65b7a95f371c40f6702..5503e369b4699f89b048802c0d0e0eb7cec54f35 100644 (file)
@@ -14,3 +14,6 @@ M: sequence ppop 1 head* ;
 GENERIC: new-nth ( val i seq -- seq' )
 
 M: sequence new-nth clone [ set-nth ] keep ;
+
+: changed-nth ( i seq quot -- seq' )
+    [ [ nth ] dip call ] [ drop new-nth ] 3bi ; inline
index b749bd63eb83b575a96293cfa44a619067fabb0c..31b6ba3f2612de4c42224c190b4ce5c496c2522c 100644 (file)
@@ -214,6 +214,7 @@ M: tuple pprint-narrow? drop t ;
 
 M: object pprint* pprint-object ;
 M: vector pprint* pprint-object ;
+M: byte-vector pprint* pprint-object ;
 M: hashtable pprint* pprint-object ;
 
 M: curry pprint*
index 44cf5f724fea12c1045bd38c29ce870ec967dfa4..159421c18c94c6a6a033aa3e1ccced768a987c90 100644 (file)
@@ -1,6 +1,6 @@
 USING: prettyprint.backend prettyprint.config
 prettyprint.sections prettyprint.private help.markup help.syntax
-io kernel words definitions quotations strings ;
+io kernel words definitions quotations strings generic classes ;
 IN: prettyprint
 
 ARTICLE: "prettyprint-numbers" "Prettyprinting numbers"
@@ -150,6 +150,8 @@ $nl
 { $subsection pprint-cell }
 "Printing a definition (see " { $link "definitions" } "):"
 { $subsection see }
+"Printing the methods defined on a generic word or class (see " { $link "objects" } "):"
+{ $subsection see-methods }
 "More prettyprinter usage:"
 { $subsection "prettyprint-numbers" }
 { $subsection "prettyprint-stacks" }
@@ -167,17 +169,26 @@ HELP: with-pprint
 
 HELP: pprint
 { $values { "obj" object } }
-{ $description "Prettyprints an object to " { $link output-stream } ". Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ;
+{ $description "Prettyprints an object to " { $link output-stream } ". Output is influenced by many variables; see " { $link "prettyprint-variables" } "." }
+{ $warning
+    "Unparsing a large object can take a long time and consume a lot of memory. If you need to print large objects, use " { $link pprint-short } " or set some " { $link "prettyprint-variables" } " to limit output size."
+} ;
 
 { pprint pprint* with-pprint } related-words
 
 HELP: .
 { $values { "obj" object } }
-{ $description "Prettyprints an object to " { $link output-stream } " with a trailing line break. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ;
+{ $description "Prettyprints an object to " { $link output-stream } " with a trailing line break. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." }
+{ $warning
+    "Printing a large object can take a long time and consume a lot of memory. If you need to print large objects, use " { $link short. } " or set some " { $link "prettyprint-variables" } " to limit output size."
+} ;
 
 HELP: unparse
 { $values { "obj" object } { "str" "Factor source string" } }
-{ $description "Outputs a prettyprinted string representation of an object. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ;
+{ $description "Outputs a prettyprinted string representation of an object. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." }
+{ $warning
+    "Unparsing a large object can take a long time and consume a lot of memory. If you need to unparse large objects, use " { $link unparse-short } " or set some " { $link "prettyprint-variables" } " to limit output size."
+} ;
 
 HELP: pprint-short
 { $values { "obj" object } }
@@ -240,6 +251,10 @@ HELP: see
 { $values { "defspec" "a definition specifier" } }
 { $contract "Prettyprints a definition." } ;
 
+HELP: see-methods
+{ $values { "word" "a " { $link generic } " or a " { $link class } } }
+{ $contract "Prettyprints the methods defined on a generic word or class." } ;
+
 HELP: definer
 { $values { "defspec" "a definition specifier" } { "start" word } { "end" "a word or " { $link f } } }
 { $contract "Outputs the parsing words which delimit the definition." }
index d62f696a7490c9bc5e0e443f48a264bf025cbaab..067d221d2fc571e5703d4d88549a3b639d286287 100644 (file)
@@ -32,3 +32,14 @@ HELP: RENAME:
     "RENAME: + math => -"
     "2 3 - ! => 5" } } ;
 
+ARTICLE: "qualified" "Qualified word lookup"
+"The " { $vocab-link "qualified" } " vocabulary provides a handful of parsing words which give more control over word lookup than is offered by " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } "."
+$nl
+"These words are useful when there is no way to avoid using two vocabularies with identical word names in the same source file."
+{ $subsection POSTPONE: QUALIFIED: }
+{ $subsection POSTPONE: QUALIFIED-WITH: }
+{ $subsection POSTPONE: FROM: }
+{ $subsection POSTPONE: EXCLUDE: }
+{ $subsection POSTPONE: RENAME: } ;
+
+ABOUT: "qualified"
index 8f67ddf7309dfa3d78fac6ca7f6d06223a1de5d5..78efec4861d4b891552214c0ad949e6a94d9895b 100644 (file)
@@ -1,24 +1,33 @@
-USING: tools.test qualified ;
-IN: foo
+USING: tools.test qualified eval accessors parser ;
+IN: qualified.tests.foo
 : x 1 ;
-IN: bar
+: y 5 ;
+IN: qualified.tests.bar
 : x 2 ;
-IN: baz
+: y 4 ;
+IN: qualified.tests.baz
 : x 3 ;
 
-QUALIFIED: foo
-QUALIFIED: bar
-[ 1 2 3 ] [ foo:x bar:x x ] unit-test
+QUALIFIED: qualified.tests.foo
+QUALIFIED: qualified.tests.bar
+[ 1 2 3 ] [ qualified.tests.foo:x qualified.tests.bar:x x ] unit-test
 
-QUALIFIED-WITH: bar p
+QUALIFIED-WITH: qualified.tests.bar p
 [ 2 ] [ p:x ] unit-test
 
-RENAME: x baz => y
+RENAME: x qualified.tests.baz => y
 [ 3 ] [ y ] unit-test
 
-FROM: baz => x ;
+FROM: qualified.tests.baz => x ;
 [ 3 ] [ x ] unit-test
+[ 3 ] [ y ] unit-test
 
-EXCLUDE: bar => x ;
+EXCLUDE: qualified.tests.bar => x ;
 [ 3 ] [ x ] unit-test
+[ 4 ] [ y ] unit-test
+
+[ "USE: qualified IN: qualified.tests FROM: qualified.tests => doesnotexist ;" eval ]
+[ error>> no-word-error? ] must-fail-with
 
+[ "USE: qualified IN: qualified.tests RENAME: doesnotexist qualified.tests => blah" eval ]
+[ error>> no-word-error? ] must-fail-with
index d636cc01526d8069e3a74936e3ac426458952b16..d387ef4b0ecf8b7eb01b215fb6700ea73a52feea 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2007, 2008 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences assocs hashtables parser lexer
-vocabs words namespaces vocabs.loader debugger sets ;
+vocabs words namespaces vocabs.loader debugger sets fry ;
 IN: qualified
 
 : define-qualified ( vocab-name prefix-name -- )
     [ load-vocab vocab-words ] [ CHAR: : suffix ] bi*
-    [ -rot >r append r> ] curry assoc-map
+    '[ [ [ _ ] dip append ] dip ] assoc-map
     use get push ;
 
 : QUALIFIED:
@@ -19,27 +19,27 @@ IN: qualified
 
 : expect=> ( -- ) scan "=>" assert= ;
 
-: partial-vocab ( words name -- assoc )
-    dupd [
-        lookup [ "No such word: " swap append throw ] unless*
-    ] curry map zip ;
+: partial-vocab ( words vocab -- assoc )
+    '[ dup _ lookup [ no-word-error ] unless* ]
+    { } map>assoc ;
 
-: partial-vocab-ignoring ( words name -- assoc )
+: FROM:
+    #! Syntax: FROM: vocab => words... ;
+    scan dup load-vocab drop expect=>
+    ";" parse-tokens swap partial-vocab use get push ; parsing
+
+: partial-vocab-excluding ( words vocab -- assoc )
     [ load-vocab vocab-words keys swap diff ] keep partial-vocab ;
 
 : EXCLUDE:
     #! Syntax: EXCLUDE: vocab => words ... ;
     scan expect=>
-    ";" parse-tokens swap partial-vocab-ignoring use get push ; parsing
-
-: FROM:
-    #! Syntax: FROM: vocab => words... ;
-    scan dup load-vocab drop expect=>
-    ";" parse-tokens swap partial-vocab use get push ; parsing
+    ";" parse-tokens swap partial-vocab-excluding use get push ; parsing
 
 : RENAME:
     #! Syntax: RENAME: word vocab => newname
-    scan scan dup load-vocab drop lookup [ "No such word" throw ] unless*
+    scan scan dup load-vocab drop
+    dupd lookup [ ] [ no-word-error ] ?if
     expect=>
     scan associate use get push ; parsing
 
index 712883e4b8e440fe7c5d4ab622a9a7351e1fc682..c31d338fac84672c5a5467666790b3b183a4987e 100644 (file)
@@ -16,7 +16,7 @@ TUPLE: mersenne-twister seq i ;
 : mt-a HEX: 9908b0df ; inline
 
 : calculate-y ( n seq -- y )
-    [ nth 32 mask-bit ]
+    [ nth 31 mask-bit ]
     [ [ 1+ ] [ nth ] bi* 31 bits ] 2bi bitor ; inline
 
 : (mt-generate) ( n seq -- next-mt )
index a0b62cf7de59aecb0729e36fc6e1191cc4501a5f..5c93606ab5eda41355a9feb93317b736c7f268b4 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types kernel math namespaces sequences
 io.backend io.binary combinators system vocabs.loader
-summary math.bitwise ;
+summary math.bitwise byte-vectors fry byte-arrays ;
 IN: random
 
 SYMBOL: system-random-generator
@@ -14,7 +14,12 @@ GENERIC: random-32* ( tuple -- r )
 GENERIC: random-bytes* ( n tuple -- byte-array )
 
 M: object random-bytes* ( n tuple -- byte-array )
-    [ random-32* ] curry replicate [ 4 >le ] map concat ;
+    [ [ <byte-vector> ] keep 4 /mod ] dip tuck
+    [ pick '[ _ random-32* 4 >le _ push-all ] times ]
+    [
+        over zero?
+        [ 2drop ] [ random-32* 4 >le swap head over push-all ] if
+    ] 2bi* ;
 
 M: object random-32* ( tuple -- r ) 4 random-bytes* le> ;
 
@@ -28,16 +33,13 @@ M: f random-bytes* ( n obj -- * ) no-random-number-generator ;
 M: f random-32* ( obj -- * ) no-random-number-generator ;
 
 : random-bytes ( n -- byte-array )
-    [
-        dup 3 mask zero? [ 1+ ] unless
-        random-generator get random-bytes*
-    ] keep head ;
+    random-generator get random-bytes* ;
 
 <PRIVATE
 
 : random-integer ( n -- n' )
     dup log2 7 + 8 /i 1+
-    [ random-bytes byte-array>bignum ]
+    [ random-bytes >byte-array byte-array>bignum ]
     [ 3 shift 2^ ] bi / * >integer ;
 
 PRIVATE>
index 3ab2d731fe756759e305e10a908d1674eb291abf..93a2a0fa14feb0cf954f1ecbb1e77cc463fbe155 100644 (file)
@@ -1,2 +1,3 @@
 collections
 text
+algorithms
index 42d711b32ba66957d114e76b2aedcc5a59c9c58a..1e3d675068069c79aa420adc0a2e43d7814a6f10 100644 (file)
@@ -1 +1,2 @@
 collections
+algorithms
diff --git a/basis/stack-checker/backend/backend-tests.factor b/basis/stack-checker/backend/backend-tests.factor
new file mode 100644 (file)
index 0000000..3bbba0f
--- /dev/null
@@ -0,0 +1,22 @@
+USING: stack-checker.backend tools.test kernel namespaces
+stack-checker.state sequences ;
+IN: stack-checker.backend.tests
+
+[ ] [
+    V{ } clone meta-d set
+    V{ } clone meta-r set
+    0 d-in set
+] unit-test
+
+[ 0 ] [ 0 ensure-d length ] unit-test
+
+[ 2 ] [ 2 ensure-d length ] unit-test
+[ 2 ] [ meta-d get length ] unit-test
+
+[ 3 ] [ 3 ensure-d length ] unit-test
+[ 3 ] [ meta-d get length ] unit-test
+
+[ 1 ] [ 1 ensure-d length ] unit-test
+[ 3 ] [ meta-d get length ] unit-test
+
+[ ] [ 1 consume-d drop ] unit-test
index f8dec5f823c84cc079e95edd40c264206ffd087f..94e59950f74f20d5778171175716e93b9b582aca 100644 (file)
@@ -5,7 +5,8 @@ namespaces parser prettyprint sequences strings vectors words
 quotations effects classes continuations debugger assocs
 combinators compiler.errors accessors math.order definitions
 sets generic.standard.engines.tuple stack-checker.state
-stack-checker.visitor stack-checker.errors ;
+stack-checker.visitor stack-checker.errors
+stack-checker.values stack-checker.recursive-state ;
 IN: stack-checker.backend
 
 : push-d ( obj -- ) meta-d get push ;
@@ -17,14 +18,24 @@ IN: stack-checker.backend
 
 : peek-d ( -- obj ) pop-d dup push-d ;
 
-: consume-d ( n -- seq ) [ pop-d ] replicate reverse ;
+: make-values ( n -- values )
+    [ <value> ] replicate ;
 
-: output-d ( values -- ) meta-d get push-all ;
+: ensure-d ( n -- values )
+    meta-d get 2dup length > [
+        2dup
+        [ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
+        [ length d-in +@ ] [ #introduce, ] [ meta-d get push-all ] tri
+        meta-d get push-all
+    ] when swap tail* ;
 
-: ensure-d ( n -- values ) consume-d dup output-d ;
+: shorten-by ( n seq -- )
+    [ length swap - ] keep shorten ; inline
 
-: make-values ( n -- values )
-    [ <value> ] replicate ;
+: consume-d ( n -- seq )
+    [ ensure-d ] [ meta-d get shorten-by ] bi ;
+
+: output-d ( values -- ) meta-d get push-all ;
 
 : produce-d ( n -- values )
     make-values dup meta-d get push-all ;
@@ -35,7 +46,10 @@ IN: stack-checker.backend
     meta-r get dup empty?
     [ too-many-r> inference-error ] [ pop ] if ;
 
-: consume-r ( n -- seq ) [ pop-r ] replicate reverse ;
+: consume-r ( n -- seq )
+    meta-r get 2dup length >
+    [ too-many-r> inference-error ] when
+    [ swap tail* ] [ shorten-by ] 2bi ;
 
 : output-r ( seq -- ) meta-r get push-all ;
 
@@ -69,9 +83,6 @@ M: object apply-object push-literal ;
         infer-quot-here
     ] dip recursive-state set ;
 
-: infer-quot-recursive ( quot word label -- )
-    2array recursive-state get swap prefix infer-quot ;
-
 : time-bomb ( error -- )
     '[ _ throw ] infer-quot-here ;
 
@@ -84,7 +95,7 @@ M: object apply-object push-literal ;
     ] [
         dup value>> callable? [
             [ value>> ]
-            [ [ recursion>> ] keep f 2array prefix ]
+            [ [ recursion>> ] keep add-local-quotation ]
             bi infer-quot
         ] [
             drop bad-call
@@ -113,6 +124,9 @@ M: object apply-object push-literal ;
         terminated?>> [ terminate ] when
     ] 2bi ; inline
 
+: infer-word-def ( word -- )
+    [ def>> ] [ add-recursive-state ] bi infer-quot ;
+
 : check->r ( -- )
     meta-r get empty? terminated? get or
     [ \ too-many->r inference-error ] unless ;
@@ -161,7 +175,7 @@ M: object apply-object push-literal ;
             stack-visitor off
             dependencies off
             generic-dependencies off
-            [ [ def>> ] [ ] [ ] tri infer-quot-recursive end-infer ]
+            [ infer-word-def end-infer ]
             [ finish-word current-effect ]
             bi
         ] with-scope
index d1417d035ce64c461b35948fe74d24bd79cfe845..7b461d0028bbde2f9653fec50eb32c27e380bd34 100644 (file)
@@ -3,7 +3,7 @@
 USING: fry vectors sequences assocs math accessors kernel
 combinators quotations namespaces stack-checker.state
 stack-checker.backend stack-checker.errors stack-checker.visitor
-;
+stack-checker.values stack-checker.recursive-state ;
 IN: stack-checker.branches
 
 : balanced? ( pairs -- ? )
index bab6c17c85e93151037cf61ba272643e3f2e6615..efdc7e23b2e0e1e7a77d2b91d83c68098d747a06 100644 (file)
@@ -2,12 +2,11 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel generic sequences prettyprint io words arrays
 summary effects debugger assocs accessors namespaces
-compiler.errors ;
+compiler.errors stack-checker.values
+stack-checker.recursive-state ;
 IN: stack-checker.errors
 
-SYMBOL: recursive-state
-
-TUPLE: inference-error error type rstate ;
+TUPLE: inference-error error type word ;
 
 M: inference-error compiler-error-type type>> ;
 
@@ -15,7 +14,7 @@ M: inference-error error-help error>> error-help ;
 
 : (inference-error) ( ... class type -- * )
     >r boa r>
-    recursive-state get
+    recursive-state get word>>
     \ inference-error boa throw ; inline
 
 : inference-error ( ... class -- * )
@@ -25,16 +24,15 @@ M: inference-error error-help error>> error-help ;
     +warning+ (inference-error) ; inline
 
 M: inference-error error.
-    [
-        rstate>>
-        [ "Nesting:" print stack. ] unless-empty
-    ] [ error>> error. ] bi ;
+    [ "In word: " write word>> . ] [ error>> error. ] bi ;
 
 TUPLE: literal-expected ;
 
 M: literal-expected summary
     drop "Literal value expected" ;
 
+M: object (literal) \ literal-expected inference-warning ;
+
 TUPLE: unbalanced-branches-error branches quots ;
 
 : unbalanced-branches-error ( branches quots -- * )
index 7847fdfdcf194d4db13e226e53c205dcd814d917..b6a988652b8415a648b5e27f3d4ae02f7dae7277 100644 (file)
@@ -4,18 +4,20 @@ USING: fry namespaces assocs kernel sequences words accessors
 definitions math math.order effects classes arrays combinators
 vectors arrays
 stack-checker.state
+stack-checker.errors
+stack-checker.values
 stack-checker.visitor
 stack-checker.backend
 stack-checker.branches
-stack-checker.errors
-stack-checker.known-words ;
+stack-checker.known-words
+stack-checker.recursive-state ;
 IN: stack-checker.inlining
 
 ! Code to handle inline words. Much of the complexity stems from
 ! having to handle recursive inline words.
 
-: (inline-word) ( word label -- )
-    [ [ def>> ] keep ] dip infer-quot-recursive ;
+: infer-inline-word-def ( word label -- )
+    [ drop def>> ] [ add-inline-word ] 2bi infer-quot ;
 
 TUPLE: inline-recursive < identity-tuple
 id
@@ -88,7 +90,7 @@ SYMBOL: enter-out
         nest-visitor
 
         dup <inline-recursive>
-        [ dup emit-enter-recursive (inline-word) ]
+        [ dup emit-enter-recursive infer-inline-word-def ]
         [ end-recursive-word ]
         [ nip ]
         2tri
@@ -133,20 +135,23 @@ SYMBOL: enter-out
     object <repetition> '[ _ prepend ] bi@
     <effect> ;
 
-: call-recursive-inline-word ( word -- )
-    dup "recursive" word-prop [
-        [ required-stack-effect adjust-stack-effect ] [ ] [ recursive-label ] tri
-        [ 2nip check-call ] [ nip '[ _ #call-recursive, ] consume/produce ] 3bi
-    ] [ undeclared-recursion-error inference-error ] if ;
+: call-recursive-inline-word ( word label -- )
+    over "recursive" word-prop [
+        [ required-stack-effect adjust-stack-effect ] dip
+        [ check-call ] [ '[ _ #call-recursive, ] consume/produce ] bi
+    ] [ drop undeclared-recursion-error inference-error ] if ;
 
 : inline-word ( word -- )
     [ inlined-dependency depends-on ]
     [
-        {
-            { [ dup inline-recursive-label ] [ call-recursive-inline-word ] }
-            { [ dup "recursive" word-prop ] [ inline-recursive-word ] }
-            [ dup (inline-word) ]
-        } cond
+        dup inline-recursive-label [
+            call-recursive-inline-word
+        ] [
+            dup "recursive" word-prop
+            [ inline-recursive-word ]
+            [ dup infer-inline-word-def ]
+            if
+        ] if*
     ] bi ;
 
 M: word apply-object
index c40b94fd3ce757b2a5fb35aacceb9fc3476477b3..4aea0f2d28129a0388642661ccbd1a18d0d51846 100644 (file)
@@ -10,14 +10,16 @@ sequences sequences.private slots.private strings
 strings.private system threads.private classes.tuple
 classes.tuple.private vectors vectors.private words definitions
 words.private assocs summary compiler.units system.private
-combinators locals.backend words.private quotations.private
+combinators locals locals.backend locals.private words.private
+quotations.private stack-checker.values
+stack-checker.alien
 stack-checker.state
+stack-checker.errors
+stack-checker.visitor
 stack-checker.backend
 stack-checker.branches
-stack-checker.errors
 stack-checker.transforms
-stack-checker.visitor
-stack-checker.alien ;
+stack-checker.recursive-state ;
 IN: stack-checker.known-words
 
 : infer-primitive ( word -- )
@@ -48,7 +50,7 @@ IN: stack-checker.known-words
 : infer-shuffle ( shuffle -- )
     [ in>> length consume-d ] keep ! inputs shuffle
     [ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
-    [ nip ] [ swap zip ] 2bi ! inputs copies mapping
+    [ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
     #shuffle, ;
 
 : infer-shuffle-word ( word -- )
@@ -123,21 +125,23 @@ M: object infer-call*
 
 : infer-load-locals ( -- )
     pop-literal nip
-    [ dup reverse <effect> infer-shuffle ]
-    [ infer->r ]
-    bi ;
+    consume-d dup reverse copy-values dup output-r
+    [ [ f f ] dip ] [ reverse swap zip ] 2bi #shuffle, ;
 
 : infer-get-local ( -- )
-    pop-literal nip
-    [ infer-r> ]
-    [ dup 0 prefix <effect> infer-shuffle ]
-    [ infer->r ]
-    tri ;
+    [let* | n [ pop-literal nip ]
+            in-r [ n consume-r ]
+            out-d [ in-r first copy-value 1array ]
+            out-r [ in-r copy-values ] |
+         out-d output-d
+         out-r output-r
+         f out-d in-r out-r
+         out-r in-r zip out-d first in-r first 2array suffix
+         #shuffle,
+    ] ;
 
 : infer-drop-locals ( -- )
-    pop-literal nip
-    [ infer-r> ]
-    [ { } <effect> infer-shuffle ] bi ;
+    f f pop-literal nip consume-r f f #shuffle, ;
 
 : infer-special ( word -- )
     {
@@ -164,6 +168,12 @@ M: object infer-call*
         { \ alien-callback [ infer-alien-callback ] }
     } case ;
 
+: infer-local-reader ( word -- )
+    (( -- value )) apply-word/effect ;
+
+: infer-local-writer ( word -- )
+    (( value -- )) apply-word/effect ;
+
 {
     >r r> declare call (call) curry compose execute (execute) if
 dispatch <tuple-boa> (throw) load-locals get-local drop-locals
@@ -183,7 +193,10 @@ do-primitive alien-invoke alien-indirect alien-callback
         { [ dup "macro" word-prop ] [ apply-macro ] }
         { [ dup "cannot-infer" word-prop ] [ cannot-infer-effect ] }
         { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
-        { [ dup recursive-label ] [ call-recursive-word ] }
+        { [ dup local? ] [ infer-local-reader ] }
+        { [ dup local-reader? ] [ infer-local-reader ] }
+        { [ dup local-writer? ] [ infer-local-writer ] }
+        { [ dup recursive-word? ] [ call-recursive-word ] }
         [ dup infer-word apply-word/effect ]
     } cond ;
 
diff --git a/basis/stack-checker/recursive-state/recursive-state.factor b/basis/stack-checker/recursive-state/recursive-state.factor
new file mode 100644 (file)
index 0000000..41d7331
--- /dev/null
@@ -0,0 +1,43 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays sequences kernel sequences assocs
+namespaces stack-checker.recursive-state.tree ;
+IN: stack-checker.recursive-state
+
+TUPLE: recursive-state words word quotations inline-words ;
+
+C: <recursive-state> recursive-state
+
+: prepare-recursive-state ( word rstate -- rstate )
+    swap >>word
+    f >>quotations
+    f >>inline-words ; inline
+
+: initial-recursive-state ( word -- state )
+    recursive-state new
+        f >>words
+        prepare-recursive-state ; inline
+
+f initial-recursive-state recursive-state set-global
+
+: add-recursive-state ( word -- rstate )
+    recursive-state get clone
+        [ word>> dup ] keep [ store ] change-words
+        prepare-recursive-state ;
+
+: add-local-quotation ( recursive-state quot -- rstate )
+    swap clone [ dupd store ] change-quotations ;
+
+: add-inline-word ( word label -- rstate )
+    swap recursive-state get clone
+    [ store ] change-inline-words ;
+
+: recursive-word? ( word -- ? )
+    recursive-state get 2dup word>> eq?
+    [ 2drop t ] [ words>> lookup ] if ;
+
+: inline-recursive-label ( word -- label/f )
+    recursive-state get inline-words>> lookup ;
+
+: recursive-quotation? ( quot -- ? )
+    recursive-state get quotations>> lookup ;
diff --git a/basis/stack-checker/recursive-state/tree/tree.factor b/basis/stack-checker/recursive-state/tree/tree.factor
new file mode 100644 (file)
index 0000000..dd392af
--- /dev/null
@@ -0,0 +1,31 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel sequences math math.order ;
+IN: stack-checker.recursive-state.tree
+
+! Persistent unbalanced hash tree using eq? comparison.
+! We use this to speed up stack-checker.recursive-state.
+! Perhaps this should go somewhere else
+
+TUPLE: node value key hashcode left right ;
+
+GENERIC: lookup ( key node -- value/f )
+
+M: f lookup nip ;
+
+: decide ( key node -- key node ? )
+    over hashcode over hashcode>> <= ; inline
+
+M: node lookup
+    2dup key>> eq?
+    [ nip value>> ]
+    [ decide [ left>> ] [ right>> ] if lookup ] if ;
+
+GENERIC: store ( value key node -- node' )
+
+M: f store drop dup hashcode f f node boa ;
+
+M: node store
+    clone decide
+    [ [ store ] change-left ]
+    [ [ store ] change-right ] if ;
index a9df463703465d0929b61a83b58ff1147b9c349f..f208178b10f335d239341c46ba7c59983100c417 100644 (file)
@@ -27,7 +27,7 @@ ARTICLE: "inference-combinators" "Combinator stack effects"
 "Consider a combinator such as " { $link keep } ". The combinator itself does not have a stack effect, because it applies " { $link call } " to a potentially arbitrary quotation. However, since the combinator is declared " { $link POSTPONE: inline } ", a given usage of it can have a stack effect:"
 { $example "[ [ 2 + ] keep ] infer." "( object -- object object )" }
 "Another example is the " { $link compose } " combinator. Because it is decared " { $link POSTPONE: inline } ", we can infer the stack effect of applying " { $link call } " to the result of " { $link compose } ":"
-{ $example "[ 2 [ + ] curry [ sq ] compose ] infer." "( -- object object )" }
+{ $example "[ 2 [ + ] curry [ sq ] compose ] infer." "( -- object )" }
 "Incidentally, this example demonstrates that the stack effect of nested currying and composition can also be inferred."
 $nl
 "A general rule of thumb is that any word which applies " { $link call } " or " { $link curry } " to one of its inputs must be declared " { $link POSTPONE: inline } "."
index 11dc6f9ef8d1cceb34d5f66f068f4ead7cb10727..2706ec60ef490782c7da033dfb5f1bac5e27e665 100644 (file)
@@ -1,48 +1,10 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs namespaces sequences kernel definitions math
-effects accessors words fry classes.algebra stack-checker.errors
+USING: assocs arrays namespaces sequences kernel definitions
+math effects accessors words fry classes.algebra
 compiler.units ;
 IN: stack-checker.state
 
-: <value> ( -- value ) \ <value> counter ;
-
-SYMBOL: known-values
-
-: known ( value -- known ) known-values get at ;
-
-: set-known ( known value -- )
-    over [ known-values get set-at ] [ 2drop ] if ;
-
-: make-known ( known -- value )
-    <value> [ set-known ] keep ;
-
-: copy-value ( value -- value' )
-    known make-known ;
-
-: copy-values ( values -- values' )
-    [ copy-value ] map ;
-
-! Literal value
-TUPLE: literal < identity-tuple value recursion ;
-
-: <literal> ( obj -- value )
-    recursive-state get \ literal boa ;
-
-: literal ( value -- literal )
-    known dup literal?
-    [  \ literal-expected inference-warning ] unless ;
-
-! Result of curry
-TUPLE: curried obj quot ;
-
-C: <curried> curried
-
-! Result of compose
-TUPLE: composed quot1 quot2 ;
-
-C: <composed> composed
-
 ! Did the current control-flow path throw an error?
 SYMBOL: terminated?
 
@@ -68,23 +30,6 @@ SYMBOL: meta-r
     V{ } clone meta-r set
     0 d-in set ;
 
-: init-known-values ( -- )
-    H{ } clone known-values set ;
-
-: recursive-label ( word -- label/f )
-    recursive-state get at ;
-
-: local-recursive-state ( -- assoc )
-    recursive-state get dup
-    [ first dup word? [ inline? ] when not ] find drop
-    [ head-slice ] when* ;
-
-: inline-recursive-label ( word -- label/f )
-    local-recursive-state at ;
-
-: recursive-quotation? ( quot -- ? )
-    local-recursive-state [ first eq? ] with contains? ;
-
 ! Words that the current quotation depends on
 SYMBOL: dependencies
 
@@ -98,9 +43,12 @@ SYMBOL: dependencies
 ! Generic words that the current quotation depends on
 SYMBOL: generic-dependencies
 
+: ?class-or ( class/f class -- class' )
+    swap [ class-or ] when* ;
+
 : depends-on-generic ( generic class -- )
     generic-dependencies get dup
-    [ swap '[ null or _ class-or ] change-at ] [ 3drop ] if ;
+    [ swap '[ _ ?class-or ] change-at ] [ 3drop ] if ;
 
 ! Words we've inferred the stack effect of, for rollback
 SYMBOL: recorded
index abc3ae1950962550730774b2e392585e25c4181c..e4f8c50eeb9d3ee9b04d11cee4f7b8ed49b3432c 100644 (file)
@@ -5,11 +5,12 @@ namespaces make quotations assocs combinators classes.tuple
 classes.tuple.private effects summary hashtables classes generic
 sets definitions generic.standard slots.private continuations
 stack-checker.backend stack-checker.state stack-checker.visitor
-stack-checker.errors ;
+stack-checker.errors stack-checker.values
+stack-checker.recursive-state ;
 IN: stack-checker.transforms
 
 : give-up-transform ( word -- )
-    dup recursive-label
+    dup recursive-word?
     [ call-recursive-word ]
     [ dup infer-word apply-word/effect ]
     if ;
diff --git a/basis/stack-checker/values/values.factor b/basis/stack-checker/values/values.factor
new file mode 100644 (file)
index 0000000..97aa774
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors namespaces kernel assocs sequences
+stack-checker.recursive-state ;
+IN: stack-checker.values
+
+! Values
+: <value> ( -- value ) \ <value> counter ;
+
+SYMBOL: known-values
+
+: init-known-values ( -- )
+    H{ } clone known-values set ;
+
+: known ( value -- known ) known-values get at ;
+
+: set-known ( known value -- )
+    over [ known-values get set-at ] [ 2drop ] if ;
+
+: make-known ( known -- value )
+    <value> [ set-known ] keep ;
+
+: copy-value ( value -- value' )
+    known make-known ;
+
+: copy-values ( values -- values' )
+    [ copy-value ] map ;
+
+! Literal value
+TUPLE: literal < identity-tuple value recursion hashcode ;
+
+M: literal hashcode* nip hashcode>> ;
+
+: <literal> ( obj -- value )
+    recursive-state get over hashcode \ literal boa ;
+
+GENERIC: (literal) ( value -- literal )
+
+M: literal (literal) ;
+
+: literal ( value -- literal )
+    known (literal) ;
+
+! Result of curry
+TUPLE: curried obj quot ;
+
+C: <curried> curried
+
+! Result of compose
+TUPLE: composed quot1 quot2 ;
+
+C: <composed> composed
index a24d8e226d02fdb03f717b0e4ed39b517846022a..5f05d97d1a4d1970f3eb75c736f61df467c77a28 100644 (file)
@@ -8,7 +8,7 @@ M: f #introduce, drop ;
 M: f #call, 3drop ;
 M: f #call-recursive, 3drop ;
 M: f #push, 2drop ;
-M: f #shuffle, 3drop ;
+M: f #shuffle, 2drop 2drop drop ;
 M: f #>r, 2drop ;
 M: f #r>, 2drop ;
 M: f #return, drop ;
index 7d8ec90453024070d5b4596a5c9f2aebaab513df..6093cd008af0d077157283e51eae0bb6903cfc1e 100644 (file)
@@ -13,7 +13,7 @@ HOOK: #introduce, stack-visitor ( values -- )
 HOOK: #call, stack-visitor ( inputs outputs word -- )
 HOOK: #call-recursive, stack-visitor ( inputs outputs word -- )
 HOOK: #push, stack-visitor ( literal value -- )
-HOOK: #shuffle, stack-visitor ( inputs outputs mapping -- )
+HOOK: #shuffle, stack-visitor ( in-d out-d in-r out-r mapping -- )
 HOOK: #drop, stack-visitor ( values -- )
 HOOK: #>r, stack-visitor ( inputs outputs -- )
 HOOK: #r>, stack-visitor ( inputs outputs -- )
diff --git a/basis/suffix-arrays/authors.txt b/basis/suffix-arrays/authors.txt
new file mode 100755 (executable)
index 0000000..e4a36df
--- /dev/null
@@ -0,0 +1 @@
+Marc Fauconneau
\ No newline at end of file
diff --git a/basis/suffix-arrays/suffix-arrays-docs.factor b/basis/suffix-arrays/suffix-arrays-docs.factor
new file mode 100755 (executable)
index 0000000..87df272
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2008 Marc Fauconneau.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays help.markup help.syntax io.streams.string
+sequences strings math suffix-arrays.private ;
+IN: suffix-arrays
+
+HELP: >suffix-array
+{ $values
+     { "seq" sequence }
+     { "array" array } }
+{ $description "Creates a suffix array from the input sequence.  Suffix arrays are arrays of slices." } ;
+
+HELP: SA{
+{ $description "Creates a new literal suffix array at parse-time." } ;
+
+HELP: suffixes
+{ $values
+     { "string" string }
+     { "suffixes-seq" "a sequence of slices" } }
+{ $description "Returns a sequence of tail slices of the input string." } ;
+
+HELP: from-to
+{ $values
+     { "index" integer } { "begin" sequence } { "suffix-array" "a suffix-array" }
+     { "from/f" "an integer or f" } { "to/f" "an integer or f" } }
+{ $description "Finds the bounds of the suffix array that match the input sequence. A return value of " { $link f } " means that the endpoint is included." }
+{ $notes "Slices are [m,n) and we want (m,n) so we increment." } ;
+
+HELP: query
+{ $values
+     { "begin" sequence } { "suffix-array" "a suffix-array" }
+     { "matches" array } }
+{ $description "Returns a sequence of sequences from the suffix-array that contain the input sequence. An empty array is returned when there are no matches." } ;
+
+ARTICLE: "suffix-arrays" "Suffix arrays"
+"The " { $vocab-link "suffix-arrays" } " vocabulary implements the suffix array data structure for efficient lookup of subsequences. This suffix array implementation is a sorted array of suffixes. Querying it for matches uses binary search for efficiency." $nl
+
+"Creating new suffix arrays:"
+{ $subsection >suffix-array }
+"Literal suffix arrays:"
+{ $subsection POSTPONE: SA{ }
+"Querying suffix arrays:"
+{ $subsection query } ;
+
+ABOUT: "suffix-arrays"
diff --git a/basis/suffix-arrays/suffix-arrays-tests.factor b/basis/suffix-arrays/suffix-arrays-tests.factor
new file mode 100755 (executable)
index 0000000..5149804
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Marc Fauconneau.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test suffix-arrays kernel namespaces sequences ;
+IN: suffix-arrays.tests
+
+! built from [ all-words 10 head [ name>> ] map ]
+[ ] [ 
+     {
+        "run-tests"
+        "must-fail-with"
+        "test-all"
+        "short-effect"
+        "failure"
+        "test"
+        "<failure>"
+        "this-test"
+        "(unit-test)"
+        "unit-test"
+    } >suffix-array "suffix-array" set
+] unit-test
+
+[ t ]
+[ "suffix-array" get "" swap query empty? not ] unit-test
+
+[ { } ]
+[ SA{ } "something" swap query ] unit-test
+
+[ V{ "unit-test" "(unit-test)" } ]
+[ "suffix-array" get "unit-test" swap query ] unit-test
+
+[ t ]
+[ "suffix-array" get "something else" swap query empty? ] unit-test
+
+[ V{ "rofl" } ] [ SA{ "rofl" } "r" swap query ] unit-test
+[ V{ "rofl" } ] [ SA{ "rofl" } "o" swap query ] unit-test
+[ V{ "rofl" } ] [ SA{ "rofl" } "f" swap query ] unit-test
+[ V{ "rofl" } ] [ SA{ "rofl" } "l" swap query ] unit-test
+[ V{ } ] [ SA{ "rofl" } "t" swap query ] unit-test
diff --git a/basis/suffix-arrays/suffix-arrays.factor b/basis/suffix-arrays/suffix-arrays.factor
new file mode 100755 (executable)
index 0000000..b181ba9
--- /dev/null
@@ -0,0 +1,39 @@
+! Copyright (C) 2008 Marc Fauconneau.
+! See http://factorcode.org/license.txt for BSD license.
+USING: parser kernel arrays math accessors sequences
+math.vectors math.order sorting binary-search sets assocs fry ;
+IN: suffix-arrays
+
+<PRIVATE
+: suffixes ( string -- suffixes-seq )
+    dup length [ tail-slice ] with map ;
+
+: prefix<=> ( begin seq -- <=> )
+    [ <=> ] [ swap head? ] 2bi [ drop +eq+ ] when ;
+: find-index ( begin suffix-array -- index/f )
+    [ prefix<=> ] with search drop ;
+
+: from-to ( index begin suffix-array -- from/f to/f )
+    swap '[ _ head? not ]
+    [ find-last-from drop dup [ 1+ ] when ]
+    [ find-from drop ] 3bi ;
+
+: <funky-slice> ( from/f to/f seq -- slice )
+    [
+        tuck
+        [ drop 0 or ] [ length or ] 2bi*
+        [ min ] keep
+    ] keep <slice> ; inline
+
+PRIVATE>
+
+: >suffix-array ( seq -- array )
+    [ suffixes ] map concat natural-sort ;
+
+: SA{ \ } [ >suffix-array ] parse-literal ; parsing
+
+: query ( begin suffix-array -- matches )
+    2dup find-index dup
+    [ -rot [ from-to ] keep <funky-slice> [ seq>> ] map prune ]
+    [ 3drop { } ] if ;
diff --git a/basis/suffix-arrays/summary.txt b/basis/suffix-arrays/summary.txt
new file mode 100755 (executable)
index 0000000..71eda47
--- /dev/null
@@ -0,0 +1 @@
+Suffix arrays
diff --git a/basis/suffix-arrays/tags.txt b/basis/suffix-arrays/tags.txt
new file mode 100755 (executable)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/basis/suffix-arrays/words/words.factor b/basis/suffix-arrays/words/words.factor
new file mode 100755 (executable)
index 0000000..74e2fc2
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Marc Fauconneau.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: kernel arrays math accessors sequences math.vectors\r
+math.order sorting binary-search sets assocs fry suffix-arrays ;\r
+IN: suffix-arrays.words\r
+\r
+! to search on word names\r
+\r
+: new-word-sa ( words -- sa )\r
+    [ name>> ] map >suffix-array ;\r
+\r
+: name>word-map ( words -- map )\r
+    dup [ name>> V{ } clone ] H{ } map>assoc\r
+    [ '[ dup name>> _ at push ] each ] keep ;\r
+\r
+: query-word-sa ( map begin sa -- matches ) query '[ _ at ] map concat ;\r
+\r
+! usage example :\r
+! clear all-words 100 head dup name>word-map "test" rot new-word-sa query .\r
index 477ea01ef666b325da5351e6f38bf56f2f368f0a..b7ec0d07a2af2f7fa71f1de243677e9d36b1e2a4 100644 (file)
@@ -1,10 +1,10 @@
-USING: help.markup help.syntax words definitions ;
+USING: help.markup help.syntax words definitions prettyprint ;
 IN: tools.crossref
 
 ARTICLE: "tools.crossref" "Cross-referencing tools" 
 { $subsection usage. }
 { $subsection apropos }
-{ $see-also "definitions" "words" } ;
+{ $see-also "definitions" "words" see see-methods } ;
 
 ABOUT: "tools.crossref"
 
index ad1b3cbd84c15791daf15584e9df656d11730a15..ec1259c777775ad54d2c0d81d42291b782e5ecac 100755 (executable)
@@ -9,16 +9,14 @@ IN: tools.deploy.windows
     "resource:factor.dll" swap copy-file-into ;
 
 : copy-freetype ( bundle-name -- )
-    deploy-ui? get [
-        {
-            "resource:freetype6.dll"
-            "resource:zlib1.dll"
-        } swap copy-files-into
-    ] [ drop ] if ;
+    {
+        "resource:freetype6.dll"
+        "resource:zlib1.dll"
+    } swap copy-files-into ;
 
 : create-exe-dir ( vocab bundle-name -- vm )
+    dup copy-dll
     deploy-ui? get [
-        dup copy-dll
         dup copy-freetype
         dup "" copy-fonts
     ] when
@@ -26,14 +24,14 @@ IN: tools.deploy.windows
 
 M: winnt deploy*
     "resource:" [
-        deploy-name over deploy-config at
-        [
-            {
+        dup deploy-config [
+            deploy-name get
+            [
                 [ create-exe-dir ]
                 [ image-name ]
                 [ drop ]
-                [ drop deploy-config ]
-            } 2cleave make-deploy-image
-        ]
-        [ nip open-in-explorer ] 2bi
+                2tri namespace make-deploy-image
+            ]
+            [ nip open-in-explorer ] 2bi
+        ] bind
     ] with-directory ;
diff --git a/basis/tools/hexdump/authors.txt b/basis/tools/hexdump/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/tools/hexdump/hexdump-docs.factor b/basis/tools/hexdump/hexdump-docs.factor
new file mode 100644 (file)
index 0000000..9579fb7
--- /dev/null
@@ -0,0 +1,22 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax kernel sequences strings ;
+IN: tools.hexdump
+
+HELP: hexdump.
+{ $values { "seq" sequence } }
+{ $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time and writes it to standard out." } ;
+
+HELP: hexdump
+{ $values { "seq" sequence } { "str" string } }
+{ $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time.  Lines are separated by a newline character." }
+{ $see-also hexdump. } ;
+
+ARTICLE: "tools.hexdump" "Hexdump"
+"The " { $vocab-link "tools.hexdump" } " vocabulary provides a traditional hexdump view of a sequence." $nl
+"Write hexdump to string:"
+{ $subsection hexdump }
+"Write the hexdump to the output stream:"
+{ $subsection hexdump. } ;
+
+ABOUT: "tools.hexdump"
diff --git a/basis/tools/hexdump/hexdump-tests.factor b/basis/tools/hexdump/hexdump-tests.factor
new file mode 100644 (file)
index 0000000..7202e44
--- /dev/null
@@ -0,0 +1,11 @@
+USING: tools.hexdump kernel sequences tools.test ;
+IN: tools.hexdump.tests
+
+[ t ] [ "" hexdump "Length: 0, 0h\n" = ] unit-test
+[ t ] [ "abcdefghijklmnopqrstuvwxyz" hexdump "Length: 26, 1ah\n00000000h: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop\n00000010h: 71 72 73 74 75 76 77 78 79 7a                   qrstuvwxyz\n" = ] unit-test
+
+[ t ] [ 256 [ ] map hexdump "Length: 256, 100h\n00000000h: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n00000010h: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n00000020h: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f  !\"#$%&'()*+,-./\n00000030h: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n00000040h: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n00000050h: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n00000060h: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n00000070h: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n00000080h: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................\n00000090h: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................\n000000a0h: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................\n000000b0h: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................\n000000c0h: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................\n000000d0h: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................\n000000e0h: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................\n000000f0h: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................\n" = ] unit-test
+
+
+[
+    "Length: 3, 3h\n00000000h: 01 02 03                                        ...\n" ] [ B{ 1 2 3 } hexdump ] unit-test
diff --git a/basis/tools/hexdump/hexdump.factor b/basis/tools/hexdump/hexdump.factor
new file mode 100644 (file)
index 0000000..c8b9f4a
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays io io.streams.string kernel math math.parser
+namespaces sequences splitting grouping strings ascii ;
+IN: tools.hexdump
+
+<PRIVATE
+
+: write-header ( len -- )
+    "Length: " write
+    [ number>string write ", " write ]
+    [ >hex write "h" write nl ] bi ;
+
+: write-offset ( lineno -- )
+    16 * >hex 8 CHAR: 0 pad-left write "h: " write ;
+
+: >hex-digit ( digit -- str )
+    >hex 2 CHAR: 0 pad-left " " append ;
+
+: >hex-digits ( bytes -- str )
+    [ >hex-digit ] { } map-as concat 48 CHAR: \s pad-right ;
+
+: >ascii ( bytes -- str )
+    [ [ printable? ] keep CHAR: . ? ] "" map-as ;
+
+: write-hex-line ( bytes lineno -- )
+    write-offset [ >hex-digits write ] [ >ascii write ] bi nl ;
+
+PRIVATE>
+
+: hexdump. ( seq -- )
+    [ length write-header ]
+    [ 16 <sliced-groups> [ write-hex-line ] each-index ] bi ;
+
+: hexdump ( seq -- str )
+    [ hexdump. ] with-string-writer ;
diff --git a/basis/tools/hexdump/summary.txt b/basis/tools/hexdump/summary.txt
new file mode 100644 (file)
index 0000000..d860bd7
--- /dev/null
@@ -0,0 +1 @@
+Prints formatted hex dump of an arbitrary sequence
index 75ca5ede8c4060f9c6bcf63714d4d8ef2546880a..f0c71aa311d68f579061511ade1fa7db4bda38c5 100644 (file)
@@ -1,6 +1,7 @@
 IN: tools.profiler.tests
 USING: accessors tools.profiler tools.test kernel memory math
-threads alien tools.profiler.private sequences compiler.units ;
+threads alien tools.profiler.private sequences compiler.units
+words ;
 
 [ t ] [
     \ length counter>>
@@ -54,3 +55,7 @@ threads alien tools.profiler.private sequences compiler.units ;
 ] unit-test
 
 [ 666 ] [ \ recompile-while-profiling-test counter>> ] unit-test
+
+[ ] [ [ [ ] compile-call ] profile ] unit-test
+
+[ [ gensym execute ] profile ] [ T{ undefined } = ] must-fail-with
index 6659940b2b2fdcf2f321758724b384a1328efb83..281180126695f6abf69bfb0d639fb87666c7c6ee 100644 (file)
@@ -148,7 +148,7 @@ ERROR: no-vocab vocab ;
             "{ $values" print
             [ "    " write ($values.) ]
             [ [ nl "    " write ($values.) ] unless-empty ] bi*
-            " }" write nl
+            nl "}" print
         ] if
     ] when* ;
 
@@ -263,3 +263,12 @@ SYMBOL: examples-flag
         [ example ] times
         "}" print
     ] with-variable ;
+
+: scaffold-rc ( path -- )
+    [ touch-file ] [ "Click to edit: " write <pathname> . ] bi ;
+
+: scaffold-factor-boot-rc ( -- )
+    home ".factor-boot-rc" append-path scaffold-rc ;
+
+: scaffold-factor-rc ( -- )
+    home ".factor-rc" append-path scaffold-rc ;
index 4b2521d19c4d401be2bb71b9313a2c85bcb8bc34..02c0ad126df6f240feee713e40e58381ab485f5f 100644 (file)
@@ -17,7 +17,7 @@ ARTICLE: "tools.test.run" "Running unit tests"
 { $subsection test-all } ;
 
 ARTICLE: "tools.test.failure" "Handling test failures"
-"Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Sometimes, you want to develop a tool which inspects the test failures and takes some kind of action instead; one example is " { $vocab-link "builder" } "."
+"Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Some tools inspect the test failures and takes some kind of action instead, for example, " { $vocab-link "mason" } "."
 $nl
 "The following words output an association list mapping vocabulary names to sequences of failures; a failure is an array having the shape " { $snippet "{ error test continuation }" } ", and the elements are as follows:"
 { $list
index d2dfe56ed4423f32d99ade596f55f5b8d0e3f6bf..5a6118fb0049884a34bd1ae96eb94ff0296b9980 100644 (file)
@@ -196,6 +196,7 @@ M: freetype-renderer string-height ( open-font string -- h )
 :: (draw-string) ( open-font sprites string loc -- )
     GL_TEXTURE_2D [
         loc [
+            -0.5 0.5 0.0 glTranslated
             string open-font string char-widths scan-sums [
                 [ open-font sprites ] 2dip draw-char
             ] 2each
index 4ad9e1487434e6b3a6a7bf6e20fde2901c891559..11fb69fc7d9b6582123fc9ad436a90ccaa702448 100644 (file)
@@ -1,12 +1,11 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel math models namespaces sequences
-       strings quotations assocs combinators classes colors
-       classes.tuple opengl math.vectors
-       ui.commands ui.gadgets ui.gadgets.borders
-       ui.gadgets.labels ui.gadgets.theme
-       ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures
-       ui.render math.geometry.rect ;
+strings quotations assocs combinators classes colors
+classes.tuple opengl opengl.gl math.vectors ui.commands ui.gadgets
+ui.gadgets.borders ui.gadgets.labels ui.gadgets.theme
+ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures
+ui.render math.geometry.rect locals alien.c-types ;
 
 IN: ui.gadgets.buttons
 
@@ -62,10 +61,10 @@ C: <button-paint> button-paint
     } cond ;
 
 M: button-paint draw-interior
-    button-paint draw-interior ;
+    button-paint dup [ draw-interior ] [ 2drop ] if ;
 
 M: button-paint draw-boundary
-    button-paint draw-boundary ;
+    button-paint dup [ draw-boundary ] [ 2drop ] if ;
 
 : align-left ( button -- button )
     { 0 1/2 } >>align ; inline
@@ -103,17 +102,34 @@ repeat-button H{
     #! the mouse is held down.
     repeat-button new-button bevel-button-theme ;
 
-TUPLE: checkmark-paint color ;
+TUPLE: checkmark-paint < caching-pen color last-vertices ;
 
-C: <checkmark-paint> checkmark-paint
+: <checkmark-paint> ( color -- paint )
+    checkmark-paint new swap >>color ;
+
+<PRIVATE
+
+: checkmark-points ( dim -- points )
+    {
+        [ { 0 0 } v* { 0 1 } v+ ]
+        [ { 1 1 } v* { 0 1 } v+ ]
+        [ { 0 1 } v* ]
+        [ { 1 0 } v* ]
+    } cleave 4array ;
+
+: checkmark-vertices ( dim -- vertices )
+    checkmark-points concat >c-float-array ;
+
+PRIVATE>
+
+M: checkmark-paint recompute-pen
+    swap dim>> checkmark-vertices >>last-vertices drop ;
 
 M: checkmark-paint draw-interior
-    color>> set-color
-    origin get [
-        rect-dim
-        { 0 0 } over gl-line
-        dup { 0 1 } v* swap { 1 0 } v* gl-line
-    ] with-translation ;
+    [ compute-pen ]
+    [ color>> gl-color ]
+    [ last-vertices>> gl-vertex-pointer ] tri
+    GL_LINES 0 4 glDrawArrays ;
 
 : checkmark-theme ( gadget -- gadget )
     f
@@ -148,30 +164,47 @@ TUPLE: checkbox < button ;
 M: checkbox model-changed
     swap value>> >>selected? relayout-1 ;
 
-TUPLE: radio-paint color ;
+TUPLE: radio-paint < caching-pen color interior-vertices boundary-vertices ;
+
+: <radio-paint> ( color -- paint ) radio-paint new swap >>color ;
+
+<PRIVATE
+
+: circle-steps 8 ;
 
-C: <radio-paint> radio-paint
+PRIVATE>
+
+M: radio-paint recompute-pen
+    swap dim>>
+    [ { 4 4 } swap { 9 9 } v- circle-steps circle-vertices >>interior-vertices ]
+    [ { 1 1 } swap { 3 3 } v- circle-steps circle-vertices >>boundary-vertices ] bi
+    drop ;
+
+<PRIVATE
+
+: (radio-paint) ( gadget paint -- )
+    [ compute-pen ] [ color>> gl-color ] bi ;
+
+PRIVATE>
 
 M: radio-paint draw-interior
-    color>> set-color
-    origin get { 4 4 } v+ swap rect-dim { 8 8 } v- 12 gl-fill-circle ;
+    [ (radio-paint) ] [ interior-vertices>> gl-vertex-pointer ] bi
+    GL_POLYGON 0 circle-steps glDrawArrays ;
 
 M: radio-paint draw-boundary
-    color>> set-color
-    origin get { 1 1 } v+ swap rect-dim { 2 2 } v- 12 gl-circle ;
+    [ (radio-paint) ] [ boundary-vertices>> gl-vertex-pointer ] bi
+    GL_LINE_LOOP 0 circle-steps glDrawArrays ;
 
-: radio-knob-theme ( gadget -- gadget )
-    f
-    f
-    black <radio-paint>
-    black <radio-paint>
-    <button-paint> >>interior
-    black <radio-paint> >>boundary ;
+:: radio-knob-theme ( gadget -- gadget )
+    [let | radio-paint [ black <radio-paint> ] |
+        gadget
+        f f radio-paint radio-paint <button-paint> >>interior
+        radio-paint >>boundary
+        { 16 16 } >>dim
+    ] ;
 
 : <radio-knob> ( -- gadget )
-    <gadget>
-    radio-knob-theme
-    { 16 16 } >>dim ;
+    <gadget> radio-knob-theme ;
 
 TUPLE: radio-control < button value ;
 
index a1026ef35a02b84a567be2c6eb6d3608317cfc47..0d0611f532269cc98b0029956eee8fba5281e10d 100644 (file)
@@ -127,10 +127,12 @@ M: editor ungraft*
 : draw-caret ( -- )
     editor get focused?>> [
         editor get
-        dup caret-color>> set-color
-        dup caret-loc origin get v+
-        swap caret-dim over v+
-        [ { 0.5 -0.5 } v+ ] bi@ gl-line
+        [ caret-color>> gl-color ]
+        [
+            dup caret-loc origin get v+
+            swap caret-dim over v+
+            gl-line
+        ] bi
     ] when ;
 
 : line-translation ( n -- loc )
@@ -171,7 +173,7 @@ M: editor ungraft*
 
 : draw-lines ( -- )
     \ first-visible-line get [
-        editor get dup color>> set-color
+        editor get dup color>> gl-color
         dup visible-lines
         [ draw-line 1 translate-lines ] with each
     ] with-editor-translation ;
@@ -180,17 +182,19 @@ M: editor ungraft*
     dup editor-mark* swap editor-caret* sort-pair ;
 
 : (draw-selection) ( x1 x2 -- )
-    2dup = [ 2 + ] when
-    0.0 swap editor get line-height glRectd ;
+    over -
+    dup 0 = [ 2 + ] when
+    [ 0.0 2array ] [ editor get line-height 2array ] bi*
+    swap [ gl-fill-rect ] with-translation ;
 
 : draw-selected-line ( start end n -- )
     [ start/end-on-line ] keep tuck
-    >r >r editor get offset>x r> r>
+    [ editor get offset>x ] 2dip
     editor get offset>x
     (draw-selection) ;
 
 : draw-selection ( -- )
-    editor get selection-color>> set-color
+    editor get selection-color>> gl-color
     editor get selection-start/end
     over first [
         2dup [
index f4266adba18d753dcb22a67622424bfd5bbb2276..0356e7fd4d17809d83baeb7f131cfe823e7bc227 100644 (file)
@@ -23,13 +23,10 @@ SYMBOL: grid-dim
     ] with each ;
 
 M: grid-lines draw-boundary
-    origin get [
-        -0.5 -0.5 0.0 glTranslated
-        color>> set-color [
-            dup grid set
-            dup rect-dim half-gap v- grid-dim set
-            compute-grid
-            { 0 1 } draw-grid-lines
-            { 1 0 } draw-grid-lines
-        ] with-scope
-    ] with-translation ;
+    color>> gl-color [
+        dup grid set
+        dup rect-dim half-gap v- grid-dim set
+        compute-grid
+        { 0 1 } draw-grid-lines
+        { 1 0 } draw-grid-lines
+    ] with-scope ;
index 8cf13c83675084e5496382416f8693cbb7a8b760..79a485b7115fcca50f9327baaea65d36af50d721 100644 (file)
@@ -30,16 +30,16 @@ M: labelled-gadget focusable-child* content>> ;
 
 : title-theme ( gadget -- gadget )
     { 1 0 } >>orientation
-    T{ gradient f {
+    {
         T{ rgba f 0.65 0.65 1.0 1.0 }
         T{ rgba f 0.65 0.45 1.0 1.0 }
-    } } >>interior ;
+    } <gradient> >>interior ;
 
 : <title-label> ( text -- label ) <label> title-theme ;
 
 : <title-bar> ( title quot -- gadget )
     <frame>
-        swap dup [ <close-box> @left grid-add ] [ drop ] if
+        swap [ <close-box> @left grid-add ] when*
         swap <title-label> @center grid-add ;
 
 TUPLE: closable-gadget < frame content ;
index 6c38b6183d8b78e895343bc219e46431b3cec14f..6e56b48c8b33b36c3bc4dc5a222d6fea0416705f 100644 (file)
@@ -34,7 +34,7 @@ M: label pref-dim*
     [ font>> open-font ] [ text>> ] bi text-dim ;
 
 M: label draw-gadget*
-    [ color>> set-color ]
+    [ color>> gl-color ]
     [ [ font>> ] [ text>> ] bi origin get draw-text ] bi ;
 
 M: label gadget-text* label-string % ;
index 62e5b7d780abae8d23e1da5b420c040e0acff751..ec46638c918d77642c2eb7f155cde53f100e6196 100644 (file)
@@ -56,8 +56,12 @@ M: list model-changed
 
 M: list draw-gadget*
     origin get [
-        dup color>> set-color
-        selected-rect [ rect-extent gl-fill-rect ] when*
+        dup color>> gl-color
+        selected-rect [
+            dup loc>> [
+                dim>> gl-fill-rect
+            ] with-translation
+        ] when*
     ] with-translation ;
 
 M: list focusable-child* drop t ;
@@ -97,7 +101,7 @@ M: list focusable-child* drop t ;
     ] if ;
 
 : select-gadget ( gadget list -- )
-    swap over children>> index
+    tuck children>> index
     [ swap select-index ] [ drop ] if* ;
 
 : clamp-loc ( point max -- point )
index f100a72f0646d81839601d384d5e9b265284a4cf..ef5745809e06ea94eddf47ce6a0b1733ea0881a7 100644 (file)
@@ -63,7 +63,11 @@ GENERIC: draw-selection ( loc obj -- )
     >r clip get over intersects? r> [ drop ] if ; inline
 
 M: gadget draw-selection ( loc gadget -- )
-    swap offset-rect [ rect-extent gl-fill-rect ] if-fits ;
+    swap offset-rect [
+        dup loc>> [
+            dim>> gl-fill-rect
+        ] with-translation
+    ] if-fits ;
 
 M: node draw-selection ( loc node -- )
     2dup value>> swap offset-rect [
@@ -74,7 +78,7 @@ M: node draw-selection ( loc node -- )
 
 M: pane draw-gadget*
     dup gadget-selection? [
-        dup selection-color>> set-color
+        dup selection-color>> gl-color
         origin get over rect-loc v- swap selected-children
         [ draw-selection ] with each
     ] [
index fefce8a04099e5a3fe282349ca27f8c1af36ee98..d1429c40065a13d7ddf0df5fd6f11dfd3cdbd704 100644 (file)
@@ -4,7 +4,8 @@ USING: accessors arrays ui.gadgets ui.gadgets.viewports
 ui.gadgets.frames ui.gadgets.grids ui.gadgets.theme
 ui.gadgets.sliders ui.gestures kernel math namespaces sequences
 models models.range models.compose
-combinators math.vectors classes.tuple math.geometry.rect ;
+combinators math.vectors classes.tuple math.geometry.rect
+combinators.short-circuit ;
 IN: ui.gadgets.scrollers
 
 TUPLE: scroller < frame viewport x y follows ;
@@ -41,7 +42,7 @@ scroller H{
         dup model>> dependencies>> first  <x-slider> >>x dup x>> @bottom grid-add
         dup model>> dependencies>> second <y-slider> >>y dup y>> @right  grid-add
 
-        swap over model>> <viewport> >>viewport
+        tuck model>> <viewport> >>viewport
         dup viewport>> @center grid-add ;
 
 : <scroller> ( gadget -- scroller ) scroller new-scroller ;
@@ -70,13 +71,10 @@ scroller H{
 : relative-scroll-rect ( rect gadget scroller -- newrect )
     viewport>> gadget-child relative-loc offset-rect ;
 
-: find-scroller* ( gadget -- scroller )
-    dup find-scroller dup [
-        2dup viewport>> gadget-child
-        swap child? [ nip ] [ 2drop f ] if
-    ] [
-        2drop f
-    ] if ;
+: find-scroller* ( gadget -- scroller/f )
+    dup find-scroller
+    { [ nip ] [ viewport>> gadget-child swap child? ] [ nip ] }
+    2&& ;
 
 : scroll>rect ( rect gadget -- )
     dup find-scroller* dup [
index 5e4a2fbf4ce92c13b28819a934895cda2080f924..fa36e61d90d69b3c112992885fede4e8e2ba1971 100644 (file)
@@ -17,44 +17,44 @@ IN: ui.gadgets.theme
 
 : selection-color ( -- color ) light-purple ;
 
-: plain-gradient
-    T{ gradient f {
+: plain-gradient ( -- gradient )
+    {
         T{ gray f 0.94 1.0 }
         T{ gray f 0.83 1.0 }
         T{ gray f 0.83 1.0 }
         T{ gray f 0.62 1.0 }
-    } } ;
+    } <gradient> ;
 
-: rollover-gradient
-    T{ gradient f {
+: rollover-gradient ( -- gradient )
+    {
         T{ gray f 1.0  1.0 }
         T{ gray f 0.9  1.0 }
         T{ gray f 0.9  1.0 }
         T{ gray f 0.75 1.0 }
-    } } ;
+    } <gradient> ;
 
-: pressed-gradient
-    T{ gradient f {
+: pressed-gradient ( -- gradient )
+    {
         T{ gray f 0.75 1.0 }
         T{ gray f 0.9  1.0 }
         T{ gray f 0.9  1.0 }
         T{ gray f 1.0  1.0 }
-    } } ;
+    } <gradient> ;
 
-: selected-gradient
-    T{ gradient f {
+: selected-gradient ( -- gradient )
+    {
         T{ gray f 0.65 1.0 }
         T{ gray f 0.8  1.0 }
         T{ gray f 0.8  1.0 }
         T{ gray f 1.0  1.0 }
-    } } ;
+    } <gradient> ;
 
-: lowered-gradient
-    T{ gradient f {
+: lowered-gradient ( -- gradient )
+    {
         T{ gray f 0.37 1.0 }
         T{ gray f 0.43 1.0 }
         T{ gray f 0.5  1.0 }
-    } } ;
+    } <gradient> ;
 
 : sans-serif-font { "sans-serif" plain 12 } ;
 
index fc16ed934595627e0ba749a3ce563f821876d714..294ee1c63dd43cae801bc19239ae5970bde4d41c 100644 (file)
@@ -52,7 +52,7 @@ HELP: polygon
 } ;
 
 HELP: <polygon>
-{ $values { "color" "a color specifier" } { "points" "a sequence of points" } }
+{ $values { "color" "a color specifier" } { "points" "a sequence of points" } { "polygon" polygon } }
 { $description "Creates a new instance of " { $link polygon } "." } ;
 
 HELP: <polygon-gadget>
index 9aacf1c7247afa421c5c8bfacbac84229dc4722e..71304aca0bc2c0bcaa505c1caebde5277b35bf3f 100644 (file)
@@ -1,9 +1,9 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien arrays hashtables io kernel math namespaces opengl
-opengl.gl opengl.glu sequences strings io.styles vectors
-combinators math.vectors ui.gadgets colors
-math.order math.geometry.rect ;
+USING: accessors alien alien.c-types arrays hashtables io kernel
+math namespaces opengl opengl.gl opengl.glu sequences strings
+io.styles vectors combinators math.vectors ui.gadgets colors
+math.order math.geometry.rect locals ;
 IN: ui.render
 
 SYMBOL: clip
@@ -21,9 +21,9 @@ SYMBOL: viewport-translation
 : init-clip ( clip-rect rect -- )
     GL_SCISSOR_TEST glEnable
     [ rect-intersect ] keep
-    rect-dim dup { 0 1 } v* viewport-translation set
+    dim>> dup { 0 1 } v* viewport-translation set
     { 0 0 } over gl-viewport
-    0 swap first2 0 gluOrtho2D
+    -0.5 swap first2 [ 0.5 - ] [ 0.5 + ] bi* 0.5 gluOrtho2D
     clip set
     do-clip ;
 
@@ -31,12 +31,13 @@ SYMBOL: viewport-translation
     GL_SMOOTH glShadeModel
     GL_BLEND glEnable
     GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA glBlendFunc
+    GL_VERTEX_ARRAY glEnableClientState
     init-matrices
     init-clip
     ! white gl-clear is broken w.r.t window resizing
     ! Linux/PPC Radeon 9200
-    white set-color
-    clip get rect-extent gl-fill-rect ;
+    white gl-color
+    clip get dim>> gl-fill-rect ;
 
 GENERIC: draw-gadget* ( gadget -- )
 
@@ -60,10 +61,15 @@ DEFER: draw-gadget
 : (draw-gadget) ( gadget -- )
     [
         dup translate
-        dup dup interior>> draw-interior
+        dup interior>> [
+            origin get [ dupd draw-interior ] with-translation
+        ] when*
         dup draw-gadget*
         dup visible-children [ draw-gadget ] each
-        dup boundary>> draw-boundary
+        dup boundary>> [
+            origin get [ dupd draw-boundary ] with-translation
+        ] when*
+        drop
     ] with-scope ;
 
 : >absolute ( rect -- rect )
@@ -84,51 +90,102 @@ DEFER: draw-gadget
         [ [ (draw-gadget) ] with-clipping ]
     } cond ;
 
-! Pen paint properties
-M: f draw-interior 2drop ;
-M: f draw-boundary 2drop ;
+! A pen that caches vertex arrays, etc
+TUPLE: caching-pen last-dim ;
+
+GENERIC: recompute-pen ( gadget pen -- )
+
+: compute-pen ( gadget pen -- )
+    2dup [ dim>> ] [ last-dim>> ] bi* = [
+        2drop
+    ] [
+        [ swap dim>> >>last-dim drop ] [ recompute-pen ] 2bi
+    ] if ;
 
 ! Solid fill/border
-TUPLE: solid color ;
+TUPLE: solid < caching-pen color interior-vertices boundary-vertices ;
 
-C: <solid> solid
+: <solid> ( color -- solid ) solid new swap >>color ;
+
+M: solid recompute-pen
+    swap dim>>
+    [ (fill-rect-vertices) >>interior-vertices ]
+    [ (rect-vertices) >>boundary-vertices ]
+    bi drop ;
+
+<PRIVATE
 
 ! Solid pen
-: (solid) ( gadget paint -- loc dim )
-    color>> set-color rect-dim >r origin get dup r> v+ ;
+: (solid) ( gadget pen -- )
+    [ compute-pen ] [ color>> gl-color ] bi ;
+
+PRIVATE>
 
-M: solid draw-interior (solid) gl-fill-rect ;
+M: solid draw-interior
+    [ (solid) ] [ interior-vertices>> gl-vertex-pointer ] bi
+    (gl-fill-rect) ;
 
-M: solid draw-boundary (solid) gl-rect ;
+M: solid draw-boundary
+    [ (solid) ] [ boundary-vertices>> gl-vertex-pointer ] bi
+    (gl-rect) ;
 
 ! Gradient pen
-TUPLE: gradient colors ;
+TUPLE: gradient < caching-pen colors last-vertices last-colors ;
 
-C: <gradient> gradient
+: <gradient> ( colors -- gradient ) gradient new swap >>colors ;
+
+<PRIVATE
+
+:: gradient-vertices ( direction dim colors -- seq )
+    direction dim v* dim over v- swap
+    colors length dup 1- v/n [ v*n ] with map
+    [ dup rot v+ 2array ] with map
+    concat concat >c-float-array ;
+
+: gradient-colors ( colors -- seq )
+    [ color>raw 4array dup 2array ] map concat concat >c-float-array ;
+
+M: gradient recompute-pen ( gadget gradient -- )
+    tuck
+    [ [ orientation>> ] [ dim>> ] bi ] [ colors>> ] bi*
+    [ gradient-vertices >>last-vertices ]
+    [ gradient-colors >>last-colors ] bi
+    drop ;
+
+: draw-gradient ( colors -- )
+    GL_COLOR_ARRAY [
+        [ GL_QUAD_STRIP 0 ] dip length 2 * glDrawArrays
+    ] do-enabled-client-state ;
+
+PRIVATE>
 
 M: gradient draw-interior
-    origin get [
-        over orientation>>
-        swap colors>>
-        rot rect-dim
-        gl-gradient
-    ] with-translation ;
+    {
+        [ compute-pen ]
+        [ last-vertices>> gl-vertex-pointer ]
+        [ last-colors>> gl-color-pointer ]
+        [ colors>> draw-gradient ]
+    } cleave ;
 
 ! Polygon pen
-TUPLE: polygon color points ;
+TUPLE: polygon color vertex-array count ;
 
-C: <polygon> polygon
+: <polygon> ( color points -- polygon )
+    [ concat >c-float-array ] [ length ] bi polygon boa ;
 
-: draw-polygon ( polygon quot -- )
-    origin get [
-        >r dup color>> set-color points>> r> call
-    ] with-translation ; inline
+: draw-polygon ( polygon mode -- )
+    swap
+    [ color>> gl-color ]
+    [ vertex-array>> gl-vertex-pointer ]
+    [ 0 swap count>> glDrawArrays ]
+    tri ;
 
 M: polygon draw-boundary
-    [ gl-poly ] draw-polygon drop ;
+    GL_LINE_LOOP draw-polygon drop ;
 
 M: polygon draw-interior
-    [ gl-fill-poly ] draw-polygon drop ;
+    dup count>> 2 > GL_POLYGON GL_LINES ?
+    draw-polygon drop ;
 
 : arrow-up    { { 3 0 } { 6 6 } { 0 6 } } ;
 : arrow-right { { 0 0 } { 6 3 } { 0 6 } } ;
index 4c8b88d62cb341754a8a3510aaa935ca5cc0fff7..68bf7652954e4de5de5020de831944effe974f69 100644 (file)
@@ -50,7 +50,8 @@ M: listener-gadget tool-scroller
     listener>> input>> interactor-busy? ;
 
 : listener-input ( string -- )
-    get-workspace listener>> input>> set-editor-string ;
+    get-workspace listener>> input>>
+    [ set-editor-string ] [ request-focus ] bi ;
 
 : (call-listener) ( quot listener -- )
     input>> interactor-call ;
index 9e7122fc34c13d3af9d1d7acf7a02bd608d25e60..7e7ebd902a39db33bcaa4113078a87092c45a86b 100644 (file)
@@ -22,3 +22,5 @@ IN: unix.groups.tests
 
 [ ] [ effective-group-name [ ] with-effective-group ] unit-test
 [ ] [ effective-group-id [ ] with-effective-group ] unit-test
+
+[ ] [ [ ] with-group-cache ] unit-test
index 6658d5942d9d02f7f782889d5b1edb97eba76068..fb8c6b5035fcf901f2221fcbc8d90495adbbea7c 100644 (file)
@@ -19,8 +19,8 @@ C-STRUCT: statfs
 FUNCTION: int statfs ( char* path, statfs* buf ) ;
 
 TUPLE: linux32-file-system-info < file-system-info
-type bsize blocks bfree bavail files ffree fsid
-namelen frsize spare ;
+bsize blocks bfree bavail files ffree fsid namelen
+frsize spare ;
 
 M: linux >file-system-info ( struct -- statfs )
     [ \ linux32-file-system-info new ] dip
index 3bf2644e12640e75f85ce0ffb70583694f8aa080..e9cd5576aa1480184595bc1cacee5afce73c0442 100644 (file)
@@ -21,8 +21,8 @@ C-STRUCT: statfs64
 FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
 
 TUPLE: linux64-file-system-info < file-system-info
-type bsize blocks bfree bavail files ffree fsid
-namelen frsize spare ;
+bsize blocks bfree bavail files ffree fsid namelen
+frsize spare ;
 
 M: linux >file-system-info ( struct -- statfs )
     [ \ linux64-file-system-info new ] dip
index aae8d091452abf1e09052c74ebebb6e3feab14f1..43d5a99cd157d6ff5bd3c4edc8f852b110860e95 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types combinators kernel io.files unix.stat
+USING: alien.c-types combinators kernel unix.stat
 math accessors system unix io.backend layouts vocabs.loader
 sequences csv io.streams.string io.encodings.utf8 namespaces
 unix.statfs io.files ;
@@ -32,7 +32,7 @@ frequency pass-number ;
     ] with-scope
     [ mtab-csv>mtab-entry ] map ;
 
-M: linux mounted
+M: linux file-systems
     parse-mtab [
         [ mount-point>> file-system-info ] keep
         {
index 6bf09fcdc0260152a97fb1ca1509a8f8db10fddf..7c30c4b9d417994812a8741536dad4e9312bf80d 100644 (file)
@@ -122,7 +122,7 @@ TUPLE: macosx-file-system-info < file-system-info
 block-size io-size blocks blocks-free blocks-available files
 files-free file-system-id owner type-id flags filesystem-subtype ;
 
-M: macosx mounted ( -- array )
+M: macosx file-systems ( -- array )
     f <void*> dup 0 getmntinfo64 dup io-error
     [ *void* ] dip
     "statfs64" heap-size [ * memory>byte-array ] keep group
index e77ef37b0ffb3334c521980b78629a575c49bf37..0397507fcebc28a960675e04db2b3640ceab3439 100644 (file)
@@ -4,12 +4,8 @@ USING: sequences system vocabs.loader combinators accessors
 kernel math.order sorting ;
 IN: unix.statfs
 
-TUPLE: file-system-info root-directory total-free-size total-size ;
-
 HOOK: >file-system-info os ( struct -- statfs )
 
-HOOK: mounted os ( -- array )
-
 os {
     { linux   [ "unix.statfs.linux"   require ] }
     { macosx  [ "unix.statfs.macosx"  require ] }
index c466ad1575863347addd26c1007f6d0dc555ffa8..83e7e99481cc69e0bfd7af6ec798a4c333d7ca4a 100644 (file)
@@ -22,8 +22,8 @@ HELP: new-passwd
 HELP: passwd
 { $description "A platform-specific tuple correspding to every field from the Unix passwd struct. BSD passwd structures have four extra slots: " { $slot "change" } ", " { $slot "class" } "," { $slot "expire" } ", " { $slot "fields" } "." } ;
 
-HELP: passwd-cache
-{ $description "A symbol storing passwd structures indexed by user-ids when within a " { $link with-passwd-cache } "." } ;
+HELP: user-cache
+{ $description "A symbol storing passwd structures indexed by user-ids when within a " { $link with-user-cache } "." } ;
 
 HELP: passwd>new-passwd
 { $values
@@ -70,10 +70,10 @@ HELP: with-effective-user
      { "string/id" "a string or a uid" } { "quot" quotation } }
 { $description "Sets the effective username and calls the quotation. Restores the current username on success or on error after the call." } ;
 
-HELP: with-passwd-cache
+HELP: with-user-cache
 { $values
      { "quot" quotation } }
-{ $description "Iterates over the password file using library calls and creates a cache in the " { $link passwd-cache } " symbol. The cache is a hashtable indexed by user id. When looking up many users, this approach is much faster than calling system calls." } ;
+{ $description "Iterates over the password file using library calls and creates a cache in the " { $link user-cache } " symbol. The cache is a hashtable indexed by user id. When looking up many users, this approach is much faster than calling system calls." } ;
 
 HELP: with-real-user
 { $values
index a85c322acaa9ae6df92c457eb0f5bddd1b100f05..1113383635f5503ba040386ec439d42a178c9080 100644 (file)
@@ -22,3 +22,5 @@ IN: unix.users.tests
 
 [ ] [ effective-username [ ] with-effective-user ] unit-test
 [ ] [ effective-user-id [ ] with-effective-user ] unit-test
+
+[ ] [ [ ] with-user-cache ] unit-test
index eac771160bad24a4c308bc7e0679180847334361..f76fbd53889c1affc15e51130f51e94c1d001a54 100644 (file)
@@ -39,16 +39,16 @@ PRIVATE>
         [ getpwent dup ] [ passwd>new-passwd ] [ drop ] produce
     ] with-pwent ;
 
-SYMBOL: passwd-cache
+SYMBOL: user-cache
 
-: with-passwd-cache ( quot -- )
+: with-user-cache ( quot -- )
     all-users [ [ uid>> ] keep ] H{ } map>assoc
-    passwd-cache swap with-variable ; inline
+    user-cache rot with-variable ; inline
 
 GENERIC: user-passwd ( obj -- passwd )
 
 M: integer user-passwd ( id -- passwd/f )
-    passwd-cache get
+    user-cache get
     [ at ] [ getpwuid passwd>new-passwd ] if* ;
 
 M: string user-passwd ( string -- passwd/f )
index 30e1eadc7a627607fc80dbc5a937ad083fdb4318..0ddced63e885e15bce8e8acb9e3ea05d0376df92 100644 (file)
@@ -1,9 +1,8 @@
 ! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel continuations sequences math namespaces make sets
-math.parser math.ranges assocs parser-combinators.regexp
-unicode.categories arrays hashtables words classes quotations
-xmode.catalog ;
+math.parser math.ranges assocs regexp unicode.categories arrays
+hashtables words classes quotations xmode.catalog ;
 IN: validators
 
 : v-default ( str def -- str/def )
diff --git a/basis/vlists/vlists-tests.factor b/basis/vlists/vlists-tests.factor
new file mode 100644 (file)
index 0000000..3546051
--- /dev/null
@@ -0,0 +1,41 @@
+USING: vlists kernel persistent.sequences arrays tools.test
+namespaces accessors sequences assocs ;
+IN: vlists.tests
+
+[ { "hi" "there" } ]
+[ VL{ } "hi" swap ppush "there" swap ppush >array ] unit-test
+
+[ VL{ "hi" "there" "foo" } VL{ "hi" "there" "bar" } t ]
+[
+    VL{ } "hi" swap ppush "there" swap ppush "v" set
+    "foo" "v" get ppush
+    "bar" "v" get ppush
+    dup "baz" over ppush [ vector>> ] bi@ eq?
+] unit-test
+
+[ "foo" VL{ "hi" "there" } t ]
+[
+    VL{ "hi" "there" "foo" } dup "v" set
+    [ peek ] [ ppop ] bi
+    dup "v" get [ vector>> ] bi@ eq?
+] unit-test
+
+[ VL{ } 3 over push ] must-fail
+
+[ 4 VL{ "hi" } set-first ] must-fail
+
+[ 5 t ] [
+    "rice" VA{ { "rice" 5 } { "beans" 10 } } at*
+] unit-test
+
+[ 6 t ] [
+    "rice" VA{ { "rice" 5 } { "beans" 10 } { "rice" 6 } } at*
+] unit-test
+
+[ 3 ] [
+    VA{ { "rice" 5 } { "beans" 10 } { "rice" 6 } } assoc-size
+] unit-test
+
+[ f f ] [
+    "meat" VA{ { "rice" 5 } { "beans" 10 } { "rice" 6 } } at*
+] unit-test
diff --git a/basis/vlists/vlists.factor b/basis/vlists/vlists.factor
new file mode 100644 (file)
index 0000000..e0f7e55
--- /dev/null
@@ -0,0 +1,93 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays accessors sequences sequences.private
+persistent.sequences assocs persistent.assocs kernel math
+vectors parser prettyprint.backend ;
+IN: vlists
+
+TUPLE: vlist
+{ length array-capacity read-only }
+{ vector vector read-only } ;
+
+: <vlist> ( -- vlist ) 0 V{ } clone vlist boa ; inline
+
+M: vlist length length>> ;
+
+M: vlist nth-unsafe vector>> nth-unsafe ;
+
+<PRIVATE
+
+: >vlist< [ length>> ] [ vector>> ] bi ; inline
+
+: unshare ( len vec -- len vec' )
+    clone [ set-length ] 2keep ; inline
+
+PRIVATE>
+
+M: vlist ppush
+    >vlist<
+    2dup length = [ unshare ] unless
+    [ [ 1+ swap ] dip push ] keep vlist boa ;
+
+ERROR: empty-vlist-error ;
+
+M: vlist ppop
+    [ empty-vlist-error ]
+    [ [ length>> 1- ] [ vector>> ] bi vlist boa ] if-empty ;
+
+M: vlist clone
+    [ length>> ] [ vector>> >vector ] bi vlist boa ;
+
+M: vlist equal?
+    over vlist? [ sequence= ] [ 2drop f ] if ;
+
+: >vlist ( seq -- vlist )
+    [ length ] [ >vector ] bi vlist boa ; inline
+
+M: vlist like
+    drop dup vlist? [ >vlist ] unless ;
+
+INSTANCE: vlist immutable-sequence
+
+: VL{ \ } [ >vlist ] parse-literal ; parsing
+
+M: vlist pprint-delims drop \ VL{ \ } ;
+M: vlist >pprint-sequence ;
+M: vlist pprint* pprint-object ;
+
+TUPLE: valist { vlist vlist read-only } ;
+
+: <valist> ( -- valist ) <vlist> valist boa ; inline
+
+M: valist assoc-size vlist>> length 2/ ;
+
+: valist-at ( key i array -- value ? )
+    over 0 >= [
+        3dup nth-unsafe = [
+            [ 1+ ] dip nth-unsafe nip t
+        ] [
+            [ 2 - ] dip valist-at
+        ] if
+    ] [ 3drop f f ] if ; inline recursive
+
+M: valist at*
+    vlist>> >vlist< [ 2 - ] [ underlying>> ] bi* valist-at ;
+
+M: valist new-at
+    vlist>> ppush ppush valist boa ;
+
+M: valist >alist vlist>> ;
+
+: >valist ( assoc -- valist )
+    >alist concat >vlist valist boa ; inline
+
+M: valist assoc-like
+    drop dup valist? [ >valist ] unless ;
+
+INSTANCE: valist assoc
+
+: VA{ \ } [ >valist ] parse-literal ; parsing
+
+M: valist pprint-delims drop \ VA{ \ } ;
+M: valist >pprint-sequence >alist ;
+M: valist pprint* pprint-object ;
index eb90fb522e783f4bc4fa5efa7c91a27839fd1ac9..462377e85c326e18606703792b2126c38e6df32f 100644 (file)
@@ -954,7 +954,8 @@ ALIAS: GetDiskFreeSpaceEx GetDiskFreeSpaceExW
 ! FUNCTION: GetDllDirectoryA
 ! FUNCTION: GetDllDirectoryW
 ! FUNCTION: GetDriveTypeA
-! FUNCTION: GetDriveTypeW
+FUNCTION: UINT GetDriveTypeW ( LPCTSTR lpRootPathName ) ;
+ALIAS: GetDriveType GetDriveTypeW
 FUNCTION: void* GetEnvironmentStringsW ( ) ;
 ! FUNCTION: GetEnvironmentStringsA
 ALIAS: GetEnvironmentStrings GetEnvironmentStringsW
@@ -999,7 +1000,7 @@ FUNCTION: DWORD GetLastError ( ) ;
 ! FUNCTION: GetLocaleInfoA
 ! FUNCTION: GetLocaleInfoW
 ! FUNCTION: GetLocalTime
-! FUNCTION: GetLogicalDrives
+FUNCTION: DWORD GetLogicalDrives ( ) ;
 ! FUNCTION: GetLogicalDriveStringsA
 ! FUNCTION: GetLogicalDriveStringsW
 ! FUNCTION: GetLongPathNameA
@@ -1129,7 +1130,9 @@ ALIAS: GetVolumeInformation GetVolumeInformationW
 ! FUNCTION: GetVolumeNameForVolumeMountPointW
 ! FUNCTION: GetVolumePathNameA
 ! FUNCTION: GetVolumePathNamesForVolumeNameA
-! FUNCTION: GetVolumePathNamesForVolumeNameW
+FUNCTION: BOOL GetVolumePathNamesForVolumeNameW ( LPCTSTR lpszVolumeName, LPTSTR lpszVolumePathNames, DWORD cchBufferLength, PDWORD lpcchReturnLength ) ;
+ALIAS: GetVolumePathNamesForVolumeName GetVolumePathNamesForVolumeNameW
+
 ! FUNCTION: GetVolumePathNameW
 ! FUNCTION: GetWindowsDirectoryA
 FUNCTION: UINT GetWindowsDirectoryW ( LPTSTR lpBuffer, UINT uSize ) ;
index 7fbb54a56874c4234c549daf027cdb2ac33a52ee..8d75b8cff29a8f746916c2183e0c4c2ccb9b3f08 100755 (executable)
@@ -176,7 +176,7 @@ find_os() {
         *FreeBSD*) OS=freebsd;;
         *OpenBSD*) OS=openbsd;;
         *DragonFly*) OS=dragonflybsd;;
-       SunOS) OS=solaris;;
+        SunOS) OS=solaris;;
     esac
 }
 
@@ -264,24 +264,28 @@ check_os_arch_word() {
         $ECHO "WORD: $WORD"
         $ECHO "OS, ARCH, or WORD is empty.  Please report this."
 
-       echo $MAKE_TARGET
+        echo $MAKE_TARGET
         exit 5
     fi
 }
 
 set_build_info() {
     check_os_arch_word
-    MAKE_TARGET=$OS-$ARCH-$WORD
     if [[ $OS == macosx && $ARCH == ppc ]] ; then
         MAKE_IMAGE_TARGET=macosx-ppc
+        MAKE_TARGET=macosx-ppc
     elif [[ $OS == linux && $ARCH == ppc ]] ; then
         MAKE_IMAGE_TARGET=linux-ppc
+        MAKE_TARGET=linux-ppc
     elif [[ $OS == winnt && $ARCH == x86 && $WORD == 64 ]] ; then
         MAKE_IMAGE_TARGET=winnt-x86.64
+        MAKE_TARGET=winnt-x86-64
     elif [[ $ARCH == x86 && $WORD == 64 ]] ; then
         MAKE_IMAGE_TARGET=unix-x86.64
-       else
+        MAKE_TARGET=$OS-x86-64
+    else
         MAKE_IMAGE_TARGET=$ARCH.$WORD
+        MAKE_TARGET=$OS-$ARCH-$WORD
     fi
     BOOT_IMAGE=boot.$MAKE_IMAGE_TARGET.image
 }
@@ -335,9 +339,21 @@ cd_factor() {
     check_ret cd
 }
 
+check_makefile_exists() {
+    if [[ ! -e "Makefile" ]] ; then
+        echo ""
+        echo "***Makefile not found***"
+        echo "You are likely in the wrong directory."
+        echo "Run this script from your factor directory:"
+        echo "     ./build-support/factor.sh"
+        exit 6
+    fi
+}
+
 invoke_make() {
-   $MAKE $MAKE_OPTS $*
-   check_ret $MAKE
+    check_makefile_exists
+    $MAKE $MAKE_OPTS $*
+    check_ret $MAKE
 }
 
 make_clean() {
index d457d6805e5371a2c1e8902a512886ac4a7f5c2c..9a100d9795a36442696f1638c90574c25c0aa32e 100644 (file)
@@ -1,5 +1,6 @@
 IN: byte-vectors.tests\r
-USING: tools.test byte-vectors vectors sequences kernel ;\r
+USING: tools.test byte-vectors vectors sequences kernel\r
+prettyprint ;\r
 \r
 [ 0 ] [ 123 <byte-vector> length ] unit-test\r
 \r
@@ -12,3 +13,5 @@ USING: tools.test byte-vectors vectors sequences kernel ;
 ] unit-test\r
 \r
 [ t ] [ BV{ } byte-vector? ] unit-test\r
+\r
+[ "BV{ }" ] [ BV{ } unparse ] unit-test\r
index 577dd153a12a2f6e4e64305944a4340a349aef34..8cfa671a8b2ef4b2a8dcd106dc48bce09863a9af 100644 (file)
@@ -167,6 +167,6 @@ M: slice hashcode* [ sequence-hashcode ] recursive-hashcode ;
 
 M: hashtable hashcode*
     [
-        dup assoc-size 1 number=
+        dup assoc-size 1 eq?
         [ assoc-hashcode ] [ nip assoc-size ] if
     ] recursive-hashcode ;
index becd855653bf9789d3be7872f14854ab08d529eb..396b3e8f9a7cfa1ea48a380a8ed897733ac2a793 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax words classes classes.algebra
 definitions kernel alien sequences math quotations
-generic.standard generic.math combinators ;
+generic.standard generic.math combinators prettyprint ;
 IN: generic
 
 ARTICLE: "method-order" "Method precedence"
@@ -46,7 +46,8 @@ $nl
 "Low-level method constructor:"
 { $subsection <method> }
 "A " { $emphasis "method specifier" } " refers to a method and implements the " { $link "definition-protocol" } ":"
-{ $subsection method-spec } ;
+{ $subsection method-spec }
+{ $see-also see see-methods } ;
 
 ARTICLE: "method-combination" "Custom method combination"
 "Abstractly, a generic word can be thought of as a big chain of type conditional tests applied to the top of the stack, with methods as the bodies of each test. The " { $emphasis "method combination" } " is this control flow glue between the set of methods, and several aspects of it can be customized:"
index cb5f9f37919625e24f90fe44496021964e599c56..e2818a51b21958db220c5230e9c94a9106f774d1 100644 (file)
@@ -76,9 +76,6 @@ TUPLE: check-method class generic ;
 PREDICATE: method-body < word
     "method-generic" word-prop >boolean ;
 
-M: method-body inline?
-    "method-generic" word-prop inline? ;
-
 M: method-body stack-effect
     "method-generic" word-prop stack-effect ;
 
index 077795c4b786a8101e0a67954a807412720af8eb..ebe1c08cb3d1e426018736f739c0ffd3fb953c63 100644 (file)
@@ -3,7 +3,7 @@
 USING: arrays generic hashtables kernel kernel.private math
 namespaces make sequences words quotations layouts combinators
 sequences.private classes classes.builtin classes.algebra
-definitions math.order ;
+definitions math.order math.private ;
 IN: generic.math
 
 PREDICATE: math-class < class
@@ -62,13 +62,17 @@ ERROR: no-math-method left right generic ;
         2drop object-method
     ] if ;
 
+SYMBOL: picker
+
 : math-vtable ( picker quot -- quot )
     [
-        >r
-        , \ tag ,
-        num-tags get [ bootstrap-type>class ]
-        r> compose map ,
-        \ dispatch ,
+        swap picker set
+        picker get , [ tag 0 eq? ] %
+        num-tags get swap [ bootstrap-type>class ] prepose map
+        unclip ,
+        [
+            picker get , [ tag 1 fixnum-fast ] % , \ dispatch ,
+        ] [ ] make , \ if ,
     ] [ ] make ; inline
 
 TUPLE: math-combination ;
@@ -85,8 +89,7 @@ M: math-combination perform-combination
         ] [
             over object-method
         ] if nip
-    ] math-vtable nip
-    define ;
+    ] math-vtable nip define ;
 
 PREDICATE: math-generic < generic ( word -- ? )
     "combination" word-prop math-combination? ;
index 87e2f1c9b1c35774428570b0d33d4ca3e569a0c6..d1bc6d7417d883e8518f21225d884f7e407f2b72 100644 (file)
@@ -22,13 +22,14 @@ C: <lo-tag-dispatch-engine> lo-tag-dispatch-engine
         "type" word-prop
     ] if ;
 
+: sort-tags ( assoc -- alist ) >alist sort-keys reverse ;
+
 M: lo-tag-dispatch-engine engine>quot
     methods>> engines>quots*
     [ >r lo-tag-number r> ] assoc-map
     [
         picker % [ tag ] % [
-            >alist sort-keys reverse
-            linear-dispatch-quot
+            sort-tags linear-dispatch-quot
         ] [
             num-tags get direct-dispatch-quot
         ] if-small? %
@@ -51,10 +52,11 @@ C: <hi-tag-dispatch-engine> hi-tag-dispatch-engine
     \ hi-tag def>> ;
 
 M: hi-tag-dispatch-engine engine>quot
-    methods>> engines>quots* [ >r hi-tag-number r> ] assoc-map
+    methods>> engines>quots*
+    [ >r hi-tag-number r> ] assoc-map
     [
         picker % hi-tag-quot % [
-            linear-dispatch-quot
+            sort-tags linear-dispatch-quot
         ] [
             num-tags get , \ fixnum-fast ,
             [ >r num-tags get - r> ] assoc-map
index 04368099fb54b055aaa1fc49d7c544a8570079ce..78a97547fdd7619e857d6b3cb4fa058d56dff858 100644 (file)
@@ -79,9 +79,6 @@ M: engine-word stack-effect
     [ extra-values ] [ stack-effect ] bi
     dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
 
-M: engine-word inline?
-    "tuple-dispatch-generic" word-prop inline? ;
-
 M: engine-word crossref? "forgotten" word-prop not ;
 
 M: engine-word irrelevant? drop t ;
index 1d98dec87c7370e00cf26a5a39fad1fad2c21fb4..15913b46bee1bf6d4579011eaf4d289f6fd2eef6 100644 (file)
@@ -16,7 +16,7 @@ HELP: standard-combination
 { $examples
     "A generic word for append strings and characters to a sequence, dispatching on the object underneath the top of the stack:"
     { $code
-        "G: build-string 1 standard-combination ;"
+        "GENERIC# build-string 1 ( elt str -- )"
         "M: string build-string swap push-all ;"
         "M: integer build-string push ;"
     }
diff --git a/core/grouping/authors.txt b/core/grouping/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/core/grouping/grouping-docs.factor b/core/grouping/grouping-docs.factor
deleted file mode 100644 (file)
index 3b3a98e..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-USING: help.markup help.syntax sequences strings ;
-IN: grouping
-
-ARTICLE: "grouping" "Groups and clumps"
-"Splitting a sequence into disjoint, fixed-length subsequences:"
-{ $subsection group }
-"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
-{ $subsection groups }
-{ $subsection <groups> }
-{ $subsection <sliced-groups> }
-"Splitting a sequence into overlapping, fixed-length subsequences:"
-{ $subsection clump }
-"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: grouping 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 grouping ;"
-        "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 grouping ;"
-        "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: grouping 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: grouping 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
deleted file mode 100644 (file)
index dc3d970..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
-
-[ { { 1 2 } { 2 3 } } ] [ { 1 2 3 } 2 <sliced-clumps> [ >array ] map ] unit-test
diff --git a/core/grouping/grouping.factor b/core/grouping/grouping.factor
deleted file mode 100644 (file)
index 332fd26..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-! 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 read-only } { n read-only } ;
-
-: check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline
-
-: new-groups ( seq n class -- groups )
-    >r check-groups r> boa ; inline
-
-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 < clumps ;
-
-: <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
deleted file mode 100644 (file)
index 3695129..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Grouping sequence elements into subsequences
diff --git a/core/grouping/tags.txt b/core/grouping/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
index 32fda7d2fb02a8d329f2a742a3a0f5c5618d19d5..0fde459a25b129dadba2b9c97d9b55165882cac1 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel kernel.private slots.private math
-assocs math.private sequences sequences.private vectors grouping ;
+assocs math.private sequences sequences.private vectors ;
 IN: hashtables
 
 TUPLE: hashtable
@@ -128,15 +128,32 @@ M: hashtable set-at ( value key hash -- )
 : associate ( value key -- hash )
     2 <hashtable> [ set-at ] keep ;
 
+<PRIVATE
+
+: push-unsafe ( elt seq -- )
+    [ length ] keep
+    [ underlying>> set-array-nth ]
+    [ >r 1+ r> (>>length) ]
+    2bi ; inline
+
+PRIVATE>
+
 M: hashtable >alist
-    array>> 2 <groups> [ first tombstone? not ] filter ;
+    [ array>> [ length 2/ ] keep ] [ assoc-size <vector> ] bi [
+        [
+            >r
+            >r 1 fixnum-shift-fast r>
+            [ array-nth ] [ >r 1 fixnum+fast r> array-nth ] 2bi r>
+            pick tombstone? [ 3drop ] [ [ 2array ] dip push-unsafe ] if
+        ] 2curry each
+    ] keep { } like ;
 
 M: hashtable clone
     (clone) [ clone ] change-array ;
 
 M: hashtable equal?
     over hashtable? [
-        2dup [ assoc-size ] bi@ number=
+        2dup [ assoc-size ] bi@ eq?
         [ assoc= ] [ 2drop f ] if
     ] [ 2drop f ] if ;
 
index 92471acb5d0b680088b8d8d93679a11eadb7e3db..ba25e7950921ef7cda3e4e08a0332bbf9dcfbadc 100644 (file)
@@ -5,8 +5,10 @@ ABOUT: "io.encodings"
 
 ARTICLE: "io.encodings" "I/O encodings"
 "Bytes can't be understood in isolation as text. They must be interpreted under a certain encoding. Factor provides utilities for dealing with encoded text by declaring that a stream has a particular encoding, and utilities to encode and decode strings."
-{ $subsection "encodings-constructors" }
 { $subsection "encodings-descriptors" }
+{ $subsection "encodings-constructors" }
+{ $subsection "io.encodings.string" }
+"New types of encodings can be defined:"
 { $subsection "encodings-protocol" } ;
 
 ARTICLE: "encodings-constructors" "Manually constructing an encoded stream"
index 9a856882022c97a4677f6c0284cc62974f4df5be..80b515b13f32bf57c4bc3c6ca4d3a9903f2dc110 100644 (file)
@@ -1,5 +1,5 @@
-USING: help.markup help.syntax io strings
-       io.backend io.files.private quotations ;
+USING: help.markup help.syntax io strings arrays io.backend
+io.files.private quotations ;
 IN: io.files
 
 ARTICLE: "file-streams" "Reading and writing files"
@@ -323,6 +323,10 @@ HELP: with-directory-files
 { $values { "path" "a pathname string" } { "quot" quotation } }
 { $description "Calls the quotation with the directory file names on the stack and with the directory set as the " { $link current-directory } ".  Restores the current directory after the quotation is called." } ;
 
+HELP: file-systems
+{ $values { "array" array } }
+{ $description "Returns an array of " { $link file-system-info } " objects returned by iterating the mount points and calling " { $link file-system-info } " on each." } ;
+
 HELP: file-system-info
 { $values
 { "path" "a pathname string" }
index 9899f5a014eb85801209764d1c0be5a258f36ab7..ca8125d9362ca475e6c78245ace99981476de2a3 100644 (file)
@@ -184,6 +184,8 @@ SYMBOL: +unknown+
 
 ! File-system
 
+HOOK: file-systems os ( -- array )
+
 TUPLE: file-system-info device-name mount-point type free-space ;
 
 HOOK: file-system-info os ( path -- file-system-info )
index 61e10a9c005f76fe7e0676f765398e41430e340f..71f3980a6c2c412d8a3a9c82dbf4a5f7d996c142 100644 (file)
@@ -644,7 +644,7 @@ $nl
 HELP: loop
 { $values
      { "pred" quotation } }
-{ $description "Calls the quotation repeatedly until the output is true." }
+     { $description "Calls the quotation repeatedly until it outputs " { $link f } "." }
 { $examples "Loop until we hit a zero:"
     { $unchecked-example "USING: kernel random math io ; "
     " [ \"hi\" write bl 10 random zero? not ] loop"
index f410148566031854b890939451c7ed7a4c01c04b..c84699539d8f2024e21a78b1afd8dcdd4f7fef5a 100644 (file)
@@ -99,7 +99,10 @@ HELP: counter
 
 HELP: with-scope
 { $values { "quot" quotation } }
-{ $description "Calls the quotation in a new namespace. Any variables set by the quotation are discarded when it returns." } ;
+{ $description "Calls the quotation in a new namespace. Any variables set by the quotation are discarded when it returns." }
+{ $examples
+    { $example "USING: math namespaces prettyprint ;" "IN: scratchpad" "SYMBOL: x" "0 x set" "[ x [ 5 + ] change x get . ] with-scope x get ." "5\n0" }
+} ;
 
 HELP: with-variable
 { $values { "value" object } { "key" "a variable, by convention a symbol" } { "quot" quotation } }
index 1d8d1f0714a4f0a0098e1fd437ff707c478ebbf3..d33f5cd6d93d5424fa5b9a9745b64e8c54fafe40 100644 (file)
@@ -69,7 +69,7 @@ $nl
 { $subsection POSTPONE: PRIVATE> }
 { $subsection "vocabulary-search-errors" }
 { $subsection "vocabulary-search-shadow" }
-{ $see-also "words" } ;
+{ $see-also "words" "qualified" } ;
 
 ARTICLE: "reading-ahead" "Reading ahead"
 "Parsing words can consume input:"
index a86715b0732a81e265aaaf97f632d3460d7a35a2..ed8fc4510b5d2897ad9bb85da0197ca25d707bbc 100644 (file)
@@ -71,10 +71,10 @@ ERROR: no-current-vocab ;
         ] keep
     ] { } map>assoc ;
 
-TUPLE: no-word-error name ;
+ERROR: no-word-error name ;
 
 : no-word ( name -- newword )
-    dup no-word-error boa
+    dup no-word-error boa
     swap words-named [ forward-reference? not ] filter
     word-restarts throw-restarts
     dup vocabulary>> (use+) ;
index e45d98a3df1dfbbda1b59a93b98368fd010e5b91..5a30654f03677a00c34a14ea3b6d97c9a01a0c62 100644 (file)
@@ -33,7 +33,7 @@ M: string new-resizable drop <sbuf> ;
 M: string like
     drop dup string? [
         dup sbuf? [
-            dup length over underlying>> length number= [
+            dup length over underlying>> length eq? [
                 underlying>> dup reset-string-hashcode
             ] [
                 >string
index a75b97c0404a1ada155aefac6b2ee52b63690a74..8cb7f1c0882a84c9261d632dd0de75e51e8ef914 100644 (file)
@@ -841,7 +841,8 @@ HELP: unclip
 
 HELP: unclip-slice
 { $values { "seq" sequence } { "rest-slice" slice } { "first" object } }
-{ $description "Outputs a tail sequence and the first element of " { $snippet "seq" } "; the tail sequence consists of all elements of " { $snippet "seq" } " but the first. Unlike " { $link unclip } ", this word does not make a copy of the input sequence, and runs in constant time." } ;
+{ $description "Outputs a tail sequence and the first element of " { $snippet "seq" } "; the tail sequence consists of all elements of " { $snippet "seq" } " but the first. Unlike " { $link unclip } ", this word does not make a copy of the input sequence, and runs in constant time." }
+{ $examples { $example "USING: math.order prettyprint sequences ;" "{ 3 -1 -10 5 7 } unclip-slice [ min ] reduce ." "-10" } } ;
 
 HELP: unclip-last
 { $values { "seq" sequence } { "butlast" sequence } { "last" object } }
index 4f4a0cadad627f36825507b8074f45259dbcf207..767cec48301c0ac4f1d969b3f5e746af888b1fc7 100644 (file)
@@ -1,6 +1,6 @@
 IN: slots.tests
 USING: math accessors slots strings generic.standard kernel
-tools.test generic words parser eval ;
+tools.test generic words parser eval math.functions ;
 
 TUPLE: r/w-test foo ;
 
@@ -34,3 +34,18 @@ TUPLE: hello length ;
 
 [ f ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test
 [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
+
+! Test protocol slots
+SLOT: my-protocol-slot-test
+
+TUPLE: protocol-slot-test-tuple x ;
+
+M: protocol-slot-test-tuple my-protocol-slot-test>> x>> sq ;
+M: protocol-slot-test-tuple (>>my-protocol-slot-test) [ sqrt ] dip (>>x) ;
+
+[ 9 ] [ T{ protocol-slot-test-tuple { x 3 } } my-protocol-slot-test>> ] unit-test
+
+[ 4.0 ] [
+    T{ protocol-slot-test-tuple { x 3 } } clone
+    [ 7 + ] change-my-protocol-slot-test x>>
+] unit-test
index d4ae60ca9469852b11fbfb09cd2ce79fd1744611..72c79928cb34bb50888f859c5193b23da11045d9 100644 (file)
@@ -97,16 +97,16 @@ ERROR: bad-slot-value value class ;
 : setter-word ( name -- word )
     ">>" prepend (( object value -- object )) create-accessor ;
 
-: define-setter ( slot-spec -- )
-    name>> dup setter-word dup deferred? [
+: define-setter ( name -- )
+    dup setter-word dup deferred? [
         [ \ over , swap writer-word , ] [ ] make define-inline
     ] [ 2drop ] if ;
 
 : changer-word ( name -- word )
     "change-" prepend (( object quot -- object )) create-accessor ;
 
-: define-changer ( slot-spec -- )
-    name>> dup changer-word dup deferred? [
+: define-changer ( name -- )
+    dup changer-word dup deferred? [
         [
             [ over >r >r ] %
             over reader-word ,
@@ -119,8 +119,8 @@ ERROR: bad-slot-value value class ;
     [ define-reader ]
     [
         dup read-only>> [ 2drop ] [
-            [ define-setter drop ]
-            [ define-changer drop ]
+            [ name>> define-setter drop ]
+            [ name>> define-changer drop ]
             [ define-writer ]
             2tri
         ] if
@@ -131,10 +131,10 @@ ERROR: bad-slot-value value class ;
 
 : define-protocol-slot ( name -- )
     {
-        [ reader-word drop ]
-        [ writer-word drop ]
-        [ setter-word drop ]
-        [ changer-word drop ]
+        [ reader-word define-simple-generic ]
+        [ writer-word define-simple-generic ]
+        [ define-setter ]
+        [ define-changer ]
     } cleave ;
 
 ERROR: no-initial-value class ;
index 42d711b32ba66957d114e76b2aedcc5a59c9c58a..1e3d675068069c79aa420adc0a2e43d7814a6f10 100644 (file)
@@ -1 +1,2 @@
 collections
+algorithms
index 8ff5a7caf4b63981cd531ce4d796822c4b739cbb..944286cce567d72bbd5f01b30c015e76a22cc297 100644 (file)
@@ -20,7 +20,7 @@ PRIVATE>
 
 M: string equal?
     over string? [
-        over hashcode over hashcode number=
+        over hashcode over hashcode eq?
         [ sequence= ] [ 2drop f ] if
     ] [
         2drop f
index 8a4f7e7bd25ad5a2610cdc1f5b1c8ad29509ec87..66c60dc06e5c322b1a94820e428903749f7817f3 100644 (file)
@@ -135,9 +135,7 @@ compiled-generic-crossref global [ H{ } assoc-like ] change-at
     [ compiled-generic-crossref get delete-at ]
     tri ;
 
-GENERIC: inline? ( word -- ? )
-
-M: word inline? "inline" word-prop ;
+: inline? ( word -- ? ) "inline" word-prop ; inline
 
 SYMBOL: visited
 
index 7b523e9a8c78d8e8f0ac655526ceba0370ead17a..0a5d5f8703e888a42aeb786101aa099f61eecd4c 100644 (file)
@@ -1,5 +1,5 @@
 IN: advice
-USING: help.markup help.syntax tools.annotations words ;
+USING: help.markup help.syntax tools.annotations words coroutines ;
 
 HELP: make-advised
 { $values { "word" "a word to annotate in preparation of advising" } }
@@ -16,6 +16,11 @@ HELP: advised?
 { $values { "word" "a word" } { "?" "t or f, indicating if " { $snippet "word" } " is advised" } }
 { $description "Determines whether or not the given word has any advice on it." } ;
 
+HELP: ad-do-it
+{ $values { "input" "an object" } { "result" "an object" } }
+{ $description "Calls either the next applicable around advice or the main body, returning back to the point it was called from when finished.  This word should only be called from inside advice." }
+{ $see-also coyield } ;
+
 ARTICLE: "advice" "Advice"
 "Advice is a simple way of adding additition functionality to words by adding 'hooks' to a word, which can act before, after, or around the calling of the word." ;
 
index 17b60c8fb1e85ff7ee2cf245a99249fa0ba9ecf8..be16150c2e003931ca520ce4d337264709188d10 100644 (file)
@@ -1,40 +1,94 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences math tools.test advice parser namespaces ;
+USING: kernel sequences io io.streams.string math tools.test advice math.parser
+parser namespaces multiline eval words assocs ;
 IN: advice.tests
 
 [
-: foo "foo" ; 
-\ foo make-advised
+    [ ad-do-it ] must-fail
+    
+    : foo "foo" ; 
+    \ foo make-advised
  
-  { "bar" "foo" } [
-     [ "bar" ] "barify" \ foo advise-before
-     foo ] unit-test
+    { "bar" "foo" } [
+        [ "bar" ] "barify" \ foo advise-before
+        foo
+    ] unit-test
  
-  { "bar" "foo" "baz" } [
-      [ "baz" ] "bazify" \ foo advise-after
-      foo ] unit-test
+    { "bar" "foo" "baz" } [
+        [ "baz" ] "bazify" \ foo advise-after
+        foo
+    ] unit-test
  
-  { "foo" "baz" } [
-     "barify" \ foo before remove-advice
-     foo ] unit-test
+    { "foo" "baz" } [
+        "barify" \ foo before remove-advice
+        foo
+    ] unit-test
  
-: bar ( a -- b ) 1+ ;
-\ bar make-advised
-
-  { 11 } [
-     [ 2 * ] "double" \ bar advise-before
-     5 bar
-  ] unit-test 
-
-  { 11/3 } [
-      [ 3 / ] "third" \ bar advise-after
-      5 bar
-  ] unit-test
-
-  { -2 } [
-      [ -1 * ad-do-it 3 + ] "frobnobicate" \ bar advise-around
-      5 bar
-  ] unit-test
+    : bar ( a -- b ) 1+ ;
+    \ bar make-advised
+
+    { 11 } [
+        [ 2 * ] "double" \ bar advise-before
+        5 bar
+    ] unit-test 
+
+    { 11/3 } [
+        [ 3 / ] "third" \ bar advise-after
+        5 bar
+    ] unit-test
+
+    { -2 } [
+        [ -1 * ad-do-it 3 + ] "frobnobicate" \ bar advise-around
+        5 bar
+    ] unit-test
+
+    : add ( a b -- c ) + ;
+    \ add make-advised
+
+    { 10 } [
+        [ [ 2 * ] bi@ ] "double-args" \ add advise-before
+        2 3 add
+    ] unit-test 
+
+    { 21 } [
+        [ 3 * ad-do-it 1- ] "around1" \ add advise-around
+        2 3 add
+    ] unit-test 
+
+!     { 9 } [
+!         [ [ 1- ] bi@ ad-do-it 2 / ] "around2" \ add advise-around
+!         2 3 add
+!     ] unit-test
+
+!     { { "around1" "around2" } } [
+!         \ add around word-prop keys
+!     ] unit-test
+
+    { 5 f } [
+        \ add unadvise
+        2 3 add \ add advised?
+    ] unit-test
+
+!     : quux ( a b -- c ) * ;
+
+!     { f t 3+3/4 } [
+!         <" USING: advice kernel math ;
+!            IN: advice.tests
+!            \ quux advised?
+!            ADVISE: quux halve before [ 2 / ] bi@ ;
+!            \ quux advised? 
+!            3 5 quux"> eval
+!     ] unit-test
+
+!     { 3+3/4 "1+1/2 2+1/2 3+3/4" } [
+!         <" USING: advice kernel math math.parser io io.streams.string ;
+!            IN: advice.tests
+!            ADVISE: quux log around
+!            2dup [ number>string write " " write ] bi@
+!            ad-do-it 
+!            dup number>string write ;
+!            [ 3 5 quux ] with-string-writer"> eval
+!     ] unit-test 
  
- ] with-scope
\ No newline at end of file
+] with-scope
\ No newline at end of file
index 6a7d46f935cfb40b5321a20c5ea0e1edc019f7fc..383812e602721e12807e57e9615d5d1aabca881a 100644 (file)
@@ -1,24 +1,31 @@
 ! Copyright (C) 2008 James Cash
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences symbols fry words assocs tools.annotations coroutines ;
+USING: kernel sequences symbols fry words assocs linked-assocs tools.annotations
+coroutines lexer parser quotations arrays namespaces continuations ;
 IN: advice
 
-SYMBOLS: before after around advised ;
+SYMBOLS: before after around advised in-advice? ;
+
+: advised? ( word -- ? )
+    advised word-prop ;
+
+DEFER: make-advised
 
 <PRIVATE
+: init-around-co ( quot -- coroutine )
+    \ coreset suffix cocreate ;
+PRIVATE>
+
 : advise ( quot name word loc --  )
+    dup around eq? [ [ init-around-co ] 3dip ] when
+    over advised? [ over make-advised ] unless
     word-prop set-at ;
-PRIVATE>
     
-: advise-before ( quot name word --  )
-    before advise ;
+: advise-before ( quot name word --  ) before advise ;
     
-: advise-after ( quot name word --  )
-    after advise ;
+: advise-after ( quot name word --  ) after advise ;
 
-: advise-around ( quot name word --  )
-    [ \ coterminate suffix ] 2dip
-    around advise ;
+: advise-around ( quot name word --  ) around advise ;
 
 : get-advice ( word type -- seq )
     word-prop values ;
@@ -30,20 +37,27 @@ PRIVATE>
     after get-advice [ call ] each ;
 
 : call-around ( main word --  )
-    around get-advice [ cocreate ] map tuck 
-    [ [ coresume ] each ] [ call ] [ reverse [ coresume ] each ] tri* ;
+    t in-advice? [
+        around get-advice tuck 
+        [ [ coresume ] each ] [ call ] [ <reversed> [ coresume ] each ] tri*
+    ] with-variable ;
 
 : remove-advice ( name word loc --  )
     word-prop delete-at ;
 
 : ad-do-it ( input -- result )
-    coyield ;
-
-: advised? ( word -- ? )
-    advised word-prop ;
+    in-advice? get [ "ad-do-it should only be called inside 'around' advice" throw ] unless coyield ;
     
 : make-advised ( word -- )
     [ dup [ over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ]
-    [ { before after around } [ H{ } clone swap set-word-prop ] with each ] 
+    [ { before after around } [ <linked-hash> swap set-word-prop ] with each ] 
     [ t advised set-word-prop ] tri ;
-    
\ No newline at end of file
+
+: unadvise ( word --  )
+    [ reset ] [ { before after around advised } [ f swap set-word-prop ] with each ] bi ;
+
+: ADVISE: ! word adname location => word adname quot loc
+    scan-word scan scan-word parse-definition swap [ spin ] dip advise ; parsing
+    
+: UNADVISE:    
+    scan-word parsed \ unadvise parsed ; parsing
\ No newline at end of file
index a87b65d9385e1d7bacdffbd0fafa7325f17ffd3e..f4274299b1c36db85f10b2e3f3e38f18fded1061 100644 (file)
@@ -1,3 +1 @@
-advice
-aspect
-annotations
+extensions
index 037cf4111856d460a23008d3d72bdba3b0a0c7d6..cfb0462877d732b39dbc42380fdc2f027a90e526 100644 (file)
@@ -30,7 +30,7 @@ IN: automata.ui
 
 : draw-bitmap ( bitmap -- ) GL_POINTS glBegin (draw-bitmap) glEnd ;
 
-: display ( -- ) black set-color bitmap> draw-bitmap ;
+: display ( -- ) black gl-color bitmap> draw-bitmap ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
index 168c5d9ace1c70d3f543dad8c8c13e923a2b3b29..8b3c0baf764ea70f7f4748bb5c43553c2b554d21 100755 (executable)
@@ -1,12 +1,15 @@
 USING: tools.deploy.config ;
-V{
-    { deploy-ui? t }
-    { deploy-io 1 }
-    { deploy-reflection 1 }
-    { deploy-compiler? t }
+H{
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
-    { "stop-after-last-window?" t }
+    { deploy-ui? t }
+    { deploy-io 2 }
+    { deploy-threads? t }
+    { deploy-word-defs? f }
+    { deploy-compiler? t }
+    { deploy-unicode? f }
     { deploy-name "Boids" }
+    { "stop-after-last-window?" t }
+    { deploy-reflection 1 }
 }
diff --git a/extra/builder/build/build.factor b/extra/builder/build/build.factor
deleted file mode 100644 (file)
index e9f5898..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-
-USING: io.files io.launcher io.encodings.utf8 prettyprint
-       builder.util builder.common builder.child builder.release
-       builder.report builder.email builder.cleanup ;
-
-IN: builder.build
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: create-build-dir ( -- )
-  datestamp >stamp
-  build-dir make-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: enter-build-dir  ( -- ) build-dir set-current-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: clone-builds-factor ( -- )
-  { "git" "clone" builds/factor } to-strings try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: record-id ( -- )
-  "factor"
-    [ git-id "../git-id" utf8 [ . ] with-file-writer ]
-  with-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: build ( -- )
-  reset-status
-  create-build-dir
-  enter-build-dir
-  clone-builds-factor
-  record-id
-  build-child
-  release
-  report
-  email-report
-  cleanup ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-MAIN: build
\ No newline at end of file
diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor
deleted file mode 100644 (file)
index 29daa81..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-USING: kernel debugger io.files threads calendar 
-       builder.common
-       builder.updates
-       builder.build ;
-
-IN: builder
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: build-loop ( -- )
-  builds-check
-  [
-    builds/factor set-current-directory
-    new-code-available? [ build ] when
-  ]
-  try
-  5 minutes sleep
-  build-loop ;
-
-MAIN: build-loop
\ No newline at end of file
diff --git a/extra/builder/child/child.factor b/extra/builder/child/child.factor
deleted file mode 100644 (file)
index 0f701df..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-USING: namespaces debugger io.files io.launcher accessors bootstrap.image
-       calendar builder.util builder.common ;
-
-IN: builder.child
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-clean ( -- ) { gnu-make "clean" } to-strings try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-vm ( -- )
-  <process>
-    gnu-make         >>command
-    "../compile-log" >>stdout
-    +stdout+         >>stderr
-  try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: builds-factor-image ( -- img ) builds/factor my-boot-image-name append-path ;
-
-: copy-image ( -- )
-  builds-factor-image ".." copy-file-into
-  builds-factor-image "."  copy-file-into ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: boot-cmd ( -- cmd )
-  { "./factor" { "-i=" my-boot-image-name } "-no-user-init" } to-strings ;
-
-: boot ( -- )
-  <process>
-    boot-cmd      >>command
-    +closed+      >>stdin
-    "../boot-log" >>stdout
-    +stdout+      >>stderr
-    60 minutes    >>timeout
-  try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: test-cmd ( -- cmd ) { "./factor" "-run=builder.test" } ;
-
-: test ( -- )
-  <process>
-    test-cmd      >>command
-    +closed+      >>stdin
-    "../test-log" >>stdout
-    +stdout+      >>stderr
-    240 minutes   >>timeout
-  try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: (build-child) ( -- )
-  make-clean
-  make-vm      status-vm   on
-  copy-image
-  boot         status-boot on
-  test         status-test on
-               status      on ;
-
-: build-child ( -- )
-  "factor" set-current-directory
-    [ (build-child) ] try
-  ".." set-current-directory ;
\ No newline at end of file
diff --git a/extra/builder/cleanup/cleanup.factor b/extra/builder/cleanup/cleanup.factor
deleted file mode 100644 (file)
index e601506..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-USING: kernel namespaces io.files io.launcher bootstrap.image
-       builder.util builder.common ;
-
-IN: builder.cleanup
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: builder-debug
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: compress-image ( -- ) { "bzip2" my-boot-image-name } to-strings try-process ;
-
-: delete-child-factor ( -- )
-  build-dir [ { "rm" "-rf" "factor" } try-process ] with-directory ;
-
-: cleanup ( -- )
-  builder-debug get f =
-    [
-      "test-log" delete-file
-      delete-child-factor
-      compress-image
-    ]
-  when ;
-
diff --git a/extra/builder/common/common.factor b/extra/builder/common/common.factor
deleted file mode 100644 (file)
index 474606e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-
-USING: kernel namespaces sequences splitting
-       io io.files io.launcher io.encodings.utf8 prettyprint
-       vars builder.util ;
-
-IN: builder.common
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: upload-to-factorcode
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: builds-dir
-
-: builds ( -- path )
-  builds-dir get
-  home "/builds" append
-  or ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: stamp
-
-: builds/factor ( -- path ) builds "factor" append-path ;
-: build-dir     ( -- path ) builds stamp>   append-path ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: prepare-build-machine ( -- )
-  builds make-directory
-  builds
-    [ { "git" "clone" "git://factorcode.org/git/factor.git" } try-process ]
-  with-directory ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: builds-check ( -- ) builds exists? not [ prepare-build-machine ] when ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: status-vm
-SYMBOL: status-boot
-SYMBOL: status-test
-SYMBOL: status-build
-SYMBOL: status-release
-SYMBOL: status
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: reset-status ( -- )
-  { status-vm status-boot status-test status-build status-release status }
-    [ off ]
-  each ;
diff --git a/extra/builder/email/email.factor b/extra/builder/email/email.factor
deleted file mode 100644 (file)
index ecde47f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-USING: kernel namespaces accessors smtp builder.util builder.common ;
-
-IN: builder.email
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: builder-from
-SYMBOL: builder-recipients
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: subject-status ( -- str ) status get [ "report" ] [ "error" ] if ;
-
-: subject ( -- str ) { "builder@" host-name* ": " subject-status } to-string ;
-
-: email-report ( -- )
-  <email>
-    builder-from get       >>from
-    builder-recipients get >>to
-    subject                >>subject
-    "report" file>string   >>body
-  send-email ;
-
diff --git a/extra/builder/release/archive/archive.factor b/extra/builder/release/archive/archive.factor
deleted file mode 100644 (file)
index 2515343..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-
-USING: kernel combinators system sequences io.files io.launcher prettyprint
-       builder.util
-       builder.common ;
-
-IN: builder.release.archive
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: base-name ( -- string )
-  { "factor" [ os unparse ] cpu- stamp> } to-strings "-" join ;
-
-: extension ( -- extension )
-  {
-    { [ os winnt?  ] [ ".zip"    ] }  
-    { [ os macosx? ] [ ".dmg"    ] }
-    { [ os unix?   ] [ ".tar.gz" ] }
-  }
-  cond ;
-
-: archive-name ( -- string ) base-name extension append ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: windows-archive-cmd ( -- cmd ) { "zip" "-r" archive-name "factor" } ;
-
-! : macosx-archive-cmd ( -- cmd )
-!   { "hdiutil" "create"
-!               "-srcfolder" "factor"
-!               "-fs" "HFS+"
-!               "-volname" "factor"
-!               archive-name } ;
-
-: macosx-archive-cmd ( -- cmd )
-  { "mkdir" "dmg-root" }                         try-process
-  { "cp" "-r" "factor" "dmg-root" }              try-process
-  { "hdiutil" "create"
-              "-srcfolder" "dmg-root"
-              "-fs" "HFS+"
-              "-volname" "factor"
-              archive-name }          to-strings try-process
-  { "rm" "-rf" "dmg-root" }                      try-process
-  { "true" } ;
-
-: unix-archive-cmd ( -- cmd ) { "tar" "-cvzf" archive-name "factor" } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: archive-cmd ( -- cmd )
-  {
-    { [ os windows? ] [ windows-archive-cmd ] }
-    { [ os macosx?  ] [ macosx-archive-cmd  ] }
-    { [ os unix?    ] [ unix-archive-cmd    ] }
-  }
-  cond ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-archive ( -- ) archive-cmd to-strings try-process ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: releases ( -- path )
-  builds "releases" append-path
-  dup exists? not
-    [ dup make-directory ]
-  when ;
-
-: save-archive ( -- ) archive-name releases move-file-into ;
\ No newline at end of file
diff --git a/extra/builder/release/branch/branch.factor b/extra/builder/release/branch/branch.factor
deleted file mode 100644 (file)
index 6b1266b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-USING: kernel system namespaces sequences prettyprint io.files io.launcher
-       bootstrap.image
-       builder.util
-       builder.common ;
-
-IN: builder.release.branch
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: branch-name ( -- string ) "clean-" platform append ;
-
-: refspec ( -- string ) "master:" branch-name append ;
-
-: push-to-clean-branch ( -- )
-  { "git" "push" "factorcode.org:/git/factor.git" refspec }
-  to-strings
-  try-process ;
-
-: upload-clean-image ( -- )
-  {
-    "scp"
-    my-boot-image-name
-    { "factorcode.org:/var/www/factorcode.org/newsite/images/clean/" platform }
-  }
-  to-strings
-  try-process ;
-
-: (update-clean-branch) ( -- )
-  "factor"
-    [
-      push-to-clean-branch
-      upload-clean-image
-    ]
-  with-directory ;
-
-: update-clean-branch ( -- )
-  upload-to-factorcode get
-    [ (update-clean-branch) ]
-  when ;
diff --git a/extra/builder/release/release.factor b/extra/builder/release/release.factor
deleted file mode 100644 (file)
index 28ce3e8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
-USING: kernel debugger system namespaces sequences splitting combinators
-       io io.files io.launcher prettyprint bootstrap.image
-       combinators.cleave
-       builder.util
-       builder.common
-       builder.release.branch
-       builder.release.tidy
-       builder.release.archive
-       builder.release.upload ;
-
-IN: builder.release
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: (release) ( -- )
-  update-clean-branch
-  tidy
-  make-archive
-  upload
-  save-archive
-  status-release on ;
-
-: clean-build? ( -- ? )
-  { "load-everything-vocabs" "test-all-vocabs" } [ eval-file empty? ] all? ;
-
-: release ( -- ) [ clean-build? [ (release) ] when ] try ;
\ No newline at end of file
diff --git a/extra/builder/release/tidy/tidy.factor b/extra/builder/release/tidy/tidy.factor
deleted file mode 100644 (file)
index f8f27e7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-USING: kernel system io.files io.launcher builder.util ;
-
-IN: builder.release.tidy
-
-: common-files ( -- seq )
-  {
-    "boot.x86.32.image"
-    "boot.x86.64.image"
-    "boot.macosx-ppc.image"
-    "boot.linux-ppc.image"
-    "vm"
-    "temp"
-    "logs"
-    ".git"
-    ".gitignore"
-    "Makefile"
-    "unmaintained"
-    "build-support"
-  } ;
-
-: remove-common-files ( -- )
-  { "rm" "-rf" common-files } to-strings try-process ;
-
-: remove-factor-app ( -- )
-  os macosx? not [ { "rm" "-rf" "Factor.app" } try-process ] when ;
-
-: tidy ( -- )
-  "factor" [ remove-factor-app remove-common-files ] with-directory ;
diff --git a/extra/builder/release/upload/upload.factor b/extra/builder/release/upload/upload.factor
deleted file mode 100644 (file)
index 19d3936..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-
-USING: kernel namespaces make sequences arrays io io.files
-       builder.util
-       builder.common
-       builder.release.archive ;
-
-IN: builder.release.upload
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: upload-host
-
-SYMBOL: upload-username
-
-SYMBOL: upload-directory
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: remote-location ( -- dest )
-  upload-directory get platform append ;
-
-: remote-archive-name ( -- dest )
-  remote-location "/" archive-name 3append ;
-
-: temp-archive-name ( -- dest )
-  remote-archive-name ".incomplete" append ;
-
-: upload-command ( -- args )
-  "scp"
-  archive-name
-  [ upload-username get % "@" % upload-host get % ":" % temp-archive-name % ] "" make
-  3array ;
-
-: rename-command ( -- args )
-  [
-    "ssh" ,
-    upload-host get ,
-    "-l" ,
-    upload-username get ,
-    "mv" ,
-    temp-archive-name ,
-    remote-archive-name ,
-  ] { } make ;
-
-: upload-temp-file ( -- )
-  upload-command [ "Error uploading binary to factorcode" print ] run-or-bail ;
-
-: rename-temp-file ( -- )
-  rename-command [ "Error renaming binary on factorcode" print ] run-or-bail ;
-
-: upload ( -- )
-  upload-to-factorcode get
-    [ upload-temp-file rename-temp-file ]
-  when ;
diff --git a/extra/builder/report/report.factor b/extra/builder/report/report.factor
deleted file mode 100644 (file)
index 2ac8482..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-USING: kernel namespaces debugger system io io.files io.sockets
-       io.encodings.utf8 prettyprint benchmark
-       builder.util builder.common ;
-
-IN: builder.report
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: (report) ( -- )
-
-  "Build machine:   " write host-name             print
-  "CPU:             " write cpu                   .
-  "OS:              " write os                    .
-  "Build directory: " write build-dir             print
-  "git id:          " write "git-id" eval-file    print nl
-
-  status-vm   get f = [ "compile-log"  cat   "vm compile error" throw ] when
-  status-boot get f = [ "boot-log" 100 cat-n "Boot error"       throw ] when
-  status-test get f = [ "test-log" 100 cat-n "Test error"       throw ] when
-
-  "Boot time: " write "boot-time" eval-file milli-seconds>time print
-  "Load time: " write "load-time" eval-file milli-seconds>time print
-  "Test time: " write "test-time" eval-file milli-seconds>time print nl
-
-  "Did not pass load-everything: " print "load-everything-vocabs" cat
-      
-  "Did not pass test-all: "        print "test-all-vocabs"        cat
-                                         "test-failures"          cat
-      
-  "help-lint results:"             print "help-lint"              cat
-
-  "Benchmarks: " print "benchmarks" eval-file benchmarks. ;
-
-: report ( -- ) "report" utf8 [ [ (report) ] try ] with-file-writer ;
\ No newline at end of file
diff --git a/extra/builder/test/test.factor b/extra/builder/test/test.factor
deleted file mode 100644 (file)
index 2a0769f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-USING: kernel namespaces assocs
-       io.files io.encodings.utf8 prettyprint 
-       help.lint
-       benchmark
-       tools.time
-       bootstrap.stage2
-       tools.test tools.vocabs
-       builder.util ;
-
-IN: builder.test
-
-: do-load ( -- )
-  try-everything keys "../load-everything-vocabs" utf8 [ . ] with-file-writer ;
-
-: do-tests ( -- )
-  run-all-tests
-    [ keys "../test-all-vocabs" utf8 [ .              ] with-file-writer ]
-    [      "../test-failures"   utf8 [ test-failures. ] with-file-writer ]
-  bi ;
-
-: do-help-lint ( -- )
-  "" run-help-lint "../help-lint" utf8 [ typos. ] with-file-writer ;
-
-: do-benchmarks ( -- )
-  run-benchmarks "../benchmarks" utf8 [ . ] with-file-writer ;
-
-: do-all ( -- )
-  bootstrap-time get   "../boot-time" utf8 [ . ] with-file-writer
-  [ do-load  ] benchmark "../load-time" utf8 [ . ] with-file-writer
-  [ do-tests ] benchmark "../test-time" utf8 [ . ] with-file-writer
-  do-help-lint
-  do-benchmarks ;
-
-MAIN: do-all
\ No newline at end of file
diff --git a/extra/builder/updates/updates.factor b/extra/builder/updates/updates.factor
deleted file mode 100644 (file)
index a818455..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-USING: kernel io.launcher bootstrap.image bootstrap.image.download
-       builder.util builder.common ;
-
-IN: builder.updates
-
-: git-pull-cmd ( -- cmd )
-  {
-    "git"
-    "pull"
-    "--no-summary"
-    "git://factorcode.org/git/factor.git"
-    "master"
-  } ;
-
-: updates-available? ( -- ? )
-  git-id
-  git-pull-cmd try-process
-  git-id
-  = not ;
-
-: new-image-available? ( -- ? )
-  my-boot-image-name need-new-image?
-    [ download-my-image t ]
-    [ f ]
-  if ;
-
-: new-code-available? ( -- ? )
-  updates-available?
-  new-image-available?
-  or ;
\ No newline at end of file
diff --git a/extra/builder/util/util.factor b/extra/builder/util/util.factor
deleted file mode 100644 (file)
index 32d1e45..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-
-USING: kernel words namespaces classes parser continuations
-       io io.files io.launcher io.sockets
-       math math.parser
-       system
-       combinators sequences splitting quotations arrays strings tools.time
-       sequences.deep accessors assocs.lib
-       io.encodings.utf8
-       combinators.cleave calendar calendar.format eval ;
-
-IN: builder.util
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: minutes>ms ( min -- ms ) 60 * 1000 * ;
-
-: file>string ( file -- string ) utf8 file-contents ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-DEFER: to-strings
-
-: to-string ( obj -- str )
-  dup class
-    {
-      { \ string    [ ] }
-      { \ quotation [ call ] }
-      { \ word      [ execute ] }
-      { \ fixnum    [ number>string ] }
-      { \ array     [ to-strings concat ] }
-    }
-  case ;
-
-: to-strings ( seq -- str )
-  dup [ string? ] all?
-    [ ]
-    [ [ to-string ] map flatten ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: host-name* ( -- name ) host-name "." split first ;
-
-: datestamp ( -- string )
-  now
-    { year>> month>> day>> hour>> minute>> } <arr>
-  [ pad-00 ] map "-" join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: milli-seconds>time ( n -- string )
-  1000 /i 60 /mod >r 60 /mod r> 3array [ pad-00 ] map ":" join ;
-
-: eval-file ( file -- obj ) utf8 file-contents eval ;
-
-: cat ( file -- ) utf8 file-contents print ;
-
-: run-or-bail ( desc quot -- )
-  [ [ try-process ] curry   ]
-  [ [ throw       ] compose ]
-  bi*
-  recover ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USING: bootstrap.image bootstrap.image.download io.streams.null ;
-
-: retrieve-image ( -- ) [ my-arch download-image ] with-null-stream ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: longer? ( seq seq -- ? ) [ length ] bi@ > ; 
-
-: maybe-tail* ( seq n -- seq )
-  2dup longer?
-    [ tail* ]
-    [ drop  ]
-  if ;
-
-: cat-n ( file n -- )
-  [ utf8 file-lines ] [ ] bi*
-  maybe-tail*
-  [ print ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USE: prettyprint
-
-: to-file ( object file -- ) utf8 [ . ] with-file-writer ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: cpu- ( -- cpu ) cpu unparse "." split "-" join ;
-
-: platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: gnu-make ( -- string )
-  os { freebsd openbsd netbsd } member? [ "gmake" ] [ "make" ] if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: git-id ( -- id )
-  { "git" "show" } utf8 <process-reader> [ readln ] with-input-stream
-  " " split second ;
index 32312aed8950cd0e87c2416c5f4b2f735adc2615..1bbaf796ade41f3e01c1818059a0f91c97490993 100755 (executable)
@@ -1,7 +1,8 @@
-USING: accessors alien.c-types arrays combinators destructors http.client
-io io.encodings.ascii io.files kernel math math.matrices math.parser
-math.vectors opengl opengl.capabilities opengl.gl sequences sequences.lib
-splitting vectors words ;
+USING: accessors alien.c-types arrays combinators destructors
+http.client io io.encodings.ascii io.files kernel math
+math.matrices math.parser math.vectors opengl
+opengl.capabilities opengl.gl opengl.demo-support sequences
+sequences.lib splitting vectors words ;
 IN: bunny.model
 
 : numbers ( str -- seq )
index cd67b8b33e249ea1d39f49b8d43245f20d70d65d..6117a0fdeae8b1843c00d4fc7f93330b7a128aa2 100755 (executable)
@@ -1,7 +1,7 @@
 USING: arrays bunny.model bunny.cel-shaded continuations
 destructors kernel math multiline opengl opengl.shaders
-opengl.framebuffers opengl.gl opengl.capabilities sequences
-ui.gadgets combinators accessors ;
+opengl.framebuffers opengl.gl opengl.demo-support
+opengl.capabilities sequences ui.gadgets combinators accessors ;
 IN: bunny.outlined
 
 STRING: outlined-pass1-fragment-shader-main-source
diff --git a/extra/cairo-demo/authors.txt b/extra/cairo-demo/authors.txt
new file mode 100755 (executable)
index 0000000..4a2736d
--- /dev/null
@@ -0,0 +1 @@
+Sampo Vuori
diff --git a/extra/cairo-demo/cairo-demo.factor b/extra/cairo-demo/cairo-demo.factor
new file mode 100644 (file)
index 0000000..ea92e79
--- /dev/null
@@ -0,0 +1,73 @@
+! Cairo "Hello World" demo
+!  Copyright (c) 2007 Sampo Vuori
+!    License: http://factorcode.org/license.txt
+!
+! This example is an adaptation of the following cairo sample code:
+!  http://cairographics.org/samples/text/
+
+
+USING: cairo.ffi math math.constants byte-arrays kernel ui ui.render
+           ui.gadgets opengl.gl accessors ;
+
+IN: cairo-demo
+
+
+: make-image-array ( -- array )
+  384 256 4 * * <byte-array> ;
+
+: convert-array-to-surface ( array -- cairo_surface_t )
+  CAIRO_FORMAT_ARGB32 384 256 over 4 *
+  cairo_image_surface_create_for_data ;
+
+
+TUPLE: cairo-demo-gadget < gadget image-array cairo-t ;
+
+M: cairo-demo-gadget draw-gadget* ( gadget -- )
+    0 0 glRasterPos2i
+    1.0 -1.0 glPixelZoom
+    >r 384 256 GL_RGBA GL_UNSIGNED_BYTE r>
+    image-array>> glDrawPixels ;
+
+: create-surface ( gadget -- cairo_surface_t )
+    make-image-array [ swap (>>image-array) ] keep
+    convert-array-to-surface ;
+
+: init-cairo ( gadget -- cairo_t )
+   create-surface cairo_create ;
+
+M: cairo-demo-gadget pref-dim* drop { 384 256 0 } ;
+
+: draw-hello-world ( gadget -- )
+  cairo-t>>
+  dup "Sans" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_BOLD cairo_select_font_face
+  dup 90.0 cairo_set_font_size
+  dup 10.0 135.0 cairo_move_to
+  dup "Hello" cairo_show_text
+  dup 70.0 165.0 cairo_move_to
+  dup "World" cairo_text_path
+  dup 0.5 0.5 1 cairo_set_source_rgb
+  dup cairo_fill_preserve
+  dup 0 0 0 cairo_set_source_rgb
+  dup 2.56 cairo_set_line_width
+  dup cairo_stroke
+  dup 1 0.2 0.2 0.6 cairo_set_source_rgba
+  dup 10.0 135.0 5.12 0 pi 2 * cairo_arc
+  dup cairo_close_path
+  dup 70.0 165.0 5.12 0 pi 2 * cairo_arc
+  cairo_fill ;
+
+M: cairo-demo-gadget graft* ( gadget -- )
+  dup dup init-cairo swap (>>cairo-t) draw-hello-world ;
+
+M: cairo-demo-gadget ungraft* ( gadget -- )
+   cairo-t>> cairo_destroy ;
+
+: <cairo-demo-gadget> ( -- gadget )
+  cairo-demo-gadget new-gadget ;
+
+: run ( -- )
+  [
+        <cairo-demo-gadget> "Hello World from Factor!" open-window
+  ] with-ui ;
+
+MAIN: run
diff --git a/extra/cairo/authors.txt b/extra/cairo/authors.txt
new file mode 100644 (file)
index 0000000..68d35d1
--- /dev/null
@@ -0,0 +1,2 @@
+Sampo Vuori
+Doug Coleman
diff --git a/extra/cairo/cairo.factor b/extra/cairo/cairo.factor
new file mode 100755 (executable)
index 0000000..aa7d115
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: cairo.ffi kernel accessors sequences
+namespaces fry continuations destructors ;
+IN: cairo
+
+TUPLE: cairo-t alien ;
+C: <cairo-t> cairo-t
+M: cairo-t dispose ( alien -- ) alien>> cairo_destroy ;
+
+TUPLE: cairo-surface-t alien ;
+C: <cairo-surface-t> cairo-surface-t
+M: cairo-surface-t dispose ( alien -- ) alien>> cairo_surface_destroy ;
+
+: check-cairo ( cairo_status_t -- )
+    dup CAIRO_STATUS_SUCCESS = [ drop ]
+    [ cairo_status_to_string "Cairo error: " prepend throw ] if ;
+
+SYMBOL: cairo
+: cr ( -- cairo ) cairo get ;
+
+: (with-cairo) ( cairo-t quot -- )
+    >r alien>> cairo r> [ cr cairo_status check-cairo ]
+    compose with-variable ; inline
+    
+: with-cairo ( cairo quot -- )
+    >r <cairo-t> r> [ (with-cairo) ] curry with-disposal ; inline
+
+: (with-surface) ( cairo-surface-t quot -- )
+    >r alien>> r> [ cairo_surface_status check-cairo ] bi ; inline
+
+: with-surface ( cairo_surface quot -- )
+    >r <cairo-surface-t> r> [ (with-surface) ] curry with-disposal ; inline
+
+: with-cairo-from-surface ( cairo_surface quot -- )
+    '[ cairo_create _ with-cairo ] with-surface ; inline
diff --git a/extra/cairo/ffi/ffi.factor b/extra/cairo/ffi/ffi.factor
new file mode 100644 (file)
index 0000000..db18320
--- /dev/null
@@ -0,0 +1,950 @@
+! Copyright (c) 2007 Sampo Vuori
+! Copyright (c) 2008 Matthew Willis
+!
+! Adapted from cairo.h, version 1.5.14
+! License: http://factorcode.org/license.txt
+
+USING: system combinators alien alien.syntax kernel 
+alien.c-types accessors sequences arrays ui.gadgets ;
+
+IN: cairo.ffi
+<< "cairo" {
+    { [ os winnt? ] [ "libcairo-2.dll" ] }
+    { [ os macosx? ] [ "/opt/local/lib/libcairo.dylib" ] }
+    { [ os unix? ] [ "libcairo.so.2" ] }
+} cond "cdecl" add-library >>
+
+LIBRARY: cairo
+
+FUNCTION: int cairo_version ( ) ;
+FUNCTION: char* cairo_version_string ( ) ;
+
+TYPEDEF: int cairo_bool_t
+
+! I am leaving these and other void* types as opaque structures
+TYPEDEF: void* cairo_t
+TYPEDEF: void* cairo_surface_t
+
+C-STRUCT: cairo_matrix_t
+    { "double" "xx" }
+    { "double" "yx" }
+    { "double" "xy" }
+    { "double" "yy" }
+    { "double" "x0" }
+    { "double" "y0" } ;
+
+TYPEDEF: void* cairo_pattern_t
+
+TYPEDEF: void* cairo_destroy_func_t
+: cairo-destroy-func ( quot -- callback )
+    >r "void" { "void*" } "cdecl" r> alien-callback ; inline
+
+! See cairo.h for details
+C-STRUCT: cairo_user_data_key_t
+    { "int" "unused" } ;
+
+TYPEDEF: int cairo_status_t
+C-ENUM:
+    CAIRO_STATUS_SUCCESS
+    CAIRO_STATUS_NO_MEMORY
+    CAIRO_STATUS_INVALID_RESTORE
+    CAIRO_STATUS_INVALID_POP_GROUP
+    CAIRO_STATUS_NO_CURRENT_POINT
+    CAIRO_STATUS_INVALID_MATRIX
+    CAIRO_STATUS_INVALID_STATUS
+    CAIRO_STATUS_NULL_POINTER
+    CAIRO_STATUS_INVALID_STRING
+    CAIRO_STATUS_INVALID_PATH_DATA
+    CAIRO_STATUS_READ_ERROR
+    CAIRO_STATUS_WRITE_ERROR
+    CAIRO_STATUS_SURFACE_FINISHED
+    CAIRO_STATUS_SURFACE_TYPE_MISMATCH
+    CAIRO_STATUS_PATTERN_TYPE_MISMATCH
+    CAIRO_STATUS_INVALID_CONTENT
+    CAIRO_STATUS_INVALID_FORMAT
+    CAIRO_STATUS_INVALID_VISUAL
+    CAIRO_STATUS_FILE_NOT_FOUND
+    CAIRO_STATUS_INVALID_DASH
+    CAIRO_STATUS_INVALID_DSC_COMMENT
+    CAIRO_STATUS_INVALID_INDEX
+    CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
+    CAIRO_STATUS_TEMP_FILE_ERROR
+    CAIRO_STATUS_INVALID_STRIDE ;
+
+TYPEDEF: int cairo_content_t
+: CAIRO_CONTENT_COLOR          HEX: 1000 ;
+: CAIRO_CONTENT_ALPHA          HEX: 2000 ;
+: CAIRO_CONTENT_COLOR_ALPHA    HEX: 3000 ;
+
+TYPEDEF: void* cairo_write_func_t
+: cairo-write-func ( quot -- callback )
+    >r "cairo_status_t" { "void*" "uchar*" "int" }
+    "cdecl" r> alien-callback ; inline
+                          
+TYPEDEF: void* cairo_read_func_t
+: cairo-read-func ( quot -- callback )
+    >r "cairo_status_t" { "void*" "uchar*" "int" }
+    "cdecl" r> alien-callback ; inline
+
+! Functions for manipulating state objects
+FUNCTION: cairo_t*
+cairo_create ( cairo_surface_t* target ) ;
+
+FUNCTION: cairo_t*
+cairo_reference ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_destroy ( cairo_t* cr ) ;
+
+FUNCTION: uint
+cairo_get_reference_count ( cairo_t* cr ) ;
+
+FUNCTION: void*
+cairo_get_user_data ( cairo_t* cr, cairo_user_data_key_t* key ) ;
+
+FUNCTION: cairo_status_t
+cairo_set_user_data ( cairo_t* cr, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
+
+FUNCTION: void
+cairo_save ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_restore ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_push_group ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_push_group_with_content  ( cairo_t* cr, cairo_content_t content ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pop_group ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_pop_group_to_source ( cairo_t* cr ) ;
+
+! Modify state
+TYPEDEF: int cairo_operator_t
+C-ENUM:
+    CAIRO_OPERATOR_CLEAR
+
+    CAIRO_OPERATOR_SOURCE
+    CAIRO_OPERATOR_OVER
+    CAIRO_OPERATOR_IN
+    CAIRO_OPERATOR_OUT
+    CAIRO_OPERATOR_ATOP
+
+    CAIRO_OPERATOR_DEST
+    CAIRO_OPERATOR_DEST_OVER
+    CAIRO_OPERATOR_DEST_IN
+    CAIRO_OPERATOR_DEST_OUT
+    CAIRO_OPERATOR_DEST_ATOP
+
+    CAIRO_OPERATOR_XOR
+    CAIRO_OPERATOR_ADD
+    CAIRO_OPERATOR_SATURATE ;
+
+FUNCTION: void
+cairo_set_operator ( cairo_t* cr, cairo_operator_t op ) ;
+
+FUNCTION: void
+cairo_set_source ( cairo_t* cr, cairo_pattern_t* source ) ;
+
+FUNCTION: void
+cairo_set_source_rgb ( cairo_t* cr, double red, double green, double blue ) ;
+
+FUNCTION: void
+cairo_set_source_rgba ( cairo_t* cr, double red, double green, double blue, double alpha ) ;
+
+FUNCTION: void
+cairo_set_source_surface ( cairo_t* cr, cairo_surface_t* surface, double x, double y ) ;
+
+FUNCTION: void
+cairo_set_tolerance ( cairo_t* cr, double tolerance ) ;
+
+TYPEDEF: int cairo_antialias_t
+C-ENUM:
+    CAIRO_ANTIALIAS_DEFAULT
+    CAIRO_ANTIALIAS_NONE
+    CAIRO_ANTIALIAS_GRAY
+    CAIRO_ANTIALIAS_SUBPIXEL ;
+
+FUNCTION: void
+cairo_set_antialias ( cairo_t* cr, cairo_antialias_t antialias ) ;
+
+TYPEDEF: int cairo_fill_rule_t
+C-ENUM:
+    CAIRO_FILL_RULE_WINDING
+    CAIRO_FILL_RULE_EVEN_ODD ;
+
+FUNCTION: void
+cairo_set_fill_rule ( cairo_t* cr, cairo_fill_rule_t fill_rule ) ;
+
+FUNCTION: void
+cairo_set_line_width ( cairo_t* cr, double width ) ;
+
+TYPEDEF: int cairo_line_cap_t
+C-ENUM:
+    CAIRO_LINE_CAP_BUTT
+    CAIRO_LINE_CAP_ROUND
+    CAIRO_LINE_CAP_SQUARE ;
+
+FUNCTION: void
+cairo_set_line_cap ( cairo_t* cr, cairo_line_cap_t line_cap ) ;
+
+TYPEDEF: int cairo_line_join_t
+C-ENUM:
+    CAIRO_LINE_JOIN_MITER
+    CAIRO_LINE_JOIN_ROUND
+    CAIRO_LINE_JOIN_BEVEL ;
+
+FUNCTION: void
+cairo_set_line_join ( cairo_t* cr, cairo_line_join_t line_join ) ;
+
+FUNCTION: void
+cairo_set_dash ( cairo_t* cr, double* dashes, int num_dashes, double offset ) ;
+
+FUNCTION: void
+cairo_set_miter_limit ( cairo_t* cr, double limit ) ;
+
+FUNCTION: void
+cairo_translate ( cairo_t* cr, double tx, double ty ) ;
+
+FUNCTION: void
+cairo_scale ( cairo_t* cr, double sx, double sy ) ;
+
+FUNCTION: void
+cairo_rotate ( cairo_t* cr, double angle ) ;
+
+FUNCTION: void
+cairo_transform ( cairo_t* cr, cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_set_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_identity_matrix ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_user_to_device ( cairo_t* cr, double* x, double* y ) ;
+
+FUNCTION: void
+cairo_user_to_device_distance ( cairo_t* cr, double* dx, double* dy ) ;
+
+FUNCTION: void
+cairo_device_to_user ( cairo_t* cr, double* x, double* y ) ;
+
+FUNCTION: void
+cairo_device_to_user_distance ( cairo_t* cr, double* dx, double* dy ) ;
+
+! Path creation functions
+FUNCTION: void
+cairo_new_path ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_move_to ( cairo_t* cr, double x, double y ) ;
+
+FUNCTION: void
+cairo_new_sub_path ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_line_to ( cairo_t* cr, double x, double y ) ;
+
+FUNCTION: void
+cairo_curve_to ( cairo_t* cr, double x1, double y1, double x2, double y2, double x3, double y3 ) ;
+
+FUNCTION: void
+cairo_arc ( cairo_t* cr, double xc, double yc, double radius, double angle1, double angle2 ) ;
+
+FUNCTION: void
+cairo_arc_negative ( cairo_t* cr, double xc, double yc, double radius, double angle1, double angle2 ) ;
+
+FUNCTION: void
+cairo_rel_move_to ( cairo_t* cr, double dx, double dy ) ;
+
+FUNCTION: void
+cairo_rel_line_to ( cairo_t* cr, double dx, double dy ) ;
+
+FUNCTION: void
+cairo_rel_curve_to ( cairo_t* cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3 ) ;
+
+FUNCTION: void
+cairo_rectangle ( cairo_t* cr, double x, double y, double width, double height ) ;
+
+FUNCTION: void
+cairo_close_path ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_path_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
+
+! Painting functions
+FUNCTION: void
+cairo_paint ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_paint_with_alpha ( cairo_t* cr, double alpha ) ;
+
+FUNCTION: void
+cairo_mask ( cairo_t* cr, cairo_pattern_t* pattern ) ;
+
+FUNCTION: void
+cairo_mask_surface ( cairo_t* cr, cairo_surface_t* surface, double surface_x, double surface_y ) ;
+
+FUNCTION: void
+cairo_stroke ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_stroke_preserve ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_fill ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_fill_preserve ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_copy_page ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_show_page ( cairo_t* cr ) ;
+
+! Insideness testing
+FUNCTION: cairo_bool_t
+cairo_in_stroke ( cairo_t* cr, double x, double y ) ;
+
+FUNCTION: cairo_bool_t
+cairo_in_fill ( cairo_t* cr, double x, double y ) ;
+
+! Rectangular extents
+FUNCTION: void
+cairo_stroke_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
+
+FUNCTION: void
+cairo_fill_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
+
+! Clipping
+FUNCTION: void
+cairo_reset_clip ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_clip ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_clip_preserve ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_clip_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
+
+C-STRUCT: cairo_rectangle_t
+    { "double" "x" }
+    { "double" "y" }
+    { "double" "width" }
+    { "double" "height" } ;
+    
+C-STRUCT: cairo_rectangle_list_t
+    { "cairo_status_t"     "status" }
+    { "cairo_rectangle_t*" "rectangles" }
+    { "int"                "num_rectangles" } ;
+
+FUNCTION: cairo_rectangle_list_t*
+cairo_copy_clip_rectangle_list ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_rectangle_list_destroy ( cairo_rectangle_list_t* rectangle_list ) ;
+
+! Font/Text functions
+
+TYPEDEF: void* cairo_scaled_font_t
+
+TYPEDEF: void* cairo_font_face_t
+
+C-STRUCT: cairo_glyph_t
+  { "ulong"     "index" }
+  { "double"    "x" }
+  { "double"    "y" } ;
+
+C-STRUCT: cairo_text_extents_t
+    { "double" "x_bearing" }
+    { "double" "y_bearing" }
+    { "double" "width" }
+    { "double" "height" }
+    { "double" "x_advance" }
+    { "double" "y_advance" } ;
+
+C-STRUCT: cairo_font_extents_t
+    { "double" "ascent" }
+    { "double" "descent" }
+    { "double" "height" }
+    { "double" "max_x_advance" }
+    { "double" "max_y_advance" } ;
+
+TYPEDEF: int cairo_font_slant_t
+C-ENUM:
+    CAIRO_FONT_SLANT_NORMAL
+    CAIRO_FONT_SLANT_ITALIC
+    CAIRO_FONT_SLANT_OBLIQUE ;
+
+TYPEDEF: int cairo_font_weight_t
+C-ENUM:
+    CAIRO_FONT_WEIGHT_NORMAL
+    CAIRO_FONT_WEIGHT_BOLD ;
+
+TYPEDEF: int cairo_subpixel_order_t
+C-ENUM:
+    CAIRO_SUBPIXEL_ORDER_DEFAULT
+    CAIRO_SUBPIXEL_ORDER_RGB
+    CAIRO_SUBPIXEL_ORDER_BGR
+    CAIRO_SUBPIXEL_ORDER_VRGB
+    CAIRO_SUBPIXEL_ORDER_VBGR ;
+
+TYPEDEF: int cairo_hint_style_t
+C-ENUM:
+    CAIRO_HINT_STYLE_DEFAULT
+    CAIRO_HINT_STYLE_NONE
+    CAIRO_HINT_STYLE_SLIGHT
+    CAIRO_HINT_STYLE_MEDIUM
+    CAIRO_HINT_STYLE_FULL ;
+
+TYPEDEF: int cairo_hint_metrics_t
+C-ENUM:
+    CAIRO_HINT_METRICS_DEFAULT
+    CAIRO_HINT_METRICS_OFF
+    CAIRO_HINT_METRICS_ON ;
+
+TYPEDEF: void* cairo_font_options_t
+
+FUNCTION: cairo_font_options_t*
+cairo_font_options_create ( ) ;
+
+FUNCTION: cairo_font_options_t*
+cairo_font_options_copy ( cairo_font_options_t* original ) ;
+
+FUNCTION: void
+cairo_font_options_destroy ( cairo_font_options_t* options ) ;
+
+FUNCTION: cairo_status_t
+cairo_font_options_status ( cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_font_options_merge ( cairo_font_options_t* options, cairo_font_options_t* other ) ;
+
+FUNCTION: cairo_bool_t
+cairo_font_options_equal ( cairo_font_options_t* options, cairo_font_options_t* other ) ;
+
+FUNCTION: ulong
+cairo_font_options_hash ( cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_font_options_set_antialias ( cairo_font_options_t* options, cairo_antialias_t antialias ) ;
+
+FUNCTION: cairo_antialias_t
+cairo_font_options_get_antialias ( cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_font_options_set_subpixel_order ( cairo_font_options_t* options, cairo_subpixel_order_t subpixel_order ) ;
+
+FUNCTION: cairo_subpixel_order_t
+cairo_font_options_get_subpixel_order ( cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_font_options_set_hint_style ( cairo_font_options_t* options, cairo_hint_style_t hint_style ) ;
+
+FUNCTION: cairo_hint_style_t
+cairo_font_options_get_hint_style ( cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_font_options_set_hint_metrics ( cairo_font_options_t* options, cairo_hint_metrics_t hint_metrics ) ;
+
+FUNCTION: cairo_hint_metrics_t
+cairo_font_options_get_hint_metrics ( cairo_font_options_t* options ) ;
+
+! This interface is for dealing with text as text, not caring about the
+!  font object inside the the cairo_t.
+
+FUNCTION: void
+cairo_select_font_face ( cairo_t* cr, char* family, cairo_font_slant_t slant, cairo_font_weight_t weight ) ;
+
+FUNCTION: void
+cairo_set_font_size ( cairo_t* cr, double size ) ;
+
+FUNCTION: void
+cairo_set_font_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_get_font_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_set_font_options ( cairo_t* cr, cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_get_font_options ( cairo_t* cr, cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_set_font_face ( cairo_t* cr, cairo_font_face_t* font_face ) ;
+
+FUNCTION: cairo_font_face_t*
+cairo_get_font_face ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_set_scaled_font ( cairo_t* cr, cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: cairo_scaled_font_t*
+cairo_get_scaled_font ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_show_text ( cairo_t* cr, char* utf8 ) ;
+
+FUNCTION: void
+cairo_show_glyphs ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
+
+FUNCTION: void
+cairo_text_path  ( cairo_t* cr, char* utf8 ) ;
+
+FUNCTION: void
+cairo_glyph_path ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
+
+FUNCTION: void
+cairo_text_extents ( cairo_t* cr, char* utf8, cairo_text_extents_t* extents ) ;
+
+FUNCTION: void
+cairo_glyph_extents ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
+
+FUNCTION: void
+cairo_font_extents ( cairo_t* cr, cairo_font_extents_t* extents ) ;
+
+! Generic identifier for a font style
+
+FUNCTION: cairo_font_face_t*
+cairo_font_face_reference ( cairo_font_face_t* font_face ) ;
+
+FUNCTION: void
+cairo_font_face_destroy ( cairo_font_face_t* font_face ) ;
+
+FUNCTION: uint
+cairo_font_face_get_reference_count ( cairo_font_face_t* font_face ) ;
+
+FUNCTION: cairo_status_t
+cairo_font_face_status ( cairo_font_face_t* font_face ) ;
+
+TYPEDEF: int cairo_font_type_t
+C-ENUM:
+    CAIRO_FONT_TYPE_TOY
+    CAIRO_FONT_TYPE_FT
+    CAIRO_FONT_TYPE_WIN32
+    CAIRO_FONT_TYPE_QUARTZ ;
+
+FUNCTION: cairo_font_type_t
+cairo_font_face_get_type ( cairo_font_face_t* font_face ) ;
+
+FUNCTION: void* 
+cairo_font_face_get_user_data ( cairo_font_face_t* font_face, cairo_user_data_key_t* key ) ;
+
+FUNCTION: cairo_status_t
+cairo_font_face_set_user_data ( cairo_font_face_t* font_face, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
+
+! Portable interface to general font features.
+
+FUNCTION: cairo_scaled_font_t*
+cairo_scaled_font_create ( cairo_font_face_t* font_face, cairo_matrix_t* font_matrix, cairo_matrix_t* ctm, cairo_font_options_t* options ) ;
+
+FUNCTION: cairo_scaled_font_t*
+cairo_scaled_font_reference ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: void
+cairo_scaled_font_destroy ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: uint
+cairo_scaled_font_get_reference_count ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: cairo_status_t
+cairo_scaled_font_status ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: cairo_font_type_t
+cairo_scaled_font_get_type ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: void* 
+cairo_scaled_font_get_user_data ( cairo_scaled_font_t* scaled_font, cairo_user_data_key_t* key ) ;
+
+FUNCTION: cairo_status_t
+cairo_scaled_font_set_user_data ( cairo_scaled_font_t* scaled_font, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
+
+FUNCTION: void
+cairo_scaled_font_extents ( cairo_scaled_font_t* scaled_font, cairo_font_extents_t* extents ) ;
+
+FUNCTION: void
+cairo_scaled_font_text_extents ( cairo_scaled_font_t* scaled_font, char* utf8, cairo_text_extents_t* extents ) ;
+
+FUNCTION: void
+cairo_scaled_font_glyph_extents ( cairo_scaled_font_t* scaled_font, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
+
+FUNCTION: cairo_font_face_t*
+cairo_scaled_font_get_font_face ( cairo_scaled_font_t* scaled_font ) ;
+
+FUNCTION: void
+cairo_scaled_font_get_font_matrix ( cairo_scaled_font_t* scaled_font, cairo_matrix_t* font_matrix ) ;
+
+FUNCTION: void
+cairo_scaled_font_get_ctm ( cairo_scaled_font_t* scaled_font, cairo_matrix_t* ctm ) ;
+
+FUNCTION: void
+cairo_scaled_font_get_font_options ( cairo_scaled_font_t* scaled_font, cairo_font_options_t* options ) ;
+
+! Query functions
+
+FUNCTION: cairo_operator_t
+cairo_get_operator ( cairo_t* cr ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_get_source ( cairo_t* cr ) ;
+
+FUNCTION: double
+cairo_get_tolerance ( cairo_t* cr ) ;
+
+FUNCTION: cairo_antialias_t
+cairo_get_antialias ( cairo_t* cr ) ;
+
+FUNCTION: cairo_bool_t
+cairo_has_current_point ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_get_current_point ( cairo_t* cr, double* x, double* y ) ;
+
+FUNCTION: cairo_fill_rule_t
+cairo_get_fill_rule ( cairo_t* cr ) ;
+
+FUNCTION: double
+cairo_get_line_width ( cairo_t* cr ) ;
+
+FUNCTION: cairo_line_cap_t
+cairo_get_line_cap ( cairo_t* cr ) ;
+
+FUNCTION: cairo_line_join_t
+cairo_get_line_join ( cairo_t* cr ) ;
+
+FUNCTION: double
+cairo_get_miter_limit ( cairo_t* cr ) ;
+
+FUNCTION: int
+cairo_get_dash_count ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_get_dash ( cairo_t* cr, double* dashes, double* offset ) ;
+
+FUNCTION: void
+cairo_get_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_get_target ( cairo_t* cr ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_get_group_target ( cairo_t* cr ) ;
+
+TYPEDEF: int cairo_path_data_type_t
+C-ENUM:
+    CAIRO_PATH_MOVE_TO
+    CAIRO_PATH_LINE_TO
+    CAIRO_PATH_CURVE_TO
+    CAIRO_PATH_CLOSE_PATH ;
+
+! NEED TO DO UNION HERE
+C-STRUCT: cairo_path_data_t-point
+    { "double" "x" }
+    { "double" "y" } ;
+
+C-STRUCT: cairo_path_data_t-header
+    { "cairo_path_data_type_t" "type" }
+    { "int" "length" } ;
+
+C-UNION: cairo_path_data_t "cairo_path_data_t-point" "cairo_path_data_t-header" ;
+
+C-STRUCT: cairo_path_t
+    { "cairo_status_t"      "status" }
+    { "cairo_path_data_t*"  "data" }
+    { "int"                 "num_data" } ;
+
+FUNCTION: cairo_path_t*
+cairo_copy_path ( cairo_t* cr ) ;
+
+FUNCTION: cairo_path_t*
+cairo_copy_path_flat ( cairo_t* cr ) ;
+
+FUNCTION: void
+cairo_append_path ( cairo_t* cr, cairo_path_t* path ) ;
+
+FUNCTION: void
+cairo_path_destroy ( cairo_path_t* path ) ;
+
+! Error status queries
+
+FUNCTION: cairo_status_t
+cairo_status ( cairo_t* cr ) ;
+
+FUNCTION: char* 
+cairo_status_to_string ( cairo_status_t status ) ;
+
+! Surface manipulation
+
+FUNCTION: cairo_surface_t*
+cairo_surface_create_similar ( cairo_surface_t* other, cairo_content_t content, int width, int height ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_surface_reference ( cairo_surface_t* surface ) ;
+
+FUNCTION: void
+cairo_surface_finish ( cairo_surface_t* surface ) ;
+
+FUNCTION: void
+cairo_surface_destroy ( cairo_surface_t* surface ) ;
+
+FUNCTION: uint
+cairo_surface_get_reference_count ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_status_t
+cairo_surface_status ( cairo_surface_t* surface ) ;
+
+TYPEDEF: int cairo_surface_type_t
+C-ENUM:
+    CAIRO_SURFACE_TYPE_IMAGE
+    CAIRO_SURFACE_TYPE_PDF
+    CAIRO_SURFACE_TYPE_PS
+    CAIRO_SURFACE_TYPE_XLIB
+    CAIRO_SURFACE_TYPE_XCB
+    CAIRO_SURFACE_TYPE_GLITZ
+    CAIRO_SURFACE_TYPE_QUARTZ
+    CAIRO_SURFACE_TYPE_WIN32
+    CAIRO_SURFACE_TYPE_BEOS
+    CAIRO_SURFACE_TYPE_DIRECTFB
+    CAIRO_SURFACE_TYPE_SVG
+    CAIRO_SURFACE_TYPE_OS2
+    CAIRO_SURFACE_TYPE_WIN32_PRINTING
+    CAIRO_SURFACE_TYPE_QUARTZ_IMAGE ;
+
+FUNCTION: cairo_surface_type_t
+cairo_surface_get_type ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_content_t
+cairo_surface_get_content ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_status_t
+cairo_surface_write_to_png ( cairo_surface_t* surface, char* filename ) ;
+
+FUNCTION: cairo_status_t
+cairo_surface_write_to_png_stream ( cairo_surface_t* surface, cairo_write_func_t write_func, void* closure ) ;
+
+FUNCTION: void* 
+cairo_surface_get_user_data ( cairo_surface_t* surface, cairo_user_data_key_t* key ) ;
+
+FUNCTION: cairo_status_t
+cairo_surface_set_user_data ( cairo_surface_t* surface, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
+
+FUNCTION: void
+cairo_surface_get_font_options ( cairo_surface_t* surface, cairo_font_options_t* options ) ;
+
+FUNCTION: void
+cairo_surface_flush ( cairo_surface_t* surface ) ;
+
+FUNCTION: void
+cairo_surface_mark_dirty ( cairo_surface_t* surface ) ;
+
+FUNCTION: void
+cairo_surface_mark_dirty_rectangle ( cairo_surface_t* surface, int x, int y, int width, int height ) ;
+
+FUNCTION: void
+cairo_surface_set_device_offset ( cairo_surface_t* surface, double x_offset, double y_offset ) ;
+
+FUNCTION: void
+cairo_surface_get_device_offset ( cairo_surface_t* surface, double* x_offset, double* y_offset ) ;
+
+FUNCTION: void
+cairo_surface_set_fallback_resolution ( cairo_surface_t* surface, double x_pixels_per_inch, double y_pixels_per_inch ) ;
+
+FUNCTION: void
+cairo_surface_copy_page ( cairo_surface_t* surface ) ;
+
+FUNCTION: void
+cairo_surface_show_page ( cairo_surface_t* surface ) ;
+
+! Image-surface functions
+
+TYPEDEF: int cairo_format_t
+C-ENUM:
+    CAIRO_FORMAT_ARGB32
+    CAIRO_FORMAT_RGB24
+    CAIRO_FORMAT_A8
+    CAIRO_FORMAT_A1
+    CAIRO_FORMAT_RGB16_565 ;
+
+FUNCTION: cairo_surface_t*
+cairo_image_surface_create ( cairo_format_t format, int width, int height ) ;
+
+FUNCTION: int
+cairo_format_stride_for_width ( cairo_format_t format, int width ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_image_surface_create_for_data ( uchar* data, cairo_format_t format, int width, int height, int stride ) ;
+
+FUNCTION: uchar*
+cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_format_t
+cairo_image_surface_get_format ( cairo_surface_t* surface ) ;
+
+FUNCTION: int
+cairo_image_surface_get_width ( cairo_surface_t* surface ) ;
+
+FUNCTION: int
+cairo_image_surface_get_height ( cairo_surface_t* surface ) ;
+
+FUNCTION: int
+cairo_image_surface_get_stride ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_image_surface_create_from_png ( char* filename ) ;
+
+FUNCTION: cairo_surface_t*
+cairo_image_surface_create_from_png_stream ( cairo_read_func_t read_func, void* closure ) ;
+
+! Pattern creation functions
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_create_rgb ( double red, double green, double blue ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_create_rgba ( double red, double green, double blue, double alpha ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_create_for_surface ( cairo_surface_t* surface ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_create_linear ( double x0, double y0, double x1, double y1 ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_create_radial ( double cx0, double cy0, double radius0, double cx1, double cy1, double radius1 ) ;
+
+FUNCTION: cairo_pattern_t*
+cairo_pattern_reference ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: void
+cairo_pattern_destroy ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: uint
+cairo_pattern_get_reference_count ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_status ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: void*
+cairo_pattern_get_user_data ( cairo_pattern_t* pattern, cairo_user_data_key_t* key ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_set_user_data ( cairo_pattern_t* pattern, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
+
+TYPEDEF: int cairo_pattern_type_t
+C-ENUM:
+    CAIRO_PATTERN_TYPE_SOLID
+    CAIRO_PATTERN_TYPE_SURFACE
+    CAIRO_PATTERN_TYPE_LINEAR
+    CAIRO_PATTERN_TYPE_RADIA ;
+
+FUNCTION: cairo_pattern_type_t
+cairo_pattern_get_type ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: void
+cairo_pattern_add_color_stop_rgb ( cairo_pattern_t* pattern, double offset, double red, double green, double blue ) ;
+
+FUNCTION: void
+cairo_pattern_add_color_stop_rgba ( cairo_pattern_t* pattern, double offset, double red, double green, double blue, double alpha ) ;
+
+FUNCTION: void
+cairo_pattern_set_matrix ( cairo_pattern_t* pattern, cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_pattern_get_matrix ( cairo_pattern_t* pattern, cairo_matrix_t* matrix ) ;
+
+TYPEDEF: int cairo_extend_t
+C-ENUM:
+    CAIRO_EXTEND_NONE
+    CAIRO_EXTEND_REPEAT
+    CAIRO_EXTEND_REFLECT
+    CAIRO_EXTEND_PAD ;
+
+FUNCTION: void
+cairo_pattern_set_extend ( cairo_pattern_t* pattern, cairo_extend_t extend ) ;
+
+FUNCTION: cairo_extend_t
+cairo_pattern_get_extend ( cairo_pattern_t* pattern ) ;
+
+TYPEDEF: int cairo_filter_t
+C-ENUM:
+    CAIRO_FILTER_FAST
+    CAIRO_FILTER_GOOD
+    CAIRO_FILTER_BEST
+    CAIRO_FILTER_NEAREST
+    CAIRO_FILTER_BILINEAR
+    CAIRO_FILTER_GAUSSIAN ;
+
+FUNCTION: void
+cairo_pattern_set_filter ( cairo_pattern_t* pattern, cairo_filter_t filter ) ;
+
+FUNCTION: cairo_filter_t
+cairo_pattern_get_filter ( cairo_pattern_t* pattern ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_rgba ( cairo_pattern_t* pattern, double* red, double* green, double* blue, double* alpha ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_surface ( cairo_pattern_t* pattern, cairo_surface_t* *surface ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_color_stop_rgba ( cairo_pattern_t* pattern, int index, double* offset, double* red, double* green, double* blue, double* alpha ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_color_stop_count ( cairo_pattern_t* pattern, int* count ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_linear_points ( cairo_pattern_t* pattern, double* x0, double* y0, double* x1, double* y1 ) ;
+
+FUNCTION: cairo_status_t
+cairo_pattern_get_radial_circles ( cairo_pattern_t* pattern, double* x0, double* y0, double* r0, double* x1, double* y1, double* r1 ) ;
+
+! Matrix functions
+
+FUNCTION: void
+cairo_matrix_init ( cairo_matrix_t* matrix, double  xx, double  yx, double  xy, double  yy, double  x0, double  y0 ) ;
+
+FUNCTION: void
+cairo_matrix_init_identity ( cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_matrix_init_translate ( cairo_matrix_t* matrix, double tx, double ty ) ;
+
+FUNCTION: void
+cairo_matrix_init_scale ( cairo_matrix_t* matrix, double sx, double sy ) ;
+
+FUNCTION: void
+cairo_matrix_init_rotate ( cairo_matrix_t* matrix, double radians ) ;
+
+FUNCTION: void
+cairo_matrix_translate ( cairo_matrix_t* matrix, double tx, double ty ) ;
+
+FUNCTION: void
+cairo_matrix_scale ( cairo_matrix_t* matrix, double sx, double sy ) ;
+
+FUNCTION: void
+cairo_matrix_rotate ( cairo_matrix_t* matrix, double radians ) ;
+
+FUNCTION: cairo_status_t
+cairo_matrix_invert ( cairo_matrix_t* matrix ) ;
+
+FUNCTION: void
+cairo_matrix_multiply ( cairo_matrix_t* result, cairo_matrix_t* a, cairo_matrix_t* b ) ;
+
+FUNCTION: void
+cairo_matrix_transform_distance ( cairo_matrix_t* matrix, double* dx, double* dy ) ;
+
+FUNCTION: void
+cairo_matrix_transform_point ( cairo_matrix_t* matrix, double* x, double* y ) ;
+
+! Functions to be used while debugging (not intended for use in production code)
+FUNCTION: void
+cairo_debug_reset_static_data ( ) ;
diff --git a/extra/cairo/gadgets/gadgets.factor b/extra/cairo/gadgets/gadgets.factor
new file mode 100644 (file)
index 0000000..d160740
--- /dev/null
@@ -0,0 +1,58 @@
+! Copyright (C) 2008 Matthew Willis.
+! See http://factorcode.org/license.txt for BSD license.
+USING: sequences math opengl.gadgets kernel
+byte-arrays cairo.ffi cairo io.backend
+ui.gadgets accessors opengl.gl
+arrays fry classes ;
+
+IN: cairo.gadgets
+
+: width>stride ( width -- stride ) 4 * ;
+    
+: copy-cairo ( dim quot -- byte-array )
+    >r first2 over width>stride
+    [ * nip <byte-array> dup CAIRO_FORMAT_ARGB32 ]
+    [ cairo_image_surface_create_for_data ] 3bi
+    r> with-cairo-from-surface ; inline
+
+TUPLE: cairo-gadget < texture-gadget ;
+
+: <cairo-gadget> ( dim -- gadget )
+    cairo-gadget new-gadget
+        swap >>dim ;
+
+M: cairo-gadget cache-key* [ dim>> ] [ class ] bi 2array ;
+
+: render-cairo ( dim quot -- bytes format )
+    >r 2^-bounds r> copy-cairo GL_BGRA ; inline
+
+GENERIC: render-cairo* ( gadget -- )
+
+M: cairo-gadget render*
+    [ dim>> dup ] [ '[ _ render-cairo* ] ] bi
+    render-cairo render-bytes* ;
+
+! maybe also texture>png
+! : cairo>png ( gadget path -- )
+!    >r [ cairo>bytes CAIRO_FORMAT_ARGB32 ] [ width>> ]
+!    [ height>> ] tri over width>stride
+!    cairo_image_surface_create_for_data
+!    r> [ cairo_surface_write_to_png check-cairo ] curry with-surface ;
+
+: copy-surface ( surface -- )
+    cr swap 0 0 cairo_set_source_surface
+    cr cairo_paint ;
+
+TUPLE: png-gadget < texture-gadget path ;
+: <png> ( path -- gadget )
+    png-gadget new-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 render-bytes* ;
+
+M: png-gadget cache-key* path>> ;
diff --git a/extra/cairo/samples/samples.factor b/extra/cairo/samples/samples.factor
new file mode 100644 (file)
index 0000000..0f21142
--- /dev/null
@@ -0,0 +1,161 @@
+! Copyright (C) 2008 Matthew Willis
+! See http://factorcode.org/license.txt for BSD license.
+!
+! these samples are a subset of the samples on
+! http://cairographics.org/samples/
+USING: cairo cairo.ffi locals math.constants math
+io.backend kernel alien.c-types libc namespaces
+cairo.gadgets ui.gadgets accessors ;
+
+IN: cairo.samples
+
+TUPLE: arc-gadget < cairo-gadget ;
+M:: arc-gadget render-cairo* ( gadget -- )
+    [let | xc [ 128.0 ]
+           yc [ 128.0 ]
+           radius [ 100.0 ]
+           angle1 [ pi 1/4 * ]
+           angle2 [ pi ] |
+        cr 10.0 cairo_set_line_width
+        cr xc yc radius angle1 angle2 cairo_arc
+        cr cairo_stroke
+        
+        ! draw helping lines
+        cr 1 0.2 0.2 0.6 cairo_set_source_rgba
+        cr 6.0 cairo_set_line_width
+        
+        cr xc yc 10.0 0 2 pi * cairo_arc
+        cr cairo_fill
+        
+        cr xc yc radius angle1 angle1 cairo_arc
+        cr xc yc cairo_line_to
+        cr xc yc radius angle2 angle2 cairo_arc
+        cr xc yc cairo_line_to
+        cr cairo_stroke
+    ] ;
+
+TUPLE: clip-gadget < cairo-gadget ;
+M: clip-gadget render-cairo* ( gadget -- )
+    drop
+    cr 128 128 76.8 0 2 pi * cairo_arc
+    cr cairo_clip
+    cr cairo_new_path
+    
+    cr 0 0 256 256 cairo_rectangle
+    cr cairo_fill
+    cr 0 1 0 cairo_set_source_rgb
+    cr 0 0 cairo_move_to
+    cr 256 256 cairo_line_to
+    cr 256 0 cairo_move_to
+    cr 0 256 cairo_line_to
+    cr 10 cairo_set_line_width
+    cr cairo_stroke ;
+
+TUPLE: clip-image-gadget < cairo-gadget ;
+M:: clip-image-gadget render-cairo* ( gadget -- )
+    [let* | png [ "resource:misc/icons/Factor_128x128.png"
+                  normalize-path cairo_image_surface_create_from_png ]
+            w [ png cairo_image_surface_get_width ]
+            h [ png cairo_image_surface_get_height ] |
+        cr 128 128 76.8 0 2 pi * cairo_arc
+        cr cairo_clip
+        cr cairo_new_path
+
+        cr 192.0 w / 192.0 h / cairo_scale
+        cr png 32 32 cairo_set_source_surface
+        cr cairo_paint
+        png cairo_surface_destroy
+    ] ;
+
+TUPLE: dash-gadget < cairo-gadget ;
+M:: dash-gadget render-cairo* ( gadget -- )
+    [let | dashes [ { 50 10 10 10 } >c-double-array ]
+           ndash [ 4 ] |
+        cr dashes ndash -50 cairo_set_dash
+        cr 10 cairo_set_line_width
+        cr 128.0 25.6 cairo_move_to
+        cr 230.4 230.4 cairo_line_to
+        cr -102.4 0 cairo_rel_line_to
+        cr 51.2 230.4 51.2 128.0 128.0 128.0 cairo_curve_to
+        cr cairo_stroke
+    ] ;
+
+TUPLE: gradient-gadget < cairo-gadget ;
+M:: gradient-gadget render-cairo* ( gadget -- )
+    [let | pat [ 0 0 0 256 cairo_pattern_create_linear ]
+           radial [ 115.2 102.4 25.6 102.4 102.4 128.0
+                    cairo_pattern_create_radial ] |
+        pat 1 0 0 0 1 cairo_pattern_add_color_stop_rgba
+        pat 0 1 1 1 1 cairo_pattern_add_color_stop_rgba
+        cr 0 0 256 256 cairo_rectangle
+        cr pat cairo_set_source
+        cr cairo_fill
+        pat cairo_pattern_destroy
+        
+        radial 0 1 1 1 1 cairo_pattern_add_color_stop_rgba
+        radial 1 0 0 0 1 cairo_pattern_add_color_stop_rgba
+        cr radial cairo_set_source
+        cr 128.0 128.0 76.8 0 2 pi * cairo_arc
+        cr cairo_fill
+        radial cairo_pattern_destroy
+    ] ;
+
+TUPLE: text-gadget < cairo-gadget ;
+M: text-gadget render-cairo* ( gadget -- )
+    drop
+    cr "Serif" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_BOLD
+    cairo_select_font_face
+    cr 50 cairo_set_font_size
+    cr 10 135 cairo_move_to
+    cr "Hello" cairo_show_text
+    
+    cr 70 165 cairo_move_to
+    cr "factor" cairo_text_path
+    cr 0.5 0.5 1 cairo_set_source_rgb
+    cr cairo_fill_preserve
+    cr 0 0 0 cairo_set_source_rgb
+    cr 2.56 cairo_set_line_width
+    cr cairo_stroke
+    
+    ! draw helping lines
+    cr 1 0.2 0.2 0.6 cairo_set_source_rgba
+    cr 10 135 5.12 0 2 pi * cairo_arc
+    cr cairo_close_path
+    cr 70 165 5.12 0 2 pi * cairo_arc
+    cr cairo_fill ;
+
+TUPLE: utf8-gadget < cairo-gadget ;
+M: utf8-gadget render-cairo* ( gadget -- )
+    drop
+    cr "Sans" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_NORMAL
+    cairo_select_font_face
+    cr 50 cairo_set_font_size
+    "cairo_text_extents_t" malloc-object
+    cr "日本語" pick cairo_text_extents
+    cr over
+    [ cairo_text_extents_t-width 2 / ]
+    [ cairo_text_extents_t-x_bearing ] bi +
+    128 swap - pick
+    [ cairo_text_extents_t-height 2 / ]
+    [ cairo_text_extents_t-y_bearing ] bi +
+    128 swap - cairo_move_to
+    free
+    cr "日本語" cairo_show_text
+    
+    cr 1 0.2 0.2 0.6 cairo_set_source_rgba
+    cr 6 cairo_set_line_width
+    cr 128 0 cairo_move_to
+    cr 0 256 cairo_rel_line_to
+    cr 0 128 cairo_move_to
+    cr 256 0 cairo_rel_line_to
+    cr cairo_stroke ;
+ USING: quotations cairo.gadgets ui.gadgets.panes sequences ;
+ : samples ( -- )
+    {
+        arc-gadget clip-gadget clip-image-gadget dash-gadget
+        gradient-gadget text-gadget utf8-gadget
+    }
+    [ new-gadget { 256 256 } >>dim gadget. ] each ;
+ MAIN: samples
diff --git a/extra/cairo/summary.txt b/extra/cairo/summary.txt
new file mode 100644 (file)
index 0000000..f6cb370
--- /dev/null
@@ -0,0 +1 @@
+Cairo graphics library binding
diff --git a/extra/cairo/tags.txt b/extra/cairo/tags.txt
new file mode 100644 (file)
index 0000000..bb863cf
--- /dev/null
@@ -0,0 +1 @@
+bindings
index 99d5dbbc48201ccd26f947541c2eb4efda65c9f9..102de8fd22edc6caad73780ffd882f249130c918 100644 (file)
@@ -14,7 +14,7 @@ IN: cfdg
 
 SELF-SLOTS: hsva
 
-: clear-color ( color -- ) set-clear-color GL_COLOR_BUFFER_BIT glClear ;
+: clear-color ( color -- ) gl-clear-color GL_COLOR_BUFFER_BIT glClear ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -49,7 +49,7 @@ VAR: color-stack
 
 : push-color ( -- ) self> color-stack> push   self> clone >self ;
 
-: pop-color ( -- ) color-stack> pop dup >self set-color ;
+: pop-color ( -- ) color-stack> pop dup >self gl-color ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -80,11 +80,11 @@ VAR: threshold
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : circle ( -- )
-  self> set-color
+  self> gl-color
   gluNewQuadric dup 0 0.5 20 10 gluDisk gluDeleteQuadric ;
 
 : triangle ( -- )
-  self> set-color
+  self> gl-color
   GL_POLYGON glBegin
     0    0.577 glVertex2d
     0.5 -0.289 glVertex2d
@@ -92,7 +92,7 @@ VAR: threshold
   glEnd ;
 
 : square ( -- )
-  self> set-color
+  self> gl-color
   GL_POLYGON glBegin
     -0.5  0.5 glVertex2d
      0.5  0.5 glVertex2d
@@ -192,7 +192,7 @@ SYMBOL: dlist
 
   set-initial-color
 
-  self> set-color
+  self> gl-color
 
   start-shape> call
       
index 7edcfdd13839f8a2016a30f3263c70e2b4fb739a..1a2b8570c47f6dbe2abe29c771f1a8044f69fb3c 100644 (file)
@@ -1,2 +1,3 @@
 Chris Double
 Clemens F. Hofreither
+James Cash
index 327c60e01785c34e48488afccf452c95ba21563f..6c6bffa64da44b8b482e2bca14a12efc5968b276 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither.
+! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither, 2008 James Cash.
 USING: help.markup help.syntax ;
 IN: coroutines
 
@@ -46,7 +46,13 @@ HELP: coyield*
 HELP: coterminate
 { $values { "v" "an object" } }
 { $description "Terminate the current coroutine, leaving the value v on the stack when control is passed to the " { $link coresume } " caller. Resuming a terminated coroutine is a no-op." }
-{ $see-also coyield }
+{ $see-also coyield coreset }
+;
+
+HELP: coreset
+{ $values { "v" "an object" } }
+{ $description "Reset the current coroutine, leaving the value v on the stack when control is passed to the " { $link coresume } " caller. When the coroutine is resumed, it will continue at the beginning of the coroutine." }
+{ $see-also coyield coterminate }
 ;
 
 HELP: current-coro
index 6710452b228e3533838c951973bcce8775d77262..e07e9725d0d9c34da52e6c33678994d87a941dfe 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither.
+! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither, 2008 James Cash.
 ! See http://factorcode.org/license.txt for BSD license.
 IN: coroutines.tests
 USING: coroutines kernel sequences prettyprint tools.test math ;
@@ -17,3 +17,5 @@ test1 dup *coresume . dup *coresume . dup *coresume . dup *coresume 2drop
   [ [ coyield* ] each ] cocreate ;
 
 { "c" "b" "a" } [ test3 { "a" "b" "c" } over coresume >r dup *coresume >r *coresume r> r> ] unit-test
+
+{ 4+2/3 } [ [ 1+ coyield 2 * coyield 3 / coreset ] cocreate 1 5 [ over coresume ] times nip ] unit-test
\ No newline at end of file
index dc594abd2d5330858f52f918c40dda3758eba5e3..51276336e352bfadc0e6b008ea70747a6442bd88 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither.
+! Copyright (C) 2005 Chris Double, 2007 Clemens Hofreither, 2008 James Cash.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel hashtables namespaces make continuations quotations
 accessors ;
@@ -6,7 +6,7 @@ IN: coroutines
 
 SYMBOL: current-coro
 
-TUPLE: coroutine resumecc exitcc ;
+TUPLE: coroutine resumecc exitcc originalcc ;
 
 : cocreate ( quot -- co )
   coroutine new
@@ -14,14 +14,14 @@ TUPLE: coroutine resumecc exitcc ;
   [ swapd , , \ bind , 
     "Coroutine has terminated illegally." , \ throw ,
   ] [ ] make
-  >>resumecc ;
+  [ >>resumecc ] [ >>originalcc ] bi ;
 
 : coresume ( v co -- result )
   [ 
     >>exitcc
     resumecc>> call
     #! At this point, the coroutine quotation must have terminated
-    #! normally (without calling coyield or coterminate). This shouldn't happen.
+    #! normally (without calling coyield, coreset, or coterminate). This shouldn't happen.
     f over
   ] callcc1 2nip ;
 
@@ -43,3 +43,8 @@ TUPLE: coroutine resumecc exitcc ;
   current-coro get
   [ ] >>resumecc
   exitcc>> continue-with ;
+
+: coreset ( v --  )
+  current-coro get dup
+  originalcc>> >>resumecc
+  exitcc>> continue-with ;
\ No newline at end of file
index 9b9a2214c168da7671a88d7ac2c0798326e95fc7..9c82cdbb509b29e91de1adf7a7becd183a679823 100644 (file)
@@ -3,7 +3,8 @@
 USING: accessors arrays classes.singleton combinators
 continuations io io.encodings.binary io.encodings.utf8
 io.files io.sockets kernel io.streams.duplex math
-math.parser sequences splitting namespaces strings fry ftp ;
+math.parser sequences splitting namespaces strings fry ftp
+ftp.client.listing-parser urls ;
 IN: ftp.client
 
 : (ftp-response-code) ( str -- n )
@@ -24,145 +25,86 @@ IN: ftp.client
     [ fourth CHAR: - = ] tri
     [ read-response-loop ] when ;
 
+ERROR: ftp-error got expected ;
+
+: ftp-assert ( ftp-response n -- )
+    2dup [ n>> ] dip = [ 2drop ] [ ftp-error ] if ;
+
 : ftp-command ( string -- ftp-response )
     ftp-send read-response ;
 
-: ftp-user ( ftp-client -- ftp-response )
-    user>> "USER " prepend ftp-command ;
+: ftp-user ( url -- ftp-response )
+    username>> "USER " prepend ftp-command ;
 
-: ftp-password ( ftp-client -- ftp-response )
+: ftp-password ( url -- ftp-response )
     password>> "PASS " prepend ftp-command ;
 
-: ftp-set-binary ( -- ftp-response )
-    "TYPE I" ftp-command ;
-
-: ftp-pwd ( -- ftp-response )
-    "PWD" ftp-command ;
-
-: ftp-list ( -- ftp-response )
-    "LIST" ftp-command ;
-
-: ftp-quit ( -- ftp-response )
-    "QUIT" ftp-command ;
-
 : ftp-cwd ( directory -- ftp-response )
     "CWD " prepend ftp-command ;
 
 : ftp-retr ( filename -- ftp-response )
     "RETR " prepend ftp-command ;
 
-: parse-epsv ( ftp-response -- port )
-    strings>> first
-    "|" split 2 tail* first string>number ;
-
-TUPLE: remote-file
-type permissions links owner group size month day time year
-name target ;
-
-: <remote-file> ( -- remote-file ) remote-file new ;
-
-: parse-permissions ( remote-file str -- remote-file )
-    [ first ch>type >>type ] [ rest >>permissions ] bi ;
-
-: parse-list-11 ( lines -- seq )
-    [
-        11 f pad-right
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>owner ]
-            [ 3 swap nth >>group ]
-            [ 4 swap nth string>number >>size ]
-            [ 5 swap nth >>month ]
-            [ 6 swap nth >>day ]
-            [ 7 swap nth >>time ]
-            [ 8 swap nth >>name ]
-            [ 10 swap nth >>target ]
-        } cleave
-    ] map ;
-
-: parse-list-8 ( lines -- seq )
-    [
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>owner ]
-            [ 3 swap nth >>size ]
-            [ 4 swap nth >>month ]
-            [ 5 swap nth >>day ]
-            [ 6 swap nth >>time ]
-            [ 7 swap nth >>name ]
-        } cleave
-    ] map ;
-
-: parse-list-3 ( lines -- seq )
-    [
-        <remote-file> swap {
-            [ 0 swap nth parse-permissions ]
-            [ 1 swap nth string>number >>links ]
-            [ 2 swap nth >>name ]
-        } cleave
-    ] map ;
-
-: parse-list ( ftp-response -- ftp-response )
-    dup strings>>
-    [ " " split harvest ] map
-    dup length {
-        { 11 [ parse-list-11 ] }
-        { 9 [ parse-list-11 ] }
-        { 8 [ parse-list-8 ] }
-        { 3 [ parse-list-3 ] }
-        [ drop ]
-    } case >>parsed ;
+: ftp-set-binary ( -- ftp-response ) "TYPE I" ftp-command ;
 
-: ftp-epsv ( -- ftp-response )
-    "EPSV" ftp-command ;
+: ftp-pwd ( -- ftp-response ) "PWD" ftp-command ;
 
-ERROR: ftp-error got expected ;
-: ftp-assert ( ftp-response n -- )
-    2dup >r n>> r> = [ 2drop ] [ ftp-error ] if ;
+: ftp-list ( -- )
+    "LIST" ftp-command 150 ftp-assert ;
 
-: ftp-login ( ftp-client -- )
-    read-response 220 ftp-assert
-    [ ftp-user 331 ftp-assert ]
-    [ ftp-password 230 ftp-assert ] bi
-    ftp-set-binary 200 ftp-assert ;
+: ftp-quit ( -- ftp-response ) "QUIT" ftp-command ;
+
+: ftp-epsv ( -- ftp-response )
+    "EPSV" ftp-command dup 229 ftp-assert ;
 
-: open-remote-port ( -- port )
-    ftp-epsv
-    [ 229 ftp-assert ] [ parse-epsv ] bi ;
+: parse-epsv ( ftp-response -- port )
+    strings>> first "|" split 2 tail* first string>number ;
 
-: list ( ftp-client -- ftp-response )
-    host>> open-remote-port <inet> utf8 <client> drop
-    ftp-list 150 ftp-assert
+: open-passive-client ( url protocol -- stream )
+    [ host>> ftp-epsv parse-epsv <inet> ] dip <client> drop ;
+
+: list ( url -- ftp-response )
+    utf8 open-passive-client
+    ftp-list
     lines
     <ftp-response> swap >>strings
     read-response 226 ftp-assert
     parse-list ;
 
-: ftp-get ( filename ftp-client -- ftp-response )
-    host>> open-remote-port <inet> binary <client> drop
-    swap
+: (ftp-get) ( url path -- )
+    [ binary open-passive-client ] dip
     [ ftp-retr 150 ftp-assert drop ]
     [ binary <file-writer> stream-copy ] 2bi
-    read-response dup 226 ftp-assert ;
+    read-response 226 ftp-assert ;
+
+: ftp-login ( url -- )
+    read-response 220 ftp-assert
+    [ ftp-user 331 ftp-assert ]
+    [ ftp-password 230 ftp-assert ] bi
+    ftp-set-binary 200 ftp-assert ;
 
-: ftp-connect ( ftp-client -- stream )
+: ftp-connect ( url -- stream )
     [ host>> ] [ port>> ] bi <inet> utf8 <client> drop ;
 
-GENERIC: ftp-download ( path obj -- )
+: with-ftp-client ( url quot -- )
+    [ [ ftp-connect ] keep ] dip
+    '[ _ [ ftp-login ] _ bi ftp-quit drop ] with-stream ; inline
+
+: ensure-login ( url -- url )
+    dup username>> [
+        "anonymous" >>username
+        "ftp-client" >>password
+    ] unless ;
 
-: with-ftp-client ( ftp-client quot -- )
-    dupd '[
-        _ [ ftp-login ] [ @ ] bi
-        ftp-quit drop
-    ] >r ftp-connect r> with-stream ; inline
+: >ftp-url ( url -- url' ) >url ensure-port ensure-login ;
 
-M: ftp-client ftp-download ( path ftp-client -- )
-    [
-        [ drop parent-directory ftp-cwd drop ]
-        [ >r file-name r> ftp-get drop ] 2bi
+: ftp-get ( url -- )
+    >ftp-url [
+        dup path>>
+        [ nip parent-directory ftp-cwd drop ]
+        [ file-name (ftp-get) ] 2bi
     ] with-ftp-client ;
 
-M: string ftp-download ( path string -- )
-    <ftp-client> ftp-download ;
+
+
+
diff --git a/extra/ftp/client/listing-parser/authors.txt b/extra/ftp/client/listing-parser/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/ftp/client/listing-parser/listing-parser.factor b/extra/ftp/client/listing-parser/listing-parser.factor
new file mode 100644 (file)
index 0000000..04e96ed
--- /dev/null
@@ -0,0 +1,89 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators io.files kernel math.parser
+sequences splitting ;
+IN: ftp.client.listing-parser
+
+: ch>file-type ( ch -- type )
+    {
+        { CHAR: b [ +block-device+ ] }
+        { CHAR: c [ +character-device+ ] }
+        { CHAR: d [ +directory+ ] }
+        { CHAR: l [ +symbolic-link+ ] }
+        { CHAR: s [ +socket+ ] }
+        { CHAR: p [ +fifo+ ] }
+        { CHAR: - [ +regular-file+ ] }
+        [ drop +unknown+ ]
+    } case ;
+
+: file-type>ch ( type -- string )
+    {
+        { +block-device+ [ CHAR: b ] }
+        { +character-device+ [ CHAR: c ] }
+        { +directory+ [ CHAR: d ] }
+        { +symbolic-link+ [ CHAR: l ] }
+        { +socket+ [ CHAR: s ] }
+        { +fifo+ [ CHAR: p ] }
+        { +regular-file+ [ CHAR: - ] }
+        [ drop CHAR: - ]
+    } case ;
+
+: parse-permissions ( remote-file str -- remote-file )
+    [ first ch>file-type >>type ] [ rest >>permissions ] bi ;
+
+TUPLE: remote-file
+type permissions links owner group size month day time year
+name target ;
+
+: <remote-file> ( -- remote-file ) remote-file new ;
+
+: parse-list-11 ( lines -- seq )
+    [
+        11 f pad-right
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>owner ]
+            [ 3 swap nth >>group ]
+            [ 4 swap nth string>number >>size ]
+            [ 5 swap nth >>month ]
+            [ 6 swap nth >>day ]
+            [ 7 swap nth >>time ]
+            [ 8 swap nth >>name ]
+            [ 10 swap nth >>target ]
+        } cleave
+    ] map ;
+
+: parse-list-8 ( lines -- seq )
+    [
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>owner ]
+            [ 3 swap nth >>size ]
+            [ 4 swap nth >>month ]
+            [ 5 swap nth >>day ]
+            [ 6 swap nth >>time ]
+            [ 7 swap nth >>name ]
+        } cleave
+    ] map ;
+
+: parse-list-3 ( lines -- seq )
+    [
+        <remote-file> swap {
+            [ 0 swap nth parse-permissions ]
+            [ 1 swap nth string>number >>links ]
+            [ 2 swap nth >>name ]
+        } cleave
+    ] map ;
+
+: parse-list ( ftp-response -- ftp-response )
+    dup strings>>
+    [ " " split harvest ] map
+    dup length {
+        { 11 [ parse-list-11 ] }
+        { 9 [ parse-list-11 ] }
+        { 8 [ parse-list-8 ] }
+        { 3 [ parse-list-3 ] }
+        [ drop ]
+    } case >>parsed ;
index 1fd97df6d51652e7b9346396c29e454095d58e0b..adf7d5b41b77437315ececa45f93a1cf21f5d661 100644 (file)
@@ -7,21 +7,6 @@ IN: ftp
 SINGLETON: active
 SINGLETON: passive
 
-TUPLE: ftp-client host port user password mode state
-command-promise ;
-
-: <ftp-client> ( host -- ftp-client )
-    ftp-client new
-        swap >>host
-        21 >>port
-        "anonymous" >>user
-        "ftp@my.org" >>password ;
-
-: reset-ftp-client ( ftp-client -- )
-    f >>user
-    f >>password
-    drop ;
-
 TUPLE: ftp-response n strings parsed ;
 
 : <ftp-response> ( -- ftp-response )
@@ -32,32 +17,5 @@ TUPLE: ftp-response n strings parsed ;
     over strings>> push ;
 
 : ftp-send ( string -- ) write "\r\n" write flush ;
-
 : ftp-ipv4 1 ; inline
 : ftp-ipv6 2 ; inline
-
-
-: ch>type ( ch -- type )
-    {
-        { CHAR: d [ +directory+ ] }
-        { CHAR: l [ +symbolic-link+ ] }
-        { CHAR: - [ +regular-file+ ] }
-        [ drop +unknown+ ]
-    } case ;
-
-: type>ch ( type -- string )
-    {   
-        { +directory+ [ CHAR: d ] }
-        { +symbolic-link+ [ CHAR: l ] }
-        { +regular-file+ [ CHAR: - ] }
-        [ drop CHAR: - ]
-    } case ;
-
-: file-info>string ( file-info name -- string )
-    >r [ [ type>> type>ch 1string ] [ drop "rwx------" append ] bi ]
-    [ size>> number>string 15 CHAR: \s pad-left ] bi r>
-    3array " " join ;
-
-: directory-list ( -- seq )
-    "" directory-files
-    [ [ link-info ] keep file-info>string ] map ;
index 3ecf8d2f3fede0c8c7d112dfa5f533051acdf39a..f8ab04ed00a2a2f4ac14e427b8d5b14a627c7f56 100644 (file)
@@ -6,11 +6,22 @@ io.encodings.utf8 io.files io.sockets kernel math.parser
 namespaces make sequences ftp io.unix.launcher.parser
 unicode.case splitting assocs classes io.servers.connection
 destructors calendar io.timeouts io.streams.duplex threads
-continuations math concurrency.promises byte-arrays ;
+continuations math concurrency.promises byte-arrays
+io.backend sequences.lib tools.hexdump io.files.listing ;
 IN: ftp.server
 
+TUPLE: ftp-client url mode state command-promise ;
+
+: <ftp-client> ( url -- ftp-client )
+    ftp-client new
+        swap >>url ;
+    
 SYMBOL: client
 
+: ftp-server-directory ( -- str )
+    \ ftp-server-directory get-global "resource:temp" or
+    normalize-path ;
+
 TUPLE: ftp-command raw tokenized ;
 
 : <ftp-command> ( -- obj )
@@ -19,12 +30,14 @@ TUPLE: ftp-command raw tokenized ;
 TUPLE: ftp-get path ;
 
 : <ftp-get> ( path -- obj )
-    ftp-get new swap >>path ;
+    ftp-get new
+        swap >>path ;
 
 TUPLE: ftp-put path ;
 
 : <ftp-put> ( path -- obj )
-    ftp-put new swap >>path ;
+    ftp-put new
+        swap >>path ;
 
 TUPLE: ftp-list ;
 
@@ -62,7 +75,7 @@ C: <ftp-list> ftp-list
 
 : handle-USER ( ftp-command -- )
     [
-        tokenized>> second client get swap >>user drop
+        tokenized>> second client get (>>user)
         331 "Please specify the password." server-response
     ] [
         2drop "bad USER" ftp-error
@@ -70,7 +83,7 @@ C: <ftp-list> ftp-list
 
 : handle-PASS ( ftp-command -- )
     [
-        tokenized>> second client get swap >>password drop
+        tokenized>> second client get (>>password)
         230 "Login successful" server-response
     ] [
         2drop "PASS error" ftp-error
@@ -101,20 +114,20 @@ ERROR: type-error type ;
 
 : handle-PWD ( obj -- )
     drop
-    257 current-directory get "\"" swap "\"" 3append server-response ;
+    257 current-directory get "\"" "\"" surround server-response ;
 
 : handle-SYST ( obj -- )
     drop
     215 "UNIX Type: L8" server-response ;
 
 : if-command-promise ( quot -- )
-    >r client get command-promise>> r>
+    [ client get command-promise>> ] dip
     [ "Establish an active or passive connection first" ftp-error ] if* ;
 
 : handle-STOR ( obj -- )
     [
         tokenized>> second
-        [ >r <ftp-put> r> fulfill ] if-command-promise
+        [ [ <ftp-put> ] dip fulfill ] if-command-promise
     ] [
         2drop
     ] recover ;
@@ -136,7 +149,7 @@ M: ftp-list service-command ( stream obj -- )
     start-directory
     [
         utf8 encode-output
-        directory-list [ ftp-send ] each
+        directory. [ ftp-send ] each
     ] with-output-stream
     finish-directory ;
 
@@ -145,7 +158,7 @@ M: ftp-list service-command ( stream obj -- )
     rot   
     [ file-name ] [
         " " swap  file-info size>> number>string
-        "(" " bytes)." swapd 3append append
+        "(" " bytes)." surround append
     ] bi 3append server-response ;
 
 : transfer-incoming-file ( path -- )
@@ -191,7 +204,7 @@ M: ftp-put service-command ( stream obj -- )
 
 : handle-LIST ( obj -- )
     drop
-    [ >r <ftp-list> r> fulfill ] if-command-promise ;
+    [ [ <ftp-list> ] dip fulfill ] if-command-promise ;
 
 : handle-SIZE ( obj -- )
     [
@@ -217,7 +230,7 @@ M: ftp-put service-command ( stream obj -- )
     expect-connection
     [
         "Entering Passive Mode (127,0,0,1," %
-        port>bytes [ number>string ] bi@ "," swap 3append %
+        port>bytes [ number>string ] bi@ "," splice %
         ")" %
     ] "" make 227 swap server-response ;
 
@@ -235,14 +248,20 @@ M: ftp-put service-command ( stream obj -- )
 ! : handle-LPRT ( obj -- ) tokenized>> "," split ;
 
 ERROR: not-a-directory ;
+ERROR: no-permissions ;
 
 : handle-CWD ( obj -- )
     [
-        tokenized>> second dup directory? [
+        tokenized>> second dup normalize-path
+        dup ftp-server-directory head? [
+            no-permissions
+        ] unless
+
+        file-info directory? [
             set-current-directory
             250 "Directory successully changed." server-response
         ] [
-            not-a-directory throw
+            not-a-directory
         ] if
     ] [
         2drop
@@ -253,6 +272,7 @@ ERROR: not-a-directory ;
 
 : handle-client-loop ( -- )
     <ftp-command> readln
+    USE: prettyprint    global [ dup . flush ] bind
     [ >>raw ]
     [ tokenize-command >>tokenized ] bi
     dup tokenized>> first >upper {
@@ -310,7 +330,7 @@ TUPLE: ftp-server < threaded-server ;
 M: ftp-server handle-client* ( server -- )
     drop
     [
-        "" [
+        ftp-server-directory [
             host-name <ftp-client> client set
             send-banner handle-client-loop
         ] with-directory
@@ -320,6 +340,7 @@ M: ftp-server handle-client* ( server -- )
     ftp-server new-threaded-server
         swap >>insecure
         "ftp.server" >>name
+        5 minutes >>timeout
         latin1 >>encoding ;
 
 : ftpd ( port -- )
index 651c5f7ca1908ca4a25486bdf4783d0aff7ec1e8..4d83300934c1042d4863612c7c174d3ff4d8646c 100755 (executable)
@@ -5,7 +5,7 @@ USING: alien arrays byte-arrays combinators summary
 io.backend graphics.viewer io io.binary io.files kernel libc
 math math.functions namespaces opengl opengl.gl prettyprint
 sequences strings ui ui.gadgets.panes io.encodings.binary
-accessors ;
+accessors grouping ;
 IN: graphics.bitmap
 
 ! Currently can only handle 24bit bitmaps.
@@ -23,16 +23,25 @@ TUPLE: bitmap magic size reserved offset header-length width
         swap [ >>array ] [ >>color-index ] bi
         24 >>bit-count ;
 
-: raw-bitmap>string ( str n -- str )
+: 8bit>array ( bitmap -- array )
+    [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
+    [ color-index>> >array ] bi [ swap nth ] with map concat ;
+
+: 4bit>array ( bitmap -- array )
+    [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
+    [ color-index>> >array ] bi [ swap nth ] with map concat ;
+
+: raw-bitmap>array ( bitmap -- array )
+    dup bit-count>>
     {
         { 32 [ "32bit" throw ] }
-        { 24 [ ] }
+        { 24 [ color-index>> ] }
         { 16 [ "16bit" throw ] }
-        { 8 [ "8bit" throw ] }
-        { 4 [ "4bit" throw ] }
+        { 8 [ 8bit>array ] }
+        { 4 [ 4bit>array ] }
         { 2 [ "2bit" throw ] }
         { 1 [ "1bit" throw ] }
-    } case ;
+    } case >byte-array ;
 
 ERROR: bitmap-magic ;
 
@@ -72,13 +81,12 @@ M: bitmap-magic summary
 
 : load-bitmap ( path -- bitmap )
     normalize-path binary [
-        T{ bitmap } clone
-        dup parse-file-header
-        dup parse-bitmap-header
-        dup parse-bitmap
+        bitmap new
+            dup parse-file-header
+            dup parse-bitmap-header
+            dup parse-bitmap
     ] with-file-reader
-    dup color-index>> over bit-count>>
-    raw-bitmap>string >byte-array >>array ;
+    dup raw-bitmap>array >>array ;
 
 : save-bitmap ( bitmap path -- )
     binary [
@@ -118,6 +126,8 @@ M: bitmap draw-image ( bitmap -- )
         bit-count>> {
             ! { 32 [ GL_BGRA GL_UNSIGNED_INT_8_8_8_8 ] } ! broken
             { 24 [ GL_BGR GL_UNSIGNED_BYTE ] }
+            { 8 [ GL_BGR GL_UNSIGNED_BYTE ] }
+            { 4 [ GL_BGR GL_UNSIGNED_BYTE ] }
         } case
     ] keep array>> glDrawPixels ;
 
diff --git a/extra/hexdump/authors.txt b/extra/hexdump/authors.txt
deleted file mode 100644 (file)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/hexdump/hexdump-docs.factor b/extra/hexdump/hexdump-docs.factor
deleted file mode 100644 (file)
index 4278e92..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel sequences strings ;
-IN: hexdump
-
-HELP: hexdump.
-{ $values { "seq" sequence } }
-{ $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time and writes it to standard out." } ;
-
-HELP: hexdump
-{ $values { "seq" sequence } { "str" string } }
-{ $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time.  Lines are separated by a newline character." }
-{ $see-also hexdump. } ;
-
-ARTICLE: "hexdump" "Hexdump"
-"The " { $vocab-link "hexdump" } " vocabulary provides a traditional hexdump view of a sequence." $nl
-"Write hexdump to string:"
-{ $subsection hexdump }
-"Write the hexdump to the output stream:"
-{ $subsection hexdump. } ;
-
-ABOUT: "hexdump"
diff --git a/extra/hexdump/hexdump-tests.factor b/extra/hexdump/hexdump-tests.factor
deleted file mode 100644 (file)
index 7fb26e1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-IN: hexdump.tests
-USING: hexdump kernel sequences tools.test ;
-
-[ t ] [ "" hexdump "Length: 0, 0h\n" = ] unit-test
-[ t ] [ "abcdefghijklmnopqrstuvwxyz" hexdump "Length: 26, 1ah\n00000000h: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop\n00000010h: 71 72 73 74 75 76 77 78 79 7a                   qrstuvwxyz\n" = ] unit-test
-
-[ t ] [ 256 [ ] map hexdump "Length: 256, 100h\n00000000h: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n00000010h: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n00000020h: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f  !\"#$%&'()*+,-./\n00000030h: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n00000040h: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n00000050h: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n00000060h: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n00000070h: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n00000080h: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................\n00000090h: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................\n000000a0h: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................\n000000b0h: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................\n000000c0h: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................\n000000d0h: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................\n000000e0h: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................\n000000f0h: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................\n" = ] unit-test
-
diff --git a/extra/hexdump/hexdump.factor b/extra/hexdump/hexdump.factor
deleted file mode 100644 (file)
index b965fb4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays io io.streams.string kernel math math.parser
-namespaces sequences splitting grouping strings ascii ;
-IN: hexdump
-
-<PRIVATE
-
-: write-header ( len -- )
-    "Length: " write
-    [ number>string write ", " write ]
-    [ >hex write "h" write nl ] bi ;
-
-: write-offset ( lineno -- )
-    16 * >hex 8 CHAR: 0 pad-left write "h: " write ;
-
-: >hex-digit ( digit -- str )
-    >hex 2 CHAR: 0 pad-left " " append ;
-
-: >hex-digits ( bytes -- str )
-    [ >hex-digit ] { } map-as concat 48 CHAR: \s pad-right ;
-
-: >ascii ( bytes -- str )
-    [ [ printable? ] keep CHAR: . ? ] map ;
-
-: write-hex-line ( str lineno -- )
-    write-offset [ >hex-digits write ] [ >ascii write ] bi nl ;
-
-PRIVATE>
-
-: hexdump. ( seq -- )
-    [ length write-header ]
-    [ 16 <sliced-groups> [ write-hex-line ] each-index ] bi ;
-
-: hexdump ( seq -- str )
-    [ hexdump. ] with-string-writer ;
diff --git a/extra/hexdump/summary.txt b/extra/hexdump/summary.txt
deleted file mode 100644 (file)
index d860bd7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Prints formatted hex dump of an arbitrary sequence
index 6c553147a12a3d8419b0fc3caac154f151c38c41..7bd6eb7fbcffa7c831b9c9b50590625b597e970c 100644 (file)
@@ -1,6 +1,9 @@
 ! Copyright (C) 2007, 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types jamshred.game jamshred.oint jamshred.player jamshred.tunnel kernel math math.constants math.functions math.vectors opengl opengl.gl opengl.glu sequences float-arrays ;
+USING: accessors alien.c-types jamshred.game jamshred.oint
+jamshred.player jamshred.tunnel kernel math math.constants
+math.functions math.vectors opengl opengl.gl opengl.glu
+opengl.demo-support sequences float-arrays ;
 IN: jamshred.gl
 
 : min-vertices 6 ; inline
@@ -43,7 +46,7 @@ IN: jamshred.gl
     dup [ / pi 2 * * ] curry map ;
 
 : draw-segment-vertex ( segment theta -- )
-    over color>> set-color segment-vertex-and-normal
+    over color>> gl-color segment-vertex-and-normal
     gl-normal gl-vertex ;
 
 : draw-vertex-pair ( theta next-segment segment -- )
index 68046f79cf063bcd75ffb2292cb25ce8f0213a3b..ae3ddb61fc994d8c146a548faffee02e3259ddc6 100644 (file)
@@ -12,7 +12,7 @@ USING: mason.release.branch mason.config tools.test namespaces ;
     ] with-scope
 ] unit-test
 
-[ { "scp" "boot.x86.64.image" "joe@blah.com:/stuff/clean/netbsd-x86-64" } ] [
+[ { "scp" "boot.unix-x86.64.image" "joe@blah.com:/stuff/clean/netbsd-x86-64" } ] [
     [
         "joe" image-username set
         "blah.com" image-host set
index a456e6ff23fdeac190ec846d2a679d0ce268a71e..fb931650d448230b06f77083ea3abaf2a751cbbe 100644 (file)
@@ -1,16 +1,14 @@
 ! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces continuations debugger sequences fry
-io.files io.launcher mason.common mason.platform
+io.files io.launcher bootstrap.image qualified mason.common
 mason.config ;
+FROM: mason.config => target-os ;
 IN: mason.release.tidy
 
 : common-files ( -- seq )
+    images [ boot-image-name ] map
     {
-        "boot.x86.32.image"
-        "boot.x86.64.image"
-        "boot.macosx-ppc.image"
-        "boot.linux-ppc.image"
         "vm"
         "temp"
         "logs"
@@ -20,7 +18,8 @@ IN: mason.release.tidy
         "unmaintained"
         "unfinished"
         "build-support"
-    } ;
+    }
+    append ;
 
 : remove-common-files ( -- )
     common-files [ delete-tree ] each ;
index 8cccded26a8c046540197c2f77ea95b2d70be267..82a2578a7f17be76c0ddd77aaf2b4fd0d20c0369 100644 (file)
@@ -1,10 +1,9 @@
-! Copyright (c) 2007 Samuel Tardieu
+! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.functions sequences fry ;
 IN: math.algebra
 
 : chinese-remainder ( aseq nseq -- x )
-  dup product
-    [
+    dup product [
         '[ _ over / [ swap gcd drop ] keep * * ] 2map sum
     ] keep rem ; foldable
diff --git a/extra/math/analysis/analysis-docs.factor b/extra/math/analysis/analysis-docs.factor
new file mode 100644 (file)
index 0000000..a810ffc
--- /dev/null
@@ -0,0 +1,24 @@
+USING: help.markup help.syntax math ;
+IN: math.analysis
+
+HELP: gamma
+{ $values { "x" number } { "y" number } }
+{ $description "Gamma function; an extension of factorial to real and complex numbers." } ;
+
+HELP: gammaln
+{ $values { "x" number } { "gamma[x]" number } }
+{ $description "An alternative to " { $link gamma } " when gamma(x)'s range varies too widely." } ;
+
+HELP: nth-root
+{ $values { "n" integer } { "x" number } { "y" number } }
+{ $description "Calculates the nth root of a number, such that " { $snippet "y^n=x" } "." } ;
+
+HELP: exp-int
+{ $values { "x" number } { "y" number } }
+{ $description "Exponential integral function." }
+{ $notes "Works only for real values of " { $snippet "x" } " and is accurate to 7 decimal places." } ;
+
+HELP: stirling-fact
+{ $values { "n" integer } { "fact" integer } }
+{ $description "James Stirling's factorial approximation." } ;
+
index 00a104b381c66f6066d765f3c11b20e9a1ec0086..1bc692ca54756ea7c4f893747b5dbcaf014f398e 100644 (file)
@@ -19,7 +19,7 @@ IN: math.combinatorics
     0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
 
 : (>permutation) ( seq n -- seq )
-    [ [ dupd >= [ 1+ ] when ] curry map ] keep prefix ;
+    [ '[ _ dupd >= [ 1+ ] when ] map ] keep prefix ;
 
 : >permutation ( factoradic -- permutation )
     reverse 1 cut [ (>permutation) ] each ;
index eb199cd5fe9e961404f826119e8d6325a6a4d20d..6c20db10fdf55d6efeacd17099ffd6d5194b54a6 100644 (file)
@@ -1,37 +1,23 @@
-! Copyright (C) 2008 John Benediktsson
-! See http://factorcode.org/license.txt for BSD license
-
-USING: help.markup help.syntax ;
-
+USING: help.markup help.syntax math ;
 IN: math.compare
 
 HELP: absmin
-{ $values { "a" "a number" } { "b" "a number" } { "x" "a number" } }
-{ $description 
-    "Returns the smaller absolute number with the original sign." 
-} ;
+{ $values { "a" number } { "b" number } { "x" number } }
+{ $description "Returns the smaller absolute number with the original sign." } ;
 
 HELP: absmax
-{ $values { "a" "a number" } { "b" "a number" } { "x" "a number" } }
-{ $description 
-    "Returns the larger absolute number with the original sign."
-} ;
+{ $values { "a" number } { "b" number } { "x" number } }
+{ $description "Returns the larger absolute number with the original sign." } ;
 
 HELP: posmax
-{ $values { "a" "a number" } { "b" "a number" } { "x" "a number" } }
-{ $description 
-    "Returns the most-positive value, or zero if both are negative."
-} ;
+{ $values { "a" number } { "b" number } { "x" number } }
+{ $description "Returns the most-positive value, or zero if both are negative." } ;
 
 HELP: negmin
-{ $values { "a" "a number" } { "b" "a number" } { "x" "a number" } }
-{ $description 
-    "Returns the most-negative value, or zero if both are positive."
-} ;
+{ $values { "a" number } { "b" number } { "x" number } }
+{ $description "Returns the most-negative value, or zero if both are positive." } ;
 
 HELP: clamp
-{ $values { "a" "a number" } { "value" "a number" } { "b" "a number" } { "x" "a number" } }
-{ $description 
-    "Returns the value when between 'a' and 'b', 'a' if <= 'a', or 'b' if >= 'b'."
-} ;
+{ $values { "a" number } { "value" number } { "b" number } { "x" number } }
+{ $description "Returns the value when between " { $snippet "a" } " and " { $snippet "b" } ", " { $snippet "a" } " if <= " { $snippet "a" } ", or " { $snippet "b" } " if >= " { $snippet "b" } "." } ;
 
index 765f34e695f6930d0f2b4f752cb474872b7335bf..272471fe5d1819d59d24c2d114d64c4c92464cd8 100644 (file)
@@ -1,8 +1,4 @@
-! Copyright (C) 2008 John Benediktsson
-! See http://factorcode.org/license.txt for BSD license
-
-USING: kernel math math.functions math.compare tools.test ;
-
+USING: kernel math math.compare math.functions tools.test ;
 IN: math.compare.tests
 
 [ -1 ] [ -1 5 absmin ] unit-test
@@ -23,6 +19,3 @@ IN: math.compare.tests
 [ 1 ] [ 0 1 2 clamp ] unit-test
 [ 2 ] [ 0 3 2 clamp ] unit-test
 
-
-
-
index d19dac3d2b5d01d8f1fbfe35202524a04b4bc7a6..826f0ecf165cd6f08094a9f5c82f8a7e0daee2e1 100644 (file)
@@ -1,21 +1,19 @@
-! Copyright (C) 2008 John Benediktsson
+! Copyright (C) 2008 John Benediktsson.
 ! See http://factorcode.org/license.txt for BSD license
-
 USING: math math.order kernel ;
+IN: math.compare
 
-IN: math.compare 
-
-: absmin ( a b -- x ) 
-   [ [ abs ] bi@ < ] 2keep ? ;
+: absmin ( a b -- x )
+    [ [ abs ] bi@ < ] 2keep ? ;
 
-: absmax ( a b -- x ) 
-   [ [ abs ] bi@ > ] 2keep ? ;
+: absmax ( a b -- x )
+    [ [ abs ] bi@ > ] 2keep ? ;
 
-: posmax ( a b -- x ) 
-   0 max max ;
+: posmax ( a b -- x )
+    0 max max ;
 
-: negmin ( a b -- x ) 
-   0 min min ;
+: negmin ( a b -- x )
+    0 min min ;
 
 : clamp ( a value b -- x )
-   min max ; 
+    min max ;
diff --git a/extra/math/derivatives/derivatives-tests.factor b/extra/math/derivatives/derivatives-tests.factor
new file mode 100644 (file)
index 0000000..cfbc1fa
--- /dev/null
@@ -0,0 +1,5 @@
+USING: math math.derivatives tools.test ;
+IN: math.derivatives.test
+
+[ 8 ] [ 4 [ sq ] derivative >integer ] unit-test
+
index b7612e112b5ea0831e5fcb92871e4d7afeada46e..7922a48a6b823e558bfb3d5735011f6f1fc7e1fb 100644 (file)
@@ -1,6 +1,7 @@
-USING: kernel continuations combinators sequences math
-      math.order math.ranges accessors float-arrays ;
-
+! Copyright (c) 2008 Reginald Keith Ford II, Eduardo Cavazos.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel continuations combinators sequences math math.order math.ranges
+    accessors float-arrays ;
 IN: math.derivatives
 
 TUPLE: state x func h err i j errt fac hh ans a done ;
@@ -20,7 +21,8 @@ TUPLE: state x func h err i j errt fac hh ans a done ;
 : a[i-1][i-1] ( state -- elt ) [ i>> 1 - ] [ i>> 1 - ] [ a>> ] tri nth nth ;
 
 : check-h ( state -- state )
- dup h>> 0 = [ "h must be nonzero in dfridr" throw ] when ;
+    dup h>> 0 = [ "h must be nonzero in dfridr" throw ] when ;
+
 : init-a     ( state -- state ) ntab [ ntab <float-array> ] replicate >>a ;
 : init-hh    ( state -- state ) dup h>> >>hh ;
 : init-err   ( state -- state ) big >>err ;
@@ -30,75 +32,66 @@ TUPLE: state x func h err i j errt fac hh ans a done ;
 
 ! If error is decreased, save the improved answer
 : error-decreased? ( state -- state ? ) [ ] [ errt>> ] [ err>> ] tri <= ;
+
 : save-improved-answer ( state -- state )
- dup err>>   >>errt
- dup a[j][i] >>ans ;
   dup err>>   >>errt
   dup a[j][i] >>ans ;
 
 ! If higher order is worse by a significant factor SAFE, then quit early.
 : check-safe ( state -- state )
- dup
- [ [ a[i][i] ] [ a[i-1][i-1] ] bi - abs ] [ err>> safe * ] bi >=
-   [ t >>done ]
- when ;
+    dup [ [ a[i][i] ] [ a[i-1][i-1] ] bi - abs ]
+    [ err>> safe * ] bi >= [ t >>done ] when ;
+
 : x+hh ( state -- val ) [ x>> ] [ hh>> ] bi + ;
 : x-hh ( state -- val ) [ x>> ] [ hh>> ] bi - ;
+
 : limit-approx ( state -- val )
- [
-   [ [ x+hh ] [ func>> ] bi call ]
-   [ [ x-hh ] [ func>> ] bi call ]
-   bi -
- ]
- [ hh>> 2.0 * ]
- bi / ;
+    [
+        [ [ x+hh ] [ func>> ] bi call ]
+        [ [ x-hh ] [ func>> ] bi call ] bi -
+    ] [ hh>> 2.0 * ] bi / ;
+
 : a[0][0]! ( state -- state )
- { [ ] [ limit-approx ] [ drop 0 ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+    { [ ] [ limit-approx ] [ drop 0 ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+
 : a[0][i]! ( state -- state )
- { [ ] [ limit-approx ] [ i>> ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+    { [ ] [ limit-approx ] [ i>> ] [ drop 0 ] [ a>> ] } cleave nth set-nth ;
+
 : a[j-1][i]*fac ( state -- val ) [ a[j-1][i] ] [ fac>> ] bi * ;
+
 : new-a[j][i] ( state -- val )
- [ [ a[j-1][i]*fac ] [ a[j-1][i-1] ] bi - ]
- [ fac>> 1.0 - ]
- bi / ;
   [ [ a[j-1][i]*fac ] [ a[j-1][i-1] ] bi - ]
+    [ fac>> 1.0 - ] bi / ;
+
 : a[j][i]! ( state -- state )
- { [ ] [ new-a[j][i] ] [ i>> ] [ j>> ] [ a>> ] } cleave nth set-nth ;
   { [ ] [ new-a[j][i] ] [ i>> ] [ j>> ] [ a>> ] } cleave nth set-nth ;
 
 : update-errt ( state -- state )
- dup
-    [ [ a[j][i] ] [ a[j-1][i]   ] bi - abs ]
-    [ [ a[j][i] ] [ a[j-1][i-1] ] bi - abs ]
- bi max
- >>errt ;
+    dup [ [ a[j][i] ] [ a[j-1][i] ] bi - abs ]
+    [ [ a[j][i] ] [ a[j-1][i-1] ] bi - abs ] bi max >>errt ;
 
 : not-done? ( state -- state ? ) dup done>> not ;
 
 : derive ( state -- state )
- init-a
- check-h
- init-hh
- a[0][0]!
- init-err
- 1 ntab [a,b)
-  [
-     >>i
-     not-done?
-       [
-         update-hh
-         a[0][i]!
-         reset-fac
-         1 over i>> [a,b]
-           [
-             >>j
-             a[j][i]!
-             update-fac
-             update-errt
-             error-decreased? [ save-improved-answer ] when
-           ]
-         each
-         check-safe
-       ]
-     when
-   ]
- each ;
+    init-a
+    check-h
+    init-hh
+    a[0][0]!
+    init-err
+    1 ntab [a,b) [
+        >>i not-done? [
+            update-hh
+            a[0][i]!
+            reset-fac
+            1 over i>> [a,b] [
+                >>j
+                a[j][i]!
+                update-fac
+                update-errt
+                error-decreased? [ save-improved-answer ] when
+            ] each check-safe
+        ] when
+   ] each ;
 
 : derivative-state ( x func h err -- state )
     state new
@@ -112,11 +105,7 @@ TUPLE: state x func h err i j errt fac hh ans a done ;
 ! h should be small enough to give the correct sgn(f'(x))
 ! err is the max tolerance of gain in error for a single iteration-
 : (derivative) ( x func h err -- ans error )
- derivative-state
- derive
-    [ ans>> ]
-    [ errt>> ]
- bi ;
+    derivative-state derive [ ans>> ] [ errt>> ] bi ;
 
-: derivative ( x func -- m ) 0.01 2.0 (derivative) drop ; 
+: derivative ( x func -- m ) 0.01 2.0 (derivative) drop ;
 : derivative-func ( func -- der ) [ derivative ] curry ;
index 4c6675e8f170c91698dce1df3582ae4c762923e2..7f9262380c0c427e34bc1576a050dfd7fa45ea0f 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: bit-arrays kernel lists.lazy math math.functions math.primes.list
-       math.ranges sequences accessors ;
+USING: accessors bit-arrays fry kernel lists.lazy math math.functions
+    math.primes.list math.ranges sequences ;
 IN: math.erato
 
 <PRIVATE
@@ -9,35 +9,35 @@ IN: math.erato
 TUPLE: erato limit bits latest ;
 
 : ind ( n -- i )
-  2/ 1- ; inline
+    2/ 1- ; inline
 
 : is-prime ( n limit -- bool )
-  [ ind ] [ bits>> ] bi* nth ; inline
+    [ ind ] [ bits>> ] bi* nth ; inline
 
 : indices ( n erato -- range )
-  limit>> ind over 3 * ind swap rot <range> ;
+    limit>> ind over 3 * ind spin <range> ;
 
 : mark-multiples ( n erato -- )
-  over sq over limit>> <=
-  [ [ indices ] keep bits>> [ f -rot set-nth ] curry each ] [ 2drop ] if ;
+    2dup [ sq ] [ limit>> ] bi* <= [
+        [ indices ] keep bits>> '[ _ f -rot set-nth ] each
+    ] [ 2drop ] if ;
 
 : <erato> ( n -- erato )
-  dup ind 1+ <bit-array> 1 over set-bits erato boa ;
+    dup ind 1+ <bit-array> dup set-bits 1 erato boa ;
 
 : next-prime ( erato -- prime/f )
-  [ 2 + ] change-latest [ latest>> ] keep
-  2dup limit>> <=
-  [
-    2dup is-prime [ dupd mark-multiples ] [ nip next-prime ] if
-  ] [
-    2drop f
-  ] if ;
+    [ 2 + ] change-latest [ latest>> ] keep
+    2dup limit>> <= [
+        2dup is-prime [ dupd mark-multiples ] [ nip next-prime ] if
+    ] [
+        2drop f
+    ] if ;
 
 PRIVATE>
 
 : lerato ( n -- lazy-list )
-  dup 1000003 < [
-    0 primes-under-million seq>list swap [ <= ] curry lwhile
-  ] [
-    <erato> 2 [ drop next-prime ] with lfrom-by [ ] lwhile
-  ] if ;
+    dup 1000003 < [
+        0 primes-under-million seq>list swap '[ _ <= ] lwhile
+    ] [
+        <erato> 2 [ drop next-prime ] with lfrom-by [ ] lwhile
+    ] if ;
index e8982fa3e04d43ba7069f225a96940fa04ce434a..ee15b7e06fefaaf9beb1f3970158f09b3a82453c 100644 (file)
@@ -1 +1 @@
-Sieve of Eratosthene
+Sieve of Eratosthenes
diff --git a/extra/math/fft/authors.txt b/extra/math/fft/authors.txt
deleted file mode 100644 (file)
index 3b4a4af..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Hans Schmid
diff --git a/extra/math/fft/fft.factor b/extra/math/fft/fft.factor
deleted file mode 100644 (file)
index b82ecb6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! 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 grouping columns ;
-IN: math.fft
-
-: n^v ( n v -- w ) [ ^ ] with map ;
-: even ( seq -- seq ) 2 group 0 <column> ;
-: odd ( seq -- seq ) 2 group 1 <column> ;
-DEFER: fft
-: two ( seq -- seq ) fft 2 v/n dup append ;
-: omega ( n -- n' ) recip -2 pi i* * * exp ;
-: twiddle ( seq -- seq ) dup length dup omega swap n^v v* ;
-: (fft) ( seq -- seq ) dup odd two twiddle swap even two v+ ;
-: fft ( seq -- seq ) dup length 1 = [ (fft) ] unless ;
diff --git a/extra/math/fft/summary.txt b/extra/math/fft/summary.txt
deleted file mode 100644 (file)
index 3d71dfa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Fast fourier transform
index db300a3b70b709fc207eefebce4cbea14d856f4e..e02f4be6240b6dfd07f4bc73fa7696072961da76 100644 (file)
@@ -1,23 +1,21 @@
-! Copyright (C) 2008 John Benediktsson
-! See http://factorcode.org/license.txt for BSD license
-
+! Copyright (C) 2008 John Benediktsson.
+! See http://factorcode.org/license.txt for BSD license.
 USING: arrays assocs kernel grouping sequences shuffle
 math math.functions math.statistics math.vectors ;
-
 IN: math.finance
 
 <PRIVATE
 
-: weighted ( x y a -- z ) 
-    tuck [ * ] [ 1 swap - * ] 2bi* + ;
+: weighted ( x y a -- z )
+    tuck [ * ] [ 1- neg * ] 2bi* + ;
 
-: a ( n -- a ) 
-    1 + 2 swap / ;
+: a ( n -- a )
+    1+ 2 swap / ;
 
 PRIVATE>
 
 : ema ( seq n -- newseq )
-    a swap unclip [ [ dup ] 2dip swap rot weighted ] accumulate 2nip ;
+    a swap unclip [ [ dup ] 2dip spin weighted ] accumulate 2nip ;
 
 : sma ( seq n -- newseq )
     clump [ mean ] map ;
@@ -26,6 +24,5 @@ PRIVATE>
     rot dup ema [ swap ema ] dip v- ;
 
 : momentum ( seq n -- newseq )
-    2dup tail-slice -rot swap [ length ] keep
-    [ - neg ] dip swap head-slice v- ;
+    [ tail-slice ] 2keep [ dup length ] dip - head-slice v- ;
 
index 87767181cd349f6ffabe8c19f7d3c0e2c6c144df..3792d6ba9b3e95f53a9f0eca3a6e077e6622c11d 100644 (file)
@@ -1,32 +1,40 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math sequences ;
+USING: kernel math sequences prettyprint math.parser io
+math.functions ;
 IN: math.floating-point
 
-: float-sign ( float -- ? )
-    float>bits -31 shift { 1 -1 } nth ; 
+: (double-sign) ( bits -- n ) -63 shift ; inline
+: double-sign ( double -- n ) double>bits (double-sign) ;
 
-: double-sign ( float -- ? )
-    double>bits -63 shift { 1 -1 } nth ;
-
-: float-exponent-bits ( float -- n )
-    float>bits -23 shift 8 2^ 1- bitand ;
+: (double-exponent-bits) ( bits -- n )
+    -52 shift 11 2^ 1- bitand ; inline
 
 : double-exponent-bits ( double -- n )
-    double>bits -52 shift 11 2^ 1- bitand ;
+    double>bits (double-exponent-bits) ;
 
-: float-mantissa-bits ( float -- n )
-    float>bits 23 2^ 1- bitand ;
+: (double-mantissa-bits) ( double -- n )
+    52 2^ 1- bitand ;
 
 : double-mantissa-bits ( double -- n )
-    double>bits 52 2^ 1- bitand ;
-
-: float-e ( -- float ) 127 ; inline
-: double-e ( -- float ) 1023 ; inline
-
-! : calculate-float ( S M E -- float )
-    ! float-e - 2^ * * ; ! bits>float ;
-
-! : calculate-double ( S M E -- frac )
-    ! double-e - 2^ swap 52 2^ /f 1+ * * ;
+    double>bits (double-mantissa-bits) ;
+
+: >double ( S E M -- frac )
+    [ 52 shift ] dip
+    [ 63 shift ] 2dip bitor bitor bits>double ;
+
+: >double< ( double -- S E M )
+    double>bits
+    [ (double-sign) ]
+    [ (double-exponent-bits) ]
+    [ (double-mantissa-bits) ] tri ;
+
+: double. ( double -- )
+    double>bits
+    [ (double-sign) .b ]
+    [ (double-exponent-bits) >bin 11 CHAR: 0 pad-left bl print ]
+    [
+        (double-mantissa-bits) >bin 52 CHAR: 0 pad-left
+        11 [ bl ] times print
+    ] tri ;
 
index ec93a0891a5e6b7f2b3a7b121cd995817e6dab22..3bc785c1b644393a30323fc080eae933f3244241 100644 (file)
@@ -1,9 +1,18 @@
-! Copyright Â© 2008 Reginald Keith Ford II
-! Tools for quickly comparing, transforming, and evaluating mathematical Factor functions
-
+! Copyright (c) 2008 Reginald Keith Ford II.
+! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math arrays sequences sequences.lib ;
-IN: math.function-tools 
-: difference-func ( func func -- func ) [ bi - ] 2curry ; inline
-: eval ( x func -- pt ) dupd call 2array ; inline
-: eval-inverse ( y func -- pt ) dupd call swap 2array ; inline
-: eval3d ( x y func -- pt ) [ 2dup ] dip call 3array ; inline
+IN: math.function-tools
+
+! Tools for quickly comparing, transforming, and evaluating mathematical functions
+
+: difference-func ( func func -- func )
+    [ bi - ] 2curry ; inline
+
+: eval ( x func -- pt )
+    dupd call 2array ; inline
+
+: eval-inverse ( y func -- pt )
+    dupd call swap 2array ; inline
+
+: eval3d ( x y func -- pt )
+    [ 2dup ] dip call 3array ; inline
diff --git a/extra/math/haar/haar.factor b/extra/math/haar/haar.factor
deleted file mode 100644 (file)
index f1bf871..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-! Haar wavelet transform -- http://dmr.ath.cx/gfx/haar/
-USING: sequences math kernel splitting grouping columns ;
-IN: math.haar
-
-: averages ( seq -- seq )
-    [ first2 + 2 / ] map ;
-
-: differences ( seq averages -- differences )
-    >r 0 <column> r> [ - ] 2map ;
-
-: haar-step ( seq -- differences averages )
-    2 group dup averages [ differences ] keep ;
-
-: haar ( seq -- seq )
-    dup length 1 <= [ haar-step haar prepend ] unless ;
diff --git a/extra/math/haar/summary.txt b/extra/math/haar/summary.txt
deleted file mode 100644 (file)
index 5bb26dc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Haar wavelet transform
index 6e83a61eb325d996ec82be6bce3fee551d832c0e..0368dd5286195caa96654af970d00a8ee14f78b3 100755 (executable)
@@ -21,17 +21,17 @@ SYMBOL: matrix
 : cols ( -- n ) 0 nth-row length ;
 
 : skip ( i seq quot -- n )
-    over >r find-from drop r> length or ; inline
+    over [ find-from drop ] dip length or ; inline
 
 : first-col ( row# -- n )
     #! First non-zero column
     0 swap nth-row [ zero? not ] skip ;
 
 : clear-scale ( col# pivot-row i-row -- n )
-    >r over r> nth dup zero? [
+    [ over ] dip nth dup zero? [
         3drop 0
     ] [
-        >r nth dup zero? r> swap [
+        [ nth dup zero? ] dip swap [
             2drop 0
         ] [
             swap / neg
@@ -39,13 +39,13 @@ SYMBOL: matrix
     ] if ;
 
 : (clear-col) ( col# pivot-row i -- )
-    [ [ clear-scale ] 2keep >r n*v r> v+ ] change-row ;
+    [ [ clear-scale ] 2keep [ n*v ] dip v+ ] change-row ;
 
 : rows-from ( row# -- slice )
     rows dup <slice> ;
 
 : clear-col ( col# row# rows -- )
-    >r nth-row r> [ >r 2dup r> (clear-col) ] each 2drop ;
+    [ nth-row ] dip [ [ 2dup ] dip (clear-col) ] each 2drop ;
 
 : do-row ( exchange-with row# -- )
     [ exchange-rows ] keep
@@ -53,7 +53,7 @@ SYMBOL: matrix
     dup 1+ rows-from clear-col ;
 
 : find-row ( row# quot -- i elt )
-    >r rows-from r> find ; inline
+    [ rows-from ] dip find ; inline
 
 : pivot-row ( col# row# -- n )
     [ dupd nth-row nth zero? not ] find-row 2nip ;
@@ -61,7 +61,7 @@ SYMBOL: matrix
 : (echelon) ( col# row# -- )
     over cols < over rows < and [
         2dup pivot-row [ over do-row 1+ ] when*
-        >r 1+ r> (echelon)
+        [ 1+ ] dip (echelon)
     ] [
         2drop
     ] if ;
@@ -86,10 +86,10 @@ SYMBOL: matrix
     ] with-matrix ;
 
 : basis-vector ( row col# -- )
-    >r clone r>
+    [ clone ] dip
     [ swap nth neg recip ] 2keep
     [ 0 spin set-nth ] 2keep
-    >r n*v r>
+    [ n*v ] dip
     matrix get set-nth ;
 
 : nullspace ( matrix -- seq )
index 529ddb083a9ca9e0ddb2962cea05cf9b5c37bbd6..0088b17372253b890fba644cce111efc7e148108 100755 (executable)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel sequences math math.functions
-math.vectors math.order ;
+USING: arrays kernel math math.order math.vectors sequences ;
 IN: math.matrices
 
 ! Matrices
@@ -29,8 +28,8 @@ IN: math.matrices
 : m.v ( m v -- v ) [ v. ] curry map ;
 : m.  ( m m -- m ) flip [ swap m.v ] curry map ;
 
-: mmin ( m -- n ) >r 1/0. r> [ [ min ] each ] each ;
-: mmax ( m -- n ) >r -1/0. r> [ [ max ] each ] each ;
+: mmin ( m -- n ) [ 1/0. ] dip [ [ min ] each ] each ;
+: mmax ( m -- n ) [ -1/0. ] dip [ [ max ] each ] each ;
 : mnorm ( m -- n ) dup mmax abs m/n ;
 
 <PRIVATE
index 45665c701dff56944dff6117bb76ddf543e80925..def8a04738b7cea7c70dca57db3b79df72e02bd9 100755 (executable)
@@ -11,13 +11,6 @@ IN: math.miller-rabin
 
 TUPLE: positive-even-expected n ;
 
-: (factor-2s) ( r s -- r s )
-    dup even? [ -1 shift >r 1+ r> (factor-2s) ] when ;
-
-: factor-2s ( n -- r s )
-    #! factor an integer into s * 2^r
-    0 swap (factor-2s) ;
-
 :: (miller-rabin) ( n trials -- ? )
     [let | r [ n 1- factor-2s drop ]
            s [ n 1- factor-2s nip ]
index 269eae2538feaf0d090723cfb7ee637d51ce067b..4b53b1222d913e7472e7ba87f6b8ecc439b749dd 100644 (file)
@@ -1,9 +1,10 @@
-! Copyright Â© 2008 Reginald Keith Ford II
+! Copyright (c) 2008 Reginald Keith Ford II.
 ! See http://factorcode.org/license.txt for BSD license.
-! Newton's Method of approximating roots
 USING: kernel math math.derivatives ;
 IN: math.newtons-method
 
+! Newton's method of approximating roots
+
 <PRIVATE
 
 : newton-step ( x function -- x2 )
index 51512ca2e337af35197e35c1e80054b76771b40c..47226114d000928a4d231d9be024f34f86c9ed76 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel sequences vectors math math.vectors
-namespaces make shuffle splitting sequences.lib math.order ;
+USING: arrays kernel make math math.order math.vectors sequences shuffle
+    splitting vectors ;
 IN: math.polynomials
 
 ! Polynomials are vectors with the highest powers on the right:
@@ -13,14 +13,16 @@ IN: math.polynomials
     <array> 1 [ * ] accumulate nip ;
 
 <PRIVATE
-: 2pad-left ( p p n -- p p ) 0 [ pad-left swap ] 2keep pad-left swap ;
-: 2pad-right ( p p n -- p p ) 0 [ pad-right swap ] 2keep pad-right swap ;
+
+: 2pad-left ( p p n -- p p ) [ 0 pad-left ] curry bi@ ;
+: 2pad-right ( p p n -- p p ) [ 0 pad-right ] curry bi@ ;
 : pextend ( p p -- p p ) 2dup [ length ] bi@ max 2pad-right ;
 : pextend-left ( p p -- p p ) 2dup [ length ] bi@ max 2pad-left ;
 : unempty ( seq -- seq ) [ { 0 } ] when-empty ;
 : 2unempty ( seq seq -- seq seq ) [ unempty ] bi@ ;
 
 PRIVATE>
+
 : p= ( p p -- ? ) pextend = ;
 
 : ptrim ( p -- p )
@@ -33,14 +35,14 @@ PRIVATE>
 
 ! convolution
 : pextend-conv ( p p -- p p )
-    #! extend to: p_m + p_n - 1 
+    #! extend to: p_m + p_n - 1
     2dup [ length ] bi@ + 1- 2pad-right [ >vector ] bi@ ;
 
 : p* ( p p -- p )
     #! Multiply two polynomials.
     2unempty pextend-conv <reversed> dup length
     [ over length pick <slice> pick [ * ] 2map sum ] map 2nip reverse ;
-    
+
 : p-sq ( p -- p-sq )
     dup p* ;
 
@@ -72,7 +74,7 @@ PRIVATE>
     dup V{ 0 } clone p= [
         drop nip
     ] [
-        tuck p/mod >r pick p* swap >r swapd p- r> r> (pgcd)
+        tuck p/mod [ pick p* swap [ swapd p- ] dip ] dip (pgcd)
     ] if ;
 
 : pgcd ( p p -- p q )
index 059bd67c188466d43079f278226879f7375d9a17..80c93f2ae0ca244b4a69a4e89d9b44ccef913fcf 100644 (file)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel lists math math.primes namespaces make
-sequences ;
+USING: arrays kernel lists make math math.primes sequences ;
 IN: math.primes.factors
 
 <PRIVATE
@@ -11,14 +10,16 @@ IN: math.primes.factors
 
 : (count) ( n d -- n' )
     [ (factor) ] { } make
-    [ [ first ] keep length 2array , ] unless-empty ;
+    [ [ first ] [ length ] bi 2array , ] unless-empty ;
 
 : (unique) ( n d -- n' )
     [ (factor) ] { } make
     [ first , ] unless-empty ;
 
 : (factors) ( quot list n -- )
-    dup 1 > [ swap uncons swap >r pick call r> swap (factors) ] [ 3drop ] if ;
+    dup 1 > [
+        swap uncons swap [ pick call ] dip swap (factors)
+    ] [ 3drop ] if ;
 
 : (decompose) ( n quot -- seq )
     [ lprimes rot (factors) ] { } make ;
@@ -38,5 +39,5 @@ PRIVATE>
     dup 2 < [
         drop 0
     ] [
-        dup unique-factors dup 1 [ 1- * ] reduce swap product / *
+        dup unique-factors [ 1 [ 1- * ] reduce ] [ product ] bi / *
     ] if ; foldable
index feb60c555dc09199aced7017ff6fa7029e5fae41..820d5b6c4a2f1d6619ca549bbffab585bdb8e867 100644 (file)
@@ -1,8 +1,7 @@
 ! Copyright (C) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel lists.lazy math math.functions math.miller-rabin
-       math.order math.primes.list math.ranges sequences sorting
-       binary-search ;
+USING: binary-search combinators kernel lists.lazy math math.functions
+    math.miller-rabin math.primes.list sequences ;
 IN: math.primes
 
 <PRIVATE
@@ -45,8 +44,7 @@ PRIVATE>
     } cond ; foldable
 
 : primes-between ( low high -- seq )
-    primes-upto
-    [ 1- next-prime ] dip
-    [ natural-search drop ] keep [ length ] keep <slice> ; foldable
+    primes-upto [ 1- next-prime ] dip
+    [ natural-search drop ] [ length ] [ ] tri <slice> ; foldable
 
 : coprime? ( a b -- ? ) gcd nip 1 = ; foldable
index 65f18d35689e1fe6cc2811561aa3046be4c34c5c..ffc0fcc9f718073c1ffd534c443cb8a7f7631950 100755 (executable)
@@ -16,9 +16,9 @@ IN: math.quaternions
 
 : 2q ( u v -- u' u'' v' v'' ) [ first2 ] bi@ ; inline
 
-: q*a ( u v -- a ) 2q swapd ** >r * r> - ; inline
+: q*a ( u v -- a ) 2q swapd ** [ * ] dip - ; inline
 
-: q*b ( u v -- b ) 2q >r ** swap r> * + ; inline
+: q*b ( u v -- b ) 2q [ ** swap ] dip * + ; inline
 
 PRIVATE>
 
@@ -51,12 +51,12 @@ PRIVATE>
 
 : v>q ( v -- q )
     #! Turn a 3-vector into a quaternion with real part 0.
-    first3 rect> >r 0 swap rect> r> 2array ;
+    first3 rect> [ 0 swap rect> ] dip 2array ;
 
 : q>v ( q -- v )
     #! Get the vector part of a quaternion, discarding the real
     #! part.
-    first2 >r imaginary-part r> >rect 3array ;
+    first2 [ imaginary-part ] dip >rect 3array ;
 
 ! Zero
 : q0 { 0 0 } ;
@@ -71,7 +71,7 @@ PRIVATE>
 ! http://www.mathworks.com/access/helpdesk/help/toolbox/aeroblks/euleranglestoquaternions.html
 
 : (euler) ( theta unit -- q )
-    >r -0.5 * dup cos c>q swap sin r> n*v v- ;
+    [ -0.5 * dup cos c>q swap sin ] dip n*v v- ;
 
 : euler ( phi theta psi -- q )
   [ qi (euler) ] [ qj (euler) ] [ qk (euler) ] tri* q* q* ;
index ad52c0cd4ab447d5d784937f5f560141df37c3f1..0d325622415857f3456d32a2a32fd96ab32f33d5 100644 (file)
@@ -1,9 +1,10 @@
-! Copyright Â© 2008 Reginald Keith Ford II
+! Copyright (c) 2008 Reginald Keith Ford II.
 ! See http://factorcode.org/license.txt for BSD license.
-! Secant Method of approximating roots
 USING: kernel math math.function-tools math.points math.vectors ;
 IN: math.secant-method
 
+! Secant method of approximating roots
+
 <PRIVATE
 
 : secant-solution ( x1 x2 function -- solution )
index 8cd6d26c1c1e0492d0fa5e3eac696c3cda3920ed..267a95c100128ef05c910fcf388b12c84209527c 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman, Michael Judge.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.analysis math.functions math.vectors sequences
-sequences.lib sorting ;
+USING: arrays kernel math math.analysis math.functions sequences sequences.lib
+    sorting ;
 IN: math.statistics
 
 : mean ( seq -- n )
@@ -19,10 +19,10 @@ IN: math.statistics
 
 : median ( seq -- n )
     #! middle number if odd, avg of two middle numbers if even
-    natural-sort dup length dup even? [
-        1- 2 / swap [ nth ] [ [ 1+ ] dip nth ] 2bi + 2 /
+    natural-sort dup length even? [
+        [ midpoint@ dup 1- 2array ] keep nths mean
     ] [
-        2 / swap nth
+        [ midpoint@ ] keep nth
     ] if ;
 
 : range ( seq -- n )
@@ -44,14 +44,14 @@ IN: math.statistics
 
 : ste ( seq -- x )
     #! standard error, standard deviation / sqrt ( length of sequence )
-    dup std swap length sqrt / ;
+    [ std ] [ length ] bi sqrt / ;
 
 : ((r)) ( mean(x) mean(y) {x} {y} -- (r) )
     ! finds sigma((xi-mean(x))(yi-mean(y))
-    0 [ [ >r pick r> swap - ] bi@ * + ] 2reduce 2nip ;
+    0 [ [ [ pick ] dip swap - ] bi@ * + ] 2reduce 2nip ;
 
 : (r) ( mean(x) mean(y) {x} {y} sx sy -- r )
-    * recip >r [ ((r)) ] keep length 1- / r> * ;
+    * recip [ [ ((r)) ] keep length 1- / ] dip * ;
 
 : [r] ( {{x,y}...} -- mean(x) mean(y) {x} {y} sx sy )
     first2 [ [ [ mean ] bi@ ] 2keep ] 2keep [ std ] bi@ ;
index dfb0c00388398fbc2526ad3115b10571b497653c..58dab74cdbb10d61a5c8462a110fa09577fb86c4 100755 (executable)
@@ -26,7 +26,7 @@ IN: math.text.english
 
 SYMBOL: and-needed?
 : set-conjunction ( seq -- )
-    first { [ dup 100 < ] [ dup 0 > ] } 0&& and-needed? set drop ;
+    first { [ 100 < ] [ 0 > ] } 1&& and-needed? set ;
 
 : negative-text ( n -- str )
     0 < "Negative " "" ? ;
diff --git a/extra/math/transforms/fft/authors.txt b/extra/math/transforms/fft/authors.txt
new file mode 100644 (file)
index 0000000..3b4a4af
--- /dev/null
@@ -0,0 +1 @@
+Hans Schmid
diff --git a/extra/math/transforms/fft/fft-docs.factor b/extra/math/transforms/fft/fft-docs.factor
new file mode 100644 (file)
index 0000000..430058b
--- /dev/null
@@ -0,0 +1,7 @@
+USING: help.markup help.syntax sequences ;
+IN: math.transforms.fft
+
+HELP: fft
+{ $values { "seq" sequence } { "seq" sequence } }
+{ $description "Fast Fourier transform function." } ;
+
diff --git a/extra/math/transforms/fft/fft.factor b/extra/math/transforms/fft/fft.factor
new file mode 100644 (file)
index 0000000..0688c00
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (c) 2007 Hans Schmid.
+! See http://factorcode.org/license.txt for BSD license.
+USING: columns grouping kernel math math.constants math.functions math.vectors
+    sequences ;
+IN: math.transforms.fft
+
+! Fast Fourier Transform
+
+<PRIVATE
+
+: n^v ( n v -- w ) [ ^ ] with map ;
+
+: omega ( n -- n' )
+    recip -2 pi i* * * exp ;
+
+: twiddle ( seq -- seq )
+    dup length [ omega ] [ n^v ] bi v* ;
+
+PRIVATE>
+
+DEFER: fft
+
+: two ( seq -- seq )
+    fft 2 v/n dup append ;
+
+<PRIVATE
+
+: even ( seq -- seq ) 2 group 0 <column> ;
+: odd ( seq -- seq ) 2 group 1 <column> ;
+
+: (fft) ( seq -- seq )
+    [ odd two twiddle ] [ even two ] bi v+ ;
+
+PRIVATE>
+
+: fft ( seq -- seq )
+    dup length 1 = [ (fft) ] unless ;
+
diff --git a/extra/math/transforms/fft/summary.txt b/extra/math/transforms/fft/summary.txt
new file mode 100644 (file)
index 0000000..3d71dfa
--- /dev/null
@@ -0,0 +1 @@
+Fast fourier transform
diff --git a/extra/math/transforms/haar/authors.txt b/extra/math/transforms/haar/authors.txt
new file mode 100644 (file)
index 0000000..cf46c0e
--- /dev/null
@@ -0,0 +1,2 @@
+Slava Pestov
+Aaron Schaefer
diff --git a/extra/math/transforms/haar/haar-docs.factor b/extra/math/transforms/haar/haar-docs.factor
new file mode 100644 (file)
index 0000000..218a63a
--- /dev/null
@@ -0,0 +1,15 @@
+USING: help.markup help.syntax sequences ;
+IN: math.transforms.haar
+
+HELP: haar
+{ $values { "seq" sequence } { "seq" sequence } }
+{ $description "Haar wavelet transform function." }
+{ $notes "The sequence length should be a power of two." }
+{ $examples { $example "USING: math.transforms.haar prettyprint ;" "{ 7 1 6 6 3 -5 4 2 } haar ." "{ 3 2 -1 -2 3 0 4 1 }" } } ;
+
+HELP: rev-haar
+{ $values { "seq" sequence } { "seq" sequence } }
+{ $description "Reverse Haar wavelet transform function." }
+{ $notes "The sequence length should be a power of two." }
+{ $examples { $example "USING: math.transforms.haar prettyprint ;" "{ 3 2 -1 -2 3 0 4 1 } rev-haar ." "{ 7 1 6 6 3 -5 4 2 }" } } ;
+
diff --git a/extra/math/transforms/haar/haar-tests.factor b/extra/math/transforms/haar/haar-tests.factor
new file mode 100644 (file)
index 0000000..fd2ab90
--- /dev/null
@@ -0,0 +1,6 @@
+USING: math.transforms.haar tools.test ;
+IN: math.transforms.haar.tests
+
+[ { 3 2 -1 -2 3 0 4 1 } ] [ { 7 1 6 6 3 -5 4 2 } haar ] unit-test
+[ { 7 1 6 6 3 -5 4 2 } ] [ { 3 2 -1 -2 3 0 4 1 } rev-haar ] unit-test
+
diff --git a/extra/math/transforms/haar/haar.factor b/extra/math/transforms/haar/haar.factor
new file mode 100644 (file)
index 0000000..c0359b8
--- /dev/null
@@ -0,0 +1,30 @@
+! Copyright (c) 2008 Slava Pestov, Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs columns grouping kernel math math.statistics math.vectors
+    sequences ;
+IN: math.transforms.haar
+
+! Haar Wavelet Transform -- http://dmr.ath.cx/gfx/haar/
+
+<PRIVATE
+
+: averages ( seq -- seq )
+    [ mean ] map ;
+
+: differences ( seq averages -- differences )
+    [ 0 <column> ] dip v- ;
+
+: haar-step ( seq -- differences averages )
+    2 group dup averages [ differences ] keep ;
+
+: rev-haar-step ( seq -- seq )
+    halves [ v+ ] [ v- ] 2bi zip concat ;
+
+PRIVATE>
+
+: haar ( seq -- seq )
+    dup length 1 <= [ haar-step haar prepend ] unless ;
+
+: rev-haar ( seq -- seq )
+    dup length 2 > [ halves swap rev-haar prepend ] when rev-haar-step ;
+
diff --git a/extra/math/transforms/haar/summary.txt b/extra/math/transforms/haar/summary.txt
new file mode 100644 (file)
index 0000000..5bb26dc
--- /dev/null
@@ -0,0 +1 @@
+Haar wavelet transform
diff --git a/extra/math/transforms/summary.txt b/extra/math/transforms/summary.txt
new file mode 100644 (file)
index 0000000..d3d93df
--- /dev/null
@@ -0,0 +1 @@
+Collection of mathematical transforms
index 07f7b74265dd04cf779c33e59b121b4f1df7d89a..40e12a97c9a2b2bf8d8964485bbd390afc240c3a 100644 (file)
@@ -1,7 +1,7 @@
 ! From http://www.ffconsultancy.com/ocaml/maze/index.html
 USING: sequences namespaces math math.vectors opengl opengl.gl
-arrays kernel random ui ui.gadgets ui.gadgets.canvas ui.render
-math.order math.geometry.rect ;
+opengl.demo-support arrays kernel random ui ui.gadgets
+ui.gadgets.canvas ui.render math.order math.geometry.rect ;
 IN: maze
 
 : line-width 8 ;
@@ -41,6 +41,7 @@ SYMBOL: visited
     ] if ;
 
 : draw-maze ( n -- )
+    -0.5 0.5 0 glTranslated
     line-width 2 - glLineWidth
     line-width 2 - glPointSize
     1.0 1.0 1.0 1.0 glColor4d
index d9560c92f6405652775e151b9a6521660a977fbd..29d4ccffc1f17b832bfb19a197f679321dca4832 100644 (file)
@@ -1,5 +1,5 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu ui
-ui.gadgets ui.render ;
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render ;
 IN: nehe.2
 
 TUPLE: nehe2-gadget < gadget ;
index 8a2149e370cffa5d43c0b5ce718e27bd0019c1fd..75f2e573cc5a406718e339a3e03c59a2144f0ce0 100644 (file)
@@ -1,5 +1,5 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu ui
-ui.gadgets ui.render ;
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render ;
 IN: nehe.3
 
 TUPLE: nehe3-gadget < gadget ;
index 5a7988c9340f3de4fdea9fcdce1283bbc3b30944..4c1545b4ae39d865da053667936dd0a04156d96b 100644 (file)
@@ -1,5 +1,5 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu ui
-ui.gadgets ui.render threads accessors ;
+USING: arrays kernel math opengl opengl.gl opengl.glu
+opengl.demo-support ui ui.gadgets ui.render threads accessors ;
 IN: nehe.4
 
 TUPLE: nehe4-gadget < gadget rtri rquad thread quit? ;
index deaba97c7cc715fca62b633f584754d1921959d9..59170ff96458f93c78b35ca948e4d65b5835242f 100755 (executable)
@@ -1,5 +1,5 @@
-USING: arrays kernel math opengl opengl.gl opengl.glu ui\r
-ui.gadgets ui.render threads accessors ;\r
+USING: arrays kernel math opengl opengl.gl opengl.glu\r
+opengl.demo-support ui ui.gadgets ui.render threads accessors ;\r
 IN: nehe.5\r
 \r
 TUPLE: nehe5-gadget < gadget rtri rquad thread quit? ;\r
index 2bf2abae95751384c065051bd16ef0e03832e299..cd781508a7163d36c5a2271b7174aab6819dd66e 100755 (executable)
@@ -1,6 +1,6 @@
-USING: arrays kernel math math.functions
-math.order math.vectors namespaces opengl opengl.gl sequences ui
-ui.gadgets ui.gestures ui.render accessors ;
+USING: arrays kernel math math.functions math.order math.vectors
+namespaces opengl opengl.gl sequences ui ui.gadgets ui.gestures
+ui.render accessors combinators ;
 IN: opengl.demo-support
 
 : FOV 2.0 sqrt 1+ ; inline
@@ -74,6 +74,26 @@ M: demo-gadget pref-dim* ( gadget -- dim )
 : drag-yaw-pitch ( -- yaw pitch )
     last-drag-rel MOUSE-MOTION-SCALE v*n first2 ;
 
+: gl-vertex ( point -- )
+    dup length {
+        { 2 [ first2 glVertex2d ] }
+        { 3 [ first3 glVertex3d ] }
+        { 4 [ first4 glVertex4d ] }
+    } case ;
+
+: gl-normal ( normal -- ) first3 glNormal3d ;
+
+: do-state ( mode quot -- )
+    swap glBegin call glEnd ; inline
+
+: rect-vertices ( lower-left upper-right -- )
+    GL_QUADS [
+        over first2 glVertex2d
+        dup first pick second glVertex2d
+        dup first2 glVertex2d
+        swap first swap second glVertex2d
+    ] do-state ;
+
 demo-gadget H{
     { T{ key-down f f "LEFT"  } [ KEY-ROTATE-STEP neg swap yaw-demo-gadget ] }
     { T{ key-down f f "RIGHT" } [ KEY-ROTATE-STEP     swap yaw-demo-gadget ] }
index 9e670c04ab675278edd5491ec9de89be828c3d7e..758bfe280e2d02338ca741b8e359ddd9450e2fa4 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2008 Matthew Willis.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: locals math.functions math namespaces
-opengl.gl accessors kernel opengl ui.gadgets
+opengl.gl opengl.demo-support accessors kernel opengl ui.gadgets
 fry assocs
 destructors sequences ui.render colors ;
 IN: opengl.gadgets
 
-TUPLE: texture-gadget ;
+TUPLE: texture-gadget < gadget ;
 
 GENERIC: render* ( gadget -- texture dims )
 GENERIC: cache-key* ( gadget -- key )
index 889eecb49a4deb30074b72bf272395936f6740d0..0e5cb7dbbca22a85fa951f4439ad521f5bb3d586 100755 (executable)
@@ -88,7 +88,7 @@ M: string b, ( n string -- ) heap-size b, ;
 
 : (read-128-ber) ( n -- n )
     read1
-    [ >r 7 shift r> 7 clear-bit bitor ] keep
+    [ [ 7 shift ] [ 7 clear-bit ] bi* bitor ] keep
     7 bit? [ (read-128-ber) ] when ;
     
 : read-128-ber ( -- n )
index f5770105446a68d906a3cb0124ec8f3dc67add26..a530be64fa5fce4988d565e36ede58523cef0957 100644 (file)
@@ -2,7 +2,7 @@
 USING: kernel namespaces arrays sequences grouping
        alien.c-types
        math math.vectors math.geometry.rect
-       opengl.gl opengl.glu opengl generalizations vars
+       opengl.gl opengl.glu opengl.demo-support opengl generalizations vars
        combinators.cleave colors ;
 
 IN: processing.shapes
@@ -19,13 +19,13 @@ T{ rgba f 1 1 1 1 } fill-color   set-global
 
 : fill-mode ( -- )
   GL_FRONT_AND_BACK GL_FILL glPolygonMode
-  fill-color> set-color ;
+  fill-color> gl-color ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : stroke-mode ( -- )
   GL_FRONT_AND_BACK GL_LINE glPolygonMode
-  stroke-color> set-color ;
+  stroke-color> gl-color ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -105,8 +105,8 @@ T{ rgba f 1 1 1 1 } fill-color   set-global
 
 : ellipse ( center dim -- )
   GL_FRONT_AND_BACK GL_FILL glPolygonMode
-  [ stroke-color> set-color                                 gl-ellipse ]
-  [ fill-color> set-color gl-get-line-width 2 * dup 2array v- gl-ellipse ] 2bi ;
+  [ stroke-color> gl-color                                 gl-ellipse ]
+  [ fill-color> gl-color gl-get-line-width 2 * dup 2array v- gl-ellipse ] 2bi ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
index 344b0f120956ea7f3fc025e9f6839bcf025af396..1e49be9a608d38038a1a8c57a7641dda8e8b73a4 100644 (file)
@@ -46,7 +46,7 @@ PRIVATE>
 
 
 : euler001b ( -- answer )
-    1000 [ dup 5 mod swap 3 mod [ zero? ] either? ] filter sum ;
+    1000 [ [ 5 mod ] [ 3 mod ] bi [ 0 = ] either? ] filter sum ;
 
 ! [ euler001b ] 100 ave-time
 ! 0 ms run / 0 ms GC ave time - 100 trials
index eb5f97b2de3586f2ead2f533009fca867799ed51..e1918f5fa6b5fb92b1a6f36e01b5852ac5a2584b 100644 (file)
@@ -21,7 +21,7 @@ IN: project-euler.004
 <PRIVATE
 
 : source-004 ( -- seq )
-    100 999 [a,b] [ 10 mod zero? not ] filter ;
+    100 999 [a,b] [ 10 mod 0 = not ] filter ;
 
 : max-palindrome ( seq -- palindrome )
     natural-sort [ palindrome? ] find-last nip ;
index 3b812cf242ae77c77211bd5439d120701db31994..aa0478415189afa35bfaf94773ff7ae34dcc6584 100644 (file)
@@ -58,7 +58,7 @@ PRIVATE>
 <PRIVATE
 
 : worth-calculating? ( n -- ? )
-    1- 3 { [ mod zero? ] [ / even? ] } 2&& ;
+    1- 3 { [ mod 0 = ] [ / even? ] } 2&& ;
 
 PRIVATE>
 
index 62e2e066fffebbf6fce9faf27fafd479525df146..16a7139f51cd032999e95d1b0b46b4f8acb89dfa 100644 (file)
@@ -33,7 +33,7 @@ IN: project-euler.019
 : euler019 ( -- answer )
     1901 2000 [a,b] [
         12 [1,b] [ 1 zeller-congruence ] with map
-    ] map concat [ zero? ] count ;
+    ] map concat [ 0 = ] count ;
 
 ! [ euler019 ] 100 ave-time
 ! 1 ms ave run time - 0.51 SD (100 trials)
@@ -58,7 +58,7 @@ IN: project-euler.019
 PRIVATE>
 
 : euler019a ( -- answer )
-    end-date start-date first-days [ zero? ] count ;
+    end-date start-date first-days [ 0 = ] count ;
 
 ! [ euler019a ] 100 ave-time
 ! 17 ms ave run time - 2.13 SD (100 trials)
index 37118b88a37b041c31708f639ac16c9c313bb1de..3b330dbe4b1e08aba4d73389e1dc9aa4b5784ec9 100644 (file)
@@ -59,7 +59,7 @@ PRIVATE>
     ] reduce-permutations ;
 
 ! [ euler043 ] time
-! 104526 ms run / 42735 ms GC time
+! 60280 ms run / 59 ms GC time
 
 
 ! ALTERNATE SOLUTIONS
index 84041babb79a7dd84576a741ed0a140e739f9467..30c01d8f61faa59cc851bc27a68c2d5903f82e1f 100644 (file)
@@ -66,7 +66,7 @@ SYMBOL: sieve
     0 <repetition> >array sieve set ;
 
 : is-prime? ( index -- ? )
-    sieve get nth zero? ;
+    sieve get nth 0 = ;
 
 : multiples ( n -- seq )
     sieve get length 1- over <range> ;
index 5362a6e9b0dfd6cb3fcbc11e665345b3fb0a7a0b..c382d992f660db94992bd95c19cb2fecf23d7721 100644 (file)
@@ -30,7 +30,7 @@ IN: project-euler.052
     [ number>digits natural-sort ] map all-equal? ;
 
 : candidate? ( n -- ? )
-    { [ odd? ] [ 3 mod zero? ] } 1&& ;
+    { [ odd? ] [ 3 mod 0 = ] } 1&& ;
 
 : next-all-same ( x n -- n )
     dup candidate? [
diff --git a/extra/project-euler/071/071-tests.factor b/extra/project-euler/071/071-tests.factor
new file mode 100644 (file)
index 0000000..ba61d76
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.071 tools.test ;
+IN: project-euler.071.tests
+
+[ 428570 ] [ euler071 ] unit-test
diff --git a/extra/project-euler/071/071.factor b/extra/project-euler/071/071.factor
new file mode 100644 (file)
index 0000000..feecd99
--- /dev/null
@@ -0,0 +1,49 @@
+! Copyright (c) 2008 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math project-euler.common sequences ;
+IN: project-euler.071
+
+! http://projecteuler.net/index.php?section=problems&id=71
+
+! DESCRIPTION
+! -----------
+
+! Consider the fraction, n/d, where n and d are positive integers. If n<d and
+! HCF(n,d) = 1, it is called a reduced proper fraction.
+
+! If we list the set of reduced proper fractions for d <= 8 in ascending order of
+! size, we get:
+
+!     1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8,
+!     2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
+
+! It can be seen that 2/5 is the fraction immediately to the left of 3/7.
+
+! By listing the set of reduced proper fractions for d <= 1,000,000 in
+! ascending order of size, find the numerator of the fraction immediately to the
+! left of 3/7.
+
+
+! SOLUTION
+! --------
+
+! Use the properties of a Farey sequence by setting an upper bound of 3/7 and
+! then taking the mediant of that fraction and the one to its immediate left
+! repeatedly until the denominator is as close to 1000000 as possible without
+! going over.
+
+<PRIVATE
+
+: penultimate ( seq -- elt )
+    dup length 2 - swap nth ;
+
+PRIVATE>
+
+: euler071 ( -- answer )
+    2/5 [ dup denominator 1000000 <= ] [ 3/7 mediant dup ] [ ] produce
+    nip penultimate numerator ;
+
+! [ euler071 ] 100 ave-time
+! 155 ms ave run time - 6.95 SD (100 trials)
+
+MAIN: euler071
diff --git a/extra/project-euler/073/073-tests.factor b/extra/project-euler/073/073-tests.factor
new file mode 100644 (file)
index 0000000..6389150
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.073 tools.test ;
+IN: project-euler.073.tests
+
+[ 5066251 ] [ euler073 ] unit-test
diff --git a/extra/project-euler/073/073.factor b/extra/project-euler/073/073.factor
new file mode 100644 (file)
index 0000000..68dcd01
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (c) 2008 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel locals make math project-euler.common sequences ;
+IN: project-euler.073
+
+! http://projecteuler.net/index.php?section=problems&id=73
+
+! DESCRIPTION
+! -----------
+
+! Consider the fraction, n/d, where n and d are positive integers. If n<d and
+! HCF(n,d) = 1, it is called a reduced proper fraction.
+
+! If we list the set of reduced proper fractions for d <= 8 in ascending order of
+! size, we get:
+
+!     1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8,
+!     2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
+
+! It can be seen that there are 3 fractions between 1/3 and 1/2.
+
+! How many fractions lie between 1/3 and 1/2 in the sorted set of reduced
+! proper fractions for d <= 10,000?
+
+
+! SOLUTION
+! --------
+
+! Use the properties of a Farey sequence and mediants to recursively generate
+! the next fraction until the denominator is as close to 1000000 as possible
+! without going over.
+
+<PRIVATE
+
+:: (euler073) ( limit lo hi -- )
+    [let | m [ lo hi mediant ] |
+        m denominator limit <= [
+            m ,
+            limit lo m (euler073)
+            limit m hi (euler073)
+        ] when
+    ] ;
+
+PRIVATE>
+
+: euler073 ( -- answer )
+    [ 10000 1/3 1/2 (euler073) ] { } make length ;
+
+! [ euler073 ] 10 ave-time
+! 20506 ms ave run time - 937.07 SD (10 trials)
+
+MAIN: euler073
diff --git a/extra/project-euler/203/203-tests.factor b/extra/project-euler/203/203-tests.factor
new file mode 100644 (file)
index 0000000..6c49c2f
--- /dev/null
@@ -0,0 +1,5 @@
+USING: project-euler.203 tools.test ;
+IN: project-euler.203.tests
+
+[ 105 ] [ 8 solve ] unit-test
+[ 34029210557338 ] [ 51 solve ] unit-test
diff --git a/extra/project-euler/203/203.factor b/extra/project-euler/203/203.factor
new file mode 100644 (file)
index 0000000..9a29166
--- /dev/null
@@ -0,0 +1,9 @@
+USING: fry kernel math math.primes.factors sequences sets ;
+IN: project-euler.203
+
+: iterate ( n initial quot -- results ) swapd '[ @ dup ] replicate nip ; inline
+: (generate) ( seq -- seq ) [ 0 prefix ] [ 0 suffix ] bi [ + ] 2map ;
+: generate ( n -- seq ) 1- { 1 } [ (generate) ] iterate concat prune ;
+: squarefree ( n -- ? ) factors duplicates empty? ;
+: solve ( n -- n ) generate [ squarefree ] filter sum ;
+: euler203 ( -- n ) 51 solve ;
diff --git a/extra/project-euler/215/215-tests.factor b/extra/project-euler/215/215-tests.factor
new file mode 100644 (file)
index 0000000..9d265b7
--- /dev/null
@@ -0,0 +1,5 @@
+USING: project-euler.215 project-euler.215.private tools.test ;
+IN: project-euler.215.tests
+
+[ 8 ] [ 9 3 solve ] unit-test
+[ 806844323190414 ] [ euler215 ] unit-test
diff --git a/extra/project-euler/215/215.factor b/extra/project-euler/215/215.factor
new file mode 100644 (file)
index 0000000..fc09b37
--- /dev/null
@@ -0,0 +1,92 @@
+! Copyright (c) 2008 Eric Mertens.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel locals math ;
+IN: project-euler.215
+
+! http://projecteuler.net/index.php?section=problems&id=215
+
+! DESCRIPTION
+! -----------
+
+! Consider the problem of building a wall out of 2x1 and 3x1 bricks
+! (horizontalvertical dimensions) such that, for extra strength, the gaps
+! between horizontally-adjacent bricks never line up in consecutive layers,
+! i.e. never form a "running crack".
+
+! For example, the following 93 wall is not acceptable due to the running crack
+! shown in red:
+
+!     See problem site for image...
+
+! There are eight ways of forming a crack-free 9x3 wall, written W(9,3) = 8.
+
+! Calculate W(32,10).
+
+
+! SOLUTION
+! --------
+
+<PRIVATE
+
+TUPLE: block two three ;
+TUPLE: end { ways integer } ;
+
+C: <block> block
+C: <end> end
+: <failure> 0 <end> ; inline
+: <success> 1 <end> ; inline
+
+: failure? ( t -- ? ) ways>> 0 = ; inline
+
+: choice ( t p q -- t t )
+    [ [ two>> ] [ three>> ] bi ] 2dip bi* ; inline
+
+GENERIC: merge ( t t -- t )
+GENERIC# block-merge 1 ( t t -- t )
+GENERIC# end-merge 1 ( t t -- t )
+M: block merge block-merge ;
+M: end   merge end-merge ;
+M: block block-merge [ [ two>>   ] bi@ merge ]
+                     [ [ three>> ] bi@ merge ] 2bi <block> ;
+M: end   block-merge nip ;
+M: block end-merge drop ;
+M: end   end-merge [ ways>> ] bi@ + <end> ;
+
+GENERIC: h-1 ( t -- t )
+GENERIC: h0 ( t -- t )
+GENERIC: h1 ( t -- t )
+GENERIC: h2 ( t -- t )
+
+M: block h-1 [ h1 ] [ h2 ] choice merge ;
+M: block h0 drop <failure> ;
+M: block h1 [ [ h1 ] [ h2 ] choice merge ]
+            [ [ h0 ] [ h1 ] choice merge ] bi <block> ;
+M: block h2 [ h1 ] [ h2 ] choice merge <failure> swap <block> ;
+
+M: end h-1 drop <failure> ;
+M: end h0 ;
+M: end h1 drop <failure> ;
+M: end h2 dup failure? [ <failure> <block> ] unless ;
+
+: next-row ( t -- t ) [ h-1 ] [ h1 ] choice swap <block> ;
+
+: first-row ( n -- t )
+    [ <failure> <success> <failure> ] dip
+    1- [| a b c | b c <block> a b ] times 2drop ;
+
+GENERIC: total ( t -- n )
+M: block total [ total ] dup choice + ;
+M: end   total ways>> ;
+
+: solve ( width height -- ways )
+    [ first-row ] dip 1- [ next-row ] times total ;
+
+PRIVATE>
+
+: euler215 ( -- answer )
+    32 10 solve ;
+
+! [ euler215 ] 100 ave-time
+! 208 ms ave run time - 9.06 SD (100 trials)
+
+MAIN: euler215
index d3263bbc1e31a64d209f0ce1937b4a0b8dd9777b..35d9c65b538c1cc65de645555fbce855630f95e7 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (c) 2007-2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel make math math.functions math.matrices math.miller-rabin
-    math.order math.parser math.primes.factors math.ranges sequences
-    sequences.lib sorting strings unicode.case ;
+    math.order math.parser math.primes.factors math.ranges math.ratios
+    sequences sequences.lib sorting strings unicode.case ;
 IN: project-euler.common
 
 ! A collection of words used by more than one Project Euler solution
@@ -14,6 +14,7 @@ IN: project-euler.common
 ! cartesian-product - #4, #27, #29, #32, #33, #43, #44, #56
 ! log10 - #25, #134
 ! max-path - #18, #67
+! mediant - #71, #73
 ! nth-triangle - #12, #42
 ! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92
 ! palindrome? - #4, #36, #55
@@ -42,7 +43,7 @@ IN: project-euler.common
 
 : (sum-divisors) ( n -- sum )
     dup sqrt >fixnum [1,b] [
-        [ 2dup mod zero? [ 2dup / + , ] [ drop ] if ] each
+        [ 2dup mod 0 = [ 2dup / + , ] [ drop ] if ] each
         dup perfect-square? [ sqrt >fixnum neg , ] [ drop ] if
     ] { } make sum ;
 
@@ -60,6 +61,9 @@ PRIVATE>
 : log10 ( m -- n )
     log 10 log / ;
 
+: mediant ( a/c b/d -- (a+b)/(c+d) )
+    2>fraction [ + ] 2bi@ / ;
+
 : max-path ( triangle -- n )
     dup length 1 > [
         2 cut* first2 max-children [ + ] 2map suffix max-path
@@ -68,7 +72,7 @@ PRIVATE>
     ] if ;
 
 : number>digits ( n -- seq )
-    [ dup zero? not ] [ 10 /mod ] [ ] produce reverse nip ;
+    [ dup 0 = not ] [ 10 /mod ] [ ] produce reverse nip ;
 
 : nth-triangle ( n -- n )
     dup 1+ * 2 / ;
@@ -112,7 +116,7 @@ PRIVATE>
     factor-2s dup [ 1+ ]
     [ perfect-square? -1 0 ? ]
     [ dup sqrt >fixnum [1,b] ] tri* [
-        dupd mod zero? [ [ 2 + ] dip ] when
+        dupd mod 0 = [ [ 2 + ] dip ] when
     ] each drop * ;
 
 ! These transforms are for generating primitive Pythagorean triples
index d85e7e206d1b6d29a08ea110ffd1b30dadd923e4..9549505bf603b79ed3ec15feb68119d46a46ad96 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer, Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: definitions io io.files kernel math math.parser project-euler.ave-time
-    sequences vocabs vocabs.loader prettyprint
+USING: definitions io io.files kernel math math.parser
+    prettyprint project-euler.ave-time sequences vocabs vocabs.loader
     project-euler.001 project-euler.002 project-euler.003 project-euler.004
     project-euler.005 project-euler.006 project-euler.007 project-euler.008
     project-euler.009 project-euler.010 project-euler.011 project-euler.012
@@ -15,11 +15,12 @@ USING: definitions io io.files kernel math math.parser project-euler.ave-time
     project-euler.041 project-euler.042 project-euler.043 project-euler.044
     project-euler.045 project-euler.046 project-euler.047 project-euler.048
     project-euler.052 project-euler.053 project-euler.055 project-euler.056
-    project-euler.059 project-euler.067 project-euler.075 project-euler.076
-    project-euler.079 project-euler.092 project-euler.097 project-euler.100
-    project-euler.116 project-euler.117 project-euler.134 project-euler.148
-    project-euler.150 project-euler.151 project-euler.164 project-euler.169
-    project-euler.173 project-euler.175 project-euler.186 project-euler.190 ;
+    project-euler.059 project-euler.067 project-euler.071 project-euler.073
+    project-euler.075 project-euler.076 project-euler.079 project-euler.092
+    project-euler.097 project-euler.100 project-euler.116 project-euler.117
+    project-euler.134 project-euler.148 project-euler.150 project-euler.151
+    project-euler.164 project-euler.169 project-euler.173 project-euler.175
+    project-euler.186 project-euler.190 project-euler.215 ;
 IN: project-euler
 
 <PRIVATE
index 87551635f173386c55546d28f83c72d94e6e5d30..4a8197f0647df2a1bcaeb26a68c79c5c198e3f5b 100644 (file)
@@ -1,3 +1,5 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
 USING: help.markup help.syntax kernel math ;
 IN: roman
 
@@ -5,44 +7,114 @@ HELP: >roman
 { $values { "n" "an integer" } { "str" "a string" } }
 { $description "Converts a number to its lower-case Roman Numeral equivalent." }
 { $notes "The range for this word is 1-3999, inclusive." }
-{ $see-also >ROMAN roman> } ;
+{ $examples 
+    { $example "USING: io roman ;"
+               "56 >roman print"
+               "lvi"
+    }
+} ;
 
 HELP: >ROMAN
 { $values { "n" "an integer" } { "str" "a string" } }
 { $description "Converts a number to its upper-case Roman numeral equivalent." }
 { $notes "The range for this word is 1-3999, inclusive." }
-{ $see-also >roman roman> } ;
+{ $examples 
+    { $example "USING: io roman ;"
+               "56 >ROMAN print"
+               "LVI"
+    }
+} ;
 
 HELP: roman>
 { $values { "str" "a string" } { "n" "an integer" } }
 { $description "Converts a Roman numeral to an integer." }
 { $notes "The range for this word is i-mmmcmxcix, inclusive." }
-{ $see-also >roman } ;
+{ $examples 
+    { $example "USING: prettyprint roman ;"
+               "\"lvi\" roman> ."
+               "56"
+    }
+} ;
+
+{ >roman >ROMAN roman> } related-words
 
 HELP: roman+
 { $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
 { $description "Adds two Roman numerals." }
-{ $see-also roman- } ;
+{ $examples 
+    { $example "USING: io roman ;"
+               "\"v\" \"v\" roman+ print"
+               "x"
+    }
+} ;
 
 HELP: roman-
 { $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
 { $description "Subtracts two Roman numerals." }
-{ $see-also roman+ } ;
+{ $examples 
+    { $example "USING: io roman ;"
+               "\"x\" \"v\" roman- print"
+               "v"
+    }
+} ;
+
+{ roman+ roman- } related-words
 
 HELP: roman*
 { $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
 { $description "Multiplies two Roman numerals." }
-{ $see-also roman/i roman/mod } ;
+{ $examples 
+    { $example "USING: io roman ;"
+        "\"ii\" \"iii\" roman* print"
+        "vi"
+    }
+} ;
 
 HELP: roman/i
 { $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
 { $description "Computes the integer division of two Roman numerals." }
-{ $see-also roman* roman/mod /i } ;
+{ $examples 
+    { $example "USING: io roman ;"
+        "\"v\" \"iv\" roman/i print"
+        "i"
+    }
+} ;
 
 HELP: roman/mod
 { $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } { "str4" "a string" } }
 { $description "Computes the quotient and remainder of two Roman numerals." }
-{ $see-also roman* roman/i /mod } ;
+{ $examples 
+    { $example "USING: kernel io roman ;"
+        "\"v\" \"iv\" roman/mod [ print ] bi@"
+        "i\ni"
+    }
+} ;
+
+{ roman* roman/i roman/mod } related-words
 
 HELP: ROMAN:
-{ $description "A parsing word that reads the next token and converts it to an integer." } ;
+{ $description "A parsing word that reads the next token and converts it to an integer." }
+{ $examples 
+    { $example "USING: prettyprint roman ;"
+               "ROMAN: v ."
+               "5"
+    }
+} ;
+
+ARTICLE: "roman" "Roman numerals"
+"The " { $vocab-link "roman" } " vocabulary can convert numbers to and from the Roman numeral system and can perform arithmetic given Roman numerals as input." $nl
+"A parsing word for literal Roman numerals:"
+{ $subsection POSTPONE: ROMAN: }
+"Converting to Roman numerals:"
+{ $subsection >roman }
+{ $subsection >ROMAN }
+"Converting Roman numerals to integers:"
+{ $subsection roman> }
+"Roman numeral arithmetic:"
+{ $subsection roman+ }
+{ $subsection roman- }
+{ $subsection roman* }
+{ $subsection roman/i }
+{ $subsection roman/mod } ;
+
+ABOUT: "roman"
index 6fe3de4f0385e941aba1ad1f5ab356367e9886ce..9dc01c04faea05e4b1be0121400133d938ff71bd 100755 (executable)
@@ -152,3 +152,6 @@ PRIVATE>
 
 : enumerate ( seq -- seq' ) <enum> >alist ;
 
+: splice ( left-seq right-seq seq -- newseq ) swap 3append ;
+
+: surround ( seq left-seq right-seq -- newseq ) swapd 3append ;
diff --git a/extra/size-of/size-of.factor b/extra/size-of/size-of.factor
deleted file mode 100644 (file)
index 8157ba7..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-
-USING: kernel namespaces sequences
-       io io.files io.launcher io.encodings.ascii
-       bake builder.util
-       accessors vars
-       math.parser ;
-
-IN: size-of
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: headers
-
-: include-headers ( -- seq )
-  headers> [ `{ "#include <" , ">" } to-string ] map ;
-
-: size-of-c-program ( type -- lines )
-  `{
-    "#include <stdio.h>"
-    include-headers
-    { "main() { printf( \"%i\" , sizeof( " , " ) ) ; }" }
-  }
-  to-strings ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: c-file ( -- path ) "size-of.c" temp-file ;
-
-: exe ( -- path ) "size-of" temp-file ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: size-of ( type -- n )
-  size-of-c-program c-file ascii set-file-lines
-
-  { "gcc" c-file "-o" exe } to-strings
-  [ "Error compiling generated C program" print ] run-or-bail
-
-  exe ascii <process-reader> contents string>number ;
\ No newline at end of file
index f119956db6d6c4644f6a2ba35d7e7c04019b0b84..06468b875189a0f730db102621830f5893df15da 100755 (executable)
@@ -1,6 +1,7 @@
-USING: kernel opengl.demo-support opengl.gl opengl.shaders opengl.framebuffers
-opengl multiline ui.gadgets accessors sequences ui.render ui math locals
-arrays generalizations combinators opengl.capabilities ui.gadgets.worlds ;
+USING: kernel opengl opengl.demo-support opengl.gl
+opengl.shaders opengl.framebuffers opengl.capabilities multiline
+ui.gadgets accessors sequences ui.render ui math locals arrays
+generalizations combinators ui.gadgets.worlds ;
 IN: spheres
 
 STRING: plane-vertex-shader
index 423a68cf0d3db0bc3300a64babd8d01ce6380644..07865f38e0e31b1fb51848189e69831f47f67f9e 100644 (file)
@@ -25,7 +25,7 @@ IN: springies.ui
 
 ! : display ( -- ) set-projection black gl-color draw-nodes draw-springs ;
 
-: display ( -- ) set-projection black set-color draw-nodes draw-springs ;
+: display ( -- ) set-projection black gl-color draw-nodes draw-springs ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
diff --git a/extra/suffix-arrays/authors.txt b/extra/suffix-arrays/authors.txt
deleted file mode 100755 (executable)
index e4a36df..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Marc Fauconneau
\ No newline at end of file
diff --git a/extra/suffix-arrays/suffix-arrays-docs.factor b/extra/suffix-arrays/suffix-arrays-docs.factor
deleted file mode 100755 (executable)
index 87df272..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-! Copyright (C) 2008 Marc Fauconneau.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays help.markup help.syntax io.streams.string
-sequences strings math suffix-arrays.private ;
-IN: suffix-arrays
-
-HELP: >suffix-array
-{ $values
-     { "seq" sequence }
-     { "array" array } }
-{ $description "Creates a suffix array from the input sequence.  Suffix arrays are arrays of slices." } ;
-
-HELP: SA{
-{ $description "Creates a new literal suffix array at parse-time." } ;
-
-HELP: suffixes
-{ $values
-     { "string" string }
-     { "suffixes-seq" "a sequence of slices" } }
-{ $description "Returns a sequence of tail slices of the input string." } ;
-
-HELP: from-to
-{ $values
-     { "index" integer } { "begin" sequence } { "suffix-array" "a suffix-array" }
-     { "from/f" "an integer or f" } { "to/f" "an integer or f" } }
-{ $description "Finds the bounds of the suffix array that match the input sequence. A return value of " { $link f } " means that the endpoint is included." }
-{ $notes "Slices are [m,n) and we want (m,n) so we increment." } ;
-
-HELP: query
-{ $values
-     { "begin" sequence } { "suffix-array" "a suffix-array" }
-     { "matches" array } }
-{ $description "Returns a sequence of sequences from the suffix-array that contain the input sequence. An empty array is returned when there are no matches." } ;
-
-ARTICLE: "suffix-arrays" "Suffix arrays"
-"The " { $vocab-link "suffix-arrays" } " vocabulary implements the suffix array data structure for efficient lookup of subsequences. This suffix array implementation is a sorted array of suffixes. Querying it for matches uses binary search for efficiency." $nl
-
-"Creating new suffix arrays:"
-{ $subsection >suffix-array }
-"Literal suffix arrays:"
-{ $subsection POSTPONE: SA{ }
-"Querying suffix arrays:"
-{ $subsection query } ;
-
-ABOUT: "suffix-arrays"
diff --git a/extra/suffix-arrays/suffix-arrays-tests.factor b/extra/suffix-arrays/suffix-arrays-tests.factor
deleted file mode 100755 (executable)
index 5149804..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-! Copyright (C) 2008 Marc Fauconneau.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test suffix-arrays kernel namespaces sequences ;
-IN: suffix-arrays.tests
-
-! built from [ all-words 10 head [ name>> ] map ]
-[ ] [ 
-     {
-        "run-tests"
-        "must-fail-with"
-        "test-all"
-        "short-effect"
-        "failure"
-        "test"
-        "<failure>"
-        "this-test"
-        "(unit-test)"
-        "unit-test"
-    } >suffix-array "suffix-array" set
-] unit-test
-
-[ t ]
-[ "suffix-array" get "" swap query empty? not ] unit-test
-
-[ { } ]
-[ SA{ } "something" swap query ] unit-test
-
-[ V{ "unit-test" "(unit-test)" } ]
-[ "suffix-array" get "unit-test" swap query ] unit-test
-
-[ t ]
-[ "suffix-array" get "something else" swap query empty? ] unit-test
-
-[ V{ "rofl" } ] [ SA{ "rofl" } "r" swap query ] unit-test
-[ V{ "rofl" } ] [ SA{ "rofl" } "o" swap query ] unit-test
-[ V{ "rofl" } ] [ SA{ "rofl" } "f" swap query ] unit-test
-[ V{ "rofl" } ] [ SA{ "rofl" } "l" swap query ] unit-test
-[ V{ } ] [ SA{ "rofl" } "t" swap query ] unit-test
diff --git a/extra/suffix-arrays/suffix-arrays.factor b/extra/suffix-arrays/suffix-arrays.factor
deleted file mode 100755 (executable)
index b181ba9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-! Copyright (C) 2008 Marc Fauconneau.
-! See http://factorcode.org/license.txt for BSD license.
-USING: parser kernel arrays math accessors sequences
-math.vectors math.order sorting binary-search sets assocs fry ;
-IN: suffix-arrays
-
-<PRIVATE
-: suffixes ( string -- suffixes-seq )
-    dup length [ tail-slice ] with map ;
-
-: prefix<=> ( begin seq -- <=> )
-    [ <=> ] [ swap head? ] 2bi [ drop +eq+ ] when ;
-: find-index ( begin suffix-array -- index/f )
-    [ prefix<=> ] with search drop ;
-
-: from-to ( index begin suffix-array -- from/f to/f )
-    swap '[ _ head? not ]
-    [ find-last-from drop dup [ 1+ ] when ]
-    [ find-from drop ] 3bi ;
-
-: <funky-slice> ( from/f to/f seq -- slice )
-    [
-        tuck
-        [ drop 0 or ] [ length or ] 2bi*
-        [ min ] keep
-    ] keep <slice> ; inline
-
-PRIVATE>
-
-: >suffix-array ( seq -- array )
-    [ suffixes ] map concat natural-sort ;
-
-: SA{ \ } [ >suffix-array ] parse-literal ; parsing
-
-: query ( begin suffix-array -- matches )
-    2dup find-index dup
-    [ -rot [ from-to ] keep <funky-slice> [ seq>> ] map prune ]
-    [ 3drop { } ] if ;
diff --git a/extra/suffix-arrays/summary.txt b/extra/suffix-arrays/summary.txt
deleted file mode 100755 (executable)
index 71eda47..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Suffix arrays
diff --git a/extra/suffix-arrays/tags.txt b/extra/suffix-arrays/tags.txt
deleted file mode 100755 (executable)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
diff --git a/extra/suffix-arrays/words/words.factor b/extra/suffix-arrays/words/words.factor
deleted file mode 100755 (executable)
index 74e2fc2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-! Copyright (C) 2008 Marc Fauconneau.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: kernel arrays math accessors sequences math.vectors\r
-math.order sorting binary-search sets assocs fry suffix-arrays ;\r
-IN: suffix-arrays.words\r
-\r
-! to search on word names\r
-\r
-: new-word-sa ( words -- sa )\r
-    [ name>> ] map >suffix-array ;\r
-\r
-: name>word-map ( words -- map )\r
-    dup [ name>> V{ } clone ] H{ } map>assoc\r
-    [ '[ dup name>> _ at push ] each ] keep ;\r
-\r
-: query-word-sa ( map begin sa -- matches ) query '[ _ at ] map concat ;\r
-\r
-! usage example :\r
-! clear all-words 100 head dup name>word-map "test" rot new-word-sa query .\r
index 286ac0183a0d2398b7fc9486a7f0cf78b6447cb5..e3c14854d3b29aa861679fd1533858766645ab0d 100755 (executable)
@@ -1,6 +1,6 @@
 USING: combinators io io.files io.streams.string kernel math
 math.parser continuations namespaces pack prettyprint sequences
-strings system hexdump io.encodings.binary summary accessors
+strings system tools.hexdump io.encodings.binary summary accessors
 io.backend symbols byte-arrays ;
 IN: tar
 
index d47f0272939593f0fef987e08013075a41ba7b12..a9b00ffb7cd19343da7adf0659e28052e37c8a1b 100644 (file)
@@ -6,22 +6,22 @@ IN: tetris.gl
 #! OpenGL rendering for tetris
 
 : draw-block ( block -- )
-    dup { 1 1 } v+ gl-fill-rect ;
+    [ { 1 1 } gl-fill-rect ] with-translation ;
 
 : draw-piece-blocks ( piece -- )
     piece-blocks [ draw-block ] each ;
 
 : draw-piece ( piece -- )
-    dup tetromino>> colour>> set-color draw-piece-blocks ;
+    dup tetromino>> colour>> gl-color draw-piece-blocks ;
 
 : draw-next-piece ( piece -- )
     dup tetromino>> colour>>
-    clone 0.2 >>alpha set-color draw-piece-blocks ;
+    clone 0.2 >>alpha gl-color draw-piece-blocks ;
 
 ! TODO: move implementation specific stuff into tetris-board
 : (draw-row) ( x y row -- )
     >r over r> nth dup
-    [ set-color 2array draw-block ] [ 3drop ] if ;
+    [ gl-color 2array draw-block ] [ 3drop ] if ;
 
 : draw-row ( y row -- )
     dup length -rot [ (draw-row) ] 2curry each ;
diff --git a/extra/time-server/authors.txt b/extra/time-server/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/time-server/time-server-tests.factor b/extra/time-server/time-server-tests.factor
new file mode 100644 (file)
index 0000000..a9fac2d
--- /dev/null
@@ -0,0 +1,4 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test time-server ;
+IN: time-server.tests
diff --git a/extra/time-server/time-server.factor b/extra/time-server/time-server.factor
new file mode 100644 (file)
index 0000000..28debf1
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io io.servers.connection accessors threads
+calendar calendar.format ;
+IN: time-server
+
+: handle-time-client ( -- )
+    now timestamp>rfc822 print ;
+
+: <time-server> ( -- threaded-server )
+    <threaded-server>
+        "time-server" >>name
+        1234 >>insecure
+        [ handle-time-client ] >>handler ;
+
+: start-time-server ( -- threaded-server )
+    <time-server> [ start-server ] in-thread ;
+
+MAIN: start-time-server
index 0dcf853b981fa526a3603c5c2b2300089d4db42f..0c7b442ffade93987ed3d68976b58bebbb2cf51d 100644 (file)
@@ -1,5 +1,5 @@
 
-USING: namespaces debugger io.files bootstrap.image builder.util ;
+USING: namespaces debugger io.files bootstrap.image update.util ;
 
 IN: update.backup
 
index df057422f99a34beed0c8af458b48e615a38f5bf..7cc2fac853a206e0d928c7b7ec45f655bb1d3b72 100644 (file)
@@ -1,6 +1,6 @@
 
 USING: kernel namespaces system io.files bootstrap.image http.client
-       builder.util update update.backup ;
+       update update.backup update.util ;
 
 IN: update.latest
 
index 1d25a9792ef1d52f0571487450d65b9fb73c36a2..c6a5671345c95b8d0c3d63e9438cc955d6afff4f 100644 (file)
@@ -1,7 +1,9 @@
 
 USING: kernel system sequences io.files io.launcher bootstrap.image
        http.client
-       builder.util builder.release.branch ;
+       update.util ;
+
+       ! builder.util builder.release.branch ;
 
 IN: update
 
diff --git a/extra/update/util/util.factor b/extra/update/util/util.factor
new file mode 100644 (file)
index 0000000..b638b61
--- /dev/null
@@ -0,0 +1,62 @@
+
+USING: kernel classes strings quotations words math math.parser arrays
+       combinators.cleave
+       accessors
+       system prettyprint splitting
+       sequences combinators sequences.deep
+       io
+       io.launcher
+       io.encodings.utf8
+       calendar
+       calendar.format ;
+
+IN: update.util
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+DEFER: to-strings
+
+: to-string ( obj -- str )
+  dup class
+    {
+      { \ string    [ ] }
+      { \ quotation [ call ] }
+      { \ word      [ execute ] }
+      { \ fixnum    [ number>string ] }
+      { \ array     [ to-strings concat ] }
+    }
+  case ;
+
+: to-strings ( seq -- str )
+  dup [ string? ] all?
+    [ ]
+    [ [ to-string ] map flatten ]
+  if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: cpu- ( -- cpu ) cpu unparse "." split "-" join ;
+
+: platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: branch-name ( -- string ) "clean-" platform append ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: gnu-make ( -- string )
+  os { freebsd openbsd netbsd } member? [ "gmake" ] [ "make" ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: git-id ( -- id )
+  { "git" "show" } utf8 <process-reader> [ readln ] with-input-stream
+  " " split second ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: datestamp ( -- string )
+  now
+    { year>> month>> day>> hour>> minute>> } <arr>
+  [ pad-00 ] map "-" join ;
index 9cb0250518424253d7114fb2dcc88b6fc3617740..a2741ccd4ea133186c98dfd439e6a97aff94a6d5 100644 (file)
@@ -13,5 +13,5 @@
                </t:form>
        </div>
 
-       <t:validation-messages />
+       <t:validation-errors />
 </t:chloe>
index f41e8a97b481e2713ca6e5e719525f05cedb347a..27b6beaec67feadb597d937dd06761035dcd08f0 100644 (file)
@@ -51,7 +51,7 @@
        
        <p>
                <button type="submit" >Update</button>
-               <t:validation-messages />
+               <t:validation-errors />
        </p>
 
        </t:form>
index 7acdd384ba920e3c17715e866178551775465162..d3cf681165868caadcfac5e2de48d1e37e8dea85 100644 (file)
@@ -46,7 +46,7 @@
        
        <p>
                <button type="submit" class="link-button link">Create</button>
-               <t:validation-messages />
+               <t:validation-errors />
        </p>
 
        </t:form>
index 1ae8919559ca0d56779d302f02612a3e9bfbbe13..72fdf6415987d156489e13bc33a08819adcf4d67 100644 (file)
@@ -19,9 +19,6 @@
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-;; BUG: A double quote character on a commented line will break the
-;; syntax highlighting for that line.
-
 (defgroup factor nil
   "Factor mode"
   :group 'languages)
   :type 'hook
   :group 'factor)
 
+(defconst factor--parsing-words
+  '("{" "}" "^:" "^::" ";" "<<" "<PRIVATE" ">>"
+    "BIN:" "BV{" "B{" "C:" "C-STRUCT:" "C-UNION:" "CHAR:" "CS{" "C{"
+    "DEFER:" "ERROR:" "FORGET:"
+    "GENERIC#" "GENERIC:" "HEX:" "HOOK:" "H{"
+    "IN:" "INSTANCE:" "INTERSECTION:"
+    "M:" "MACRO:" "MACRO::" "MAIN:" "MATH:" "METHOD:" "MIXIN:"
+    "OCT:" "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
+    "REQUIRE:"  "REQUIRES:" "SINGLETON:" "SLOT:" "SYMBOL:" "SYMBOLS:"
+    "TUPLE:" "T{" "t\\??" "TYPEDEF:"
+    "UNION:" "USE:" "USING:" "V{" "VAR:" "VARS:" "W{"))
+
+(defconst factor--regex--parsing-words-ext
+  (regexp-opt '("B" "call-next-method" "delimiter" "f" "flushable" "foldable"
+                "initial:" "inline" "parsing" "read-only" "recursive")
+              'words))
+
 (defconst factor-font-lock-keywords
-  '(("#!.*$" . font-lock-comment-face)
+  `(("#!.*$" . font-lock-comment-face)
     ("!( .* )" . font-lock-comment-face)
     ("^!.*$" . font-lock-comment-face)
     (" !.*$" . font-lock-comment-face)
     ("( .* )" . font-lock-comment-face)
-    "BIN:"
-    "MAIN:"
-    "IN:" "USING:" "TUPLE:" "^C:" "^M:"
-    "METHOD:"
-    "USE:" "REQUIRE:" "PROVIDE:"
-    "REQUIRES:"
-    "GENERIC:" "GENERIC#" "SYMBOL:" "PREDICATE:" "VAR:" "VARS:"
-    "C-STRUCT:"
-    "C-UNION:" "<PRIVATE" "PRIVATE>" "MACRO:" "MACRO::" "DEFER:" "TYPEDEF:"
-    "SYMBOLS:"
-))
+    ("\"[^ ][^\"]*\"" . font-lock-string-face)
+    ("\\(P\\|SBUF\\)\"" 1 font-lock-keyword-face)
+    ,@(mapcar #'(lambda (w) (cons (concat "\\(^\\| \\)\\(" w "\\)\\($\\| \\)")
+                             '(2 font-lock-keyword-face)))
+              factor--parsing-words)
+    (,factor--regex--parsing-words-ext . font-lock-keyword-face)))
 
 (defun factor-indent-line ()
   "Indent current line as Factor code"
   (setq comment-start "! ")
   (make-local-variable 'font-lock-defaults)
   (setq font-lock-defaults
-       '(factor-font-lock-keywords nil nil nil nil))
+       '(factor-font-lock-keywords t nil nil nil))
   (set-syntax-table factor-mode-syntax-table)
   (make-local-variable 'indent-line-function)
   (setq indent-line-function 'factor-indent-line)
diff --git a/unmaintained/cairo-demo/authors.txt b/unmaintained/cairo-demo/authors.txt
deleted file mode 100755 (executable)
index 4a2736d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sampo Vuori
diff --git a/unmaintained/cairo-demo/cairo-demo.factor b/unmaintained/cairo-demo/cairo-demo.factor
deleted file mode 100644 (file)
index 29fb99a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-! Cairo "Hello World" demo
-!  Copyright (c) 2007 Sampo Vuori
-!    License: http://factorcode.org/license.txt
-!
-! This example is an adaptation of the following cairo sample code:
-!  http://cairographics.org/samples/text/
-
-
-USING: cairo.ffi math math.constants byte-arrays kernel ui ui.render
-           ui.gadgets opengl.gl ;
-
-IN: cairo-demo
-
-
-: make-image-array ( -- array )
-  384 256 4 * * <byte-array> ;
-
-: convert-array-to-surface ( array -- cairo_surface_t )
-  CAIRO_FORMAT_ARGB32 384 256 over 4 *
-  cairo_image_surface_create_for_data ;
-
-
-TUPLE: cairo-gadget image-array cairo-t ;
-
-M: cairo-gadget draw-gadget* ( gadget -- )
-    0 0 glRasterPos2i
-    1.0 -1.0 glPixelZoom
-    >r 384 256 GL_RGBA GL_UNSIGNED_BYTE r>
-    cairo-gadget-image-array glDrawPixels ;
-
-: create-surface ( gadget -- cairo_surface_t )
-    make-image-array
-    [ swap set-cairo-gadget-image-array ] keep
-    convert-array-to-surface ;
-
-: init-cairo ( gadget -- cairo_t )
-   create-surface cairo_create ;
-
-M: cairo-gadget pref-dim* drop { 384 256 0 } ;
-
-: draw-hello-world ( gadget -- )
-  cairo-gadget-cairo-t
-  dup "Sans" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_BOLD cairo_select_font_face
-  dup 90.0 cairo_set_font_size
-  dup 10.0 135.0 cairo_move_to
-  dup "Hello" cairo_show_text
-  dup 70.0 165.0 cairo_move_to
-  dup "World" cairo_text_path
-  dup 0.5 0.5 1 cairo_set_source_rgb
-  dup cairo_fill_preserve
-  dup 0 0 0 cairo_set_source_rgb
-  dup 2.56 cairo_set_line_width
-  dup cairo_stroke
-  dup 1 0.2 0.2 0.6 cairo_set_source_rgba
-  dup 10.0 135.0 5.12 0 pi 2 * cairo_arc
-  dup cairo_close_path
-  dup 70.0 165.0 5.12 0 pi 2 * cairo_arc
-  cairo_fill ;
-
-M: cairo-gadget graft* ( gadget -- )
-  dup dup init-cairo swap set-cairo-gadget-cairo-t draw-hello-world ;
-
-M: cairo-gadget ungraft* ( gadget -- )
-   cairo-gadget-cairo-t cairo_destroy ;
-
-: <cairo-gadget> ( -- gadget )
-  cairo-gadget construct-gadget ;
-
-: run ( -- )
-  [
-        <cairo-gadget> "Hello World from Factor!" open-window
-  ] with-ui ;
-
-MAIN: run
diff --git a/unmaintained/cairo/authors.txt b/unmaintained/cairo/authors.txt
deleted file mode 100644 (file)
index 68d35d1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Sampo Vuori
-Doug Coleman
diff --git a/unmaintained/cairo/cairo.factor b/unmaintained/cairo/cairo.factor
deleted file mode 100755 (executable)
index 46d3e42..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: cairo.ffi kernel accessors sequences
-namespaces fry continuations destructors ;
-IN: cairo
-
-TUPLE: cairo-t alien ;
-C: <cairo-t> cairo-t
-M: cairo-t dispose ( alien -- ) alien>> cairo_destroy ;
-
-TUPLE: cairo-surface-t alien ;
-C: <cairo-surface-t> cairo-surface-t
-M: cairo-surface-t dispose ( alien -- ) alien>> cairo_surface_destroy ;
-
-: check-cairo ( cairo_status_t -- )
-    dup CAIRO_STATUS_SUCCESS = [ drop ]
-    [ cairo_status_to_string "Cairo error: " prepend throw ] if ;
-
-SYMBOL: cairo
-: cr ( -- cairo ) cairo get ;
-
-: (with-cairo) ( cairo-t quot -- )
-    >r alien>> cairo r> [ cr cairo_status check-cairo ]
-    compose with-variable ; inline
-    
-: with-cairo ( cairo quot -- )
-    >r <cairo-t> r> [ (with-cairo) ] curry with-disposal ; inline
-
-: (with-surface) ( cairo-surface-t quot -- )
-    >r alien>> r> [ cairo_surface_status check-cairo ] bi ; inline
-
-: with-surface ( cairo_surface quot -- )
-    >r <cairo-surface-t> r> [ (with-surface) ] curry with-disposal ; inline
-
-: with-cairo-from-surface ( cairo_surface quot -- )
-    '[ cairo_create , with-cairo ] with-surface ; inline
diff --git a/unmaintained/cairo/ffi/ffi.factor b/unmaintained/cairo/ffi/ffi.factor
deleted file mode 100644 (file)
index 451806c..0000000
+++ /dev/null
@@ -1,950 +0,0 @@
-! Copyright (c) 2007 Sampo Vuori
-! Copyright (c) 2008 Matthew Willis
-!
-! Adapted from cairo.h, version 1.5.14
-! License: http://factorcode.org/license.txt
-
-USING: system combinators alien alien.syntax kernel 
-alien.c-types accessors sequences arrays ui.gadgets ;
-
-IN: cairo.ffi
-<< "cairo" {
-    { [ os winnt? ] [ "libcairo-2.dll" ] }
-    { [ os macosx? ] [ "libcairo.dylib" ] }
-    { [ os unix? ] [ "libcairo.so.2" ] }
-} cond "cdecl" add-library >>
-
-LIBRARY: cairo
-
-FUNCTION: int cairo_version ( ) ;
-FUNCTION: char* cairo_version_string ( ) ;
-
-TYPEDEF: int cairo_bool_t
-
-! I am leaving these and other void* types as opaque structures
-TYPEDEF: void* cairo_t
-TYPEDEF: void* cairo_surface_t
-
-C-STRUCT: cairo_matrix_t
-    { "double" "xx" }
-    { "double" "yx" }
-    { "double" "xy" }
-    { "double" "yy" }
-    { "double" "x0" }
-    { "double" "y0" } ;
-
-TYPEDEF: void* cairo_pattern_t
-
-TYPEDEF: void* cairo_destroy_func_t
-: cairo-destroy-func ( quot -- callback )
-    >r "void" { "void*" } "cdecl" r> alien-callback ; inline
-
-! See cairo.h for details
-C-STRUCT: cairo_user_data_key_t
-    { "int" "unused" } ;
-
-TYPEDEF: int cairo_status_t
-C-ENUM:
-    CAIRO_STATUS_SUCCESS
-    CAIRO_STATUS_NO_MEMORY
-    CAIRO_STATUS_INVALID_RESTORE
-    CAIRO_STATUS_INVALID_POP_GROUP
-    CAIRO_STATUS_NO_CURRENT_POINT
-    CAIRO_STATUS_INVALID_MATRIX
-    CAIRO_STATUS_INVALID_STATUS
-    CAIRO_STATUS_NULL_POINTER
-    CAIRO_STATUS_INVALID_STRING
-    CAIRO_STATUS_INVALID_PATH_DATA
-    CAIRO_STATUS_READ_ERROR
-    CAIRO_STATUS_WRITE_ERROR
-    CAIRO_STATUS_SURFACE_FINISHED
-    CAIRO_STATUS_SURFACE_TYPE_MISMATCH
-    CAIRO_STATUS_PATTERN_TYPE_MISMATCH
-    CAIRO_STATUS_INVALID_CONTENT
-    CAIRO_STATUS_INVALID_FORMAT
-    CAIRO_STATUS_INVALID_VISUAL
-    CAIRO_STATUS_FILE_NOT_FOUND
-    CAIRO_STATUS_INVALID_DASH
-    CAIRO_STATUS_INVALID_DSC_COMMENT
-    CAIRO_STATUS_INVALID_INDEX
-    CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
-    CAIRO_STATUS_TEMP_FILE_ERROR
-    CAIRO_STATUS_INVALID_STRIDE ;
-
-TYPEDEF: int cairo_content_t
-: CAIRO_CONTENT_COLOR          HEX: 1000 ;
-: CAIRO_CONTENT_ALPHA          HEX: 2000 ;
-: CAIRO_CONTENT_COLOR_ALPHA    HEX: 3000 ;
-
-TYPEDEF: void* cairo_write_func_t
-: cairo-write-func ( quot -- callback )
-    >r "cairo_status_t" { "void*" "uchar*" "int" }
-    "cdecl" r> alien-callback ; inline
-                          
-TYPEDEF: void* cairo_read_func_t
-: cairo-read-func ( quot -- callback )
-    >r "cairo_status_t" { "void*" "uchar*" "int" }
-    "cdecl" r> alien-callback ; inline
-
-! Functions for manipulating state objects
-FUNCTION: cairo_t*
-cairo_create ( cairo_surface_t* target ) ;
-
-FUNCTION: cairo_t*
-cairo_reference ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_destroy ( cairo_t* cr ) ;
-
-FUNCTION: uint
-cairo_get_reference_count ( cairo_t* cr ) ;
-
-FUNCTION: void*
-cairo_get_user_data ( cairo_t* cr, cairo_user_data_key_t* key ) ;
-
-FUNCTION: cairo_status_t
-cairo_set_user_data ( cairo_t* cr, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-
-FUNCTION: void
-cairo_save ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_restore ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_push_group ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_push_group_with_content  ( cairo_t* cr, cairo_content_t content ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pop_group ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_pop_group_to_source ( cairo_t* cr ) ;
-
-! Modify state
-TYPEDEF: int cairo_operator_t
-C-ENUM:
-    CAIRO_OPERATOR_CLEAR
-
-    CAIRO_OPERATOR_SOURCE
-    CAIRO_OPERATOR_OVER
-    CAIRO_OPERATOR_IN
-    CAIRO_OPERATOR_OUT
-    CAIRO_OPERATOR_ATOP
-
-    CAIRO_OPERATOR_DEST
-    CAIRO_OPERATOR_DEST_OVER
-    CAIRO_OPERATOR_DEST_IN
-    CAIRO_OPERATOR_DEST_OUT
-    CAIRO_OPERATOR_DEST_ATOP
-
-    CAIRO_OPERATOR_XOR
-    CAIRO_OPERATOR_ADD
-    CAIRO_OPERATOR_SATURATE ;
-
-FUNCTION: void
-cairo_set_operator ( cairo_t* cr, cairo_operator_t op ) ;
-
-FUNCTION: void
-cairo_set_source ( cairo_t* cr, cairo_pattern_t* source ) ;
-
-FUNCTION: void
-cairo_set_source_rgb ( cairo_t* cr, double red, double green, double blue ) ;
-
-FUNCTION: void
-cairo_set_source_rgba ( cairo_t* cr, double red, double green, double blue, double alpha ) ;
-
-FUNCTION: void
-cairo_set_source_surface ( cairo_t* cr, cairo_surface_t* surface, double x, double y ) ;
-
-FUNCTION: void
-cairo_set_tolerance ( cairo_t* cr, double tolerance ) ;
-
-TYPEDEF: int cairo_antialias_t
-C-ENUM:
-    CAIRO_ANTIALIAS_DEFAULT
-    CAIRO_ANTIALIAS_NONE
-    CAIRO_ANTIALIAS_GRAY
-    CAIRO_ANTIALIAS_SUBPIXEL ;
-
-FUNCTION: void
-cairo_set_antialias ( cairo_t* cr, cairo_antialias_t antialias ) ;
-
-TYPEDEF: int cairo_fill_rule_t
-C-ENUM:
-    CAIRO_FILL_RULE_WINDING
-    CAIRO_FILL_RULE_EVEN_ODD ;
-
-FUNCTION: void
-cairo_set_fill_rule ( cairo_t* cr, cairo_fill_rule_t fill_rule ) ;
-
-FUNCTION: void
-cairo_set_line_width ( cairo_t* cr, double width ) ;
-
-TYPEDEF: int cairo_line_cap_t
-C-ENUM:
-    CAIRO_LINE_CAP_BUTT
-    CAIRO_LINE_CAP_ROUND
-    CAIRO_LINE_CAP_SQUARE ;
-
-FUNCTION: void
-cairo_set_line_cap ( cairo_t* cr, cairo_line_cap_t line_cap ) ;
-
-TYPEDEF: int cairo_line_join_t
-C-ENUM:
-    CAIRO_LINE_JOIN_MITER
-    CAIRO_LINE_JOIN_ROUND
-    CAIRO_LINE_JOIN_BEVEL ;
-
-FUNCTION: void
-cairo_set_line_join ( cairo_t* cr, cairo_line_join_t line_join ) ;
-
-FUNCTION: void
-cairo_set_dash ( cairo_t* cr, double* dashes, int num_dashes, double offset ) ;
-
-FUNCTION: void
-cairo_set_miter_limit ( cairo_t* cr, double limit ) ;
-
-FUNCTION: void
-cairo_translate ( cairo_t* cr, double tx, double ty ) ;
-
-FUNCTION: void
-cairo_scale ( cairo_t* cr, double sx, double sy ) ;
-
-FUNCTION: void
-cairo_rotate ( cairo_t* cr, double angle ) ;
-
-FUNCTION: void
-cairo_transform ( cairo_t* cr, cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_set_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_identity_matrix ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_user_to_device ( cairo_t* cr, double* x, double* y ) ;
-
-FUNCTION: void
-cairo_user_to_device_distance ( cairo_t* cr, double* dx, double* dy ) ;
-
-FUNCTION: void
-cairo_device_to_user ( cairo_t* cr, double* x, double* y ) ;
-
-FUNCTION: void
-cairo_device_to_user_distance ( cairo_t* cr, double* dx, double* dy ) ;
-
-! Path creation functions
-FUNCTION: void
-cairo_new_path ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_move_to ( cairo_t* cr, double x, double y ) ;
-
-FUNCTION: void
-cairo_new_sub_path ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_line_to ( cairo_t* cr, double x, double y ) ;
-
-FUNCTION: void
-cairo_curve_to ( cairo_t* cr, double x1, double y1, double x2, double y2, double x3, double y3 ) ;
-
-FUNCTION: void
-cairo_arc ( cairo_t* cr, double xc, double yc, double radius, double angle1, double angle2 ) ;
-
-FUNCTION: void
-cairo_arc_negative ( cairo_t* cr, double xc, double yc, double radius, double angle1, double angle2 ) ;
-
-FUNCTION: void
-cairo_rel_move_to ( cairo_t* cr, double dx, double dy ) ;
-
-FUNCTION: void
-cairo_rel_line_to ( cairo_t* cr, double dx, double dy ) ;
-
-FUNCTION: void
-cairo_rel_curve_to ( cairo_t* cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3 ) ;
-
-FUNCTION: void
-cairo_rectangle ( cairo_t* cr, double x, double y, double width, double height ) ;
-
-FUNCTION: void
-cairo_close_path ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_path_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
-
-! Painting functions
-FUNCTION: void
-cairo_paint ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_paint_with_alpha ( cairo_t* cr, double alpha ) ;
-
-FUNCTION: void
-cairo_mask ( cairo_t* cr, cairo_pattern_t* pattern ) ;
-
-FUNCTION: void
-cairo_mask_surface ( cairo_t* cr, cairo_surface_t* surface, double surface_x, double surface_y ) ;
-
-FUNCTION: void
-cairo_stroke ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_stroke_preserve ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_fill ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_fill_preserve ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_copy_page ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_show_page ( cairo_t* cr ) ;
-
-! Insideness testing
-FUNCTION: cairo_bool_t
-cairo_in_stroke ( cairo_t* cr, double x, double y ) ;
-
-FUNCTION: cairo_bool_t
-cairo_in_fill ( cairo_t* cr, double x, double y ) ;
-
-! Rectangular extents
-FUNCTION: void
-cairo_stroke_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
-
-FUNCTION: void
-cairo_fill_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
-
-! Clipping
-FUNCTION: void
-cairo_reset_clip ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_clip ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_clip_preserve ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_clip_extents ( cairo_t* cr, double* x1, double* y1, double* x2, double* y2 ) ;
-
-C-STRUCT: cairo_rectangle_t
-    { "double" "x" }
-    { "double" "y" }
-    { "double" "width" }
-    { "double" "height" } ;
-    
-C-STRUCT: cairo_rectangle_list_t
-    { "cairo_status_t"     "status" }
-    { "cairo_rectangle_t*" "rectangles" }
-    { "int"                "num_rectangles" } ;
-
-FUNCTION: cairo_rectangle_list_t*
-cairo_copy_clip_rectangle_list ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_rectangle_list_destroy ( cairo_rectangle_list_t* rectangle_list ) ;
-
-! Font/Text functions
-
-TYPEDEF: void* cairo_scaled_font_t
-
-TYPEDEF: void* cairo_font_face_t
-
-C-STRUCT: cairo_glyph_t
-  { "ulong"     "index" }
-  { "double"    "x" }
-  { "double"    "y" } ;
-
-C-STRUCT: cairo_text_extents_t
-    { "double" "x_bearing" }
-    { "double" "y_bearing" }
-    { "double" "width" }
-    { "double" "height" }
-    { "double" "x_advance" }
-    { "double" "y_advance" } ;
-
-C-STRUCT: cairo_font_extents_t
-    { "double" "ascent" }
-    { "double" "descent" }
-    { "double" "height" }
-    { "double" "max_x_advance" }
-    { "double" "max_y_advance" } ;
-
-TYPEDEF: int cairo_font_slant_t
-C-ENUM:
-    CAIRO_FONT_SLANT_NORMAL
-    CAIRO_FONT_SLANT_ITALIC
-    CAIRO_FONT_SLANT_OBLIQUE ;
-
-TYPEDEF: int cairo_font_weight_t
-C-ENUM:
-    CAIRO_FONT_WEIGHT_NORMAL
-    CAIRO_FONT_WEIGHT_BOLD ;
-
-TYPEDEF: int cairo_subpixel_order_t
-C-ENUM:
-    CAIRO_SUBPIXEL_ORDER_DEFAULT
-    CAIRO_SUBPIXEL_ORDER_RGB
-    CAIRO_SUBPIXEL_ORDER_BGR
-    CAIRO_SUBPIXEL_ORDER_VRGB
-    CAIRO_SUBPIXEL_ORDER_VBGR ;
-
-TYPEDEF: int cairo_hint_style_t
-C-ENUM:
-    CAIRO_HINT_STYLE_DEFAULT
-    CAIRO_HINT_STYLE_NONE
-    CAIRO_HINT_STYLE_SLIGHT
-    CAIRO_HINT_STYLE_MEDIUM
-    CAIRO_HINT_STYLE_FULL ;
-
-TYPEDEF: int cairo_hint_metrics_t
-C-ENUM:
-    CAIRO_HINT_METRICS_DEFAULT
-    CAIRO_HINT_METRICS_OFF
-    CAIRO_HINT_METRICS_ON ;
-
-TYPEDEF: void* cairo_font_options_t
-
-FUNCTION: cairo_font_options_t*
-cairo_font_options_create ( ) ;
-
-FUNCTION: cairo_font_options_t*
-cairo_font_options_copy ( cairo_font_options_t* original ) ;
-
-FUNCTION: void
-cairo_font_options_destroy ( cairo_font_options_t* options ) ;
-
-FUNCTION: cairo_status_t
-cairo_font_options_status ( cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_font_options_merge ( cairo_font_options_t* options, cairo_font_options_t* other ) ;
-
-FUNCTION: cairo_bool_t
-cairo_font_options_equal ( cairo_font_options_t* options, cairo_font_options_t* other ) ;
-
-FUNCTION: ulong
-cairo_font_options_hash ( cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_font_options_set_antialias ( cairo_font_options_t* options, cairo_antialias_t antialias ) ;
-
-FUNCTION: cairo_antialias_t
-cairo_font_options_get_antialias ( cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_font_options_set_subpixel_order ( cairo_font_options_t* options, cairo_subpixel_order_t subpixel_order ) ;
-
-FUNCTION: cairo_subpixel_order_t
-cairo_font_options_get_subpixel_order ( cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_font_options_set_hint_style ( cairo_font_options_t* options, cairo_hint_style_t hint_style ) ;
-
-FUNCTION: cairo_hint_style_t
-cairo_font_options_get_hint_style ( cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_font_options_set_hint_metrics ( cairo_font_options_t* options, cairo_hint_metrics_t hint_metrics ) ;
-
-FUNCTION: cairo_hint_metrics_t
-cairo_font_options_get_hint_metrics ( cairo_font_options_t* options ) ;
-
-! This interface is for dealing with text as text, not caring about the
-!  font object inside the the cairo_t.
-
-FUNCTION: void
-cairo_select_font_face ( cairo_t* cr, char* family, cairo_font_slant_t slant, cairo_font_weight_t weight ) ;
-
-FUNCTION: void
-cairo_set_font_size ( cairo_t* cr, double size ) ;
-
-FUNCTION: void
-cairo_set_font_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_get_font_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_set_font_options ( cairo_t* cr, cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_get_font_options ( cairo_t* cr, cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_set_font_face ( cairo_t* cr, cairo_font_face_t* font_face ) ;
-
-FUNCTION: cairo_font_face_t*
-cairo_get_font_face ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_set_scaled_font ( cairo_t* cr, cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: cairo_scaled_font_t*
-cairo_get_scaled_font ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_show_text ( cairo_t* cr, char* utf8 ) ;
-
-FUNCTION: void
-cairo_show_glyphs ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
-
-FUNCTION: void
-cairo_text_path  ( cairo_t* cr, char* utf8 ) ;
-
-FUNCTION: void
-cairo_glyph_path ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
-
-FUNCTION: void
-cairo_text_extents ( cairo_t* cr, char* utf8, cairo_text_extents_t* extents ) ;
-
-FUNCTION: void
-cairo_glyph_extents ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
-
-FUNCTION: void
-cairo_font_extents ( cairo_t* cr, cairo_font_extents_t* extents ) ;
-
-! Generic identifier for a font style
-
-FUNCTION: cairo_font_face_t*
-cairo_font_face_reference ( cairo_font_face_t* font_face ) ;
-
-FUNCTION: void
-cairo_font_face_destroy ( cairo_font_face_t* font_face ) ;
-
-FUNCTION: uint
-cairo_font_face_get_reference_count ( cairo_font_face_t* font_face ) ;
-
-FUNCTION: cairo_status_t
-cairo_font_face_status ( cairo_font_face_t* font_face ) ;
-
-TYPEDEF: int cairo_font_type_t
-C-ENUM:
-    CAIRO_FONT_TYPE_TOY
-    CAIRO_FONT_TYPE_FT
-    CAIRO_FONT_TYPE_WIN32
-    CAIRO_FONT_TYPE_QUARTZ ;
-
-FUNCTION: cairo_font_type_t
-cairo_font_face_get_type ( cairo_font_face_t* font_face ) ;
-
-FUNCTION: void* 
-cairo_font_face_get_user_data ( cairo_font_face_t* font_face, cairo_user_data_key_t* key ) ;
-
-FUNCTION: cairo_status_t
-cairo_font_face_set_user_data ( cairo_font_face_t* font_face, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-
-! Portable interface to general font features.
-
-FUNCTION: cairo_scaled_font_t*
-cairo_scaled_font_create ( cairo_font_face_t* font_face, cairo_matrix_t* font_matrix, cairo_matrix_t* ctm, cairo_font_options_t* options ) ;
-
-FUNCTION: cairo_scaled_font_t*
-cairo_scaled_font_reference ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: void
-cairo_scaled_font_destroy ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: uint
-cairo_scaled_font_get_reference_count ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: cairo_status_t
-cairo_scaled_font_status ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: cairo_font_type_t
-cairo_scaled_font_get_type ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: void* 
-cairo_scaled_font_get_user_data ( cairo_scaled_font_t* scaled_font, cairo_user_data_key_t* key ) ;
-
-FUNCTION: cairo_status_t
-cairo_scaled_font_set_user_data ( cairo_scaled_font_t* scaled_font, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-
-FUNCTION: void
-cairo_scaled_font_extents ( cairo_scaled_font_t* scaled_font, cairo_font_extents_t* extents ) ;
-
-FUNCTION: void
-cairo_scaled_font_text_extents ( cairo_scaled_font_t* scaled_font, char* utf8, cairo_text_extents_t* extents ) ;
-
-FUNCTION: void
-cairo_scaled_font_glyph_extents ( cairo_scaled_font_t* scaled_font, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
-
-FUNCTION: cairo_font_face_t*
-cairo_scaled_font_get_font_face ( cairo_scaled_font_t* scaled_font ) ;
-
-FUNCTION: void
-cairo_scaled_font_get_font_matrix ( cairo_scaled_font_t* scaled_font, cairo_matrix_t* font_matrix ) ;
-
-FUNCTION: void
-cairo_scaled_font_get_ctm ( cairo_scaled_font_t* scaled_font, cairo_matrix_t* ctm ) ;
-
-FUNCTION: void
-cairo_scaled_font_get_font_options ( cairo_scaled_font_t* scaled_font, cairo_font_options_t* options ) ;
-
-! Query functions
-
-FUNCTION: cairo_operator_t
-cairo_get_operator ( cairo_t* cr ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_get_source ( cairo_t* cr ) ;
-
-FUNCTION: double
-cairo_get_tolerance ( cairo_t* cr ) ;
-
-FUNCTION: cairo_antialias_t
-cairo_get_antialias ( cairo_t* cr ) ;
-
-FUNCTION: cairo_bool_t
-cairo_has_current_point ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_get_current_point ( cairo_t* cr, double* x, double* y ) ;
-
-FUNCTION: cairo_fill_rule_t
-cairo_get_fill_rule ( cairo_t* cr ) ;
-
-FUNCTION: double
-cairo_get_line_width ( cairo_t* cr ) ;
-
-FUNCTION: cairo_line_cap_t
-cairo_get_line_cap ( cairo_t* cr ) ;
-
-FUNCTION: cairo_line_join_t
-cairo_get_line_join ( cairo_t* cr ) ;
-
-FUNCTION: double
-cairo_get_miter_limit ( cairo_t* cr ) ;
-
-FUNCTION: int
-cairo_get_dash_count ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_get_dash ( cairo_t* cr, double* dashes, double* offset ) ;
-
-FUNCTION: void
-cairo_get_matrix ( cairo_t* cr, cairo_matrix_t* matrix ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_get_target ( cairo_t* cr ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_get_group_target ( cairo_t* cr ) ;
-
-TYPEDEF: int cairo_path_data_type_t
-C-ENUM:
-    CAIRO_PATH_MOVE_TO
-    CAIRO_PATH_LINE_TO
-    CAIRO_PATH_CURVE_TO
-    CAIRO_PATH_CLOSE_PATH ;
-
-! NEED TO DO UNION HERE
-C-STRUCT: cairo_path_data_t-point
-    { "double" "x" }
-    { "double" "y" } ;
-
-C-STRUCT: cairo_path_data_t-header
-    { "cairo_path_data_type_t" "type" }
-    { "int" "length" } ;
-
-C-UNION: cairo_path_data_t "cairo_path_data_t-point" "cairo_path_data_t-header" ;
-
-C-STRUCT: cairo_path_t
-    { "cairo_status_t"      "status" }
-    { "cairo_path_data_t*"  "data" }
-    { "int"                 "num_data" } ;
-
-FUNCTION: cairo_path_t*
-cairo_copy_path ( cairo_t* cr ) ;
-
-FUNCTION: cairo_path_t*
-cairo_copy_path_flat ( cairo_t* cr ) ;
-
-FUNCTION: void
-cairo_append_path ( cairo_t* cr, cairo_path_t* path ) ;
-
-FUNCTION: void
-cairo_path_destroy ( cairo_path_t* path ) ;
-
-! Error status queries
-
-FUNCTION: cairo_status_t
-cairo_status ( cairo_t* cr ) ;
-
-FUNCTION: char* 
-cairo_status_to_string ( cairo_status_t status ) ;
-
-! Surface manipulation
-
-FUNCTION: cairo_surface_t*
-cairo_surface_create_similar ( cairo_surface_t* other, cairo_content_t content, int width, int height ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_surface_reference ( cairo_surface_t* surface ) ;
-
-FUNCTION: void
-cairo_surface_finish ( cairo_surface_t* surface ) ;
-
-FUNCTION: void
-cairo_surface_destroy ( cairo_surface_t* surface ) ;
-
-FUNCTION: uint
-cairo_surface_get_reference_count ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_status_t
-cairo_surface_status ( cairo_surface_t* surface ) ;
-
-TYPEDEF: int cairo_surface_type_t
-C-ENUM:
-    CAIRO_SURFACE_TYPE_IMAGE
-    CAIRO_SURFACE_TYPE_PDF
-    CAIRO_SURFACE_TYPE_PS
-    CAIRO_SURFACE_TYPE_XLIB
-    CAIRO_SURFACE_TYPE_XCB
-    CAIRO_SURFACE_TYPE_GLITZ
-    CAIRO_SURFACE_TYPE_QUARTZ
-    CAIRO_SURFACE_TYPE_WIN32
-    CAIRO_SURFACE_TYPE_BEOS
-    CAIRO_SURFACE_TYPE_DIRECTFB
-    CAIRO_SURFACE_TYPE_SVG
-    CAIRO_SURFACE_TYPE_OS2
-    CAIRO_SURFACE_TYPE_WIN32_PRINTING
-    CAIRO_SURFACE_TYPE_QUARTZ_IMAGE ;
-
-FUNCTION: cairo_surface_type_t
-cairo_surface_get_type ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_content_t
-cairo_surface_get_content ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_status_t
-cairo_surface_write_to_png ( cairo_surface_t* surface, char* filename ) ;
-
-FUNCTION: cairo_status_t
-cairo_surface_write_to_png_stream ( cairo_surface_t* surface, cairo_write_func_t write_func, void* closure ) ;
-
-FUNCTION: void* 
-cairo_surface_get_user_data ( cairo_surface_t* surface, cairo_user_data_key_t* key ) ;
-
-FUNCTION: cairo_status_t
-cairo_surface_set_user_data ( cairo_surface_t* surface, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-
-FUNCTION: void
-cairo_surface_get_font_options ( cairo_surface_t* surface, cairo_font_options_t* options ) ;
-
-FUNCTION: void
-cairo_surface_flush ( cairo_surface_t* surface ) ;
-
-FUNCTION: void
-cairo_surface_mark_dirty ( cairo_surface_t* surface ) ;
-
-FUNCTION: void
-cairo_surface_mark_dirty_rectangle ( cairo_surface_t* surface, int x, int y, int width, int height ) ;
-
-FUNCTION: void
-cairo_surface_set_device_offset ( cairo_surface_t* surface, double x_offset, double y_offset ) ;
-
-FUNCTION: void
-cairo_surface_get_device_offset ( cairo_surface_t* surface, double* x_offset, double* y_offset ) ;
-
-FUNCTION: void
-cairo_surface_set_fallback_resolution ( cairo_surface_t* surface, double x_pixels_per_inch, double y_pixels_per_inch ) ;
-
-FUNCTION: void
-cairo_surface_copy_page ( cairo_surface_t* surface ) ;
-
-FUNCTION: void
-cairo_surface_show_page ( cairo_surface_t* surface ) ;
-
-! Image-surface functions
-
-TYPEDEF: int cairo_format_t
-C-ENUM:
-    CAIRO_FORMAT_ARGB32
-    CAIRO_FORMAT_RGB24
-    CAIRO_FORMAT_A8
-    CAIRO_FORMAT_A1
-    CAIRO_FORMAT_RGB16_565 ;
-
-FUNCTION: cairo_surface_t*
-cairo_image_surface_create ( cairo_format_t format, int width, int height ) ;
-
-FUNCTION: int
-cairo_format_stride_for_width ( cairo_format_t format, int width ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_image_surface_create_for_data ( uchar* data, cairo_format_t format, int width, int height, int stride ) ;
-
-FUNCTION: uchar*
-cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_format_t
-cairo_image_surface_get_format ( cairo_surface_t* surface ) ;
-
-FUNCTION: int
-cairo_image_surface_get_width ( cairo_surface_t* surface ) ;
-
-FUNCTION: int
-cairo_image_surface_get_height ( cairo_surface_t* surface ) ;
-
-FUNCTION: int
-cairo_image_surface_get_stride ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_image_surface_create_from_png ( char* filename ) ;
-
-FUNCTION: cairo_surface_t*
-cairo_image_surface_create_from_png_stream ( cairo_read_func_t read_func, void* closure ) ;
-
-! Pattern creation functions
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_create_rgb ( double red, double green, double blue ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_create_rgba ( double red, double green, double blue, double alpha ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_create_for_surface ( cairo_surface_t* surface ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_create_linear ( double x0, double y0, double x1, double y1 ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_create_radial ( double cx0, double cy0, double radius0, double cx1, double cy1, double radius1 ) ;
-
-FUNCTION: cairo_pattern_t*
-cairo_pattern_reference ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: void
-cairo_pattern_destroy ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: uint
-cairo_pattern_get_reference_count ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_status ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: void*
-cairo_pattern_get_user_data ( cairo_pattern_t* pattern, cairo_user_data_key_t* key ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_set_user_data ( cairo_pattern_t* pattern, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-
-TYPEDEF: int cairo_pattern_type_t
-C-ENUM:
-    CAIRO_PATTERN_TYPE_SOLID
-    CAIRO_PATTERN_TYPE_SURFACE
-    CAIRO_PATTERN_TYPE_LINEAR
-    CAIRO_PATTERN_TYPE_RADIA ;
-
-FUNCTION: cairo_pattern_type_t
-cairo_pattern_get_type ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: void
-cairo_pattern_add_color_stop_rgb ( cairo_pattern_t* pattern, double offset, double red, double green, double blue ) ;
-
-FUNCTION: void
-cairo_pattern_add_color_stop_rgba ( cairo_pattern_t* pattern, double offset, double red, double green, double blue, double alpha ) ;
-
-FUNCTION: void
-cairo_pattern_set_matrix ( cairo_pattern_t* pattern, cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_pattern_get_matrix ( cairo_pattern_t* pattern, cairo_matrix_t* matrix ) ;
-
-TYPEDEF: int cairo_extend_t
-C-ENUM:
-    CAIRO_EXTEND_NONE
-    CAIRO_EXTEND_REPEAT
-    CAIRO_EXTEND_REFLECT
-    CAIRO_EXTEND_PAD ;
-
-FUNCTION: void
-cairo_pattern_set_extend ( cairo_pattern_t* pattern, cairo_extend_t extend ) ;
-
-FUNCTION: cairo_extend_t
-cairo_pattern_get_extend ( cairo_pattern_t* pattern ) ;
-
-TYPEDEF: int cairo_filter_t
-C-ENUM:
-    CAIRO_FILTER_FAST
-    CAIRO_FILTER_GOOD
-    CAIRO_FILTER_BEST
-    CAIRO_FILTER_NEAREST
-    CAIRO_FILTER_BILINEAR
-    CAIRO_FILTER_GAUSSIAN ;
-
-FUNCTION: void
-cairo_pattern_set_filter ( cairo_pattern_t* pattern, cairo_filter_t filter ) ;
-
-FUNCTION: cairo_filter_t
-cairo_pattern_get_filter ( cairo_pattern_t* pattern ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_rgba ( cairo_pattern_t* pattern, double* red, double* green, double* blue, double* alpha ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_surface ( cairo_pattern_t* pattern, cairo_surface_t* *surface ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_color_stop_rgba ( cairo_pattern_t* pattern, int index, double* offset, double* red, double* green, double* blue, double* alpha ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_color_stop_count ( cairo_pattern_t* pattern, int* count ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_linear_points ( cairo_pattern_t* pattern, double* x0, double* y0, double* x1, double* y1 ) ;
-
-FUNCTION: cairo_status_t
-cairo_pattern_get_radial_circles ( cairo_pattern_t* pattern, double* x0, double* y0, double* r0, double* x1, double* y1, double* r1 ) ;
-
-! Matrix functions
-
-FUNCTION: void
-cairo_matrix_init ( cairo_matrix_t* matrix, double  xx, double  yx, double  xy, double  yy, double  x0, double  y0 ) ;
-
-FUNCTION: void
-cairo_matrix_init_identity ( cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_matrix_init_translate ( cairo_matrix_t* matrix, double tx, double ty ) ;
-
-FUNCTION: void
-cairo_matrix_init_scale ( cairo_matrix_t* matrix, double sx, double sy ) ;
-
-FUNCTION: void
-cairo_matrix_init_rotate ( cairo_matrix_t* matrix, double radians ) ;
-
-FUNCTION: void
-cairo_matrix_translate ( cairo_matrix_t* matrix, double tx, double ty ) ;
-
-FUNCTION: void
-cairo_matrix_scale ( cairo_matrix_t* matrix, double sx, double sy ) ;
-
-FUNCTION: void
-cairo_matrix_rotate ( cairo_matrix_t* matrix, double radians ) ;
-
-FUNCTION: cairo_status_t
-cairo_matrix_invert ( cairo_matrix_t* matrix ) ;
-
-FUNCTION: void
-cairo_matrix_multiply ( cairo_matrix_t* result, cairo_matrix_t* a, cairo_matrix_t* b ) ;
-
-FUNCTION: void
-cairo_matrix_transform_distance ( cairo_matrix_t* matrix, double* dx, double* dy ) ;
-
-FUNCTION: void
-cairo_matrix_transform_point ( cairo_matrix_t* matrix, double* x, double* y ) ;
-
-! Functions to be used while debugging (not intended for use in production code)
-FUNCTION: void
-cairo_debug_reset_static_data ( ) ;
diff --git a/unmaintained/cairo/gadgets/gadgets.factor b/unmaintained/cairo/gadgets/gadgets.factor
deleted file mode 100644 (file)
index c9fef61..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-! Copyright (C) 2008 Matthew Willis.
-! See http://factorcode.org/license.txt for BSD license.
-USING: sequences math opengl.gadgets kernel
-byte-arrays cairo.ffi cairo io.backend
-ui.gadgets accessors opengl.gl
-arrays ;
-
-IN: cairo.gadgets
-
-: width>stride ( width -- stride ) 4 * ;
-    
-: copy-cairo ( dim quot -- byte-array )
-    >r first2 over width>stride
-    [ * nip <byte-array> dup CAIRO_FORMAT_ARGB32 ]
-    [ cairo_image_surface_create_for_data ] 3bi
-    r> with-cairo-from-surface ; inline
-
-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 -- )
-!    >r [ cairo>bytes CAIRO_FORMAT_ARGB32 ] [ width>> ]
-!    [ height>> ] tri over width>stride
-!    cairo_image_surface_create_for_data
-!    r> [ cairo_surface_write_to_png check-cairo ] curry with-surface ;
-
-: copy-surface ( surface -- )
-    cr swap 0 0 cairo_set_source_surface
-    cr cairo_paint ;
-
-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 render-bytes* ;
-
-M: png-gadget cache-key* path>> ;
diff --git a/unmaintained/cairo/samples/samples.factor b/unmaintained/cairo/samples/samples.factor
deleted file mode 100644 (file)
index 0e83381..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-! Copyright (C) 2008 Matthew Willis
-! See http://factorcode.org/license.txt for BSD license.
-!
-! these samples are a subset of the samples on
-! http://cairographics.org/samples/
-USING: cairo cairo.ffi locals math.constants math
-io.backend kernel alien.c-types libc namespaces ;
-
-IN: cairo.samples
-
-:: arc ( -- )
-    [let | xc [ 128.0 ]
-           yc [ 128.0 ]
-           radius [ 100.0 ]
-           angle1 [ pi 1/4 * ]
-           angle2 [ pi ] |
-        cr 10.0 cairo_set_line_width
-        cr xc yc radius angle1 angle2 cairo_arc
-        cr cairo_stroke
-        
-        ! draw helping lines
-        cr 1 0.2 0.2 0.6 cairo_set_source_rgba
-        cr 6.0 cairo_set_line_width
-        
-        cr xc yc 10.0 0 2 pi * cairo_arc
-        cr cairo_fill
-        
-        cr xc yc radius angle1 angle1 cairo_arc
-        cr xc yc cairo_line_to
-        cr xc yc radius angle2 angle2 cairo_arc
-        cr xc yc cairo_line_to
-        cr cairo_stroke
-    ] ;
-
-: clip ( -- )
-    cr 128 128 76.8 0 2 pi * cairo_arc
-    cr cairo_clip
-    cr cairo_new_path
-    
-    cr 0 0 256 256 cairo_rectangle
-    cr cairo_fill
-    cr 0 1 0 cairo_set_source_rgb
-    cr 0 0 cairo_move_to
-    cr 256 256 cairo_line_to
-    cr 256 0 cairo_move_to
-    cr 0 256 cairo_line_to
-    cr 10 cairo_set_line_width
-    cr cairo_stroke ;
-
-:: clip-image ( -- )
-    [let* | png [ "resource:misc/icons/Factor_128x128.png"
-                  normalize-path cairo_image_surface_create_from_png ]
-            w [ png cairo_image_surface_get_width ]
-            h [ png cairo_image_surface_get_height ] |
-        cr 128 128 76.8 0 2 pi * cairo_arc
-        cr cairo_clip
-        cr cairo_new_path
-
-        cr 192.0 w / 192.0 h / cairo_scale
-        cr png 32 32 cairo_set_source_surface
-        cr cairo_paint
-        png cairo_surface_destroy
-    ] ;
-
-:: dash ( -- )
-    [let | dashes [ { 50 10 10 10 } >c-double-array ]
-           ndash [ 4 ] |
-        cr dashes ndash -50 cairo_set_dash
-        cr 10 cairo_set_line_width
-        cr 128.0 25.6 cairo_move_to
-        cr 230.4 230.4 cairo_line_to
-        cr -102.4 0 cairo_rel_line_to
-        cr 51.2 230.4 51.2 128.0 128.0 128.0 cairo_curve_to
-        cr cairo_stroke
-    ] ;
-
-:: gradient ( -- )
-    [let | pat [ 0 0 0 256 cairo_pattern_create_linear ]
-           radial [ 115.2 102.4 25.6 102.4 102.4 128.0
-                    cairo_pattern_create_radial ] |
-        pat 1 0 0 0 1 cairo_pattern_add_color_stop_rgba
-        pat 0 1 1 1 1 cairo_pattern_add_color_stop_rgba
-        cr 0 0 256 256 cairo_rectangle
-        cr pat cairo_set_source
-        cr cairo_fill
-        pat cairo_pattern_destroy
-        
-        radial 0 1 1 1 1 cairo_pattern_add_color_stop_rgba
-        radial 1 0 0 0 1 cairo_pattern_add_color_stop_rgba
-        cr radial cairo_set_source
-        cr 128.0 128.0 76.8 0 2 pi * cairo_arc
-        cr cairo_fill
-        radial cairo_pattern_destroy
-    ] ;
-
-: text ( -- )
-    cr "Serif" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_BOLD
-    cairo_select_font_face
-    cr 50 cairo_set_font_size
-    cr 10 135 cairo_move_to
-    cr "Hello" cairo_show_text
-    
-    cr 70 165 cairo_move_to
-    cr "factor" cairo_text_path
-    cr 0.5 0.5 1 cairo_set_source_rgb
-    cr cairo_fill_preserve
-    cr 0 0 0 cairo_set_source_rgb
-    cr 2.56 cairo_set_line_width
-    cr cairo_stroke
-    
-    ! draw helping lines
-    cr 1 0.2 0.2 0.6 cairo_set_source_rgba
-    cr 10 135 5.12 0 2 pi * cairo_arc
-    cr cairo_close_path
-    cr 70 165 5.12 0 2 pi * cairo_arc
-    cr cairo_fill ;
-
-: utf8 ( -- )
-    cr "Sans" CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_WEIGHT_NORMAL
-    cairo_select_font_face
-    cr 50 cairo_set_font_size
-    "cairo_text_extents_t" malloc-object
-    cr "日本語" pick cairo_text_extents
-    cr over
-    [ cairo_text_extents_t-width 2 / ]
-    [ cairo_text_extents_t-x_bearing ] bi +
-    128 swap - pick
-    [ cairo_text_extents_t-height 2 / ]
-    [ cairo_text_extents_t-y_bearing ] bi +
-    128 swap - cairo_move_to
-    free
-    cr "日本語" cairo_show_text
-    
-    cr 1 0.2 0.2 0.6 cairo_set_source_rgba
-    cr 6 cairo_set_line_width
-    cr 128 0 cairo_move_to
-    cr 0 256 cairo_rel_line_to
-    cr 0 128 cairo_move_to
-    cr 256 0 cairo_rel_line_to
-    cr cairo_stroke ;
- USING: quotations cairo.gadgets ui.gadgets.panes sequences ;
- : samples ( -- )
-    { arc clip clip-image dash gradient text utf8 }
-    [ { 256 256 } swap 1quotation <cairo-gadget> gadget. ] each ;
- MAIN: samples
diff --git a/unmaintained/cairo/summary.txt b/unmaintained/cairo/summary.txt
deleted file mode 100644 (file)
index f6cb370..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Cairo graphics library binding
diff --git a/unmaintained/cairo/tags.txt b/unmaintained/cairo/tags.txt
deleted file mode 100644 (file)
index bb863cf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bindings
diff --git a/unmaintained/size-of/size-of.factor b/unmaintained/size-of/size-of.factor
new file mode 100644 (file)
index 0000000..8157ba7
--- /dev/null
@@ -0,0 +1,39 @@
+
+USING: kernel namespaces sequences
+       io io.files io.launcher io.encodings.ascii
+       bake builder.util
+       accessors vars
+       math.parser ;
+
+IN: size-of
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: headers
+
+: include-headers ( -- seq )
+  headers> [ `{ "#include <" , ">" } to-string ] map ;
+
+: size-of-c-program ( type -- lines )
+  `{
+    "#include <stdio.h>"
+    include-headers
+    { "main() { printf( \"%i\" , sizeof( " , " ) ) ; }" }
+  }
+  to-strings ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: c-file ( -- path ) "size-of.c" temp-file ;
+
+: exe ( -- path ) "size-of" temp-file ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: size-of ( type -- n )
+  size-of-c-program c-file ascii set-file-lines
+
+  { "gcc" c-file "-o" exe } to-strings
+  [ "Error compiling generated C program" print ] run-or-bail
+
+  exe ascii <process-reader> contents string>number ;
\ No newline at end of file
index 5b4ff3b8321c341cb82b6e0d5d9ff0d0c8240912..8b7df45e9ada4bb060c01020064ce178bdb4a3c9 100755 (executable)
@@ -82,7 +82,7 @@ void box_alien(void *ptr)
 }
 
 /* make an alien pointing at an offset of another alien */
-DEFINE_PRIMITIVE(displaced_alien)
+void primitive_displaced_alien(void)
 {
        CELL alien = dpop();
        CELL displacement = to_cell(dpop());
@@ -107,7 +107,7 @@ DEFINE_PRIMITIVE(displaced_alien)
 
 /* address of an object representing a C pointer. Explicitly throw an error
 if the object is a byte array, as a sanity check. */
-DEFINE_PRIMITIVE(alien_address)
+void primitive_alien_address(void)
 {
        box_unsigned_cell((CELL)pinned_alien_offset(dpop()));
 }
@@ -121,11 +121,11 @@ INLINE void *alien_pointer(void)
 
 /* define words to read/write values at an alien address */
 #define DEFINE_ALIEN_ACCESSOR(name,type,boxer,to) \
-       DEFINE_PRIMITIVE(alien_##name) \
+       void primitive_alien_##name(void) \
        { \
                boxer(*(type*)alien_pointer()); \
        } \
-       DEFINE_PRIMITIVE(set_alien_##name) \
+       void primitive_set_alien_##name(void) \
        { \
                type* ptr = alien_pointer(); \
                type value = to(dpop()); \
@@ -170,7 +170,7 @@ void box_small_struct(CELL x, CELL y, CELL size)
 }
 
 /* open a native library and push a handle */
-DEFINE_PRIMITIVE(dlopen)
+void primitive_dlopen(void)
 {
        CELL path = tag_object(string_to_native_alien(
                untag_string(dpop())));
@@ -183,7 +183,7 @@ DEFINE_PRIMITIVE(dlopen)
 }
 
 /* look up a symbol in a native library */
-DEFINE_PRIMITIVE(dlsym)
+void primitive_dlsym(void)
 {
        CELL dll = dpop();
        REGISTER_ROOT(dll);
@@ -205,12 +205,12 @@ DEFINE_PRIMITIVE(dlsym)
 }
 
 /* close a native library handle */
-DEFINE_PRIMITIVE(dlclose)
+void primitive_dlclose(void)
 {
        ffi_dlclose(untag_dll(dpop()));
 }
 
-DEFINE_PRIMITIVE(dll_validp)
+void primitive_dll_validp(void)
 {
        CELL dll = dpop();
        if(dll == F)
index babfbc358d76809c7a1df92231b43360c180143c..ec1eb08acf9fcaece8760195883d4bfa4003c8b0 100755 (executable)
@@ -1,7 +1,7 @@
 CELL allot_alien(CELL delegate, CELL displacement);
 
-DECLARE_PRIMITIVE(displaced_alien);
-DECLARE_PRIMITIVE(alien_address);
+void primitive_displaced_alien(void);
+void primitive_alien_address(void);
 
 DLLEXPORT void *alien_offset(CELL object);
 
@@ -10,32 +10,32 @@ void fixup_alien(F_ALIEN* d);
 DLLEXPORT void *unbox_alien(void);
 DLLEXPORT void box_alien(void *ptr);
 
-DECLARE_PRIMITIVE(alien_signed_cell);
-DECLARE_PRIMITIVE(set_alien_signed_cell);
-DECLARE_PRIMITIVE(alien_unsigned_cell);
-DECLARE_PRIMITIVE(set_alien_unsigned_cell);
-DECLARE_PRIMITIVE(alien_signed_8);
-DECLARE_PRIMITIVE(set_alien_signed_8);
-DECLARE_PRIMITIVE(alien_unsigned_8);
-DECLARE_PRIMITIVE(set_alien_unsigned_8);
-DECLARE_PRIMITIVE(alien_signed_4);
-DECLARE_PRIMITIVE(set_alien_signed_4);
-DECLARE_PRIMITIVE(alien_unsigned_4);
-DECLARE_PRIMITIVE(set_alien_unsigned_4);
-DECLARE_PRIMITIVE(alien_signed_2);
-DECLARE_PRIMITIVE(set_alien_signed_2);
-DECLARE_PRIMITIVE(alien_unsigned_2);
-DECLARE_PRIMITIVE(set_alien_unsigned_2);
-DECLARE_PRIMITIVE(alien_signed_1);
-DECLARE_PRIMITIVE(set_alien_signed_1);
-DECLARE_PRIMITIVE(alien_unsigned_1);
-DECLARE_PRIMITIVE(set_alien_unsigned_1);
-DECLARE_PRIMITIVE(alien_float);
-DECLARE_PRIMITIVE(set_alien_float);
-DECLARE_PRIMITIVE(alien_double);
-DECLARE_PRIMITIVE(set_alien_double);
-DECLARE_PRIMITIVE(alien_cell);
-DECLARE_PRIMITIVE(set_alien_cell);
+void primitive_alien_signed_cell(void);
+void primitive_set_alien_signed_cell(void);
+void primitive_alien_unsigned_cell(void);
+void primitive_set_alien_unsigned_cell(void);
+void primitive_alien_signed_8(void);
+void primitive_set_alien_signed_8(void);
+void primitive_alien_unsigned_8(void);
+void primitive_set_alien_unsigned_8(void);
+void primitive_alien_signed_4(void);
+void primitive_set_alien_signed_4(void);
+void primitive_alien_unsigned_4(void);
+void primitive_set_alien_unsigned_4(void);
+void primitive_alien_signed_2(void);
+void primitive_set_alien_signed_2(void);
+void primitive_alien_unsigned_2(void);
+void primitive_set_alien_unsigned_2(void);
+void primitive_alien_signed_1(void);
+void primitive_set_alien_signed_1(void);
+void primitive_alien_unsigned_1(void);
+void primitive_set_alien_unsigned_1(void);
+void primitive_alien_float(void);
+void primitive_set_alien_float(void);
+void primitive_alien_double(void);
+void primitive_set_alien_double(void);
+void primitive_alien_cell(void);
+void primitive_set_alien_cell(void);
 
 DLLEXPORT void to_value_struct(CELL src, void *dest, CELL size);
 DLLEXPORT void box_value_struct(void *src, CELL size);
@@ -43,7 +43,7 @@ DLLEXPORT void box_small_struct(CELL x, CELL y, CELL size);
 
 DEFINE_UNTAG(F_DLL,DLL_TYPE,dll)
 
-DECLARE_PRIMITIVE(dlopen);
-DECLARE_PRIMITIVE(dlsym);
-DECLARE_PRIMITIVE(dlclose);
-DECLARE_PRIMITIVE(dll_validp);
+void primitive_dlopen(void);
+void primitive_dlsym(void);
+void primitive_dlclose(void);
+void primitive_dll_validp(void);
index c9466bbbb2ee05db6a75784a6eee54040b36071d..dfa7dd5f4a8f5c28e362b50ff4d041c99d8cb242 100755 (executable)
@@ -6,11 +6,6 @@ F_FASTCALL void save_callstack_bottom(F_STACK_FRAME *callstack_bottom)
        stack_chain->callstack_bottom = callstack_bottom;
 }
 
-F_FASTCALL __attribute__((noinline)) void save_callstack_top(F_STACK_FRAME *callstack_top)
-{
-       stack_chain->callstack_top = callstack_top;
-}
-
 void iterate_callstack(CELL top, CELL bottom, CALLSTACK_ITER iterator)
 {
        F_STACK_FRAME *frame = (F_STACK_FRAME *)bottom - 1;
@@ -68,7 +63,7 @@ F_STACK_FRAME *capture_start(void)
        return frame + 1;
 }
 
-DEFINE_PRIMITIVE(callstack)
+void primitive_callstack(void)
 {
        F_STACK_FRAME *top = capture_start();
        F_STACK_FRAME *bottom = stack_chain->callstack_bottom;
@@ -82,7 +77,7 @@ DEFINE_PRIMITIVE(callstack)
        dpush(tag_object(callstack));
 }
 
-DEFINE_PRIMITIVE(set_callstack)
+void primitive_set_callstack(void)
 {
        F_CALLSTACK *stack = untag_callstack(dpop());
 
@@ -117,7 +112,7 @@ CELL frame_executing(F_STACK_FRAME *frame)
 F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame)
 {
        if(frame->size == 0)
-               critical_error("Stack frame has zero size",frame);
+               critical_error("Stack frame has zero size",(CELL)frame);
        return (F_STACK_FRAME *)((CELL)frame - frame->size);
 }
 
@@ -158,7 +153,7 @@ void stack_frame_to_array(F_STACK_FRAME *frame)
        set_array_nth(array,frame_index++,frame_scan(frame));
 }
 
-DEFINE_PRIMITIVE(callstack_to_array)
+void primitive_callstack_to_array(void)
 {
        F_CALLSTACK *stack = untag_callstack(dpop());
 
@@ -190,7 +185,7 @@ F_STACK_FRAME *innermost_stack_frame(F_CALLSTACK *callstack)
 
 /* Some primitives implementing a limited form of callstack mutation.
 Used by the single stepper. */
-DEFINE_PRIMITIVE(innermost_stack_frame_quot)
+void primitive_innermost_stack_frame_quot(void)
 {
        F_STACK_FRAME *inner = innermost_stack_frame(
                untag_callstack(dpop()));
@@ -199,7 +194,7 @@ DEFINE_PRIMITIVE(innermost_stack_frame_quot)
        dpush(frame_executing(inner));
 }
 
-DEFINE_PRIMITIVE(innermost_stack_frame_scan)
+void primitive_innermost_stack_frame_scan(void)
 {
        F_STACK_FRAME *inner = innermost_stack_frame(
                untag_callstack(dpop()));
@@ -208,7 +203,7 @@ DEFINE_PRIMITIVE(innermost_stack_frame_scan)
        dpush(frame_scan(inner));
 }
 
-DEFINE_PRIMITIVE(set_innermost_stack_frame_quot)
+void primitive_set_innermost_stack_frame_quot(void)
 {
        F_CALLSTACK *callstack = untag_callstack(dpop());
        F_QUOTATION *quot = untag_quotation(dpop());
index 6c38cd01177e16b28e660642b05a5036ba1c8a98..da0748b07191d11bbf9e54d5b6d1cef579d730e3 100755 (executable)
@@ -1,5 +1,4 @@
 F_FASTCALL void save_callstack_bottom(F_STACK_FRAME *callstack_bottom);
-F_FASTCALL __attribute__((noinline)) void save_callstack_top(F_STACK_FRAME *callstack_top);
 
 #define FIRST_STACK_FRAME(stack) (F_STACK_FRAME *)((stack) + 1)
 
@@ -14,11 +13,11 @@ CELL frame_executing(F_STACK_FRAME *frame);
 CELL frame_scan(F_STACK_FRAME *frame);
 CELL frame_type(F_STACK_FRAME *frame);
 
-DECLARE_PRIMITIVE(callstack);
-DECLARE_PRIMITIVE(set_datastack);
-DECLARE_PRIMITIVE(set_retainstack);
-DECLARE_PRIMITIVE(set_callstack);
-DECLARE_PRIMITIVE(callstack_to_array);
-DECLARE_PRIMITIVE(innermost_stack_frame_quot);
-DECLARE_PRIMITIVE(innermost_stack_frame_scan);
-DECLARE_PRIMITIVE(set_innermost_stack_frame_quot);
+void primitive_callstack(void);
+void primitive_set_datastack(void);
+void primitive_set_retainstack(void);
+void primitive_set_callstack(void);
+void primitive_callstack_to_array(void);
+void primitive_innermost_stack_frame_quot(void);
+void primitive_innermost_stack_frame_scan(void);
+void primitive_set_innermost_stack_frame_quot(void);
index 03661999c52fc49811bf08d25b0ca28efcb5ef81..bd6384408b61795e6606e1bc964ba8ee798dc6ec 100755 (executable)
@@ -295,7 +295,7 @@ void recursive_mark(F_BLOCK *block)
 }
 
 /* Push the free space and total size of the code heap */
-DEFINE_PRIMITIVE(code_room)
+void primitive_code_room(void)
 {
        CELL used, total_free, max_free;
        heap_usage(&code_heap,&used,&total_free,&max_free);
index f93cba9c7aec3f6b8f2ce53ef3964ccd727960da..72ad8d451c6ffea36a1ba9f8f7ab055a6c7a4d0c 100644 (file)
@@ -82,4 +82,4 @@ void recursive_mark(F_BLOCK *block);
 void dump_heap(F_HEAP *heap);
 void compact_code_heap(void);
 
-DECLARE_PRIMITIVE(code_room);
+void primitive_code_room(void);
index 1435caa9d2caf659cd76e00ac561d3eaccb1fb0d..2268df27e30c26e4e0113f5c08f5ac63d12de1fc 100755 (executable)
@@ -68,9 +68,11 @@ INLINE CELL compute_code_rel(F_REL *rel,
        case RT_XT:
                return (CELL)untag_word(get(CREF(literals_start,REL_ARGUMENT(rel))))->xt;
        case RT_HERE:
-               return rel->offset + code_start;
+               return rel->offset + code_start + (short)REL_ARGUMENT(rel);
        case RT_LABEL:
                return code_start + REL_ARGUMENT(rel);
+       case RT_STACK_CHAIN:
+               return (CELL)&stack_chain;
        default:
                critical_error("Bad rel type",rel->type);
                return -1; /* Can't happen */
@@ -322,7 +324,7 @@ void default_word_code(F_WORD *word, bool relocate)
        word->compiledp = F;
 }
 
-DEFINE_PRIMITIVE(modify_code_heap)
+void primitive_modify_code_heap(void)
 {
        bool rescan_code_heap = to_boolean(dpop());
        F_ARRAY *alist = untag_array(dpop());
index c3b476c4b53dc111bc19b06882ff22ba633baa79..7b1545ddf57d803799ec1045f22f90cb69c10834 100755 (executable)
@@ -13,8 +13,10 @@ typedef enum {
        RT_HERE,
        /* a local label */
        RT_LABEL,
-       /* immeditae literal */
-       RT_IMMEDIATE
+       /* immediate literal */
+       RT_IMMEDIATE,
+       /* address of stack_chain var */
+       RT_STACK_CHAIN
 } F_RELTYPE;
 
 typedef enum {
@@ -71,4 +73,4 @@ F_COMPILED *add_compiled_block(
 CELL compiled_code_format(void);
 bool stack_traces_p(void);
 
-DECLARE_PRIMITIVE(modify_code_heap);
+void primitive_modify_code_heap(void);
index e0e674a7e2b7b68d6fdbf70a9e752f61e8e4b61e..6ddbd52da2db80c73adc63365856ec6dc6204f96 100755 (executable)
@@ -10,14 +10,18 @@ and the callstack top is passed in EDX */
 #define DS_REG %esi
 #define RETURN_REG %eax
 
+#define NV_TEMP_REG %ebx
+
 #define CELL_SIZE 4
 #define STACK_PADDING 12
 
 #define PUSH_NONVOLATILE \
        push %ebx ; \
+       push %ebp ; \
        push %ebp
 
 #define POP_NONVOLATILE \
+       pop %ebp ; \
        pop %ebp ; \
        pop %ebx
 
index 15a4eb8da32f56c5c823a724b7559bb36e796d7a..c981095d62ac85104ba3667919b1617a2454282e 100644 (file)
@@ -7,6 +7,8 @@
 #define CELL_SIZE 8
 #define STACK_PADDING 56
 
+#define NV_TEMP_REG %rbp
+
 #ifdef WINDOWS
 
        #define ARG0 %rcx
                push %rdi ; \
                push %rsi ; \
                push %rbx ; \
+               push %rbp ; \
                push %rbp
 
        #define POP_NONVOLATILE \
+               pop %rbp ; \
                pop %rbp ; \
                pop %rbx ; \
                pop %rsi ; \
                push %rbx ; \
                push %rbp ; \
                push %r12 ; \
+               push %r13 ; \
                push %r13
 
        #define POP_NONVOLATILE \
+               pop %r13 ; \
                pop %r13 ; \
                pop %r12 ; \
                pop %rbp ; \
index 3d6cacdebd177182d69e9e16a0a4317373e272a6..1857fb0ed806de7728148f01ee12da53c800768d 100755 (executable)
@@ -1,20 +1,21 @@
 DEF(F_FASTCALL void,c_to_factor,(CELL quot)):
        PUSH_NONVOLATILE
-       push ARG0
-
-       /* Save stack pointer */
-       lea -CELL_SIZE(STACK_REG),ARG0      
+       mov ARG0,NV_TEMP_REG
 
        /* Create register shadow area for Win64 */
-       sub $32,STACK_REG                    
+       sub $32,STACK_REG
+
+       /* Save stack pointer */
+       lea -CELL_SIZE(STACK_REG),ARG0
        call MANGLE(save_callstack_bottom)
-       add $32,STACK_REG
 
        /* Call quot-xt */
-       mov (STACK_REG),ARG0
+       mov NV_TEMP_REG,ARG0
        call *QUOT_XT_OFFSET(ARG0)
 
-       pop ARG0
+       /* Tear down register shadow area */
+       add $32,STACK_REG
+
        POP_NONVOLATILE
        ret
 
index 5342ff04d927983e9446d227a670fe97776b1f1b..cf1632811c1803343b2cbe38afd5d6c589d79ab6 100755 (executable)
@@ -250,13 +250,13 @@ CELL unaligned_object_size(CELL pointer)
        }
 }
 
-DEFINE_PRIMITIVE(size)
+void primitive_size(void)
 {
        box_unsigned_cell(object_size(dpop()));
 }
 
 /* Push memory usage statistics in data heap */
-DEFINE_PRIMITIVE(data_room)
+void primitive_data_room(void)
 {
        F_ARRAY *a = allot_array(ARRAY_TYPE,data_heap->gen_count * 2,F);
        int gen;
@@ -281,7 +281,7 @@ void begin_scan(void)
        gc_off = true;
 }
 
-DEFINE_PRIMITIVE(begin_scan)
+void primitive_begin_scan(void)
 {
        gc();
        begin_scan();
@@ -306,13 +306,13 @@ CELL next_object(void)
 }
 
 /* Push object at heap scan cursor and advance; pushes f when done */
-DEFINE_PRIMITIVE(next_object)
+void primitive_next_object(void)
 {
        dpush(next_object());
 }
 
 /* Re-enables GC */
-DEFINE_PRIMITIVE(end_scan)
+void primitive_end_scan(void)
 {
        gc_off = false;
 }
@@ -911,12 +911,12 @@ void minor_gc(void)
        garbage_collection(NURSERY,false,0);
 }
 
-DEFINE_PRIMITIVE(gc)
+void primitive_gc(void)
 {
        gc();
 }
 
-DEFINE_PRIMITIVE(gc_stats)
+void primitive_gc_stats(void)
 {
        GROWABLE_ARRAY(stats);
 
@@ -945,12 +945,12 @@ DEFINE_PRIMITIVE(gc_stats)
        dpush(stats);
 }
 
-DEFINE_PRIMITIVE(gc_reset)
+void primitive_gc_reset(void)
 {
        gc_reset();
 }
 
-DEFINE_PRIMITIVE(become)
+void primitive_become(void)
 {
        F_ARRAY *new_objects = untag_array(dpop());
        F_ARRAY *old_objects = untag_array(dpop());
index 3c21695c2c485874191e7fc287c02ddf2f19a365..0d63cc6bfee00173ec902ce27defb79f6f579def 100755 (executable)
@@ -13,11 +13,11 @@ CELL binary_payload_start(CELL pointer);
 void begin_scan(void);
 CELL next_object(void);
 
-DECLARE_PRIMITIVE(data_room);
-DECLARE_PRIMITIVE(size);
-DECLARE_PRIMITIVE(begin_scan);
-DECLARE_PRIMITIVE(next_object);
-DECLARE_PRIMITIVE(end_scan);
+void primitive_data_room(void);
+void primitive_size(void);
+void primitive_begin_scan(void);
+void primitive_next_object(void);
+void primitive_end_scan(void);
 
 void gc(void);
 DLLEXPORT void minor_gc(void);
@@ -388,9 +388,9 @@ INLINE void* allot_object(CELL type, CELL a)
 
 CELL collect_next(CELL scan);
 
-DECLARE_PRIMITIVE(gc);
-DECLARE_PRIMITIVE(gc_stats);
-DECLARE_PRIMITIVE(gc_reset);
-DECLARE_PRIMITIVE(become);
+void primitive_gc(void);
+void primitive_gc_stats(void);
+void primitive_gc_reset(void);
+void primitive_become(void);
 
 CELL find_all_words(void);
index 2550931c727196a8f5c94155770130862cf01a6f..41205d4aff6399d51a994d5726154ea69f1e245f 100755 (executable)
@@ -474,7 +474,7 @@ void factorbug(void)
        }
 }
 
-DEFINE_PRIMITIVE(die)
+void primitive_die(void)
 {
        fprintf(stderr,"The die word was called by the library. Unless you called it yourself,\n");
        fprintf(stderr,"you have triggered a bug in Factor. Please report.\n");
index 547fdba4367fbc38824ca8a481d3dad05c048204..594d8ec9197c71a191fb3493714b445cb682a4e4 100755 (executable)
@@ -6,4 +6,4 @@ void dump_zone(F_ZONE *z);
 
 bool fep_disabled;
 
-DECLARE_PRIMITIVE(die);
+void primitive_die(void);
index 36072920fea5c40b81e4e2605b6d1dd5074eae7f..fe6e79be6d4650abf0daff074f49131fa27de9ac 100755 (executable)
@@ -142,19 +142,19 @@ void misc_signal_handler_impl(void)
        signal_error(signal_number,signal_callstack_top);
 }
 
-DEFINE_PRIMITIVE(throw)
+void primitive_throw(void)
 {
        dpop();
        throw_impl(dpop(),stack_chain->callstack_top);
 }
 
-DEFINE_PRIMITIVE(call_clear)
+void primitive_call_clear(void)
 {
        throw_impl(dpop(),stack_chain->callstack_bottom);
 }
 
 /* For testing purposes */
-DEFINE_PRIMITIVE(unimplemented)
+void primitive_unimplemented(void)
 {
        not_implemented_error();
 }
index 22cd6533c30842fe74babf1b4f1b63d09281ed6a..c7f8bc8712a5a918235c5199f7dbd9f91949cd41 100755 (executable)
@@ -22,7 +22,7 @@ typedef enum
 void out_of_memory(void);
 void fatal_error(char* msg, CELL tagged);
 void critical_error(char* msg, CELL tagged);
-DECLARE_PRIMITIVE(die);
+void primitive_die(void);
 
 void throw_error(CELL error, F_STACK_FRAME *native_stack);
 void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, F_STACK_FRAME *native_stack);
@@ -32,8 +32,8 @@ void signal_error(int signal, F_STACK_FRAME *native_stack);
 void type_error(CELL type, CELL tagged);
 void not_implemented_error(void);
 
-DECLARE_PRIMITIVE(throw);
-DECLARE_PRIMITIVE(call_clear);
+void primitive_throw(void);
+void primitive_call_clear(void);
 
 INLINE void type_check(CELL type, CELL tagged)
 {
@@ -57,4 +57,4 @@ void memory_signal_handler_impl(void);
 void divide_by_zero_signal_handler_impl(void);
 void misc_signal_handler_impl(void);
 
-DECLARE_PRIMITIVE(unimplemented);
+void primitive_unimplemented(void);
index 62f9e1c906c2ea83f832e19f9b8e77ddfa6d2fd7..289c1e94c8eb33416b97335e1de7a16093238bf8 100755 (executable)
@@ -161,7 +161,7 @@ bool save_image(const F_CHAR *filename)
        return true;
 }
 
-DEFINE_PRIMITIVE(save_image)
+void primitive_save_image(void)
 {
        /* do a full GC to push everything into tenured space */
        gc();
@@ -184,7 +184,7 @@ void strip_compiled_quotations(void)
        gc_off = false;
 }
 
-DEFINE_PRIMITIVE(save_image_and_exit)
+void primitive_save_image_and_exit(void)
 {
        /* We unbox this before doing anything else. This is the only point
        where we might throw an error, so we have to throw an error here since
index 9e582fc6c661f54d0f4c8fa5a3e3cbd43078a6ef..6e1b03af0dcc0965dcd7d52b37c09bdbe1e791f0 100755 (executable)
@@ -40,8 +40,8 @@ void load_image(F_PARAMETERS *p);
 void init_objects(F_HEADER *h);
 bool save_image(const F_CHAR *file);
 
-DECLARE_PRIMITIVE(save_image);
-DECLARE_PRIMITIVE(save_image_and_exit);
+void primitive_save_image(void);
+void primitive_save_image_and_exit(void);
 
 /* relocation base of currently loaded image's data heap */
 CELL data_relocation_base;
diff --git a/vm/io.c b/vm/io.c
index bc561f5e5b86bf5cbf3147c3a2899a0e563f9103..bad4854775279ea82c276268c855af9f07237164 100755 (executable)
--- a/vm/io.c
+++ b/vm/io.c
@@ -29,7 +29,7 @@ void io_error(void)
        general_error(ERROR_IO,error,F,NULL);
 }
 
-DEFINE_PRIMITIVE(fopen)
+void primitive_fopen(void)
 {
        char *mode = unbox_char_string();
        REGISTER_C_STRING(mode);
@@ -49,7 +49,7 @@ DEFINE_PRIMITIVE(fopen)
        }
 }
 
-DEFINE_PRIMITIVE(fgetc)
+void primitive_fgetc(void)
 {
        FILE* file = unbox_alien();
 
@@ -74,7 +74,7 @@ DEFINE_PRIMITIVE(fgetc)
        }
 }
 
-DEFINE_PRIMITIVE(fread)
+void primitive_fread(void)
 {
        FILE* file = unbox_alien();
        CELL size = unbox_array_size();
@@ -116,7 +116,7 @@ DEFINE_PRIMITIVE(fread)
        }
 }
 
-DEFINE_PRIMITIVE(fputc)
+void primitive_fputc(void)
 {
        FILE *file = unbox_alien();
        F_FIXNUM ch = to_fixnum(dpop());
@@ -134,7 +134,7 @@ DEFINE_PRIMITIVE(fputc)
        }
 }
 
-DEFINE_PRIMITIVE(fwrite)
+void primitive_fwrite(void)
 {
        FILE *file = unbox_alien();
        F_BYTE_ARRAY *text = untag_byte_array(dpop());
@@ -163,7 +163,7 @@ DEFINE_PRIMITIVE(fwrite)
        }
 }
 
-DEFINE_PRIMITIVE(fflush)
+void primitive_fflush(void)
 {
        FILE *file = unbox_alien();
        for(;;)
@@ -175,7 +175,7 @@ DEFINE_PRIMITIVE(fflush)
        }
 }
 
-DEFINE_PRIMITIVE(fclose)
+void primitive_fclose(void)
 {
        FILE *file = unbox_alien();
        for(;;)
diff --git a/vm/io.h b/vm/io.h
index f4af9b8bec3a0c8469a6744a65a20865ed3d682e..08c9dd780793d3dca0b3c7a854c25c55d34544cc 100755 (executable)
--- a/vm/io.h
+++ b/vm/io.h
@@ -3,15 +3,15 @@ void io_error(void);
 int err_no(void);
 void clear_err_no(void);
 
-DECLARE_PRIMITIVE(fopen);
-DECLARE_PRIMITIVE(fgetc);
-DECLARE_PRIMITIVE(fread);
-DECLARE_PRIMITIVE(fputc);
-DECLARE_PRIMITIVE(fwrite);
-DECLARE_PRIMITIVE(fflush);
-DECLARE_PRIMITIVE(fclose);
+void primitive_fopen(void);
+void primitive_fgetc(void);
+void primitive_fread(void);
+void primitive_fputc(void);
+void primitive_fwrite(void);
+void primitive_fflush(void);
+void primitive_fclose(void);
 
 /* Platform specific primitives */
-DECLARE_PRIMITIVE(open_file);
-DECLARE_PRIMITIVE(existsp);
-DECLARE_PRIMITIVE(read_dir);
+void primitive_open_file(void);
+void primitive_existsp(void);
+void primitive_read_dir(void);
index 7d3b64ed39461152fe60da458aa8aa2c9b7bdbfd..388a472f2e9edde841943ddb3b701e90893a42fb 100644 (file)
--- a/vm/math.c
+++ b/vm/math.c
@@ -21,12 +21,12 @@ CELL to_cell(CELL tagged)
        return (CELL)to_fixnum(tagged);
 }
 
-DEFINE_PRIMITIVE(bignum_to_fixnum)
+void primitive_bignum_to_fixnum(void)
 {
        drepl(tag_fixnum(bignum_to_fixnum(untag_object(dpeek()))));
 }
 
-DEFINE_PRIMITIVE(float_to_fixnum)
+void primitive_float_to_fixnum(void)
 {
        drepl(tag_fixnum(float_to_fixnum(dpeek())));
 }
@@ -35,13 +35,13 @@ DEFINE_PRIMITIVE(float_to_fixnum)
        F_FIXNUM y = untag_fixnum_fast(dpop()); \
        F_FIXNUM x = untag_fixnum_fast(dpop());
 
-DEFINE_PRIMITIVE(fixnum_add)
+void primitive_fixnum_add(void)
 {
        POP_FIXNUMS(x,y)
        box_signed_cell(x + y);
 }
 
-DEFINE_PRIMITIVE(fixnum_subtract)
+void primitive_fixnum_subtract(void)
 {
        POP_FIXNUMS(x,y)
        box_signed_cell(x - y);
@@ -49,7 +49,7 @@ DEFINE_PRIMITIVE(fixnum_subtract)
 
 /* Multiply two integers, and trap overflow.
 Thanks to David Blaikie (The_Vulture from freenode #java) for the hint. */
-DEFINE_PRIMITIVE(fixnum_multiply)
+void primitive_fixnum_multiply(void)
 {
        POP_FIXNUMS(x,y)
 
@@ -72,13 +72,13 @@ DEFINE_PRIMITIVE(fixnum_multiply)
        }
 }
 
-DEFINE_PRIMITIVE(fixnum_divint)
+void primitive_fixnum_divint(void)
 {
        POP_FIXNUMS(x,y)
        box_signed_cell(x / y);
 }
 
-DEFINE_PRIMITIVE(fixnum_divmod)
+void primitive_fixnum_divmod(void)
 {
        POP_FIXNUMS(x,y)
        box_signed_cell(x / y);
@@ -90,7 +90,7 @@ DEFINE_PRIMITIVE(fixnum_divmod)
  * If we're shifting right by n bits, we won't overflow as long as none of the
  * high WORD_SIZE-TAG_BITS-n bits are set.
  */
-DEFINE_PRIMITIVE(fixnum_shift)
+void primitive_fixnum_shift(void)
 {
        POP_FIXNUMS(x,y)
 
@@ -122,12 +122,12 @@ DEFINE_PRIMITIVE(fixnum_shift)
 }
 
 /* Bignums */
-DEFINE_PRIMITIVE(fixnum_to_bignum)
+void primitive_fixnum_to_bignum(void)
 {
        drepl(tag_bignum(fixnum_to_bignum(untag_fixnum_fast(dpeek()))));
 }
 
-DEFINE_PRIMITIVE(float_to_bignum)
+void primitive_float_to_bignum(void)
 {
        drepl(tag_bignum(float_to_bignum(dpeek())));
 }
@@ -136,37 +136,37 @@ DEFINE_PRIMITIVE(float_to_bignum)
        F_ARRAY *y = untag_object(dpop()); \
        F_ARRAY *x = untag_object(dpop());
 
-DEFINE_PRIMITIVE(bignum_eq)
+void primitive_bignum_eq(void)
 {
        POP_BIGNUMS(x,y);
        box_boolean(bignum_equal_p(x,y));
 }
 
-DEFINE_PRIMITIVE(bignum_add)
+void primitive_bignum_add(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_add(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_subtract)
+void primitive_bignum_subtract(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_subtract(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_multiply)
+void primitive_bignum_multiply(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_multiply(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_divint)
+void primitive_bignum_divint(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_quotient(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_divmod)
+void primitive_bignum_divmod(void)
 {
        F_ARRAY *q, *r;
        POP_BIGNUMS(x,y);
@@ -175,74 +175,74 @@ DEFINE_PRIMITIVE(bignum_divmod)
        dpush(tag_bignum(r));
 }
 
-DEFINE_PRIMITIVE(bignum_mod)
+void primitive_bignum_mod(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_remainder(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_and)
+void primitive_bignum_and(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_bitwise_and(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_or)
+void primitive_bignum_or(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_bitwise_ior(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_xor)
+void primitive_bignum_xor(void)
 {
        POP_BIGNUMS(x,y);
        dpush(tag_bignum(bignum_bitwise_xor(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_shift)
+void primitive_bignum_shift(void)
 {
        F_FIXNUM y = to_fixnum(dpop());
         F_ARRAY* x = untag_object(dpop());
        dpush(tag_bignum(bignum_arithmetic_shift(x,y)));
 }
 
-DEFINE_PRIMITIVE(bignum_less)
+void primitive_bignum_less(void)
 {
        POP_BIGNUMS(x,y);
        box_boolean(bignum_compare(x,y) == bignum_comparison_less);
 }
 
-DEFINE_PRIMITIVE(bignum_lesseq)
+void primitive_bignum_lesseq(void)
 {
        POP_BIGNUMS(x,y);
        box_boolean(bignum_compare(x,y) != bignum_comparison_greater);
 }
 
-DEFINE_PRIMITIVE(bignum_greater)
+void primitive_bignum_greater(void)
 {
        POP_BIGNUMS(x,y);
        box_boolean(bignum_compare(x,y) == bignum_comparison_greater);
 }
 
-DEFINE_PRIMITIVE(bignum_greatereq)
+void primitive_bignum_greatereq(void)
 {
        POP_BIGNUMS(x,y);
        box_boolean(bignum_compare(x,y) != bignum_comparison_less);
 }
 
-DEFINE_PRIMITIVE(bignum_not)
+void primitive_bignum_not(void)
 {
        drepl(tag_bignum(bignum_bitwise_not(untag_object(dpeek()))));
 }
 
-DEFINE_PRIMITIVE(bignum_bitp)
+void primitive_bignum_bitp(void)
 {
        F_FIXNUM bit = to_fixnum(dpop());
        F_ARRAY *x = untag_object(dpop());
        box_boolean(bignum_logbitp(bit,x));
 }
 
-DEFINE_PRIMITIVE(bignum_log2)
+void primitive_bignum_log2(void)
 {
        drepl(tag_bignum(bignum_integer_length(untag_object(dpeek()))));
 }
@@ -253,7 +253,7 @@ unsigned int bignum_producer(unsigned int digit)
        return *(ptr + digit);
 }
 
-DEFINE_PRIMITIVE(byte_array_to_bignum)
+void primitive_byte_array_to_bignum(void)
 {
        type_check(BYTE_ARRAY_TYPE,dpeek());
        CELL n_digits = array_capacity(untag_object(dpeek()));
@@ -383,7 +383,7 @@ CELL unbox_array_size(void)
 
 /* Does not reduce to lowest terms, so should only be used by math
 library implementation, to avoid breaking invariants. */
-DEFINE_PRIMITIVE(from_fraction)
+void primitive_from_fraction(void)
 {
        F_RATIO* ratio = allot_object(RATIO_TYPE,sizeof(F_RATIO));
        ratio->denominator = dpop();
@@ -392,17 +392,17 @@ DEFINE_PRIMITIVE(from_fraction)
 }
 
 /* Floats */
-DEFINE_PRIMITIVE(fixnum_to_float)
+void primitive_fixnum_to_float(void)
 {
        drepl(allot_float(fixnum_to_float(dpeek())));
 }
 
-DEFINE_PRIMITIVE(bignum_to_float)
+void primitive_bignum_to_float(void)
 {
        drepl(allot_float(bignum_to_float(dpeek())));
 }
 
-DEFINE_PRIMITIVE(str_to_float)
+void primitive_str_to_float(void)
 {
        char *c_str, *end;
        double f;
@@ -418,7 +418,7 @@ DEFINE_PRIMITIVE(str_to_float)
                drepl(allot_float(f));
 }
 
-DEFINE_PRIMITIVE(float_to_str)
+void primitive_float_to_str(void)
 {
        char tmp[33];
        snprintf(tmp,32,"%.16g",untag_float(dpop()));
@@ -430,82 +430,82 @@ DEFINE_PRIMITIVE(float_to_str)
        double y = untag_float_fast(dpop()); \
        double x = untag_float_fast(dpop());
 
-DEFINE_PRIMITIVE(float_eq)
+void primitive_float_eq(void)
 {
        POP_FLOATS(x,y);
        box_boolean(x == y);
 }
 
-DEFINE_PRIMITIVE(float_add)
+void primitive_float_add(void)
 {
        POP_FLOATS(x,y);
        box_double(x + y);
 }
 
-DEFINE_PRIMITIVE(float_subtract)
+void primitive_float_subtract(void)
 {
        POP_FLOATS(x,y);
        box_double(x - y);
 }
 
-DEFINE_PRIMITIVE(float_multiply)
+void primitive_float_multiply(void)
 {
        POP_FLOATS(x,y);
        box_double(x * y);
 }
 
-DEFINE_PRIMITIVE(float_divfloat)
+void primitive_float_divfloat(void)
 {
        POP_FLOATS(x,y);
        box_double(x / y);
 }
 
-DEFINE_PRIMITIVE(float_mod)
+void primitive_float_mod(void)
 {
        POP_FLOATS(x,y);
        box_double(fmod(x,y));
 }
 
-DEFINE_PRIMITIVE(float_less)
+void primitive_float_less(void)
 {
        POP_FLOATS(x,y);
        box_boolean(x < y);
 }
 
-DEFINE_PRIMITIVE(float_lesseq)
+void primitive_float_lesseq(void)
 {
        POP_FLOATS(x,y);
        box_boolean(x <= y);
 }
 
-DEFINE_PRIMITIVE(float_greater)
+void primitive_float_greater(void)
 {
        POP_FLOATS(x,y);
        box_boolean(x > y);
 }
 
-DEFINE_PRIMITIVE(float_greatereq)
+void primitive_float_greatereq(void)
 {
        POP_FLOATS(x,y);
        box_boolean(x >= y);
 }
 
-DEFINE_PRIMITIVE(float_bits)
+void primitive_float_bits(void)
 {
        box_unsigned_4(float_bits(untag_float(dpop())));
 }
 
-DEFINE_PRIMITIVE(bits_float)
+void primitive_bits_float(void)
 {
        box_float(bits_float(to_cell(dpop())));
 }
 
-DEFINE_PRIMITIVE(double_bits)
+void primitive_double_bits(void)
 {
        box_unsigned_8(double_bits(untag_float(dpop())));
 }
 
-DEFINE_PRIMITIVE(bits_double)
+void primitive_bits_double(void)
 {
        box_double(bits_double(to_unsigned_8(dpop())));
 }
@@ -532,7 +532,7 @@ void box_double(double flo)
 
 /* Complex numbers */
 
-DEFINE_PRIMITIVE(from_rect)
+void primitive_from_rect(void)
 {
        F_COMPLEX* complex = allot_object(COMPLEX_TYPE,sizeof(F_COMPLEX));
        complex->imaginary = dpop();
index 07d7fa91990bca49f0d8572a0b70ebe4f62341c8..4fa3c8d35f086d1a60e85404a4c87ed38f878e57 100644 (file)
--- a/vm/math.h
+++ b/vm/math.h
@@ -6,15 +6,15 @@
 DLLEXPORT F_FIXNUM to_fixnum(CELL tagged);
 DLLEXPORT CELL to_cell(CELL tagged);
 
-DECLARE_PRIMITIVE(bignum_to_fixnum);
-DECLARE_PRIMITIVE(float_to_fixnum);
+void primitive_bignum_to_fixnum(void);
+void primitive_float_to_fixnum(void);
 
-DECLARE_PRIMITIVE(fixnum_add);
-DECLARE_PRIMITIVE(fixnum_subtract);
-DECLARE_PRIMITIVE(fixnum_multiply);
-DECLARE_PRIMITIVE(fixnum_divint);
-DECLARE_PRIMITIVE(fixnum_divmod);
-DECLARE_PRIMITIVE(fixnum_shift);
+void primitive_fixnum_add(void);
+void primitive_fixnum_subtract(void);
+void primitive_fixnum_multiply(void);
+void primitive_fixnum_divint(void);
+void primitive_fixnum_divmod(void);
+void primitive_fixnum_shift(void);
 
 CELL bignum_zero;
 CELL bignum_pos_one;
@@ -25,27 +25,27 @@ INLINE CELL tag_bignum(F_ARRAY* bignum)
        return RETAG(bignum,BIGNUM_TYPE);
 }
 
-DECLARE_PRIMITIVE(fixnum_to_bignum);
-DECLARE_PRIMITIVE(float_to_bignum);
-DECLARE_PRIMITIVE(bignum_eq);
-DECLARE_PRIMITIVE(bignum_add);
-DECLARE_PRIMITIVE(bignum_subtract);
-DECLARE_PRIMITIVE(bignum_multiply);
-DECLARE_PRIMITIVE(bignum_divint);
-DECLARE_PRIMITIVE(bignum_divmod);
-DECLARE_PRIMITIVE(bignum_mod);
-DECLARE_PRIMITIVE(bignum_and);
-DECLARE_PRIMITIVE(bignum_or);
-DECLARE_PRIMITIVE(bignum_xor);
-DECLARE_PRIMITIVE(bignum_shift);
-DECLARE_PRIMITIVE(bignum_less);
-DECLARE_PRIMITIVE(bignum_lesseq);
-DECLARE_PRIMITIVE(bignum_greater);
-DECLARE_PRIMITIVE(bignum_greatereq);
-DECLARE_PRIMITIVE(bignum_not);
-DECLARE_PRIMITIVE(bignum_bitp);
-DECLARE_PRIMITIVE(bignum_log2);
-DECLARE_PRIMITIVE(byte_array_to_bignum);
+void primitive_fixnum_to_bignum(void);
+void primitive_float_to_bignum(void);
+void primitive_bignum_eq(void);
+void primitive_bignum_add(void);
+void primitive_bignum_subtract(void);
+void primitive_bignum_multiply(void);
+void primitive_bignum_divint(void);
+void primitive_bignum_divmod(void);
+void primitive_bignum_mod(void);
+void primitive_bignum_and(void);
+void primitive_bignum_or(void);
+void primitive_bignum_xor(void);
+void primitive_bignum_shift(void);
+void primitive_bignum_less(void);
+void primitive_bignum_lesseq(void);
+void primitive_bignum_greater(void);
+void primitive_bignum_greatereq(void);
+void primitive_bignum_not(void);
+void primitive_bignum_bitp(void);
+void primitive_bignum_log2(void);
+void primitive_byte_array_to_bignum(void);
 
 INLINE CELL allot_integer(F_FIXNUM x)
 {
@@ -80,7 +80,7 @@ DLLEXPORT u64 to_unsigned_8(CELL obj);
 
 CELL unbox_array_size(void);
 
-DECLARE_PRIMITIVE(from_fraction);
+void primitive_from_fraction(void);
 
 INLINE double untag_float_fast(CELL tagged)
 {
@@ -125,26 +125,26 @@ DLLEXPORT float to_float(CELL value);
 DLLEXPORT void box_double(double flo);
 DLLEXPORT double to_double(CELL value);
 
-DECLARE_PRIMITIVE(fixnum_to_float);
-DECLARE_PRIMITIVE(bignum_to_float);
-DECLARE_PRIMITIVE(str_to_float);
-DECLARE_PRIMITIVE(float_to_str);
-DECLARE_PRIMITIVE(float_to_bits);
-
-DECLARE_PRIMITIVE(float_eq);
-DECLARE_PRIMITIVE(float_add);
-DECLARE_PRIMITIVE(float_subtract);
-DECLARE_PRIMITIVE(float_multiply);
-DECLARE_PRIMITIVE(float_divfloat);
-DECLARE_PRIMITIVE(float_mod);
-DECLARE_PRIMITIVE(float_less);
-DECLARE_PRIMITIVE(float_lesseq);
-DECLARE_PRIMITIVE(float_greater);
-DECLARE_PRIMITIVE(float_greatereq);
-
-DECLARE_PRIMITIVE(float_bits);
-DECLARE_PRIMITIVE(bits_float);
-DECLARE_PRIMITIVE(double_bits);
-DECLARE_PRIMITIVE(bits_double);
-
-DECLARE_PRIMITIVE(from_rect);
+void primitive_fixnum_to_float(void);
+void primitive_bignum_to_float(void);
+void primitive_str_to_float(void);
+void primitive_float_to_str(void);
+void primitive_float_to_bits(void);
+
+void primitive_float_eq(void);
+void primitive_float_add(void);
+void primitive_float_subtract(void);
+void primitive_float_multiply(void);
+void primitive_float_divfloat(void);
+void primitive_float_mod(void);
+void primitive_float_less(void);
+void primitive_float_lesseq(void);
+void primitive_float_greater(void);
+void primitive_float_greatereq(void);
+
+void primitive_float_bits(void);
+void primitive_bits_float(void);
+void primitive_double_bits(void);
+void primitive_bits_double(void);
+
+void primitive_from_rect(void);
index 4ca62e6623168475679804587c8a2eba6960f6eb..c11962f6e1dde1249b4605719a99387657cdc77a 100755 (executable)
@@ -55,7 +55,7 @@ void ffi_dlclose(F_DLL *dll)
        dll->dll = NULL;
 }
 
-DEFINE_PRIMITIVE(existsp)
+void primitive_existsp(void)
 {
        struct stat sb;
        box_boolean(stat(unbox_char_string(),&sb) >= 0);
index 9b73692aa05f1ee12483c9b7800ecfa216358d4b..02b51b82ed4fe2fb999e0d4f5082607003a63e74 100755 (executable)
@@ -27,7 +27,7 @@ char *getenv(char *name)
        return 0; /* unreachable */
 }
 
-DEFINE_PRIMITIVE(os_envs)
+void primitive_os_envs(void)
 {
        not_implemented_error();
 }
index c19aa5c4b501afa22370377288638046b38f5496..fc289c288ea8f97fd89f2fe24ad6e3fbb32a39de 100755 (executable)
@@ -87,7 +87,7 @@ const F_CHAR *vm_executable_path(void)
        return safe_strdup(full_path);
 }
 
-DEFINE_PRIMITIVE(existsp)
+void primitive_existsp(void)
 {
        BY_HANDLE_FILE_INFORMATION bhfi;
 
index 811b473acdc72c77aa9070359bf9d74069f31357..30e0a4af964da03b9a2cb51dfe3c4d40e06f5d98 100644 (file)
@@ -1,42 +1 @@
 extern void *primitives[];
-
-/* Primitives are called with two parameters, the word itself and the current
-callstack pointer. The DEFINE_PRIMITIVE() macro takes care of boilerplate to
-save the current callstack pointer so that GC and other facilities can proceed
-to inspect Factor stack frames below the primitive's C stack frame.
-
-Usage:
-
-DEFINE_PRIMITIVE(name)
-{
-       ... CODE ...
-}
-
-Becomes
-
-F_FASTCALL void primitive_name(CELL word, F_STACK_FRAME *callstack_top)
-{
-       save_callstack_top(callstack_top);
-       ... CODE ...
-}
-
-On x86, F_FASTCALL expands into a GCC declaration which forces the two
-parameters to be passed in registers. This simplifies the quotation compiler
-and support code in cpu-x86.S.
-
-We do the assignment of stack_chain->callstack_top in a ``noinline'' function
-to inhibit assignment re-ordering. */
-#define DEFINE_PRIMITIVE(name) \
-       INLINE void primitive_##name##_impl(void); \
-       \
-       F_FASTCALL void primitive_##name(CELL word, F_STACK_FRAME *callstack_top) \
-       { \
-               save_callstack_top(callstack_top); \
-               primitive_##name##_impl(); \
-       } \
-       \
-       INLINE void primitive_##name##_impl(void) \
-
-/* Prototype for header files */
-#define DECLARE_PRIMITIVE(name) \
-       F_FASTCALL void primitive_##name(CELL word, F_STACK_FRAME *callstack_top)
index 27e903178b3b8427b835234e70d9db6ed661dee1..e3db67964f664d1515e3b79e346d1ac23affdd1e 100755 (executable)
@@ -32,7 +32,6 @@ F_COMPILED *compile_profiling_stub(F_WORD *word)
 /* Allocates memory */
 void update_word_xt(F_WORD *word)
 {
-       /* If we just enabled the profiler, reset call count */
        if(profiling_p)
        {
                if(!word->profiling)
@@ -80,7 +79,7 @@ void set_profiling(bool profiling)
        iterate_code_heap(relocate_code_block);
 }
 
-DEFINE_PRIMITIVE(profiling)
+void primitive_profiling(void)
 {
        set_profiling(to_boolean(dpop()));
 }
index d14ceb283b2fe502da2c22c3ce714c6699c20d1c..26a3a78d4b9dc0728513288b736bddffc3fb3977 100755 (executable)
@@ -1,4 +1,4 @@
 bool profiling_p;
-DECLARE_PRIMITIVE(profiling);
+void primitive_profiling(void);
 F_COMPILED *compile_profiling_stub(F_WORD *word);
 void update_word_xt(F_WORD *word);
index b75d3f79e00c6776c3964cd7cec72ffe05e3ca95..bf917aeec06a7c40155870ee2c42d3dc6e7306dd 100755 (executable)
@@ -209,6 +209,7 @@ void jit_compile(CELL quot, bool relocate)
                case FIXNUM_TYPE:
                        if(jit_primitive_call_p(untag_object(array),i))
                        {
+                               EMIT(userenv[JIT_SAVE_STACK],0);
                                EMIT(userenv[JIT_PRIMITIVE],to_fixnum(obj));
 
                                i++;
@@ -344,6 +345,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
                case FIXNUM_TYPE:
                        if(jit_primitive_call_p(untag_object(array),i))
                        {
+                               COUNT(userenv[JIT_SAVE_STACK],i);
                                COUNT(userenv[JIT_PRIMITIVE],i);
 
                                i++;
@@ -412,7 +414,7 @@ F_FASTCALL CELL primitive_jit_compile(CELL quot, F_STACK_FRAME *stack)
 }
 
 /* push a new quotation on the stack */
-DEFINE_PRIMITIVE(array_to_quotation)
+void primitive_array_to_quotation(void)
 {
        F_QUOTATION *quot = allot_object(QUOTATION_TYPE,sizeof(F_QUOTATION));
        quot->array = dpeek();
@@ -421,7 +423,7 @@ DEFINE_PRIMITIVE(array_to_quotation)
        drepl(tag_object(quot));
 }
 
-DEFINE_PRIMITIVE(quotation_xt)
+void primitive_quotation_xt(void)
 {
        F_QUOTATION *quot = untag_quotation(dpeek());
        drepl(allot_cell((CELL)quot->xt));
index 0845957c0b84372f152e28b7af89b598794ec2d8..45bf78d14fb384d299f0a0ae5e392d8ab1f2f0aa 100755 (executable)
@@ -2,5 +2,5 @@ void set_quot_xt(F_QUOTATION *quot, F_COMPILED *code);
 void jit_compile(CELL quot, bool relocate);
 F_FASTCALL CELL primitive_jit_compile(CELL quot, F_STACK_FRAME *stack);
 F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset);
-DECLARE_PRIMITIVE(array_to_quotation);
-DECLARE_PRIMITIVE(quotation_xt);
+void primitive_array_to_quotation(void);
+void primitive_quotation_xt(void);
index c4a3e115c13708c336a67cf6c7677ee3458c248e..c7d93d29c81768644439bdc2ac175ee3f5732787 100755 (executable)
--- a/vm/run.c
+++ b/vm/run.c
@@ -105,13 +105,13 @@ bool stack_to_array(CELL bottom, CELL top)
        }
 }
 
-DEFINE_PRIMITIVE(datastack)
+void primitive_datastack(void)
 {
        if(!stack_to_array(ds_bot,ds))
                general_error(ERROR_DS_UNDERFLOW,F,F,NULL);
 }
 
-DEFINE_PRIMITIVE(retainstack)
+void primitive_retainstack(void)
 {
        if(!stack_to_array(rs_bot,rs))
                general_error(ERROR_RS_UNDERFLOW,F,F,NULL);
@@ -125,45 +125,45 @@ CELL array_to_stack(F_ARRAY *array, CELL bottom)
        return bottom + depth - CELLS;
 }
 
-DEFINE_PRIMITIVE(set_datastack)
+void primitive_set_datastack(void)
 {
        ds = array_to_stack(untag_array(dpop()),ds_bot);
 }
 
-DEFINE_PRIMITIVE(set_retainstack)
+void primitive_set_retainstack(void)
 {
        rs = array_to_stack(untag_array(dpop()),rs_bot);
 }
 
-DEFINE_PRIMITIVE(getenv)
+void primitive_getenv(void)
 {
        F_FIXNUM e = untag_fixnum_fast(dpeek());
        drepl(userenv[e]);
 }
 
-DEFINE_PRIMITIVE(setenv)
+void primitive_setenv(void)
 {
        F_FIXNUM e = untag_fixnum_fast(dpop());
        CELL value = dpop();
        userenv[e] = value;
 }
 
-DEFINE_PRIMITIVE(exit)
+void primitive_exit(void)
 {
        exit(to_fixnum(dpop()));
 }
 
-DEFINE_PRIMITIVE(millis)
+void primitive_millis(void)
 {
        box_unsigned_8(current_millis());
 }
 
-DEFINE_PRIMITIVE(sleep)
+void primitive_sleep(void)
 {
        sleep_millis(to_cell(dpop()));
 }
 
-DEFINE_PRIMITIVE(set_slot)
+void primitive_set_slot(void)
 {
        F_FIXNUM slot = untag_fixnum_fast(dpop());
        CELL obj = dpop();
index 96e606e38cba5302edad54ff3e7b9f015e7345df..2dbbcc8c0640e646a7cefab8ed89e7ee120de1a1 100755 (executable)
--- a/vm/run.h
+++ b/vm/run.h
@@ -48,8 +48,8 @@ typedef enum {
        JIT_RETURN,
        JIT_PROFILING,
        JIT_PUSH_IMMEDIATE,
-
        JIT_DECLARE_WORD    = 42,
+       JIT_SAVE_STACK,
 
        STACK_TRACES_ENV    = 59,
 
@@ -226,18 +226,18 @@ DLLEXPORT void nest_stacks(void);
 DLLEXPORT void unnest_stacks(void);
 void init_stacks(CELL ds_size, CELL rs_size);
 
-DECLARE_PRIMITIVE(datastack);
-DECLARE_PRIMITIVE(retainstack);
-DECLARE_PRIMITIVE(getenv);
-DECLARE_PRIMITIVE(setenv);
-DECLARE_PRIMITIVE(exit);
-DECLARE_PRIMITIVE(os_env);
-DECLARE_PRIMITIVE(os_envs);
-DECLARE_PRIMITIVE(set_os_env);
-DECLARE_PRIMITIVE(unset_os_env);
-DECLARE_PRIMITIVE(set_os_envs);
-DECLARE_PRIMITIVE(millis);
-DECLARE_PRIMITIVE(sleep);
-DECLARE_PRIMITIVE(set_slot);
+void primitive_datastack(void);
+void primitive_retainstack(void);
+void primitive_getenv(void);
+void primitive_setenv(void);
+void primitive_exit(void);
+void primitive_os_env(void);
+void primitive_os_envs(void);
+void primitive_set_os_env(void);
+void primitive_unset_os_env(void);
+void primitive_set_os_envs(void);
+void primitive_millis(void);
+void primitive_sleep(void);
+void primitive_set_slot(void);
 
 bool stage2;
index 5e2ed4bed9a039ab2aa58955ee3168d48ade34c0..f1588465a4dae398fb45659060dc8ef9f9c780ef 100755 (executable)
@@ -29,7 +29,7 @@ CELL clone_object(CELL object)
        }
 }
 
-DEFINE_PRIMITIVE(clone)
+void primitive_clone(void)
 {
        drepl(clone_object(dpeek()));
 }
@@ -61,11 +61,14 @@ F_WORD *allot_word(CELL vocab, CELL name)
        update_word_xt(word);
        UNREGISTER_UNTAGGED(word);
 
+       if(profiling_p)
+               iterate_code_heap_step(word->profiling,relocate_code_block);
+
        return word;
 }
 
 /* <word> ( name vocabulary -- word ) */
-DEFINE_PRIMITIVE(word)
+void primitive_word(void)
 {
        CELL vocab = dpop();
        CELL name = dpop();
@@ -73,15 +76,15 @@ DEFINE_PRIMITIVE(word)
 }
 
 /* word-xt ( word -- start end ) */
-DEFINE_PRIMITIVE(word_xt)
+void primitive_word_xt(void)
 {
        F_WORD *word = untag_word(dpop());
-       F_COMPILED *code = word->code;
+       F_COMPILED *code = (profiling_p ? word->profiling : word->code);
        dpush(allot_cell((CELL)code + sizeof(F_COMPILED)));
        dpush(allot_cell((CELL)code + sizeof(F_COMPILED) + code->code_length));
 }
 
-DEFINE_PRIMITIVE(wrapper)
+void primitive_wrapper(void)
 {
        F_WRAPPER *wrapper = allot_object(WRAPPER_TYPE,sizeof(F_WRAPPER));
        wrapper->object = dpeek();
@@ -120,7 +123,7 @@ F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill)
 }
 
 /* push a new array on the stack */
-DEFINE_PRIMITIVE(array)
+void primitive_array(void)
 {
        CELL initial = dpop();
        CELL size = unbox_array_size();
@@ -191,7 +194,7 @@ F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill)
        return new_array;
 }
 
-DEFINE_PRIMITIVE(resize_array)
+void primitive_resize_array(void)
 {
        F_ARRAY* array = untag_array(dpop());
        CELL capacity = unbox_array_size();
@@ -256,7 +259,7 @@ F_BYTE_ARRAY *allot_byte_array(CELL size)
 }
 
 /* push a new byte array on the stack */
-DEFINE_PRIMITIVE(byte_array)
+void primitive_byte_array(void)
 {
        CELL size = unbox_array_size();
        dpush(tag_object(allot_byte_array(size)));
@@ -277,7 +280,7 @@ F_BYTE_ARRAY *reallot_byte_array(F_BYTE_ARRAY *array, CELL capacity)
        return new_array;
 }
 
-DEFINE_PRIMITIVE(resize_byte_array)
+void primitive_resize_byte_array(void)
 {
        F_BYTE_ARRAY* array = untag_byte_array(dpop());
        CELL capacity = unbox_array_size();
@@ -310,7 +313,7 @@ F_TUPLE *allot_tuple(F_TUPLE_LAYOUT *layout)
        return tuple;
 }
 
-DEFINE_PRIMITIVE(tuple)
+void primitive_tuple(void)
 {
        F_TUPLE_LAYOUT *layout = untag_object(dpop());
        F_FIXNUM size = untag_fixnum_fast(layout->size);
@@ -324,7 +327,7 @@ DEFINE_PRIMITIVE(tuple)
 }
 
 /* push a new tuple on the stack, filling its slots from the stack */
-DEFINE_PRIMITIVE(tuple_boa)
+void primitive_tuple_boa(void)
 {
        F_TUPLE_LAYOUT *layout = untag_object(dpop());
        F_FIXNUM size = untag_fixnum_fast(layout->size);
@@ -431,7 +434,7 @@ F_STRING *allot_string(CELL capacity, CELL fill)
        return string;
 }
 
-DEFINE_PRIMITIVE(string)
+void primitive_string(void)
 {
        CELL initial = to_cell(dpop());
        CELL length = unbox_array_size();
@@ -474,7 +477,7 @@ F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill)
        return new_string;
 }
 
-DEFINE_PRIMITIVE(resize_string)
+void primitive_resize_string(void)
 {
        F_STRING* string = untag_string(dpop());
        CELL capacity = unbox_array_size();
@@ -541,7 +544,7 @@ F_BYTE_ARRAY *allot_c_string(CELL capacity, CELL size)
                for(i = 0; i < capacity; i++) \
                        string[i] = string_nth(s,i); \
        } \
-       DEFINE_PRIMITIVE(type##_string_to_memory) \
+       void primitive_##type##_string_to_memory(void) \
        { \
                type *address = unbox_alien(); \
                F_STRING *str = untag_string(dpop()); \
@@ -573,14 +576,14 @@ F_BYTE_ARRAY *allot_c_string(CELL capacity, CELL size)
 STRING_TO_MEMORY(char);
 STRING_TO_MEMORY(u16);
 
-DEFINE_PRIMITIVE(string_nth)
+void primitive_string_nth(void)
 {
        F_STRING *string = untag_object(dpop());
        CELL index = untag_fixnum_fast(dpop());
        dpush(tag_fixnum(string_nth(string,index)));
 }
 
-DEFINE_PRIMITIVE(set_string_nth)
+void primitive_set_string_nth(void)
 {
        F_STRING *string = untag_object(dpop());
        CELL index = untag_fixnum_fast(dpop());
index 6efae35f5e41eee3461748e7becb94483892ebf4..ebbb8a264241aa22382e0e7cd11c542323f6f32c 100755 (executable)
@@ -112,23 +112,23 @@ CELL allot_array_1(CELL obj);
 CELL allot_array_2(CELL v1, CELL v2);
 CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4);
 
-DECLARE_PRIMITIVE(array);
-DECLARE_PRIMITIVE(tuple);
-DECLARE_PRIMITIVE(tuple_boa);
-DECLARE_PRIMITIVE(tuple_layout);
-DECLARE_PRIMITIVE(byte_array);
-DECLARE_PRIMITIVE(clone);
+void primitive_array(void);
+void primitive_tuple(void);
+void primitive_tuple_boa(void);
+void primitive_tuple_layout(void);
+void primitive_byte_array(void);
+void primitive_clone(void);
 
 F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill);
 F_BYTE_ARRAY *reallot_byte_array(F_BYTE_ARRAY *array, CELL capacity);
-DECLARE_PRIMITIVE(resize_array);
-DECLARE_PRIMITIVE(resize_byte_array);
+void primitive_resize_array(void);
+void primitive_resize_byte_array(void);
 
 F_STRING* allot_string_internal(CELL capacity);
 F_STRING* allot_string(CELL capacity, CELL fill);
-DECLARE_PRIMITIVE(string);
+void primitive_string(void);
 F_STRING *reallot_string(F_STRING *string, CELL capacity, CELL fill);
-DECLARE_PRIMITIVE(resize_string);
+void primitive_resize_string(void);
 
 F_STRING *memory_to_char_string(const char *string, CELL length);
 F_STRING *from_char_string(const char *c_string);
@@ -152,14 +152,14 @@ DLLEXPORT u16 *unbox_u16_string(void);
 CELL string_nth(F_STRING* string, CELL index);
 void set_string_nth(F_STRING* string, CELL index, CELL value);
 
-DECLARE_PRIMITIVE(string_nth);
-DECLARE_PRIMITIVE(set_string_nth);
+void primitive_string_nth(void);
+void primitive_set_string_nth(void);
 
 F_WORD *allot_word(CELL vocab, CELL name);
-DECLARE_PRIMITIVE(word);
-DECLARE_PRIMITIVE(word_xt);
+void primitive_word(void);
+void primitive_word_xt(void);
 
-DECLARE_PRIMITIVE(wrapper);
+void primitive_wrapper(void);
 
 /* Macros to simulate a vector in C */
 #define GROWABLE_ARRAY(result) \