]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorSlava Pestov <slava@goo.local>
Mon, 11 May 2009 19:38:45 +0000 (14:38 -0500)
committerSlava Pestov <slava@goo.local>
Mon, 11 May 2009 19:38:45 +0000 (14:38 -0500)
401 files changed:
README.txt
basis/alien/c-types/c-types.factor
basis/alien/libraries/libraries.factor [changed mode: 0644->0755]
basis/base64/base64-tests.factor
basis/bootstrap/compiler/compiler.factor [changed mode: 0644->0755]
basis/bootstrap/image/image.factor
basis/bootstrap/image/syntax/authors.txt [new file with mode: 0644]
basis/bootstrap/image/syntax/syntax.factor [new file with mode: 0644]
basis/checksums/common/common.factor
basis/checksums/sha2/sha2-tests.factor
basis/checksums/sha2/sha2.factor
basis/cocoa/application/application.factor
basis/cocoa/cocoa.factor
basis/cocoa/messages/messages.factor
basis/cocoa/plists/plists.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/compiler.factor
basis/compiler/constants/constants.factor
basis/compiler/tests/alien.factor
basis/compiler/tests/curry.factor
basis/compiler/tests/optimizer.factor
basis/compiler/tree/builder/builder.factor
basis/compiler/tree/escape-analysis/escape-analysis-tests.factor
basis/compiler/tree/modular-arithmetic/modular-arithmetic-tests.factor
basis/compiler/tree/modular-arithmetic/modular-arithmetic.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/known-words/known-words.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/tuple-unboxing/tuple-unboxing-tests.factor
basis/core-graphics/core-graphics.factor
basis/core-graphics/types/types.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/assembler/assembler-tests.factor
basis/cpu/ppc/assembler/assembler.factor
basis/cpu/ppc/assembler/backend/backend.factor
basis/cpu/ppc/bootstrap.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/assembler/assembler.factor
basis/cpu/x86/bootstrap.factor
basis/cpu/x86/x86.factor
basis/dlists/dlists-docs.factor
basis/dlists/dlists-tests.factor
basis/dlists/dlists.factor
basis/fry/fry-docs.factor
basis/generalizations/generalizations-docs.factor
basis/generalizations/generalizations-tests.factor
basis/generalizations/generalizations.factor
basis/images/tiff/tiff.factor
basis/io/backend/windows/privileges/privileges-tests.factor [new file with mode: 0755]
basis/io/backend/windows/privileges/privileges.factor [changed mode: 0644->0755]
basis/io/directories/search/search-docs.factor
basis/io/directories/search/search.factor
basis/io/files/unique/unique.factor
basis/io/launcher/unix/unix-tests.factor
basis/io/launcher/windows/nt/nt-tests.factor
basis/io/streams/string/string-tests.factor
basis/literals/literals-docs.factor
basis/literals/literals-tests.factor [changed mode: 0644->0755]
basis/literals/literals.factor [changed mode: 0644->0755]
basis/math/bits/bits.factor
basis/math/bitwise/bitwise.factor
basis/math/blas/vectors/vectors.factor
basis/math/combinatorics/combinatorics-docs.factor
basis/math/combinatorics/combinatorics-tests.factor
basis/math/combinatorics/combinatorics.factor
basis/math/constants/constants.factor
basis/math/functions/functions-tests.factor
basis/math/functions/functions.factor
basis/math/intervals/intervals.factor
basis/math/miller-rabin/authors.txt [deleted file]
basis/math/miller-rabin/miller-rabin-tests.factor [deleted file]
basis/math/miller-rabin/miller-rabin.factor [deleted file]
basis/math/miller-rabin/summary.txt [deleted file]
basis/math/polynomials/polynomials-docs.factor
basis/math/polynomials/polynomials.factor
basis/math/primes/factors/factors.factor
basis/math/primes/lucas-lehmer/authors.txt [new file with mode: 0644]
basis/math/primes/lucas-lehmer/lucas-lehmer-docs.factor [new file with mode: 0644]
basis/math/primes/lucas-lehmer/lucas-lehmer-tests.factor [new file with mode: 0644]
basis/math/primes/lucas-lehmer/lucas-lehmer.factor [new file with mode: 0644]
basis/math/primes/miller-rabin/authors.txt [new file with mode: 0755]
basis/math/primes/miller-rabin/miller-rabin-docs.factor [new file with mode: 0644]
basis/math/primes/miller-rabin/miller-rabin-tests.factor [new file with mode: 0644]
basis/math/primes/miller-rabin/miller-rabin.factor [new file with mode: 0755]
basis/math/primes/miller-rabin/summary.txt [new file with mode: 0644]
basis/math/primes/primes-docs.factor
basis/math/primes/primes-tests.factor
basis/math/primes/primes.factor
basis/math/primes/safe/authors.txt [new file with mode: 0644]
basis/math/primes/safe/safe-docs.factor [new file with mode: 0644]
basis/math/primes/safe/safe-tests.factor [new file with mode: 0644]
basis/math/primes/safe/safe.factor [new file with mode: 0644]
basis/math/ranges/ranges.factor
basis/math/rectangles/prettyprint/authors.txt [new file with mode: 0644]
basis/math/rectangles/prettyprint/prettyprint.factor [new file with mode: 0644]
basis/math/rectangles/rectangles.factor
basis/math/statistics/statistics.factor
basis/math/vectors/vectors-tests.factor
basis/math/vectors/vectors.factor
basis/none/deploy.factor
basis/opengl/textures/textures.factor
basis/random/mersenne-twister/mersenne-twister-tests.factor
basis/random/random-docs.factor
basis/random/random-tests.factor
basis/random/random.factor
basis/specialized-arrays/specialized-arrays-tests.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/stack-checker-tests.factor
basis/tools/continuations/continuations.factor
basis/tools/deploy/backend/backend.factor
basis/tools/deploy/config/config-docs.factor
basis/tools/deploy/config/config.factor
basis/tools/deploy/deploy-docs.factor
basis/tools/deploy/deploy-tests.factor
basis/tools/deploy/shaker/shaker.factor
basis/tools/deploy/shaker/strip-cocoa.factor
basis/tools/deploy/test/1/deploy.factor
basis/tools/deploy/test/10/deploy.factor
basis/tools/deploy/test/11/deploy.factor
basis/tools/deploy/test/12/deploy.factor
basis/tools/deploy/test/13/deploy.factor
basis/tools/deploy/test/2/deploy.factor
basis/tools/deploy/test/3/deploy.factor
basis/tools/deploy/test/4/deploy.factor
basis/tools/deploy/test/5/deploy.factor
basis/tools/deploy/test/6/deploy.factor
basis/tools/deploy/test/7/deploy.factor
basis/tools/deploy/test/8/8.factor [deleted file]
basis/tools/deploy/test/8/deploy.factor [deleted file]
basis/tools/deploy/test/9/deploy.factor
basis/tools/disassembler/udis/udis-tests.factor [new file with mode: 0644]
basis/tools/disassembler/udis/udis.factor
basis/tools/time/time.factor
basis/tools/trace/trace-tests.factor
basis/tools/trace/trace.factor
basis/tools/walker/walker-tests.factor
basis/ui/backend/backend.factor
basis/ui/backend/cocoa/cocoa.factor
basis/ui/backend/windows/windows.factor
basis/ui/gadgets/gadgets.factor
basis/ui/gadgets/prettyprint/authors.txt [new file with mode: 0644]
basis/ui/gadgets/prettyprint/prettyprint.factor [new file with mode: 0644]
basis/ui/gadgets/worlds/worlds-docs.factor
basis/ui/gadgets/worlds/worlds.factor
basis/ui/gestures/gestures.factor
basis/ui/pixel-formats/pixel-formats.factor
basis/ui/tools/deploy/deploy.factor
basis/ui/ui-docs.factor
basis/ui/ui.factor
basis/urls/encoding/encoding-tests.factor
basis/urls/urls.factor
basis/windows/com/com.factor
basis/windows/com/wrapper/wrapper.factor
basis/windows/dinput/dinput.factor
basis/windows/user32/user32.factor [changed mode: 0644->0755]
basis/xml/xml.factor
core/alien/strings/strings.factor
core/bootstrap/primitives.factor
core/checksums/crc32/crc32.factor
core/combinators/combinators-docs.factor
core/continuations/continuations-docs.factor
core/continuations/continuations-tests.factor
core/continuations/continuations.factor
core/generic/hook/hook.factor
core/generic/single/single-tests.factor
core/generic/single/single.factor
core/generic/standard/standard.factor
core/hashtables/hashtables.factor
core/io/io-docs.factor
core/io/io.factor
core/io/streams/byte-array/byte-array-tests.factor
core/kernel/kernel-docs.factor
core/kernel/kernel-tests.factor
core/kernel/kernel.factor
core/math/math-docs.factor
core/math/math-tests.factor
core/math/math.factor
core/memory/memory.factor
core/quotations/quotations.factor
core/sequences/sequences-docs.factor
core/sequences/sequences.factor
core/words/words.factor
extra/4DNav/deploy.factor
extra/benchmark/fib6/deploy.factor
extra/benchmark/pidigits/pidigits.factor
extra/benchmark/regex-dna/deploy.factor
extra/bson/reader/reader.factor
extra/bson/writer/writer.factor
extra/bunny/deploy.factor
extra/bunny/model/model.factor
extra/bunny/outlined/outlined.factor
extra/chicago-talk/deploy.factor
extra/color-picker/deploy.factor
extra/crypto/hmac/hmac.factor
extra/crypto/rsa/rsa.factor
extra/crypto/timing/authors.txt [deleted file]
extra/crypto/timing/timing-tests.factor [deleted file]
extra/crypto/timing/timing.factor [deleted file]
extra/drills/deployed/deploy.factor
extra/game-input/dinput/dinput.factor
extra/game-input/game-input-docs.factor
extra/game-input/game-input.factor
extra/game-input/iokit/iokit.factor
extra/game-loop/game-loop.factor
extra/game-worlds/game-worlds.factor [new file with mode: 0644]
extra/gesture-logger/deploy.factor
extra/hashcash/authors.txt [new file with mode: 0755]
extra/hashcash/hashcash-docs.factor [new file with mode: 0644]
extra/hashcash/hashcash-tests.factor [new file with mode: 0644]
extra/hashcash/hashcash.factor [new file with mode: 0755]
extra/hashcash/summary.txt [new file with mode: 0644]
extra/hello-ui/deploy.factor
extra/hello-unicode/deploy.factor
extra/hello-world/deploy.factor
extra/id3/id3.factor
extra/images/viewer/viewer.factor
extra/jamshred/deploy.factor
extra/joystick-demo/deploy.factor
extra/key-caps/key-caps.factor
extra/mason/build/build.factor
extra/mason/common/common.factor
extra/mason/email/email-tests.factor
extra/mason/email/email.factor
extra/mason/notify/notify.factor
extra/mason/release/branch/branch.factor
extra/mason/report/report.factor
extra/math/affine-transforms/affine-transforms.factor
extra/maze/deploy.factor
extra/merger/deploy.factor
extra/minneapolis-talk/deploy.factor
extra/modules/remote-loading/authors.txt [deleted file]
extra/modules/remote-loading/remote-loading.factor [deleted file]
extra/modules/remote-loading/summary.txt [deleted file]
extra/modules/rpc-server/authors.txt [deleted file]
extra/modules/rpc-server/rpc-server.factor [deleted file]
extra/modules/rpc-server/summary.txt [deleted file]
extra/modules/rpc/authors.txt [deleted file]
extra/modules/rpc/rpc-docs.factor [deleted file]
extra/modules/rpc/rpc.factor [deleted file]
extra/modules/rpc/summary.txt [deleted file]
extra/modules/uploads/authors.txt [deleted file]
extra/modules/uploads/summary.txt [deleted file]
extra/modules/uploads/uploads.factor [deleted file]
extra/modules/using/authors.txt [deleted file]
extra/modules/using/summary.txt [deleted file]
extra/modules/using/tests/tags.txt [deleted file]
extra/modules/using/tests/test-server.factor [deleted file]
extra/modules/using/tests/tests.factor [deleted file]
extra/modules/using/using-docs.factor [deleted file]
extra/modules/using/using.factor [deleted file]
extra/mongodb/tuple/collection/collection.factor
extra/mongodb/tuple/tuple.factor
extra/nehe/deploy.factor
extra/noise/noise.factor [new file with mode: 0644]
extra/opengl/demo-support/demo-support.factor
extra/poker/poker-docs.factor
extra/poker/poker-tests.factor
extra/poker/poker.factor
extra/poker/summary.txt
extra/project-euler/001/001.factor
extra/project-euler/005/005.factor
extra/project-euler/018/018.factor
extra/project-euler/025/025.factor
extra/project-euler/027/027.factor
extra/project-euler/030/030.factor
extra/project-euler/032/032.factor
extra/project-euler/046/046.factor
extra/project-euler/048/048.factor
extra/project-euler/055/055.factor
extra/project-euler/057/057.factor
extra/project-euler/150/150.factor
extra/project-euler/common/common.factor
extra/random/blum-blum-shub/blum-blum-shub.factor
extra/redis/authors.txt [new file with mode: 0644]
extra/redis/command-writer/authors.txt [new file with mode: 0644]
extra/redis/command-writer/command-writer-tests.factor [new file with mode: 0644]
extra/redis/command-writer/command-writer.factor [new file with mode: 0644]
extra/redis/command-writer/summary.txt [new file with mode: 0644]
extra/redis/redis.factor [new file with mode: 0644]
extra/redis/response-parser/authors.txt [new file with mode: 0644]
extra/redis/response-parser/response-parser-tests.factor [new file with mode: 0644]
extra/redis/response-parser/response-parser.factor [new file with mode: 0644]
extra/redis/response-parser/summary.txt [new file with mode: 0644]
extra/redis/summary.txt [new file with mode: 0644]
extra/reports/noise/noise.factor
extra/spheres/deploy.factor
extra/spider/unique-deque/unique-deque.factor
extra/sudoku/deploy.factor
extra/tar/tar.factor
extra/terrain/deploy.factor [new file with mode: 0644]
extra/terrain/generation/generation.factor [new file with mode: 0644]
extra/terrain/shaders/shaders.factor [new file with mode: 0644]
extra/terrain/terrain.factor [new file with mode: 0644]
extra/tetris/deploy.factor
extra/webapps/wee-url/wee-url.factor
extra/webkit-demo/deploy.factor
unmaintained/modules/remote-loading/authors.txt [new file with mode: 0644]
unmaintained/modules/remote-loading/remote-loading.factor [new file with mode: 0644]
unmaintained/modules/remote-loading/summary.txt [new file with mode: 0644]
unmaintained/modules/rpc-server/authors.txt [new file with mode: 0644]
unmaintained/modules/rpc-server/rpc-server.factor [new file with mode: 0644]
unmaintained/modules/rpc-server/summary.txt [new file with mode: 0644]
unmaintained/modules/rpc/authors.txt [new file with mode: 0644]
unmaintained/modules/rpc/rpc-docs.factor [new file with mode: 0644]
unmaintained/modules/rpc/rpc.factor [new file with mode: 0644]
unmaintained/modules/rpc/summary.txt [new file with mode: 0644]
unmaintained/modules/uploads/authors.txt [new file with mode: 0644]
unmaintained/modules/uploads/summary.txt [new file with mode: 0644]
unmaintained/modules/uploads/uploads.factor [new file with mode: 0644]
unmaintained/modules/using/authors.txt [new file with mode: 0644]
unmaintained/modules/using/summary.txt [new file with mode: 0644]
unmaintained/modules/using/tests/tags.txt [new file with mode: 0644]
unmaintained/modules/using/tests/test-server.factor [new file with mode: 0644]
unmaintained/modules/using/tests/tests.factor [new file with mode: 0644]
unmaintained/modules/using/using-docs.factor [new file with mode: 0644]
unmaintained/modules/using/using.factor [new file with mode: 0644]
vm/Config.windows
vm/alien.cpp
vm/alien.hpp
vm/callstack.cpp
vm/callstack.hpp
vm/code_block.cpp [changed mode: 0644->0755]
vm/code_block.hpp
vm/code_gc.cpp
vm/code_gc.hpp
vm/code_heap.cpp
vm/code_heap.hpp
vm/contexts.cpp
vm/contexts.hpp
vm/cpu-ppc.S
vm/cpu-ppc.hpp
vm/cpu-x86.32.S
vm/cpu-x86.32.hpp
vm/cpu-x86.64.S
vm/cpu-x86.64.hpp [changed mode: 0644->0755]
vm/cpu-x86.hpp
vm/data_gc.cpp
vm/data_gc.hpp
vm/data_heap.cpp [changed mode: 0644->0755]
vm/data_heap.hpp
vm/debug.cpp
vm/debug.hpp
vm/dispatch.cpp [changed mode: 0644->0755]
vm/dispatch.hpp
vm/errors.cpp
vm/errors.hpp
vm/factor.cpp
vm/factor.hpp
vm/ffi_test.c
vm/ffi_test.h
vm/image.cpp
vm/image.hpp
vm/inline_cache.cpp [changed mode: 0644->0755]
vm/inline_cache.hpp
vm/io.cpp
vm/io.hpp
vm/jit.cpp
vm/jit.hpp
vm/layouts.hpp
vm/mach_signal.cpp
vm/mach_signal.hpp
vm/master.hpp [changed mode: 0644->0755]
vm/math.cpp [changed mode: 0644->0755]
vm/math.hpp
vm/os-freebsd.cpp
vm/os-freebsd.hpp
vm/os-genunix.cpp
vm/os-genunix.hpp
vm/os-linux.cpp
vm/os-linux.hpp
vm/os-macosx.hpp
vm/os-netbsd.cpp
vm/os-openbsd.cpp
vm/os-solaris.cpp
vm/os-unix.cpp
vm/os-unix.hpp
vm/os-windows-ce.cpp
vm/os-windows-ce.hpp
vm/os-windows-nt.cpp
vm/os-windows-nt.hpp
vm/os-windows.cpp
vm/os-windows.hpp
vm/primitives.cpp
vm/profiler.cpp
vm/profiler.hpp
vm/quotations.cpp
vm/quotations.hpp
vm/run.hpp
vm/segments.hpp
vm/stacks.hpp
vm/utilities.cpp
vm/utilities.hpp
vm/words.cpp
vm/words.hpp
vm/write_barrier.cpp [changed mode: 0644->0755]
vm/write_barrier.hpp [changed mode: 0644->0755]

index addbe38f0dc032f07322ff7ba50d8c10a033404a..a33a85b218b2f8063897b886bc52e47e95d88988 100755 (executable)
@@ -20,25 +20,18 @@ implementation. It is not an introduction to the language itself.
 
 * Compiling the Factor VM
 
-The Factor runtime is written in GNU C++, and is built with GNU make and
-gcc.
-
 Factor supports various platforms. For an up-to-date list, see
 <http://factorcode.org>.
 
-Factor requires gcc 3.4 or later.
-
-On x86, Factor /will not/ build using gcc 3.3 or earlier.
-
-If you are using gcc 4.3, you might get an unusable Factor binary unless
-you add 'SITE_CFLAGS=-fno-forward-propagate' to the command-line
-arguments for make.
+The Factor VM is written in C++ and uses GNU extensions. When compiling
+with GCC 3.x, boost::unordered_map must be installed. On GCC 4.x, Factor
+uses std::tr1::unordered_map which is shipped as part of GCC.
 
 Run 'make' ('gmake' on *BSD) with no parameters to build the Factor VM.
 
 * Bootstrapping the Factor image
 
-Once you have compiled the Factor runtime, you must bootstrap the Factor
+Once you have compiled the Factor VM, you must bootstrap the Factor
 system using the image that corresponds to your CPU architecture.
 
 Boot images can be obtained from <http://factorcode.org/images/latest/>.
@@ -97,7 +90,7 @@ When compiling Factor, pass the X11=1 parameter:
 
 Then bootstrap with the following switches:
 
-  ./factor -i=boot.<cpu>.image -ui-backend=x11 -ui-text-backend=pango
+  ./factor -i=boot.<cpu>.image -ui-backend=x11
 
 Now if $DISPLAY is set, running ./factor will start the UI.
 
@@ -138,7 +131,7 @@ usage documentation, enter the following in the UI listener:
 The Factor source tree is organized as follows:
 
   build-support/ - scripts used for compiling Factor
-  vm/ - sources for the Factor VM, written in C++
+  vm/ - Factor VM
   core/ - Factor core library
   basis/ - Factor basis library, compiler, tools
   extra/ - more libraries and applications
index 9cd57f61ab5451f21bd7821a7415525f208574b3..df5a5bbba8ea2bc46cfd8ca97f4dfcfc3dc97ce5 100755 (executable)
@@ -259,8 +259,9 @@ M: long-long-type box-return ( type -- )
     [ dup c-setter '[ _ <c-object> [ 0 @ ] keep ] ] bi
     (( value -- c-ptr )) define-inline ;
 
-: c-bool> ( int -- ? )
-    0 = not ; inline
+: >c-bool ( ? -- int ) 1 0 ? ; inline
+
+: c-bool> ( int -- ? ) 0 = not ; inline
 
 : define-primitive-type ( type name -- )
     [ typedef ]
@@ -409,10 +410,10 @@ CONSTANT: primitive-types
     "uchar" define-primitive-type
 
     <c-type>
-        [ alien-unsigned-4 zero? not ] >>getter
-        [ [ 1 0 ? ] 2dip set-alien-unsigned-4 ] >>setter
-        4 >>size
-        4 >>align
+        [ alien-unsigned-1 c-bool> ] >>getter
+        [ [ >c-bool ] 2dip set-alien-unsigned-1 ] >>setter
+        1 >>size
+        1 >>align
         "box_boolean" >>boxer
         "to_boolean" >>unboxer
     "bool" define-primitive-type
old mode 100644 (file)
new mode 100755 (executable)
index 6c18065..0b39bed
@@ -5,7 +5,7 @@ IN: alien.libraries
 
 : dlopen ( path -- dll ) native-string>alien (dlopen) ;
 
-: dlsym ( name dll -- alien ) [ native-string>alien ] dip (dlsym) ;
+: dlsym ( name dll -- alien ) [ string>symbol ] dip (dlsym) ;
 
 SYMBOL: libraries
 
index 9094286575ce78ec4aced1611619f368aaa7ef5d..e962fa7e5937598aa1e125b9139395ae56530a07 100644 (file)
@@ -4,7 +4,7 @@ IN: base64.tests
 
 [ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" ascii encode >base64 base64> ascii decode
 ] unit-test
-[ f ] [ "" ascii encode >base64 base64> ascii decode ] unit-test
+[ "" ] [ "" ascii encode >base64 base64> ascii decode ] unit-test
 [ "a" ] [ "a" ascii encode >base64 base64> ascii decode ] unit-test
 [ "ab" ] [ "ab" ascii encode >base64 base64> ascii decode ] unit-test
 [ "abc" ] [ "abc" ascii encode >base64 base64> ascii decode ] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index 7940703..3aefdec
@@ -41,7 +41,7 @@ nl
 ! which are also quick to compile are replaced by
 ! compiled definitions as soon as possible.
 {
-    roll -roll declare not
+    not
 
     array? hashtable? vector?
     tuple? sbuf? tombstone?
index cad40b63848fda7dd99be8c01a1fbc3f0765c477..92d75604e08c0845afab6ccac8813f0a71124547 100644 (file)
@@ -9,7 +9,7 @@ classes.builtin classes.tuple classes.tuple.private vocabs
 vocabs.loader source-files definitions debugger quotations.private
 sequences.private combinators math.order math.private accessors
 slots.private generic.single.private compiler.units compiler.constants
-fry ;
+fry bootstrap.image.syntax ;
 IN: bootstrap.image
 
 : arch ( os cpu -- arch )
@@ -52,6 +52,9 @@ GENERIC: (eql?) ( obj1 obj2 -- ? )
 
 M: integer (eql?) = ;
 
+M: float (eql?)
+    over float? [ fp-bitwise= ] [ 2drop f ] if ;
+
 M: sequence (eql?)
     over sequence? [
         2dup [ length ] bi@ =
@@ -93,24 +96,19 @@ CONSTANT: -1-offset             9
 
 SYMBOL: sub-primitives
 
-SYMBOL: jit-define-rc
-SYMBOL: jit-define-rt
-SYMBOL: jit-define-offset
+SYMBOL: jit-relocations
 
-: compute-offset ( -- offset )
-    building get length jit-define-rc get rc-absolute-cell = bootstrap-cell 4 ? - ;
+: compute-offset ( rc -- offset )
+    [ building get length ] dip rc-absolute-cell = bootstrap-cell 4 ? - ;
 
 : jit-rel ( rc rt -- )
-    jit-define-rt set
-    jit-define-rc set
-    compute-offset jit-define-offset set ;
+    over compute-offset 3array jit-relocations get push-all ;
 
-: make-jit ( quot -- quad )
+: make-jit ( quot -- jit-data )
     [
+        V{ } clone jit-relocations set
         call( -- )
-        jit-define-rc get
-        jit-define-rt get
-        jit-define-offset get 3array
+        jit-relocations get >array
     ] B{ } make prefix ;
 
 : jit-define ( quot name -- )
@@ -128,98 +126,59 @@ SYMBOL: big-endian
 ! Bootstrap architecture name
 SYMBOL: architecture
 
-! Bootstrap global namesapce
-SYMBOL: bootstrap-global
+RESET
 
 ! Boot quotation, set in stage1.factor
-SYMBOL: bootstrap-boot-quot
+USERENV: bootstrap-boot-quot 20
+
+! Bootstrap global namesapce
+USERENV: bootstrap-global 21
 
 ! JIT parameters
-SYMBOL: jit-prolog
-SYMBOL: jit-primitive-word
-SYMBOL: jit-primitive
-SYMBOL: jit-word-jump
-SYMBOL: jit-word-call
-SYMBOL: jit-push-immediate
-SYMBOL: jit-if-word
-SYMBOL: jit-if-1
-SYMBOL: jit-if-2
-SYMBOL: jit-dip-word
-SYMBOL: jit-dip
-SYMBOL: jit-2dip-word
-SYMBOL: jit-2dip
-SYMBOL: jit-3dip-word
-SYMBOL: jit-3dip
-SYMBOL: jit-execute-word
-SYMBOL: jit-execute-jump
-SYMBOL: jit-execute-call
-SYMBOL: jit-epilog
-SYMBOL: jit-return
-SYMBOL: jit-profiling
-SYMBOL: jit-save-stack
+USERENV: jit-prolog 23
+USERENV: jit-primitive-word 24
+USERENV: jit-primitive 25
+USERENV: jit-word-jump 26
+USERENV: jit-word-call 27
+USERENV: jit-word-special 28
+USERENV: jit-if-word 29
+USERENV: jit-if 30
+USERENV: jit-epilog 31
+USERENV: jit-return 32
+USERENV: jit-profiling 33
+USERENV: jit-push-immediate 34
+USERENV: jit-dip-word 35
+USERENV: jit-dip 36
+USERENV: jit-2dip-word 37
+USERENV: jit-2dip 38
+USERENV: jit-3dip-word 39
+USERENV: jit-3dip 40
+USERENV: jit-execute-word 41
+USERENV: jit-execute-jump 42
+USERENV: jit-execute-call 43
 
 ! PIC stubs
-SYMBOL: pic-load
-SYMBOL: pic-tag
-SYMBOL: pic-hi-tag
-SYMBOL: pic-tuple
-SYMBOL: pic-hi-tag-tuple
-SYMBOL: pic-check-tag
-SYMBOL: pic-check
-SYMBOL: pic-hit
-SYMBOL: pic-miss-word
+USERENV: pic-load 47
+USERENV: pic-tag 48
+USERENV: pic-hi-tag 49
+USERENV: pic-tuple 50
+USERENV: pic-hi-tag-tuple 51
+USERENV: pic-check-tag 52
+USERENV: pic-check 53
+USERENV: pic-hit 54
+USERENV: pic-miss-word 55
+USERENV: pic-miss-tail-word 56
 
 ! Megamorphic dispatch
-SYMBOL: mega-lookup
-SYMBOL: mega-lookup-word
-SYMBOL: mega-miss-word
+USERENV: mega-lookup 57
+USERENV: mega-lookup-word 58
+USERENV: mega-miss-word 59
 
 ! Default definition for undefined words
-SYMBOL: undefined-quot
-
-: userenvs ( -- assoc )
-    H{
-        { bootstrap-boot-quot 20 }
-        { bootstrap-global 21 }
-        { jit-prolog 23 }
-        { jit-primitive-word 24 }
-        { jit-primitive 25 }
-        { jit-word-jump 26 }
-        { jit-word-call 27 }
-        { jit-if-word 28 }
-        { jit-if-1 29 }
-        { jit-if-2 30 }
-        { jit-epilog 33 }
-        { jit-return 34 }
-        { jit-profiling 35 }
-        { jit-push-immediate 36 }
-        { jit-save-stack 38 }
-        { jit-dip-word 39 }
-        { jit-dip 40 }
-        { jit-2dip-word 41 }
-        { jit-2dip 42 }
-        { jit-3dip-word 43 }
-        { jit-3dip 44 }
-        { jit-execute-word 45 }
-        { jit-execute-jump 46 }
-        { jit-execute-call 47 }
-        { pic-load 48 }
-        { pic-tag 49 }
-        { pic-hi-tag 50 }
-        { pic-tuple 51 }
-        { pic-hi-tag-tuple 52 }
-        { pic-check-tag 53 }
-        { pic-check 54 }
-        { pic-hit 55 }
-        { pic-miss-word 56 }
-        { mega-lookup 57 }
-        { mega-lookup-word 58 }
-        { mega-miss-word 59 }
-        { undefined-quot 60 }
-    } ; inline
+USERENV: undefined-quot 60
 
 : userenv-offset ( symbol -- n )
-    userenvs at header-size + ;
+    userenvs get at header-size + ;
 
 : emit ( cell -- ) image get push ;
 
@@ -351,7 +310,8 @@ M: f '
                     [ vocabulary>> , ]
                     [ def>> , ]
                     [ props>> , ]
-                    [ direct-entry-def>> , ] ! direct-entry-def
+                    [ pic-def>> , ]
+                    [ pic-tail-def>> , ]
                     [ drop 0 , ] ! count
                     [ word-sub-primitive , ]
                     [ drop 0 , ] ! xt
@@ -510,11 +470,7 @@ M: quotation '
         class<=-cache class-not-cache classes-intersect-cache
         class-and-cache class-or-cache next-method-quot-cache
     } [ H{ } clone ] H{ } map>assoc assoc-union
-    bootstrap-global set
-    bootstrap-global emit-userenv ;
-
-: emit-boot-quot ( -- )
-    bootstrap-boot-quot emit-userenv ;
+    bootstrap-global set ;
 
 : emit-jit-data ( -- )
     \ if jit-if-word set
@@ -524,46 +480,13 @@ M: quotation '
     \ 3dip jit-3dip-word set
     \ (execute) jit-execute-word set
     \ inline-cache-miss \ pic-miss-word set
+    \ inline-cache-miss-tail \ pic-miss-tail-word set
     \ mega-cache-lookup \ mega-lookup-word set
     \ mega-cache-miss \ mega-miss-word set
-    [ undefined ] undefined-quot set
-    {
-        jit-prolog
-        jit-primitive-word
-        jit-primitive
-        jit-word-jump
-        jit-word-call
-        jit-push-immediate
-        jit-if-word
-        jit-if-1
-        jit-if-2
-        jit-dip-word
-        jit-dip
-        jit-2dip-word
-        jit-2dip
-        jit-3dip-word
-        jit-3dip
-        jit-execute-word
-        jit-execute-jump
-        jit-execute-call
-        jit-epilog
-        jit-return
-        jit-profiling
-        jit-save-stack
-        pic-load
-        pic-tag
-        pic-hi-tag
-        pic-tuple
-        pic-hi-tag-tuple
-        pic-check-tag
-        pic-check
-        pic-hit
-        pic-miss-word
-        mega-lookup
-        mega-lookup-word
-        mega-miss-word
-        undefined-quot
-    } [ emit-userenv ] each ;
+    [ undefined ] undefined-quot set ;
+
+: emit-userenvs ( -- )
+    userenvs get keys [ emit-userenv ] each ;
 
 : fixup-header ( -- )
     heap-size data-heap-size-offset fixup ;
@@ -580,8 +503,8 @@ M: quotation '
     emit-jit-data
     "Serializing global namespace..." print flush
     emit-global
-    "Serializing boot quotation..." print flush
-    emit-boot-quot
+    "Serializing user environment..." print flush
+    emit-userenvs
     "Performing word fixups..." print flush
     fixup-words
     "Performing header fixups..." print flush
diff --git a/basis/bootstrap/image/syntax/authors.txt b/basis/bootstrap/image/syntax/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/bootstrap/image/syntax/syntax.factor b/basis/bootstrap/image/syntax/syntax.factor
new file mode 100644 (file)
index 0000000..29dc097
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: parser kernel namespaces assocs words.symbol ;
+IN: bootstrap.image.syntax
+
+SYMBOL: userenvs
+
+SYNTAX: RESET H{ } clone userenvs set-global ;
+
+SYNTAX: USERENV:
+    CREATE-WORD scan-word
+    [ swap userenvs get set-at ]
+    [ drop define-symbol ]
+    2bi ;
\ No newline at end of file
index 0ae4328446c1d1e4aa8295c7165f70845277f75b..76675f94132ac32985cf42d67279b310ea25bcb7 100644 (file)
@@ -9,6 +9,9 @@ SYMBOL: bytes-read
 : calculate-pad-length ( length -- length' )
     [ 56 < 55 119 ? ] keep - ;
 
+: calculate-pad-length-long ( length -- length' )
+    [ 120 < 119 247 ? ] keep - ;
+
 : pad-last-block ( str big-endian? length -- str )
     [
         [ % ] 2dip HEX: 80 ,
index 2f4e3c51c4a8c49f1b28eabe96de6c04aed7c394..c14ea5a98db8a776202d530926ec6c26f33803ee 100644 (file)
@@ -1,7 +1,42 @@
-USING: arrays kernel math namespaces sequences tools.test checksums.sha2 checksums ;
-[ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ] [ "" sha-256 checksum-bytes hex-string ] unit-test
-[ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" ] [ "abc" sha-256 checksum-bytes hex-string ] unit-test
-[ "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" ] [ "message digest" sha-256 checksum-bytes hex-string ] unit-test
-[ "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" ] [ "abcdefghijklmnopqrstuvwxyz" sha-256 checksum-bytes hex-string ] unit-test
-[ "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" sha-256 checksum-bytes hex-string ] unit-test
-[ "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" sha-256 checksum-bytes hex-string ] unit-test
+USING: arrays kernel math namespaces sequences tools.test
+checksums.sha2 checksums ;
+IN: checksums.sha2.tests
+
+: test-checksum ( text identifier -- checksum )
+    checksum-bytes hex-string ;
+
+[ "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" ]
+[
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+    sha-224 test-checksum
+] unit-test
+
+[ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ]
+[ "" sha-256 test-checksum ] unit-test
+
+[ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" ]
+[ "abc" sha-256 test-checksum ] unit-test
+
+[ "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" ]
+[ "message digest" sha-256 test-checksum ] unit-test
+
+[ "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" ]
+[ "abcdefghijklmnopqrstuvwxyz" sha-256 test-checksum ] unit-test
+
+[ "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0" ]
+[
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    sha-256 test-checksum
+] unit-test
+
+[ "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" ]
+[
+    "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+    sha-256 test-checksum
+] unit-test
+
+
+
+
+! [ "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" ]
+! [ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" sha-512 test-checksum ] unit-test
index 3b092a78dea62f9e8d5c595b2758c9f49daa16d0..12e32f6c693e4314b0914e313ff097bfa51c8449 100644 (file)
@@ -2,12 +2,27 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel splitting grouping math sequences namespaces make
 io.binary math.bitwise checksums checksums.common
-sbufs strings ;
+sbufs strings combinators.smart math.ranges fry combinators
+accessors locals ;
 IN: checksums.sha2
 
-<PRIVATE
+SINGLETON: sha-224
+SINGLETON: sha-256
+
+INSTANCE: sha-224 checksum
+INSTANCE: sha-256 checksum
+
+TUPLE: sha2-state K H word-size block-size ;
+
+TUPLE: sha2-short < sha2-state ;
 
-SYMBOLS: vars M K H S0 S1 process-M word-size block-size ;
+TUPLE: sha2-long < sha2-state ;
+
+TUPLE: sha-224-state < sha2-short ;
+
+TUPLE: sha-256-state < sha2-short ;
+
+<PRIVATE
 
 CONSTANT: a 0
 CONSTANT: b 1
@@ -18,13 +33,43 @@ CONSTANT: f 5
 CONSTANT: g 6
 CONSTANT: h 7
 
-: initial-H-256 ( -- seq )
+CONSTANT: initial-H-224
+    {
+        HEX: c1059ed8 HEX: 367cd507 HEX: 3070dd17 HEX: f70e5939
+        HEX: ffc00b31 HEX: 68581511 HEX: 64f98fa7 HEX: befa4fa4
+    }
+
+CONSTANT: initial-H-256
     {
         HEX: 6a09e667 HEX: bb67ae85 HEX: 3c6ef372 HEX: a54ff53a
         HEX: 510e527f HEX: 9b05688c HEX: 1f83d9ab HEX: 5be0cd19
-    } ;
+    }
 
-: K-256 ( -- seq )
+CONSTANT: initial-H-384
+    {
+        HEX: cbbb9d5dc1059ed8
+        HEX: 629a292a367cd507
+        HEX: 9159015a3070dd17
+        HEX: 152fecd8f70e5939
+        HEX: 67332667ffc00b31
+        HEX: 8eb44a8768581511
+        HEX: db0c2e0d64f98fa7
+        HEX: 47b5481dbefa4fa4
+    }
+
+CONSTANT: initial-H-512
+    {
+        HEX: 6a09e667f3bcc908
+        HEX: bb67ae8584caa73b
+        HEX: 3c6ef372fe94f82b
+        HEX: a54ff53a5f1d36f1
+        HEX: 510e527fade682d1
+        HEX: 9b05688c2b3e6c1f
+        HEX: 1f83d9abfb41bd6b
+        HEX: 5be0cd19137e2179
+    }
+
+CONSTANT: K-256
     {
         HEX: 428a2f98 HEX: 71374491 HEX: b5c0fbcf HEX: e9b5dba5
         HEX: 3956c25b HEX: 59f111f1 HEX: 923f82a4 HEX: ab1c5ed5
@@ -42,62 +87,163 @@ CONSTANT: h 7
         HEX: 391c0cb3 HEX: 4ed8aa4a HEX: 5b9cca4f HEX: 682e6ff3
         HEX: 748f82ee HEX: 78a5636f HEX: 84c87814 HEX: 8cc70208
         HEX: 90befffa HEX: a4506ceb HEX: bef9a3f7 HEX: c67178f2
-    } ;
+    }
+
+CONSTANT: K-384
+    {
+
+        HEX: 428a2f98d728ae22 HEX: 7137449123ef65cd HEX: b5c0fbcfec4d3b2f HEX: e9b5dba58189dbbc 
+        HEX: 3956c25bf348b538 HEX: 59f111f1b605d019 HEX: 923f82a4af194f9b HEX: ab1c5ed5da6d8118 
+        HEX: d807aa98a3030242 HEX: 12835b0145706fbe HEX: 243185be4ee4b28c HEX: 550c7dc3d5ffb4e2
+        HEX: 72be5d74f27b896f HEX: 80deb1fe3b1696b1 HEX: 9bdc06a725c71235 HEX: c19bf174cf692694 
+        HEX: e49b69c19ef14ad2 HEX: efbe4786384f25e3 HEX: 0fc19dc68b8cd5b5 HEX: 240ca1cc77ac9c65 
+        HEX: 2de92c6f592b0275 HEX: 4a7484aa6ea6e483 HEX: 5cb0a9dcbd41fbd4 HEX: 76f988da831153b5 
+        HEX: 983e5152ee66dfab HEX: a831c66d2db43210 HEX: b00327c898fb213f HEX: bf597fc7beef0ee4 
+        HEX: c6e00bf33da88fc2 HEX: d5a79147930aa725 HEX: 06ca6351e003826f HEX: 142929670a0e6e70 
+        HEX: 27b70a8546d22ffc HEX: 2e1b21385c26c926 HEX: 4d2c6dfc5ac42aed HEX: 53380d139d95b3df 
+        HEX: 650a73548baf63de HEX: 766a0abb3c77b2a8 HEX: 81c2c92e47edaee6 HEX: 92722c851482353b 
+        HEX: a2bfe8a14cf10364 HEX: a81a664bbc423001 HEX: c24b8b70d0f89791 HEX: c76c51a30654be30 
+        HEX: d192e819d6ef5218 HEX: d69906245565a910 HEX: f40e35855771202a HEX: 106aa07032bbd1b8 
+        HEX: 19a4c116b8d2d0c8 HEX: 1e376c085141ab53 HEX: 2748774cdf8eeb99 HEX: 34b0bcb5e19b48a8 
+        HEX: 391c0cb3c5c95a63 HEX: 4ed8aa4ae3418acb HEX: 5b9cca4f7763e373 HEX: 682e6ff3d6b2b8a3 
+        HEX: 748f82ee5defb2fc HEX: 78a5636f43172f60 HEX: 84c87814a1f0ab72 HEX: 8cc702081a6439ec 
+        HEX: 90befffa23631e28 HEX: a4506cebde82bde9 HEX: bef9a3f7b2c67915 HEX: c67178f2e372532b 
+        HEX: ca273eceea26619c HEX: d186b8c721c0c207 HEX: eada7dd6cde0eb1e HEX: f57d4f7fee6ed178 
+        HEX: 06f067aa72176fba HEX: 0a637dc5a2c898a6 HEX: 113f9804bef90dae HEX: 1b710b35131c471b 
+        HEX: 28db77f523047d84 HEX: 32caab7b40c72493 HEX: 3c9ebe0a15c9bebc HEX: 431d67c49c100d4c 
+        HEX: 4cc5d4becb3e42b6 HEX: 597f299cfc657e2a HEX: 5fcb6fab3ad6faec HEX: 6c44198c4a475817
+    }
+
+ALIAS: K-512 K-384
 
 : s0-256 ( x -- x' )
-    [ -7 bitroll-32 ] keep
-    [ -18 bitroll-32 ] keep
-    -3 shift bitxor bitxor ; inline
+    [
+        [ -7 bitroll-32 ]
+        [ -18 bitroll-32 ]
+        [ -3 shift ] tri
+    ] [ bitxor ] reduce-outputs ; inline
 
 : s1-256 ( x -- x' )
-    [ -17 bitroll-32 ] keep
-    [ -19 bitroll-32 ] keep
-    -10 shift bitxor bitxor ; inline
-
-: process-M-256 ( seq n -- )
-    [ 16 - swap nth ] 2keep
-    [ 15 - swap nth s0-256 ] 2keep
-    [ 7 - swap nth ] 2keep
-    [ 2 - swap nth s1-256 ] 2keep
-    [ + + w+ ] 2dip swap set-nth ; inline
-
-: prepare-message-schedule ( seq -- w-seq )
-    word-size get group [ be> ] map block-size get 0 pad-tail
-    dup 16 64 dup <slice> [
-        process-M-256
-    ] with each ;
+    [
+        [ -17 bitroll-32 ]
+        [ -19 bitroll-32 ]
+        [ -10 shift ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: S0-256 ( x -- x' )
+    [
+        [ -2 bitroll-32 ]
+        [ -13 bitroll-32 ]
+        [ -22 bitroll-32 ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: S1-256 ( x -- x' )
+    [
+        [ -6 bitroll-32 ]
+        [ -11 bitroll-32 ]
+        [ -25 bitroll-32 ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: s0-512 ( x -- x' )
+    [
+        [ -1 bitroll-64 ]
+        [ -8 bitroll-64 ]
+        [ -7 shift ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: s1-512 ( x -- x' )
+    [
+        [ -19 bitroll-64 ]
+        [ -61 bitroll-64 ]
+        [ -6 shift ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: S0-512 ( x -- x' )
+    [
+        [ -28 bitroll-64 ]
+        [ -34 bitroll-64 ]
+        [ -39 bitroll-64 ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: S1-512 ( x -- x' )
+    [
+        [ -14 bitroll-64 ]
+        [ -18 bitroll-64 ]
+        [ -41 bitroll-64 ] tri
+    ] [ bitxor ] reduce-outputs ; inline
+
+: process-M-256 ( n seq -- )
+    {
+        [ [ 16 - ] dip nth ]
+        [ [ 15 - ] dip nth s0-256 ]
+        [ [ 7 - ] dip nth ]
+        [ [ 2 - ] dip nth s1-256 w+ w+ w+ ]
+        [ ]
+    } 2cleave set-nth ; inline
+
+: process-M-512 ( n seq -- )
+    {
+        [ [ 16 - ] dip nth ]
+        [ [ 15 - ] dip nth s0-512 ]
+        [ [ 7 - ] dip nth ]
+        [ [ 2 - ] dip nth s1-512 w+ w+ w+ ]
+        [ ]
+    } 2cleave set-nth ; inline
 
 : ch ( x y z -- x' )
-    [ bitxor bitand ] keep bitxor ;
+    [ bitxor bitand ] keep bitxor ; inline
 
 : maj ( x y z -- x' )
-    [ [ bitand ] 2keep bitor ] dip bitand bitor ;
+    [ [ bitand ] [ bitor ] 2bi ] dip bitand bitor ; inline
 
-: S0-256 ( x -- x' )
-    [ -2 bitroll-32 ] keep
-    [ -13 bitroll-32 ] keep
-    -22 bitroll-32 bitxor bitxor ; inline
+: slice3 ( n seq -- a b c )
+    [ dup 3 + ] dip <slice> first3 ; inline
 
-: S1-256 ( x -- x' )
-    [ -6 bitroll-32 ] keep
-    [ -11 bitroll-32 ] keep
-    -25 bitroll-32 bitxor bitxor ; inline
+GENERIC: pad-initial-bytes ( string sha2 -- padded-string )
 
-: slice3 ( n seq -- a b c ) [ dup 3 + ] dip <slice> first3 ; inline
+M: sha2-short pad-initial-bytes ( string sha2 -- padded-string )
+    drop
+    dup [
+        HEX: 80 ,
+        length
+        [ 64 mod calculate-pad-length 0 <string> % ]
+        [ 3 shift 8 >be % ] bi
+    ] "" make append ;
 
-: T1 ( W n -- T1 )
-    [ swap nth ] keep
-    K get nth +
-    e vars get slice3 ch +
-    e vars get nth S1-256 +
-    h vars get nth w+ ;
+M: sha2-long pad-initial-bytes ( string sha2 -- padded-string )
+    drop dup [
+        HEX: 80 ,
+        length
+        [ 128 mod calculate-pad-length-long 0 <string> % ]
+        [ 3 shift 8 >be % ] bi
+    ] "" make append ;
+
+: seq>byte-array ( seq n -- string )
+    '[ _ >be ] map B{ } join ;
+
+:: T1-256 ( n M H sha2 -- T1 )
+    n M nth
+    n sha2 K>> nth +
+    e H slice3 ch w+
+    e H nth S1-256 w+
+    h H nth w+ ; inline
 
-: T2 ( -- T2 )
-    a vars get nth S0-256
-    a vars get slice3 maj w+ ;
+: T2-256 ( H -- T2 )
+    [ a swap nth S0-256 ]
+    [ a swap slice3 maj w+ ] bi ; inline
 
-: update-vars ( T1 T2 -- )
-    vars get
+:: T1-512 ( n M H sha2 -- T1 )
+    n M nth
+    n sha2 K>> nth +
+    e H slice3 ch w+
+    e H nth S1-512 w+
+    h H nth w+ ; inline
+
+: T2-512 ( H -- T2 )
+    [ a swap nth S0-512 ]
+    [ a swap slice3 maj w+ ] bi ; inline
+
+: update-H ( T1 T2 H -- )
     h g pick exchange
     g f pick exchange
     f e pick exchange
@@ -105,42 +251,56 @@ CONSTANT: h 7
     d c pick exchange
     c b pick exchange
     b a pick exchange
-    [ w+ a ] dip set-nth ;
+    [ w+ a ] dip set-nth ; inline
 
-: process-chunk ( M -- )
-    H get clone vars set
-    prepare-message-schedule block-size get [
-        T1 T2 update-vars
-    ] with each vars get H get [ w+ ] 2map H set ;
+: prepare-message-schedule ( seq sha2 -- w-seq )
+    [ word-size>> <sliced-groups> [ be> ] map ]
+    [
+        block-size>> [ 0 pad-tail 16 ] keep [a,b) over
+        '[ _ process-M-256 ] each
+    ] bi ; inline
 
-: seq>byte-array ( n seq -- string )
-    [ swap [ >be % ] curry each ] B{ } make ;
+:: process-chunk ( M block-size cloned-H sha2 -- )
+    block-size [
+        M cloned-H sha2 T1-256
+        cloned-H T2-256
+        cloned-H update-H
+    ] each
+    cloned-H sha2 H>> [ w+ ] 2map sha2 (>>H) ; inline
 
-: preprocess-plaintext ( string big-endian? -- padded-string )
-    #! pad 0x80 then 00 til 8 bytes left, then 64bit length in bits
-    [ >sbuf ] dip over [
-        HEX: 80 ,
-        dup length HEX: 3f bitand
-        calculate-pad-length 0 <string> %
-        length 3 shift 8 rot [ >be ] [ >le ] if %
-    ] "" make over push-all ;
+: sha2-steps ( sliced-groups state -- )
+    '[
+        _
+        [ prepare-message-schedule ]
+        [ [ block-size>> ] [ H>> clone ] [ ] tri process-chunk ] bi
+    ] each ;
 
-: byte-array>sha2 ( byte-array -- string )
-    t preprocess-plaintext
-    block-size get group [ process-chunk ] each
-    4 H get seq>byte-array ;
+: byte-array>sha2 ( bytes state -- )
+    [ [ pad-initial-bytes ] [ nip block-size>> ] 2bi <sliced-groups> ]
+    [ sha2-steps ] bi ;
 
-PRIVATE>
+: <sha-224-state> ( -- sha2-state )
+    sha-224-state new
+        K-256 >>K
+        initial-H-224 >>H
+        4 >>word-size
+        64 >>block-size ;
 
-SINGLETON: sha-256
+: <sha-256-state> ( -- sha2-state )
+    sha-256-state new
+        K-256 >>K
+        initial-H-256 >>H
+        4 >>word-size
+        64 >>block-size ;
 
-INSTANCE: sha-256 checksum
+PRIVATE>
+
+M: sha-224 checksum-bytes
+    drop <sha-224-state>
+    [ byte-array>sha2 ]
+    [ H>> 7 head 4 seq>byte-array ] bi ;
 
 M: sha-256 checksum-bytes
-    drop [
-        K-256 K set
-        initial-H-256 H set
-        4 word-size set
-        64 block-size set
-        byte-array>sha2
-    ] with-scope ;
+    drop <sha-256-state>
+    [ byte-array>sha2 ]
+    [ H>> 4 seq>byte-array ] bi ;
index 8b33986fc2864a938bfe35497118987fb811ebf5..66093645c1d40abdd58a8d2dc284c5299365fbee 100644 (file)
@@ -14,7 +14,7 @@ NSApplicationDelegateReplyCancel
 NSApplicationDelegateReplyFailure ;
 
 : with-autorelease-pool ( quot -- )
-    NSAutoreleasePool -> new slip -> release ; inline
+    NSAutoreleasePool -> new [ call ] [ -> release ] bi* ; inline
 
 : NSApp ( -- app ) NSApplication -> sharedApplication ;
 
index 3e933e66430a231cf6794b5c9374af1a21180d4c..b78bb020d0cf6140229f009f1a27ca15e76138e9 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2006 Slava Pestov
+! Copyright (C) 2006, 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: compiler io kernel cocoa.runtime cocoa.subclassing
 cocoa.messages cocoa.types sequences words vocabs parser
@@ -27,22 +27,16 @@ SYMBOL: frameworks
 
 frameworks [ V{ } clone ] initialize
 
-[ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook
+[ frameworks get [ load-framework ] each ] "cocoa" add-init-hook
 
 SYNTAX: FRAMEWORK: scan [ load-framework ] [ frameworks get push ] bi ;
 
 SYNTAX: IMPORT: scan [ ] import-objc-class ;
 
-"Compiling Objective C bridge..." print
+"Importing Cocoa classes..." print
 
 "cocoa.classes" create-vocab drop
 
-{
-    "cocoa" "cocoa.runtime" "cocoa.messages" "cocoa.subclassing"
-} [ words ] map concat compile
-
-"Importing Cocoa classes..." print
-
 [
     {
         "NSApplication"
index 65bb2c02ef19fd372b1f9d56f01ea4c7498837cb..fdd4ba81d75d6e88ef1dfdc46c6c22b520cf61fa 100644 (file)
@@ -68,7 +68,7 @@ MACRO: (send) ( selector super? -- quot )
     [ dup lookup-method ] dip
     [ make-prepare-send ] 2keep
     super-message-senders message-senders ? get at
-    '[ _ call _ execute ] ;
+    1quotation append ;
 
 : send ( receiver args... selector -- return... ) f (send) ; inline
 
index 31b59a6eacdfde285975d86f2cafe6a710f6ef65..ceb097bb3adc50749915272b3d82af74b8a56a80 100644 (file)
@@ -4,7 +4,7 @@
 USING: strings arrays hashtables assocs sequences fry macros
 cocoa.messages cocoa.classes cocoa.application cocoa kernel
 namespaces io.backend math cocoa.enumeration byte-arrays
-combinators alien.c-types words core-foundation
+combinators alien.c-types words core-foundation quotations
 core-foundation.data core-foundation.utilities ;
 IN: cocoa.plists
 
@@ -41,10 +41,16 @@ DEFER: plist>
     *void* [ -> release "read-plist failed" throw ] when* ;
 
 MACRO: objc-class-case ( alist -- quot )
-    [ [ '[ dup _ execute -> isKindOfClass: c-bool> ] ] dip ] assoc-map '[ _ cond ] ;
+    [
+        dup callable?
+        [ first2 [ '[ dup _ execute -> isKindOfClass: c-bool> ] ] dip 2array ]
+        unless
+    ] map '[ _ cond ] ;
 
 PRIVATE>
 
+ERROR: invalid-plist-object object ;
+
 : plist> ( plist -- value )
     {
         { NSString [ (plist-NSString>) ] }
@@ -53,6 +59,7 @@ PRIVATE>
         { NSArray [ (plist-NSArray>) ] }
         { NSDictionary [ (plist-NSDictionary>) ] }
         { NSObject [ ] }
+        [ invalid-plist-object ]
     } objc-class-case ;
 
 : read-plist ( path -- assoc )
index 826fa87b739b09f34910d2b81f739b0b4b8e06f5..c7b67b72b4d0bc01ffdf3850927c902ea321862b 100755 (executable)
@@ -88,7 +88,7 @@ M: ##call generate-insn
     word>> dup sub-primitive>>
     [ first % ] [ [ add-call ] [ %call ] bi ] ?if ;
 
-M: ##jump generate-insn word>> [ add-call ] [ %jump-label ] bi ;
+M: ##jump generate-insn word>> [ add-call ] [ %jump ] bi ;
 
 M: ##return generate-insn drop %return ;
 
@@ -444,8 +444,7 @@ TUPLE: callback-context ;
 
 : do-callback ( quot token -- )
     init-catchstack
-    dup 2 setenv
-    slip
+    [ 2 setenv call ] keep
     wait-to-return ; inline
 
 : callback-return-quot ( ctype -- quot )
index 99f258d93c618faa0f143b9f575c59a23792b144..d0c874feb0cd7116b46c7230b2422eafcfcf8d11 100755 (executable)
@@ -56,8 +56,11 @@ SYMBOL: literal-table
 : rel-word ( word class -- )
     [ add-literal ] dip rt-xt rel-fixup ;
 
-: rel-word-direct ( word class -- )
-    [ add-literal ] dip rt-xt-direct rel-fixup ;
+: rel-word-pic ( word class -- )
+    [ add-literal ] dip rt-xt-pic rel-fixup ;
+
+: rel-word-pic-tail ( word class -- )
+    [ add-literal ] dip rt-xt-pic-tail rel-fixup ;
 
 : rel-primitive ( word class -- )
     [ def>> first add-literal ] dip rt-primitive rel-fixup ;
index e418f0ef608320cccd9d7e36002539568cbfa658..01e58461ffedf85b250b979f51def43051a68971 100644 (file)
@@ -112,19 +112,18 @@ M: predicate-engine-word no-compile? "owner-generic" word-prop no-compile? ;
     } cond ;
 
 : optimize? ( word -- ? )
-    {
-        [ predicate-engine-word? ]
-        [ contains-breakpoints? ]
-        [ single-generic? ]
-    } 1|| not ;
+    { [ predicate-engine-word? ] [ single-generic? ] } 1|| not ;
+
+: contains-breakpoints? ( -- ? )
+    dependencies get keys [ "break?" word-prop ] any? ;
 
 : frontend ( word -- nodes )
     #! If the word contains breakpoints, don't optimize it, since
     #! the walker does not support this.
-    dup optimize?
-    [ [ build-tree ] [ deoptimize ] recover optimize-tree ]
-    [ dup def>> deoptimize-with ]
-    if ;
+    dup optimize? [
+        [ [ build-tree ] [ deoptimize ] recover optimize-tree ] keep
+        contains-breakpoints? [ nip dup def>> deoptimize-with ] [ drop ] if
+    ] [ dup def>> deoptimize-with ] if ;
 
 : compile-dependency ( word -- )
     #! If a word calls an unoptimized word, try to compile the callee.
index 2f0494b58aecbfb64f38a46384472420faa6c629..6b383388ef6574c5d6d060400b47f2242273518f 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math kernel layouts system strings words quotations byte-arrays
-alien arrays ;
+alien arrays literals sequences ;
 IN: compiler.constants
 
 ! These constants must match vm/memory.h
@@ -14,42 +14,42 @@ CONSTANT: deck-bits 18
 : float-offset ( -- n ) 8 float tag-number - ; inline
 : string-offset ( -- n ) 4 bootstrap-cells string tag-number - ; inline
 : string-aux-offset ( -- n ) 2 bootstrap-cells string tag-number - ; inline
-: profile-count-offset ( -- n ) 7 bootstrap-cells \ word tag-number - ; inline
+: profile-count-offset ( -- n ) 8 bootstrap-cells \ word tag-number - ; inline
 : byte-array-offset ( -- n ) 2 bootstrap-cells byte-array tag-number - ; inline
 : alien-offset ( -- n ) 3 bootstrap-cells alien tag-number - ; inline
 : underlying-alien-offset ( -- n ) bootstrap-cell alien tag-number - ; inline
 : tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ; inline
-: word-xt-offset ( -- n ) 9 bootstrap-cells \ word tag-number - ; inline
+: word-xt-offset ( -- n ) 10 bootstrap-cells \ word tag-number - ; inline
 : quot-xt-offset ( -- n ) 5 bootstrap-cells quotation tag-number - ; inline
-: word-code-offset ( -- n ) 10 bootstrap-cells \ word tag-number - ; inline
+: word-code-offset ( -- n ) 11 bootstrap-cells \ word tag-number - ; inline
 : array-start-offset ( -- n ) 2 bootstrap-cells array tag-number - ; inline
-: compiled-header-size ( -- n ) 5 bootstrap-cells ; inline
+: compiled-header-size ( -- n ) 4 bootstrap-cells ; inline
 
 ! Relocation classes
-CONSTANT: rc-absolute-cell    0
-CONSTANT: rc-absolute         1
-CONSTANT: rc-relative         2
+CONSTANT: rc-absolute-cell 0
+CONSTANT: rc-absolute 1
+CONSTANT: rc-relative 2
 CONSTANT: rc-absolute-ppc-2/2 3
-CONSTANT: rc-relative-ppc-2   4
-CONSTANT: rc-relative-ppc-3   5
-CONSTANT: rc-relative-arm-3   6
-CONSTANT: rc-indirect-arm     7
-CONSTANT: rc-indirect-arm-pc  8
+CONSTANT: rc-absolute-ppc-2 4
+CONSTANT: rc-relative-ppc-2 5
+CONSTANT: rc-relative-ppc-3 6
+CONSTANT: rc-relative-arm-3 7
+CONSTANT: rc-indirect-arm 8
+CONSTANT: rc-indirect-arm-pc 9
 
 ! Relocation types
-CONSTANT: rt-primitive   0
-CONSTANT: rt-dlsym       1
-CONSTANT: rt-dispatch    2
-CONSTANT: rt-xt          3
-CONSTANT: rt-xt-direct   4
-CONSTANT: rt-here        5
-CONSTANT: rt-this        6
-CONSTANT: rt-immediate   7
-CONSTANT: rt-stack-chain 8
-CONSTANT: rt-untagged    9
+CONSTANT: rt-primitive 0
+CONSTANT: rt-dlsym 1
+CONSTANT: rt-dispatch 2
+CONSTANT: rt-xt 3
+CONSTANT: rt-xt-pic 4
+CONSTANT: rt-xt-pic-tail 5
+CONSTANT: rt-here 6
+CONSTANT: rt-this 7
+CONSTANT: rt-immediate 8
+CONSTANT: rt-stack-chain 9
+CONSTANT: rt-untagged 10
+CONSTANT: rt-megamorphic-cache-hits 11
 
 : rc-absolute? ( n -- ? )
-    [ rc-absolute-ppc-2/2 = ]
-    [ rc-absolute-cell = ]
-    [ rc-absolute = ]
-    tri or or ;
+    ${ rc-absolute-ppc-2/2 rc-absolute-cell rc-absolute } member? ;
index 42ed90d64ad0a7d85d1672b774585e6b15b3d5cf..f7f24433d7b88823a825beb288a380c791fd33d0 100755 (executable)
@@ -588,3 +588,16 @@ FUNCTION: complex-float ffi_test_47 ( complex-float x, complex-double y ) ;
     C{ 1.0 2.0 }
     C{ 1.5 1.0 } ffi_test_47
 ] unit-test
+
+! Reported by jedahu
+C-STRUCT: bool-field-test
+   { "char*" "name" }
+   { "bool"  "on" }
+   { "short" "parents" } ;
+
+FUNCTION: short ffi_test_48 ( bool-field-test x ) ;
+
+[ 123 ] [
+    "bool-field-test" <c-object> 123 over set-bool-field-test-parents
+    ffi_test_48
+] unit-test
\ No newline at end of file
index 32611ba87a1d36ba1386f76d2ee958552da592a0..b541e19f34bf6c904ad30db38bb56843b604677f 100644 (file)
@@ -33,7 +33,7 @@ IN: compiler.tests.curry
 ] unit-test
 
 : foobar ( quot: ( -- ) -- )
-    dup slip swap [ foobar ] [ drop ] if ; inline recursive
+    [ call ] keep swap [ foobar ] [ drop ] if ; inline recursive
 
 [ ] [ [ [ f ] foobar ] compile-call ] unit-test
 
index f19a950711e1993f6b42d3f8e9d6e0df34fdf38a..fa1248435bf1806a9aa48f450ccb7d8fdb8af44f 100644 (file)
@@ -389,4 +389,10 @@ DEFER: loop-bbb
 
 [ f ] [ \ broken-declaration optimized? ] unit-test
 
-[ ] [ [ \ broken-declaration forget ] with-compilation-unit ] unit-test
\ No newline at end of file
+[ ] [ [ \ broken-declaration forget ] with-compilation-unit ] unit-test
+
+! Modular arithmetic bug
+: modular-arithmetic-bug ( a -- b ) >integer 256 mod ;
+
+[ 1 ] [ 257 modular-arithmetic-bug ] unit-test
+[ -10 ] [ -10 modular-arithmetic-bug ] unit-test
\ No newline at end of file
index 37cc1f05da8fe83c8b8b2e26b5f16c838a293d6b..00325f5a72184ee5ef7024835ef35ce373f06060 100644 (file)
@@ -65,5 +65,3 @@ PRIVATE>
         ] [ dup inference-error? [ drop f ] [ rethrow ] if ] recover
     ] with-variable ;
 
-: contains-breakpoints? ( word -- ? )
-    def>> [ word? ] filter [ "break?" word-prop ] any? ;
index 5f89372ebe2d7bec6898d15156f6c6390b5a9caf..3d9d77ae56b235c94da3c8356e49691fc2987b98 100644 (file)
@@ -302,7 +302,7 @@ C: <ro-box> ro-box
 [ 0 ] [ [ 1 cons boa "x" get slot ] count-unboxed-allocations ] unit-test
 
 : impeach-node ( quot: ( node -- ) -- )
-    dup slip impeach-node ; inline recursive
+    [ call ] keep impeach-node ; inline recursive
 
 : bleach-node ( quot: ( node -- ) -- )
     [ bleach-node ] curry [ ] compose impeach-node ; inline recursive
index 5d6a9cdea1661206c285515a78ef8602fd0d9c0a..6e1c32d89d632b96520bd08a607e183d79123cf5 100644 (file)
@@ -98,13 +98,18 @@ TUPLE: declared-fixnum { x fixnum } ;
     ] { mod fixnum-mod } inlined?
 ] unit-test
 
-
 [ f ] [
     [
         256 mod
     ] { mod fixnum-mod } inlined?
 ] unit-test
 
+[ f ] [
+    [
+        >fixnum 256 mod
+    ] { mod fixnum-mod } inlined?
+] unit-test
+
 [ f ] [
     [
         dup 0 >= [ 256 mod ] when
@@ -128,3 +133,6 @@ TUPLE: declared-fixnum { x fixnum } ;
         { integer } declare [ 256 rem ] map
     ] { mod fixnum-mod rem } inlined?
 ] unit-test
+
+[ [ >fixnum 255 fixnum-bitand ] ]
+[ [ >integer 256 rem ] test-modular-arithmetic ] unit-test
\ No newline at end of file
index de2600f69145d094915f6d3f561dfad5cdc16dd2..31939a0d229e605435a05e84edfde81365fc7d4d 100644 (file)
@@ -2,6 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math math.partial-dispatch namespaces sequences sets
 accessors assocs words kernel memoize fry combinators
+combinators.short-circuit
 compiler.tree
 compiler.tree.combinators
 compiler.tree.def-use
@@ -69,6 +70,12 @@ GENERIC: optimize-modular-arithmetic* ( node -- nodes )
 : optimize->fixnum ( #call -- nodes )
     dup redundant->fixnum? [ drop f ] when ;
 
+: optimize->integer ( #call -- nodes )
+    dup out-d>> first actually-used-by dup length 1 = [
+        first node>> { [ #call? ] [ word>> \ >fixnum eq? ] } 1&&
+        [ drop { } ] when
+    ] [ drop ] if ;
+
 MEMO: fixnum-coercion ( flags -- nodes )
     [ [ ] [ >fixnum ] ? ] map '[ _ spread ] splice-quot ;
 
@@ -87,6 +94,7 @@ MEMO: fixnum-coercion ( flags -- nodes )
 M: #call optimize-modular-arithmetic*
     dup word>> {
         { [ dup \ >fixnum eq? ] [ drop optimize->fixnum ] }
+        { [ dup \ >integer eq? ] [ drop optimize->integer ] }
         { [ dup "modular-arithmetic" word-prop ] [ drop optimize-modular-op ] }
         [ drop ]
     } cond ;
index 2a7d4313148a346c01f8c006393b55924b220632..ee9abf00ec1301e4e65996eb7fba6286cac57d6f 100755 (executable)
@@ -157,11 +157,7 @@ DEFER: (flat-length)
     ] sum-outputs ;
 
 : should-inline? ( #call word -- ? )
-    {
-        { [ dup contains-breakpoints? ] [ 2drop f ] }
-        { [ dup "inline" word-prop ] [ 2drop t ] }
-        [ inlining-rank 5 >= ]
-    } cond ;
+    dup inline? [ 2drop t ] [ inlining-rank 5 >= ] if ;
 
 SYMBOL: history
 
index b91a1157f74dff30c6d9fcc7a09ab906a119ea54..2f5c166ac50b1d981f530ae07b2a012da5b1713d 100644 (file)
@@ -148,10 +148,6 @@ most-negative-fixnum most-positive-fixnum [a,b]
 comparison-ops
 [ dup '[ _ define-comparison-constraints ] each-derived-op ] each
 
-! generic-comparison-ops [
-!     dup specific-comparison define-comparison-constraints
-! ] each
-
 ! Remove redundant comparisons
 : fold-comparison ( info1 info2 word -- info )
     [ [ interval>> ] bi@ ] dip interval-comparison {
@@ -217,6 +213,8 @@ generic-comparison-ops [
     { >float float }
     { fixnum>float float }
     { bignum>float float }
+
+    { >integer integer }
 } [
     '[
         _
@@ -228,19 +226,26 @@ generic-comparison-ops [
     ] "outputs" set-word-prop
 ] assoc-each
 
+: rem-custom-inlining ( #call -- quot/f )
+    second value-info literal>> dup integer?
+    [ power-of-2? [ 1- bitand ] f ? ] [ drop f ] if ;
+
 {
     mod-integer-integer
     mod-integer-fixnum
     mod-fixnum-integer
     fixnum-mod
-    rem
 } [
     [
-        in-d>> second value-info >literal<
-        [ dup integer? [ power-of-2? [ 1- bitand ] f ? ] [ drop f ] if ] when
+        in-d>> dup first value-info interval>> [0,inf] interval-subset?
+        [ rem-custom-inlining ] [ drop f ] if
     ] "custom-inlining" set-word-prop
 ] each
 
+\ rem [
+    in-d>> rem-custom-inlining
+] "custom-inlining" set-word-prop
+
 {
     bitand-integer-integer
     bitand-integer-fixnum
index eba41dbfdf89447add34b20b193156836c49afa6..aba8dc9eda147937fd0a79cd2cafa5d287c389af 100644 (file)
@@ -690,4 +690,7 @@ TUPLE: littledan-2 { from read-only } { to read-only } ;
 ! Mutable tuples with circularity should not cause problems
 TUPLE: circle me ;
 
-[ ] [ circle new dup >>me 1quotation final-info drop ] unit-test
\ No newline at end of file
+[ ] [ circle new dup >>me 1quotation final-info drop ] unit-test
+
+! Joe found an oversight
+[ V{ integer } ] [ [ >integer ] final-classes ] unit-test
\ No newline at end of file
index 70670648b1666816d80b597bde1f3de9473b5bb4..0d5f05fab0592823f6e2eafadadaa99a2e01b2b1 100644 (file)
@@ -39,7 +39,7 @@ TUPLE: empty-tuple ;
 
 ! A more complicated example
 : impeach-node ( quot: ( node -- ) -- )
-    dup slip impeach-node ; inline recursive
+    [ call ] keep impeach-node ; inline recursive
 
 : bleach-node ( quot: ( node -- ) -- )
     [ bleach-node ] curry [ ] compose impeach-node ; inline recursive
index 5e95e2e36eeb1b639a7a6c706b714d9e35b34e28..924f7130f07dbc3cd9bbc70e79ba7f9dcfede62e 100644 (file)
@@ -105,6 +105,15 @@ CONSTANT: kCGLRendererGenericFloatID HEX: 00020400
 
 FUNCTION: CGLError CGLSetParameter ( CGLContextObj ctx, CGLContextParameter pname, GLint* params ) ;
 
+FUNCTION: CGDirectDisplayID CGMainDisplayID ( ) ;
+
+FUNCTION: CGError CGDisplayHideCursor ( CGDirectDisplayID display ) ;
+FUNCTION: CGError CGDisplayShowCursor ( CGDirectDisplayID display ) ;
+
+FUNCTION: CGError CGAssociateMouseAndMouseCursorPosition ( boolean_t connected ) ;
+
+FUNCTION: CGError CGWarpMouseCursorPosition ( CGPoint newCursorPosition ) ;
+
 <PRIVATE
 
 : bitmap-flags ( -- flags )
index 13e4285ea1770ddb603798ac3ee393aac34f93b9..0acdad9c0cb7adb0e53fcda46255fe691185e988 100644 (file)
@@ -90,5 +90,8 @@ TYPEDEF: void* CGContextRef
 TYPEDEF: uint CGBitmapInfo
 
 TYPEDEF: int CGLError
+TYPEDEF: int CGError
+TYPEDEF: uint CGDirectDisplayID
+TYPEDEF: int boolean_t
 TYPEDEF: void* CGLContextObj
-TYPEDEF: int CGLContextParameter
\ No newline at end of file
+TYPEDEF: int CGLContextParameter
index 2c9675426bc4a8ca6da82ef686b3ac8b97b90907..de5d1da4e01a0b94e04d54f469ad2dfe50f1145d 100644 (file)
@@ -47,6 +47,7 @@ HOOK: %inc-r cpu ( n -- )
 
 HOOK: stack-frame-size cpu ( stack-frame -- n )
 HOOK: %call cpu ( word -- )
+HOOK: %jump cpu ( word -- )
 HOOK: %jump-label cpu ( label -- )
 HOOK: %return cpu ( -- )
 
index 09db4cb050780e4c28724216e9410552a6ae7ab7..14327d08b88f0a49ccf15e70c77404a2199041cd 100644 (file)
@@ -3,114 +3,114 @@ USING: cpu.ppc.assembler tools.test arrays kernel namespaces
 make vocabs sequences ;
 
 : test-assembler ( expected quot -- )
-    [ 1array ] [ [ { } make ] curry ] bi* unit-test ;
+    [ 1array ] [ [ B{ } make ] curry ] bi* unit-test ;
 
-{ HEX: 38220003 } [ 1 2 3 ADDI ] test-assembler
-{ HEX: 3c220003 } [ 1 2 3 ADDIS ] test-assembler
-{ HEX: 30220003 } [ 1 2 3 ADDIC ] test-assembler
-{ HEX: 34220003 } [ 1 2 3 ADDIC. ] test-assembler
-{ HEX: 38400001 } [ 1 2 LI ] test-assembler
-{ HEX: 3c400001 } [ 1 2 LIS ] test-assembler
-{ HEX: 3822fffd } [ 1 2 3 SUBI ] test-assembler
-{ HEX: 1c220003 } [ 1 2 3 MULI ] test-assembler
-{ HEX: 7c221a14 } [ 1 2 3 ADD ] test-assembler
-{ HEX: 7c221a15 } [ 1 2 3 ADD. ] test-assembler
-{ HEX: 7c221e14 } [ 1 2 3 ADDO ] test-assembler
-{ HEX: 7c221e15 } [ 1 2 3 ADDO. ] test-assembler
-{ HEX: 7c221814 } [ 1 2 3 ADDC ] test-assembler
-{ HEX: 7c221815 } [ 1 2 3 ADDC. ] test-assembler
-{ HEX: 7c221e14 } [ 1 2 3 ADDO ] test-assembler
-{ HEX: 7c221c15 } [ 1 2 3 ADDCO. ] test-assembler
-{ HEX: 7c221914 } [ 1 2 3 ADDE ] test-assembler
-{ HEX: 7c411838 } [ 1 2 3 AND ] test-assembler
-{ HEX: 7c411839 } [ 1 2 3 AND. ] test-assembler
-{ HEX: 7c221bd6 } [ 1 2 3 DIVW ] test-assembler
-{ HEX: 7c221b96 } [ 1 2 3 DIVWU ] test-assembler
-{ HEX: 7c411a38 } [ 1 2 3 EQV ] test-assembler
-{ HEX: 7c411bb8 } [ 1 2 3 NAND ] test-assembler
-{ HEX: 7c4118f8 } [ 1 2 3 NOR ] test-assembler
-{ HEX: 7c4110f8 } [ 1 2 NOT ] test-assembler
-{ HEX: 60410003 } [ 1 2 3 ORI ] test-assembler
-{ HEX: 64410003 } [ 1 2 3 ORIS ] test-assembler
-{ HEX: 7c411b78 } [ 1 2 3 OR ] test-assembler
-{ HEX: 7c411378 } [ 1 2 MR ] test-assembler
-{ HEX: 7c221896 } [ 1 2 3 MULHW ] test-assembler
-{ HEX: 1c220003 } [ 1 2 3 MULLI ] test-assembler
-{ HEX: 7c221816 } [ 1 2 3 MULHWU ] test-assembler
-{ HEX: 7c2219d6 } [ 1 2 3 MULLW ] test-assembler
-{ HEX: 7c411830 } [ 1 2 3 SLW ] test-assembler
-{ HEX: 7c411e30 } [ 1 2 3 SRAW ] test-assembler
-{ HEX: 7c411c30 } [ 1 2 3 SRW ] test-assembler
-{ HEX: 7c411e70 } [ 1 2 3 SRAWI ] test-assembler
-{ HEX: 7c221850 } [ 1 2 3 SUBF ] test-assembler
-{ HEX: 7c221810 } [ 1 2 3 SUBFC ] test-assembler
-{ HEX: 7c221910 } [ 1 2 3 SUBFE ] test-assembler
-{ HEX: 7c410774 } [ 1 2 EXTSB ] test-assembler
-{ HEX: 68410003 } [ 1 2 3 XORI ] test-assembler
-{ HEX: 7c411a78 } [ 1 2 3 XOR ] test-assembler
-{ HEX: 7c2200d0 } [ 1 2 NEG ] test-assembler
-{ HEX: 2c220003 } [ 1 2 3 CMPI ] test-assembler
-{ HEX: 28220003 } [ 1 2 3 CMPLI ] test-assembler
-{ HEX: 7c411800 } [ 1 2 3 CMP ] test-assembler
-{ HEX: 5422190a } [ 1 2 3 4 5 RLWINM ] test-assembler
-{ HEX: 54221838 } [ 1 2 3 SLWI ] test-assembler
-{ HEX: 5422e8fe } [ 1 2 3 SRWI ] test-assembler
-{ HEX: 88220003 } [ 1 2 3 LBZ ] test-assembler
-{ HEX: 8c220003 } [ 1 2 3 LBZU ] test-assembler
-{ HEX: a8220003 } [ 1 2 3 LHA ] test-assembler
-{ HEX: ac220003 } [ 1 2 3 LHAU ] test-assembler
-{ HEX: a0220003 } [ 1 2 3 LHZ ] test-assembler
-{ HEX: a4220003 } [ 1 2 3 LHZU ] test-assembler
-{ HEX: 80220003 } [ 1 2 3 LWZ ] test-assembler
-{ HEX: 84220003 } [ 1 2 3 LWZU ] test-assembler
-{ HEX: 7c4118ae } [ 1 2 3 LBZX ] test-assembler
-{ HEX: 7c4118ee } [ 1 2 3 LBZUX ] test-assembler
-{ HEX: 7c411aae } [ 1 2 3 LHAX ] test-assembler
-{ HEX: 7c411aee } [ 1 2 3 LHAUX ] test-assembler
-{ HEX: 7c411a2e } [ 1 2 3 LHZX ] test-assembler
-{ HEX: 7c411a6e } [ 1 2 3 LHZUX ] test-assembler
-{ HEX: 7c41182e } [ 1 2 3 LWZX ] test-assembler
-{ HEX: 7c41186e } [ 1 2 3 LWZUX ] test-assembler
-{ HEX: 48000001 } [ 1 B ] test-assembler
-{ HEX: 48000001 } [ 1 BL ] test-assembler
-{ HEX: 41800004 } [ 1 BLT ] test-assembler
-{ HEX: 41810004 } [ 1 BGT ] test-assembler
-{ HEX: 40810004 } [ 1 BLE ] test-assembler
-{ HEX: 40800004 } [ 1 BGE ] test-assembler
-{ HEX: 41800004 } [ 1 BLT ] test-assembler
-{ HEX: 40820004 } [ 1 BNE ] test-assembler
-{ HEX: 41820004 } [ 1 BEQ ] test-assembler
-{ HEX: 41830004 } [ 1 BO ] test-assembler
-{ HEX: 40830004 } [ 1 BNO ] test-assembler
-{ HEX: 4c200020 } [ 1 BCLR ] test-assembler
-{ HEX: 4e800020 } [ BLR ] test-assembler
-{ HEX: 4e800021 } [ BLRL ] test-assembler
-{ HEX: 4c200420 } [ 1 BCCTR ] test-assembler
-{ HEX: 4e800420 } [ BCTR ] test-assembler
-{ HEX: 7c6102a6 } [ 3 MFXER ] test-assembler
-{ HEX: 7c6802a6 } [ 3 MFLR ] test-assembler
-{ HEX: 7c6902a6 } [ 3 MFCTR ] test-assembler
-{ HEX: 7c6103a6 } [ 3 MTXER ] test-assembler
-{ HEX: 7c6803a6 } [ 3 MTLR ] test-assembler
-{ HEX: 7c6903a6 } [ 3 MTCTR ] test-assembler
-{ HEX: 7c6102a6 } [ 3 MFXER ] test-assembler
-{ HEX: 7c6802a6 } [ 3 MFLR ] test-assembler
-{ HEX: c0220003 } [ 1 2 3 LFS ] test-assembler
-{ HEX: c4220003 } [ 1 2 3 LFSU ] test-assembler
-{ HEX: c8220003 } [ 1 2 3 LFD ] test-assembler
-{ HEX: cc220003 } [ 1 2 3 LFDU ] test-assembler
-{ HEX: d0220003 } [ 1 2 3 STFS ] test-assembler
-{ HEX: d4220003 } [ 1 2 3 STFSU ] test-assembler
-{ HEX: d8220003 } [ 1 2 3 STFD ] test-assembler
-{ HEX: dc220003 } [ 1 2 3 STFDU ] test-assembler
-{ HEX: fc201048 } [ 1 2 FMR ] test-assembler
-{ HEX: fc20101e } [ 1 2 FCTIWZ ] test-assembler
-{ HEX: fc22182a } [ 1 2 3 FADD ] test-assembler
-{ HEX: fc22182b } [ 1 2 3 FADD. ] test-assembler
-{ HEX: fc221828 } [ 1 2 3 FSUB ] test-assembler
-{ HEX: fc2200f2 } [ 1 2 3 FMUL ] test-assembler
-{ HEX: fc221824 } [ 1 2 3 FDIV ] test-assembler
-{ HEX: fc20102c } [ 1 2 FSQRT ] test-assembler
-{ HEX: fc411800 } [ 1 2 3 FCMPU ] test-assembler
-{ HEX: fc411840 } [ 1 2 3 FCMPO ] test-assembler
-{ HEX: 3c601234 HEX: 60635678 } [ HEX: 12345678 3 LOAD ] test-assembler
+B{ HEX: 38 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 ADDI ] test-assembler
+B{ HEX: 3c HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 ADDIS ] test-assembler
+B{ HEX: 30 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 ADDIC ] test-assembler
+B{ HEX: 34 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 ADDIC. ] test-assembler
+B{ HEX: 38 HEX: 40 HEX: 00 HEX: 01 } [ 1 2 LI ] test-assembler
+B{ HEX: 3c HEX: 40 HEX: 00 HEX: 01 } [ 1 2 LIS ] test-assembler
+B{ HEX: 38 HEX: 22 HEX: ff HEX: fd } [ 1 2 3 SUBI ] test-assembler
+B{ HEX: 1c HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 MULI ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1a HEX: 14 } [ 1 2 3 ADD ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1a HEX: 15 } [ 1 2 3 ADD. ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1e HEX: 14 } [ 1 2 3 ADDO ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1e HEX: 15 } [ 1 2 3 ADDO. ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 14 } [ 1 2 3 ADDC ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 15 } [ 1 2 3 ADDC. ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1e HEX: 14 } [ 1 2 3 ADDO ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1c HEX: 15 } [ 1 2 3 ADDCO. ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 19 HEX: 14 } [ 1 2 3 ADDE ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 38 } [ 1 2 3 AND ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 39 } [ 1 2 3 AND. ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1b HEX: d6 } [ 1 2 3 DIVW ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 1b HEX: 96 } [ 1 2 3 DIVWU ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: 38 } [ 1 2 3 EQV ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1b HEX: b8 } [ 1 2 3 NAND ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: f8 } [ 1 2 3 NOR ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 10 HEX: f8 } [ 1 2 NOT ] test-assembler
+B{ HEX: 60 HEX: 41 HEX: 00 HEX: 03 } [ 1 2 3 ORI ] test-assembler
+B{ HEX: 64 HEX: 41 HEX: 00 HEX: 03 } [ 1 2 3 ORIS ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1b HEX: 78 } [ 1 2 3 OR ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 13 HEX: 78 } [ 1 2 MR ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 96 } [ 1 2 3 MULHW ] test-assembler
+B{ HEX: 1c HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 MULLI ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 16 } [ 1 2 3 MULHWU ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 19 HEX: d6 } [ 1 2 3 MULLW ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 30 } [ 1 2 3 SLW ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1e HEX: 30 } [ 1 2 3 SRAW ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1c HEX: 30 } [ 1 2 3 SRW ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1e HEX: 70 } [ 1 2 3 SRAWI ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 50 } [ 1 2 3 SUBF ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 18 HEX: 10 } [ 1 2 3 SUBFC ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 19 HEX: 10 } [ 1 2 3 SUBFE ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 07 HEX: 74 } [ 1 2 EXTSB ] test-assembler
+B{ HEX: 68 HEX: 41 HEX: 00 HEX: 03 } [ 1 2 3 XORI ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: 78 } [ 1 2 3 XOR ] test-assembler
+B{ HEX: 7c HEX: 22 HEX: 00 HEX: d0 } [ 1 2 NEG ] test-assembler
+B{ HEX: 2c HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 CMPI ] test-assembler
+B{ HEX: 28 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 CMPLI ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 00 } [ 1 2 3 CMP ] test-assembler
+B{ HEX: 54 HEX: 22 HEX: 19 HEX: 0a } [ 1 2 3 4 5 RLWINM ] test-assembler
+B{ HEX: 54 HEX: 22 HEX: 18 HEX: 38 } [ 1 2 3 SLWI ] test-assembler
+B{ HEX: 54 HEX: 22 HEX: e8 HEX: fe } [ 1 2 3 SRWI ] test-assembler
+B{ HEX: 88 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LBZ ] test-assembler
+B{ HEX: 8c HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LBZU ] test-assembler
+B{ HEX: a8 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LHA ] test-assembler
+B{ HEX: ac HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LHAU ] test-assembler
+B{ HEX: a0 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LHZ ] test-assembler
+B{ HEX: a4 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LHZU ] test-assembler
+B{ HEX: 80 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LWZ ] test-assembler
+B{ HEX: 84 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LWZU ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: ae } [ 1 2 3 LBZX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: ee } [ 1 2 3 LBZUX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: ae } [ 1 2 3 LHAX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: ee } [ 1 2 3 LHAUX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: 2e } [ 1 2 3 LHZX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 1a HEX: 6e } [ 1 2 3 LHZUX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 2e } [ 1 2 3 LWZX ] test-assembler
+B{ HEX: 7c HEX: 41 HEX: 18 HEX: 6e } [ 1 2 3 LWZUX ] test-assembler
+B{ HEX: 48 HEX: 00 HEX: 00 HEX: 01 } [ 1 B ] test-assembler
+B{ HEX: 48 HEX: 00 HEX: 00 HEX: 01 } [ 1 BL ] test-assembler
+B{ HEX: 41 HEX: 80 HEX: 00 HEX: 04 } [ 1 BLT ] test-assembler
+B{ HEX: 41 HEX: 81 HEX: 00 HEX: 04 } [ 1 BGT ] test-assembler
+B{ HEX: 40 HEX: 81 HEX: 00 HEX: 04 } [ 1 BLE ] test-assembler
+B{ HEX: 40 HEX: 80 HEX: 00 HEX: 04 } [ 1 BGE ] test-assembler
+B{ HEX: 41 HEX: 80 HEX: 00 HEX: 04 } [ 1 BLT ] test-assembler
+B{ HEX: 40 HEX: 82 HEX: 00 HEX: 04 } [ 1 BNE ] test-assembler
+B{ HEX: 41 HEX: 82 HEX: 00 HEX: 04 } [ 1 BEQ ] test-assembler
+B{ HEX: 41 HEX: 83 HEX: 00 HEX: 04 } [ 1 BO ] test-assembler
+B{ HEX: 40 HEX: 83 HEX: 00 HEX: 04 } [ 1 BNO ] test-assembler
+B{ HEX: 4c HEX: 20 HEX: 00 HEX: 20 } [ 1 BCLR ] test-assembler
+B{ HEX: 4e HEX: 80 HEX: 00 HEX: 20 } [ BLR ] test-assembler
+B{ HEX: 4e HEX: 80 HEX: 00 HEX: 21 } [ BLRL ] test-assembler
+B{ HEX: 4c HEX: 20 HEX: 04 HEX: 20 } [ 1 BCCTR ] test-assembler
+B{ HEX: 4e HEX: 80 HEX: 04 HEX: 20 } [ BCTR ] test-assembler
+B{ HEX: 7c HEX: 61 HEX: 02 HEX: a6 } [ 3 MFXER ] test-assembler
+B{ HEX: 7c HEX: 68 HEX: 02 HEX: a6 } [ 3 MFLR ] test-assembler
+B{ HEX: 7c HEX: 69 HEX: 02 HEX: a6 } [ 3 MFCTR ] test-assembler
+B{ HEX: 7c HEX: 61 HEX: 03 HEX: a6 } [ 3 MTXER ] test-assembler
+B{ HEX: 7c HEX: 68 HEX: 03 HEX: a6 } [ 3 MTLR ] test-assembler
+B{ HEX: 7c HEX: 69 HEX: 03 HEX: a6 } [ 3 MTCTR ] test-assembler
+B{ HEX: 7c HEX: 61 HEX: 02 HEX: a6 } [ 3 MFXER ] test-assembler
+B{ HEX: 7c HEX: 68 HEX: 02 HEX: a6 } [ 3 MFLR ] test-assembler
+B{ HEX: c0 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LFS ] test-assembler
+B{ HEX: c4 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LFSU ] test-assembler
+B{ HEX: c8 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LFD ] test-assembler
+B{ HEX: cc HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 LFDU ] test-assembler
+B{ HEX: d0 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 STFS ] test-assembler
+B{ HEX: d4 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 STFSU ] test-assembler
+B{ HEX: d8 HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 STFD ] test-assembler
+B{ HEX: dc HEX: 22 HEX: 00 HEX: 03 } [ 1 2 3 STFDU ] test-assembler
+B{ HEX: fc HEX: 20 HEX: 10 HEX: 48 } [ 1 2 FMR ] test-assembler
+B{ HEX: fc HEX: 20 HEX: 10 HEX: 1e } [ 1 2 FCTIWZ ] test-assembler
+B{ HEX: fc HEX: 22 HEX: 18 HEX: 2a } [ 1 2 3 FADD ] test-assembler
+B{ HEX: fc HEX: 22 HEX: 18 HEX: 2b } [ 1 2 3 FADD. ] test-assembler
+B{ HEX: fc HEX: 22 HEX: 18 HEX: 28 } [ 1 2 3 FSUB ] test-assembler
+B{ HEX: fc HEX: 22 HEX: 00 HEX: f2 } [ 1 2 3 FMUL ] test-assembler
+B{ HEX: fc HEX: 22 HEX: 18 HEX: 24 } [ 1 2 3 FDIV ] test-assembler
+B{ HEX: fc HEX: 20 HEX: 10 HEX: 2c } [ 1 2 FSQRT ] test-assembler
+B{ HEX: fc HEX: 41 HEX: 18 HEX: 00 } [ 1 2 3 FCMPU ] test-assembler
+B{ HEX: fc HEX: 41 HEX: 18 HEX: 40 } [ 1 2 3 FCMPO ] test-assembler
+B{ HEX: 3c HEX: 60 HEX: 12 HEX: 34 HEX: 60 HEX: 63 HEX: 56 HEX: 78 } [ HEX: 12345678 3 LOAD ] test-assembler
index fbb878a888044f01f1b178a55b18b38b98cf7083..2daf3678ce06987fb20c89980be561b24b02230e 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: compiler.codegen.fixup kernel namespaces words
-io.binary math math.order cpu.ppc.assembler.backend ;
+USING: kernel namespaces words io.binary math math.order
+cpu.ppc.assembler.backend ;
 IN: cpu.ppc.assembler
 
 ! See the Motorola or IBM documentation for details. The opcode
index befbe112bd0d248fa46d4404eb5feb82d8170471..1e6365b1e79c039caf9776dfbadc165b6c75fb9a 100644 (file)
@@ -1,11 +1,10 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: compiler.codegen.fixup cpu.architecture
-compiler.constants kernel namespaces make sequences words math
-math.bitwise io.binary parser lexer ;
+USING:  kernel namespaces make sequences words math
+math.bitwise io.binary parser lexer fry ;
 IN: cpu.ppc.assembler.backend
 
-: insn ( operand opcode -- ) { 26 0 } bitfield , ;
+: insn ( operand opcode -- ) { 26 0 } bitfield 4 >be % ;
 
 : a-insn ( d a b c xo rc opcode -- )
     [ { 0 1 6 11 16 21 } bitfield ] dip insn ;
@@ -74,21 +73,16 @@ SYNTAX: XO1: (XO) (1) (( a s -- )) define-declared ;
 
 GENERIC# (B) 2 ( dest aa lk -- )
 M: integer (B) 18 i-insn ;
-M: word (B) [ 0 ] 2dip (B) rc-relative-ppc-3 rel-word ;
-M: label (B) [ 0 ] 2dip (B) rc-relative-ppc-3 label-fixup ;
 
 GENERIC: BC ( a b c -- )
 M: integer BC 0 0 16 b-insn ;
-M: word BC [ 0 BC ] dip rc-relative-ppc-2 rel-word ;
-M: label BC [ 0 BC ] dip rc-relative-ppc-2 label-fixup ;
 
 : CREATE-B ( -- word ) scan "B" prepend create-in ;
 
 SYNTAX: BC:
     CREATE-B scan-word scan-word
-    [ rot BC ] 2curry (( c -- )) define-declared ;
+    '[ [ _ _ ] dip BC ] (( c -- )) define-declared ;
 
 SYNTAX: B:
     CREATE-B scan-word scan-word scan-word scan-word scan-word
-    [ b-insn ] curry curry curry curry curry
-    (( bo -- )) define-declared ;
+    '[ _ _ _ _ _ b-insn ] (( bo -- )) define-declared ;
index 7278fd20929f7e0a6d8fcca4878e7972e7288bfb..b09938f4b9bbe208ccee56eb42658d76aa074005 100644 (file)
@@ -9,8 +9,8 @@ IN: bootstrap.ppc
 4 \ cell set\r
 big-endian on\r
 \r
-CONSTANT: ds-reg 29\r
-CONSTANT: rs-reg 30\r
+CONSTANT: ds-reg 13\r
+CONSTANT: rs-reg 14\r
 \r
 : factor-area-size ( -- n ) 4 bootstrap-cells ;\r
 \r
@@ -21,46 +21,48 @@ CONSTANT: rs-reg 30
 : xt-save ( -- n ) stack-frame 2 bootstrap-cells - ;\r
 \r
 [\r
-    0 6 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
-    11 6 profile-count-offset LWZ\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    11 3 profile-count-offset LWZ\r
     11 11 1 tag-fixnum ADDI\r
-    11 6 profile-count-offset STW\r
-    11 6 word-code-offset LWZ\r
+    11 3 profile-count-offset STW\r
+    11 3 word-code-offset LWZ\r
     11 11 compiled-header-size ADDI\r
     11 MTCTR\r
     BCTR\r
 ] jit-profiling jit-define\r
 \r
 [\r
-    0 6 LOAD32 rc-absolute-ppc-2/2 rt-this jit-rel\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-this jit-rel\r
     0 MFLR\r
     1 1 stack-frame SUBI\r
-    6 1 xt-save STW\r
-    stack-frame 6 LI\r
-    6 1 next-save STW\r
+    3 1 xt-save STW\r
+    stack-frame 3 LI\r
+    3 1 next-save STW\r
     0 1 lr-save stack-frame + STW\r
 ] jit-prolog jit-define\r
 \r
 [\r
-    0 6 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
-    6 ds-reg 4 STWU\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    3 ds-reg 4 STWU\r
 ] jit-push-immediate jit-define\r
 \r
 [\r
-    0 6 LOAD32 rc-absolute-ppc-2/2 rt-stack-chain jit-rel\r
-    7 6 0 LWZ\r
-    1 7 0 STW\r
-] jit-save-stack jit-define\r
-\r
-[\r
-    0 6 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel\r
-    6 MTCTR\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-stack-chain jit-rel\r
+    4 3 0 LWZ\r
+    1 4 0 STW\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel\r
+    3 MTCTR\r
     BCTR\r
 ] jit-primitive jit-define\r
 \r
-[ 0 BL rc-relative-ppc-3 rt-xt-direct jit-rel ] jit-word-call jit-define\r
+[ 0 BL rc-relative-ppc-3 rt-xt-pic jit-rel ] jit-word-call jit-define\r
+\r
+[\r
+    0 6 LOAD32 rc-absolute-ppc-2/2 rt-here jit-rel\r
+    0 B rc-relative-ppc-3 rt-xt-pic-tail jit-rel\r
+] jit-word-jump jit-define\r
 \r
-[ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-word-jump jit-define\r
+[ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-word-special jit-define\r
 \r
 [\r
     3 ds-reg 0 LWZ\r
@@ -68,11 +70,8 @@ CONSTANT: rs-reg 30
     0 3 \ f tag-number CMPI\r
     2 BEQ\r
     0 B rc-relative-ppc-3 rt-xt jit-rel\r
-] jit-if-1 jit-define\r
-\r
-[\r
     0 B rc-relative-ppc-3 rt-xt jit-rel\r
-] jit-if-2 jit-define\r
+] jit-if jit-define\r
 \r
 : jit->r ( -- )\r
     4 ds-reg 0 LWZ\r
@@ -138,6 +137,16 @@ CONSTANT: rs-reg 30
     jit-3r>\r
 ] jit-3dip jit-define\r
 \r
+: prepare-(execute) ( -- operand )\r
+    3 ds-reg 0 LWZ\r
+    ds-reg dup 4 SUBI\r
+    4 3 word-xt-offset LWZ\r
+    4 ;\r
+\r
+[ prepare-(execute) MTCTR BCTR ] jit-execute-jump jit-define\r
+\r
+[ prepare-(execute) MTLR BLRL ] jit-execute-call jit-define\r
+\r
 [\r
     0 1 lr-save stack-frame + LWZ\r
     1 1 stack-frame ADDI\r
@@ -146,24 +155,108 @@ CONSTANT: rs-reg 30
 \r
 [ BLR ] jit-return jit-define\r
 \r
-! Sub-primitives\r
+! ! ! Polymorphic inline caches\r
 \r
-! Quotations and words\r
+! Don't touch r6 here; it's used to pass the tail call site\r
+! address for tail PICs\r
+\r
+! Load a value from a stack position\r
 [\r
-    3 ds-reg 0 LWZ\r
-    ds-reg dup 4 SUBI\r
-    4 3 quot-xt-offset LWZ\r
-    4 MTCTR\r
+    4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel\r
+] pic-load jit-define\r
+\r
+! Tag\r
+: load-tag ( -- )\r
+    4 4 tag-mask get ANDI\r
+    4 4 tag-bits get SLWI ;\r
+\r
+[ load-tag ] pic-tag jit-define\r
+\r
+! Hi-tag\r
+[\r
+    3 4 MR\r
+    load-tag\r
+    0 4 object tag-number tag-fixnum CMPI\r
+    2 BNE\r
+    4 3 object tag-number neg LWZ\r
+] pic-hi-tag jit-define\r
+\r
+! Tuple\r
+[\r
+    3 4 MR\r
+    load-tag\r
+    0 4 tuple tag-number tag-fixnum CMPI\r
+    2 BNE\r
+    4 3 tuple tag-number neg bootstrap-cell + LWZ\r
+] pic-tuple jit-define\r
+\r
+! Hi-tag and tuple\r
+[\r
+    3 4 MR\r
+    load-tag\r
+    ! If bits 2 and 3 are set, the tag is either 6 (object) or 7 (tuple)\r
+    0 4 BIN: 110 tag-fixnum CMPI\r
+    5 BLT\r
+    ! Untag r3\r
+    3 3 0 0 31 tag-bits get - RLWINM\r
+    ! Set r4 to 0 for objects, and bootstrap-cell for tuples\r
+    4 4 1 tag-fixnum ANDI\r
+    4 4 1 SRAWI\r
+    ! Load header cell or tuple layout cell\r
+    4 4 3 LWZX\r
+] pic-hi-tag-tuple jit-define\r
+\r
+[\r
+    0 4 0 CMPI rc-absolute-ppc-2 rt-immediate jit-rel\r
+] pic-check-tag jit-define\r
+\r
+[\r
+    0 5 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    4 0 5 CMP\r
+] pic-check jit-define\r
+\r
+[ 2 BNE 0 B rc-relative-ppc-3 rt-xt jit-rel ] pic-hit jit-define\r
+\r
+! ! ! Megamorphic caches\r
+\r
+[\r
+    ! cache = ...\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    ! key = class\r
+    5 4 MR\r
+    ! key &= cache.length - 1\r
+    5 5 mega-cache-size get 1- bootstrap-cell * ANDI\r
+    ! cache += array-start-offset\r
+    3 3 array-start-offset ADDI\r
+    ! cache += key\r
+    3 3 5 ADD\r
+    ! if(get(cache) == class)\r
+    6 3 0 LWZ\r
+    6 0 4 CMP\r
+    10 BNE\r
+    ! megamorphic_cache_hits++\r
+    0 4 LOAD32 rc-absolute-ppc-2/2 rt-megamorphic-cache-hits jit-rel\r
+    5 4 0 LWZ\r
+    5 5 1 ADDI\r
+    5 4 0 STW\r
+    ! ... goto get(cache + bootstrap-cell)\r
+    3 3 4 LWZ\r
+    3 3 word-xt-offset LWZ\r
+    3 MTCTR\r
     BCTR\r
-] \ (call) define-sub-primitive\r
+    ! fall-through on miss\r
+] mega-lookup jit-define\r
 \r
+! ! ! Sub-primitives\r
+\r
+! Quotations and words\r
 [\r
     3 ds-reg 0 LWZ\r
     ds-reg dup 4 SUBI\r
-    4 3 word-xt-offset LWZ\r
+    4 3 quot-xt-offset LWZ\r
     4 MTCTR\r
     BCTR\r
-] \ (execute) define-sub-primitive\r
+] \ (call) define-sub-primitive\r
 \r
 ! Objects\r
 [\r
index 85bf188bb81298731d3bdf46f9575ffaa85ce836..dc7108b3a11a143953fe3f9e986ffceed8a4d0e0 100644 (file)
@@ -1,33 +1,39 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 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.cfg.intrinsics compiler.cfg.stack-frame ;
+alien alien.accessors alien.c-types literals cpu.architecture
+cpu.ppc.assembler cpu.ppc.assembler.backend literals compiler.cfg.registers
+compiler.cfg.instructions compiler.constants compiler.codegen
+compiler.codegen.fixup compiler.cfg.intrinsics
+compiler.cfg.stack-frame compiler.units ;
 IN: cpu.ppc
 
 ! PowerPC register assignments:
-! r2-r27: integer vregs
-! r28: integer scratch
-! r29: data stack
-! r30: retain stack
+! r2-r12: integer vregs
+! r15-r29
+! r30: integer scratch
 ! f0-f29: float vregs
-! f30, f31: float scratch
+! f30: float scratch
+
+! Add some methods to the assembler that are useful to us
+M: label (B) [ 0 ] 2dip (B) rc-relative-ppc-3 label-fixup ;
+M: label BC [ 0 BC ] dip rc-relative-ppc-2 label-fixup ;
 
 enable-float-intrinsics
 
-<< \ ##integer>float t frame-required? set-word-prop
-\ ##float>integer t frame-required? set-word-prop >>
+<<
+\ ##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 29 1 } }
+        { int-regs $[ 2 12 [a,b] 15 29 [a,b] append ] }
+        { double-float-regs $[ 0 29 [a,b] ] }
     } ;
 
-CONSTANT: scratch-reg 28
+CONSTANT: scratch-reg 30
 CONSTANT: fp-scratch-reg 30
 
 M: ppc two-operand? f ;
@@ -40,8 +46,8 @@ M: ppc %load-reference ( reg obj -- )
 M: ppc %alien-global ( register symbol dll -- )
     [ 0 swap LOAD32 ] 2dip rc-absolute-ppc-2/2 rel-dlsym ;
 
-CONSTANT: ds-reg 29
-CONSTANT: rs-reg 30
+CONSTANT: ds-reg 13
+CONSTANT: rs-reg 14
 
 GENERIC: loc-reg ( loc -- reg )
 
@@ -108,7 +114,12 @@ M: ppc stack-frame-size ( stack-frame -- i )
     factor-area-size +
     4 cells align ;
 
-M: ppc %call ( label -- ) BL ;
+M: ppc %call ( word -- ) 0 BL rc-relative-ppc-3 rel-word-pic ;
+
+M: ppc %jump ( word -- )
+    0 6 LOAD32 8 rc-absolute-ppc-2/2 rel-here
+    0 B rc-relative-ppc-3 rel-word-pic-tail ;
+
 M: ppc %jump-label ( label -- ) B ;
 M: ppc %return ( -- ) BLR ;
 
@@ -120,7 +131,7 @@ M:: ppc %dispatch ( src temp offset -- )
     BCTR ;
 
 M: ppc %dispatch-label ( word -- )
-    0 , rc-absolute-cell rel-word ;
+    B{ 0 0 0 0 } % rc-absolute-cell rel-word ;
 
 :: (%slot) ( obj slot tag temp -- reg offset )
     temp slot obj ADD
@@ -641,10 +652,10 @@ M: ppc %alien-callback ( quot -- )
 
 M: ppc %prepare-alien-indirect ( -- )
     "unbox_alien" f %alien-invoke
-    13 3 MR ;
+    15 3 MR ;
 
 M: ppc %alien-indirect ( -- )
-    13 MTLR BLRL ;
+    15 MTLR BLRL ;
 
 M: ppc %callback-value ( ctype -- )
     ! Save top of data stack
@@ -702,3 +713,14 @@ USE: vocabs.loader
 } cond
 
 "complex-double" c-type t >>return-in-registers? drop
+
+[
+    <c-type>
+        [ alien-unsigned-4 c-bool> ] >>getter
+        [ [ >c-bool ] 2dip set-alien-unsigned-4 ] >>setter
+        4 >>size
+        4 >>align
+        "box_boolean" >>boxer
+        "to_boolean" >>unboxer
+    "bool" define-primitive-type
+] with-compilation-unit
index 10cd9c8657e00444f420996efb57401570f18633..0a0ac4a53e727e570093db26083375cb7b217ca6 100755 (executable)
@@ -42,11 +42,13 @@ M:: x86.32 %dispatch ( src temp offset -- )
 M: x86.32 param-reg-1 EAX ;
 M: x86.32 param-reg-2 EDX ;
 
+M: x86.32 pic-tail-reg EBX ;
+
 M: x86.32 reserved-area-size 0 ;
 
-M: x86.32 %alien-invoke (CALL) rel-dlsym ;
+M: x86.32 %alien-invoke 0 CALL rc-relative rel-dlsym ;
 
-M: x86.32 %alien-invoke-tail (JMP) rel-dlsym ;
+M: x86.32 %alien-invoke-tail 0 JMP rc-relative rel-dlsym ;
 
 M: x86.32 return-struct-in-registers? ( c-type -- ? )
     c-type
index be21344815ffb97fdeb862219dcf09c614d9e5b3..490d37ccbc42ef8092f41c1f2e14a28a64230803 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
 cpu.x86.assembler layouts vocabs parser compiler.constants ;
@@ -26,10 +26,8 @@ IN: bootstrap.x86
     temp0 0 [] MOV rc-absolute-cell rt-stack-chain jit-rel
     ! save stack pointer
     temp0 [] stack-reg MOV
-] jit-save-stack jit-define
-
-[
-    (JMP) drop rc-relative rt-primitive jit-rel
+    ! call the primitive
+    0 JMP rc-relative rt-primitive jit-rel
 ] jit-primitive jit-define
 
 << "vocab:cpu/x86/bootstrap.factor" parse-file parsed >>
index 8cc69958a4ec4761168b7a1acb5d966b7ba126e1..ad1b487e448100ae628f01a9901ae25416e46005 100644 (file)
@@ -39,6 +39,8 @@ M: x86.64 param-reg-1 int-regs param-regs first ;
 M: x86.64 param-reg-2 int-regs param-regs second ;
 : param-reg-3 ( -- reg ) int-regs param-regs third ; inline
 
+M: x86.64 pic-tail-reg RBX ;
+
 M: int-regs return-reg drop RAX ;
 M: float-regs return-reg drop XMM0 ;
 
index 8d1ed086e70f3bf6b5d913206ab805f88a40e717..c5c7e63dbc7f4be149ed4e7c5c18977472eac70c 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
 cpu.x86.assembler layouts vocabs parser compiler.constants math ;
@@ -25,9 +25,6 @@ IN: bootstrap.x86
     temp0 temp0 [] MOV
     ! save stack pointer
     temp0 [] stack-reg MOV
-] jit-save-stack jit-define
-
-[
     ! load XT
     temp1 0 MOV rc-absolute-cell rt-primitive jit-rel
     ! go
index 5560d17a1e45459159b04d38ac8ce85dfe7fe0f1..2b40aa2053f0b55779c64b97056966d397cbc531 100644 (file)
@@ -1,12 +1,11 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays cpu.architecture compiler.constants
-compiler.codegen.fixup io.binary kernel combinators
-kernel.private math namespaces make sequences words system
-layouts math.order accessors cpu.x86.assembler.syntax ;
+USING: arrays io.binary kernel combinators
+kernel.private math namespaces make sequences words system layouts
+math.order accessors cpu.x86.assembler.syntax ;
 IN: cpu.x86.assembler
 
-! A postfix assembler for x86 and AMD64.
+! A postfix assembler for x86-32 and x86-64.
 
 ! In 32-bit mode, { 1234 } is absolute indirect addressing.
 ! In 64-bit mode, { 1234 } is RIP-relative.
@@ -296,36 +295,23 @@ M: operand (MOV-I)
     { BIN: 000 t HEX: c6 }
     pick byte? [ immediate-1 ] [ immediate-4 ] if ;
 
-PREDICATE: callable < word register? not ;
-
 GENERIC: MOV ( dst src -- )
 M: immediate MOV swap (MOV-I) ;
-M: callable MOV [ 0 ] 2dip (MOV-I) rc-absolute-cell rel-word ;
 M: operand MOV HEX: 88 2-operand ;
 
 : LEA ( dst src -- ) swap HEX: 8d 2-operand ;
 
 ! Control flow
 GENERIC: JMP ( op -- )
-: (JMP) ( -- rel-class ) HEX: e9 , 0 4, rc-relative ;
-M: f JMP (JMP) 2drop ;
-M: callable JMP (JMP) rel-word ;
-M: label JMP (JMP) label-fixup ;
+M: integer JMP HEX: e9 , 4, ;
 M: operand JMP { BIN: 100 t HEX: ff } 1-operand ;
 
 GENERIC: CALL ( op -- )
-: (CALL) ( -- rel-class ) HEX: e8 , 0 4, rc-relative ;
-M: f CALL (CALL) 2drop ;
-M: callable CALL (CALL) rel-word-direct ;
-M: label CALL (CALL) label-fixup ;
+M: integer CALL HEX: e8 , 4, ;
 M: operand CALL { BIN: 010 t HEX: ff } 1-operand ;
 
 GENERIC# JUMPcc 1 ( addr opcode -- )
-: (JUMPcc) ( addr n -- rel-class ) extended-opcode, 4, rc-relative ;
-M: f JUMPcc [ 0 ] dip (JUMPcc) 2drop ;
-M: integer JUMPcc (JUMPcc) drop ;
-M: callable JUMPcc [ 0 ] dip (JUMPcc) rel-word ;
-M: label JUMPcc [ 0 ] dip (JUMPcc) label-fixup ;
+M: integer JUMPcc extended-opcode, 4, ;
 
 : JO  ( dst -- ) HEX: 80 JUMPcc ;
 : JNO ( dst -- ) HEX: 81 JUMPcc ;
index 4fe5e5cd33b2f5fcb1a0381645b3a14f7b27392f..474ce2ea468fc2f4e56b355c90461750f68cb7a2 100644 (file)
@@ -42,13 +42,18 @@ big-endian off
 ] jit-push-immediate jit-define
 
 [
-    f JMP rc-relative rt-xt jit-rel
+    temp3 0 MOV rc-absolute-cell rt-here jit-rel
+    0 JMP rc-relative rt-xt-pic-tail jit-rel
 ] jit-word-jump jit-define
 
 [
-    f CALL rc-relative rt-xt-direct jit-rel
+    0 CALL rc-relative rt-xt-pic jit-rel
 ] jit-word-call jit-define
 
+[
+    0 JMP rc-relative rt-xt jit-rel
+] jit-word-special jit-define
+
 [
     ! load boolean
     temp0 ds-reg [] MOV
@@ -57,13 +62,10 @@ big-endian off
     ! compare boolean with f
     temp0 \ f tag-number CMP
     ! jump to true branch if not equal
-    f JNE rc-relative rt-xt jit-rel
-] jit-if-1 jit-define
-
-[
+    0 JNE rc-relative rt-xt jit-rel
     ! jump to false branch if equal
-    f JMP rc-relative rt-xt jit-rel
-] jit-if-2 jit-define
+    0 JMP rc-relative rt-xt jit-rel
+] jit-if jit-define
 
 : jit->r ( -- )
     rs-reg bootstrap-cell ADD
@@ -115,19 +117,19 @@ big-endian off
 
 [
     jit->r
-    f CALL rc-relative rt-xt jit-rel
+    0 CALL rc-relative rt-xt jit-rel
     jit-r>
 ] jit-dip jit-define
 
 [
     jit-2>r
-    f CALL rc-relative rt-xt jit-rel
+    0 CALL rc-relative rt-xt jit-rel
     jit-2r>
 ] jit-2dip jit-define
 
 [
     jit-3>r
-    f CALL rc-relative rt-xt jit-rel
+    0 CALL rc-relative rt-xt jit-rel
     jit-3r>
 ] jit-3dip jit-define
 
@@ -152,8 +154,7 @@ big-endian off
 
 ! ! ! Polymorphic inline caches
 
-! temp0 contains the object being dispatched on
-! temp1 contains its class
+! The PIC and megamorphic code stubs are not permitted to touch temp3.
 
 ! Load a value from a stack position
 [
@@ -197,7 +198,7 @@ big-endian off
     [
         ! Untag temp0
         temp0 tag-mask get bitnot AND
-        ! Set temp1 to 0 for objects, and 8 for tuples
+        ! Set temp1 to 0 for objects, and bootstrap-cell for tuples
         temp1 1 tag-fixnum AND
         bootstrap-cell 4 = [ temp1 1 SHR ] when
         ! Load header cell or tuple layout cell
@@ -214,7 +215,7 @@ big-endian off
     temp1 temp2 CMP
 ] pic-check jit-define
 
-[ f JE rc-relative rt-xt jit-rel ] pic-hit jit-define
+[ 0 JE rc-relative rt-xt jit-rel ] pic-hit jit-define
 
 ! ! ! Megamorphic caches
 
@@ -232,12 +233,13 @@ big-endian off
     temp0 temp2 ADD
     ! if(get(cache) == class)
     temp0 [] temp1 CMP
-    ! ... goto get(cache + bootstrap-cell)
-    [
-        temp0 temp0 bootstrap-cell [+] MOV
-        temp0 word-xt-offset [+] JMP
-    ] [ ] make
-    [ length JNE ] [ % ] bi
+    bootstrap-cell 4 = 14 22 ? JNE ! Yuck!
+    ! megamorphic_cache_hits++
+    temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
+    temp1 [] 1 ADD
+    ! goto get(cache + bootstrap-cell)
+    temp0 temp0 bootstrap-cell [+] MOV
+    temp0 word-xt-offset [+] JMP
     ! fall-through on miss
 ] mega-lookup jit-define
 
index 2859e71be2b6e8932eff788a98f544fbf6838759..e12cec9738a0051e65a6f75333cb41a79752fd97 100644 (file)
@@ -11,6 +11,10 @@ IN: cpu.x86
 
 << enable-fixnum-log2 >>
 
+! Add some methods to the assembler to be more useful to the backend
+M: label JMP 0 JMP rc-relative label-fixup ;
+M: label JUMPcc [ 0 ] dip JUMPcc rc-relative label-fixup ;
+
 M: x86 two-operand? t ;
 
 HOOK: temp-reg-1 cpu ( -- reg )
@@ -19,6 +23,8 @@ HOOK: temp-reg-2 cpu ( -- reg )
 HOOK: param-reg-1 cpu ( -- reg )
 HOOK: param-reg-2 cpu ( -- reg )
 
+HOOK: pic-tail-reg cpu ( -- reg )
+
 M: x86 %load-immediate MOV ;
 
 M: x86 %load-reference swap 0 MOV rc-absolute-cell rel-immediate ;
@@ -53,8 +59,18 @@ M: x86 stack-frame-size ( stack-frame -- i )
     reserved-area-size +
     align-stack ;
 
-M: x86 %call ( label -- ) CALL ;
-M: x86 %jump-label ( label -- ) JMP ;
+M: x86 %call ( word -- ) 0 CALL rc-relative rel-word-pic ;
+
+: xt-tail-pic-offset ( -- n )
+    #! See the comment in vm/cpu-x86.hpp
+    cell 4 + 1 + ; inline
+
+M: x86 %jump ( word -- )
+    pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here
+    0 JMP rc-relative rel-word-pic-tail ;
+
+M: x86 %jump-label ( label -- ) 0 JMP rc-relative label-fixup ;
+
 M: x86 %return ( -- ) 0 RET ;
 
 : code-alignment ( align -- n )
index 12e39746c7278f85b728f722ab9922e4d5fa5b43..e210ad35ced613e9bbea301958d5548596e8cbd6 100755 (executable)
@@ -15,6 +15,7 @@ $nl
 "Iterating over elements:"
 { $subsection dlist-each }
 { $subsection dlist-find }
+{ $subsection dlist-filter }
 { $subsection dlist-any? }
 "Deleting a node matching a predicate:"
 { $subsection delete-node-if* }
@@ -40,6 +41,11 @@ HELP: dlist-find
     "This operation is O(n)."
 } ;
 
+HELP: dlist-filter
+{ $values { "dlist" { $link dlist } } { "quot" quotation } { "dlist" { $link dlist } } }
+{ $description "Applies the quotation to each element of the " { $link dlist } " in turn, removing the corresponding nodes if the quotation returns " { $link f } "." }
+{ $side-effects { "dlist" } } ;
+
 HELP: dlist-any?
 { $values { "dlist" { $link dlist } } { "quot" quotation } { "?" "a boolean" } }
 { $description "Just like " { $link dlist-find } " except it doesn't return the object." }
index 3689680157d82898e0e9f89b94dcf1aa223987dc..8072c93753c0be2be127ebe39d73f8e436c5af4f 100755 (executable)
@@ -79,3 +79,8 @@ IN: dlists.tests
 [ V{ f 3 1 f } ] [ <dlist> 1 over push-front 3 over push-front f over push-front f over push-back dlist>seq ] unit-test
 
 [ V{ } ] [ <dlist> dlist>seq ] unit-test
+
+[ V{ 0 2 4 } ] [ <dlist> { 0 1 2 3 4 } over push-all-back [ even? ] dlist-filter dlist>seq ] unit-test
+[ V{ 2 4 } ] [ <dlist> { 1 2 3 4 } over push-all-back [ even? ] dlist-filter dlist>seq ] unit-test
+[ V{ 2 4 } ] [ <dlist> { 1 2 3 4 5 } over push-all-back [ even? ] dlist-filter dlist>seq ] unit-test
+[ V{ 0 2 4 } ] [ <dlist> { 0 1 2 3 4 5 } over push-all-back [ even? ] dlist-filter dlist>seq ] unit-test
index 3d7224ed1631eed46dcdddadc028a0fea4cdaffd..89675c6469cbeae1fc2ca3d1f85d1801e5ebadd3 100755 (executable)
@@ -95,7 +95,7 @@ M: dlist pop-front* ( dlist -- )
     [
         [
             [ empty-dlist ] unless*
-            [ f ] change-next drop
+            next>>
             f over set-prev-when
         ] change-front drop
     ] keep
@@ -108,7 +108,7 @@ M: dlist pop-back* ( dlist -- )
     [
         [
             [ empty-dlist ] unless*
-            [ f ] change-prev drop
+            prev>>
             f over set-next-when
         ] change-back drop
     ] keep
@@ -157,6 +157,9 @@ M: dlist clear-deque ( dlist -- )
 
 : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 
+: dlist-filter ( dlist quot -- dlist )
+    over [ '[ dup obj>> @ [ drop ] [ _ delete-node ] if ] dlist-each-node ] keep ; inline
+
 M: dlist clone
     <dlist> [ '[ _ push-back ] dlist-each ] keep ;
 
index 5d750775e571d0885fc70b2dc49c7a1f37e3d435..32ad856d004e9c82f350a91f048fae609039b790 100644 (file)
@@ -57,7 +57,6 @@ $nl
 "Here are some built-in combinators rewritten in terms of fried quotations:"\r
 { $table\r
     { { $link literalize } { $snippet ": literalize '[ _ ] ;" } }\r
-    { { $link slip } { $snippet ": slip '[ @ _ ] call ;" } }\r
     { { $link curry } { $snippet ": curry '[ _ @ ] ;" } }\r
     { { $link compose } { $snippet ": compose '[ @ @ ] ;" } }\r
     { { $link bi@ } { $snippet ": bi@ tuck '[ _ @ _ @ ] call ;" } }\r
index 36715111940242937ab1e43d6976993a4151f139..d6a3aa948a8489f0bfdc4cf2f722a412cc411f0e 100644 (file)
@@ -161,22 +161,6 @@ HELP: ndip
     }\r
 } ;\r
 \r
-HELP: nslip\r
-{ $values { "n" integer } }\r
-{ $description "A generalization of " { $link slip } " that can work " \r
-"for any stack depth. The first " { $snippet "n" } " items after the quotation will be "\r
-"removed from the stack, the quotation called, and the items restored."\r
-} \r
-{ $examples\r
-  { $example "USING: generalizations kernel prettyprint ;" "[ 99 ] 1 2 3 4 5 5 nslip 6 narray ." "{ 99 1 2 3 4 5 }" }\r
-  "Some core words expressed in terms of " { $link nslip } ":"\r
-    { $table\r
-        { { $link slip } { $snippet "1 nslip" } }\r
-        { { $link 2slip } { $snippet "2 nslip" } }\r
-        { { $link 3slip } { $snippet "3 nslip" } }\r
-    }\r
-} ;\r
-\r
 HELP: nkeep\r
 { $values { "quot" quotation } { "n" integer } }\r
 { $description "A generalization of " { $link keep } " that can work " \r
@@ -339,7 +323,6 @@ ARTICLE: "shuffle-generalizations" "Generalized shuffle words"
 \r
 ARTICLE: "combinator-generalizations" "Generalized combinators"\r
 { $subsection ndip }\r
-{ $subsection nslip }\r
 { $subsection nkeep }\r
 { $subsection napply }\r
 { $subsection ncleave }\r
index 7ede271d017d0fec830904498e06e664b7bdb913..d0f614f9cdbaeb6cba920e90280f333435fbe68e 100644 (file)
@@ -26,8 +26,6 @@ IN: generalizations.tests
 [ [ 1 ] 5 ndip ] must-infer\r
 [ 1 2 3 4 ] [ 2 3 4 [ 1 ] 3 ndip ] unit-test\r
 \r
-[ [ 99 ] 1 2 3 4 5 5 nslip ] must-infer\r
-{ 99 1 2 3 4 5 } [ [ 99 ] 1 2 3 4 5 5 nslip ] unit-test\r
 [ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] must-infer\r
 { 2 1 2 3 4 5 } [ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] unit-test\r
 [ [ 1 2 3 + ] ] [ 1 2 3 [ + ] 3 ncurry ] unit-test\r
index 139b7a528add97756ddd2848585b57fc7368e7fc..397166a4182af0bb28febe6fd5f38577a6fcb4d4 100644 (file)
@@ -60,9 +60,6 @@ MACRO: ntuck ( n -- )
 MACRO: ndip ( quot n -- )
     [ '[ _ dip ] ] times ;
 
-MACRO: nslip ( n -- )
-    '[ [ call ] _ ndip ] ;
-
 MACRO: nkeep ( quot n -- )
     tuck '[ _ ndup _ _ ndip ] ;
 
index 6bf1ea2ff115175c3f28b0746092399812d9d627..27dc25de7374a2404da0eb8b54438d61495296ee 100755 (executable)
@@ -5,7 +5,7 @@ compression.lzw constructors endian fry grouping images io
 io.binary io.encodings.ascii io.encodings.binary
 io.encodings.string io.encodings.utf8 io.files kernel math
 math.bitwise math.order math.parser pack prettyprint sequences
-strings math.vectors specialized-arrays.float ;
+strings math.vectors specialized-arrays.float locals ;
 IN: images.tiff
 
 TUPLE: tiff-image < image ;
@@ -184,7 +184,7 @@ samples-per-pixel new-subfile-type subfile-type orientation
 software date-time photoshop exif-ifd sub-ifd inter-color-profile
 xmp iptc fill-order document-name page-number page-name
 x-position y-position host-computer copyright artist
-min-sample-value max-sample-value make model cell-width cell-length
+min-sample-value max-sample-value tiff-make tiff-model cell-width cell-length
 gray-response-unit gray-response-curve color-map threshholding
 image-description free-offsets free-byte-counts tile-width tile-length
 matteing data-type image-depth tile-depth
@@ -243,10 +243,13 @@ ERROR: bad-tiff-magic bytes ;
 
 ERROR: no-tag class ;
 
-: find-tag ( idf class -- tag )
-    swap processed-tags>> ?at [ no-tag ] unless ;
+: find-tag* ( ifd class -- tag/class ? )
+    swap processed-tags>> ?at ;
 
-: tag? ( idf class -- tag )
+: find-tag ( ifd class -- tag )
+    find-tag* [ no-tag ] unless ;
+
+: tag? ( ifd class -- tag )
     swap processed-tags>> key? ;
 
 : read-strips ( ifd -- ifd )
@@ -339,8 +342,8 @@ ERROR: bad-small-ifd-type n ;
         { 266 [ fill-order ] }
         { 269 [ ascii decode document-name ] }
         { 270 [ ascii decode image-description ] }
-        { 271 [ ascii decode make ] }
-        { 272 [ ascii decode model ] }
+        { 271 [ ascii decode tiff-make ] }
+        { 272 [ ascii decode tiff-model ] }
         { 273 [ strip-offsets ] }
         { 274 [ orientation ] }
         { 277 [ samples-per-pixel ] }
@@ -350,7 +353,7 @@ ERROR: bad-small-ifd-type n ;
         { 281 [ max-sample-value ] }
         { 282 [ first x-resolution ] }
         { 283 [ first y-resolution ] }
-        { 284 [ planar-configuration ] }
+        { 284 [ lookup-planar-configuration planar-configuration ] }
         { 285 [ page-name ] }
         { 286 [ x-position ] }
         { 287 [ y-position ] }
@@ -437,8 +440,8 @@ ERROR: unhandled-compression compression ;
     [ samples-per-pixel find-tag ] tri
     [ * ] keep
     '[
-        _ group [ _ group [ rest ] [ first ] bi
-        [ v+ ] accumulate swap suffix concat ] map
+        _ group
+        [ _ group unclip [ v+ ] accumulate swap suffix concat ] map
         concat >byte-array
     ] change-bitmap ;
 
@@ -521,23 +524,39 @@ ERROR: unknown-component-order ifd ;
         ] with-tiff-endianness
     ] with-file-reader ;
 
-: process-tif-ifds ( parsed-tiff -- parsed-tiff )
-    dup ifds>> [
-        read-strips
-        uncompress-strips
-        strips>bitmap
-        fix-bitmap-endianness
-        strips-predictor
-        dup extra-samples tag? [ handle-alpha-data ] when
-        drop
-    ] each ;
+: process-chunky-ifd ( ifd -- )
+    read-strips
+    uncompress-strips
+    strips>bitmap
+    fix-bitmap-endianness
+    strips-predictor
+    dup extra-samples tag? [ handle-alpha-data ] when
+    drop ;
+
+: process-planar-ifd ( ifd -- )
+    "planar ifd not supported" throw ;
+
+: dispatch-planar-configuration ( ifd planar-configuration -- )
+    {
+        { planar-configuration-chunky [ process-chunky-ifd ] }
+        { planar-configuration-planar [ process-planar-ifd ] }
+    } case ;
+
+: process-ifd ( ifd -- )
+    dup planar-configuration find-tag* [
+        dispatch-planar-configuration
+    ] [
+        drop "no planar configuration" throw
+    ] if ;
+
+: process-tif-ifds ( parsed-tiff -- )
+    ifds>> [ process-ifd ] each ;
 
 : load-tiff ( path -- parsed-tiff )
-    [ load-tiff-ifds ] [
-        binary [
-            [ process-tif-ifds ] with-tiff-endianness
-        ] with-file-reader
-    ] bi ;
+    [ load-tiff-ifds dup ] keep
+    binary [
+        [ process-tif-ifds ] with-tiff-endianness
+    ] with-file-reader ;
 
 ! tiff files can store several images -- we just take the first for now
 M: tiff-image load-image* ( path tiff-image -- image )
diff --git a/basis/io/backend/windows/privileges/privileges-tests.factor b/basis/io/backend/windows/privileges/privileges-tests.factor
new file mode 100755 (executable)
index 0000000..7237651
--- /dev/null
@@ -0,0 +1,4 @@
+IN: io.backend.windows.privileges.tests\r
+USING: io.backend.windows.privileges tools.test ;\r
+\r
+[ [ ] with-privileges ] must-infer\r
old mode 100644 (file)
new mode 100755 (executable)
index 8661ba9..58806cc
@@ -1,12 +1,13 @@
 USING: io.backend kernel continuations sequences\r
-system vocabs.loader combinators ;\r
+system vocabs.loader combinators fry ;\r
 IN: io.backend.windows.privileges\r
 \r
-HOOK: set-privilege io-backend ( name ? -- ) inline\r
+HOOK: set-privilege io-backend ( name ? -- )\r
 \r
 : with-privileges ( seq quot -- )\r
-    over [ [ t set-privilege ] each ] curry compose\r
-    swap [ [ f set-privilege ] each ] curry [ ] cleanup ; inline\r
+    [ '[ _ [ t set-privilege ] each @ ] ]\r
+    [ drop '[ _ [ f set-privilege ] each ] ]\r
+    2bi [ ] cleanup ; inline\r
 \r
 {\r
     { [ os winnt? ] [ "io.backend.windows.nt.privileges" require ] }\r
index a6c82a1bff21e16ae374384c388fb943b051e88b..6bfaa07227058fb8f32f91f1b9ab15a8665fbf8c 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel quotations ;
+USING: help.markup help.syntax kernel quotations sequences ;
 IN: io.directories.search
 
 HELP: each-file
@@ -57,6 +57,32 @@ HELP: find-all-in-directories
 }
 { $description "Finds all files in the input directories matching the predicate quotation in a breadth-first or depth-first traversal." } ;
 
+HELP: find-by-extension
+{ $values
+    { "path" "a pathname string" } { "extension" "a file extension" }
+    { "seq" sequence }
+}
+{ $description "Searches a directory for all files with the given extension. File extension and filenames are converted to lower-case and compared using the " { $link tail? } " word. The file extension should contain the period." }
+{ $examples
+    { $unchecked-example
+        "USING: io.directories.search ;"
+        "\"/\" \".mp3\" find-by-extension"
+    }
+} ;
+
+HELP: find-by-extensions
+{ $values
+    { "path" "a pathname string" } { "extensions" "a sequence of file extensions" }
+    { "seq" sequence }
+}
+{ $description "Searches a directory for all files in the given list of extensions. File extensions and filenames are converted to lower-case and compared using the " { $link tail? } " word. File extensions should contain the period." }
+{ $examples
+    { $unchecked-example
+        "USING: io.directories.search ;"
+        "\"/\" { \".jpg\" \".gif\" \".tiff\" \".png\" \".bmp\" } find-by-extensions"
+    }
+} ;
+
 { find-file find-all-files find-in-directories find-all-in-directories } related-words
 
 ARTICLE: "io.directories.search" "Searching directories"
@@ -65,10 +91,13 @@ ARTICLE: "io.directories.search" "Searching directories"
 { $subsection recursive-directory-files }
 { $subsection recursive-directory-entries }
 { $subsection each-file }
-"Finding files:"
+"Finding files by name:"
 { $subsection find-file }
 { $subsection find-all-files }
 { $subsection find-in-directories }
-{ $subsection find-all-in-directories } ;
+{ $subsection find-all-in-directories }
+"Finding files by extension:"
+{ $subsection find-by-extension }
+{ $subsection find-by-extensions } ;
 
 ABOUT: "io.directories.search"
index f7d18306f8a1cff9bd106da87dd48a29425ea299..3fbf09a3c3a71ef1a91e69998ef9ce7d38bf626e 100755 (executable)
@@ -3,7 +3,7 @@
 USING: accessors arrays continuations deques dlists fry
 io.directories io.files io.files.info io.pathnames kernel
 sequences system vocabs.loader locals math namespaces
-sorting assocs calendar threads io math.parser ;
+sorting assocs calendar threads io math.parser unicode.case ;
 IN: io.directories.search
 
 : qualified-directory-entries ( path -- seq )
@@ -106,4 +106,11 @@ ERROR: file-not-found path bfs? quot ;
         ] { } map>assoc
     ] with-qualified-directory-entries sort-values ;
 
+: find-by-extensions ( path extensions -- seq )
+    [ >lower ] map
+    '[ >lower _ [ tail? ] with any? ] find-all-files ;
+    
+: find-by-extension ( path extension -- seq )
+    1array find-by-extensions ;
+
 os windows? [ "io.directories.search.windows" require ] when
index 0e4338e3e0415d37a530e5a3d74da5c2de9e477d..a7ae317668bd1a01790821e4bb35a1e52b062a20 100644 (file)
@@ -35,6 +35,9 @@ SYMBOL: unique-retries
 : random-name ( -- string )
     unique-length get [ random-ch ] "" replicate-as ;
 
+: retry ( quot: ( -- ? )  n -- )
+    swap [ drop ] prepose attempt-all ; inline
+
 : (make-unique-file) ( path prefix suffix -- path )
     '[
         _ _ _ random-name glue append-path
index 99d45e4fd7ca0c80a40eeeef030ddd2de8347c0d..852d8171e403233ea31a49ea4d295fe7ed2eb5ac 100644 (file)
@@ -48,7 +48,7 @@ concurrency.promises threads unix.process ;
     try-process
 ] unit-test
 
-[ f ] [
+[ "" ] [
     "cat"
     "launcher-test-1" temp-file
     2array
index 53b3d3ce7eb019ce51ebcbb0012a8e5815d91fce..4587556e0c2692710c5b39ce3a191106e5666d72 100755 (executable)
@@ -42,7 +42,7 @@ IN: io.launcher.windows.nt.tests
         console-vm "-run=listener" 2array >>command
         +closed+ >>stdin
         +stdout+ >>stderr
-    ascii [ input-stream get contents ] with-process-reader
+    ascii [ contents ] with-process-reader
 ] unit-test
 
 : launcher-test-path ( -- str )
@@ -85,7 +85,7 @@ IN: io.launcher.windows.nt.tests
         <process>
             console-vm "-script" "stderr.factor" 3array >>command
             "err2.txt" temp-file >>stderr
-        ascii <process-reader> lines first
+        ascii <process-reader> stream-lines first
     ] with-directory
 ] unit-test
 
@@ -97,7 +97,7 @@ IN: io.launcher.windows.nt.tests
     launcher-test-path [
         <process>
             console-vm "-script" "env.factor" 3array >>command
-        ascii <process-reader> contents
+        ascii <process-reader> stream-contents
     ] with-directory eval( -- alist )
 
     os-envs =
@@ -109,7 +109,7 @@ IN: io.launcher.windows.nt.tests
             console-vm "-script" "env.factor" 3array >>command
             +replace-environment+ >>environment-mode
             os-envs >>environment
-        ascii <process-reader> contents
+        ascii <process-reader> stream-contents
     ] with-directory eval( -- alist )
     
     os-envs =
@@ -120,7 +120,7 @@ IN: io.launcher.windows.nt.tests
         <process>
             console-vm "-script" "env.factor" 3array >>command
             { { "A" "B" } } >>environment
-        ascii <process-reader> contents
+        ascii <process-reader> stream-contents
     ] with-directory eval( -- alist )
 
     "A" swap at
@@ -132,7 +132,7 @@ IN: io.launcher.windows.nt.tests
             console-vm "-script" "env.factor" 3array >>command
             { { "USERPROFILE" "XXX" } } >>environment
             +prepend-environment+ >>environment-mode
-        ascii <process-reader> contents
+        ascii <process-reader> stream-contents
     ] with-directory eval( -- alist )
 
     "USERPROFILE" swap at "XXX" =
index 967c0d461347c1c1075379c8c430290f6bdf8a19..27971f14316fab75f4a62f5c831ca04c92e317a6 100644 (file)
@@ -2,6 +2,8 @@ USING: io.streams.string io kernel arrays namespaces make
 tools.test ;
 IN: io.streams.string.tests
 
+[ "" ] [ "" [ contents ] with-string-reader ] unit-test
+
 [ "line 1" CHAR: l ]
 [
     "line 1\nline 2\nline 3" <string-reader>
index 0d61dcb467534b754c888e9131ed131fe90bba00..9dd398d962425b56c5a8b7bac3be42bb2b599fc5 100644 (file)
@@ -21,7 +21,7 @@ CONSTANT: five 5
 USING: kernel literals prettyprint ;
 IN: scratchpad
 
-<< : seven-eleven ( -- a b ) 7 11 ; >>
+: seven-eleven ( -- a b ) 7 11 ;
 { $ seven-eleven } .
     "> "{ 7 11 }" }
 
@@ -43,7 +43,24 @@ IN: scratchpad
 
 } ;
 
-{ POSTPONE: $ POSTPONE: $[ } related-words
+HELP: ${
+{ $syntax "${ code }" }
+{ $description "Outputs an array containing the results of executing " { $snippet "code" } " at parse time." }
+{ $notes { $snippet "code" } "'s definition is looked up and " { $link call } "ed at parse time, so words that reference words in the current compilation unit cannot be used with " { $snippet "$" } "." }
+{ $examples
+
+    { $example <"
+USING: kernel literals math prettyprint ;
+IN: scratchpad
+
+CONSTANT: five 5
+CONSTANT: six 6
+${ five six 7 } .
+    "> "{ 5 6 7 }"
+    }
+} ;
+
+{ POSTPONE: $ POSTPONE: $[ POSTPONE: ${ } related-words
 
 ARTICLE: "literals" "Interpolating code results into literal values"
 "The " { $vocab-link "literals" } " vocabulary contains words to run code at parse time and insert the results into more complex literal values."
@@ -51,11 +68,12 @@ ARTICLE: "literals" "Interpolating code results into literal values"
 USING: kernel literals math prettyprint ;
 IN: scratchpad
 
-<< CONSTANT: five 5 >>
+CONSTANT: five 5
 { $ five $[ five dup 1+ dup 2 + ] } .
     "> "{ 5 5 6 8 }" }
 { $subsection POSTPONE: $ }
 { $subsection POSTPONE: $[ }
+{ $subsection POSTPONE: ${ }
 ;
 
 ABOUT: "literals"
old mode 100644 (file)
new mode 100755 (executable)
index 29072f1..d7256a6
@@ -20,8 +20,10 @@ IN: literals.tests
 
 [ { 1.0 { 0.5 1.5 } 4.0 } ] [ { 1.0 { $[ 1.0 2.0 / ] 1.5 } $[ 2.0 2.0 * ] } ] unit-test
 
-<<
 CONSTANT: constant-a 3
->>
 
 [ { 3 10 "ftw" } ] [ ${ constant-a 10 "ftw" } ] unit-test
+
+: sixty-nine ( -- a b ) 6 9 ;
+
+[ { 6 9 } ] [ ${ sixty-nine } ] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index 7c7592d..ba1da39
@@ -1,8 +1,21 @@
 ! (c) Joe Groff, see license for details
 USING: accessors continuations kernel parser words quotations
-combinators.smart vectors sequences ;
+combinators.smart vectors sequences fry ;
 IN: literals
 
-SYNTAX: $ scan-word [ def>> call ] curry with-datastack >vector ;
+<PRIVATE
+
+! Use def>> call so that CONSTANT:s defined in the same file can
+! be called
+
+: expand-literal ( seq obj -- seq' )
+    '[ _ dup word? [ def>> call ] when ] with-datastack ;
+
+: expand-literals ( seq -- seq' )
+    [ [ { } ] dip expand-literal ] map concat ;
+
+PRIVATE>
+
+SYNTAX: $ scan-word expand-literal >vector ;
 SYNTAX: $[ parse-quotation with-datastack >vector ;
-SYNTAX: ${ \ } [ [ ?execute ] { } map-as ] parse-literal ;
+SYNTAX: ${ \ } [ expand-literals ] parse-literal ;
index 8920955df340f8a9b11b219ffeddc530252f53f4..72b83a991ffd99f1eafeb67433bf0aed5cd256ea 100644 (file)
@@ -7,7 +7,7 @@ TUPLE: bits { number read-only } { length read-only } ;
 C: <bits> bits
 
 : make-bits ( number -- bits )
-    dup zero? [ drop T{ bits f 0 0 } ] [ dup abs log2 1+ <bits> ] if ; inline
+    dup zero? [ drop T{ bits f 0 0 } ] [ dup abs log2 1 + <bits> ] if ; inline
 
 M: bits length length>> ;
 
index 3148567bc0a0cdf9649dbf822ce9fce4b59f0f69..ff4806348b5ade12deb50c130e3cd2197133e3e5 100755 (executable)
@@ -13,10 +13,10 @@ IN: math.bitwise
 : unmask? ( x n -- ? ) unmask 0 > ; inline
 : mask ( x n -- ? ) bitand ; inline
 : mask? ( x n -- ? ) mask 0 > ; inline
-: wrap ( m n -- m' ) 1- bitand ; inline
+: wrap ( m n -- m' ) 1 - bitand ; inline
 : bits ( m n -- m' ) 2^ wrap ; inline
 : mask-bit ( m n -- m' ) 2^ mask ; inline
-: on-bits ( n -- m ) 2^ 1- ; inline
+: on-bits ( n -- m ) 2^ 1 - ; inline
 : toggle-bit ( m n -- m' ) 2^ bitxor ; inline
 
 : shift-mod ( n s w -- n )
@@ -35,6 +35,11 @@ IN: math.bitwise
 : w- ( int int -- int ) - 32 bits ; inline
 : w* ( int int -- int ) * 32 bits ; inline
 
+! 64-bit arithmetic
+: W+ ( int int -- int ) + 64 bits ; inline
+: W- ( int int -- int ) - 64 bits ; inline
+: W* ( int int -- int ) * 64 bits ; inline
+
 ! flags
 MACRO: flags ( values -- )
     [ 0 ] [ [ ?execute bitor ] curry compose ] reduce ;
@@ -64,8 +69,8 @@ DEFER: byte-bit-count
 <<
 
 \ byte-bit-count
-256 [
-    8 <bits> 0 [ [ 1+ ] when ] reduce
+256 iota [
+    8 <bits> 0 [ [ 1 + ] when ] reduce
 ] B{ } map-as '[ HEX: ff bitand _ nth-unsafe ]
 (( byte -- table )) define-declared
 
@@ -97,12 +102,19 @@ PRIVATE>
 
 ! Signed byte array to integer conversion
 : signed-le> ( bytes -- x )
-    [ le> ] [ length 8 * 1- on-bits ] bi
+    [ le> ] [ length 8 * 1 - on-bits ] bi
     2dup > [ bitnot bitor ] [ drop ] if ;
 
 : signed-be> ( bytes -- x )
     <reversed> signed-le> ;
 
 : >signed ( x n -- y )
-    2dup neg 1+ shift 1 = [ 2^ - ] [ drop ] if ;
+    2dup neg 1 + shift 1 = [ 2^ - ] [ drop ] if ;
+
+: >odd ( n -- int ) 0 set-bit ; foldable
+
+: >even ( n -- int ) 0 clear-bit ; foldable
+
+: next-even ( m -- n ) >even 2 + ; foldable
 
+: next-odd ( m -- n ) dup even? [ 1 + ] [ 2 + ] if ; foldable
index d7c6ebc92739083c13b1dd176f489343a26ca124..3017a12b18c02c66d8dfbf71c77b84a9ef83adda 100755 (executable)
@@ -164,7 +164,7 @@ M: VECTOR element-type
 M: VECTOR Vswap
     (prepare-swap) [ XSWAP ] 2dip ;
 M: VECTOR Viamax
-    (prepare-nrm2) IXAMAX 1- ;
+    (prepare-nrm2) IXAMAX 1 - ;
 
 M: VECTOR (blas-vector-like)
     drop <VECTOR> ;
index 514c808ee0bc5f40a80efe4ea7495d8f5989b1e2..041539c9815c2aaa82611688731e7f0df1ae3239 100644 (file)
@@ -1,37 +1,93 @@
-USING: help.markup help.syntax kernel math math.order sequences ;
+USING: help.markup help.syntax kernel math math.order multiline sequences ;
 IN: math.combinatorics
 
 HELP: factorial
 { $values { "n" "a non-negative integer" } { "n!" integer } }
 { $description "Outputs the product of all positive integers less than or equal to " { $snippet "n" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "4 factorial ." "24" } } ;
+{ $examples 
+    { $example "USING: math.combinatorics prettyprint ;"
+        "4 factorial ." "24" }
+} ;
 
 HELP: nPk
 { $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nPk" integer } }
 { $description "Outputs the total number of unique permutations of size " { $snippet "k" } " (order does matter) that can be taken from a set of size " { $snippet "n" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nPk ." "5040" } } ;
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "10 4 nPk ." "5040" }
+} ;
 
 HELP: nCk
 { $values { "n" "a non-negative integer" } { "k" "a non-negative integer" } { "nCk" integer } }
 { $description "Outputs the total number of unique combinations of size " { $snippet "k" } " (order does not matter) that can be taken from a set of size " { $snippet "n" } ". Commonly written as \"n choose k\"." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "10 4 nCk ." "210" } } ;
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "10 4 nCk ." "210" }
+} ;
 
 HELP: permutation
 { $values { "n" "a non-negative integer" } { "seq" sequence } { "seq" sequence } }
 { $description "Outputs the " { $snippet "nth" } " lexicographical permutation of " { $snippet "seq" } "." }
 { $notes "Permutations are 0-based and a bounds error will be thrown if " { $snippet "n" } " is larger than " { $snippet "seq length factorial 1-" } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "1 3 permutation ." "{ 0 2 1 }" } { $example "USING: math.combinatorics prettyprint ;" "5 { \"apple\" \"banana\" \"orange\" } permutation ." "{ \"orange\" \"banana\" \"apple\" }" } } ;
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "1 3 permutation ." "{ 0 2 1 }" }
+    { $example "USING: math.combinatorics prettyprint ;"
+        "5 { \"apple\" \"banana\" \"orange\" } permutation ." "{ \"orange\" \"banana\" \"apple\" }" }
+} ;
 
 HELP: all-permutations
 { $values { "seq" sequence } { "seq" sequence } }
 { $description "Outputs a sequence containing all permutations of " { $snippet "seq" } " in lexicographical order." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "3 all-permutations ." "{ { 0 1 2 } { 0 2 1 } { 1 0 2 } { 1 2 0 } { 2 0 1 } { 2 1 0 } }" } } ;
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "3 all-permutations ." "{ { 0 1 2 } { 0 2 1 } { 1 0 2 } { 1 2 0 } { 2 0 1 } { 2 1 0 } }" }
+} ;
+
+HELP: each-permutation
+{ $values { "seq" sequence } { "quot" { $quotation "( seq -- )" } } }
+{ $description "Applies the quotation to each permuation of " { $snippet "seq" } " in order." } ;
 
 HELP: inverse-permutation
 { $values { "seq" sequence } { "permutation" sequence } }
 { $description "Outputs a sequence of indices representing the lexicographical permutation of " { $snippet "seq" } "." }
 { $notes "All items in " { $snippet "seq" } " must be comparable by " { $link <=> } "." }
-{ $examples { $example "USING: math.combinatorics prettyprint ;" "\"dcba\" inverse-permutation ." "{ 3 2 1 0 }" } { $example "USING: math.combinatorics prettyprint ;" "{ 12 56 34 78 } inverse-permutation ." "{ 0 2 1 3 }" } } ;
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "\"dcba\" inverse-permutation ." "{ 3 2 1 0 }" }
+    { $example "USING: math.combinatorics prettyprint ;"
+        "{ 12 56 34 78 } inverse-permutation ." "{ 0 2 1 3 }" }
+} ;
+
+HELP: combination
+{ $values { "m" "a non-negative integer" } { "seq" sequence } { "k" "a non-negative integer" } { "seq" sequence } }
+{ $description "Outputs the " { $snippet "mth" } " lexicographical combination of " { $snippet "seq" } " choosing " { $snippet "k" } " elements." }
+{ $notes "Combinations are 0-based and a bounds error will be thrown if " { $snippet "m" } " is larger than " { $snippet "seq length k nCk" } "." }
+{ $examples
+    { $example "USING: math.combinatorics sequences prettyprint ;"
+        "6 7 iota 4 combination ." "{ 0 1 3 6 }" }
+    { $example "USING: math.combinatorics prettyprint ;"
+        "0 { \"a\" \"b\" \"c\" \"d\" } 2 combination ." "{ \"a\" \"b\" }" }
+} ;
+
+HELP: all-combinations
+{ $values { "seq" sequence } { "k" "a non-negative integer" } { "seq" sequence } }
+{ $description "Outputs a sequence containing all combinations of " { $snippet "seq" } " choosing " { $snippet "k" } " elements, in lexicographical order." }
+{ $examples
+    { $example "USING: math.combinatorics prettyprint ;"
+        "{ \"a\" \"b\" \"c\" \"d\" } 2 all-combinations ."
+<" {
+    { "a" "b" }
+    { "a" "c" }
+    { "a" "d" }
+    { "b" "c" }
+    { "b" "d" }
+    { "c" "d" }
+}"> } } ;
+
+HELP: each-combination
+{ $values { "seq" sequence } { "k" "a non-negative integer" } { "quot" { $quotation "( seq -- )" } } }
+{ $description "Applies the quotation to each combination of " { $snippet "seq" } " choosing " { $snippet "k" } " elements, in order." } ;
 
 
 IN: math.combinatorics.private
index 5ef435a4e0a0ae427634d8ea847570299021134d..ca6ec9cb53c02d0d5722d8bf70eae70bfd3cd4b9 100644 (file)
@@ -1,18 +1,6 @@
-USING: math.combinatorics math.combinatorics.private tools.test ;
+USING: math.combinatorics math.combinatorics.private tools.test sequences ;
 IN: math.combinatorics.tests
 
-[ { } ] [ 0 factoradic ] unit-test
-[ { 1 0 } ] [ 1 factoradic ] unit-test
-[ { 1 1 0 3 0 1 0 } ] [ 859 factoradic ] unit-test
-
-[ { 0 1 2 3 } ] [ { 0 0 0 0 } >permutation ] unit-test
-[ { 0 1 3 2 } ] [ { 0 0 1 0 } >permutation ] unit-test
-[ { 1 2 0 6 3 5 4 } ] [ { 1 1 0 3 0 1 0 } >permutation ] unit-test
-
-[ { 0 1 2 3 } ] [ 0 4 permutation-indices ] unit-test
-[ { 0 1 3 2 } ] [ 1 4 permutation-indices ] unit-test
-[ { 1 2 0 6 3 5 4 } ] [ 859 7 permutation-indices ] unit-test
-
 [ 1 ] [ 0 factorial ] unit-test
 [ 1 ] [ 1 factorial ] unit-test
 [ 3628800 ] [ 10 factorial ] unit-test
@@ -31,6 +19,19 @@ IN: math.combinatorics.tests
 [ 2598960 ] [ 52 5 nCk ] unit-test
 [ 2598960 ] [ 52 47 nCk ] unit-test
 
+
+[ { } ] [ 0 factoradic ] unit-test
+[ { 1 0 } ] [ 1 factoradic ] unit-test
+[ { 1 1 0 3 0 1 0 } ] [ 859 factoradic ] unit-test
+
+[ { 0 1 2 3 } ] [ { 0 0 0 0 } >permutation ] unit-test
+[ { 0 1 3 2 } ] [ { 0 0 1 0 } >permutation ] unit-test
+[ { 1 2 0 6 3 5 4 } ] [ { 1 1 0 3 0 1 0 } >permutation ] unit-test
+
+[ { 0 1 2 3 } ] [ 0 4 iota permutation-indices ] unit-test
+[ { 0 1 3 2 } ] [ 1 4 iota permutation-indices ] unit-test
+[ { 1 2 0 6 3 5 4 } ] [ 859 7 iota permutation-indices ] unit-test
+
 [ { "a" "b" "c" "d" } ] [ 0 { "a" "b" "c" "d" } permutation ] unit-test
 [ { "d" "c" "b" "a" } ] [ 23 { "a" "b" "c" "d" } permutation ] unit-test
 [ { "d" "a" "b" "c" } ] [ 18 { "a" "b" "c" "d" } permutation ] unit-test
@@ -43,3 +44,29 @@ IN: math.combinatorics.tests
 [ { 2 1 0 } ] [ { "c" "b" "a" } inverse-permutation ] unit-test
 [ { 3 0 2 1 } ] [ { 12 45 34 2 } inverse-permutation ] unit-test
 
+
+[ 2598960 ] [ 52 iota 5 <combo> choose ] unit-test
+
+[ 6 3 13 6 ] [ 7 4 28 next-values ] unit-test
+[ 5 2 3 5 ] [ 6 3 13 next-values ] unit-test
+[ 3 1 0 3 ] [ 5 2 3 next-values ] unit-test
+[ 0 0 0 0 ] [ 3 1 0 next-values ] unit-test
+
+[ 9 ] [ 0 5 iota 3 <combo> dual-index ] unit-test
+[ 0 ] [ 9 5 iota 3 <combo> dual-index ] unit-test
+[ 179 ] [ 72 10 iota 5 <combo> dual-index ] unit-test
+
+[ { 5 3 2 1 } ] [ 7 4 <combo> 8 combinadic ] unit-test
+[ { 4 3 2 1 0 } ] [ 10 iota 5 <combo> 0 combinadic ] unit-test
+[ { 8 6 3 1 0 } ] [ 10 iota 5 <combo> 72 combinadic ] unit-test
+[ { 9 8 7 6 5 } ] [ 10 iota 5 <combo> 251 combinadic ] unit-test
+
+[ { 0 1 2 } ] [ 0 5 iota 3 <combo> combination-indices ] unit-test
+[ { 2 3 4 } ] [ 9 5 iota 3 <combo> combination-indices ] unit-test
+
+[ { "a" "b" "c" } ] [ 0 { "a" "b" "c" "d" "e" } 3 combination ] unit-test
+[ { "c" "d" "e" } ] [ 9 { "a" "b" "c" "d" "e" } 3 combination ] unit-test
+
+[ { { "a" "b" } { "a" "c" }
+    { "a" "d" } { "b" "c" }
+    { "b" "d" } { "c" "d" } } ] [ { "a" "b" "c" "d" } 2 all-combinations ] unit-test
index afdf4e378ed2bd6d1395cc15f4b951bbac0c9a81..bc09f9fe0fa9b609147c751e7eb01a8e05fba3bc 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
+! Copyright (c) 2007-2009 Slava Pestov, Doug Coleman, Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs kernel math math.order math.ranges mirrors
-namespaces sequences sorting fry ;
+USING: accessors assocs binary-search fry kernel locals math math.order
+    math.ranges mirrors namespaces sequences sorting ;
 IN: math.combinatorics
 
 <PRIVATE
@@ -12,14 +12,27 @@ IN: math.combinatorics
 : twiddle ( n k -- n k )
     2dup - dupd > [ dupd - ] when ; inline
 
-! See this article for explanation of the factoradic-based permutation methodology:
-! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
+PRIVATE>
+
+: factorial ( n -- n! )
+    1 [ 1 + * ] reduce ;
+
+: nPk ( n k -- nPk )
+    2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
+
+: nCk ( n k -- nCk )
+    twiddle [ nPk ] keep factorial / ;
+
+
+! Factoradic-based permutation methodology
+
+<PRIVATE
 
 : factoradic ( n -- factoradic )
-    0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] produce reverse 2nip ;
+    0 [ over 0 > ] [ 1 + [ /mod ] keep swap ] produce reverse 2nip ;
 
 : (>permutation) ( seq n -- seq )
-    [ '[ _ dupd >= [ 1+ ] when ] map ] keep prefix ;
+    [ '[ _ dupd >= [ 1 + ] when ] map ] keep prefix ;
 
 : >permutation ( factoradic -- permutation )
     reverse 1 cut [ (>permutation) ] each ;
@@ -29,27 +42,84 @@ IN: math.combinatorics
 
 PRIVATE>
 
-: factorial ( n -- n! )
-    1 [ 1+ * ] reduce ;
-
-: nPk ( n k -- nPk )
-    2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
-
-: nCk ( n k -- nCk )
-    twiddle [ nPk ] keep factorial / ;
-
 : permutation ( n seq -- seq )
     [ permutation-indices ] keep nths ;
 
 : all-permutations ( seq -- seq )
-    [ length factorial ] keep '[ _ permutation ] map ;
+    [ length factorial ] keep
+    '[ _ permutation ] map ;
 
 : each-permutation ( seq quot -- )
     [ [ length factorial ] keep ] dip
     '[ _ permutation @ ] each ; inline
 
-: reduce-permutations ( seq initial quot -- result )
+: reduce-permutations ( seq identity quot -- result )
     swapd each-permutation ; inline
 
 : inverse-permutation ( seq -- permutation )
     <enum> >alist sort-values keys ;
+
+
+! Combinadic-based combination methodology
+
+<PRIVATE
+
+TUPLE: combo
+    { seq sequence }
+    { k integer } ;
+
+C: <combo> combo
+
+: choose ( combo -- nCk )
+    [ seq>> length ] [ k>> ] bi nCk ;
+
+: largest-value ( a b x -- v )
+    dup 0 = [
+        drop 1 - nip
+    ] [
+        [ [0,b) ] 2dip '[ _ nCk _ >=< ] search nip
+    ] if ;
+
+:: next-values ( a b x -- a' b' x' v )
+    a b x largest-value dup :> v  ! a'
+    b 1 -                         ! b'
+    x v b nCk -                   ! x'
+    v ;                           ! v == a'
+
+: dual-index ( m combo -- m' )
+    choose 1 - swap - ;
+
+: initial-values ( combo m -- n k m )
+    [ [ seq>> length ] [ k>> ] bi ] dip ;
+
+: combinadic ( combo m -- combinadic )
+    initial-values [ over 0 > ] [ next-values ] produce
+    [ 3drop ] dip ;
+
+: combination-indices ( m combo -- seq )
+    [ tuck dual-index combinadic ] keep
+    seq>> length 1 - swap [ - ] with map ;
+
+: apply-combination ( m combo -- seq )
+    [ combination-indices ] keep seq>> nths ;
+
+PRIVATE>
+
+: combination ( m seq k -- seq )
+    <combo> apply-combination ;
+
+: all-combinations ( seq k -- seq )
+    <combo> [ choose [0,b) ] keep
+    '[ _ apply-combination ] map ;
+
+: each-combination ( seq k quot -- )
+    [ <combo> [ choose [0,b) ] keep ] dip
+    '[ _ apply-combination @ ] each ; inline
+
+: map-combinations ( seq k quot -- )
+    [ <combo> [ choose [0,b) ] keep ] dip
+    '[ _ apply-combination @ ] map ; inline
+
+: reduce-combinations ( seq k identity quot -- result )
+    [ -rot ] dip each-combination ; inline
+
index 118a8e8197c038d6de93e62d76b255d4b72ab684..a2d3213e78ce64f63597f74612e87a3f444e68a3 100644 (file)
@@ -7,6 +7,7 @@ IN: math.constants
 : euler ( -- gamma ) 0.57721566490153286060 ; inline
 : phi ( -- phi ) 1.61803398874989484820 ; inline
 : pi ( -- pi ) 3.14159265358979323846 ; inline
+: 2pi ( -- pi ) 2 pi * ; inline
 : epsilon ( -- epsilon ) 2.2204460492503131e-16 ; inline
 : smallest-float ( -- x ) HEX: 1 bits>double ; foldable
 : largest-float ( -- x ) HEX: 7fefffffffffffff bits>double ; foldable
index 397a7cc2f3faa66e9bec396f0dd1eda396da3300..66d813bab8c9f919ad31ecde044237ff011dea59 100644 (file)
@@ -157,3 +157,8 @@ IN: math.functions.tests
     2135623355842621559
     [ >bignum ] tri@ ^mod
 ] unit-test
+
+[ 1.0  ] [ 1.0 2.5 0.0 lerp ] unit-test
+[ 2.5  ] [ 1.0 2.5 1.0 lerp ] unit-test
+[ 1.75 ] [ 1.0 2.5 0.5 lerp ] unit-test
+
index c21053317e6d88c984f56b7bacef622bca38d594..a1bf9480d50315a0d15991427af3f9fe441b4869 100644 (file)
@@ -18,12 +18,12 @@ M: real sqrt
 : factor-2s ( n -- r s )
     #! factor an integer into 2^r * s
     dup 0 = [ 1 ] [
-        0 swap [ dup even? ] [ [ 1+ ] [ 2/ ] bi* ] while
+        0 swap [ dup even? ] [ [ 1 + ] [ 2/ ] bi* ] while
     ] if ; inline
 
 <PRIVATE
 
-GENERIC# ^n 1 ( z w -- z^w )
+GENERIC# ^n 1 ( z w -- z^w ) foldable
 
 : (^n) ( z w -- z^w )
     make-bits 1 [ [ dupd * ] when [ sq ] dip ] reduce nip ; inline
@@ -216,17 +216,17 @@ M: real tanh ftanh ;
 : coth ( x -- y ) tanh recip ; inline
 
 : acosh ( x -- y )
-    dup sq 1- sqrt + log ; inline
+    dup sq 1 - sqrt + log ; inline
 
 : asech ( x -- y ) recip acosh ; inline
 
 : asinh ( x -- y )
-    dup sq 1+ sqrt + log ; inline
+    dup sq 1 + sqrt + log ; inline
 
 : acosech ( x -- y ) recip asinh ; inline
 
 : atanh ( x -- y )
-    [ 1+ ] [ 1- neg ] bi / log 2 / ; inline
+    [ 1 + ] [ 1 - neg ] bi / log 2 / ; inline
 
 : acoth ( x -- y ) recip atanh ; inline
 
@@ -259,6 +259,9 @@ M: real atan fatan ;
 
 : floor ( x -- y )
     dup 1 mod dup zero?
-    [ drop ] [ dup 0 < [ - 1- ] [ - ] if ] if ; foldable
+    [ drop ] [ dup 0 < [ - 1 - ] [ - ] if ] if ; foldable
 
 : ceiling ( x -- y ) neg floor neg ; foldable
+
+: lerp ( a b t -- a_t ) [ over - ] dip * + ; inline
+
index 02ea181f4e7b365188cfb0111e6229cd6dc94aa2..767197a975721c2f01df860426714ebe3a3f0618 100755 (executable)
@@ -48,6 +48,8 @@ TUPLE: interval { from read-only } { to read-only } ;
 
 : (a,inf] ( a -- interval ) 1/0. (a,b] ; inline
 
+: [0,inf] ( -- interval ) 0 [a,inf] ; foldable
+
 : [-inf,inf] ( -- interval ) full-interval ; inline
 
 : compare-endpoints ( p1 p2 quot -- ? )
@@ -262,7 +264,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] ] }
+        { [ dup full-interval eq? ] [ drop [0,inf] ] }
         { [ 0 over interval-contains? ] [ (interval-abs) { 0 t } suffix points>interval ] }
         [ (interval-abs) points>interval ]
     } cond ;
@@ -376,11 +378,11 @@ SYMBOL: incomparable
 : interval-log2 ( i1 -- i2 )
     {
         { empty-interval [ empty-interval ] }
-        { full-interval [ 0 [a,inf] ] }
+        { full-interval [ [0,inf] ] }
         [
             to>> first 1 max dup most-positive-fixnum >
             [ drop full-interval interval-log2 ]
-            [ 1+ >integer log2 0 swap [a,b] ]
+            [ 1 + >integer log2 0 swap [a,b] ]
             if
         ]
     } case ;
@@ -407,7 +409,7 @@ SYMBOL: incomparable
 
 : integral-closure ( i1 -- i2 )
     dup special-interval? [
-        [ from>> first2 [ 1+ ] unless ]
-        [ to>> first2 [ 1- ] unless ]
+        [ from>> first2 [ 1 + ] unless ]
+        [ to>> first2 [ 1 - ] unless ]
         bi [a,b]
     ] unless ;
diff --git a/basis/math/miller-rabin/authors.txt b/basis/math/miller-rabin/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/basis/math/miller-rabin/miller-rabin-tests.factor b/basis/math/miller-rabin/miller-rabin-tests.factor
deleted file mode 100644 (file)
index 5f1b983..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-USING: math.miller-rabin tools.test ;
-IN: math.miller-rabin.tests
-
-[ f ] [ 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 miller-rabin ] unit-test
-[ t ] [ 2 miller-rabin ] unit-test
-[ t ] [ 3 miller-rabin ] unit-test
-[ f ] [ 36 miller-rabin ] unit-test
-[ t ] [ 37 miller-rabin ] unit-test
-[ 101 ] [ 100 next-prime ] unit-test
-[ t ] [ 2135623355842621559 miller-rabin ] unit-test
-[ 100000000000031 ] [ 100000000000000 next-prime ] unit-test
\ No newline at end of file
diff --git a/basis/math/miller-rabin/miller-rabin.factor b/basis/math/miller-rabin/miller-rabin.factor
deleted file mode 100755 (executable)
index 8c237d0..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel locals math math.functions math.ranges
-random sequences sets ;
-IN: math.miller-rabin
-
-<PRIVATE
-
-: >odd ( n -- int ) dup even? [ 1+ ] when ; foldable
-
-TUPLE: positive-even-expected n ;
-
-:: (miller-rabin) ( n trials -- ? )
-    [let | r [ n 1- factor-2s drop ]
-           s [ n 1- factor-2s nip ]
-           prime?! [ t ]
-           a! [ 0 ]
-           count! [ 0 ] |
-        trials [
-            n 1- [1,b] random a!
-            a s n ^mod 1 = [
-                0 count!
-                r [
-                    2^ s * a swap n ^mod n - -1 =
-                    [ count 1+ count! r + ] when
-                ] each
-                count zero? [ f prime?! trials + ] when
-            ] unless drop
-        ] each prime? ] ;
-
-PRIVATE>
-
-: next-odd ( m -- n ) dup even? [ 1+ ] [ 2 + ] if ;
-
-: miller-rabin* ( n numtrials -- ? )
-    over {
-        { [ dup 1 <= ] [ 3drop f ] }
-        { [ dup 2 = ] [ 3drop t ] }
-        { [ dup even? ] [ 3drop f ] }
-        [ drop (miller-rabin) ]
-    } cond ;
-
-: miller-rabin ( n -- ? ) 10 miller-rabin* ;
-
-: next-prime ( n -- p )
-    next-odd dup miller-rabin [ next-prime ] unless ;
-
-: random-prime ( numbits -- p )
-    random-bits next-prime ;
-
-ERROR: no-relative-prime n ;
-
-<PRIVATE
-
-: (find-relative-prime) ( n guess -- p )
-    over 1 <= [ over no-relative-prime ] when
-    dup 1 <= [ drop 3 ] when
-    2dup gcd nip 1 > [ 2 + (find-relative-prime) ] [ nip ] if ;
-
-PRIVATE>
-
-: find-relative-prime* ( n guess -- p )
-    #! find a prime relative to n with initial guess
-    >odd (find-relative-prime) ;
-
-: find-relative-prime ( n -- p )
-    dup random find-relative-prime* ;
-
-ERROR: too-few-primes ;
-
-: unique-primes ( numbits n -- seq )
-    #! generate two primes
-    swap
-    dup 5 < [ too-few-primes ] when
-    2dup [ random-prime ] curry replicate
-    dup all-unique? [ 2nip ] [ drop unique-primes ] if ;
diff --git a/basis/math/miller-rabin/summary.txt b/basis/math/miller-rabin/summary.txt
deleted file mode 100644 (file)
index b2591a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Miller-Rabin probabilistic primality test
index edffa5377d2627501af43f6ba099c347ddedbdca..6617556270fdd5510d1aca0161061b48e59f6b7e 100644 (file)
@@ -93,7 +93,13 @@ HELP: pdiff
 { $description "Finds the derivative of " { $snippet "p" } "." } ;
 
 HELP: polyval
-{ $values { "p" "a polynomial" } { "x" number } { "p[x]" number } }
+{ $values { "x" number } { "p" "a polynomial" } { "p[x]" number } }
 { $description "Evaluate " { $snippet "p" } " with the input " { $snippet "x" } "." }
-{ $examples { $example "USING: math.polynomials prettyprint ;" "{ 1 0 1 } 2 polyval ." "5" } } ;
+{ $examples { $example "USING: math.polynomials prettyprint ;" "2 { 1 0 1 } polyval ." "5" } } ;
 
+HELP: polyval*
+{ $values { "p" "a literal polynomial" } }
+{ $description "Macro version of " { $link polyval } ". Evaluates the literal polynomial " { $snippet "p" } " at the value off the top of the stack." }
+{ $examples { $example "USING: math.polynomials prettyprint ;" "2 { 1 0 1 } polyval* ." "5" } } ;
+
+{ polyval polyval* } related-words
index 749bde3a10caebeb082d7869cd7fba4827ac4d49..fd6eda4a905f90fb331149a247c9b69e53763edb 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel make math math.order math.vectors sequences
-    splitting vectors ;
+    splitting vectors macros combinators ;
 IN: math.polynomials
 
 <PRIVATE
@@ -16,7 +16,7 @@ IN: math.polynomials
 PRIVATE>
 
 : powers ( n x -- seq )
-    <array> 1 [ * ] accumulate nip ;
+    <repetition> 1 [ * ] accumulate nip ;
 
 : p= ( p q -- ? ) pextend = ;
 
@@ -29,7 +29,7 @@ PRIVATE>
 : n*p ( n p -- n*p ) n*v ;
 
 : pextend-conv ( p q -- p q )
-    2dup [ length ] bi@ + 1- 2pad-tail [ >vector ] bi@ ;
+    2dup [ length ] bi@ + 1 - 2pad-tail [ >vector ] bi@ ;
 
 : p* ( p q -- r )
     2unempty pextend-conv <reversed> dup length
@@ -44,7 +44,7 @@ PRIVATE>
     2ptrim
     2dup [ length ] bi@ -
     dup 1 < [ drop 1 ] when
-    [ over length + 0 pad-head pextend ] keep 1+ ;
+    [ over length + 0 pad-head pextend ] keep 1 + ;
 
 : /-last ( seq seq -- a )
     #! divide the last two numbers in the sequences
@@ -80,6 +80,12 @@ PRIVATE>
 : pdiff ( p -- p' )
     dup length v* { 0 } ?head drop ;
 
-: polyval ( p x -- p[x] )
-    [ dup length ] dip powers v. ;
+: polyval ( x p -- p[x] )
+    [ length swap powers ] [ nip ] 2bi v. ;
+
+MACRO: polyval* ( p -- )
+    reverse
+    [ 1 tail [ \ * swap \ + [ ] 3sequence ] map ]
+    [ first \ drop swap [ ] 2sequence ] bi
+    prefix \ cleave [ ] 2sequence ;
 
index 278bf70b3d28d9c263600e5c6511e89ef79bf003..f5fa468687f1f38eb5d5a98906bd1fee8adca2e4 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2007-2009 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays combinators kernel make math math.functions math.primes sequences ;
+USING: arrays combinators kernel make math math.functions
+math.primes sequences ;
 IN: math.primes.factors
 
 <PRIVATE
diff --git a/basis/math/primes/lucas-lehmer/authors.txt b/basis/math/primes/lucas-lehmer/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/math/primes/lucas-lehmer/lucas-lehmer-docs.factor b/basis/math/primes/lucas-lehmer/lucas-lehmer-docs.factor
new file mode 100644 (file)
index 0000000..582b59b
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax kernel ;
+IN: math.primes.lucas-lehmer
+
+HELP: lucas-lehmer
+{ $values
+    { "p" "a prime number" }
+    { "?" "a boolean" }
+}
+{ $description "Runs the Lucas-Lehmer test on the prime " { $snippet "p" } " and returns " { $link t } " if " { $snippet "(2 ^ p) - 1" } " is prime." }
+{ $examples
+    { $example "! Test that (2 ^ 61) - 1 is prime:"
+               "USING: math.primes.lucas-lehmer prettyprint ;"
+               "61 lucas-lehmer ."
+               "t"
+    }
+} ;
+
+ARTICLE: "math.primes.lucas-lehmer" "Lucas-Lehmer Mersenne Primality test"
+"The " { $vocab-link "math.primes.lucas-lehmer" } " vocabulary tests numbers of the form " { $snippet "(2 ^ p) - 1" } " for primality, where " { $snippet "p" } " is prime." $nl
+"Run the Lucas-Lehmer test:"
+{ $subsection lucas-lehmer } ;
+
+ABOUT: "math.primes.lucas-lehmer"
diff --git a/basis/math/primes/lucas-lehmer/lucas-lehmer-tests.factor b/basis/math/primes/lucas-lehmer/lucas-lehmer-tests.factor
new file mode 100644 (file)
index 0000000..b114fa8
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test math.primes.lucas-lehmer ;
+IN: math.primes.lucas-lehmer.tests
+
+[ t ] [ 2 lucas-lehmer ] unit-test
+[ t ] [ 3 lucas-lehmer ] unit-test
+[ f ] [ 4 lucas-lehmer ] unit-test
+[ t ] [ 5 lucas-lehmer ] unit-test
+[ f ] [ 6 lucas-lehmer ] unit-test
+[ f ] [ 11 lucas-lehmer ] unit-test
+[ t ] [ 13 lucas-lehmer ] unit-test
+[ t ] [ 61 lucas-lehmer ] unit-test
diff --git a/basis/math/primes/lucas-lehmer/lucas-lehmer.factor b/basis/math/primes/lucas-lehmer/lucas-lehmer.factor
new file mode 100644 (file)
index 0000000..a8bf097
--- /dev/null
@@ -0,0 +1,27 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators fry kernel locals math
+math.primes combinators.short-circuit ;
+IN: math.primes.lucas-lehmer
+
+ERROR: invalid-lucas-lehmer-candidate obj ;
+
+<PRIVATE
+
+: do-lucas-lehmer ( p -- ? )
+    [ drop 4 ] [ 2 - ] [ 2^ 1 - ] tri
+    '[ sq 2 - _ mod ] times 0 = ;
+
+: lucas-lehmer-guard ( obj -- obj )
+    dup { [ integer? ] [ 0 > ] } 1&&
+    [ invalid-lucas-lehmer-candidate ] unless ;
+
+PRIVATE>
+
+: lucas-lehmer ( p -- ? )
+    lucas-lehmer-guard
+    {
+        { [ dup 2 = ] [ drop t ] }
+        { [ dup prime? ] [ do-lucas-lehmer ] }
+        [ drop f ]
+    } cond ;
diff --git a/basis/math/primes/miller-rabin/authors.txt b/basis/math/primes/miller-rabin/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/math/primes/miller-rabin/miller-rabin-docs.factor b/basis/math/primes/miller-rabin/miller-rabin-docs.factor
new file mode 100644 (file)
index 0000000..2d19d51
--- /dev/null
@@ -0,0 +1,28 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax kernel sequences math ;
+IN: math.primes.miller-rabin
+
+HELP: miller-rabin
+{ $values
+    { "n" integer }
+    { "?" "a boolean" }
+}
+{ $description "Returns true if the number is a prime. Calls " { $link miller-rabin* } " with a default of 10 Miller-Rabin tests." } ;
+
+{ miller-rabin miller-rabin* } related-words
+
+HELP: miller-rabin*
+{ $values
+    { "n" integer } { "numtrials" integer }
+    { "?" "a boolean" }
+}
+{ $description "Performs " { $snippet "numtrials" } " trials of the Miller-Rabin probabilistic primality test algorithm and returns true if prime." } ;
+
+ARTICLE: "math.primes.miller-rabin" "Miller-Rabin probabilistic primality test"
+"The " { $vocab-link "math.primes.miller-rabin" } " vocabulary implements the Miller-Rabin probabilistic primality test and utility words that use it in order to generate random prime numbers." $nl
+"The Miller-Rabin probabilistic primality test:"
+{ $subsection miller-rabin }
+{ $subsection miller-rabin* } ;
+
+ABOUT: "math.primes.miller-rabin"
diff --git a/basis/math/primes/miller-rabin/miller-rabin-tests.factor b/basis/math/primes/miller-rabin/miller-rabin-tests.factor
new file mode 100644 (file)
index 0000000..d201abf
--- /dev/null
@@ -0,0 +1,11 @@
+USING: kernel math.primes.miller-rabin sequences tools.test ;
+IN: math.primes.miller-rabin.tests
+
+[ f ] [ 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 miller-rabin ] unit-test
+[ t ] [ 2 miller-rabin ] unit-test
+[ t ] [ 3 miller-rabin ] unit-test
+[ f ] [ 36 miller-rabin ] unit-test
+[ t ] [ 37 miller-rabin ] unit-test
+[ t ] [ 2135623355842621559 miller-rabin ] unit-test
+
+[ f ] [ 1000 [ drop 15 miller-rabin ] any? ] unit-test
diff --git a/basis/math/primes/miller-rabin/miller-rabin.factor b/basis/math/primes/miller-rabin/miller-rabin.factor
new file mode 100755 (executable)
index 0000000..b0dfc4e
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (c) 2008-2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators combinators.short-circuit kernel locals math
+math.functions math.ranges random sequences sets ;
+IN: math.primes.miller-rabin
+
+<PRIVATE
+
+:: (miller-rabin) ( n trials -- ? )
+    n 1 - :> n-1
+    n-1 factor-2s :> s :> r
+    0 :> a!
+    trials [
+        drop
+        2 n 2 - [a,b] random a!
+        a s n ^mod 1 = [
+            f
+        ] [
+            r iota [
+                2^ s * a swap n ^mod n - -1 =
+            ] any? not
+        ] if
+    ] any? not ;
+
+PRIVATE>
+
+: miller-rabin* ( n numtrials -- ? )
+    over {
+        { [ dup 1 <= ] [ 3drop f ] }
+        { [ dup 2 = ] [ 3drop t ] }
+        { [ dup even? ] [ 3drop f ] }
+        [ drop (miller-rabin) ]
+    } cond ;
+
+: miller-rabin ( n -- ? ) 10 miller-rabin* ;
diff --git a/basis/math/primes/miller-rabin/summary.txt b/basis/math/primes/miller-rabin/summary.txt
new file mode 100644 (file)
index 0000000..b2591a3
--- /dev/null
@@ -0,0 +1 @@
+Miller-Rabin probabilistic primality test
index c7dbc950e855217d2d864226c362620574ccd950..71bf3ac2c8130ea50c8b6279efe3c4811b5520f3 100644 (file)
@@ -1,10 +1,10 @@
-USING: help.markup help.syntax ;
+USING: help.markup help.syntax math sequences ;
 IN: math.primes
 
 { next-prime prime? } related-words
 
 HELP: next-prime
-{ $values { "n" "an integer not smaller than 2" } { "p" "a prime number" } }
+{ $values { "n" integer } { "p" "a prime number" } }
 { $description "Return the next prime number greater than " { $snippet "n" } "." } ;
 
 HELP: prime?
@@ -20,3 +20,48 @@ HELP: primes-upto
 HELP: primes-between
 { $values { "low" "an integer" } { "high" "an integer" } { "seq" "a sequence" } }
 { $description "Return a sequence containing all the prime numbers between " { $snippet "low" } " and " { $snippet "high" } "." } ;
+
+HELP: find-relative-prime
+{ $values
+    { "n" integer }
+    { "p" integer }
+}
+{ $description "Returns a number that is relatively prime to " { $snippet "n" } "." } ;
+
+HELP: find-relative-prime*
+{ $values
+    { "n" integer } { "guess" integer }
+    { "p" integer }
+}
+{ $description "Returns a number that is relatively prime to " { $snippet "n" } ", starting by trying " { $snippet "guess" } "." } ;
+
+HELP: random-prime
+{ $values
+    { "numbits" integer }
+    { "p" integer }
+}
+{ $description "Returns a prime number exactly " { $snippet "numbits" } " bits in length, with the topmost bit set to one." } ;
+
+HELP: unique-primes
+{ $values
+    { "numbits" integer } { "n" integer }
+    { "seq" sequence }
+}
+{ $description "Generates a sequence of " { $snippet "n" } " unique prime numbers with exactly " { $snippet "numbits" } " bits." } ;
+
+ARTICLE: "math.primes" "Prime numbers"
+"The " { $vocab-link "math.primes" } " vocabulary implements words related to prime numbers. Serveral useful vocabularies exist for testing primality. The Sieve of Eratosthenes in " { $vocab-link "math.primes.erato" } " is useful for testing primality below five million. For larger integers, " { $vocab-link "math.primes.miller-rabin" } " is a fast probabilstic primality test. The " { $vocab-link "math.primes.lucas-lehmer" } " vocabulary implements an algorithm for finding huge Mersenne prime numbers." $nl
+"Testing if a number is prime:"
+{ $subsection prime? }
+"Generating prime numbers:"
+{ $subsection next-prime }
+{ $subsection primes-upto }
+{ $subsection primes-between }
+{ $subsection random-prime }
+"Generating relative prime numbers:"
+{ $subsection find-relative-prime }
+{ $subsection find-relative-prime* }
+"Make a sequence of random prime numbers:"
+{ $subsection unique-primes } ;
+
+ABOUT: "math.primes"
index db738399ef828ab6a49f207c028eb39c4be536b2..6580f0780e3d887c12468a94a9866b5205c33602 100644 (file)
@@ -1,4 +1,6 @@
-USING: arrays math.primes tools.test ;
+USING: arrays math math.primes math.primes.miller-rabin
+tools.test ;
+IN: math.primes.tests
 
 { 1237 } [ 1234 next-prime ] unit-test
 { f t } [ 1234 prime? 1237 prime? ] unit-test
@@ -7,3 +9,12 @@ USING: arrays math.primes tools.test ;
 
 { { 4999963 4999999 5000011 5000077 5000081 } }
 [ 4999962 5000082 primes-between >array ] unit-test
+
+[ 2 ] [ 1 next-prime ] unit-test
+[ 3 ] [ 2 next-prime ] unit-test
+[ 5 ] [ 3 next-prime ] unit-test
+[ 101 ] [ 100 next-prime ] unit-test
+[ t ] [ 2135623355842621559 miller-rabin ] unit-test
+[ 100000000000031 ] [ 100000000000000 next-prime ] unit-test
+
+[ 49 ] [ 50 random-prime log2 ] unit-test
index 688fdad7138101884a1d6ec055d227c88863ba9b..e3985fc6000107e5dcc450baed6f6469b2de95b5 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2007-2009 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel math math.functions math.miller-rabin
-math.order math.primes.erato math.ranges sequences ;
+USING: combinators kernel math math.bitwise math.functions
+math.order math.primes.erato math.primes.miller-rabin
+math.ranges random sequences sets fry ;
 IN: math.primes
 
 <PRIVATE
@@ -21,7 +22,11 @@ PRIVATE>
     } cond ; foldable
 
 : next-prime ( n -- p )
-    next-odd [ dup really-prime? ] [ 2 + ] until ; foldable
+    dup 2 < [
+        drop 2
+    ] [
+        next-odd [ dup really-prime? ] [ 2 + ] until
+    ] if ; foldable
 
 : primes-between ( low high -- seq )
     [ dup 3 max dup even? [ 1 + ] when ] dip
@@ -31,3 +36,34 @@ PRIVATE>
 : primes-upto ( n -- seq ) 2 swap primes-between ;
 
 : coprime? ( a b -- ? ) gcd nip 1 = ; foldable
+
+: random-prime ( numbits -- p )
+    random-bits* next-prime ;
+
+: estimated-primes ( m -- n )
+    dup log / ; foldable
+
+ERROR: no-relative-prime n ;
+
+<PRIVATE
+
+: (find-relative-prime) ( n guess -- p )
+    over 1 <= [ over no-relative-prime ] when
+    dup 1 <= [ drop 3 ] when
+    2dup gcd nip 1 > [ 2 + (find-relative-prime) ] [ nip ] if ;
+
+PRIVATE>
+
+: find-relative-prime* ( n guess -- p )
+    #! find a prime relative to n with initial guess
+    >odd (find-relative-prime) ;
+
+: find-relative-prime ( n -- p )
+    dup random find-relative-prime* ;
+
+ERROR: too-few-primes n numbits ;
+
+: unique-primes ( n numbits -- seq )
+    2dup 2^ estimated-primes > [ too-few-primes ] when
+    2dup '[ _ random-prime ] replicate
+    dup all-unique? [ 2nip ] [ drop unique-primes ] if ;
diff --git a/basis/math/primes/safe/authors.txt b/basis/math/primes/safe/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/math/primes/safe/safe-docs.factor b/basis/math/primes/safe/safe-docs.factor
new file mode 100644 (file)
index 0000000..861fc4e
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators.short-circuit help.markup help.syntax kernel
+math math.functions math.primes random ;
+IN: math.primes.safe
+
+HELP: next-safe-prime
+{ $values
+    { "n" integer }
+    { "q" integer }
+}
+{ $description "Tests consecutive numbers and returns the next safe prime. A safe prime is desirable in cryptography applications such as Diffie-Hellman and SRP6." } ;
+
+HELP: random-safe-prime
+{ $values
+    { "numbits" integer }
+    { "p" integer }
+}
+{ $description "Returns a safe prime number " { $snippet "numbits" } " bits in length, with the topmost bit set to one." } ;
+
+HELP: safe-prime?
+{ $values
+    { "q" integer }
+    { "?" "a boolean" }
+}
+{ $description "Tests whether the number is a safe prime. A safe prime " { $snippet "p" } " must be prime, as must " { $snippet "(p - 1) / 2" } "." } ;
+
+
+ARTICLE: "math.primes.safe" "Safe prime numbers"
+"The " { $vocab-link "math.primes.safe" } " vocabulary implements words to calculate safe prime numbers. Safe primes are of the form p = 2q + 1, where p,q are prime. Safe primes have desirable qualities for cryptographic applications." $nl
+
+"Testing if a number is a safe prime:"
+{ $subsection safe-prime? }
+"Generating safe prime numbers:"
+{ $subsection next-safe-prime }
+{ $subsection random-safe-prime } ;
+
+ABOUT: "math.primes.safe"
diff --git a/basis/math/primes/safe/safe-tests.factor b/basis/math/primes/safe/safe-tests.factor
new file mode 100644 (file)
index 0000000..ef9aa92
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math.primes.safe math.primes.safe.private tools.test ;
+IN: math.primes.safe.tests
+
+[ 863 ] [ 862 next-safe-prime ] unit-test
+[ f ] [ 862 safe-prime? ] unit-test
+[ t ] [ 7 safe-prime? ] unit-test
+[ f ] [ 31 safe-prime? ] unit-test
+[ t ] [ 47 safe-prime-candidate? ] unit-test
+[ t ] [ 47 safe-prime? ] unit-test
+[ t ] [ 863 safe-prime? ] unit-test
+
+[ 47 ] [ 31 next-safe-prime ] unit-test
diff --git a/basis/math/primes/safe/safe.factor b/basis/math/primes/safe/safe.factor
new file mode 100644 (file)
index 0000000..a3becb6
--- /dev/null
@@ -0,0 +1,29 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators.short-circuit kernel math math.functions
+math.primes random ;
+IN: math.primes.safe
+
+<PRIVATE
+
+: safe-prime-candidate? ( n -- ? )
+    1 + 6 divisor? ;
+
+: next-safe-prime-candidate ( n -- candidate )
+    next-prime dup safe-prime-candidate?
+    [ next-safe-prime-candidate ] unless ;
+
+PRIVATE>
+
+: safe-prime? ( q -- ? )
+    {
+        [ 1 - 2 / dup integer? [ prime? ] [ drop f ] if ]
+        [ prime? ]
+    } 1&& ;
+
+: next-safe-prime ( n -- q )
+    next-safe-prime-candidate
+    dup safe-prime? [ next-safe-prime ] unless ;
+
+: random-safe-prime ( numbits -- p )
+    random-bits* next-safe-prime ;
index 068f599b6ff2c72bdd3619452ffdd2ace962355b..883be006dc255cbf18dfe0af209692362fd3a25a 100644 (file)
@@ -10,7 +10,7 @@ TUPLE: range
 { step read-only } ;
 
 : <range> ( a b step -- range )
-    [ over - ] dip [ /i 1+ 0 max ] keep range boa ; inline
+    [ over - ] dip [ /i 1 + 0 max ] keep range boa ; inline
 
 M: range length ( seq -- n )
     length>> ;
diff --git a/basis/math/rectangles/prettyprint/authors.txt b/basis/math/rectangles/prettyprint/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/math/rectangles/prettyprint/prettyprint.factor b/basis/math/rectangles/prettyprint/prettyprint.factor
new file mode 100644 (file)
index 0000000..c23be50
--- /dev/null
@@ -0,0 +1,7 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors math.rectangles kernel prettyprint.custom prettyprint.backend ;
+IN: math.rectangles.prettyprint
+
+M: rect pprint*
+    \ RECT: [ [ loc>> ] [ dim>> ] bi [ pprint* ] bi@ ] pprint-prefix ;
index 90174d144e5825ceb483dde2138dada9a7e307ad..c8569dfdb9a12d02af8667a9d295c8bbf0471ba3 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel arrays sequences math math.vectors accessors
-parser prettyprint.custom prettyprint.backend ;
+parser ;
 IN: math.rectangles
 
 TUPLE: rect { loc initial: { 0 0 } } { dim initial: { 0 0 } } ;
@@ -10,9 +10,6 @@ TUPLE: rect { loc initial: { 0 0 } } { dim initial: { 0 0 } } ;
 
 SYNTAX: RECT: scan-object scan-object <rect> parsed ;
 
-M: rect pprint*
-    \ RECT: [ [ loc>> ] [ dim>> ] bi [ pprint* ] bi@ ] pprint-prefix ;
-
 : <zero-rect> ( -- rect ) rect new ; inline
 
 : point>rect ( loc -- rect ) { 0 0 } <rect> ; inline
@@ -21,6 +18,8 @@ M: rect pprint*
 
 : rect-extent ( rect -- loc ext ) rect-bounds over v+ ;
 
+: rect-center ( rect -- center ) rect-bounds 2 v/n v+ ;
+
 : with-rect-extents ( rect1 rect2 loc-quot: ( loc1 loc2 -- ) ext-quot: ( ext1 ext2 -- ) -- )
     [ [ rect-extent ] bi@ ] 2dip bi-curry* bi* ; inline
 
@@ -62,3 +61,7 @@ M: rect contains-point?
     [ [ loc>> ] dip (>>loc) ]
     [ [ dim>> ] dip (>>dim) ]
     2bi ; inline
+
+USING: vocabs vocabs.loader ;
+
+"prettyprint" vocab [ "math.rectangles.prettyprint" require ] when
\ No newline at end of file
index 589876184ff2ad826dd7ed7d7648ddd7a7fd0b90..4cd8c5b88865be31cde80f18a159f3943fe14ab3 100644 (file)
@@ -15,7 +15,7 @@ IN: math.statistics
 
 : median ( seq -- n )
     natural-sort dup length even? [
-        [ midpoint@ dup 1- 2array ] keep nths mean
+        [ midpoint@ dup 1 - 2array ] keep nths mean
     ] [
         [ midpoint@ ] keep nth
     ] if ;
@@ -33,7 +33,7 @@ IN: math.statistics
         drop 0
     ] [
         [ [ mean ] keep [ - sq ] with sigma ] keep
-        length 1- /
+        length 1 - /
     ] if ;
 
 : std ( seq -- x )
@@ -47,7 +47,7 @@ IN: math.statistics
     0 [ [ [ pick ] dip swap - ] bi@ * + ] 2reduce 2nip ;
 
 : (r) ( mean(x) mean(y) {x} {y} sx sy -- r )
-    * recip [ [ ((r)) ] keep length 1- / ] dip * ;
+    * 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 aef4ade87771cdd23062948a560a4651e85092cc..968af6a3aa6159fa2956d88a65ebdf906e5d9b95 100644 (file)
@@ -9,3 +9,10 @@ USING: math.vectors tools.test ;
 [ 5 ] [ { 1 2 } norm-sq ] unit-test
 [ 13 ] [ { 2 3 } norm-sq ] unit-test
 
+[ { 1.0  2.5  } ] [ { 1.0 2.5 } { 2.5 1.0 } 0.0 vnlerp ] unit-test 
+[ { 2.5  1.0  } ] [ { 1.0 2.5 } { 2.5 1.0 } 1.0 vnlerp ] unit-test 
+[ { 1.75 1.75 } ] [ { 1.0 2.5 } { 2.5 1.0 } 0.5 vnlerp ] unit-test 
+
+[ { 1.75 2.125 } ] [ { 1.0 2.5 } { 2.5 1.0 } { 0.5 0.25 } vlerp ] unit-test 
+
+[ 1.125 ] [ 0.0 1.0 2.0 4.0 { 0.5 0.25 } bilerp ] unit-test
index eb5fa7b9705135ae33a099ea5b0ddf4aef1bb8bc..bad2733bbf1176585d608c759c3ffbc2e4742388 100644 (file)
@@ -6,6 +6,11 @@ IN: math.vectors
 
 : vneg ( u -- v ) [ neg ] map ;
 
+: v+n ( u n -- v ) [ + ] curry map ;
+: n+v ( n u -- v ) [ + ] with map ;
+: v-n ( u n -- v ) [ - ] curry map ;
+: n-v ( n u -- v ) [ - ] with map ;
+
 : v*n ( u n -- v ) [ * ] curry map ;
 : n*v ( n u -- v ) [ * ] with map ;
 : v/n ( u n -- v ) [ / ] curry map ;
@@ -19,6 +24,10 @@ IN: math.vectors
 : vmax ( u v -- w ) [ max ] 2map ;
 : vmin ( u v -- w ) [ min ] 2map ;
 
+: vfloor    ( v -- _v_ ) [ floor    ] map ;
+: vceiling  ( v -- ^v^ ) [ ceiling  ] map ;
+: vtruncate ( v -- -v- ) [ truncate ] map ;
+
 : vsupremum ( seq -- vmax ) [ ] [ vmax ] map-reduce ; 
 : vinfimum ( seq -- vmin ) [ ] [ vmin ] map-reduce ; 
 
@@ -32,6 +41,23 @@ IN: math.vectors
 : set-axis ( u v axis -- w )
     [ [ zero? 2over ? ] dip swap nth ] map-index 2nip ;
 
+: 2tetra@ ( p q r s t u v w quot -- )
+    dup [ [ 2bi@ ] curry 4dip ] dip 2bi@ ; inline
+
+: trilerp ( aaa baa aba bba aab bab abb bbb {t,u,v} -- a_tuv )
+    [ first lerp ] [ second lerp ] [ third lerp ] tri-curry
+    [ 2tetra@ ] [ 2bi@ ] [ call ] tri* ;
+
+: bilerp ( aa ba ab bb {t,u} -- a_tu )
+    [ first lerp ] [ second lerp ] bi-curry
+    [ 2bi@ ] [ call ] bi* ;
+
+: vlerp ( a b t -- a_t )
+    [ lerp ] 3map ;
+
+: vnlerp ( a b t -- a_t )
+    [ lerp ] curry 2map ;
+
 HINTS: vneg { array } ;
 HINTS: norm-sq { array } ;
 HINTS: norm { array } ;
@@ -50,3 +76,9 @@ HINTS: v/ { array array } ;
 HINTS: vmax { array array } ;
 HINTS: vmin { array array } ;
 HINTS: v. { array array } ;
+
+HINTS: vlerp { array array array } ;
+HINTS: vnlerp { array array object } ;
+
+HINTS: bilerp { object object object object array } ;
+HINTS: trilerp { object object object object object object object object array } ;
index f604beab3f8a87430f5e632513f7deb9dac03192..06cc8c6a20e456eed75521b92f18c9b7944fec8b 100644 (file)
@@ -6,7 +6,6 @@ H{
     { deploy-name "none" }
     { "stop-after-last-window?" t }
     { deploy-c-types? f }
-    { deploy-compiler? f }
     { deploy-io 1 }
     { deploy-ui? f }
     { deploy-reflection 1 }
index d103e90beec923bac0d4d7de4c1e65dadb26975f..49725d22427d2a5dcd494aeab97bb05766e1e460 100755 (executable)
@@ -39,6 +39,8 @@ SLOT: display-list
 
 GENERIC: draw-scaled-texture ( dim texture -- )
 
+DEFER: make-texture
+
 <PRIVATE
 
 TUPLE: single-texture image dim loc texture-coords texture display-list disposed ;
@@ -61,18 +63,6 @@ TUPLE: single-texture image dim loc texture-coords texture display-list disposed
     [ dim>> first2 ] [ component-order>> component-order>format ] [ bitmap>> ] tri
     glTexSubImage2D ;
 
-: make-texture ( image -- id )
-    #! We use glTexSubImage2D to work around the power of 2 texture size
-    #! limitation
-    gen-texture [
-        GL_TEXTURE_BIT [
-            GL_TEXTURE_2D swap glBindTexture
-            non-power-of-2-textures? get
-            [ dup bitmap>> (tex-image) ]
-            [ [ f (tex-image) ] [ (tex-sub-image) ] bi ] if
-        ] do-attribs
-    ] keep ;
-
 : init-texture ( -- )
     GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST glTexParameteri
     GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST glTexParameteri
@@ -176,6 +166,18 @@ CONSTANT: max-texture-size { 512 512 }
 
 PRIVATE>
 
+: make-texture ( image -- id )
+    #! We use glTexSubImage2D to work around the power of 2 texture size
+    #! limitation
+    gen-texture [
+        GL_TEXTURE_BIT [
+            GL_TEXTURE_2D swap glBindTexture
+            non-power-of-2-textures? get
+            [ dup bitmap>> (tex-image) ]
+            [ [ f (tex-image) ] [ (tex-sub-image) ] bi ] if
+        ] do-attribs
+    ] keep ;
+
 : <texture> ( image loc -- texture )
     over dim>> max-texture-size [ <= ] 2all?
     [ <single-texture> ]
index c35d7488ac5ac40bd460090679a279efb5bd81d0..651e43ef5b148dc53967cc59d611a82f7b38ac53 100644 (file)
@@ -11,7 +11,7 @@ IN: random.mersenne-twister.tests
     100 [ 100 random ] replicate ;
 
 : test-rng ( seed quot -- )
-    [  <mersenne-twister> ] dip with-random ; inline
+    [ <mersenne-twister> ] dip with-random ; inline
 
 [ f ] [ 1234 [ randoms randoms = ] test-rng ] unit-test
 
index c7600a731f6ebf3c097a785be5a69dede16b323a..222ecaf93531d52f7ca28904348e1c84772fdb15 100755 (executable)
@@ -40,9 +40,17 @@ HELP: random-bytes
 } ;
 
 HELP: random-bits
-{ $values { "n" "an integer" } { "r" "a random integer" } }
+{ $values { "numbits" integer } { "r" "a random integer" } }
 { $description "Outputs an random integer n bits in length." } ;
 
+HELP: random-bits*
+{ $values
+    { "numbits" integer }
+    { "n" integer }
+}
+{ $description "Returns an integer exactly " { $snippet "numbits" } " in length, with the topmost bit set to one." } ;
+
+
 HELP: with-random
 { $values { "tuple" "a random generator" } { "quot" "a quotation" } }
 { $description "Calls the quotation with the random generator in a dynamic variable.  All random numbers will be generated using this random generator." } ;
@@ -93,6 +101,9 @@ $nl
 "Randomizing a sequence:"
 { $subsection randomize }
 "Deleting a random element from a sequence:"
-{ $subsection delete-random } ;
+{ $subsection delete-random }
+"Random numbers with " { $snippet "n" } " bits:"
+{ $subsection random-bits }
+{ $subsection random-bits* } ;
 
 ABOUT: "random"
index 9607627b3d36e1508569af76568e434ad1f3a1fe..2b6ac9b1b87908ee944099c347f9ba805e98cfaf 100644 (file)
@@ -23,3 +23,5 @@ IN: random.tests
 
 [ f ]
 [ 100 [ { 0 1 } random ] replicate all-equal? ] unit-test
+
+[ 49 ] [ 50 random-bits* log2 ] unit-test
index d972e1e7ac6e454ef689721b793a3af268ed549a..661e77125805dc683bde2953e6de78528a0fd7d3 100755 (executable)
@@ -3,7 +3,7 @@
 USING: alien.c-types kernel math namespaces sequences
 io.backend io.binary combinators system vocabs.loader
 summary math.bitwise byte-vectors fry byte-arrays
-math.ranges ;
+math.ranges math.constants math.functions accessors ;
 IN: random
 
 SYMBOL: system-random-generator
@@ -45,7 +45,10 @@ M: f random-32* ( obj -- * ) no-random-number-generator ;
 
 PRIVATE>
 
-: random-bits ( n -- r ) 2^ random-integer ;
+: random-bits ( numbits -- r ) 2^ random-integer ;
+
+: random-bits* ( numbits -- n )
+    1 - [ random-bits ] keep set-bit ;
 
 : random ( seq -- elt )
     [ f ] [
@@ -69,6 +72,20 @@ PRIVATE>
 : with-secure-random ( quot -- )
     secure-random-generator get swap with-random ; inline
 
+: uniform-random-float ( min max -- n )
+    4 random-bytes underlying>> *uint >float
+    4 random-bytes underlying>> *uint >float
+    2.0 32 ^ * +
+    [ over - 2.0 -64 ^ * ] dip
+    * + ; inline
+
+: normal-random-float ( mean sigma -- n )
+    0.0 1.0 uniform-random-float
+    0.0 1.0 uniform-random-float
+    [ 2 pi * * cos ]
+    [ 1.0 swap - log -2.0 * sqrt ]
+    bi* * * + ;
+
 USE: vocabs.loader
 
 {
index 73e719b806f5d45beb2bf5a5635c04c81b1eb4a9..1e470b699a00b21bd78b37358cb6eb500e0446d1 100644 (file)
@@ -2,7 +2,8 @@ IN: specialized-arrays.tests
 USING: tools.test specialized-arrays sequences
 specialized-arrays.int specialized-arrays.bool
 specialized-arrays.ushort alien.c-types accessors kernel
-specialized-arrays.direct.int arrays ;
+specialized-arrays.direct.int specialized-arrays.char
+specialized-arrays.uint arrays combinators ;
 
 [ t ] [ { 1 2 3 } >int-array int-array? ] unit-test
 
@@ -10,7 +11,13 @@ specialized-arrays.direct.int arrays ;
 
 [ 2 ] [ int-array{ 1 2 3 } second ] unit-test
 
-[ t ] [ { t f t } >bool-array underlying>> { 1 0 1 } >int-array underlying>> = ] unit-test
+[ t ] [
+    { t f t } >bool-array underlying>>
+    { 1 0 1 } "bool" heap-size {
+        { 1 [ >char-array ] }
+        { 4 [ >uint-array ] }
+    } case underlying>> =
+] unit-test
 
 [ ushort-array{ 1234 } ] [
     little-endian? B{ 210 4 } B{ 4 210 } ? byte-array>ushort-array
index f6f94bf20dc49caf3f718f409deb48e2eebd816b..56ef67d2a8d2a0973d8a9dd60f4837a74cfbe035 100644 (file)
@@ -95,15 +95,6 @@ M: composed infer-call*
 M: object infer-call*
     "literal quotation" literal-expected ;
 
-: infer-nslip ( n -- )
-    [ infer->r infer-call ] [ infer-r> ] bi ;
-
-: infer-slip ( -- ) 1 infer-nslip ;
-
-: infer-2slip ( -- ) 2 infer-nslip ;
-
-: infer-3slip ( -- ) 3 infer-nslip ;
-
 : infer-ndip ( word n -- )
     [ literals get ] 2dip
     [ '[ _ def>> infer-quot-here ] ]
@@ -180,9 +171,6 @@ M: object infer-call*
         { \ declare [ infer-declare ] }
         { \ call [ infer-call ] }
         { \ (call) [ infer-call ] }
-        { \ slip [ infer-slip ] }
-        { \ 2slip [ infer-2slip ] }
-        { \ 3slip [ infer-3slip ] }
         { \ dip [ infer-dip ] }
         { \ 2dip [ infer-2dip ] }
         { \ 3dip [ infer-3dip ] }
@@ -216,7 +204,7 @@ M: object infer-call*
     "local-word-def" word-prop infer-quot-here ;
 
 {
-    declare call (call) slip 2slip 3slip dip 2dip 3dip curry compose
+    declare call (call) dip 2dip 3dip curry compose
     execute (execute) call-effect-unsafe execute-effect-unsafe if
     dispatch <tuple-boa> exit load-local load-locals get-local
     drop-locals do-primitive alien-invoke alien-indirect
@@ -651,7 +639,7 @@ M: object infer-call*
 
 \ become { array array } { } define-primitive
 
-\ innermost-frame-quot { callstack } { quotation } define-primitive
+\ innermost-frame-executing { callstack } { object } define-primitive
 
 \ innermost-frame-scan { callstack } { fixnum } define-primitive
 
index 919cd098f6c286bafe168a4b6a707680b3596eff..201f3ce30b8003b5a15840be40351e54655ac50f 100644 (file)
@@ -180,7 +180,7 @@ DEFER: blah4
     over [
         2drop
     ] [
-        [ swap slip ] keep swap bad-combinator
+        [ dip ] keep swap bad-combinator
     ] if ; inline recursive
 
 [ [ [ 1 ] [ ] bad-combinator ] infer ] must-fail
index 8c572f4ae3c7788e92830588af7f3b1a9e5b6b3d..15fdb9f9b551b5b431e2d1d8da76412f754d770f 100644 (file)
@@ -4,7 +4,7 @@ USING: threads kernel namespaces continuations combinators
 sequences math namespaces.private continuations.private
 concurrency.messaging quotations kernel.private words
 sequences.private assocs models models.arrow arrays accessors
-generic generic.single definitions make sbufs tools.crossref ;
+generic generic.single definitions make sbufs tools.crossref fry ;
 IN: tools.continuations
 
 <PRIVATE
@@ -79,21 +79,18 @@ M: object add-breakpoint ;
     (step-into-call-next-method)
 } [ t "no-compile" set-word-prop ] each >>
 
+: >innermost-frame< ( callstack -- n quot )
+    [ innermost-frame-scan 1 + ] [ innermost-frame-executing ] bi ;
+
+: (change-frame) ( callstack quot -- callstack' )
+    [ dup innermost-frame-executing quotation? ] dip '[
+        clone [ >innermost-frame< @ ] [ set-innermost-frame-quot ] [ ] tri
+    ] when ; inline
+
 : change-frame ( continuation quot -- continuation' )
     #! Applies quot to innermost call frame of the
     #! continuation.
-    [ clone ] dip [
-        [ clone ] dip
-        [
-            [
-                [ innermost-frame-scan 1+ ]
-                [ innermost-frame-quot ] bi
-            ] dip call
-        ]
-        [ drop set-innermost-frame-quot ]
-        [ drop ]
-        2tri
-    ] curry change-call ; inline
+    [ clone ] dip '[ _ (change-frame) ] change-call ; inline
 
 PRIVATE>
 
@@ -101,7 +98,7 @@ PRIVATE>
     [
         2dup length = [ nip [ break ] append ] [
             2dup nth \ break = [ nip ] [
-                swap 1+ cut [ break ] glue 
+                swap 1 + cut [ break ] glue 
             ] if
         ] if
     ] change-frame ;
@@ -109,7 +106,6 @@ PRIVATE>
 : continuation-step-out ( continuation -- continuation' )
     [ nip \ break suffix ] change-frame ;
 
-
 {
     { call [ (step-into-quot) ] }
     { dip [ (step-into-dip) ] }
@@ -124,7 +120,7 @@ PRIVATE>
 
 ! Never step into these words
 : don't-step-into ( word -- )
-    dup [ execute break ] curry "step-into" set-word-prop ;
+    dup '[ _ execute break ] "step-into" set-word-prop ;
 
 {
     >n ndrop >c c>
@@ -151,6 +147,4 @@ PRIVATE>
     ] change-frame ;
 
 : continuation-current ( continuation -- obj )
-    call>>
-    [ innermost-frame-scan 1+ ]
-    [ innermost-frame-quot ] bi ?nth ;
+    call>> >innermost-frame< ?nth ;
index b74548a65f3346a0478c5e6c18a26206b9bc5e0e..ba822769272f302e4143ffb6cb6cb971cefbf787 100755 (executable)
@@ -43,14 +43,14 @@ CONSTANT: theme-path "basis/ui/gadgets/theme/"
     [ my-arch make-image ] unless ;
 
 : bootstrap-profile ( -- profile )
-    {
-        { "math"     deploy-math?     }
-        { "compiler" deploy-compiler? }
-        { "threads"  deploy-threads?  }
-        { "ui"       deploy-ui?       }
-        { "unicode"  deploy-unicode?  }
-    } [ nip get ] assoc-filter keys
-    native-io? [ "io" suffix ] when ;
+    [
+        deploy-math? get [ "math" , ] when
+        deploy-threads? get [ "threads" , ] when
+        "compiler" ,
+        deploy-ui? get [ "ui" , ] when
+        deploy-unicode? get [ "unicode" , ] when
+        native-io? [ "io" , ] when
+    ] { } make ;
 
 : staging-image-name ( profile -- name )
     "staging."
index c8249e4e41c89522eedd5473fc38bc8b4e5bd805..bd612c644a9a59f3e46447fb18d20a76f7d782c5 100644 (file)
@@ -5,7 +5,6 @@ IN: tools.deploy.config
 ARTICLE: "deploy-flags" "Deployment flags"
 "There are two sets of deployment flags. The first set controls the major subsystems which are to be included in the deployment image:"
 { $subsection deploy-math?     }
-{ $subsection deploy-compiler? }
 { $subsection deploy-unicode?   }
 { $subsection deploy-threads?  }
 { $subsection deploy-ui?       }
@@ -53,11 +52,6 @@ HELP: deploy-math?
 $nl
 "On by default. Often the programmer will use rationals without realizing it. A small amount of space can be saved by stripping these features out, but some code may require changes to work properly." } ;
 
-HELP: deploy-compiler?
-{ $description "Deploy flag. If set, words in the deployed image will be compiled with the optimizing compiler when possible."
-$nl
-"On by default. Most programs should be compiled, not only for performance but because features which depend on the C library interface only function after compilation." } ;
-
 HELP: deploy-unicode?
 { $description "Deploy flag. If set, full Unicode " { $link POSTPONE: CHAR: } " syntax is included."
 $nl
index 63c8393b51ff2c8099a067a2969a9272c22fa5b9..89d1fe3821d90db514065c507cebbdc41fcb8c7f 100644 (file)
@@ -7,7 +7,6 @@ IN: tools.deploy.config
 SYMBOL: deploy-name
 
 SYMBOL: deploy-ui?
-SYMBOL: deploy-compiler?
 SYMBOL: deploy-math?
 SYMBOL: deploy-unicode?
 SYMBOL: deploy-threads?
@@ -55,7 +54,6 @@ SYMBOL: deploy-image
         { deploy-ui?                f }
         { deploy-io                 2 }
         { deploy-reflection         1 }
-        { deploy-compiler?          t }
         { deploy-threads?           t }
         { deploy-unicode?           f }
         { deploy-math?              t }
index 4c03047eb86960ea856790387553076ac1acb339..71701b6a56d6faa1316371011ed495290a5d63b0 100644 (file)
@@ -29,6 +29,8 @@ ARTICLE: "tools.deploy.caveats" "Deploy tool caveats"
 "In deployed applications, the " { $link boa } " word does not verify that the parameters on the stack satisfy the tuple's slot declarations, if any. This reduces deploy image size but can make bugs harder to track down. Make sure your program is fully debugged before deployment."
 { $heading "Behavior of " { $link POSTPONE: execute( } }
 "Similarly, the " { $link POSTPONE: execute( } " word does not check word stack effects in deployed applications, since stack effects are stripped out, and so it behaves exactly like " { $link POSTPONE: execute-effect-unsafe } "."
+{ $heading "Behavior of " { $link POSTPONE: call-next-method } }
+"The " { $link POSTPONE: call-next-method } " word does not check if the input is of the right type in deployed applications."
 { $heading "Error reporting" }
 "If the " { $link deploy-reflection } " level in the configuration is low enough, the debugger is stripped out, and error messages can be rather cryptic. Increase the reflection level to get readable error messages."
 { $heading "Choosing the right deploy flags" }
index 3bebf7236d6074c1db7ecbc62fb4af785febfebf..842faba6402af1345b35e5d560d1a947a745d01e 100644 (file)
@@ -11,7 +11,7 @@ io.directories tools.deploy.test ;
 \r
 [ t ] [ "hello-ui" shake-and-bake 1300000 small-enough? ] unit-test\r
 \r
-[ "staging.math-compiler-threads-ui-strip.image" ] [\r
+[ "staging.math-threads-compiler-ui-strip.image" ] [\r
     "hello-ui" deploy-config\r
     [ bootstrap-profile staging-image-name file-name ] bind\r
 ] unit-test\r
@@ -20,6 +20,10 @@ io.directories tools.deploy.test ;
 \r
 [ t ] [ "tetris" shake-and-bake 1500000 small-enough? ] unit-test\r
 \r
+[ t ] [ "spheres" shake-and-bake 1500000 small-enough? ] unit-test\r
+\r
+[ t ] [ "terrain" shake-and-bake 1600000 small-enough? ] unit-test\r
+\r
 [ t ] [ "bunny" shake-and-bake 2500000 small-enough? ] unit-test\r
 \r
 os macosx? [\r
@@ -84,7 +88,6 @@ M: quit-responder call-responder*
 {\r
     "tools.deploy.test.6"\r
     "tools.deploy.test.7"\r
-    "tools.deploy.test.8"\r
     "tools.deploy.test.9"\r
     "tools.deploy.test.10"\r
     "tools.deploy.test.11"\r
index fd43d1ccc9d512a2bc70819c7ca1c7d82c8ee68f..d79326ddc461937146ace83d166fff437b00187c 100755 (executable)
@@ -1,13 +1,11 @@
 ! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors io.backend io.streams.c init fry
-namespaces make assocs kernel parser lexer strings.parser vocabs
-sequences words memory kernel.private
-continuations io vocabs.loader system strings sets
-vectors quotations byte-arrays sorting compiler.units
-definitions generic generic.standard tools.deploy.config ;
+USING: arrays accessors io.backend io.streams.c init fry namespaces
+make assocs kernel parser lexer strings.parser vocabs sequences words
+memory kernel.private continuations io vocabs.loader system strings
+sets vectors quotations byte-arrays sorting compiler.units definitions
+generic generic.standard tools.deploy.config combinators classes ;
 QUALIFIED: bootstrap.stage2
-QUALIFIED: classes
 QUALIFIED: command-line
 QUALIFIED: compiler.errors
 QUALIFIED: continuations
@@ -23,7 +21,13 @@ IN: tools.deploy.shaker
 
 : strip-init-hooks ( -- )
     "Stripping startup hooks" show
-    { "cpu.x86" "command-line" "libc" "system" "environment" }
+    {
+        "command-line"
+        "cpu.x86"
+        "environment"
+        "libc"
+        "alien.strings"
+    }
     [ init-hooks get delete-at ] each
     deploy-threads? get [
         "threads" init-hooks get delete-at
@@ -36,8 +40,12 @@ IN: tools.deploy.shaker
         "io.backend" init-hooks get delete-at
     ] when
     strip-dictionary? [
-        "compiler.units" init-hooks get delete-at
-        "vocabs.cache" init-hooks get delete-at
+        {
+            "compiler.units"
+            "vocabs"
+            "vocabs.cache"
+            "source-files.errors"
+        } [ init-hooks get delete-at ] each
     ] when ;
 
 : strip-debugger ( -- )
@@ -183,6 +191,11 @@ IN: tools.deploy.shaker
     strip-word-names? [ dup strip-word-names ] when
     2drop ;
 
+: strip-compiler-classes ( -- )
+    "Stripping compiler classes" show
+    "compiler" child-vocabs [ words ] map concat [ class? ] filter
+    [ dup implementors [ "methods" word-prop delete-at ] with each ] each ;
+
 : strip-default-methods ( -- )
     strip-debugger? [
         "Stripping default methods" show
@@ -245,14 +258,14 @@ IN: tools.deploy.shaker
             {
                 gensym
                 name>char-hook
-                classes:next-method-quot-cache
-                classes:class-and-cache
-                classes:class-not-cache
-                classes:class-or-cache
-                classes:class<=-cache
-                classes:classes-intersect-cache
-                classes:implementors-map
-                classes:update-map
+                next-method-quot-cache
+                class-and-cache
+                class-not-cache
+                class-or-cache
+                class<=-cache
+                classes-intersect-cache
+                implementors-map
+                update-map
                 command-line:main-vocab-hook
                 compiled-crossref
                 compiled-generic-crossref
@@ -260,21 +273,20 @@ IN: tools.deploy.shaker
                 compiler.errors:compiler-errors
                 definition-observers
                 interactive-vocabs
-                layouts:num-tags
-                layouts:num-types
-                layouts:tag-mask
-                layouts:tag-numbers
-                layouts:type-numbers
                 lexer-factory
                 print-use-hook
                 root-cache
                 source-files.errors:error-types
+                source-files.errors:error-observers
                 vocabs:dictionary
                 vocabs:load-vocab-hook
+                vocabs:vocab-observers
                 word
                 parser-notes
             } %
 
+            { } { "layouts" } strip-vocab-globals %
+
             { } { "math.partial-dispatch" } strip-vocab-globals %
 
             { } { "peg" } strip-vocab-globals %
@@ -325,8 +337,17 @@ IN: tools.deploy.shaker
     [ instances dup H{ } clone [ [ ] cache ] curry map ] dip call
     become ; inline
 
-: compress-byte-arrays ( -- )
-    [ byte-array? ] [ ] "byte arrays" compress ;
+: compress-object? ( obj -- ? )
+    {
+        { [ dup array? ] [ empty? ] }
+        { [ dup byte-array? ] [ drop t ] }
+        { [ dup string? ] [ drop t ] }
+        { [ dup wrapper? ] [ drop t ] }
+        [ drop f ]
+    } cond ;
+
+: compress-objects ( -- )
+    [ compress-object? ] [ ] "objects" compress ;
 
 : remain-compiled ( old new -- old new )
     #! Quotations which were formerly compiled must remain
@@ -340,19 +361,6 @@ IN: tools.deploy.shaker
     [ quotation? ] [ remain-compiled ] "quotations" compress
     [ quotation? ] instances [ f >>cached-effect f >>cache-counter drop ] each ;
 
-: compress-strings ( -- )
-    [ string? ] [ ] "strings" compress ;
-
-: compress-wrappers ( -- )
-    [ wrapper? ] [ ] "wrappers" compress ;
-
-: finish-deploy ( final-image -- )
-    "Finishing up" show
-    V{ } set-namestack
-    V{ } set-catchstack
-    "Saving final image" show
-    save-image-and-exit ;
-
 SYMBOL: deploy-vocab
 
 : [:c] ( -- word ) ":c" "debugger" lookup ;
@@ -383,18 +391,23 @@ SYMBOL: deploy-vocab
     t "quiet" set-global
     f output-stream set-global ;
 
+: unsafe-next-method-quot ( method -- quot )
+    [ "method-class" word-prop ]
+    [ "method-generic" word-prop ] bi
+    next-method 1quotation ;
+
 : compute-next-methods ( -- )
     [ standard-generic? ] instances [
         "methods" word-prop [
-            nip
-            dup next-method-quot "next-method-quot" set-word-prop
+            nip dup
+            unsafe-next-method-quot
+            "next-method-quot" set-word-prop
         ] assoc-each
     ] each
     "vocab:tools/deploy/shaker/next-methods.factor" run-file ;
 
 : strip ( -- )
     init-stripper
-    strip-default-methods
     strip-libc
     strip-call
     strip-cocoa
@@ -402,14 +415,14 @@ SYMBOL: deploy-vocab
     compute-next-methods
     strip-init-hooks
     strip-c-io
+    strip-compiler-classes
+    strip-default-methods
     f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore
     deploy-vocab get vocab-main deploy-boot-quot
     stripped-word-props
     stripped-globals strip-globals
-    compress-byte-arrays
+    compress-objects
     compress-quotations
-    compress-strings
-    compress-wrappers
     strip-words ;
 
 : deploy-error-handler ( quot -- )
@@ -437,7 +450,8 @@ SYMBOL: deploy-vocab
                 "Vocabulary has no MAIN: word." print flush 1 exit
             ] unless
             strip
-            finish-deploy
+            "Saving final image" show
+            save-image-and-exit
         ] deploy-error-handler
     ] bind ;
 
index df64443b7b1d88bcd1871f22c0264539af86f781..133308b7329858a4f26656c6cce3d7933e5a7efb 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2007, 2008 Slava Pestov
+! Copyright (C) 2007, 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: cocoa cocoa.messages cocoa.application cocoa.nibs assocs
 namespaces kernel kernel.private words compiler.units sequences
-init vocabs ;
+init vocabs memoize accessors ;
 IN: tools.deploy.shaker.cocoa
 
 : pool ( obj -- obj' ) \ pool get [ ] cache ;
@@ -42,3 +42,8 @@ H{ } clone \ pool [
         [ get values compile ] each
     ] bind
 ] with-variable
+
+\ make-prepare-send reset-memoized
+\ <selector> reset-memoized
+
+\ (send) def>> second clear-assoc
\ No newline at end of file
index 6d6a1c1bd362939bf5cd5158f10698dd87b64059..509024a5c39aca5e15cc8d1b2fd3f4aece5a61a7 100644 (file)
@@ -8,7 +8,6 @@ H{
     { deploy-math? t }
     { deploy-io 2 }
     { deploy-name "tools.deploy.test.1" }
-    { deploy-compiler? t }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
 }
index 3f5940651df3e790801e5b850823c074864ba1b4..c42063f644f851de6787009ad6bba9ab400b5cdb 100644 (file)
@@ -4,7 +4,6 @@ H{
     { deploy-unicode? f }
     { deploy-io 2 }
     { deploy-word-props? f }
-    { deploy-compiler? f }
     { deploy-threads? f }
     { deploy-word-defs? f }
     { "stop-after-last-window?" t }
index 42f707b332a9ae275a2de2cfad9e7c608aa69d80..4828f70d905e87690177e8ea4137e47beaffb7df 100644 (file)
@@ -9,7 +9,6 @@ H{
     { deploy-math? f }
     { deploy-unicode? f }
     { deploy-threads? f }
-    { deploy-compiler? f }
     { deploy-io 2 }
     { deploy-ui? f }
 }
index 638e1ca0000f262e7465d8e058d1e9d0121e8018..a3aaa3bca242a078c3201a384cd1ba2cab1ef083 100644 (file)
@@ -9,7 +9,6 @@ H{
     { deploy-io 2 }
     { deploy-ui? f }
     { deploy-name "tools.deploy.test.12" }
-    { deploy-compiler? f }
     { deploy-word-defs? f }
     { deploy-threads? f }
 }
index 951319231152fd4490f23c8b12d66a2dace640b5..d175075c1431d3d100f1b54b07ed493839fe80bb 100644 (file)
@@ -1,7 +1,6 @@
 USING: tools.deploy.config ;
 H{
     { deploy-threads? t }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-io 2 }
     { "stop-after-last-window?" t }
index 1457769ce19a4bc44b1d1b8d0ca9a2846df148f1..10cd7a85d9361b530f129cf84c4b4de5e285de12 100644 (file)
@@ -8,7 +8,6 @@ H{
     { deploy-math? t }
     { deploy-io 2 }
     { deploy-name "tools.deploy.test.2" }
-    { deploy-compiler? t }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
 }
index f3131237bfa4e7c739a0df95c9a1a4c9288e7f04..b72b00d1e4ab7a2228afbcdf523f4a5f1e11cc76 100644 (file)
@@ -6,7 +6,6 @@ H{
     { "stop-after-last-window?" t }
     { deploy-word-defs? f }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-threads? t }
     { deploy-io 3 }
     { deploy-math? t }
index 981bbcf982739d4bb852a7d5ac78f0f0a8675157..b2f22055c4f8acfa2c8dea24b3fcf403bcbe632b 100644 (file)
@@ -8,7 +8,6 @@ H{
     { deploy-math? t }
     { deploy-io 2 }
     { deploy-name "tools.deploy.test.4" }
-    { deploy-compiler? t }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
 }
index 22f50214975dbe99280fe29c2e5abc11c161cf14..3f9b7f15995be44007dbf86d4560e9356965755d 100644 (file)
@@ -8,7 +8,6 @@ H{
     { deploy-math? t }
     { deploy-io 3 }
     { deploy-name "tools.deploy.test.5" }
-    { deploy-compiler? t }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
 }
index c474fcdadfada8b972ebdd04ac72024dde755128..b86bfdb31a9c8ad2b89dbf52731b69bfebd09260 100644 (file)
@@ -5,7 +5,6 @@ H{
     { deploy-io 1 }
     { deploy-name "tools.deploy.test.6" }
     { deploy-math? t }
-    { deploy-compiler? t }
     { deploy-ui? f }
     { deploy-c-types? f }
     { deploy-word-defs? f }
index bc374f1088981c373fc5328e969c649fcbd099a6..d1e93fc7c25962be383f5d87ee7aaf0204ed8895 100644 (file)
@@ -6,7 +6,6 @@ H{
     { deploy-io 2 }
     { deploy-math? t }
     { "stop-after-last-window?" t }
-    { deploy-compiler? t }
     { deploy-unicode? f }
     { deploy-c-types? f }
     { deploy-reflection 1 }
diff --git a/basis/tools/deploy/test/8/8.factor b/basis/tools/deploy/test/8/8.factor
deleted file mode 100644 (file)
index c495928..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-USING: kernel ;
-IN: tools.deploy.test.8
-
-: literal-merge-test-1 ( -- x ) H{ { "lil" "wayne" } } ;
-: literal-merge-test-2 ( -- x ) H{ { "lil" "wayne" } } ;
-
-: literal-merge-test ( -- )
-    literal-merge-test-1
-    literal-merge-test-2 eq? t assert= ;
-
-MAIN: literal-merge-test
diff --git a/basis/tools/deploy/test/8/deploy.factor b/basis/tools/deploy/test/8/deploy.factor
deleted file mode 100644 (file)
index 3bea1ed..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-USING: tools.deploy.config ;
-H{
-    { deploy-name "tools.deploy.test.8" }
-    { deploy-c-types? f }
-    { deploy-word-props? f }
-    { deploy-ui? f }
-    { deploy-reflection 1 }
-    { deploy-compiler? f }
-    { deploy-unicode? f }
-    { deploy-io 1 }
-    { deploy-word-defs? f }
-    { deploy-threads? f }
-    { "stop-after-last-window?" t }
-    { deploy-math? f }
-}
index 91b1da569751c17a6c2765cc4db6da7b52882c84..caddbe36d009482f056d8b777187a8f5d68d2932 100644 (file)
@@ -6,7 +6,6 @@ H{
     { "stop-after-last-window?" t }
     { deploy-word-defs? f }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-threads? f }
     { deploy-io 1 }
     { deploy-math? t }
diff --git a/basis/tools/disassembler/udis/udis-tests.factor b/basis/tools/disassembler/udis/udis-tests.factor
new file mode 100644 (file)
index 0000000..9ad3dbb
--- /dev/null
@@ -0,0 +1,9 @@
+IN: tools.disassembler.udis.tests
+USING: tools.disassembler.udis tools.test alien.c-types system combinators kernel ;
+
+{
+    { [ os linux? cpu x86.64? and ] [ [ 656 ] [ "ud" heap-size ] unit-test ] }
+    { [ os macosx? cpu x86.32? and ] [ [ 592 ] [ "ud" heap-size ] unit-test ] }
+    { [ os macosx? cpu x86.64? and ] [ [ 656 ] [ "ud" heap-size ] unit-test ] }
+    [ ]
+} cond
\ No newline at end of file
index cd9dd9cf4b968f3066a3296cf2b77968418a1314..df624cab28f72fd373469c60cd5b8bb0d70db23a 100755 (executable)
@@ -16,7 +16,57 @@ IN: tools.disassembler.udis
 
 LIBRARY: libudis86
 
-TYPEDEF: char[592] ud
+C-STRUCT: ud_operand
+    { "int" "type" }
+    { "uchar" "size" }
+    { "ulonglong" "lval" }
+    { "int" "base" }
+    { "int" "index" }
+    { "uchar" "offset" }
+    { "uchar" "scale" } ;
+
+C-STRUCT: ud
+    { "void*" "inp_hook" }
+    { "uchar" "inp_curr" }
+    { "uchar" "inp_fill" }
+    { "FILE*" "inp_file" }
+    { "uchar" "inp_ctr" }
+    { "uchar*" "inp_buff" }
+    { "uchar*" "inp_buff_end" }
+    { "uchar" "inp_end" }
+    { "void*" "translator" }
+    { "ulonglong" "insn_offset" }
+    { "char[32]" "insn_hexcode" }
+    { "char[64]" "insn_buffer" }
+    { "uint" "insn_fill" }
+    { "uchar" "dis_mode" }
+    { "ulonglong" "pc" }
+    { "uchar" "vendor" }
+    { "struct map_entry*" "mapen" }
+    { "int" "mnemonic" }
+    { "ud_operand[3]" "operand" }
+    { "uchar" "error" }
+    { "uchar" "pfx_rex" }
+    { "uchar" "pfx_seg" }
+    { "uchar" "pfx_opr" }
+    { "uchar" "pfx_adr" }
+    { "uchar" "pfx_lock" }
+    { "uchar" "pfx_rep" }
+    { "uchar" "pfx_repe" }
+    { "uchar" "pfx_repne" }
+    { "uchar" "pfx_insn" }
+    { "uchar" "default64" }
+    { "uchar" "opr_mode" }
+    { "uchar" "adr_mode" }
+    { "uchar" "br_far" }
+    { "uchar" "br_near" }
+    { "uchar" "implicit_addr" }
+    { "uchar" "c1" }
+    { "uchar" "c2" }
+    { "uchar" "c3" }
+    { "uchar[256]" "inp_cache" }
+    { "uchar[64]" "inp_sess" }
+    { "ud_itab_entry*" "itab_entry" } ;
 
 FUNCTION: void ud_translate_intel ( ud* u ) ;
 FUNCTION: void ud_translate_att ( ud* u ) ;
index 65e87f976fc349987bfa7dd090cece07aa7b2d13..948c0d482db0ea7dbd985a7bf0592891de67ca4e 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.vectors memory io io.styles prettyprint
+USING: kernel math memory io io.styles prettyprint
 namespaces system sequences splitting grouping assocs strings
 generic.single combinators ;
 IN: tools.time
index 74f7c40943de7d8aa9d518cf8c3afccfd9bec6f1..06511c7adaeb6af188cac6bcf5394ad2554eaaf6 100644 (file)
@@ -1,4 +1,30 @@
 IN: tools.trace.tests
-USING: tools.trace tools.test sequences ;
+USING: tools.trace tools.test tools.continuations kernel math combinators
+sequences ;
 
-[ { 3 2 1 } ] [ { 1 2 3 } [ reverse ] trace ] unit-test
\ No newline at end of file
+[ { 3 2 1 } ] [ { 1 2 3 } [ reverse ] trace ] unit-test
+
+GENERIC: method-breakpoint-test ( x -- y )
+
+TUPLE: method-breakpoint-tuple ;
+
+M: method-breakpoint-tuple method-breakpoint-test break drop 1 2 + ;
+
+\ method-breakpoint-test don't-step-into
+
+[ 3 ]
+[ [ T{ method-breakpoint-tuple } method-breakpoint-test ] trace ] unit-test
+
+: case-breakpoint-test ( -- x )
+    5 { [ break 1 + ] } case ;
+
+\ case-breakpoint-test don't-step-into
+
+[ 6 ] [ [ case-breakpoint-test ] trace ] unit-test
+
+: call(-breakpoint-test ( -- x )
+    [ break 1 ] call( -- x ) 2 + ;
+
+\ call(-breakpoint-test don't-step-into
+
+[ 3 ] [ [ call(-breakpoint-test ] trace ] unit-test
index e2c6bf864beab210a82b929eaaafb8fa1366a843..f7f0ae4a695dd0b505ed1c743239945cdcccf6ca 100644 (file)
@@ -4,19 +4,21 @@ USING: concurrency.promises models tools.continuations kernel
 sequences concurrency.messaging locals continuations threads
 namespaces namespaces.private make assocs accessors io strings
 prettyprint math math.parser words effects summary io.styles classes
-generic.math combinators.short-circuit ;
+generic.math combinators.short-circuit kernel.private quotations ;
 IN: tools.trace
 
-: callstack-depth ( callstack -- n )
-    callstack>array length 2/ ;
-
-SYMBOL: end
-
 SYMBOL: exclude-vocabs
 SYMBOL: include-vocabs
 
 exclude-vocabs { "math" "accessors" } swap set-global
 
+<PRIVATE
+
+: callstack-depth ( callstack -- n )
+    callstack>array length 2/ ;
+
+SYMBOL: end
+
 : include? ( vocab -- ? )
     include-vocabs get dup [ member? ] [ 2drop t ] if ;
 
@@ -65,15 +67,20 @@ M: trace-step summary
     [ CHAR: \s <string> write ]
     [ number>string write ": " write ] bi ;
 
+: trace-into? ( continuation -- ? )
+    continuation-current into? ;
+
 : trace-step ( continuation -- continuation' )
-    dup continuation-current end eq? [
-        [ print-depth ]
-        [ print-step ]
-        [
-            dup continuation-current into?
-            [ continuation-step-into ] [ continuation-step ] if
-        ] tri
-    ] unless ;
+    dup call>> innermost-frame-executing quotation? [
+        dup continuation-current end eq? [
+            [ print-depth ]
+            [ print-step ]
+            [ dup trace-into? [ continuation-step-into ] [ continuation-step ] if ]
+            tri
+        ] unless
+    ] when ;
+
+PRIVATE>
 
 : trace ( quot -- data )
     [ [ trace-step ] break-hook ] dip
index 6f87792faa1e09d022bdfc6a64e06540b203d3ea..b6094d7d7ef4a78cd5b8bc5715fa9a395470a3b6 100644 (file)
@@ -2,7 +2,7 @@ USING: tools.walker io io.streams.string kernel math
 math.private namespaces prettyprint sequences tools.test
 continuations math.parser threads arrays tools.walker.debug
 generic.single sequences.private kernel.private
-tools.continuations accessors words ;
+tools.continuations accessors words combinators ;
 IN: tools.walker.tests
 
 [ { } ] [
@@ -131,4 +131,18 @@ M: method-breakpoint-tuple method-breakpoint-test break drop 1 2 + ;
 \ method-breakpoint-test don't-step-into
 
 [ { 3 } ]
-[ [ T{ method-breakpoint-tuple } method-breakpoint-test ] test-walker ] unit-test
\ No newline at end of file
+[ [ T{ method-breakpoint-tuple } method-breakpoint-test ] test-walker ] unit-test
+
+: case-breakpoint-test ( -- x )
+    5 { [ break 1 + ] } case ;
+
+\ case-breakpoint-test don't-step-into
+
+[ { 6 } ] [ [ case-breakpoint-test ] test-walker ] unit-test
+
+: call(-breakpoint-test ( -- x )
+    [ break 1 ] call( -- x ) 2 + ;
+
+\ call(-breakpoint-test don't-step-into
+
+[ { 3 } ] [ [ call(-breakpoint-test ] test-walker ] unit-test
index 9c844d366386873b725857a14bcb5734b363af58..63d551798ce074854fd3649f003fc1f18b2feb08 100755 (executable)
@@ -31,4 +31,8 @@ HOOK: offscreen-pixels ui-backend ( world -- alien w h )
     '[ select-gl-context @ ]
     [ flush-gl-context gl-error ] bi ; inline
 
-HOOK: (with-ui) ui-backend ( quot -- )
\ No newline at end of file
+HOOK: (with-ui) ui-backend ( quot -- )
+
+HOOK: (grab-input) ui-backend ( handle -- )
+
+HOOK: (ungrab-input) ui-backend ( handle -- )
index 5b1b4b0c2aa0a42f4a2c127974eb70bb61de3a47..47a3bfc1a60fc4c2793b7fb3d308f6389e9b3674 100755 (executable)
@@ -29,7 +29,7 @@ PIXEL-FORMAT-ATTRIBUTE-TABLE: NSOpenGLPFA { } H{
     { fullscreen { $ NSOpenGLPFAFullScreen } }
     { windowed { $ NSOpenGLPFAWindow } }
     { accelerated { $ NSOpenGLPFAAccelerated } }
-    { software-rendered { $ NSOpenGLPFASingleRenderer $ kCGLRendererGenericFloatID } }
+    { software-rendered { $ NSOpenGLPFARendererID $ kCGLRendererGenericFloatID } }
     { backing-store { $ NSOpenGLPFABackingStore } }
     { multisampled { $ NSOpenGLPFAMultisample } }
     { supersampled { $ NSOpenGLPFASupersample } }
@@ -122,6 +122,17 @@ M:: cocoa-ui-backend (open-window) ( world -- )
 M: cocoa-ui-backend (close-window) ( handle -- )
     window>> -> release ;
 
+M: cocoa-ui-backend (grab-input) ( handle -- )
+    0 CGAssociateMouseAndMouseCursorPosition drop
+    CGMainDisplayID CGDisplayHideCursor drop
+    window>> -> frame CGRect>rect rect-center
+    first2 <CGPoint> CGWarpMouseCursorPosition drop ;
+
+M: cocoa-ui-backend (ungrab-input) ( handle -- )
+    drop
+    CGMainDisplayID CGDisplayShowCursor drop
+    1 CGAssociateMouseAndMouseCursorPosition drop ;
+
 M: cocoa-ui-backend close-window ( gadget -- )
     find-world [
         handle>> [
index 24ae72740f10e8626f01951bcc5b6e8ff12b0ddb..2cf409193785897aff01fd08b432912819bf4cfa 100755 (executable)
@@ -11,7 +11,7 @@ threads libc combinators fry combinators.short-circuit continuations
 command-line shuffle opengl ui.render ascii math.bitwise locals
 accessors math.rectangles math.order ascii calendar
 io.encodings.utf16n windows.errors literals ui.pixel-formats 
-ui.pixel-formats.private memoize classes ;
+ui.pixel-formats.private memoize classes struct-arrays ;
 IN: ui.backend.windows
 
 SINGLETON: windows-ui-backend
@@ -616,19 +616,21 @@ M: windows-ui-backend do-events
     GetDoubleClickTime milliseconds double-click-timeout set-global ;
 
 : cleanup-win32-ui ( -- )
-    class-name-ptr get-global [ dup f UnregisterClass drop free ] when*
-    msg-obj get-global [ free ] when*
-    f class-name-ptr set-global
-    f msg-obj set-global ;
+    class-name-ptr [
+        [ [ f UnregisterClass drop ] [ free ] bi ] when* f
+    ] change-global
+    msg-obj change-global [ [ free ] when* f ] ;
 
-: get-dc ( world -- ) handle>> dup hWnd>> GetDC dup win32-error=0/f >>hDC drop ;
+: get-dc ( world -- )
+    handle>> dup hWnd>> GetDC dup win32-error=0/f >>hDC drop ;
 
 : get-rc ( world -- )
     handle>> dup hDC>> dup wglCreateContext dup win32-error=0/f
     [ wglMakeCurrent win32-error=0/f ] keep >>hRC drop ;
 
 : set-pixel-format ( pixel-format hdc -- )
-    swap handle>> "PIXELFORMATDESCRIPTOR" <c-object> SetPixelFormat win32-error=0/f ;
+    swap handle>>
+    "PIXELFORMATDESCRIPTOR" <c-object> SetPixelFormat win32-error=0/f ;
 
 : setup-gl ( world -- )
     [ get-dc ] keep
@@ -703,9 +705,24 @@ M: windows-ui-backend beep ( -- )
     "MONITORINFOEX" <c-object> dup length over set-MONITORINFOEX-cbSize
     [ GetMonitorInfo win32-error=0/f ] keep MONITORINFOEX-rcMonitor ;
 
+: client-area>RECT ( hwnd -- RECT )
+    "RECT" <c-object>
+    [ GetClientRect win32-error=0/f ]
+    [ "POINT" byte-array>struct-array [ ClientToScreen drop ] with each ]
+    [ nip ] 2tri ;
+
 : hwnd>RECT ( hwnd -- RECT )
     "RECT" <c-object> [ GetWindowRect win32-error=0/f ] keep ;
 
+M: windows-ui-backend (grab-input) ( handle -- )
+    0 ShowCursor drop
+    hWnd>> client-area>RECT ClipCursor drop ;
+
+M: windows-ui-backend (ungrab-input) ( handle -- )
+    drop
+    f ClipCursor drop
+    1 ShowCursor drop ;
+
 : fullscreen-flags ( -- n )
     { WS_CAPTION WS_BORDER WS_THICKFRAME } flags ; inline
 
index f9f397d46f1fc38d2c87639c4bd1d76101254eb4..5dd1710cdd0e66042b98732a0b76ed4d021d68b9 100644 (file)
@@ -3,8 +3,7 @@
 USING: accessors arrays hashtables kernel models math namespaces
 make sequences quotations math.vectors combinators sorting
 binary-search vectors dlists deques models threads
-concurrency.flags math.order math.rectangles fry locals
-prettyprint.backend prettyprint.custom ;
+concurrency.flags math.order math.rectangles fry locals ;
 IN: ui.gadgets
 
 ! Values for orientation slot
@@ -28,9 +27,6 @@ interior
 boundary
 model ;
 
-! Don't print gadgets with RECT: syntax
-M: gadget pprint* pprint-tuple ;
-
 M: gadget equal? 2drop f ;
 
 M: gadget hashcode* nip [ [ \ gadget counter ] unless* ] change-id id>> ;
@@ -397,3 +393,7 @@ M: f request-focus-on 2drop ;
 
 : focus-path ( gadget -- seq )
     [ focus>> ] follow ;
+
+USING: vocabs vocabs.loader ;
+
+"prettyprint" vocab [ "ui.gadgets.prettyprint" require ] when
\ No newline at end of file
diff --git a/basis/ui/gadgets/prettyprint/authors.txt b/basis/ui/gadgets/prettyprint/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/ui/gadgets/prettyprint/prettyprint.factor b/basis/ui/gadgets/prettyprint/prettyprint.factor
new file mode 100644 (file)
index 0000000..82a89ed
--- /dev/null
@@ -0,0 +1,7 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: ui.gadgets prettyprint.backend prettyprint.custom ;
+IN: ui.gadgets.prettyprint
+
+! Don't print gadgets with RECT: syntax
+M: gadget pprint* pprint-tuple ;
\ No newline at end of file
index d4e9790d89d8186f7f479c5bdea5367a10d143e2..c12c6b93aac42c983b2cedc1df80ed30bc08130b 100755 (executable)
@@ -13,6 +13,17 @@ HELP: origin
 HELP: hand-world
 { $var-description "Global variable. The " { $link world } " containing the gadget at the mouse location." } ;
 
+HELP: grab-input
+{ $values { "gadget" gadget } }
+{ $description "Sets the " { $link world } " containing " { $snippet "gadget" } " to grab mouse and keyboard input while focused." }
+{ $notes "Normal mouse gestures may not be available while input is grabbed." } ;
+
+HELP: ungrab-input
+{ $values { "gadget" gadget } }
+{ $description "Sets the " { $link world } " containing " { $snippet "gadget" } " not to grab mouse and keyboard input while focused." } ;
+
+{ grab-input ungrab-input } related-words
+
 HELP: set-title
 { $values { "string" string } { "world" world } }
 { $description "Sets the title bar of the native window containing the world." }
@@ -42,6 +53,7 @@ HELP: world
         { { $snippet "focus" } " - the current owner of the keyboard focus in the world." }
         { { $snippet "focused?" } " - a boolean indicating if the native window containing the world has keyboard focus." }
         { { $snippet "fonts" } " - a hashtable used by the " { $link font-renderer } "." }
+        { { $snippet "grab-input?" } " - if set to " { $link t } ", the world will hide the mouse cursor and disable normal mouse input while focused. Use " { $link grab-input } " and " { $link ungrab-input } " to change this setting." }
         { { $snippet "handle" } " - a backend-specific native handle representing the native window containing the world, or " { $link f } " if the world is not grafted." }
         { { $snippet "window-loc" } " - the on-screen location of the native window containing the world. The co-ordinate system here is backend-specific." }
     }
index 3568559eac7be44b787acb9f01d7965d62a202a0..d85bba999215e2ab81dc3e41d6b14018795db719 100755 (executable)
@@ -4,14 +4,14 @@ USING: accessors arrays assocs continuations kernel math models
 namespaces opengl opengl.textures sequences io combinators
 combinators.short-circuit fry math.vectors math.rectangles cache
 ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks
-ui.commands ui.pixel-formats destructors literals ;
+ui.commands ui.pixel-formats destructors literals strings ;
 IN: ui.gadgets.worlds
 
 CONSTANT: default-world-pixel-format-attributes
     { windowed double-buffered T{ depth-bits { value 16 } } }
 
 TUPLE: world < track
-    active? focused?
+    active? focused? grab-input?
     layers
     title status status-owner
     text-handle handle images
@@ -20,7 +20,8 @@ TUPLE: world < track
 
 TUPLE: world-attributes
     { world-class initial: world }
-    title
+    grab-input?
+    { title string initial: "Factor Window" }
     status
     gadgets
     { pixel-format-attributes initial: $ default-world-pixel-format-attributes } ;
@@ -30,6 +31,20 @@ TUPLE: world-attributes
 
 : find-world ( gadget -- world/f ) [ world? ] find-parent ;
 
+: grab-input ( gadget -- )
+    find-world dup grab-input?>>
+    [ drop ] [
+        t >>grab-input?
+        dup focused?>> [ handle>> (grab-input) ] [ drop ] if
+    ] if ;
+
+: ungrab-input ( gadget -- )
+    find-world dup grab-input?>>
+    [
+        f >>grab-input?
+        dup focused?>> [ handle>> (ungrab-input) ] [ drop ] if
+    ] [ drop ] if ;
+    
 : show-status ( string/f gadget -- )
     dup find-world dup [
         dup status>> [
@@ -62,14 +77,16 @@ M: world request-focus-on ( child gadget -- )
 : new-world ( class -- world )
     vertical swap new-track
         t >>root?
-        t >>active?
-        { 0 0 } >>window-loc ;
+        f >>active?
+        { 0 0 } >>window-loc
+        f >>grab-input? ;
 
 : apply-world-attributes ( world attributes -- world )
     {
         [ title>> >>title ]
         [ status>> >>status ]
         [ pixel-format-attributes>> >>pixel-format-attributes ]
+        [ grab-input?>> >>grab-input? ]
         [ gadgets>> [ 1 track-add ] each ]
     } cleave ;
 
index 7e038ef2e0de6ece498911fc86f68350eaa24350..073b2d5e2683ff20f2d084cd7d669888e87cbd8c 100644 (file)
@@ -3,8 +3,8 @@
 USING: accessors arrays assocs kernel math math.order models
 namespaces make sequences words strings system hashtables math.parser
 math.vectors classes.tuple classes boxes calendar alarms combinators
-sets columns fry deques ui.gadgets ui.gadgets.private unicode.case
-unicode.categories combinators.short-circuit ;
+sets columns fry deques ui.gadgets ui.gadgets.private ascii
+combinators.short-circuit ;
 IN: ui.gestures
 
 GENERIC: handle-gesture ( gesture gadget -- ? )
@@ -296,10 +296,10 @@ HOOK: modifiers>string os ( modifiers -- string )
 M: macosx modifiers>string
     [
         {
-            { A+ [ "\u{place-of-interest-sign}" ] }
-            { M+ [ "\u{option-key}" ] }
-            { S+ [ "\u{upwards-white-arrow}" ] }
-            { C+ [ "\u{up-arrowhead}" ] }
+            { A+ [ "\u002318" ] }
+            { M+ [ "\u002325" ] }
+            { S+ [ "\u0021e7" ] }
+            { C+ [ "\u002303" ] }
         } case
     ] map "" join ;
 
index 52abf4436224a7c5616a5d506d14886ca20ca70d..a280ab0666fb75307a3ddaeb350ad0097bc4f2f8 100644 (file)
@@ -1,6 +1,6 @@
 USING: accessors assocs classes destructors functors kernel
 lexer math parser sequences specialized-arrays.int ui.backend
-words.symbol ;
+words ;
 IN: ui.pixel-formats
 
 SYMBOLS:
@@ -71,7 +71,7 @@ GENERIC: >PFA ( attribute -- pfas )
 
 M: object >PFA
     drop { } ;
-M: symbol >PFA
+M: word >PFA
     TABLE at [ { } ] unless* ;
 M: pixel-format-attribute >PFA
     dup class TABLE at
index 6a8322ac02fb9aded6b27a4c6bb782aa6bf9defa..d3c1278bf55bfe93cfa07d09a7e0f7376e114662 100644 (file)
@@ -29,7 +29,6 @@ TUPLE: deploy-gadget < pack vocab settings ;
 
 : advanced-settings ( parent -- parent )
     "Advanced:" <label> add-gadget
-    deploy-compiler? get "Use optimizing compiler" <checkbox> add-gadget
     deploy-math? get "Rational and complex number support" <checkbox> add-gadget
     deploy-threads? get "Threading support" <checkbox> add-gadget
     deploy-unicode? get "Unicode character literal support" <checkbox> add-gadget
index 397fc419fa586d73e5e2979ec5ca1439875da944..e206c7d408a82b8f815e159a8acf3d05ec9782d6 100644 (file)
@@ -40,12 +40,12 @@ HELP: find-window
 { $description "Finds a native window such that the gadget passed to " { $link open-window } " satisfies the quotation, outputting " { $link f } " if no such gadget could be found. The front-most native window is checked first." } ;
 
 HELP: register-window
-{ $values { "world" world } { "handle" "a baackend-specific handle" } }
+{ $values { "world" world } { "handle" "a backend-specific handle" } }
 { $description "Adds a window to the global " { $link windows } " variable." }
 { $notes "This word should only be called by the UI backend.  User code can open new windows with " { $link open-window } "." } ;
 
 HELP: unregister-window
-{ $values { "handle" "a baackend-specific handle" } }
+{ $values { "handle" "a backend-specific handle" } }
 { $description "Removes a window from the global " { $link windows } " variable." }
 { $notes "This word should only be called only by the UI backend, and not user code." } ;
 
index d07403836a2ba5cc02238ad5fffc9894be59fe67..0a6f26fd5b90eb2b3271f74b9502e75eba4497de 100644 (file)
@@ -41,31 +41,46 @@ SYMBOL: windows
     lose-focus swap each-gesture
     gain-focus swap each-gesture ;
 
+: ?grab-input ( world -- )
+    dup grab-input?>> [ handle>> (grab-input) ] [ drop ] if ;
+
+: ?ungrab-input ( world -- )
+    dup grab-input?>> [ handle>> (ungrab-input) ] [ drop ] if ;
+
 : focus-world ( world -- )
     t >>focused?
-    dup raised-window
-    focus-path f focus-gestures ;
+    [ ?grab-input ] [
+        dup raised-window
+        focus-path f focus-gestures
+    ] bi ;
 
 : unfocus-world ( world -- )
     f >>focused?
-    focus-path f swap focus-gestures ;
+    [ ?ungrab-input ]
+    [ focus-path f swap focus-gestures ] bi ;
 
-: try-to-open-window ( world -- )
+: set-up-window ( world -- )
     {
-        [ (open-window) ]
         [ handle>> select-gl-context ]
-        [
-            [ begin-world ]
-            [ [ handle>> (close-window) ] [ ui-error ] bi* ]
-            recover
-        ]
+        [ [ title>> ] keep set-title ]
+        [ begin-world ]
         [ resize-world ]
+        [ t >>active? drop ]
+        [ request-focus ]
     } cleave ;
 
+: clean-up-broken-window ( world -- )
+    [
+        dup { [ focused?>> ] [ grab-input?>> ] } 1&&
+        [ handle>> (ungrab-input) ] [ drop ] if
+    ] [ handle>> (close-window) ] bi ;
+
 M: world graft*
-    [ try-to-open-window ]
-    [ [ title>> ] keep set-title ]
-    [ request-focus ] tri ;
+    [ (open-window) ]
+    [
+        [ set-up-window ]
+        [ [ clean-up-broken-window ] [ ui-error ] bi* ] recover
+    ] bi ;
 
 : reset-world ( world -- )
     #! This is used when a window is being closed, but also
@@ -145,7 +160,9 @@ SYMBOL: ui-thread
 PRIVATE>
 
 : find-window ( quot -- world )
-    [ windows get values ] dip '[ gadget-child @ ] find-last nip ; inline
+    [ windows get values ] dip
+    '[ dup children>> [ ] [ nip first ] if-empty @ ]
+    find-last nip ; inline
 
 : ui-running? ( -- ? )
     \ ui-running get-global ;
index 78e31a764df16020d3debd71f959eb7cd8ce17b4..f3e04975882ed82f623cb2f8a4b24b145e906c53 100644 (file)
@@ -2,8 +2,8 @@ IN: urls.encoding.tests
 USING: urls.encoding tools.test arrays kernel assocs present accessors ;
 
 [ "~hello world" ] [ "%7ehello world" url-decode ] unit-test
-[ f ] [ "%XX%XX%XX" url-decode ] unit-test
-[ f ] [ "%XX%XX%X" url-decode ] unit-test
+[ "" ] [ "%XX%XX%XX" url-decode ] unit-test
+[ "" ] [ "%XX%XX%X" url-decode ] unit-test
 
 [ "hello world" ] [ "hello%20world" url-decode ] unit-test
 [ " ! "         ] [ "%20%21%20"     url-decode ] unit-test
index 1e886ae3e26e1e6fac90f75bb175640023d031d9..a72fac567a28b0f532e786f78583da339ffc228c 100644 (file)
@@ -25,12 +25,14 @@ TUPLE: url protocol username password host port path query anchor ;
     ] if ;
 
 : parse-host ( string -- host port )
-    ":" split1 [ url-decode ] [
-        dup [
-            string>number
-            dup [ "Invalid port" throw ] unless
-        ] when
-    ] bi* ;
+    [
+        ":" split1 [ url-decode ] [
+            dup [
+                string>number
+                dup [ "Invalid port" throw ] unless
+            ] when
+        ] bi*
+    ] [ f f ] if* ;
 
 GENERIC: >url ( obj -- url )
 
index af828c9145c61f00dc6b72eba13d0148e3226d0c..d485692a910fbef397b53e4c872661973280066c 100644 (file)
@@ -40,6 +40,6 @@ COM-INTERFACE: IDropTarget IUnknown {00000122-0000-0000-C000-000000000046}
     IUnknown::Release drop ; inline\r
 \r
 : with-com-interface ( interface quot -- )\r
-    over [ slip ] [ com-release ] [ ] cleanup ; inline\r
+    over [ com-release ] curry [ ] cleanup ; inline\r
 \r
 DESTRUCTOR: com-release\r
index e78c987cd4ac6ee8de1136dc37bb2e2b884af740..9d52378da912855bfbb39619b611fe53d83d7deb 100755 (executable)
@@ -93,7 +93,7 @@ unless
 
 : compile-alien-callback ( word return parameters abi quot -- word )
     '[ _ _ _ _ alien-callback ]
-    [ [ (( -- alien )) define-declared ] pick slip ]
+    [ [ (( -- alien )) define-declared ] pick [ call ] dip ]
     with-compilation-unit ;
 
 : (callback-word) ( function-name interface-name counter -- word )
index 20a54dff9884ca6eb94205c9d2e9b0b262e6a95a..e5e32aac0e81a04a136eab293b9171a3fe83d115 100755 (executable)
@@ -444,6 +444,18 @@ CONSTANT: DISCL_FOREGROUND    HEX: 00000004
 CONSTANT: DISCL_BACKGROUND    HEX: 00000008
 CONSTANT: DISCL_NOWINKEY      HEX: 00000010
 
+CONSTANT: DIMOFS_X        0
+CONSTANT: DIMOFS_Y        4
+CONSTANT: DIMOFS_Z        8
+CONSTANT: DIMOFS_BUTTON0 12
+CONSTANT: DIMOFS_BUTTON1 13
+CONSTANT: DIMOFS_BUTTON2 14
+CONSTANT: DIMOFS_BUTTON3 15
+CONSTANT: DIMOFS_BUTTON4 16
+CONSTANT: DIMOFS_BUTTON5 17
+CONSTANT: DIMOFS_BUTTON6 18
+CONSTANT: DIMOFS_BUTTON7 19
+
 CONSTANT: DIK_ESCAPE          HEX: 01
 CONSTANT: DIK_1               HEX: 02
 CONSTANT: DIK_2               HEX: 03
old mode 100644 (file)
new mode 100755 (executable)
index 1e694bc..2272695
@@ -652,9 +652,9 @@ FUNCTION: HDC BeginPaint ( HWND hwnd, LPPAINTSTRUCT lpPaint ) ;
 FUNCTION: HWND ChildWindowFromPoint ( HWND hWndParent, POINT point ) ;
 ! FUNCTION: ChildWindowFromPointEx
 ! FUNCTION: ClientThreadSetup
-! FUNCTION: ClientToScreen
+FUNCTION: BOOL ClientToScreen ( HWND hWnd, POINT* point ) ;
 ! FUNCTION: CliImmSetHotKey
-! FUNCTION: ClipCursor
+FUNCTION: int ClipCursor ( RECT* clipRect ) ;
 FUNCTION: BOOL CloseClipboard ( ) ;
 ! FUNCTION: CloseDesktop
 ! FUNCTION: CloseWindow
@@ -1363,7 +1363,7 @@ CONSTANT: HWND_TOP f
 ! FUNCTION: SetWindowWord
 ! FUNCTION: SetWinEventHook
 ! FUNCTION: ShowCaret
-! FUNCTION: ShowCursor
+FUNCTION: int ShowCursor ( BOOL show ) ;
 ! FUNCTION: ShowOwnedPopups
 ! FUNCTION: ShowScrollBar
 ! FUNCTION: ShowStartGlass
index fba2eafaba84f72f40364c4eca307950a9077cfb..9df7165e6cd7da88f48ef0555e9bda6a84c3654a 100755 (executable)
@@ -143,7 +143,7 @@ PRIVATE>
 <PRIVATE
 
 : call-under ( quot object -- quot )
-    swap dup slip ; inline
+    swap [ call ] keep ; inline
 
 : xml-loop ( quot: ( xml-elem -- ) -- )
     parse-text call-under
index 943530d4f274c274ec7df8b7df37fe9ec392e5bf..c74c325726a82fa156f49d7a61c04930ed202d90 100644 (file)
@@ -34,25 +34,32 @@ M: string string>alien
 
 HOOK: alien>native-string os ( alien -- string )
 
-HOOK: native-string>alien os ( string -- alien )
-
 M: windows alien>native-string utf16n alien>string ;
 
-M: wince native-string>alien utf16n string>alien ;
+M: unix alien>native-string utf8 alien>string ;
 
-M: winnt native-string>alien utf8 string>alien ;
+HOOK: native-string>alien os ( string -- alien )
 
-M: unix alien>native-string utf8 alien>string ;
+M: windows native-string>alien utf16n string>alien ;
 
 M: unix native-string>alien utf8 string>alien ;
 
 : dll-path ( dll -- string )
     path>> alien>native-string ;
 
-: string>symbol ( str -- alien )
-    dup string?
-    [ native-string>alien ]
-    [ [ native-string>alien ] map ] if ;
+HOOK: string>symbol* os ( str/seq -- alien )
+
+M: winnt string>symbol* utf8 string>alien ;
+
+M: wince string>symbol* utf16n string>alien ;
+
+M: unix string>symbol* utf8 string>alien ;
+
+GENERIC: string>symbol ( str -- alien )
+
+M: string string>symbol string>symbol* ;
+
+M: sequence string>symbol [ string>symbol* ] map ;
 
 [
     8 getenv utf8 alien>string string>cpu \ cpu set-global
index e5a6bbe5fabba4202e4b54d9eff6974c4239ce6b..57bc61a0058c4ce1988c308625b0fe9d16fdde14 100644 (file)
@@ -231,7 +231,8 @@ bi
     "vocabulary"
     { "def" { "quotation" "quotations" } initial: [ ] }
     "props"
-    { "direct-entry-def" }
+    "pic-def"
+    "pic-tail-def"
     { "counter" { "fixnum" "math" } }
     { "sub-primitive" read-only }
 } define-builtin
@@ -493,7 +494,7 @@ tuple
     { "(sleep)" "threads.private" (( us -- )) }
     { "<tuple-boa>" "classes.tuple.private" (( ... layout -- tuple )) }
     { "callstack>array" "kernel" (( callstack -- array )) }
-    { "innermost-frame-quot" "kernel.private" (( callstack -- quot )) }
+    { "innermost-frame-executing" "kernel.private" (( callstack -- obj )) }
     { "innermost-frame-scan" "kernel.private" (( callstack -- n )) }
     { "set-innermost-frame-quot" "kernel.private" (( n callstack -- )) }
     { "call-clear" "kernel" (( quot -- )) }
@@ -505,6 +506,7 @@ tuple
     { "load-locals" "locals.backend" (( ... n -- )) }
     { "check-datastack" "kernel.private" (( array in# out# -- ? )) }
     { "inline-cache-miss" "generic.single.private" (( generic methods index cache -- )) }
+    { "inline-cache-miss-tail" "generic.single.private" (( generic methods index cache -- )) }
     { "mega-cache-miss" "generic.single.private" (( methods index cache -- method )) }
     { "lookup-method" "generic.single.private" (( object methods -- method )) }
     { "reset-dispatch-stats" "generic.single" (( -- )) }
index 7655ec84824a84e364034d6c772056a8073145b1..209de83763801b4877271874dc0029c050131697 100644 (file)
@@ -12,12 +12,12 @@ CONSTANT: crc32-table V{ }
 256 iota [
     8 [
         [ 2/ ] [ even? ] bi [ crc32-polynomial bitxor ] unless
-    ] times >bignum
+    ] times
 ] map 0 crc32-table copy
 
 : (crc32) ( crc ch -- crc )
-    >bignum dupd bitxor
-    mask-byte crc32-table nth-unsafe >bignum
+    dupd bitxor
+    mask-byte crc32-table nth-unsafe
     swap -8 shift bitxor ; inline
 
 SINGLETON: crc32
index 8b301affbd995e1cd02edb06e0f3723b1efca838..1a17e8c1fbf34e99549600db5c7a7feac1573150 100755 (executable)
@@ -62,9 +62,6 @@ $nl
     ": dip   [ ] bi* ;"
     ": 2dip  [ ] [ ] tri* ;"
     ""
-    ": slip  [ call ] [ ] bi* ;"
-    ": 2slip [ call ] [ ] [ ] tri* ;"
-    ""
     ": nip   [ drop ] [ ] bi* ;"
     ": 2nip  [ drop ] [ drop ] [ ] tri* ;"
     ""
@@ -121,7 +118,7 @@ $nl
 { $subsection both? }
 { $subsection either? } ;
 
-ARTICLE: "slip-keep-combinators" "Retain stack combinators"
+ARTICLE: "retainstack-combinators" "Retain stack combinators"
 "Sometimes an additional storage area is needed to hold objects. The " { $emphasis "retain stack" } " is an auxilliary stack for this purpose. Objects can be moved between the data and retain stacks using a set of combinators."
 $nl
 "The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
@@ -129,10 +126,6 @@ $nl
 { $subsection 2dip }
 { $subsection 3dip }
 { $subsection 4dip }
-"The slip combinators invoke a quotation further down on the stack. They are most useful for implementing other combinators:"
-{ $subsection slip }
-{ $subsection 2slip }
-{ $subsection 3slip }
 "The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
 { $subsection keep }
 { $subsection 2keep }
@@ -259,7 +252,7 @@ ARTICLE: "conditionals" "Conditional combinators"
 
 ARTICLE: "dataflow-combinators" "Data flow combinators"
 "Data flow combinators pass values between quotations:"
-{ $subsection "slip-keep-combinators" }
+{ $subsection "retainstack-combinators" }
 { $subsection "cleave-combinators" }
 { $subsection "spread-combinators" }
 { $subsection "apply-combinators" }
index 2c91981f1362c2ad554ce296d404458debfd8cc2..fa8ecbe385dfd03b45a73d8ed7c9b85b53f5b0db 100644 (file)
@@ -79,7 +79,6 @@ $nl
 { $subsection continue-with }
 "Continuations as control-flow:"
 { $subsection attempt-all }
-{ $subsection retry }
 { $subsection with-return }
 "Continuations serve as the building block for a number of higher-level abstractions, such as " { $link "errors" } " and " { $link "threads" } "."
 { $subsection "continuations.private" } ;
@@ -232,21 +231,6 @@ HELP: attempt-all
     }
 } ;
 
-HELP: retry
-{ $values
-     { "quot" quotation } { "n" integer }
-}
-{ $description "Tries the quotation up to " { $snippet "n" } " times until it returns true. Retries the quotation if an exception is thrown or if the quotation returns " { $link f } ". The quotation is expected to have side effects that may fail, such as generating a random name for a new file until successful." }
-{ $examples
-    "Try to get a 0 as a random number:"
-    { $unchecked-example "USING: continuations math prettyprint random ;"
-        "[ 5 random 0 = ] 5 retry"
-        "t"
-    }
-} ;
-
-{ attempt-all retry } related-words
-
 HELP: return
 { $description "Returns early from a quotation by reifying the continuation captured by " { $link with-return } " ; execution is resumed starting immediately after " { $link with-return } "." } ;
 
index 6409fc588e9e377345ebbe2c7e399d0bcf647e4b..a2617d0ebbfda4df8da27e91fde0b5f9e167a1f9 100644 (file)
@@ -64,7 +64,7 @@ IN: continuations.tests
 
 [ 1 2 ] [ bar ] unit-test
 
-[ t ] [ \ bar def>> "c" get innermost-frame-quot = ] unit-test
+[ t ] [ \ bar def>> "c" get innermost-frame-executing = ] unit-test
 
 [ 1 ] [ "c" get innermost-frame-scan ] unit-test
 
index 56ac4a71e9721b678d38790992ea725f082a2152..7681c2b089f5543acf06398de31932ba82384906 100644 (file)
@@ -155,8 +155,6 @@ ERROR: attempt-all-error ;
         ] { } make peek swap [ rethrow ] when
     ] if ; inline
 
-: retry ( quot: ( -- ? )  n -- ) swap [ drop ] prepose attempt-all ; inline
-
 TUPLE: condition error restarts continuation ;
 
 C: <condition> condition ( error restarts cc -- condition )
index fe5b62f6c0386e9653495f6999866fd0ae33b6a7..5edbc54bd8b7dd96751c9520a1d6083d26ed705b 100644 (file)
@@ -17,8 +17,6 @@ M: hook-combination picker
 
 M: hook-combination dispatch# drop 0 ;
 
-M: hook-combination inline-cache-quot 2drop f ;
-
 M: hook-combination mega-cache-quot
     1quotation picker [ lookup-method (execute) ] surround ;
 
index c8cab970fd61b3b09803e240878611e5361a96c1..e48d404b92a60dd5d43b8cc5ad1804d21571eeb9 100644 (file)
@@ -273,5 +273,5 @@ M: growable call-next-hooker call-next-method "growable " prepend ;
 [ ] [ "IN: generic.single.tests GENERIC: xyz ( a -- b )" eval( -- ) ] unit-test
 [ ] [ "IN: generic.single.tests MATH: xyz ( a b -- c )" eval( -- ) ] unit-test
 
-[ f ] [ "xyz" "generic.single.tests" lookup direct-entry-def>> ] unit-test
+[ f ] [ "xyz" "generic.single.tests" lookup pic-def>> ] unit-test
 [ f ] [ "xyz" "generic.single.tests" lookup "decision-tree" word-prop ] unit-test
\ No newline at end of file
index d8fa04edd64e3e8a1cb3e636f6341bb74cfb6946..8d84b21bf761a4b9e8a4ebfc39e15d299d08c8d2 100644 (file)
@@ -163,7 +163,7 @@ M: hi-tag-dispatch-engine compile-engine
 
 : build-fast-hash ( methods -- buckets )
     >alist V{ } clone [ hashcode 1array ] distribute-buckets
-    [ compile-engines* >alist >array ] map ;
+    [ compile-engines* >alist { } join ] map ;
 
 M: echelon-dispatch-engine compile-engine
     dup n>> 0 = [
@@ -238,10 +238,14 @@ M: f compile-engine ;
         [ <engine> compile-engine ] bi
     ] tri ;
 
-HOOK: inline-cache-quot combination ( word methods -- quot/f )
+HOOK: inline-cache-quots combination ( word methods -- pic-quot/f pic-tail-quot/f )
+
+M: single-combination inline-cache-quots 2drop f f ;
 
 : define-inline-cache-quot ( word methods -- )
-    [ drop ] [ inline-cache-quot ] 2bi >>direct-entry-def drop ;
+    [ drop ] [ inline-cache-quots ] 2bi
+    [ >>pic-def ] [ >>pic-tail-def ] bi*
+    drop ;
 
 HOOK: mega-cache-quot combination ( methods -- quot/f )
 
index 87611a76d0a8ab7fa1dce518a1f8015e4969f999..b76bcaa5829add4e5cf5ff271f515709844c9d28 100644 (file)
@@ -3,14 +3,12 @@
 USING: accessors definitions generic generic.single kernel
 namespaces words math math.order combinators sequences
 generic.single.private quotations kernel.private
-assocs arrays layouts ;
+assocs arrays layouts make ;
 IN: generic.standard
 
 TUPLE: standard-combination < single-combination # ;
 
-: <standard-combination> ( n -- standard-combination )
-    dup 0 2 between? [ "Bad dispatch position" throw ] unless
-    standard-combination boa ;
+C: <standard-combination> standard-combination
 
 PREDICATE: standard-generic < generic
     "combination" word-prop standard-combination? ;
@@ -40,17 +38,22 @@ M: standard-generic effective-method
     [ datastack ] dip [ "combination" word-prop #>> swap <reversed> nth ] keep
     (effective-method) ;
 
-M: standard-combination inline-cache-quot ( word methods -- )
+: inline-cache-quot ( word methods miss-word -- quot )
+    [ [ literalize , ] [ , ] [ combination get #>> , { } , , ] tri* ] [ ] make ;
+
+M: standard-combination inline-cache-quots
     #! Direct calls to the generic word (not tail calls or indirect calls)
     #! will jump to the inline cache entry point instead of the megamorphic
     #! dispatch entry point.
-    combination get #>> [ { } inline-cache-miss ] 3curry [ ] like ;
+    [ \ inline-cache-miss inline-cache-quot ]
+    [ \ inline-cache-miss-tail inline-cache-quot ]
+    2bi ;
 
 : make-empty-cache ( -- array )
     mega-cache-size get f <array> ;
 
 M: standard-combination mega-cache-quot
-    combination get #>> make-empty-cache [ mega-cache-lookup ] 3curry [ ] like ;
+    combination get #>> make-empty-cache \ mega-cache-lookup [ ] 4sequence ;
 
 M: standard-generic definer drop \ GENERIC# f ;
 
index 0914134bb6f1b3b15c386bd0174d2bbff4911137..03bc3e01fd0d3a4a34488ffec18a6ac17ca60a4b 100644 (file)
@@ -139,14 +139,14 @@ M: hashtable set-at ( value key hash -- )
 PRIVATE>
 
 M: hashtable >alist
-    [ array>> [ length 2/ iota ] keep ] [ assoc-size <vector> ] bi [
+    [ array>> [ length 2/ ] keep ] [ assoc-size <vector> ] bi [
         [
             [
                 [ 1 fixnum-shift-fast ] dip
                 [ array-nth ] [ [ 1 fixnum+fast ] dip array-nth ] 2bi
             ] dip
             pick tombstone? [ 3drop ] [ [ 2array ] dip push-unsafe ] if
-        ] 2curry each
+        ] 2curry each-integer
     ] keep { } like ;
 
 M: hashtable clone
index 3469a8106477d0614eaa67dad4f6146ccb9d7aa8..ac74e6b11e68163667991b8a48fa862e47355b2d 100644 (file)
@@ -117,6 +117,7 @@ HELP: seek-relative
 }
 { $description "Seeks to an offset from the current position of the stream pointer." } ;
 
+{ seek-absolute seek-relative seek-end } related-words
 
 HELP: seek-input
 { $values
@@ -238,13 +239,13 @@ HELP: each-block
 { $description "Calls the quotation with successive blocks of data, until the current " { $link input-stream } " is exhausted." } ;
 
 HELP: stream-contents
-{ $values { "stream" "an input stream" } { "seq" "a string, byte array or " { $link f } } }
-{ $description "Reads the entire contents of a stream. If the stream is empty, outputs "  { $link f } "." }
+{ $values { "stream" "an input stream" } { "seq" { $or string byte-array } } }
+{ $description "Reads all elements in the given stream until the stream is exhausted. The type of the sequence depends on the stream's element type." }
 $io-error ;
 
 HELP: contents
-{ $values { "seq" "a string, byte array or " { $link f } } }
-{ $description "Reads the entire contents of a the stream stored in " { $link input-stream } ". If the stream is empty, outputs " { $link f } "." }
+{ $values { "seq" { $or string byte-array } } }
+{ $description "Reads all elements in the " { $link input-stream } " until the stream is exhausted. The type of the sequence depends on the stream's element type." }
 $io-error ;
 
 ARTICLE: "stream-protocol" "Stream protocol"
@@ -343,6 +344,10 @@ $nl
 { $subsection bl }
 "Seeking on the default output stream:"
 { $subsection seek-output }
+"Seeking descriptors:"
+{ $subsection seek-absolute }
+{ $subsection seek-relative }
+{ $subsection seek-end }
 "A pair of combinators for rebinding the " { $link output-stream } " variable:"
 { $subsection with-output-stream }
 { $subsection with-output-stream* }
index b43098bcd4feaa83582f103d7acaec097aacaac4..669f104a5f6f8a42aee93e1bc51b51564b63e2ef 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2003, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: hashtables generic kernel math namespaces make sequences
-continuations destructors assocs ;
+continuations destructors assocs combinators ;
 IN: io
 
 SYMBOLS: +byte+ +character+ ;
@@ -20,7 +20,9 @@ GENERIC: stream-flush ( stream -- )
 GENERIC: stream-nl ( stream -- )
 
 ERROR: bad-seek-type type ;
+
 SINGLETONS: seek-absolute seek-relative seek-end ;
+
 GENERIC: stream-seek ( n seek-type stream -- )
 
 : stream-print ( str stream -- ) [ stream-write ] keep stream-nl ;
@@ -68,29 +70,39 @@ SYMBOL: error-stream
 
 : bl ( -- ) " " write ;
 
-: stream-lines ( stream -- seq )
-    [ [ readln dup ] [ ] produce nip ] with-input-stream ;
-
-: lines ( -- seq )
-    input-stream get stream-lines ;
-
 <PRIVATE
 
 : each-morsel ( handler: ( data -- ) reader: ( -- data ) -- )
     [ dup ] compose swap while drop ; inline
 
+: stream-element-exemplar ( type -- exemplar )
+    {
+        { +byte+ [ B{ } ] }
+        { +character+ [ "" ] }
+    } case ;
+
+: element-exemplar ( -- exemplar )
+    input-stream get
+    stream-element-type
+    stream-element-exemplar ;
+
 PRIVATE>
 
 : each-line ( quot -- )
     [ readln ] each-morsel ; inline
 
-: stream-contents ( stream -- seq )
-    [
-        [ 65536 read-partial dup ] [ ] produce nip concat f like
-    ] with-input-stream ;
+: lines ( -- seq )
+    [ ] accumulator [ each-line ] dip { } like ;
+
+: stream-lines ( stream -- seq )
+    [ lines ] with-input-stream ;
 
 : contents ( -- seq )
-    input-stream get stream-contents ;
+    [ 65536 read-partial dup ] [ ] produce nip
+    element-exemplar concat-as ;
+
+: stream-contents ( stream -- seq )
+    [ contents ] with-input-stream ;
 
 : each-block ( quot: ( block -- ) -- )
     [ 8192 read-partial ] each-morsel ; inline
index 0cd35dfa213b11583f61ad91958703ffbe53004a..43a8373232d9c9c397d32db00a0e3f466c8ff220 100644 (file)
@@ -1,6 +1,7 @@
 USING: tools.test io.streams.byte-array io.encodings.binary
 io.encodings.utf8 io kernel arrays strings namespaces ;
 
+[ B{ } ] [ B{ } binary [ contents ] with-byte-reader ] unit-test
 [ B{ 1 2 3 } ] [ binary [ B{ 1 2 3 } write ] with-byte-writer ] unit-test
 [ B{ 1 2 3 } ] [ { 1 2 3 } binary [ 3 read ] with-byte-reader ] unit-test
 
index e67e2bc0ddb5de076284329b03ffd1e09549d758..22e0e76451f87222df5e0d88e836fee8b3b0ff46 100644 (file)
@@ -212,18 +212,6 @@ HELP: call-clear ( quot -- )
 { $description "Calls a quotation with an empty call stack. If the quotation returns, Factor will exit.." }
 { $notes "Used to implement " { $link "threads" } "." } ;
 
-HELP: slip
-{ $values { "quot" quotation } { "x" object } }
-{ $description "Calls a quotation while hiding the top of the stack." } ;
-
-HELP: 2slip
-{ $values { "quot" quotation } { "x" object } { "y" object } }
-{ $description "Calls a quotation while hiding the top two stack elements." } ;
-
-HELP: 3slip
-{ $values { "quot" quotation } { "x" object } { "y" object } { "z" object } }
-{ $description "Calls a quotation while hiding the top three stack elements." } ;
-
 HELP: keep
 { $values { "quot" { $quotation "( x -- ... )" } } { "x" object } }
 { $description "Call a quotation with a value on the stack, restoring the value when the quotation returns." }
index 5a88db4f9e0595e26fce7c28bf40f0799bfa6539..c8e0fcd2a98c7e2355ca12a4ec4645ec092963a0 100644 (file)
@@ -61,20 +61,16 @@ IN: kernel.tests
 [ 2 ] [ f 2 xor ] unit-test
 [ f ] [ f f xor ] unit-test
 
-[ slip ] must-fail
+[ dip ] must-fail
 [ ] [ :c ] unit-test
 
-[ 1 slip ] must-fail
+[ 1 [ call ] dip ] must-fail
 [ ] [ :c ] unit-test
 
-[ 1 2 slip ] must-fail
+[ 1 2 [ call ] dip ] must-fail
 [ ] [ :c ] unit-test
 
-[ 1 2 3 slip ] must-fail
-[ ] [ :c ] unit-test
-
-
-[ 5 ] [ [ 2 2 + ] 1 slip + ] unit-test
+[ 5 ] [ 1 [ 2 2 + ] dip + ] unit-test
 
 [ [ ] keep ] must-fail
 
index 624508022595f40d9944617fdc50b12ea3e1b4db..d6350e0420241ffbd5d2001f3c75f9d1805db265 100644 (file)
@@ -58,37 +58,19 @@ DEFER: if
 : ?if ( default cond true false -- )
     pick [ drop [ drop ] 2dip call ] [ 2nip call ] if ; inline
 
-! Slippers and dippers.
+! Dippers.
 ! Not declared inline because the compiler special-cases them
 
-: slip ( quot x -- x )
-    #! 'slip' and 'dip' can be defined in terms of each other
-    #! because the JIT special-cases a 'dip' preceeded by
-    #! a literal quotation.
-    [ call ] dip ;
+: dip ( x quot -- x ) swap [ call ] dip ;
 
-: 2slip ( quot x y -- x y )
-    #! '2slip' and '2dip' can be defined in terms of each other
-    #! because the JIT special-cases a '2dip' preceeded by
-    #! a literal quotation.
-    [ call ] 2dip ;
+: 2dip ( x y quot -- x y ) -rot [ call ] 2dip ;
 
-: 3slip ( quot x y z -- x y z )
-    #! '3slip' and '3dip' can be defined in terms of each other
-    #! because the JIT special-cases a '3dip' preceeded by
-    #! a literal quotation.
-    [ call ] 3dip ;
-
-: dip ( x quot -- x ) swap slip ;
-
-: 2dip ( x y quot -- x y ) -rot 2slip ;
-
-: 3dip ( x y z quot -- x y z ) -roll 3slip ;
+: 3dip ( x y z quot -- x y z ) -roll [ call ] 3dip ;
 
 : 4dip ( w x y z quot -- w x y z ) swap [ 3dip ] dip ; inline
 
 ! Keepers
-: keep ( x quot -- x ) over slip ; inline
+: keep ( x quot -- x ) over [ call ] dip ; inline
 
 : 2keep ( x y quot -- x y ) [ 2dup ] dip 2dip ; inline
 
index c28bf062c1954abd705f692fcf5c0bb1adf694da..e5f68a511cbdf566088e2b2f510cbcbd7ddb267f 100644 (file)
@@ -245,10 +245,22 @@ HELP: times
     { $example "USING: io math ;" "3 [ \"Hi\" print ] times" "Hi\nHi\nHi" }
 } ;
 
+HELP: fp-special?
+{ $values { "x" real } { "?" "a boolean" } }
+{ $description "Tests if " { $snippet "x" } " is an IEEE special value (Not-a-Number or Infinity). While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." } ;
+
 HELP: fp-nan?
 { $values { "x" real } { "?" "a boolean" } }
 { $description "Tests if " { $snippet "x" } " is an IEEE Not-a-Number value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." } ;
 
+HELP: fp-qnan?
+{ $values { "x" real } { "?" "a boolean" } }
+{ $description "Tests if " { $snippet "x" } " is an IEEE Quiet Not-a-Number value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." } ;
+
+HELP: fp-snan?
+{ $values { "x" real } { "?" "a boolean" } }
+{ $description "Tests if " { $snippet "x" } " is an IEEE Signaling Not-a-Number value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." } ;
+
 HELP: fp-infinity?
 { $values { "x" real } { "?" "a boolean" } }
 { $description "Tests if " { $snippet "x" } " is an IEEE Infinity value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." }
@@ -257,7 +269,26 @@ HELP: fp-infinity?
     { $example "USING: io kernel math ;" "-1/0. [ fp-infinity? ] [ 0 < ] bi and [ \"negative infinity\" print ] when" "negative infinity" }
 } ;
 
-{ fp-nan? fp-infinity? } related-words
+HELP: fp-nan-payload
+{ $values { "x" real } { "bits" integer } }
+{ $description "If " { $snippet "x" } " is an IEEE Not-a-Number value, returns the payload encoded in the value. Returns " { $link f } " if " { $snippet "x" } " is not a " { $link float } "." } ;
+
+HELP: <fp-nan>
+{ $values { "payload" integer } { "nan" float } }
+{ $description "Constructs an IEEE Not-a-Number value with a payload of " { $snippet "payload" } "." }
+{ $notes "A " { $snippet "payload" } " of " { $snippet "0" } " will construct an Infinity value." } ;
+
+{ fp-special? fp-nan? fp-qnan? fp-snan? fp-infinity? fp-nan-payload <fp-nan> } related-words
+
+HELP: next-float
+{ $values { "m" float } { "n" float } }
+{ $description "Returns the least representable " { $link float } " value greater than " { $snippet "m" } "." } ;
+
+HELP: prev-float
+{ $values { "m" float } { "n" float } }
+{ $description "Returns the greatest representable " { $link float } " value less than " { $snippet "m" } "." } ;
+
+{ next-float prev-float } related-words
 
 HELP: real-part
 { $values { "z" number } { "x" real } }
index c2077eb790cea8371271938742af97dc280fae67..b7cc51e6693586821d7fab5ac0be3bc6756fda68 100644 (file)
@@ -12,7 +12,24 @@ IN: math.tests
 [ f ] [ 1/0. fp-nan? ] unit-test
 [ f ] [ -1/0. fp-nan? ] unit-test
 [ t ] [ -0/0. fp-nan? ] unit-test
+[ t ] [ 1 <fp-nan> fp-nan? ] unit-test
+! [ t ] [ 1 <fp-nan> fp-snan? ] unit-test
+! [ f ] [ 1 <fp-nan> fp-qnan? ] unit-test
+[ t ] [ HEX: 8000000000001 <fp-nan> fp-nan? ] unit-test
+[ f ] [ HEX: 8000000000001 <fp-nan> fp-snan? ] unit-test
+[ t ] [ HEX: 8000000000001 <fp-nan> fp-qnan? ] unit-test
 
 [ t ] [ 1/0. fp-infinity? ] unit-test
 [ t ] [ -1/0. fp-infinity? ] unit-test
 [ f ] [ -0/0. fp-infinity? ] unit-test
+
+[ f ] [ 0 <fp-nan> fp-nan? ] unit-test
+[ t ] [ 0 <fp-nan> fp-infinity? ] unit-test
+
+[ 0.0 ] [ -0.0 next-float ] unit-test
+[ t ] [ 1.0 dup next-float < ] unit-test
+[ t ] [ -1.0 dup next-float < ] unit-test
+
+[ -0.0 ] [ 0.0 prev-float ] unit-test
+[ t ] [ 1.0 dup prev-float > ] unit-test
+[ t ] [ -1.0 dup prev-float > ] unit-test
index 8e0000326f99e65d670ab25bf18bd05a71a06973..da9bc4d1b5346fa61f266b12d5041aabc0e3318e 100755 (executable)
@@ -81,26 +81,64 @@ TUPLE: complex { real real read-only } { imaginary real read-only } ;
 
 UNION: number real complex ;
 
+: fp-bitwise= ( x y -- ? ) [ double>bits ] bi@ = ; inline
+
+GENERIC: fp-special? ( x -- ? )
 GENERIC: fp-nan? ( x -- ? )
+GENERIC: fp-qnan? ( x -- ? )
+GENERIC: fp-snan? ( x -- ? )
+GENERIC: fp-infinity? ( x -- ? )
+GENERIC: fp-nan-payload ( x -- bits )
 
+M: object fp-special?
+    drop f ;
 M: object fp-nan?
     drop f ;
+M: object fp-qnan?
+    drop f ;
+M: object fp-snan?
+    drop f ;
+M: object fp-infinity?
+    drop f ;
+M: object fp-nan-payload
+    drop f ;
+
+M: float fp-special?
+    double>bits -52 shift HEX: 7ff [ bitand ] keep = ;
+
+M: float fp-nan-payload
+    double>bits HEX: fffffffffffff bitand ; foldable flushable
 
 M: float fp-nan?
-    double>bits -51 shift HEX: fff [ bitand ] keep = ;
+    dup fp-special? [ fp-nan-payload zero? not ] [ drop f ] if ;
 
-GENERIC: fp-infinity? ( x -- ? )
+M: float fp-qnan?
+    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? not ] [ drop f ] if ;
 
-M: object fp-infinity?
-    drop f ;
+M: float fp-snan?
+    dup fp-nan? [ fp-nan-payload HEX: 8000000000000 bitand zero? ] [ drop f ] if ;
+
+M: float fp-infinity?
+    dup fp-special? [ fp-nan-payload zero? ] [ drop f ] if ;
+
+: <fp-nan> ( payload -- nan )
+    HEX: 7ff0000000000000 bitor bits>double ; foldable flushable
 
-M: float fp-infinity? ( float -- ? )
+: next-float ( m -- n )
     double>bits
-    dup -52 shift HEX: 7ff [ bitand ] keep = [
-        HEX: fffffffffffff bitand 0 =
-    ] [
-        drop f
-    ] if ;
+    dup -0.0 double>bits > [ 1 - bits>double ] [ ! negative non-zero
+        dup -0.0 double>bits = [ drop 0.0 ] [ ! negative zero
+            1 + bits>double ! positive
+        ] if
+    ] if ; foldable flushable
+
+: prev-float ( m -- n )
+    double>bits
+    dup -0.0 double>bits >= [ 1 + bits>double ] [ ! negative
+        dup 0.0 double>bits = [ drop -0.0 ] [ ! positive zero
+            1 - bits>double ! positive non-zero
+        ] if
+    ] if ; foldable flushable
 
 : next-power-of-2 ( m -- n )
     dup 2 <= [ drop 2 ] [ 1 - log2 1 + 2^ ] if ; inline
index c748f71c8e9df855f997872e21ca456706c5920a..1c61e33d83542a8eb27a604b3ed6d404a67a2be3 100644 (file)
@@ -26,6 +26,6 @@ IN: memory
     normalize-path native-string>alien (save-image) ;
 
 : save-image-and-exit ( path -- )
-    normalize-path native-string>alien (save-image) ;
+    normalize-path native-string>alien (save-image-and-exit) ;
 
 : save ( -- ) image save-image ;
index 3245ac1e206bda428464352efd80422fe5489741..af3c110d61db516a333fa34cc20daf2a75d4caf6 100644 (file)
@@ -19,7 +19,7 @@ M: quotation call (call) ;
 
 M: curry call uncurry call ;
 
-M: compose call uncompose slip call ;
+M: compose call uncompose [ call ] dip call ;
 
 M: wrapper equal?
     over wrapper? [ [ wrapped>> ] bi@ = ] [ 2drop f ] if ;
index cfd96789b4be5505c9d0196d5e0ee459737c48c4..b6cfface122944b6c53562f877ad3dbe06ccdc25 100755 (executable)
@@ -533,12 +533,18 @@ HELP: concat
 { $description "Concatenates a sequence of sequences together into one sequence. If " { $snippet "seq" } " is empty, outputs " { $snippet "{ }" } ", otherwise the resulting sequence is of the same class as the first element of " { $snippet "seq" } "." }
 { $errors "Throws an error if one of the sequences in " { $snippet "seq" } " contains elements not permitted in sequences of the same class as the first element of " { $snippet "seq" } "." } ;
 
+HELP: concat-as
+{ $values { "seq" sequence } { "exemplar" sequence } { "newseq" sequence } }
+{ $description "Concatenates a sequence of sequences together into one sequence with the same type as " { $snippet "exemplar" } "." }
+{ $errors "Throws an error if one of the sequences in " { $snippet "seq" } " contains elements not permitted in sequences of the same class as " { $snippet "exemplar" } "." } ;
+
 HELP: join
 { $values { "seq" sequence } { "glue" sequence } { "newseq" sequence } }
 { $description "Concatenates a sequence of sequences together into one sequence, placing a copy of " { $snippet "glue" } " between each pair of sequences. The resulting sequence is of the same class as " { $snippet "glue" } "." }
+{ $notes "If the " { $snippet "glue" } " sequence is empty, this word calls " { $link concat-as } "." }
 { $errors "Throws an error if one of the sequences in " { $snippet "seq" } " contains elements not permitted in sequences of the same class as " { $snippet "glue" } "." } ;
 
-{ join concat } related-words
+{ join concat concat-as } related-words
 
 HELP: peek
 { $values { "seq" sequence } { "elt" object } }
index d60602fc719893a62f07c8b8492e32e0d0759d8a..dd48501fa03ec6060c848dfe5ca6f35708768f62 100755 (executable)
@@ -704,13 +704,14 @@ PRIVATE>
 : sum-lengths ( seq -- n )
     0 [ length + ] reduce ;
 
+: concat-as ( seq exemplar -- newseq )
+    swap [ { } ] [
+        [ sum-lengths over new-resizable ] keep
+        [ over push-all ] each
+    ] if-empty swap like ;
+
 : concat ( seq -- newseq )
-    [ { } ] [
-        [ sum-lengths ] keep
-        [ first new-resizable ] keep
-        [ [ over push-all ] each ] keep
-        first like
-    ] if-empty ;
+    [ { } ] [ dup first concat-as ] if-empty ;
 
 <PRIVATE
 
@@ -720,12 +721,14 @@ PRIVATE>
 PRIVATE>
 
 : join ( seq glue -- newseq )
-    [
-        2dup joined-length over new-resizable [
-            [ [ push-all ] 2curry ] [ [ nip push-all ] 2curry ] 2bi
-            interleave
-        ] keep
-    ] keep like ;
+    dup empty? [ concat-as ] [
+        [
+            2dup joined-length over new-resizable [
+                [ [ push-all ] 2curry ] [ [ nip push-all ] 2curry ] 2bi
+                interleave
+            ] keep
+        ] keep like
+    ] if ;
 
 : padding ( seq n elt quot -- newseq )
     [
index 1976c1e4cd295e5674bf3bf9fd39ffd9201c8baa..c01cf13bcd1d270c978718b65029107fffe62f9b 100755 (executable)
@@ -155,7 +155,8 @@ M: word reset-word
     [ subwords forget-all ]
     [ reset-word ]
     [
-        f >>direct-entry-def
+        f >>pic-def
+        f >>pic-tail-def
         {
             "methods"
             "combination"
index e39f91acf6e0f1b429ab7b4e7926e275550df74c..44481f49f9f596de76f55dfec7ad677b2aa2023e 100755 (executable)
@@ -7,7 +7,6 @@ H{
     { deploy-math? t }
     { deploy-threads? t }
     { deploy-reflection 3 }
-    { deploy-compiler? t }
     { deploy-unicode? t }
     { deploy-io 3 }
     { "stop-after-last-window?" t }
index 3a367dcd5176f672e6c699583b38613b33d2fec3..92adf90802a7887b23c2f7b5df42eb65ee917a39 100644 (file)
@@ -6,7 +6,6 @@ H{
     { deploy-word-props? f }
     { deploy-ui? f }
     { deploy-io 1 }
-    { deploy-compiler? t }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
     { deploy-unicode? f }
index 5de5cc5e9945b1cee1ebd73ce90b3ee87bfacc82..0f8a98e6f9dede654385dd0e5472d0702acf1546 100644 (file)
@@ -18,7 +18,7 @@ IN: benchmark.pidigits
 : >matrix ( q s r t -- z )
     4array 2 group ;
 
-: produce ( z n -- z' )
+: produce ( z y -- z' )
     [ 10 ] dip -10 * 0 1 >matrix swap m. ;
 
 : gen-x ( x -- matrix )
index 91edab430e0ff21257bec1966e3e83df2d8133ac..5f9fddf1a8ab9fcef468d41807171a8c0233daf6 100644 (file)
@@ -3,7 +3,6 @@ H{
     { deploy-word-defs? f }
     { deploy-word-props? f }
     { deploy-math? f }
-    { deploy-compiler? t }
     { deploy-ui? f }
     { deploy-c-types? f }
     { "stop-after-last-window?" t }
index 96cde41c2b72f60d0e68d076c0f72b3b0158f555..9f1d8c31d294476a5c9f2001994f62b9641655f9 100644 (file)
@@ -181,19 +181,16 @@ M: bson-oid element-data-read ( type -- oid )
     read-longlong
     read-int32 oid boa ;
 
-M: bson-binary-custom element-binary-read ( size type -- dbref )
-    2drop
-    read-cstring
-    read-cstring objref boa ;
-
 M: bson-binary-bytes element-binary-read ( size type -- bytes )
     drop read ;
 
-M: bson-binary-function element-binary-read ( size type -- quot )
+M: bson-binary-custom element-binary-read ( size type -- quot )
     drop read bytes>object ;
 
 PRIVATE>
 
+USE: tools.continuations
+
 : stream>assoc ( exemplar -- assoc bytes-read )
     <state> dup state
     [ read-int32 >>size read-elements ] with-variable 
index 1b9d45b1241495c360fb72c93d603b6d9a79baf0..682257558f36710b961006f2e5217c26cd06416d 100644 (file)
@@ -62,7 +62,6 @@ M: t bson-type? ( boolean -- type ) drop T_Boolean ;
 M: f bson-type? ( boolean -- type ) drop T_Boolean ; 
 
 M: real bson-type? ( real -- type ) drop T_Double ; 
-M: word bson-type? ( word -- type ) drop T_String ; 
 M: tuple bson-type? ( tuple -- type ) drop T_Object ;  
 M: sequence bson-type? ( seq -- type ) drop T_Array ;
 M: string bson-type? ( string -- type ) drop T_String ; 
@@ -73,6 +72,7 @@ M: mdbregexp bson-type? ( regexp -- type ) drop T_Regexp ;
 
 M: oid bson-type? ( word -- type ) drop T_OID ;
 M: objref bson-type? ( objref -- type ) drop T_Binary ;
+M: word bson-type? ( word -- type ) drop T_Binary ;
 M: quotation bson-type? ( quotation -- type ) drop T_Binary ; 
 M: byte-array bson-type? ( byte-array -- type ) drop T_Binary ; 
 
@@ -112,21 +112,8 @@ M: byte-array bson-write ( binary -- )
     T_Binary_Bytes write-byte
     write ; 
 
-M: quotation bson-write ( quotation -- )
-    object>bytes [ length write-int32 ] keep
-    T_Binary_Function write-byte
-    write ; 
-
 M: oid bson-write ( oid -- )
     [ a>> write-longlong ] [ b>> write-int32 ] bi ;
-
-M: objref bson-write ( objref -- )
-    [ binary ] dip
-    '[ _
-       [ ns>> write-cstring ]
-       [ objid>> write-cstring ] bi ] with-byte-writer
-    [ length write-int32 ] keep
-    T_Binary_Custom write-byte write ;
        
 M: mdbregexp bson-write ( regexp -- )
    [ regexp>> write-cstring ]
@@ -149,7 +136,16 @@ M: assoc bson-write ( assoc -- )
        [ over skip-field? [ 2drop ] [ write-pair ] if ] assoc-each
        write-eoo ] with-length-prefix ; 
 
-M: word bson-write name>> bson-write ;
+: (serialize-code) ( code -- )
+    object>bytes [ length write-int32 ] keep
+    T_Binary_Custom write-byte
+    write ;
+
+M: quotation bson-write ( quotation -- )
+    (serialize-code) ;
+    
+M: word bson-write ( word -- )
+    (serialize-code) ;
 
 PRIVATE>
 
index 0954c9ad4188b9dc222172b136c43b0c4373e115..7cf6a3ecbafdd147edd37d71750b00fca2b0e059 100755 (executable)
@@ -3,7 +3,6 @@ H{
     { deploy-io 3 }
     { deploy-word-defs? f }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-c-types? f }
     { deploy-name "Bunny" }
     { deploy-word-props? f }
index 0009e39fa7a4460b5538edb2e0dee9332ebb493b..387193690270436f674a6a313112882f4270a671 100755 (executable)
@@ -89,7 +89,7 @@ M: bunny-buffers bunny-geom
             GL_FLOAT 0 0 buffer-offset glNormalPointer
             [
                 nv>> "float" heap-size * buffer-offset
-                3 GL_FLOAT 0 roll glVertexPointer
+                [ 3 GL_FLOAT 0 ] dip glVertexPointer
             ] [
                 ni>>
                 GL_TRIANGLES swap GL_UNSIGNED_INT 0 buffer-offset glDrawElements
index 0ad2a72100e97cbe1c0678287f3ab088916652c6..7d614ff94769a56345f44f516300e8312fd6d5f9 100755 (executable)
@@ -120,7 +120,7 @@ TUPLE: bunny-outlined
 
 : outlining-supported? ( -- ? )
     "2.0" {
-        "GL_ARB_shading_objects"
+        "GL_ARB_shader_objects"
         "GL_ARB_draw_buffers"
         "GL_ARB_multitexture"
     } has-gl-version-or-extensions? {
index 8f8adc18d88128a921703c94da8abd165e646c43..0ef255185187e2d5f5327a1aa166631ecb949505 100755 (executable)
@@ -3,7 +3,6 @@ V{
     { deploy-ui? t }
     { deploy-io 1 }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
index eeeb63dd7db86f61de4a72153f5b3d5f470a83d6..1c24d9eacbe5bfe235b32275a5e757b37231dceb 100755 (executable)
@@ -7,7 +7,6 @@ H{
     { deploy-unicode? f }
     { deploy-c-types? f }
     { deploy-word-defs? f }
-    { deploy-compiler? t }
     { deploy-io 2 }
     { deploy-reflection 1 }
     { "stop-after-last-window?" t }
index 6e6229f18243dcc4ca9bb100ca473f422d7e1cb5..9a668aa23a096e4ddb244825c0fef5ff80d482c7 100755 (executable)
@@ -31,8 +31,8 @@ MEMO: opad ( -- seq ) 64 HEX: 5c <array> ;
 
 : init-hmac ( K -- o i )
     64 0 pad-tail 
-    [ opad seq-bitxor ] keep
-    ipad seq-bitxor ;
+    [ opad seq-bitxor ]
+    [ ipad seq-bitxor ] bi ;
 
 PRIVATE>
 
index 373dd9637c7c811da2a80217218ccad830bc9090..f4ef4687b5b98a2c1b60b9094be7540eb57116ce 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.miller-rabin kernel math math.functions namespaces
+USING: math.primes kernel math math.functions namespaces
 sequences accessors ;
 IN: crypto.rsa
 
@@ -21,7 +21,7 @@ C: <rsa> rsa
 CONSTANT: public-key 65537
 
 : rsa-primes ( numbits -- p q )
-    2/ 2 unique-primes first2 ;
+    2/ 2 swap unique-primes first2 ;
 
 : modulus-phi ( numbits -- n phi ) 
     #! Loop until phi is not divisible by the public key.
diff --git a/extra/crypto/timing/authors.txt b/extra/crypto/timing/authors.txt
deleted file mode 100755 (executable)
index 7c1b2f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
diff --git a/extra/crypto/timing/timing-tests.factor b/extra/crypto/timing/timing-tests.factor
deleted file mode 100644 (file)
index 9afb913..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-USING: crypto.timing kernel tools.test system math ;
-IN: crypto.timing.tests
-
-[ t ] [ millis [ ] 1000 with-timing millis swap - 1000 >= ] unit-test
diff --git a/extra/crypto/timing/timing.factor b/extra/crypto/timing/timing.factor
deleted file mode 100644 (file)
index b2a59a1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math threads system calendar ;
-IN: crypto.timing
-
-: with-timing ( quot n -- )
-    #! force the quotation to execute in, at minimum, n milliseconds
-    millis 2slip millis - + milliseconds sleep ; inline
index 2f629123600e90092f52d53886998ece27b3f158..eaa0d3bb6949fce87143fa6ca32b8838bcec21bb 100644 (file)
@@ -5,7 +5,6 @@ H{
     { deploy-math? t }
     { deploy-name "drills" }
     { deploy-ui? t }
-    { deploy-compiler? t }
     { "stop-after-last-window?" t }
     { deploy-word-props? f }
     { deploy-c-types? f }
index 20815859ab341a624d087363630270a3f5536221..8540907db911afbdde8651d62c697ac698b24242 100755 (executable)
@@ -5,16 +5,20 @@ windows.user32 windows.messages sequences combinators locals
 math.rectangles accessors math alien alien.strings
 io.encodings.utf16 io.encodings.utf16n continuations
 byte-arrays game-input.dinput.keys-array game-input
-ui.backend.windows windows.errors ;
+ui.backend.windows windows.errors struct-arrays
+math.bitwise ;
 IN: game-input.dinput
 
+CONSTANT: MOUSE-BUFFER-SIZE 16
+
 SINGLETON: dinput-game-input-backend
 
 dinput-game-input-backend game-input-backend set-global
 
 SYMBOLS: +dinput+ +keyboard-device+ +keyboard-state+
     +controller-devices+ +controller-guids+
-    +device-change-window+ +device-change-handle+ ;
+    +device-change-window+ +device-change-handle+
+    +mouse-device+ +mouse-state+ +mouse-buffer+ ;
 
 : create-dinput ( -- )
     f GetModuleHandle DIRECTINPUT_VERSION IDirectInput8W-iid
@@ -35,8 +39,24 @@ SYMBOLS: +dinput+ +keyboard-device+ +keyboard-state+
 : set-data-format ( device format-symbol -- )
     get IDirectInputDevice8W::SetDataFormat ole32-error ;
 
+: <buffer-size-diprop> ( size -- DIPROPDWORD )
+    "DIPROPDWORD" <c-object>
+        "DIPROPDWORD" heap-size over set-DIPROPHEADER-dwSize
+        "DIPROPHEADER" heap-size over set-DIPROPHEADER-dwHeaderSize
+        0 over set-DIPROPHEADER-dwObj
+        DIPH_DEVICE over set-DIPROPHEADER-dwHow
+        swap over set-DIPROPDWORD-dwData ;
+
+: set-buffer-size ( device size -- )
+    DIPROP_BUFFERSIZE swap <buffer-size-diprop>
+    IDirectInputDevice8W::SetProperty ole32-error ;
+
 : configure-keyboard ( keyboard -- )
     [ c_dfDIKeyboard_HID set-data-format ] [ set-coop-level ] bi ;
+: configure-mouse ( mouse -- )
+    [ c_dfDIMouse2 set-data-format ]
+    [ MOUSE-BUFFER-SIZE set-buffer-size ]
+    [ set-coop-level ] tri ;
 : configure-controller ( controller -- )
     [ c_dfDIJoystick2 set-data-format ] [ set-coop-level ] bi ;
 
@@ -47,6 +67,15 @@ SYMBOLS: +dinput+ +keyboard-device+ +keyboard-state+
     256 <byte-array> <keys-array> keyboard-state boa
     +keyboard-state+ set-global ;
 
+: find-mouse ( -- )
+    GUID_SysMouse device-for-guid
+    [ configure-mouse ]
+    [ +mouse-device+ set-global ] bi
+    0 0 0 0 8 f <array> mouse-state boa
+    +mouse-state+ set-global
+    MOUSE-BUFFER-SIZE "DIDEVICEOBJECTDATA" <c-array>
+    +mouse-buffer+ set-global ;
+
 : device-info ( device -- DIDEVICEIMAGEINFOW )
     "DIDEVICEINSTANCEW" <c-object>
     "DIDEVICEINSTANCEW" heap-size over set-DIDEVICEINSTANCEW-dwSize
@@ -190,16 +219,22 @@ TUPLE: window-rect < rect window-loc ;
     +keyboard-device+ [ com-release f ] change-global
     f +keyboard-state+ set-global ;
 
+: release-mouse ( -- )
+    +mouse-device+ [ com-release f ] change-global
+    f +mouse-state+ set-global ;
+
 M: dinput-game-input-backend (open-game-input)
     create-dinput
     create-device-change-window
     find-keyboard
+    find-mouse
     set-up-controllers
     add-wm-devicechange ;
 
 M: dinput-game-input-backend (close-game-input)
     remove-wm-devicechange
     release-controllers
+    release-mouse
     release-keyboard
     close-device-change-window
     delete-dinput ;
@@ -263,6 +298,22 @@ CONSTANT: pov-values
         [ DIJOYSTATE2-rgbButtons over buttons>> length >buttons >>buttons ]
     } 2cleave ;
 
+: read-device-buffer ( device buffer count -- buffer count' )
+    [ "DIDEVICEOBJECTDATA" heap-size ] 2dip <uint>
+    [ 0 IDirectInputDevice8W::GetDeviceData ole32-error ] 2keep *uint ;
+
+: (fill-mouse-state) ( state DIDEVICEOBJECTDATA -- state )
+    [ DIDEVICEOBJECTDATA-dwData 32 >signed ] [ DIDEVICEOBJECTDATA-dwOfs ] bi {
+        { DIMOFS_X [ [ + ] curry change-dx ] }
+        { DIMOFS_Y [ [ + ] curry change-dy ] }
+        { DIMOFS_Z [ [ + ] curry change-scroll-dy ] }
+        [ [ c-bool> ] [ DIMOFS_BUTTON0 - ] bi* rot [ buttons>> set-nth ] keep ]
+    } case ;
+
+: fill-mouse-state ( buffer count -- state )
+    [ +mouse-state+ get ] 2dip swap
+    [ "DIDEVICEOBJECTDATA" byte-array>struct-array nth (fill-mouse-state) ] curry each ;
+
 : get-device-state ( device byte-array -- )
     [ dup IDirectInputDevice8W::Poll ole32-error ] dip
     [ length ] keep
@@ -283,3 +334,17 @@ M: dinput-game-input-backend read-keyboard
     +keyboard-device+ get
     [ +keyboard-state+ get [ keys>> underlying>> get-device-state ] keep ]
     [ ] [ f ] with-acquisition ;
+
+M: dinput-game-input-backend read-mouse
+    +mouse-device+ get [ +mouse-buffer+ get MOUSE-BUFFER-SIZE read-device-buffer ]
+    [ fill-mouse-state ] [ f ] with-acquisition ;
+
+M: dinput-game-input-backend reset-mouse
+    +mouse-device+ get [ f MOUSE-BUFFER-SIZE read-device-buffer ]
+    [ 2drop ] [ ] with-acquisition
+    +mouse-state+ get
+        0 >>dx
+        0 >>dy
+        0 >>scroll-dx
+        0 >>scroll-dy
+        drop ;
index 5428ca66d042bf72bf288317b389e3b90cfd09ec..4ef0acdaaf696a5dd22852f9c0ab9640fb45eceb 100755 (executable)
@@ -3,7 +3,7 @@ sequences strings math ;
 IN: game-input
 
 ARTICLE: "game-input" "Game controller input"
-"The " { $vocab-link "game-input" } " vocabulary provides cross-platform access to game controller devices such as joysticks and gamepads. It also provides an interface for polling raw keyboard input." $nl
+"The " { $vocab-link "game-input" } " vocabulary provides cross-platform access to game controller devices such as joysticks and gamepads. It also provides an interface for polling raw keyboard and mouse input." $nl
 "The game input interface must be initialized before being used:"
 { $subsection open-game-input }
 { $subsection close-game-input }
@@ -18,17 +18,19 @@ ARTICLE: "game-input" "Game controller input"
 { $subsection instance-id }
 "A hook is provided for invoking the system calibration tool:"
 { $subsection calibrate-controller }
-"The current state of a controller or the keyboard can be read:"
+"The current state of a controller, the keyboard, and the mouse can be read:"
 { $subsection read-controller }
 { $subsection read-keyboard }
+{ $subsection read-mouse }
 { $subsection controller-state }
-{ $subsection keyboard-state } ;
+{ $subsection keyboard-state }
+{ $subsection mouse-state } ;
 
 HELP: open-game-input
-{ $description "Initializes the game input interface. An exception will be thrown if the initialization fails. If the game input interface is already opened, nothing happens." } ;
+{ $description "Initializes the game input interface. An exception will be thrown if the initialization fails. Calls to open-game-input are reference counted; each call to open-game-input needs a corresponding call to close-game-input to close the game input interface." } ;
 
 HELP: close-game-input
-{ $description "Closes the game input interface, releasing any allocated resources. Once this word is called, any remaining " { $link controller } " objects are invalid. If the game input interface is not opened, nothing happens." } ;
+{ $description "Closes the game input interface, releasing any allocated resources. Once this word is called, any remaining " { $link controller } " objects are invalid." } ;
 
 HELP: game-input-opened?
 { $values { "?" "a boolean" } }
@@ -86,6 +88,14 @@ HELP: read-keyboard
 { $warning "For efficiency, the implementation may reuse the returned " { $snippet "keyboard-state" } " object next time " { $snippet "read-keyboard" } " is called. You should " { $link clone } " any values from the returned tuple you need to preserve."
 $nl "The keyboard state returned by this word is unprocessed by any keymaps, modifier keys, key repeat settings, or other operating environment postprocessing. Because of this, " { $snippet "read-keyboard" } " should not be used for text entry purposes. The Factor UI's standard gesture mechanism should be used in cases where the logical meaning of keypresses is needed; see " { $link "keyboard-gestures" } "." } ;
 
+HELP: read-mouse
+{ $values { "mouse-state" mouse-state } }
+{ $description "Reads the current mouse state relative to either when the game input interface was opened with " { $link open-game-input } " or when the mouse state was reset with " { $link reset-mouse } "." }
+{ $warning "For efficiency, the implementation may reuse the returned " { $snippet "mouse-state" } " object for future " { $snippet "read-mouse" } " or " { $snippet "reset-mouse" } " calls. You should " { $link clone } " the " { $snippet "mouse-state" } " object if you need to preserve it." } ;
+
+HELP: reset-mouse
+{ $description "Resets the mouse state. Future " { $link read-mouse } " values will be relative to the time this word is called." } ;
+
 HELP: controller-state
 { $class-description "The " { $link read-controller } " word returns objects of this class. " { $snippet "controller-state" } " objects have the following slots:"
 { $list
@@ -121,6 +131,19 @@ HELP: keyboard-state
 { $class-description "The " { $link read-keyboard } " word returns objects of this class. The " { $snippet "keys" } " slot of a " { $snippet "keyboard-state" } " object contains a " { $link sequence } " of 256 members representing the state of the keys on the keyboard. Each element is a boolean value indicating whether the corresponding key is pressed. The sequence is indexed by scancode as defined under usage page 7 of the USB HID standard. Named scancode constants are provided in the " { $vocab-link "game-input.scancodes" } " vocabulary." }
 { $warning "The scancodes used to index " { $snippet "keyboard-state" } " objects correspond to physical key positions on the keyboard--they are unaffected by keymaps, modifier keys, or other operating environment postprocessing. The face value of the constants in " { $vocab-link "game-input.scancodes" } " do not necessarily correspond to what the user expects the key to type. Because of this, " { $link read-keyboard } " should not be used for text entry purposes. The Factor UI's standard gesture mechanism should be used in cases where the logical meaning of keypresses is needed; see " { $link "keyboard-gestures" } "." } ;
 
+HELP: mouse-state
+{ $class-description "The " { $link read-mouse } " word returns objects of this class. " { $snippet "mouse-state" } " objects have the following slots:"
+{ $list
+    { { $snippet "dx" } " contains the mouse's X axis movement." }
+    { { $snippet "dy" } " contains the mouse's Y axis movement." }
+    { { $snippet "scroll-dx" } " contains the scroller's X axis movement." }
+    { { $snippet "scroll-dy" } " contains the scroller's Y axis movement." }
+    { { $snippet "buttons" } " contains a sequence of boolean values indicate the state of the mouse's buttons." }
+}
+"Mouse movement is recorded relative to when the game input interface was opened with " { $link open-game-input } " or the mouse state is reset with " { $link reset-mouse } "."
+} ;
+
+
 { keyboard-state read-keyboard } related-words
 
 ABOUT: "game-input"
index 6efe31861a69863490d75b03b1042a5e5086e954..922906df483ffac80a4d7a029433b9c20a3c84c9 100755 (executable)
@@ -1,38 +1,61 @@
-USING: arrays accessors continuations kernel system
+USING: arrays accessors continuations kernel math system
 sequences namespaces init vocabs vocabs.loader combinators ;
 IN: game-input
 
 SYMBOLS: game-input-backend game-input-opened ;
 
+game-input-opened [ 0 ] initialize
+
 HOOK: (open-game-input)  game-input-backend ( -- )
 HOOK: (close-game-input) game-input-backend ( -- )
 HOOK: (reset-game-input) game-input-backend ( -- )
 
+HOOK: get-controllers game-input-backend ( -- sequence )
+
+HOOK: product-string game-input-backend ( controller -- string )
+HOOK: product-id game-input-backend ( controller -- id )
+HOOK: instance-id game-input-backend ( controller -- id )
+
+HOOK: read-controller game-input-backend ( controller -- controller-state )
+HOOK: calibrate-controller game-input-backend ( controller -- )
+
+HOOK: read-keyboard game-input-backend ( -- keyboard-state )
+
+HOOK: read-mouse game-input-backend ( -- mouse-state )
+
+HOOK: reset-mouse game-input-backend ( -- )
+
 : game-input-opened? ( -- ? )
-    game-input-opened get ;
+    game-input-opened get zero? not ;
 
 <PRIVATE
 
 M: f (reset-game-input) ;
 
 : reset-game-input ( -- )
-    game-input-opened off
     (reset-game-input) ;
 
 [ reset-game-input ] "game-input" add-init-hook
 
 PRIVATE>
 
+ERROR: game-input-not-open ;
+
 : open-game-input ( -- )
     game-input-opened? [
         (open-game-input) 
-        game-input-opened on
-    ] unless ;
+    ] unless
+    game-input-opened [ 1+ ] change-global
+    reset-mouse ;
 : close-game-input ( -- )
+    game-input-opened [
+        dup zero? [ game-input-not-open ] when
+        1-
+    ] change-global
     game-input-opened? [
         (close-game-input) 
         reset-game-input
-    ] when ;
+    ] unless ;
 
 : with-game-input ( quot -- )
     open-game-input [ close-game-input ] [ ] cleanup ; inline
@@ -48,12 +71,6 @@ SYMBOLS:
     pov-up pov-up-right pov-right pov-down-right
     pov-down pov-down-left pov-left pov-up-left ;
 
-HOOK: get-controllers game-input-backend ( -- sequence )
-
-HOOK: product-string game-input-backend ( controller -- string )
-HOOK: product-id game-input-backend ( controller -- id )
-HOOK: instance-id game-input-backend ( controller -- id )
-
 : find-controller-products ( product-id -- sequence )
     get-controllers [ product-id = ] with filter ;
 : find-controller-instance ( product-id instance-id -- controller/f )
@@ -63,15 +80,15 @@ HOOK: instance-id game-input-backend ( controller -- id )
         [ instance-id = ] 2bi* and
     ] with with find nip ;
 
-HOOK: read-controller game-input-backend ( controller -- controller-state )
-HOOK: calibrate-controller game-input-backend ( controller -- )
-
 TUPLE: keyboard-state keys ;
 
 M: keyboard-state clone
     call-next-method dup keys>> clone >>keys ;
 
-HOOK: read-keyboard game-input-backend ( -- keyboard-state )
+TUPLE: mouse-state dx dy scroll-dx scroll-dy buttons ;
+
+M: mouse-state clone
+    call-next-method dup buttons>> clone >>buttons ;
 
 {
     { [ os windows? ] [ "game-input.dinput" require ] }
index 2ded2638996402ff893906d1ec5f1a2c387a39ea..5f09a054f97e795900b2f90a06bf845dd9ea9187 100755 (executable)
@@ -1,13 +1,15 @@
 USING: cocoa cocoa.plists core-foundation iokit iokit.hid
 kernel cocoa.enumeration destructors math.parser cocoa.application 
 sequences locals combinators.short-circuit threads
-namespaces assocs vectors arrays combinators
+namespaces assocs vectors arrays combinators hints alien
 core-foundation.run-loop accessors sequences.private
-alien.c-types math parser game-input ;
+alien.c-types math parser game-input vectors ;
 IN: game-input.iokit
 
 SINGLETON: iokit-game-input-backend
 
+SYMBOLS: +hid-manager+ +keyboard-state+ +mouse-state+ +controller-states+ ;
+
 iokit-game-input-backend game-input-backend set-global
 
 : hid-manager-matching ( matching-seq -- alien )
@@ -23,9 +25,12 @@ iokit-game-input-backend game-input-backend set-global
 
 CONSTANT: game-devices-matching-seq
     {
+        H{ { "DeviceUsage" 2 } { "DeviceUsagePage" 1 } } ! mouses
         H{ { "DeviceUsage" 4 } { "DeviceUsagePage" 1 } } ! joysticks
         H{ { "DeviceUsage" 5 } { "DeviceUsagePage" 1 } } ! gamepads
         H{ { "DeviceUsage" 6 } { "DeviceUsagePage" 1 } } ! keyboards
+        H{ { "DeviceUsage" 7 } { "DeviceUsagePage" 1 } } ! keypads
+        H{ { "DeviceUsage" 8 } { "DeviceUsagePage" 1 } } ! multiaxis controllers
     }
 
 CONSTANT: buttons-matching-hash
@@ -46,6 +51,8 @@ CONSTANT: rz-axis-matching-hash
     H{ { "UsagePage" 1 } { "Usage" HEX: 35 } { "Type" 1 } }
 CONSTANT: slider-matching-hash
     H{ { "UsagePage" 1 } { "Usage" HEX: 36 } { "Type" 1 } }
+CONSTANT: wheel-matching-hash
+    H{ { "UsagePage" 1 } { "Usage" HEX: 38 } { "Type" 1 } }
 CONSTANT: hat-switch-matching-hash
     H{ { "UsagePage" 1 } { "Usage" HEX: 39 } { "Type" 1 } }
 
@@ -82,44 +89,54 @@ CONSTANT: hat-switch-matching-hash
     game-devices-matching-seq hid-manager-matching ;
 
 : device-property ( device key -- value )
-    <NSString> IOHIDDeviceGetProperty plist> ;
+    <NSString> IOHIDDeviceGetProperty [ plist> ] [ f ] if* ;
 : element-property ( element key -- value )
-    <NSString> IOHIDElementGetProperty plist> ;
+    <NSString> IOHIDElementGetProperty [ plist> ] [ f ] if* ;
 : set-element-property ( element key value -- )
     [ <NSString> ] [ >plist ] bi* IOHIDElementSetProperty drop ;
 : transfer-element-property ( element from-key to-key -- )
-    [ dupd element-property ] dip swap set-element-property ;
+    [ dupd element-property ] dip swap
+    [ set-element-property ] [ 2drop ] if* ;
+
+: mouse-device? ( device -- ? )
+    1 2 IOHIDDeviceConformsTo ;
 
 : controller-device? ( device -- ? )
     {
         [ 1 4 IOHIDDeviceConformsTo ]
         [ 1 5 IOHIDDeviceConformsTo ]
+        [ 1 8 IOHIDDeviceConformsTo ]
     } 1|| ;
 
 : element-usage ( element -- {usage-page,usage} )
     [ IOHIDElementGetUsagePage ] [ IOHIDElementGetUsage ] bi
     2array ;
 
-: button? ( {usage-page,usage} -- ? )
-    first 9 = ; inline
-: keyboard-key? ( {usage-page,usage} -- ? )
-    first 7 = ; inline
+: button? ( element -- ? )
+    IOHIDElementGetUsagePage 9 = ; inline
+: keyboard-key? ( element -- ? )
+    IOHIDElementGetUsagePage 7 = ; inline
+: axis? ( element -- ? )
+    IOHIDElementGetUsagePage 1 = ; inline
+
 : x-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 30 } = ; inline
+    IOHIDElementGetUsage HEX: 30 = ; inline
 : y-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 31 } = ; inline
+    IOHIDElementGetUsage HEX: 31 = ; inline
 : z-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 32 } = ; inline
+    IOHIDElementGetUsage HEX: 32 = ; inline
 : rx-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 33 } = ; inline
+    IOHIDElementGetUsage HEX: 33 = ; inline
 : ry-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 34 } = ; inline
+    IOHIDElementGetUsage HEX: 34 = ; inline
 : rz-axis? ( {usage-page,usage} -- ? )
-    { 1 HEX: 35 } = ; inline
+    IOHIDElementGetUsage HEX: 35 = ; inline
 : slider? ( {usage-page,usage} -- ? )
-    { 1 HEX: 36 } = ; inline
+    IOHIDElementGetUsage HEX: 36 = ; inline
+: wheel? ( {usage-page,usage} -- ? )
+    IOHIDElementGetUsage HEX: 38 = ; inline
 : hat-switch? ( {usage-page,usage} -- ? )
-    { 1 HEX: 39 } = ; inline
+    IOHIDElementGetUsage HEX: 39 = ; inline
 
 CONSTANT: pov-values
     {
@@ -132,34 +149,70 @@ CONSTANT: pov-values
     IOHIDValueGetIntegerValue dup zero? [ drop f ] when ;
 : axis-value ( value -- [-1,1] )
     kIOHIDValueScaleTypeCalibrated IOHIDValueGetScaledValue ;
+: mouse-axis-value ( value -- n )
+    IOHIDValueGetIntegerValue ;
 : pov-value ( value -- pov-direction )
     IOHIDValueGetIntegerValue pov-values ?nth [ pov-neutral ] unless* ;
 
+: record-button ( state hid-value element -- )
+    [ buttons>> ] [ button-value ] [ IOHIDElementGetUsage 1- ] tri* rot set-nth ;
+
 : record-controller ( controller-state value -- )
-    dup IOHIDValueGetElement element-usage {
-        { [ dup button? ] [ [ button-value ] [ second 1- ] bi* rot buttons>> set-nth ] } 
-        { [ dup x-axis? ] [ drop axis-value >>x drop ] }
-        { [ dup y-axis? ] [ drop axis-value >>y drop ] }
-        { [ dup z-axis? ] [ drop axis-value >>z drop ] }
-        { [ dup rx-axis? ] [ drop axis-value >>rx drop ] }
-        { [ dup ry-axis? ] [ drop axis-value >>ry drop ] }
-        { [ dup rz-axis? ] [ drop axis-value >>rz drop ] }
-        { [ dup slider? ] [ drop axis-value >>slider drop ] }
-        { [ dup hat-switch? ] [ drop pov-value >>pov drop ] }
+    dup IOHIDValueGetElement {
+        { [ dup button? ] [ record-button ] } 
+        { [ dup axis? ] [ {
+            { [ dup x-axis? ] [ drop axis-value >>x drop ] }
+            { [ dup y-axis? ] [ drop axis-value >>y drop ] }
+            { [ dup z-axis? ] [ drop axis-value >>z drop ] }
+            { [ dup rx-axis? ] [ drop axis-value >>rx drop ] }
+            { [ dup ry-axis? ] [ drop axis-value >>ry drop ] }
+            { [ dup rz-axis? ] [ drop axis-value >>rz drop ] }
+            { [ dup slider? ] [ drop axis-value >>slider drop ] }
+            { [ dup hat-switch? ] [ drop pov-value >>pov drop ] }
+            [ 3drop ]
+        } cond ] }
         [ 3drop ]
     } cond ;
 
-SYMBOLS: +hid-manager+ +keyboard-state+ +controller-states+ ;
+HINTS: record-controller { controller-state alien } ;
 
 : ?set-nth ( value nth seq -- )
     2dup bounds-check? [ set-nth-unsafe ] [ 3drop ] if ;
 
-: record-keyboard ( value -- )
-    dup IOHIDValueGetElement element-usage keyboard-key? [
+: record-keyboard ( keyboard-state value -- )
+    dup IOHIDValueGetElement dup keyboard-key? [
         [ IOHIDValueGetIntegerValue c-bool> ]
-        [ IOHIDValueGetElement IOHIDElementGetUsage ] bi
-        +keyboard-state+ get ?set-nth
-    ] [ drop ] if ;
+        [ IOHIDElementGetUsage ] bi*
+        rot ?set-nth
+    ] [ 3drop ] if ;
+
+HINTS: record-keyboard { array alien } ;
+
+: record-mouse ( mouse-state value -- )
+    dup IOHIDValueGetElement {
+        { [ dup button? ] [ record-button ] }
+        { [ dup axis? ] [ {
+            { [ dup x-axis? ] [ drop mouse-axis-value [ + ] curry change-dx drop ] }
+            { [ dup y-axis? ] [ drop mouse-axis-value [ + ] curry change-dy drop ] }
+            { [ dup wheel?  ] [ drop mouse-axis-value [ + ] curry change-scroll-dx drop ] }
+            { [ dup z-axis? ] [ drop mouse-axis-value [ + ] curry change-scroll-dy drop ] }
+            [ 3drop ]
+        } cond ] }
+        [ 3drop ]
+    } cond ;
+
+HINTS: record-mouse { mouse-state alien } ;
+
+M: iokit-game-input-backend read-mouse
+    +mouse-state+ get ;
+
+M: iokit-game-input-backend reset-mouse
+    +mouse-state+ get
+        0 >>dx
+        0 >>dy
+        0 >>scroll-dx 
+        0 >>scroll-dy
+        drop ;
 
 : default-calibrate-saturation ( element -- )
     [ kIOHIDElementMinKey kIOHIDElementCalibrationSaturationMinKey transfer-element-property ]
@@ -194,12 +247,21 @@ SYMBOLS: +hid-manager+ +keyboard-state+ +controller-states+ ;
         [ button-count f <array> ]
     } cleave controller-state boa ;
 
+: ?add-mouse-buttons ( device -- )
+    button-count +mouse-state+ get buttons>> 
+    2dup length >
+    [ set-length ] [ 2drop ] if ;
+
 : device-matched-callback ( -- alien )
     [| context result sender device |
-        device controller-device? [
-            device <device-controller-state>
-            device +controller-states+ get set-at
-        ] when
+        {
+            { [ device controller-device? ] [
+                device <device-controller-state>
+                device +controller-states+ get set-at
+            ] }
+            { [ device mouse-device? ] [ device ?add-mouse-buttons ] }
+            [ ]
+        } cond
     ] IOHIDDeviceCallback ;
 
 : device-removed-callback ( -- alien )
@@ -209,15 +271,20 @@ SYMBOLS: +hid-manager+ +keyboard-state+ +controller-states+ ;
 
 : device-input-callback ( -- alien )
     [| context result sender value |
-        sender controller-device?
-        [ sender +controller-states+ get at value record-controller ]
-        [ value record-keyboard ]
-        if
+        {
+            { [ sender controller-device? ] [
+                sender +controller-states+ get at value record-controller
+            ] }
+            { [ sender mouse-device? ] [ +mouse-state+ get value record-mouse ] }
+            [ +keyboard-state+ get value record-keyboard ]
+        } cond
     ] IOHIDValueCallback ;
 
 : initialize-variables ( manager -- )
     +hid-manager+ set-global
     4 <vector> +controller-states+ set-global
+    0 0 0 0 2 <vector> mouse-state boa
+        +mouse-state+ set-global
     256 f <array> +keyboard-state+ set-global ;
 
 M: iokit-game-input-backend (open-game-input)
@@ -234,7 +301,7 @@ M: iokit-game-input-backend (open-game-input)
     } cleave ;
 
 M: iokit-game-input-backend (reset-game-input)
-    { +hid-manager+ +keyboard-state+ +controller-states+ }
+    { +hid-manager+ +keyboard-state+ +mouse-state+ +controller-states+ }
     [ f swap set-global ] each ;
 
 M: iokit-game-input-backend (close-game-input)
@@ -249,6 +316,7 @@ M: iokit-game-input-backend (close-game-input)
             f
         ] change-global
         f +keyboard-state+ set-global
+        f +mouse-state+ set-global
         f +controller-states+ set-global
     ] when ;
 
index 8e7c7017d40723156ef361831525533a89b7a788..8abbe6ba25ef5e702554e86ce3056be4a96717f2 100644 (file)
@@ -1,4 +1,4 @@
-USING: accessors destructors kernel math math.order namespaces
+USING: accessors calendar destructors kernel math math.order namespaces
 system threads ;
 IN: game-loop
 
@@ -50,7 +50,7 @@ CONSTANT: MAX-FRAMES-TO-SKIP 5
 
 : (run-loop) ( loop -- )
     dup running?>>
-    [ [ MAX-FRAMES-TO-SKIP ?tick ] [ redraw ] [ yield (run-loop) ] tri ]
+    [ [ MAX-FRAMES-TO-SKIP ?tick ] [ redraw ] [ 1 milliseconds sleep (run-loop) ] tri ]
     [ drop ] if ;
 
 : run-loop ( loop -- )
diff --git a/extra/game-worlds/game-worlds.factor b/extra/game-worlds/game-worlds.factor
new file mode 100644 (file)
index 0000000..fa6b326
--- /dev/null
@@ -0,0 +1,25 @@
+USING: accessors game-input game-loop kernel math ui.gadgets
+ui.gadgets.worlds ui.gestures ;
+IN: game-worlds
+
+TUPLE: game-world < world
+    game-loop
+    { tick-slice float initial: 0.0 } ;
+
+GENERIC: tick-length ( world -- millis )
+
+M: game-world draw*
+    swap >>tick-slice draw-world ;
+
+M: game-world begin-world
+    dup [ tick-length ] [ ] bi <game-loop> [ >>game-loop ] keep start-loop
+    drop
+    open-game-input ;
+
+M: game-world end-world
+    close-game-input
+    [ [ stop-loop ] when* f ] change-game-loop
+    drop ;
+
+M: game-world focusable-child* drop t ;
+
index 0692feb30d0fb9cdd457c91203864411fcc12a9b..124e2f0437467122a351660115d8abdb760818a7 100755 (executable)
@@ -3,7 +3,6 @@ V{
     { deploy-ui? t }
     { deploy-io 1 }
     { deploy-reflection 3 }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
diff --git a/extra/hashcash/authors.txt b/extra/hashcash/authors.txt
new file mode 100755 (executable)
index 0000000..f6e3b59
--- /dev/null
@@ -0,0 +1 @@
+Diego Martinelli
diff --git a/extra/hashcash/hashcash-docs.factor b/extra/hashcash/hashcash-docs.factor
new file mode 100644 (file)
index 0000000..2cfe0bb
--- /dev/null
@@ -0,0 +1,60 @@
+USING: help.markup help.syntax kernel math ;
+IN: hashcash
+
+ARTICLE: "hashcash" "Hashcash"
+"Hashcash is a denial-of-service counter measure tool."
+$nl
+"A hashcash stamp constitutes a proof-of-work which takes a parameterizable amount of work to compute for the sender. The recipient can verify received hashcash stamps efficiently."
+$nl
+"More info on hashcash:"
+$nl
+{ $url "http://www.hashcash.org/" } $nl
+{ $url "http://en.wikipedia.org/wiki/Hashcash" } $nl
+{ $url "http://www.ibm.com/developerworks/linux/library/l-hashcash.html?ca=dgr-lnxw01HashCash" } $nl
+"This library provide basic utilities for hashcash creation and validation."
+$nl
+"Creating stamps:"
+{ $subsection mint }
+{ $subsection mint* }
+"Validation:"
+{ $subsection check-stamp }
+"Hashcash tuple and constructor:"
+{ $subsection hashcash }
+{ $subsection <hashcash> }
+"Utilities:"
+{ $subsection salt } ;
+
+{ mint mint* <hashcash> check-stamp salt } related-words
+
+HELP: mint
+{ $values { "resource" "a string" } { "stamp" "generated stamp" } }
+{ $description "This word generate a valid stamp with default parameters and the specified resource." } ;
+
+HELP: mint*
+{ $values { "tuple" "a tuple" } { "stamp" "generated stamp" } }
+{ $description "As " { $snippet "mint" } " but it takes an hashcash tuple as a parameter." } ;
+
+HELP: check-stamp
+{ $values { "stamp" "a string" } { "?" boolean } }
+{ $description "Check for stamp's validity. Only supports hashcash version 1." } ;
+
+HELP: salt
+{ $values { "length" integer } { "salted" "a string" } }
+{ $description "It generates a random string of " { $snippet "length" } " characters." } ;
+
+HELP: <hashcash>
+{ $values { "tuple" object } }
+{ $description "It fill an hashcash tuple with the default values: 1 as hashcash version, 20 as bits, today's date as date and a random 8 character long salt" } ;
+
+HELP: hashcash
+{ $class-description "An hashcash object. An hashcash have the following slots:"
+    { $table
+        { { $slot "version" } "The version number. Only version 1 is supported." }
+        { { $slot "bits" } "The claimed bit value." }
+        { { $slot "date" } "The date a stamp was minted." }
+        { { $slot "resource" } "The resource for which a stamp is minted." }
+        { { $slot "ext" } "Extensions that a specialized application may want." }
+        { { $slot "salt" } "A random salt." }
+        { { $slot "suffix" } "The computed suffix. This is supposed to be manipulated by the library." }
+    }
+} ;
diff --git a/extra/hashcash/hashcash-tests.factor b/extra/hashcash/hashcash-tests.factor
new file mode 100644 (file)
index 0000000..efef40a
--- /dev/null
@@ -0,0 +1,15 @@
+USING: accessors sequences tools.test hashcash ;
+
+[ t ] [ "foo@bar.com" mint check-stamp ] unit-test
+
+[ t ] [ 
+    <hashcash> 
+        "foo@bar.com" >>resource 
+        16 >>bits 
+    mint* check-stamp ] unit-test
+
+[ t ] [ 
+    "1:20:040927:mertz@gnosis.cx::odVZhQMP:7ca28" check-stamp
+] unit-test
+
+[ 8 ] [ 8 salt length ] unit-test
diff --git a/extra/hashcash/hashcash.factor b/extra/hashcash/hashcash.factor
new file mode 100755 (executable)
index 0000000..1eb690b
--- /dev/null
@@ -0,0 +1,90 @@
+! Copyright (C) 2009 Diego Martinelli.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors byte-arrays calendar calendar.format 
+checksums checksums.openssl classes.tuple 
+fry kernel make math math.functions math.parser math.ranges 
+present random sequences splitting strings syntax ;
+IN: hashcash
+
+! Hashcash implementation
+! Reference materials listed below:
+! 
+! http://hashcash.org
+! http://en.wikipedia.org/wiki/Hashcash
+! http://www.ibm.com/developerworks/linux/library/l-hashcash.html?ca=dgr-lnxw01HashCash
+! 
+! And the reference implementation (in python):
+! http://www.gnosis.cx/download/gnosis/util/hashcash.py
+
+<PRIVATE
+
+! Return a string with today's date in the form YYMMDD
+: get-date ( -- str )
+    now [ year>> 100 mod pad-00 ] 
+        [ month>> pad-00 ] 
+        [ day>> pad-00 ] tri 3append ;
+
+! Random salt is formed by ascii characters
+! between 33 and 126
+: available-chars ( -- seq )
+    33 126 [a,b] [ CHAR: : = not ] filter ;
+
+PRIVATE>
+
+! Generate a 'length' long random salt
+: salt ( length -- salted )
+    available-chars '[ _ random ] "" replicate-as ;
+
+TUPLE: hashcash version bits date resource ext salt suffix ;
+
+: <hashcash> ( -- tuple )
+    hashcash new
+        1 >>version
+        20 >>bits
+        get-date >>date
+        8 salt >>salt ;
+
+M: hashcash string>> 
+    tuple-slots [ present ] map ":" join ;
+
+<PRIVATE
+
+: sha1-checksum ( str -- bytes )
+    openssl-sha1 checksum-bytes ; inline
+
+: set-suffix ( tuple guess -- tuple )
+    >hex >>suffix ;
+
+: get-bits ( bytes -- str )
+    [ >bin 8 CHAR: 0 pad-head ] { } map-as concat ;
+
+: checksummed-bits ( tuple -- relevant-bits )
+    dup string>> sha1-checksum
+    swap bits>> 8 / ceiling head get-bits ;
+
+: all-char-zero? ( seq -- ? )
+    [ CHAR: 0 = ] all? ; inline
+
+: valid-guess? ( checksum tuple -- ? )
+    bits>> head all-char-zero? ;
+
+: (mint) ( tuple counter -- tuple ) 
+    2dup set-suffix checksummed-bits pick 
+    valid-guess? [ drop ] [ 1+ (mint) ] if ;
+
+PRIVATE>
+
+: mint* ( tuple -- stamp )
+    0 (mint) string>> ;
+
+: mint ( resource -- stamp )
+    <hashcash>
+        swap >>resource
+    mint* ;
+
+! One might wanna add check based on the date,
+! passing a 'good-until' duration param
+: check-stamp ( stamp -- ? )
+    dup ":" split [ sha1-checksum get-bits ] dip
+    second string>number head all-char-zero? ;
+
diff --git a/extra/hashcash/summary.txt b/extra/hashcash/summary.txt
new file mode 100644 (file)
index 0000000..e5ec1d4
--- /dev/null
@@ -0,0 +1 @@
+Hashcash implementation
index 28ce8f519d32f1874cd665dfd8c65e3fd53d89a9..7fcc167cea3feb733b5334bec34330ee12bc6802 100644 (file)
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-threads? t }
+    { deploy-ui? t }
+    { deploy-reflection 1 }
+    { deploy-unicode? f }
     { deploy-math? t }
-    { deploy-name "Hello world" }
+    { deploy-io 2 }
     { deploy-c-types? f }
+    { deploy-name "Hello world" }
     { deploy-word-props? f }
-    { deploy-io 2 }
-    { deploy-ui? t }
-    { "stop-after-last-window?" t }
     { deploy-word-defs? f }
-    { deploy-compiler? t }
-    { deploy-reflection 1 }
+    { "stop-after-last-window?" t }
+    { deploy-threads? t }
 }
index f2f1c9fb189ae15826793f1ac5b211819c960351..106817aa5077251e1f84cb3dd3182b122177fa34 100644 (file)
@@ -3,7 +3,6 @@ H{
     { deploy-word-defs? f }
     { deploy-reflection 1 }
     { deploy-word-props? f }
-    { deploy-compiler? t }
     { deploy-threads? t }
     { deploy-unicode? f }
     { "stop-after-last-window?" t }
index 48c14f7cbafd7cb091160ff1465008c43102e93c..0852188761fce2f683dbe25dacfc47b52c1d0f41 100755 (executable)
@@ -1,15 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-name "Hello world (console)" }
-    { deploy-c-types? f }
-    { deploy-word-props? f }
-    { deploy-ui? f }
-    { deploy-reflection 1 }
-    { deploy-compiler? f }
     { deploy-unicode? f }
+    { deploy-ui? f }
+    { deploy-name "Hello world (console)" }
     { deploy-io 2 }
-    { deploy-word-defs? f }
     { deploy-threads? f }
-    { "stop-after-last-window?" t }
+    { deploy-reflection 1 }
     { deploy-math? f }
+    { deploy-word-props? f }
+    { deploy-word-defs? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
 }
index 79df00ff5e723c91acb6ee825c634143200fd60f..6acace858276fa25cec8f85a05b209a048ad46a7 100644 (file)
@@ -233,8 +233,7 @@ PRIVATE>
 : genre ( id3 -- string/f )
     "TCON" find-id3-frame parse-genre ;
 
-: find-mp3s ( path -- seq )
-    [ >lower ".mp3" tail? ] find-all-files ;
+: find-mp3s ( path -- seq ) ".mp3" find-by-extension ;
 
 ERROR: id3-parse-error path error ;
 
index 2818c16f9f6fc02760ec29b400a283b6f2df4976..b41dae9b38c1ffd31203f80401e2966b831065d0 100644 (file)
@@ -5,23 +5,28 @@ opengl opengl.gl opengl.textures sequences strings ui ui.gadgets
 ui.gadgets.panes ui.render ui.images ;
 IN: images.viewer
 
-TUPLE: image-gadget < gadget image-name ;
+TUPLE: image-gadget < gadget image texture ;
 
-M: image-gadget pref-dim*
-    image-name>> image-dim ;
+M: image-gadget pref-dim* image>> dim>> ;
+
+: image-gadget-texture ( gadget -- texture )
+    dup texture>> [ ] [ dup image>> { 0 0 } <texture> >>texture texture>> ] ?if ;
 
 M: image-gadget draw-gadget* ( gadget -- )
-    image-name>> draw-image ;
+    [ dim>> ] [ image-gadget-texture ] bi draw-scaled-texture ;
+
+! Todo: delete texture on ungraft
+
+GENERIC: <image-gadget> ( object -- gadget )
 
-: <image-gadget> ( image-name -- gadget )
+M: image <image-gadget>
     \ image-gadget new
-        swap >>image-name ;
+        swap >>image ;
 
-: image-window ( path -- gadget )
-    [ <image-name> <image-gadget> dup ] [ open-window ] bi ;
+M: string <image-gadget> load-image <image-gadget> ;
 
-GENERIC: image. ( object -- )
+M: pathname <image-gadget> string>> load-image <image-gadget> ;
 
-M: string image. ( image -- ) <image-name> <image-gadget> gadget. ;
+: image-window ( object -- ) <image-gadget> "Image" open-window ;
 
-M: pathname image. ( image -- ) <image-name> <image-gadget> gadget. ;
+: image. ( object -- ) <image-gadget> gadget. ;
index 9a18cf1f9b76b5b47d8db2566cce452ffd2d85e0..867fb8d62643f27c5313c74c36e8fcc844d7d405 100644 (file)
@@ -3,7 +3,6 @@ V{
     { deploy-ui? t }
     { deploy-io 1 }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
index 8f25662f9e06654e84423fb04fbabb0a24882244..8ef5231362e96d0cd3f2b20bcbc86ae79422c668 100644 (file)
@@ -10,5 +10,4 @@ H{
     { deploy-math? t }
     { "stop-after-last-window?" t }
     { deploy-ui? t }
-    { deploy-compiler? t }
 }
index 9f86336f96229e7695a9aa83c75f108a0f1ad2f8..b58870fadcf65597d5612b135cefd07e519530e0 100755 (executable)
@@ -162,18 +162,19 @@ M: key-caps-gadget pref-dim* drop KEYBOARD-SIZE ;
     relayout-1 ;
 
 M: key-caps-gadget graft*
+    open-game-input
     dup '[ _ update-key-caps-state ] FREQUENCY every >>alarm
     drop ;
 
 M: key-caps-gadget ungraft*
-    alarm>> [ cancel-alarm ] when* ;
+    alarm>> [ cancel-alarm ] when*
+    close-game-input ;
 
 M: key-caps-gadget handle-gesture
     drop [ key-down? ] [ key-up? ] bi or not ;
 
 : key-caps ( -- )
     [
-        open-game-input
         <key-caps-gadget> { 5 5 } <border> "Key Caps" open-window
     ] with-ui ;
 
index 199d48dec07bcab00f03e3dac98182d083f81a39..5031b5d93068e39f3facd95dc5a932091460228f 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel calendar io.directories io.encodings.utf8
-io.files io.launcher mason.child mason.cleanup mason.common
-mason.help mason.release mason.report mason.email mason.notify
-namespaces prettyprint ;
+io.files io.launcher namespaces prettyprint mason.child mason.cleanup
+mason.common mason.help mason.release mason.report mason.email
+mason.notify ;
 IN: mason.build
 
 QUALIFIED: continuations
@@ -19,7 +19,10 @@ QUALIFIED: continuations
 
 : begin-build ( -- )
     "factor" [ git-id ] with-directory
-    [ "git-id" to-file ] [ notify-begin-build ] bi ;
+    [ "git-id" to-file ]
+    [ current-git-id set ]
+    [ notify-begin-build ]
+    tri ;
 
 : build ( -- )
     create-build-dir
index e4a9d9da13a96cfd80f8955893b84eb56d9210b7..b7545a3c9e63e2c94fdcf937d3901be1476c79e5 100755 (executable)
@@ -4,10 +4,13 @@ USING: kernel namespaces sequences splitting system accessors
 math.functions make io io.files io.pathnames io.directories
 io.directories.hierarchy io.launcher io.encodings.utf8 prettyprint
 combinators.short-circuit parser combinators calendar
-calendar.format arrays mason.config locals system debugger ;
+calendar.format arrays mason.config locals system debugger fry
+continuations strings ;
 IN: mason.common
 
-ERROR: output-process-error output process ;
+SYMBOL: current-git-id
+
+ERROR: output-process-error { output string } { process process } ;
 
 M: output-process-error error.
     [ "Process:" print process>> . nl ]
@@ -35,15 +38,19 @@ M: unix really-delete-tree delete-tree ;
     <process>
         swap >>command
         15 minutes >>timeout
+        +closed+ >>stdin
     try-output-process ;
 
+: retry ( n quot -- )
+    '[ drop @ f ] attempt-all drop ; inline
+
 :: upload-safely ( local username host remote -- )
     [let* | temp [ remote ".incomplete" append ]
             scp-remote [ { username "@" host ":" temp } concat ]
             scp [ scp-command get ]
             ssh [ ssh-command get ] |
-        { scp local scp-remote } short-running-process
-        { ssh host "-l" username "mv" temp remote } short-running-process
+        5 [ { scp local scp-remote } short-running-process ] retry
+        5 [ { ssh host "-l" username "mv" temp remote } short-running-process ] retry
     ] ;
 
 : eval-file ( file -- obj )
index e2afe01a5661025f8dfde9c27b11ba86b4274a78..5f48ff0d4f355c5a17c6b9f4475de707c9499746 100644 (file)
@@ -1,10 +1,11 @@
 IN: mason.email.tests
 USING: mason.email mason.common mason.config namespaces tools.test ;
 
-[ "mason on linux-x86-64: error" ] [
+[ "mason on linux-x86-64: 12345 -- error" ] [
     [
         "linux" target-os set
         "x86.64" target-cpu set
+        "12345" current-git-id set
         status-error subject prefix-subject
     ] with-scope
 ] unit-test
index 23203e5222022600ef569ebab5d3f2f3b9f83ad6..302df599b48aa047f9e56c868aeafdac6197b57f 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces accessors combinators make smtp debugger
-prettyprint io io.streams.string io.encodings.utf8 io.files io.sockets
-mason.common mason.platform mason.config ;
+prettyprint sequences io io.streams.string io.encodings.utf8 io.files
+io.sockets mason.common mason.platform mason.config ;
 IN: mason.email
 
 : prefix-subject ( str -- str' )
@@ -18,11 +18,11 @@ IN: mason.email
     send-email ;
 
 : subject ( status -- str )
-    {
+    [ current-git-id get 7 short head " -- " ] dip {
         { status-clean [ "clean" ] }
         { status-dirty [ "dirty" ] }
         { status-error [ "error" ] }
-    } case ;
+    } case 3append ;
 
 : email-report ( report status -- )
     [ "text/html" ] dip subject email-status ;
index 96e31c4a450cecfaaef1ecad18d16d43b7a19ab2..c75014e1b0ea233a612669e3c697717f6e26e30b 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays accessors io io.sockets io.encodings.utf8 io.files
 io.launcher kernel make mason.config mason.common mason.email
-mason.twitter namespaces sequences prettyprint ;
+mason.twitter namespaces sequences prettyprint fry ;
 IN: mason.notify
 
 : status-notify ( input-file args -- )
@@ -14,10 +14,12 @@ IN: mason.notify
             target-cpu get ,
             target-os get ,
         ] { } make prepend
-        <process>
-            swap >>command
-            swap [ +closed+ ] unless* >>stdin
-        try-output-process
+        [ 5 ] 2dip '[
+            <process>
+                _ >>command
+                _ [ +closed+ ] unless* >>stdin
+            try-output-process
+        ] retry
     ] [ 2drop ] if ;
 
 : notify-begin-build ( git-id -- )
index 75ce828c2801cf1ad9570ab5e9917de65470fd05..07ec5a8bcd46ff0e6abf2c7978cedac81cc187bd 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.directories io.files io.launcher kernel make
-mason.common mason.config mason.platform namespaces prettyprint
-sequences ;
+namespaces prettyprint sequences mason.common mason.config
+mason.platform ;
 IN: mason.release.branch
 
 : branch-name ( -- string ) "clean-" platform append ;
@@ -21,7 +21,7 @@ IN: mason.release.branch
     ] { } make ;
 
 : push-to-clean-branch ( -- )
-    push-to-clean-branch-cmd short-running-process ;
+    5 [ push-to-clean-branch-cmd short-running-process ] retry ;
 
 : upload-clean-image-cmd ( -- args )
     [
@@ -36,7 +36,7 @@ IN: mason.release.branch
     ] { } make ;
 
 : upload-clean-image ( -- )
-    upload-clean-image-cmd short-running-process ;
+    5 [ upload-clean-image-cmd short-running-process ] retry ;
 
 : (update-clean-branch) ( -- )
     "factor" [
index 7707d162991c3124e8ce744289fa3f575f52f9a0..6e48e7cf04556d76491e45c6d401eca20d8b8061 100644 (file)
@@ -12,7 +12,7 @@ IN: mason.report
     target-cpu get
     host-name
     build-dir
-    "git-id" eval-file
+    current-git-id get
     [XML
     <h1>Build report for <->/<-></h1>
     <table>
@@ -112,8 +112,7 @@ IN: mason.report
             benchmark-error-vocabs-file
             benchmark-error-messages-file
             error-dump
-            
-            "Benchmark timings"
+
             benchmarks-file eval-file benchmarks-table
         ] output>array
     ] with-report ;
index 20b73ba67884c2bdddb34e9399f4a6d4f0844151..d1fd602f72118104b287f6c91538b2c88215da72 100644 (file)
@@ -17,6 +17,8 @@ CONSTANT: identity-transform T{ affine-transform f { 1.0 0.0 } { 0.0 1.0 } { 0.0
     [ drop origin>> ] 2tri
     v+ v+ ;
 
+: <identity> ( -- a )
+    { 1.0 0.0 } { 0.0 1.0 } { 0.0 0.0 } <affine-transform> ;
 : <translation> ( origin -- a )
     [ { 1.0 0.0 } { 0.0 1.0 } ] dip <affine-transform> ;
 : <rotation> ( theta -- transform )
index 1eda31561755d097bd30edd30836a767133a85dd..9f5795d55ac82fe0779edd4298f6cab479b3f2d1 100755 (executable)
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-threads? t }
+    { deploy-ui? t }
+    { deploy-reflection 1 }
+    { deploy-unicode? f }
     { deploy-math? t }
-    { deploy-name "Maze" }
+    { deploy-io 2 }
     { deploy-c-types? f }
+    { deploy-name "Maze" }
     { deploy-word-props? f }
-    { deploy-io 2 }
-    { deploy-ui? t }
-    { "stop-after-last-window?" t }
     { deploy-word-defs? f }
-    { deploy-compiler? t }
-    { deploy-reflection 1 }
+    { "stop-after-last-window?" t }
+    { deploy-threads? t }
 }
index 54535d5bc82edc750a55f5888576fd767f18c568..adaab737c3dc00696a0c0656356fdb86302c84de 100644 (file)
@@ -7,7 +7,6 @@ H{
     { "stop-after-last-window?" t }
     { deploy-ui? t }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-name "Merger" }
     { deploy-word-props? f }
     { deploy-threads? t }
index 32b78a2c137af31b0547281c96ccb4449af7a898..c74ff304871abeebf9eebb1ceafe45bc2bc8c9c5 100755 (executable)
@@ -3,7 +3,6 @@ V{
     { deploy-ui? t }
     { deploy-io 1 }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
diff --git a/extra/modules/remote-loading/authors.txt b/extra/modules/remote-loading/authors.txt
deleted file mode 100644 (file)
index 2300f69..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sam Anklesaria
diff --git a/extra/modules/remote-loading/remote-loading.factor b/extra/modules/remote-loading/remote-loading.factor
deleted file mode 100644 (file)
index 7a51f24..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-USING: modules.rpc-server vocabs ;
-IN: modules.remote-loading mem-service
-
-: get-vocab ( vocabstr -- vocab ) vocab ;
\ No newline at end of file
diff --git a/extra/modules/remote-loading/summary.txt b/extra/modules/remote-loading/summary.txt
deleted file mode 100644 (file)
index 304f855..0000000
+++ /dev/null
@@ -1 +0,0 @@
-required for listeners allowing remote loading of modules
\ No newline at end of file
diff --git a/extra/modules/rpc-server/authors.txt b/extra/modules/rpc-server/authors.txt
deleted file mode 100644 (file)
index 2300f69..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sam Anklesaria
diff --git a/extra/modules/rpc-server/rpc-server.factor b/extra/modules/rpc-server/rpc-server.factor
deleted file mode 100644 (file)
index 525ff35..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-USING: accessors assocs continuations effects io
-io.encodings.binary io.servers.connection kernel
-memoize namespaces parser sets sequences serialize
-threads vocabs vocabs.parser words ;
-
-IN: modules.rpc-server
-
-SYMBOL: serving-vocabs V{ } clone serving-vocabs set-global
-
-: do-rpc ( args word -- bytes )
-   [ execute ] curry with-datastack object>bytes ; inline
-
-MEMO: mem-do-rpc ( args word -- bytes ) do-rpc ; inline
-
-: process ( vocabspec -- ) vocab-words [ deserialize ] dip deserialize
-   swap at "executer" get execute( args word -- bytes ) write flush ;
-
-: (serve) ( -- ) deserialize dup serving-vocabs get-global index
-   [ process ] [ drop ] if ;
-
-: start-serving-vocabs ( -- ) [
-   <threaded-server> 5000 >>insecure binary >>encoding [ (serve) ] >>handler
-   start-server ] in-thread ;
-
-: (service) ( -- ) serving-vocabs get-global empty? [ start-serving-vocabs ] when
-   current-vocab serving-vocabs get-global adjoin
-   "get-words" create-in
-   in get [ vocab vocab-words [ stack-effect ] { } assoc-map-as ] curry
-   (( -- words )) define-inline ;
-
-SYNTAX: service \ do-rpc  "executer" set (service) ;
-SYNTAX: mem-service \ mem-do-rpc "executer" set (service) ;
-
-load-vocab-hook [
-   [ dup words>> values
-   \ mem-do-rpc "memoize" word-prop [ delete-at ] curry each ]
-append ] change-global
\ No newline at end of file
diff --git a/extra/modules/rpc-server/summary.txt b/extra/modules/rpc-server/summary.txt
deleted file mode 100644 (file)
index 396a1c8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-remote procedure call server
\ No newline at end of file
diff --git a/extra/modules/rpc/authors.txt b/extra/modules/rpc/authors.txt
deleted file mode 100644 (file)
index 2300f69..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sam Anklesaria
diff --git a/extra/modules/rpc/rpc-docs.factor b/extra/modules/rpc/rpc-docs.factor
deleted file mode 100644 (file)
index af99d21..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-USING: help.syntax help.markup ;
-IN: modules.rpc
-ARTICLE: { "modules" "protocol" } "RPC Protocol"
-{ $list
-   "Send vocab as string"
-   "Send arglist"
-   "Send word as string"
-   "Receive result list"
-} ;
\ No newline at end of file
diff --git a/extra/modules/rpc/rpc.factor b/extra/modules/rpc/rpc.factor
deleted file mode 100644 (file)
index 1c1217a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-USING: accessors compiler.units combinators fry generalizations io
-io.encodings.binary io.sockets kernel namespaces
-parser sequences serialize vocabs vocabs.parser words ;
-IN: modules.rpc
-
-DEFER: get-words
-
-: remote-quot ( addrspec vocabspec effect str -- quot )
-   '[ _ 5000 <inet> binary
-      [
-         _ serialize _ in>> length narray serialize _ serialize flush deserialize dup length firstn
-      ] with-client
-    ] ;
-
-: define-remote ( addrspec vocabspec effect str -- ) [
-      [ remote-quot ] 2keep create-in -rot define-declared word make-inline
-   ] with-compilation-unit ;
-
-: with-in ( vocab quot -- vocab ) over
-   [ '[ _ set-in @ ] in get swap dip set-in ] dip vocab ; inline
-
-: remote-vocab ( addrspec vocabspec -- vocab )
-   dup "-remote" append [ 
-      [ (( -- words )) [ "get-words" remote-quot ] keep call-effect ] 2keep
-      [ rot first2 swap define-remote ] 2curry each
-   ] with-in ;
\ No newline at end of file
diff --git a/extra/modules/rpc/summary.txt b/extra/modules/rpc/summary.txt
deleted file mode 100644 (file)
index cc1501f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-remote procedure call client
\ No newline at end of file
diff --git a/extra/modules/uploads/authors.txt b/extra/modules/uploads/authors.txt
deleted file mode 100644 (file)
index 2300f69..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sam Anklesaria
diff --git a/extra/modules/uploads/summary.txt b/extra/modules/uploads/summary.txt
deleted file mode 100644 (file)
index 1ba8ffe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-module pushing in remote-loading listeners
\ No newline at end of file
diff --git a/extra/modules/uploads/uploads.factor b/extra/modules/uploads/uploads.factor
deleted file mode 100644 (file)
index 137a2c9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-USING: assocs modules.rpc-server vocabs
-modules.remote-loading words ;
-IN: modules.uploads service
-
-: upload-vocab ( word binary -- ) \ get-vocab "memoize" word-prop set-at ;
\ No newline at end of file
diff --git a/extra/modules/using/authors.txt b/extra/modules/using/authors.txt
deleted file mode 100644 (file)
index 2300f69..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Sam Anklesaria
diff --git a/extra/modules/using/summary.txt b/extra/modules/using/summary.txt
deleted file mode 100644 (file)
index 6bafda7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-improved module import syntax
\ No newline at end of file
diff --git a/extra/modules/using/tests/tags.txt b/extra/modules/using/tests/tags.txt
deleted file mode 100644 (file)
index 6bf6830..0000000
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/modules/using/tests/test-server.factor b/extra/modules/using/tests/test-server.factor
deleted file mode 100644 (file)
index 3e6b736..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-USING: modules.rpc-server io.servers.connection ;
-IN: modules.test-server service
-: rpc-hello ( -- str ) "hello world" stop-this-server ;
\ No newline at end of file
diff --git a/extra/modules/using/tests/tests.factor b/extra/modules/using/tests/tests.factor
deleted file mode 100644 (file)
index 894075a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-USING: modules.using ;
-IN: modules.using.tests
-USING: tools.test localhost::modules.test-server ;
-[ "hello world" ] [ rpc-hello ] unit-test
\ No newline at end of file
diff --git a/extra/modules/using/using-docs.factor b/extra/modules/using/using-docs.factor
deleted file mode 100644 (file)
index c78e546..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-USING: modules.using modules.rpc-server help.syntax help.markup strings ;
-IN: modules
-
-HELP: service
-{ $syntax "IN: module service" }
-{ $description "Starts a server for requests for remote procedure calls." } ;
-
-ARTICLE: { "modules" "remote-loading" } "Using the remote-loading vocabulary"
-"If loaded, starts serving vocabularies, accessable through a " { $link POSTPONE: USING: } " form" ;
-
-HELP: USING:
-{ $syntax "USING: rpc-server::module fetch-sever::module { module qualified-name } { module => word ... } ... ;" }
-{ $description "Adds vocabularies to the front of the search path.  Vocabularies can be fetched remotely, if preceded by a valid hostname.  Name pairs facilitate imports like in the "
-{ $link POSTPONE: QUALIFIED: } " or " { $link POSTPONE: FROM: } " forms." } ;
\ No newline at end of file
diff --git a/extra/modules/using/using.factor b/extra/modules/using/using.factor
deleted file mode 100644 (file)
index b0891aa..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-USING: assocs kernel modules.remote-loading modules.rpc
-namespaces peg peg.ebnf peg-lexer sequences vocabs vocabs.parser
-strings ;
-IN: modules.using
-
-: >qualified ( vocab prefix -- assoc )
-    [ vocab-words ] [ 58 suffix ] bi* [ swap [ prepend ] dip ] curry assoc-map ;
-
-: >partial-vocab ( words assoc -- assoc )
-    [ dupd at [ no-word-error ] unless* ] curry { } map>assoc ;
-
-: remote-load ( addr vocabspec -- voab ) [ "modules.remote-loading" remote-vocab (use+) ] dip get-vocab ;
-
-: load'em ( vocab words/? -- ) [ swap >partial-vocab ] when* use get push ;
-
-EBNF: modulize
-tokenpart = (!(':').)+ => [[ >string ]]
-s = ':' => [[ drop ignore ]]
-rpc = tokenpart s s tokenpart => [[ first2 remote-vocab ]]
-remote = tokenpart s tokenpart => [[ first2 remote-load ]]
-plain = tokenpart => [[ load-vocab ]]
-module = rpc | remote | plain
-;EBNF
-
-ON-BNF: USING:
-tokenizer = <foreign factor>
-sym = !(";"|"}"|"=>").
-modspec = sym => [[ modulize ]]
-qualified = modspec sym => [[ first2 >qualified ]]
-unqualified = modspec => [[ vocab-words ]]
-words = ("=>" sym+ )? => [[ [ f ] [ second ] if-empty ]]
-long = "{" ( qualified | unqualified ) words "}" => [[ rest first2 load'em ignore ]]
-short = modspec => [[ use+ ignore ]]
-wordSpec = long | short
-using = wordSpec+ ";" => [[ drop ignore ]]
-;ON-BNF
\ No newline at end of file
index 1bd2d94e69c865432577fc3a9a8b4053ae0feadd..60b2d25764a8546976c9349f65cb353153aca75e 100644 (file)
@@ -92,6 +92,8 @@ GENERIC: mdb-index-map ( tuple -- sequence )
       [ ] [ name>> ] bi  H{ } clone [ set-at ] keep
     ] [ 2drop H{ } clone ] if ;
 
+
+
 PRIVATE>
 
 : MDB_ADDON_SLOTS ( -- slots )
@@ -116,7 +118,7 @@ PRIVATE>
     [ drop MDB_USER_KEY set-word-prop ] [ 3drop ] if ; inline
 
 : set-index-map ( class index-list -- )
-    [ [ dup user-defined-key-index ] dip index-list>map  ] output>sequence
+    [ dup user-defined-key-index ] dip index-list>map 2array
     assoc-combine MDB_INDEX_MAP set-word-prop ; inline
 
 M: tuple-class tuple-collection ( tuple -- mdb-collection )
index 917395797984c98cd4d3cdc6a58ea74ad4f78348..677fa09bf9d828d191bed1dc1ae20732ef52ea66 100644 (file)
@@ -54,19 +54,30 @@ M: mdb-persistent id-selector
            <update> >upsert update ] assoc-each ; inline
 PRIVATE>
  
-: save-tuple ( tuple -- )
-   tuple>storable [ (save-tuples) ] assoc-each ;
+: save-tuple-deep ( tuple -- )
+    tuple>storable [ (save-tuples) ] assoc-each ; 
  
 : update-tuple ( tuple -- )
-   save-tuple ;
+    [ tuple-collection name>> ]
+    [ id-selector ]
+    [ tuple>assoc ] tri
+    <update> update ;
+
+: save-tuple ( tuple -- )
+    update-tuple ;
 
 : insert-tuple ( tuple -- )
-   save-tuple ;
+   [ tuple-collection name>> ]
+   [ tuple>assoc ] bi
+   save ;
 
 : delete-tuple ( tuple -- )
    [ tuple-collection name>> ] keep
    id-selector delete ;
 
+: delete-tuples ( seq -- )
+    [ delete-tuple ] each ;
+
 : tuple>query ( tuple -- query )
    [ tuple-collection name>> ] keep
    tuple>selector <query> ;
index 6cf9543678ca9502312fb7ec279c92f0ac7eec80..2d6bdec8a837cd57bd4f6ded0ccc4aa49a4fb57d 100755 (executable)
@@ -3,7 +3,6 @@ V{
     { deploy-ui? t }
     { deploy-io 1 }
     { deploy-reflection 1 }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-word-props? f }
     { deploy-c-types? f }
diff --git a/extra/noise/noise.factor b/extra/noise/noise.factor
new file mode 100644 (file)
index 0000000..46704ee
--- /dev/null
@@ -0,0 +1,128 @@
+USING: byte-arrays combinators fry images kernel locals math
+math.affine-transforms math.functions math.order
+math.polynomials math.vectors random random.mersenne-twister
+sequences sequences.product hints arrays sequences.private
+combinators.short-circuit math.private ;
+IN: noise
+
+: <perlin-noise-table> ( -- table )
+    256 iota >byte-array randomize dup append ; inline
+
+: with-seed ( seed quot -- )
+    [ <mersenne-twister> ] dip with-random ; inline
+
+<PRIVATE
+
+: (fade) ( x y z -- x' y' z' )
+    [ { 0.0 0.0 0.0 10.0 -15.0 6.0 } polyval* ] tri@ ;
+
+HINTS: (fade) { float float float } ;
+
+: fade ( point -- point' )
+    first3 (fade) 3array ; inline
+
+:: grad ( hash x y z -- gradient )
+    hash 8  bitand zero? [ x ] [ y ] if
+        :> u
+    hash 12 bitand zero?
+    [ y ] [ hash 13 bitand 12 = [ x ] [ z ] if ] if
+        :> v
+
+    hash 1 bitand zero? [ u ] [ u neg ] if
+    hash 2 bitand zero? [ v ] [ v neg ] if + ;
+
+HINTS: grad { fixnum float float float } ;
+
+: unit-cube ( point -- cube )
+    [ floor >fixnum 256 rem ] map ;
+
+:: hashes ( table x y z -- aaa baa aba bba aab bab abb bbb )
+    x               table nth-unsafe y fixnum+fast :> a
+    x 1 fixnum+fast table nth-unsafe y fixnum+fast :> b
+
+    a               table nth-unsafe z fixnum+fast :> aa
+    b               table nth-unsafe z fixnum+fast :> ba
+    a 1 fixnum+fast table nth-unsafe z fixnum+fast :> ab
+    b 1 fixnum+fast table nth-unsafe z fixnum+fast :> bb
+
+    aa               table nth-unsafe 
+    ba               table nth-unsafe 
+    ab               table nth-unsafe 
+    bb               table nth-unsafe 
+    aa 1 fixnum+fast table nth-unsafe 
+    ba 1 fixnum+fast table nth-unsafe 
+    ab 1 fixnum+fast table nth-unsafe 
+    bb 1 fixnum+fast table nth-unsafe ; inline
+
+HINTS: hashes { byte-array fixnum fixnum fixnum } ;
+
+: >byte-map ( floats -- bytes )
+    [ 255.0 * >fixnum ] B{ } map-as ;
+
+: >image ( bytes dim -- image )
+    swap [ L f ] dip image boa ;
+
+:: perlin-noise-unsafe ( table point -- value )
+    point unit-cube :> cube
+    point dup vfloor v- :> gradients
+    gradients fade :> faded
+
+    table cube first3 hashes {
+        [ gradients first3                                    grad ]
+        [ gradients first3 [ 1.0 - ] [       ] [       ] tri* grad ]
+        [ gradients first3 [       ] [ 1.0 - ] [       ] tri* grad ]
+        [ gradients first3 [ 1.0 - ] [ 1.0 - ] [       ] tri* grad ]
+        [ gradients first3 [       ] [       ] [ 1.0 - ] tri* grad ]
+        [ gradients first3 [ 1.0 - ] [       ] [ 1.0 - ] tri* grad ]
+        [ gradients first3 [       ] [ 1.0 - ] [ 1.0 - ] tri* grad ]
+        [ gradients first3 [ 1.0 - ] [ 1.0 - ] [ 1.0 - ] tri* grad ]
+    } spread
+    faded trilerp ;
+
+ERROR: invalid-perlin-noise-table table ;
+
+: validate-table ( table -- table )
+    dup { [ byte-array? ] [ length 512 >= ] } 1&&
+    [ invalid-perlin-noise-table ] unless ;
+
+PRIVATE>
+
+: perlin-noise ( table point -- value )
+    [ validate-table ] dip perlin-noise-unsafe ; inline
+
+: normalize-0-1 ( sequence -- sequence' )
+    [ supremum ] [ infimum [ - ] keep ] [ ] tri
+    [ swap - ] with map [ swap / ] with map ;
+
+: clamp-0-1 ( sequence -- sequence' )
+    [ 0.0 max 1.0 min ] map ;
+
+: perlin-noise-map ( table transform dim -- map ) 
+    [ validate-table ] 2dip
+    [ iota ] map [ a.v 0.0 suffix perlin-noise-unsafe ] with with product-map ;
+
+: perlin-noise-byte-map ( table transform dim -- map )
+    perlin-noise-map normalize-0-1 >byte-map ;
+
+: perlin-noise-image ( table transform dim -- image )
+    [ perlin-noise-byte-map ] [ >image ] bi ;
+
+: uniform-noise-map ( seed dim -- map )
+    [ product [ 0.0 1.0 uniform-random-float ] replicate ]
+    curry with-seed ;
+
+: uniform-noise-byte-map ( seed dim -- map )
+    uniform-noise-map >byte-map ;
+
+: uniform-noise-image ( seed dim -- image )
+    [ uniform-noise-byte-map ] [ >image ] bi ;
+
+: normal-noise-map ( seed sigma dim -- map )
+    swap '[ _ product [ 0.5 _ normal-random-float ] replicate ]
+    with-seed ;
+
+: normal-noise-byte-map ( seed sigma dim -- map )
+    normal-noise-map clamp-0-1 >byte-map ;
+
+: normal-noise-image ( seed sigma dim -- image )
+    [ normal-noise-byte-map ] [ >image ] bi ;
index 35c64d4ad1106cd361292d1dfe1a9ee7de59cc45..8afbd52647e2e2ef68fa9af50a4c9e4f2d5d2f02 100755 (executable)
@@ -1,9 +1,9 @@
 USING: arrays kernel math math.functions math.order math.vectors
 namespaces opengl opengl.gl sequences ui ui.gadgets ui.gestures
-ui.gadgets.worlds ui.render accessors combinators ;
+ui.gadgets.worlds ui.render accessors combinators literals ;
 IN: opengl.demo-support
 
-: FOV ( -- x ) 2.0 sqrt 1+ ; inline
+CONSTANT: FOV $[ 2.0 sqrt 1+ ]
 CONSTANT: MOUSE-MOTION-SCALE 0.5
 CONSTANT: KEY-ROTATE-STEP 10.0
 
index 09019a29d729392b352fff57915594f1abe92bba..fef47b859c212d40a21c8e33fb88b84499e6fd45 100644 (file)
@@ -2,7 +2,7 @@ USING: help.markup help.syntax strings ;
 IN: poker
 
 HELP: <hand>
-{ $values { "str" string } { "hand" "a new hand" } }
+{ $values { "str" string } { "hand" "a new " { $link hand } } }
 { $description "Creates a new poker hand containing the cards specified in " { $snippet "str" } "." }
 { $examples
     { $example "USING: kernel math.order poker prettyprint ;"
@@ -12,8 +12,16 @@ HELP: <hand>
 }
 { $notes "Cards may be specified in any order. Hands are directly comparable to each other on the basis of their computed value. Two hands are considered equal when they would tie in a game (despite being composed of different cards)." } ;
 
+HELP: best-hand
+{ $values { "str" string } { "hand" "a new " { $link hand } } }
+{ $description "Creates a new poker hand containing the best possible combination of the cards specified in " { $snippet "str" } "." }
+{ $examples
+    { $example "USING: kernel poker prettyprint ;"
+        "\"AS KD JC KH 2D 2S KC\" best-hand >value ." "\"Full House\"" }
+} ;
+
 HELP: >cards
-{ $values { "hand" "a hand" } { "str" string } }
+{ $values { "hand" hand } { "str" string } }
 { $description "Outputs a string representation of a hand's cards." }
 { $examples
     { $example "USING: poker prettyprint ;"
@@ -21,10 +29,18 @@ HELP: >cards
 } ;
 
 HELP: >value
-{ $values { "hand" "a hand" } { "str" string } }
+{ $values { "hand" hand } { "str" string } }
 { $description "Outputs a string representation of a hand's value." }
 { $examples
     { $example "USING: poker prettyprint ;"
         "\"AC KC QC JC TC\" <hand> >value ." "\"Straight Flush\"" }
 }
 { $notes "This should not be used as a basis for hand comparison." } ;
+
+HELP: <deck>
+{ $values { "deck" "a new " { $link deck } } }
+{ $description "Creates a standard deck of 52 cards." } ;
+
+HELP: shuffle
+{ $values { "deck" deck } { "deck" "a shuffled " { $link deck } } }
+{ $description "Shuffles the cards in " { $snippet "deck" } ", in-place, using the Fisher-Yates algorithm." } ;
index ad371a6bff6d8084d68e554bd7a71665eea9f12a..6b05178462bfc4ffddb13fa2cb815ecb720471d3 100644 (file)
@@ -1,4 +1,4 @@
-USING: accessors poker poker.private tools.test math.order kernel ;
+USING: accessors kernel math.order poker poker.private tools.test ;
 IN: poker.tests
 
 [ 134236965 ] [ "KD" >ckf ] unit-test
@@ -26,3 +26,5 @@ IN: poker.tests
 
 [ t ] [ "7C 5D 4H 3S 2C" "7D 5D 4D 3C 2S" [ <hand> ] bi@ = ] unit-test
 [ f ] [ "7C 5D 4H 3S 2C" "7D 5D 4D 3C 2S" [ <hand> ] bi@ eq? ] unit-test
+
+[ 190 ] [ "AS KD JC KH 2D 2S KC" best-hand value>> ] unit-test
index e8e9fa23c5e9cf25ded89c01c287ffe5c35eca2b..a5a5a936284f4cfa2d6d31e0e4e6c38d76a4a4aa 100644 (file)
@@ -1,7 +1,9 @@
-! Copyright (c) 2009 Aaron Schaefer.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors ascii binary-search combinators kernel locals math
-    math.bitwise math.order poker.arrays sequences splitting ;
+! Copyright (c) 2009 Aaron Schaefer. All rights reserved.
+! The contents of this file are licensed under the Simplified BSD License
+! A copy of the license is available at http://factorcode.org/license.txt
+USING: accessors arrays ascii binary-search combinators kernel locals math
+    math.bitwise math.combinatorics math.order poker.arrays random sequences
+    sequences.product splitting ;
 IN: poker
 
 ! The algorithm used is based on Cactus Kev's Poker Hand Evaluator with
@@ -47,19 +49,21 @@ CONSTANT: QUEEN  10
 CONSTANT: KING   11
 CONSTANT: ACE    12
 
-CONSTANT: STRAIGHT_FLUSH   1
-CONSTANT: FOUR_OF_A_KIND   2
-CONSTANT: FULL_HOUSE       3
-CONSTANT: FLUSH            4
-CONSTANT: STRAIGHT         5
-CONSTANT: THREE_OF_A_KIND  6
-CONSTANT: TWO_PAIR         7
-CONSTANT: ONE_PAIR         8
-CONSTANT: HIGH_CARD        9
+CONSTANT: STRAIGHT_FLUSH   0
+CONSTANT: FOUR_OF_A_KIND   1
+CONSTANT: FULL_HOUSE       2
+CONSTANT: FLUSH            3
+CONSTANT: STRAIGHT         4
+CONSTANT: THREE_OF_A_KIND  5
+CONSTANT: TWO_PAIR         6
+CONSTANT: ONE_PAIR         7
+CONSTANT: HIGH_CARD        8
+
+CONSTANT: SUIT_STR { "C" "D" "H" "S" }
 
 CONSTANT: RANK_STR { "2" "3" "4" "5" "6" "7" "8" "9" "T" "J" "Q" "K" "A" }
 
-CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
+CONSTANT: VALUE_STR { "Straight Flush" "Four of a Kind" "Full House" "Flush"
     "Straight" "Three of a Kind" "Two Pair" "One Pair" "High Card" }
 
 : card-rank-prime ( rank -- n )
@@ -108,6 +112,9 @@ CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
     #! Cactus Kev Format
     >upper 1 cut (>ckf) ;
 
+: parse-cards ( str -- seq )
+    " " split [ >ckf ] map ;
+
 : flush? ( cards -- ? )
     HEX: F000 [ bitand ] reduce 0 = not ;
 
@@ -152,8 +159,8 @@ CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
         [ drop "S" ]
     } cond ;
 
-: hand-rank ( hand -- rank )
-    value>> {
+: hand-rank ( value -- rank )
+    {
         { [ dup 6185 > ] [ drop HIGH_CARD ] }        ! 1277 high card
         { [ dup 3325 > ] [ drop ONE_PAIR ] }         ! 2860 one pair
         { [ dup 2467 > ] [ drop TWO_PAIR ] }         !  858 two pair
@@ -165,24 +172,38 @@ CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
         [ drop STRAIGHT_FLUSH ]                      !   10 straight-flushes
     } cond ;
 
+: card>string ( card -- str )
+    [ >card-rank ] [ >card-suit ] bi append ;
+
 PRIVATE>
 
 TUPLE: hand
     { cards sequence }
-    { value integer } ;
+    { value integer initial: 9999 } ;
 
 M: hand <=> [ value>> ] compare ;
 M: hand equal?
     over hand? [ [ value>> ] bi@ = ] [ 2drop f ] if ;
 
 : <hand> ( str -- hand )
-    " " split [ >ckf ] map
-    dup hand-value hand boa ;
+    parse-cards dup hand-value hand boa ;
+
+: best-hand ( str -- hand )
+    parse-cards 5 hand new
+    [ dup hand-value hand boa min ] reduce-combinations ;
 
 : >cards ( hand -- str )
-    cards>> [
-        [ >card-rank ] [ >card-suit ] bi append
-    ] map " " join ;
+    cards>> [ card>string ] map " " join ;
 
 : >value ( hand -- str )
-    hand-rank VALUE_STR nth ;
+    value>> hand-rank VALUE_STR nth ;
+
+TUPLE: deck
+    { cards sequence } ;
+
+: <deck> ( -- deck )
+    RANK_STR SUIT_STR 2array [ concat >ckf ] product-map deck boa ;
+
+: shuffle ( deck -- deck )
+    [ randomize ] change-cards ;
+
index c8efe851c814f132ba015e3cb01e4cdf2978993c..8dbbe9bd7420fe2859c78b0ea8d9b74c4828794a 100644 (file)
@@ -1 +1 @@
-5-card poker hand evaluator
+Poker hand evaluator
index 0d4f5fb1bdddbbc5e5fd92c50048be95cd4b49c5..204527418b2828de68ede1571adb1a49cdaf6111 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2007, 2008 Aaron Schaefer, Slava Pestov.
+! Copyright (c) 2007-2009 Aaron Schaefer, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.functions math.ranges project-euler.common sequences
     sets ;
@@ -47,14 +47,14 @@ PRIVATE>
 
 
 : euler001b ( -- answer )
-    1000 [ [ 5 mod ] [ 3 mod ] bi [ 0 = ] either? ] filter sum ;
+    1000 [0,b) [ [ 5 mod ] [ 3 mod ] bi [ 0 = ] either? ] filter sum ;
 
 ! [ euler001b ] 100 ave-time
 ! 0 ms ave run time - 0.06 SD (100 trials)
 
 
 : euler001c ( -- answer )
-    1000 [ { 3 5 } [ divisor? ] with any? ] filter sum ;
+    1000 [0,b) [ { 3 5 } [ divisor? ] with any? ] filter sum ;
 
 ! [ euler001c ] 100 ave-time
 ! 0 ms ave run time - 0.06 SD (100 trials)
index 7fef29a6b9d73be55a9c70923485db6c50df537e..8512bc97fa42aa3334edfc407e45d50a7b69c9eb 100644 (file)
@@ -1,6 +1,6 @@
-! Copyright (c) 2007 Aaron Schaefer.
+! Copyright (c) 2007, 2009 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math math.functions sequences project-euler.common ;
+USING: math math.functions math.ranges project-euler.common sequences ;
 IN: project-euler.005
 
 ! http://projecteuler.net/index.php?section=problems&id=5
@@ -18,7 +18,7 @@ IN: project-euler.005
 ! --------
 
 : euler005 ( -- answer )
-    20 1 [ 1+ lcm ] reduce ;
+    20 [1,b] 1 [ lcm ] reduce ;
 
 ! [ euler005 ] 100 ave-time
 ! 0 ms ave run time - 0.14 SD (100 trials)
index 9c7c4fee74d18667c27079fe4a954994480a99d0..9189323121a28479e0e881bb1da28d9ba36a688a 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu, Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math project-euler.common sequences ;
+USING: kernel math math.ranges project-euler.common sequences ;
 IN: project-euler.018
 
 ! http://projecteuler.net/index.php?section=problems&id=18
@@ -66,7 +66,7 @@ IN: project-euler.018
            91  71  52  38  17  14  91  43  58  50  27  29  48
          63  66  04  68  89  53  67  30  73  16  69  87  40  31
        04  62  98  27  23  09  70  98  73  93  38  53  60  04  23
-     } 15 iota [ 1+ cut swap ] map nip ;
+     } 15 [1,b] [ cut swap ] map nip ;
 
 PRIVATE>
 
index 80a933dc63a74a106aca65fbd1dcdf2b7a4e4188..5dfe7b9f56343ea334886858a2fe2a6d42f1d826 100644 (file)
@@ -39,7 +39,7 @@ IN: project-euler.025
 ! Memoized brute force
 
 MEMO: fib ( m -- n )
-    dup 1 > [ 1- dup fib swap 1- fib + ] when ;
+    dup 1 > [ [ 1 - fib ] [ 2 - fib ] bi + ] when ;
 
 <PRIVATE
 
index 4bcfb66a9405d73726179abfbca50f8d673c20ee..f7bffbf66587d55452c1015796e34c44d7953c46 100644 (file)
@@ -1,7 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.primes project-euler.common sequences
-project-euler.common ;
+USING: kernel math math.primes math.ranges project-euler.common sequences ;
 IN: project-euler.027
 
 ! http://projecteuler.net/index.php?section=problems&id=27
@@ -47,7 +46,7 @@ IN: project-euler.027
 <PRIVATE
 
 : source-027 ( -- seq )
-    1000 [ prime? ] filter [ dup [ neg ] map append ] keep
+    1000 [0,b) [ prime? ] filter [ dup [ neg ] map append ] keep
     cartesian-product [ first2 < ] filter ;
 
 : quadratic ( b a n -- m )
index 54d48660d5af251e7caf7124892f12c0bebd9122..2a75336a0d4c3c9e9ac8b45cea2d2f53a9217648 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions project-euler.common sequences ;
+USING: kernel math math.functions math.ranges project-euler.common sequences ;
 IN: project-euler.030
 
 ! http://projecteuler.net/index.php?section=problems&id=30
@@ -38,7 +38,7 @@ IN: project-euler.030
 PRIVATE>
 
 : euler030 ( -- answer )
-    325537 [ dup sum-fifth-powers = ] filter sum 1- ;
+    325537 [0,b) [ dup sum-fifth-powers = ] filter sum 1- ;
 
 ! [ euler030 ] 100 ave-time
 ! 1700 ms ave run time - 64.84 SD (100 trials)
index 64c9ec445e373a6b4c40b71d19c05bcef77a4cad..814f8a5a6382d92187e616db9901315fc33d8a6e 100755 (executable)
@@ -28,7 +28,7 @@ IN: project-euler.032
 
 : source-032 ( -- seq )
     9 factorial iota [
-        9 permutation [ 1+ ] map 10 digits>integer
+        9 permutation [ 1 + ] map 10 digits>integer
     ] map ;
 
 : 1and4 ( n -- ? )
index e4b8dcc955518ad86bf8f71bfbed1b4457574b3c..0aa9eafe58017297ca159ffff4a694490c7ec8db 100755 (executable)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.primes math.ranges sequences project-euler.common ;
+USING: kernel math math.functions math.primes math.ranges
+sequences project-euler.common math.bitwise ;
 IN: project-euler.046
 
 ! http://projecteuler.net/index.php?section=problems&id=46
index e56b9e9548bd99a70e19e4262234e9b183b6b3ce..640a3a68f69efe0549e752388b9dc10bf259e493 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions sequences project-euler.common ;
+USING: kernel math math.functions math.ranges project-euler.common sequences ;
 IN: project-euler.048
 
 ! http://projecteuler.net/index.php?section=problems&id=48
@@ -17,7 +17,7 @@ IN: project-euler.048
 ! --------
 
 : euler048 ( -- answer )
-    1000 [ 1+ dup ^ ] sigma 10 10 ^ mod ;
+    1000 [1,b] [ dup ^ ] sigma 10 10 ^ mod ;
 
 ! [ euler048 ] 100 ave-time
 ! 276 ms run / 1 ms GC ave time - 100 trials
index 43f380b3ba820de37a836288f8b00fbd213eceae..07525fe6a49fdfaee5940b219b2ecbc060af2907 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.parser project-euler.common sequences ;
+USING: kernel math math.parser math.ranges project-euler.common sequences ;
 IN: project-euler.055
 
 ! http://projecteuler.net/index.php?section=problems&id=55
@@ -61,7 +61,7 @@ IN: project-euler.055
 PRIVATE>
 
 : euler055 ( -- answer )
-    10000 [ lychrel? ] count ;
+    10000 [0,b) [ lychrel? ] count ;
 
 ! [ euler055 ] 100 ave-time
 ! 478 ms ave run time - 30.63 SD (100 trials)
index 681a17dd9ec2fe17434d74e380e77e868be72996..97789944fe9b74ced76c1bfa7c19f53110f55273 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2008 Samuel Tardieu
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.parser sequences project-euler.common ;
+USING: kernel math math.functions math.parser math.ranges project-euler.common
+    sequences ;
 IN: project-euler.057
 
 ! http://projecteuler.net/index.php?section=problems&id=57
@@ -11,14 +12,14 @@ IN: project-euler.057
 ! It is possible to show that the square root of two can be expressed
 ! as an infinite continued fraction.
 
-! âˆš 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...
+!     âˆš 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...
 
 ! By expanding this for the first four iterations, we get:
 
-! 1 + 1/2 = 3/2 = 1.5
-! 1 + 1/(2 + 1/2) = 7/5 = 1.4
-! 1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
-! 1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...
+!     1 + 1/2 = 3/2 = 1.5
+!     1 + 1/(2 + 1/2) = 7/5 = 1.4
+!     1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
+!     1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...
 
 ! The next three expansions are 99/70, 239/169, and 577/408, but the
 ! eighth expansion, 1393/985, is the first example where the number of
@@ -35,9 +36,9 @@ IN: project-euler.057
     >fraction [ number>string length ] bi@ > ; inline
 
 : euler057 ( -- answer )
-    0 1000 [ drop 2 + recip dup 1+ longer-numerator? ] count nip ;
+    0 1000 [0,b) [ drop 2 + recip dup 1 + longer-numerator? ] count nip ;
 
-! [ euler057 ] time
-! 3.375118 seconds
+! [ euler057 ] 100 ave-time
+! 1728 ms ave run time - 80.81 SD (100 trials)
 
 SOLUTION: euler057
index 314698534fe8dfc0e8b2845d3cf644a5b6ddf0bd..eeb4b0c315eb82420b8db813dd3c1d1ddacf650b 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: hints kernel locals math math.order sequences sequences.private project-euler.common ;
+USING: hints kernel locals math math.order math.ranges project-euler.common
+    sequences sequences.private ;
 IN: project-euler.150
 
 ! http://projecteuler.net/index.php?section=problems&id=150
@@ -50,13 +51,13 @@ IN: project-euler.150
     615949 * 797807 + 20 2^ rem dup 19 2^ - ; inline
 
 : sums-triangle ( -- seq )
-    0 1000 iota [ 1+ [ next ] replicate partial-sums ] map nip ;
+    0 1000 [1,b] [ [ next ] replicate partial-sums ] map nip ;
 
 :: (euler150) ( m -- n )
     [let | table [ sums-triangle ] |
         m [| x |
             x 1+ [| y |
-                m x - iota [| z |
+                m x - [0,b) [| z |
                     x z + table nth-unsafe
                     [ y z + 1+ swap nth-unsafe ]
                     [ y        swap nth-unsafe ] bi -
index c2ffe26d949cbdbeefaf594651d0a4966d7f4d61..84291f2ce83d44a6d81f3eccc74426ddc3d78814 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007-2009 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel lists make math math.functions math.matrices
-    math.miller-rabin math.order math.parser math.primes.factors
+    math.primes.miller-rabin math.order math.parser math.primes.factors
     math.primes.lists math.ranges math.ratios namespaces parser prettyprint
     quotations sequences sorting strings unicode.case vocabs vocabs.parser
     words ;
index dc764fd040b6894a3121b1b425479345dc9f36e7..8229abca69caaeba103398fa7ce831cbd7ba4f51 100755 (executable)
@@ -1,5 +1,5 @@
-USING: kernel math sequences namespaces
-math.miller-rabin math.functions accessors random ;
+USING: kernel math sequences namespaces math.primes
+math.functions accessors random ;
 IN: random.blum-blum-shub
 
 ! Blum Blum Shub, n = pq, x_i+1 = x_i ^ 2 mod n
diff --git a/extra/redis/authors.txt b/extra/redis/authors.txt
new file mode 100644 (file)
index 0000000..f4a8cb1
--- /dev/null
@@ -0,0 +1 @@
+Bruno Deferrari
diff --git a/extra/redis/command-writer/authors.txt b/extra/redis/command-writer/authors.txt
new file mode 100644 (file)
index 0000000..f4a8cb1
--- /dev/null
@@ -0,0 +1 @@
+Bruno Deferrari
diff --git a/extra/redis/command-writer/command-writer-tests.factor b/extra/redis/command-writer/command-writer-tests.factor
new file mode 100644 (file)
index 0000000..901c4e4
--- /dev/null
@@ -0,0 +1,138 @@
+! Copyright (C) 2009 Bruno Deferrari
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test redis.command-writer io.streams.string ;
+IN: redis.command-writer.tests
+
+#! Connection
+[ "QUIT\r\n" ] [ [ quit ] with-string-writer ] unit-test
+
+[ "PING\r\n" ] [ [ ping ] with-string-writer ] unit-test
+
+[ "AUTH password\r\n" ] [ [ "password" auth ] with-string-writer ] unit-test
+
+#! String values
+[ "SET key 3\r\nfoo\r\n" ] [ [ "foo" "key" set ] with-string-writer ] unit-test
+
+[ "GET key\r\n" ] [ [ "key" get ] with-string-writer ] unit-test
+
+[ "GETSET key 3\r\nfoo\r\n" ] [
+    [ "foo" "key" getset ] with-string-writer
+] unit-test
+
+[ "MGET key1 key2 key3\r\n" ] [
+    [ { "key1" "key2" "key3" } mget ] with-string-writer
+] unit-test
+
+[ "SETNX key 3\r\nfoo\r\n" ] [
+    [ "foo" "key" setnx ] with-string-writer
+] unit-test
+
+[ "INCR key\r\n" ] [ [ "key" incr ] with-string-writer ] unit-test
+
+[ "INCRBY key 7\r\n" ] [ [ 7 "key" incrby ] with-string-writer ] unit-test
+
+[ "DECR key\r\n" ] [ [ "key" decr ] with-string-writer ] unit-test
+
+[ "DECRBY key 7\r\n" ] [ [ 7 "key" decrby ] with-string-writer ] unit-test
+
+[ "EXISTS key\r\n" ] [ [ "key" exists ] with-string-writer ] unit-test
+
+[ "DEL key\r\n" ] [ [ "key" del ] with-string-writer ] unit-test
+
+[ "TYPE key\r\n" ] [ [ "key" type ] with-string-writer ] unit-test
+
+#! Key space
+[ "KEYS pat*\r\n" ] [ [ "pat*" keys ] with-string-writer ] unit-test
+
+[ "RANDOMKEY\r\n" ] [ [ randomkey ] with-string-writer ] unit-test
+
+[ "RENAME key newkey\r\n" ] [
+    [ "newkey" "key" rename ] with-string-writer
+] unit-test
+
+[ "RENAMENX key newkey\r\n" ] [
+    [ "newkey" "key" renamenx ] with-string-writer
+] unit-test
+
+[ "DBSIZE\r\n" ] [ [ dbsize ] with-string-writer ] unit-test
+
+[ "EXPIRE key 7\r\n" ] [ [ 7 "key" expire ] with-string-writer ] unit-test
+
+#! Lists
+[ "RPUSH key 3\r\nfoo\r\n" ] [ [ "foo" "key" rpush ] with-string-writer ] unit-test
+
+[ "LPUSH key 3\r\nfoo\r\n" ] [ [ "foo" "key" lpush ] with-string-writer ] unit-test
+
+[ "LLEN key\r\n" ] [ [ "key" llen ] with-string-writer ] unit-test
+
+[ "LRANGE key 5 9\r\n" ] [ [ 5 9 "key" lrange ] with-string-writer ] unit-test
+
+[ "LTRIM key 5 9\r\n" ] [ [ 5 9 "key" ltrim ] with-string-writer ] unit-test
+
+[ "LINDEX key 7\r\n" ] [ [ 7 "key" lindex ] with-string-writer ] unit-test
+
+[ "LSET key 0 3\r\nfoo\r\n" ] [ [ "foo" 0 "key" lset ] with-string-writer ] unit-test
+
+[ "LREM key 1 3\r\nfoo\r\n" ] [ [ "foo" 1 "key" lrem ] with-string-writer ] unit-test
+
+[ "LPOP key\r\n" ] [ [ "key" lpop ] with-string-writer ] unit-test
+
+[ "RPOP key\r\n" ] [ [ "key" rpop ] with-string-writer ] unit-test
+
+#! Sets
+[ "SADD key 3\r\nfoo\r\n" ] [ [ "foo" "key" sadd ] with-string-writer ] unit-test
+
+[ "SREM key 3\r\nfoo\r\n" ] [ [ "foo" "key" srem ] with-string-writer ] unit-test
+
+[ "SMOVE srckey dstkey 3\r\nfoo\r\n" ] [
+    [ "foo" "dstkey" "srckey" smove ] with-string-writer
+] unit-test
+
+[ "SCARD key\r\n" ] [ [ "key" scard ] with-string-writer ] unit-test
+
+[ "SISMEMBER key 3\r\nfoo\r\n" ] [
+    [ "foo" "key" sismember ] with-string-writer
+] unit-test
+
+[ "SINTER key1 key2 key3\r\n" ] [
+    [ { "key1" "key2" "key3" } sinter ] with-string-writer
+] unit-test
+
+[ "SINTERSTORE dstkey key1 key2 key3\r\n" ] [
+    [ { "key1" "key2" "key3" } "dstkey" sinterstore ] with-string-writer
+] unit-test
+
+[ "SUNION key1 key2 key3\r\n" ] [
+    [ { "key1" "key2" "key3" } sunion ] with-string-writer
+] unit-test
+
+[ "SUNIONSTORE dstkey key1 key2 key3\r\n" ] [
+    [ { "key1" "key2" "key3" } "dstkey" sunionstore ] with-string-writer
+] unit-test
+
+[ "SMEMBERS key\r\n" ] [ [ "key" smembers ] with-string-writer ] unit-test
+
+#! Multiple db
+[ "SELECT 2\r\n" ] [ [ 2 select ] with-string-writer ] unit-test
+
+[ "MOVE key 2\r\n" ] [ [ 2 "key" move ] with-string-writer ] unit-test
+
+[ "FLUSHDB\r\n" ] [ [ flushdb ] with-string-writer ] unit-test
+
+[ "FLUSHALL\r\n" ] [ [ flushall ] with-string-writer ] unit-test
+
+#! Sorting
+
+#! Persistence control
+[ "SAVE\r\n" ] [ [ save ] with-string-writer ] unit-test
+
+[ "BGSAVE\r\n" ] [ [ bgsave ] with-string-writer ] unit-test
+
+[ "LASTSAVE\r\n" ] [ [ lastsave ] with-string-writer ] unit-test
+
+[ "SHUTDOWN\r\n" ] [ [ shutdown ] with-string-writer ] unit-test
+
+#! Remote server control
+[ "INFO\r\n" ] [ [ info ] with-string-writer ] unit-test
+
+[ "MONITOR\r\n" ] [ [ monitor ] with-string-writer ] unit-test
diff --git a/extra/redis/command-writer/command-writer.factor b/extra/redis/command-writer/command-writer.factor
new file mode 100644 (file)
index 0000000..e5e635f
--- /dev/null
@@ -0,0 +1,104 @@
+! Copyright (C) 2009 Bruno Deferrari
+! See http://factorcode.org/license.txt for BSD license.
+USING: io io.crlf kernel math.parser sequences strings interpolate locals ;
+IN: redis.command-writer
+
+<PRIVATE
+
+GENERIC: write-value-with-length ( value -- )
+
+M: string write-value-with-length
+    [ length number>string write crlf ]
+    [ write ] bi ;
+
+: space ( -- ) CHAR: space write1 ;
+
+: write-key/value ( value key -- )
+    write space
+    write-value-with-length ;
+
+: write-key/integer ( integer key -- )
+    write space
+    number>string write ;
+
+PRIVATE>
+
+#! Connection
+: quit ( -- ) "QUIT" write crlf ;
+: ping ( -- ) "PING" write crlf ;
+: auth ( password -- ) "AUTH " write write crlf ;
+
+#! String values
+: set ( value key -- ) "SET " write write-key/value crlf ;
+: get ( key -- ) "GET " write write crlf ;
+: getset ( value key -- ) "GETSET " write write-key/value crlf ;
+: mget ( keys -- ) "MGET " write " " join write crlf ;
+: setnx ( value key -- ) "SETNX " write write-key/value crlf ;
+: incr ( key -- ) "INCR " write write crlf ;
+: incrby ( integer key -- ) "INCRBY " write write-key/integer crlf ;
+: decr ( key -- ) "DECR " write write crlf ;
+: decrby ( integer key -- ) "DECRBY " write write-key/integer crlf ;
+: exists ( key -- ) "EXISTS " write write crlf ;
+: del ( key -- ) "DEL " write write crlf ;
+: type ( key -- ) "TYPE " write write crlf ;
+
+#! Key space
+: keys ( pattern -- ) "KEYS " write write crlf ;
+: randomkey ( -- ) "RANDOMKEY" write crlf ;
+: rename ( newkey key -- ) "RENAME " write write space write crlf ;
+: renamenx ( newkey key -- ) "RENAMENX " write write space write crlf ;
+: dbsize ( -- ) "DBSIZE" write crlf ;
+: expire ( integer key -- ) "EXPIRE " write write-key/integer crlf ;
+
+#! Lists
+: rpush ( value key -- ) "RPUSH " write write-key/value crlf ;
+: lpush ( value key -- ) "LPUSH " write write-key/value crlf ;
+: llen ( key -- ) "LLEN " write write crlf ;
+: lrange ( start end key -- )
+    "LRANGE " write write [ space number>string write ] bi@ crlf ;
+: ltrim ( start end key -- )
+    "LTRIM " write write [ space number>string write ] bi@ crlf ;
+: lindex ( integer key -- ) "LINDEX " write write-key/integer crlf ;
+: lset ( value index key -- )
+    "LSET " write write-key/integer space write-value-with-length crlf ;
+: lrem ( value amount key -- )
+    "LREM " write write-key/integer space write-value-with-length crlf ;
+: lpop ( key -- ) "LPOP " write write crlf ;
+: rpop ( key -- ) "RPOP " write write crlf ;
+
+#! Sets
+: sadd ( member key -- )
+    "SADD " write write space write-value-with-length crlf ;
+: srem  ( member key -- )
+    "SREM " write write space write-value-with-length crlf ;
+: smove ( member newkey key -- )
+    "SMOVE " write write space write space write-value-with-length crlf ;
+: scard ( key -- ) "SCARD " write write crlf ;
+: sismember ( member key -- )
+    "SISMEMBER " write write space write-value-with-length crlf ;
+: sinter ( keys -- ) "SINTER " write " " join write crlf ;
+: sinterstore ( keys destkey -- )
+    "SINTERSTORE " write write space " " join write crlf ;
+: sunion ( keys -- ) "SUNION " write " " join write crlf ;
+: sunionstore ( keys destkey -- )
+    "SUNIONSTORE " write write " " join space write crlf ;
+: smembers ( key -- ) "SMEMBERS " write write crlf ;
+
+#! Multiple db
+: select ( integer -- ) "SELECT " write number>string write crlf ;
+: move ( integer key -- ) "MOVE " write write-key/integer crlf ;
+: flushdb ( -- ) "FLUSHDB" write crlf ;
+: flushall ( -- ) "FLUSHALL" write crlf ;
+
+#! Sorting
+! sort
+
+#! Persistence control
+: save ( -- ) "SAVE" write crlf ;
+: bgsave ( -- ) "BGSAVE" write crlf ;
+: lastsave ( -- ) "LASTSAVE" write crlf ;
+: shutdown ( -- ) "SHUTDOWN" write crlf ;
+
+#! Remote server control
+: info ( -- ) "INFO" write crlf ;
+: monitor ( -- ) "MONITOR" write crlf ;
diff --git a/extra/redis/command-writer/summary.txt b/extra/redis/command-writer/summary.txt
new file mode 100644 (file)
index 0000000..917b915
--- /dev/null
@@ -0,0 +1 @@
+Definitions of messages sent to Redis
diff --git a/extra/redis/redis.factor b/extra/redis/redis.factor
new file mode 100644 (file)
index 0000000..1f6d732
--- /dev/null
@@ -0,0 +1,74 @@
+! Copyright (C) 2009 Bruno Deferrari
+! See http://factorcode.org/license.txt for BSD license.
+USING: io redis.response-parser redis.command-writer ;
+IN: redis
+
+#! Connection
+: redis-quit ( -- ) quit flush ;
+: redis-ping ( -- response ) ping flush read-response ;
+: redis-auth ( password -- response ) auth flush read-response ;
+
+#! String values
+: redis-set ( value key -- response ) set flush read-response ;
+: redis-get ( key -- response ) get flush read-response ;
+: redis-getset ( value key -- response ) getset flush read-response ;
+: redis-mget ( keys -- response ) mget flush read-response ;
+: redis-setnx ( value key -- response ) setnx flush read-response ;
+: redis-incr ( key -- response ) incr flush read-response ;
+: redis-incrby ( integer key -- response ) incrby flush read-response ;
+: redis-decr ( key -- response ) decr flush read-response ;
+: redis-decrby ( integer key -- response ) decrby flush read-response ;
+: redis-exists ( key -- response ) exists flush read-response ;
+: redis-del ( key -- response ) del flush read-response ;
+: redis-type ( key -- response ) type flush read-response ;
+
+#! Key space
+: redis-keys ( pattern -- response ) keys flush read-response ;
+: redis-randomkey ( -- response ) randomkey flush read-response ;
+: redis-rename ( newkey key -- response ) rename flush read-response ;
+: redis-renamenx ( newkey key -- response ) renamenx flush read-response ;
+: redis-dbsize ( -- response ) dbsize flush read-response ;
+: redis-expire ( integer key -- response ) expire flush read-response ;
+
+#! Lists
+: redis-rpush ( value key -- response ) rpush flush read-response ;
+: redis-lpush ( value key -- response ) lpush flush read-response ;
+: redis-llen ( key -- response ) llen flush read-response ;
+: redis-lrange ( start end key -- response ) lrange flush read-response ;
+: redis-ltrim ( start end key -- response ) ltrim flush read-response ;
+: redis-lindex ( integer key -- response ) lindex flush read-response ;
+: redis-lset ( value index key -- response ) lset flush read-response ;
+: redis-lrem ( value amount key -- response ) lrem flush read-response ;
+: redis-lpop ( key -- response ) lpop flush read-response ;
+: redis-rpop ( key -- response ) rpop flush read-response ;
+
+#! Sets
+: redis-sadd ( member key -- response ) sadd flush read-response ;
+: redis-srem  ( member key -- response ) srem flush read-response ;
+: redis-smove ( member newkey key -- response ) smove flush read-response ;
+: redis-scard ( key -- response ) scard flush read-response ;
+: redis-sismember ( member key -- response ) sismember flush read-response ;
+: redis-sinter ( keys -- response ) sinter flush read-response ;
+: redis-sinterstore ( keys destkey -- response ) sinterstore flush read-response ;
+: redis-sunion ( keys -- response ) sunion flush read-response ;
+: redis-sunionstore ( keys destkey -- response ) sunionstore flush read-response ;
+: redis-smembers ( key -- response ) smembers flush read-response ;
+
+#! Multiple db
+: redis-select ( integer -- response ) select flush read-response ;
+: redis-move ( integer key -- response ) move flush read-response ;
+: redis-flushdb ( -- response ) flushdb flush read-response ;
+: redis-flushall ( -- response ) flushall flush read-response ;
+
+#! Sorting
+! sort
+
+#! Persistence control
+: redis-save ( -- response ) save flush read-response ;
+: redis-bgsave ( -- response ) bgsave flush read-response ;
+: redis-lastsave ( -- response ) lastsave flush read-response ;
+: redis-shutdown ( -- response ) shutdown flush read-response ;
+
+#! Remote server control
+: redis-info ( -- response ) info flush read-response ;
+: redis-monitor ( -- response ) monitor flush read-response ;
diff --git a/extra/redis/response-parser/authors.txt b/extra/redis/response-parser/authors.txt
new file mode 100644 (file)
index 0000000..f4a8cb1
--- /dev/null
@@ -0,0 +1 @@
+Bruno Deferrari
diff --git a/extra/redis/response-parser/response-parser-tests.factor b/extra/redis/response-parser/response-parser-tests.factor
new file mode 100644 (file)
index 0000000..bde3611
--- /dev/null
@@ -0,0 +1,20 @@
+! Copyright (C) 2009 Bruno Deferrari
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test redis.response-parser io.streams.string ;
+IN: redis.response-parser.tests
+
+[ 1 ] [ ":1\r\n" [ read-response ] with-string-reader ] unit-test
+
+[ "hello" ] [ "$5\r\nhello\r\n" [ read-response ] with-string-reader ] unit-test
+
+[ f ] [ "$-1\r\n" [ read-response ] with-string-reader ] unit-test
+
+[ { "hello" "world!" } ] [
+    "*2\r\n$5\r\nhello\r\n$6\r\nworld!\r\n" [ read-response ] with-string-reader
+] unit-test
+
+[ { "hello" f "world!" } ] [
+    "*3\r\n$5\r\nhello\r\n$-1\r\n$6\r\nworld!\r\n" [
+        read-response
+    ] with-string-reader
+] unit-test
diff --git a/extra/redis/response-parser/response-parser.factor b/extra/redis/response-parser/response-parser.factor
new file mode 100644 (file)
index 0000000..3d92d55
--- /dev/null
@@ -0,0 +1,27 @@
+! Copyright (C) 2009 Bruno Deferrari
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators io kernel math math.parser sequences ;
+IN: redis.response-parser
+
+<PRIVATE
+
+: read-bulk ( n -- bytes ) dup 0 < [ drop f ] [ read 2 read drop ] if ;
+: (read-multi-bulk) ( -- bytes ) readln rest string>number read-bulk ;
+: read-multi-bulk ( n -- seq/f )
+    dup 0 < [ drop f ] [
+        iota [ drop (read-multi-bulk) ] map
+    ] if ;
+
+: handle-response ( string -- string ) ; ! TODO
+: handle-error ( string -- string ) ; ! TODO
+
+PRIVATE>
+
+: read-response ( -- response )
+    readln unclip {
+        { CHAR: : [ string>number ] }
+        { CHAR: + [ handle-response ] }
+        { CHAR: $ [ string>number read-bulk ] }
+        { CHAR: * [ string>number read-multi-bulk ] }
+        { CHAR: - [ handle-error ] }
+    } case ;
diff --git a/extra/redis/response-parser/summary.txt b/extra/redis/response-parser/summary.txt
new file mode 100644 (file)
index 0000000..b89407c
--- /dev/null
@@ -0,0 +1 @@
+Parser for responses sent by the Redis server
diff --git a/extra/redis/summary.txt b/extra/redis/summary.txt
new file mode 100644 (file)
index 0000000..0cd6e69
--- /dev/null
@@ -0,0 +1 @@
+Words for communicating with the Redis key-value database
index 89e00f88c56670bb4dc05eeaf5b0f279cb9b96e4..f5c2ea9811b0b25eb4d00fba5e83e48bed9e14b0 100755 (executable)
@@ -19,13 +19,11 @@ IN: reports.noise
         { 2keep 1 }\r
         { 2nip 2 }\r
         { 2over 4 }\r
-        { 2slip 2 }\r
         { 2swap 3 }\r
         { 3curry 2 }\r
         { 3drop 1 }\r
         { 3dup 2 }\r
         { 3keep 3 }\r
-        { 3slip 3 }\r
         { 4drop 2 }\r
         { 4dup 3 }\r
         { compose 1/2 }\r
@@ -52,14 +50,12 @@ IN: reports.noise
         { nkeep 5 }\r
         { npick 6 }\r
         { nrot 5 }\r
-        { nslip 5 }\r
         { ntuck 6 }\r
         { nwith 4 }\r
         { over 2 }\r
         { pick 4 }\r
         { roll 4 }\r
         { rot 3 }\r
-        { slip 1 }\r
         { spin 3 }\r
         { swap 1 }\r
         { swapd 3 }\r
index d6591a1a26781ae73d3844d6668278e8e9b98894..df314317cf9744e1c56d111c4533ec3e0b512933 100644 (file)
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
+    { deploy-ui? t }
     { deploy-reflection 1 }
-    { deploy-word-defs? f }
-    { deploy-word-props? f }
-    { deploy-name "Spheres" }
-    { deploy-compiler? t }
+    { deploy-unicode? f }
     { deploy-math? t }
-    { deploy-io 1 }
-    { deploy-threads? t }
-    { "stop-after-last-window?" t }
-    { deploy-ui? t }
+    { deploy-io 2 }
     { deploy-c-types? f }
+    { deploy-name "Spheres" }
+    { deploy-word-props? f }
+    { deploy-word-defs? f }
+    { "stop-after-last-window?" t }
+    { deploy-threads? t }
 }
index b26797f8d51dabb58f20d401edf39b1d5b327439..b4bbc9fbf8a5f5566f30189420940803bd0220ba 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs deques dlists kernel spider ;
+USING: accessors assocs deques dlists kernel ;
 IN: spider.unique-deque
 
 TUPLE: todo-url url depth ;
@@ -32,6 +32,6 @@ TUPLE: unique-deque assoc deque ;
 
 : slurp-deque-when ( deque quot1 quot2: ( value -- ) -- )
     pick deque-empty? [ 3drop ] [
-        [ [ pop-front dup ] 2dip slip [ t ] compose [ drop f ] if ]
+        [ [ pop-front dup ] 2dip [ call ] dip [ t ] compose [ drop f ] if ]
         [ roll [ slurp-deque-when ] [ 3drop ] if ] 3bi
     ] if ; inline recursive
index 92c4395decf31bcb76d1b4885517628355ac5674..c873600134f0663973fc60e3f65be4092b160f32 100755 (executable)
@@ -3,7 +3,6 @@ H{
     { deploy-word-defs? f }
     { deploy-name "Sudoku" }
     { deploy-threads? f }
-    { deploy-compiler? t }
     { deploy-math? t }
     { deploy-c-types? f }
     { deploy-io 2 }
index e28187125231155aefe93ff6f5fa1dab95207f85..93554c146ac1f586e515fd1ff9697231df909096 100755 (executable)
@@ -18,7 +18,7 @@ ERROR: checksum-error header ;
 : trim-string ( seq -- newseq ) [ "\0 " member? ] trim ;
 
 : read-c-string ( n -- str/f )
-    read [ zero? ] trim-tail [ f ] when-empty ;
+    read [ zero? ] trim-tail [ f ] when-empty >string ;
 
 : read-tar-header ( -- obj )
     \ tar-header new
diff --git a/extra/terrain/deploy.factor b/extra/terrain/deploy.factor
new file mode 100644 (file)
index 0000000..b51873a
--- /dev/null
@@ -0,0 +1,14 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-ui? t }
+    { deploy-reflection 1 }
+    { deploy-unicode? f }
+    { deploy-math? t }
+    { deploy-io 2 }
+    { deploy-c-types? f }
+    { deploy-name "Terrain" }
+    { deploy-word-props? f }
+    { deploy-word-defs? f }
+    { "stop-after-last-window?" t }
+    { deploy-threads? t }
+}
diff --git a/extra/terrain/generation/generation.factor b/extra/terrain/generation/generation.factor
new file mode 100644 (file)
index 0000000..18f73e8
--- /dev/null
@@ -0,0 +1,60 @@
+USING: accessors arrays byte-arrays combinators fry grouping
+images kernel math math.affine-transforms math.order
+math.vectors noise random sequences ;
+IN: terrain.generation
+
+CONSTANT: terrain-segment-size { 512 512 }
+CONSTANT: terrain-big-noise-scale { 0.002 0.002 }
+CONSTANT: terrain-small-noise-scale { 0.05 0.05 }
+
+TUPLE: terrain big-noise-table small-noise-table tiny-noise-seed ; 
+
+: <terrain> ( -- terrain )
+    <perlin-noise-table> <perlin-noise-table>
+    32 random-bits terrain boa ;
+
+: seed-at ( seed at -- seed' )
+    first2 [ + ] dip [ 32 random-bits + ] curry with-seed ;
+
+: big-noise-segment ( terrain at -- map )
+    [ big-noise-table>> terrain-big-noise-scale first2 <scale> ] dip
+    terrain-segment-size [ v* <translation> a. ] keep perlin-noise-byte-map ;
+: small-noise-segment ( terrain at -- map )
+    [ small-noise-table>> terrain-small-noise-scale first2 <scale> ] dip
+    terrain-segment-size [ v* <translation> a. ] keep perlin-noise-byte-map ;
+: tiny-noise-segment ( terrain at -- map )
+    [ tiny-noise-seed>> ] dip seed-at 0.1
+    terrain-segment-size normal-noise-byte-map ;
+
+: padding ( terrain at -- padding )
+    2drop terrain-segment-size product 255 <repetition> ;
+
+TUPLE: segment image ;
+
+: terrain-segment ( terrain at -- image )
+    {
+        [ big-noise-segment ]
+        [ small-noise-segment ]
+        [ tiny-noise-segment ]
+        [ padding ]
+    } 2cleave
+    4array flip concat >byte-array
+    [ terrain-segment-size RGBA f ] dip image boa ;
+
+: 4max ( a b c d -- max )
+    max max max ; inline
+
+: mipmap ( {{pixels}} quot: ( aa ab ba bb -- c ) -- pixels' )
+    [ [ 2 <groups> ] map 2 <groups> ] dip
+    '[ first2 [ [ first2 ] bi@ @ ] 2map ] map ; inline
+
+: group-pixels ( bitmap dim -- scanlines )
+    [ 4 <groups> ] [ first <groups> ] bi* ;
+
+: concat-pixels ( scanlines -- bitmap )
+    [ concat ] map concat ;
+
+: segment-mipmap ( image -- image' )
+    [ clone ] [ bitmap>> ] [ dim>> ] tri
+    group-pixels [ 4max ] mipmap concat-pixels >>bitmap
+    [ 2 v/n ] change-dim ;
diff --git a/extra/terrain/shaders/shaders.factor b/extra/terrain/shaders/shaders.factor
new file mode 100644 (file)
index 0000000..e5b517a
--- /dev/null
@@ -0,0 +1,81 @@
+USING: multiline ;
+IN: terrain.shaders
+
+STRING: sky-vertex-shader
+
+uniform float sky_theta;
+varying vec3 direction;
+
+void main()
+{
+    vec4 v = vec4(gl_Vertex.xy, 1.0, 1.0);
+    gl_Position = v;
+
+    vec4 p = (gl_ProjectionMatrixInverse * v) * vec4(1,1,-1,1);
+    
+    float s = sin(sky_theta), c = cos(sky_theta);
+    direction = mat3(1, 0, 0,  0, c, s,  0, -s, c)
+        * (gl_ModelViewMatrixInverse * vec4(p.xyz, 0.0)).xyz;
+}
+
+;
+
+STRING: sky-pixel-shader
+
+uniform sampler2D sky;
+uniform float sky_gradient, sky_theta;
+
+const vec4 SKY_COLOR_A = vec4(0.25, 0.0, 0.5,  1.0),
+           SKY_COLOR_B = vec4(0.6,  0.5, 0.75, 1.0);
+
+varying vec3 direction;
+
+void main()
+{
+    float t = texture2D(sky, normalize(direction.xyz).xy * 0.5 + vec2(0.5)).x + sky_gradient;
+    gl_FragColor = mix(SKY_COLOR_A, SKY_COLOR_B, sin(6.28*t));
+}
+
+;
+
+STRING: terrain-vertex-shader
+
+uniform sampler2D heightmap;
+uniform vec4 component_scale;
+
+varying vec2 heightcoords;
+
+float height(sampler2D map, vec2 coords)
+{
+    vec4 v = texture2D(map, coords);
+    return dot(v, component_scale);
+}
+
+void main()
+{
+    gl_Position = gl_ModelViewProjectionMatrix
+        * (gl_Vertex + vec4(0, height(heightmap, gl_Vertex.xz), 0, 0));
+    heightcoords = gl_Vertex.xz;
+}
+
+;
+
+STRING: terrain-pixel-shader
+
+uniform sampler2D heightmap;
+uniform vec4 component_scale;
+
+varying vec2 heightcoords;
+
+float height(sampler2D map, vec2 coords)
+{
+    vec4 v = texture2D(map, coords);
+    return dot(v, component_scale);
+}
+
+void main()
+{
+    gl_FragColor = texture2D(heightmap, heightcoords);
+}
+
+;
diff --git a/extra/terrain/terrain.factor b/extra/terrain/terrain.factor
new file mode 100644 (file)
index 0000000..411d34f
--- /dev/null
@@ -0,0 +1,263 @@
+USING: accessors arrays combinators game-input game-loop
+game-input.scancodes grouping kernel literals locals
+math math.constants math.functions math.matrices math.order
+math.vectors opengl opengl.capabilities opengl.gl
+opengl.shaders opengl.textures opengl.textures.private
+sequences sequences.product specialized-arrays.float
+terrain.generation terrain.shaders ui ui.gadgets
+ui.gadgets.worlds ui.pixel-formats game-worlds method-chains
+math.affine-transforms noise ;
+IN: terrain
+
+CONSTANT: FOV $[ 2.0 sqrt 1+ ]
+CONSTANT: NEAR-PLANE $[ 1.0 1024.0 / ]
+CONSTANT: FAR-PLANE 2.0
+CONSTANT: PLAYER-START-LOCATION { 0.5 0.51 0.5 }
+CONSTANT: PLAYER-HEIGHT $[ 1.0 256.0 / ]
+CONSTANT: GRAVITY $[ 1.0 4096.0 / ]
+CONSTANT: JUMP $[ 1.0 1024.0 / ]
+CONSTANT: MOUSE-SCALE $[ 1.0 10.0 / ]
+CONSTANT: MOVEMENT-SPEED $[ 1.0 16384.0 / ]
+CONSTANT: FRICTION 0.95
+CONSTANT: COMPONENT-SCALE { 0.5 0.01 0.0005 0.0 }
+CONSTANT: SKY-PERIOD 1200
+CONSTANT: SKY-SPEED 0.0005
+
+CONSTANT: terrain-vertex-size { 512 512 }
+CONSTANT: terrain-vertex-distance { $[ 1.0 512.0 / ] $[ 1.0 512.0 / ] }
+CONSTANT: terrain-vertex-row-length $[ 512 1 + 2 * ]
+
+TUPLE: player
+    location yaw pitch velocity ;
+
+TUPLE: terrain-world < game-world
+    player
+    sky-image sky-texture sky-program
+    terrain terrain-segment terrain-texture terrain-program
+    terrain-vertex-buffer ;
+
+M: terrain-world tick-length
+    drop 1000 30 /i ;
+
+: frustum ( dim -- -x x -y y near far )
+    dup first2 min v/n
+    NEAR-PLANE FOV / v*n first2 [ [ neg ] keep ] bi@
+    NEAR-PLANE FAR-PLANE ;
+
+: set-modelview-matrix ( gadget -- )
+    GL_DEPTH_BUFFER_BIT glClear
+    GL_MODELVIEW glMatrixMode
+    glLoadIdentity
+    player>>
+    [ pitch>> 1.0 0.0 0.0 glRotatef ]
+    [ yaw>> 0.0 1.0 0.0 glRotatef ]
+    [ location>> vneg first3 glTranslatef ] tri ;
+
+: vertex-array-vertex ( x z -- vertex )
+    [ terrain-vertex-distance first * ]
+    [ terrain-vertex-distance second * ] bi*
+    [ 0 ] dip float-array{ } 3sequence ;
+
+: vertex-array-row ( z -- vertices )
+    dup 1 + 2array
+    terrain-vertex-size first 1 + iota
+    2array [ first2 swap vertex-array-vertex ] product-map
+    concat ;
+
+: vertex-array ( -- vertices )
+    terrain-vertex-size second iota
+    [ vertex-array-row ] map concat ;
+
+: >vertex-buffer ( bytes -- buffer )
+    [ GL_ARRAY_BUFFER ] dip GL_STATIC_DRAW <gl-buffer> ;
+
+: draw-vertex-buffer-row ( i -- )
+    [ GL_TRIANGLE_STRIP ] dip
+    terrain-vertex-row-length * terrain-vertex-row-length
+    glDrawArrays ;
+
+: draw-vertex-buffer ( buffer -- )
+    [ GL_ARRAY_BUFFER ] dip [
+        3 GL_FLOAT 0 f glVertexPointer
+        terrain-vertex-size second iota [ draw-vertex-buffer-row ] each
+    ] with-gl-buffer ;
+
+: degrees ( deg -- rad )
+    pi 180.0 / * ;
+
+:: eye-rotate ( yaw pitch v -- v' )
+    yaw degrees neg :> y
+    pitch degrees neg :> p
+    y cos :> cosy
+    y sin :> siny
+    p cos :> cosp
+    p sin :> sinp
+
+    cosy         0.0       siny        neg  3array
+    siny sinp *  cosp      cosy sinp *      3array
+    siny cosp *  sinp neg  cosy cosp *      3array 3array
+    v swap v.m ;
+
+: forward-vector ( player -- v )
+    yaw>> 0.0
+    { 0.0 0.0 $ MOVEMENT-SPEED } vneg eye-rotate ;
+: rightward-vector ( player -- v )
+    yaw>> 0.0
+    { $ MOVEMENT-SPEED 0.0 0.0 } eye-rotate ;
+
+: walk-forward ( player -- )
+    dup forward-vector [ v+ ] curry change-velocity drop ;
+: walk-backward ( player -- )
+    dup forward-vector [ v- ] curry change-velocity drop ;
+: walk-leftward ( player -- )
+    dup rightward-vector [ v- ] curry change-velocity drop ;
+: walk-rightward ( player -- )
+    dup rightward-vector [ v+ ] curry change-velocity drop ;
+: jump ( player -- )
+    [ { 0.0 $ JUMP 0.0 } v+ ] change-velocity drop ;
+
+: clamp-pitch ( pitch -- pitch' )
+    90.0 min -90.0 max ;
+
+: rotate-with-mouse ( player mouse -- )
+    [ dx>> MOUSE-SCALE * [ + ] curry change-yaw ]
+    [ dy>> MOUSE-SCALE * [ + clamp-pitch ] curry change-pitch ] bi
+    drop ;
+
+:: handle-input ( world -- )
+    world player>> :> player
+    read-keyboard keys>> :> keys
+    key-w keys nth [ player walk-forward ] when 
+    key-s keys nth [ player walk-backward ] when 
+    key-a keys nth [ player walk-leftward ] when 
+    key-d keys nth [ player walk-rightward ] when 
+    key-space keys nth [ player jump ] when 
+    key-escape keys nth [ world close-window ] when
+    player read-mouse rotate-with-mouse
+    reset-mouse ;
+
+: apply-friction ( velocity -- velocity' )
+    FRICTION v*n ;
+
+: apply-gravity ( velocity -- velocity' )
+    1 over [ GRAVITY - ] change-nth ;
+
+: clamp-coords ( coords dim -- coords' )
+    [ { 0 0 } vmax ] dip { 2 2 } v- vmin ;
+
+:: pixel-indices ( coords dim -- indices )
+    coords vfloor [ >integer ] map dim clamp-coords :> floor-coords
+    floor-coords first2 dim first * + :> base-index
+    base-index dim first + :> next-row-index
+
+    base-index
+    base-index 1 +
+    next-row-index
+    next-row-index 1 + 4array ;
+
+:: terrain-height-at ( segment point -- height )
+    segment dim>> :> dim
+    dim point v* :> pixel
+    pixel dup vfloor v- :> pixel-mantissa
+    segment bitmap>> 4 <groups> :> pixels
+    pixel dim pixel-indices :> indices
+    
+    indices [ pixels nth COMPONENT-SCALE v. 255.0 / ] map
+    first4 pixel-mantissa bilerp ;
+
+: collide ( segment location -- location' )
+    [ [ first ] [ third ] bi 2array terrain-height-at PLAYER-HEIGHT + ]
+    [ [ 1 ] 2dip [ max ] with change-nth ]
+    [ ] tri ;
+
+: tick-player ( world player -- )
+    [ apply-friction apply-gravity ] change-velocity
+    dup velocity>> [ v+ [ terrain-segment>> ] dip collide ] curry with change-location
+    drop ;
+
+M: terrain-world tick*
+    [ dup focused?>> [ handle-input ] [ drop ] if ]
+    [ dup player>> tick-player ] bi ;
+
+: set-texture-parameters ( texture -- )
+    GL_TEXTURE_2D GL_TEXTURE0 bind-texture-unit
+    GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR glTexParameteri
+    GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR glTexParameteri
+    GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_CLAMP_TO_EDGE glTexParameteri
+    GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_CLAMP_TO_EDGE glTexParameteri ;
+
+: sky-gradient ( world -- t )
+    game-loop>> tick-number>> SKY-PERIOD mod SKY-PERIOD /f ;
+: sky-theta ( world -- theta )
+    game-loop>> tick-number>> SKY-SPEED * ;
+
+BEFORE: terrain-world begin-world
+    "2.0" { "GL_ARB_vertex_buffer_object" "GL_ARB_shader_objects" }
+    require-gl-version-or-extensions
+    GL_DEPTH_TEST glEnable
+    GL_TEXTURE_2D glEnable
+    GL_VERTEX_ARRAY glEnableClientState
+    PLAYER-START-LOCATION 0.0 0.0 { 0.0 0.0 0.0 } player boa >>player
+    <perlin-noise-table> 0.01 0.01 <scale> { 512 512 } perlin-noise-image
+    [ >>sky-image ] keep
+    make-texture [ set-texture-parameters ] keep >>sky-texture
+    <terrain> [ >>terrain ] keep
+    { 0 0 } terrain-segment [ >>terrain-segment ] keep
+    make-texture [ set-texture-parameters ] keep >>terrain-texture
+    sky-vertex-shader sky-pixel-shader <simple-gl-program>
+    >>sky-program
+    terrain-vertex-shader terrain-pixel-shader <simple-gl-program>
+    >>terrain-program
+    vertex-array >vertex-buffer >>terrain-vertex-buffer
+    drop ;
+
+AFTER: terrain-world end-world
+    {
+        [ terrain-vertex-buffer>> delete-gl-buffer ]
+        [ terrain-program>> delete-gl-program ]
+        [ terrain-texture>> delete-texture ]
+        [ sky-program>> delete-gl-program ]
+        [ sky-texture>> delete-texture ]
+    } cleave ;
+
+M: terrain-world resize-world
+    GL_PROJECTION glMatrixMode
+    glLoadIdentity
+    dim>> [ [ 0 0 ] dip first2 glViewport ]
+    [ frustum glFrustum ] bi ;
+
+M: terrain-world draw-world*
+    {
+        [ set-modelview-matrix ]
+        [ terrain-texture>> GL_TEXTURE_2D GL_TEXTURE0 bind-texture-unit ]
+        [ sky-texture>> GL_TEXTURE_2D GL_TEXTURE1 bind-texture-unit ]
+        [ GL_DEPTH_TEST glDisable dup sky-program>> [
+            [ nip "sky" glGetUniformLocation 1 glUniform1i ]
+            [ "sky_gradient" glGetUniformLocation swap sky-gradient glUniform1f ]
+            [ "sky_theta" glGetUniformLocation swap sky-theta glUniform1f ] 2tri
+            { -1.0 -1.0 } { 2.0 2.0 } gl-fill-rect
+        ] with-gl-program ]
+        [ GL_DEPTH_TEST glEnable dup terrain-program>> [
+            [ "heightmap" glGetUniformLocation 0 glUniform1i ]
+            [ "component_scale" glGetUniformLocation COMPONENT-SCALE first4 glUniform4f ] bi
+            terrain-vertex-buffer>> draw-vertex-buffer
+        ] with-gl-program ]
+    } cleave gl-error ;
+
+M: terrain-world pref-dim* drop { 640 480 } ;
+
+: terrain-window ( -- )
+    [
+        f T{ world-attributes
+            { world-class terrain-world }
+            { title "Terrain" }
+            { pixel-format-attributes {
+                windowed
+                double-buffered
+                T{ depth-bits { value 24 } }
+            } }
+            { grab-input? t }
+        } open-window
+    ] with-ui ;
+
+MAIN: terrain-window
index 03ec5d4e6405b7f975e47fa5ce3792a2be12e93e..a2d71ab08bf9302c2fa463557157a584765b310e 100755 (executable)
@@ -1,7 +1,6 @@
 USING: tools.deploy.config ;
 H{
     { deploy-ui? t }
-    { deploy-compiler? t }
     { deploy-threads? t }
     { deploy-word-props? f }
     { deploy-reflection 1 }
index bc429a0af6d8a8f4b5bdefca0b9cd38b975b0060..8e200a44527bf0b2873c74717b4a2de5a3cd7b15 100644 (file)
@@ -26,6 +26,9 @@ short-url "SHORT_URLS" {
 : random-url ( -- string )
     1 6 [a,b] random [ letter-bank random ] "" replicate-as ;
 
+: retry ( quot: ( -- ? )  n -- )
+    swap [ drop ] prepose attempt-all ; inline
+
 : insert-short-url ( short-url -- short-url )
     '[ _ dup random-url >>short insert-tuple ] 10 retry ;
 
index 322212c4fc7170edf9036ae8860f75d6d82d5dfa..fb320446649769ce001a068ec8368ab693d74df3 100644 (file)
@@ -4,7 +4,6 @@ H{
     { deploy-threads? f }
     { deploy-word-defs? f }
     { deploy-ui? f }
-    { deploy-compiler? t }
     { deploy-word-props? f }
     { "stop-after-last-window?" t }
     { deploy-unicode? f }
diff --git a/unmaintained/modules/remote-loading/authors.txt b/unmaintained/modules/remote-loading/authors.txt
new file mode 100644 (file)
index 0000000..2300f69
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
diff --git a/unmaintained/modules/remote-loading/remote-loading.factor b/unmaintained/modules/remote-loading/remote-loading.factor
new file mode 100644 (file)
index 0000000..7a51f24
--- /dev/null
@@ -0,0 +1,4 @@
+USING: modules.rpc-server vocabs ;
+IN: modules.remote-loading mem-service
+
+: get-vocab ( vocabstr -- vocab ) vocab ;
\ No newline at end of file
diff --git a/unmaintained/modules/remote-loading/summary.txt b/unmaintained/modules/remote-loading/summary.txt
new file mode 100644 (file)
index 0000000..304f855
--- /dev/null
@@ -0,0 +1 @@
+required for listeners allowing remote loading of modules
\ No newline at end of file
diff --git a/unmaintained/modules/rpc-server/authors.txt b/unmaintained/modules/rpc-server/authors.txt
new file mode 100644 (file)
index 0000000..2300f69
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
diff --git a/unmaintained/modules/rpc-server/rpc-server.factor b/unmaintained/modules/rpc-server/rpc-server.factor
new file mode 100644 (file)
index 0000000..525ff35
--- /dev/null
@@ -0,0 +1,37 @@
+USING: accessors assocs continuations effects io
+io.encodings.binary io.servers.connection kernel
+memoize namespaces parser sets sequences serialize
+threads vocabs vocabs.parser words ;
+
+IN: modules.rpc-server
+
+SYMBOL: serving-vocabs V{ } clone serving-vocabs set-global
+
+: do-rpc ( args word -- bytes )
+   [ execute ] curry with-datastack object>bytes ; inline
+
+MEMO: mem-do-rpc ( args word -- bytes ) do-rpc ; inline
+
+: process ( vocabspec -- ) vocab-words [ deserialize ] dip deserialize
+   swap at "executer" get execute( args word -- bytes ) write flush ;
+
+: (serve) ( -- ) deserialize dup serving-vocabs get-global index
+   [ process ] [ drop ] if ;
+
+: start-serving-vocabs ( -- ) [
+   <threaded-server> 5000 >>insecure binary >>encoding [ (serve) ] >>handler
+   start-server ] in-thread ;
+
+: (service) ( -- ) serving-vocabs get-global empty? [ start-serving-vocabs ] when
+   current-vocab serving-vocabs get-global adjoin
+   "get-words" create-in
+   in get [ vocab vocab-words [ stack-effect ] { } assoc-map-as ] curry
+   (( -- words )) define-inline ;
+
+SYNTAX: service \ do-rpc  "executer" set (service) ;
+SYNTAX: mem-service \ mem-do-rpc "executer" set (service) ;
+
+load-vocab-hook [
+   [ dup words>> values
+   \ mem-do-rpc "memoize" word-prop [ delete-at ] curry each ]
+append ] change-global
\ No newline at end of file
diff --git a/unmaintained/modules/rpc-server/summary.txt b/unmaintained/modules/rpc-server/summary.txt
new file mode 100644 (file)
index 0000000..396a1c8
--- /dev/null
@@ -0,0 +1 @@
+remote procedure call server
\ No newline at end of file
diff --git a/unmaintained/modules/rpc/authors.txt b/unmaintained/modules/rpc/authors.txt
new file mode 100644 (file)
index 0000000..2300f69
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
diff --git a/unmaintained/modules/rpc/rpc-docs.factor b/unmaintained/modules/rpc/rpc-docs.factor
new file mode 100644 (file)
index 0000000..af99d21
--- /dev/null
@@ -0,0 +1,9 @@
+USING: help.syntax help.markup ;
+IN: modules.rpc
+ARTICLE: { "modules" "protocol" } "RPC Protocol"
+{ $list
+   "Send vocab as string"
+   "Send arglist"
+   "Send word as string"
+   "Receive result list"
+} ;
\ No newline at end of file
diff --git a/unmaintained/modules/rpc/rpc.factor b/unmaintained/modules/rpc/rpc.factor
new file mode 100644 (file)
index 0000000..1c1217a
--- /dev/null
@@ -0,0 +1,26 @@
+USING: accessors compiler.units combinators fry generalizations io
+io.encodings.binary io.sockets kernel namespaces
+parser sequences serialize vocabs vocabs.parser words ;
+IN: modules.rpc
+
+DEFER: get-words
+
+: remote-quot ( addrspec vocabspec effect str -- quot )
+   '[ _ 5000 <inet> binary
+      [
+         _ serialize _ in>> length narray serialize _ serialize flush deserialize dup length firstn
+      ] with-client
+    ] ;
+
+: define-remote ( addrspec vocabspec effect str -- ) [
+      [ remote-quot ] 2keep create-in -rot define-declared word make-inline
+   ] with-compilation-unit ;
+
+: with-in ( vocab quot -- vocab ) over
+   [ '[ _ set-in @ ] in get swap dip set-in ] dip vocab ; inline
+
+: remote-vocab ( addrspec vocabspec -- vocab )
+   dup "-remote" append [ 
+      [ (( -- words )) [ "get-words" remote-quot ] keep call-effect ] 2keep
+      [ rot first2 swap define-remote ] 2curry each
+   ] with-in ;
\ No newline at end of file
diff --git a/unmaintained/modules/rpc/summary.txt b/unmaintained/modules/rpc/summary.txt
new file mode 100644 (file)
index 0000000..cc1501f
--- /dev/null
@@ -0,0 +1 @@
+remote procedure call client
\ No newline at end of file
diff --git a/unmaintained/modules/uploads/authors.txt b/unmaintained/modules/uploads/authors.txt
new file mode 100644 (file)
index 0000000..2300f69
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
diff --git a/unmaintained/modules/uploads/summary.txt b/unmaintained/modules/uploads/summary.txt
new file mode 100644 (file)
index 0000000..1ba8ffe
--- /dev/null
@@ -0,0 +1 @@
+module pushing in remote-loading listeners
\ No newline at end of file
diff --git a/unmaintained/modules/uploads/uploads.factor b/unmaintained/modules/uploads/uploads.factor
new file mode 100644 (file)
index 0000000..137a2c9
--- /dev/null
@@ -0,0 +1,5 @@
+USING: assocs modules.rpc-server vocabs
+modules.remote-loading words ;
+IN: modules.uploads service
+
+: upload-vocab ( word binary -- ) \ get-vocab "memoize" word-prop set-at ;
\ No newline at end of file
diff --git a/unmaintained/modules/using/authors.txt b/unmaintained/modules/using/authors.txt
new file mode 100644 (file)
index 0000000..2300f69
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
diff --git a/unmaintained/modules/using/summary.txt b/unmaintained/modules/using/summary.txt
new file mode 100644 (file)
index 0000000..6bafda7
--- /dev/null
@@ -0,0 +1 @@
+improved module import syntax
\ No newline at end of file
diff --git a/unmaintained/modules/using/tests/tags.txt b/unmaintained/modules/using/tests/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/unmaintained/modules/using/tests/test-server.factor b/unmaintained/modules/using/tests/test-server.factor
new file mode 100644 (file)
index 0000000..3e6b736
--- /dev/null
@@ -0,0 +1,3 @@
+USING: modules.rpc-server io.servers.connection ;
+IN: modules.test-server service
+: rpc-hello ( -- str ) "hello world" stop-this-server ;
\ No newline at end of file
diff --git a/unmaintained/modules/using/tests/tests.factor b/unmaintained/modules/using/tests/tests.factor
new file mode 100644 (file)
index 0000000..894075a
--- /dev/null
@@ -0,0 +1,4 @@
+USING: modules.using ;
+IN: modules.using.tests
+USING: tools.test localhost::modules.test-server ;
+[ "hello world" ] [ rpc-hello ] unit-test
\ No newline at end of file
diff --git a/unmaintained/modules/using/using-docs.factor b/unmaintained/modules/using/using-docs.factor
new file mode 100644 (file)
index 0000000..c78e546
--- /dev/null
@@ -0,0 +1,14 @@
+USING: modules.using modules.rpc-server help.syntax help.markup strings ;
+IN: modules
+
+HELP: service
+{ $syntax "IN: module service" }
+{ $description "Starts a server for requests for remote procedure calls." } ;
+
+ARTICLE: { "modules" "remote-loading" } "Using the remote-loading vocabulary"
+"If loaded, starts serving vocabularies, accessable through a " { $link POSTPONE: USING: } " form" ;
+
+HELP: USING:
+{ $syntax "USING: rpc-server::module fetch-sever::module { module qualified-name } { module => word ... } ... ;" }
+{ $description "Adds vocabularies to the front of the search path.  Vocabularies can be fetched remotely, if preceded by a valid hostname.  Name pairs facilitate imports like in the "
+{ $link POSTPONE: QUALIFIED: } " or " { $link POSTPONE: FROM: } " forms." } ;
\ No newline at end of file
diff --git a/unmaintained/modules/using/using.factor b/unmaintained/modules/using/using.factor
new file mode 100644 (file)
index 0000000..b0891aa
--- /dev/null
@@ -0,0 +1,36 @@
+USING: assocs kernel modules.remote-loading modules.rpc
+namespaces peg peg.ebnf peg-lexer sequences vocabs vocabs.parser
+strings ;
+IN: modules.using
+
+: >qualified ( vocab prefix -- assoc )
+    [ vocab-words ] [ 58 suffix ] bi* [ swap [ prepend ] dip ] curry assoc-map ;
+
+: >partial-vocab ( words assoc -- assoc )
+    [ dupd at [ no-word-error ] unless* ] curry { } map>assoc ;
+
+: remote-load ( addr vocabspec -- voab ) [ "modules.remote-loading" remote-vocab (use+) ] dip get-vocab ;
+
+: load'em ( vocab words/? -- ) [ swap >partial-vocab ] when* use get push ;
+
+EBNF: modulize
+tokenpart = (!(':').)+ => [[ >string ]]
+s = ':' => [[ drop ignore ]]
+rpc = tokenpart s s tokenpart => [[ first2 remote-vocab ]]
+remote = tokenpart s tokenpart => [[ first2 remote-load ]]
+plain = tokenpart => [[ load-vocab ]]
+module = rpc | remote | plain
+;EBNF
+
+ON-BNF: USING:
+tokenizer = <foreign factor>
+sym = !(";"|"}"|"=>").
+modspec = sym => [[ modulize ]]
+qualified = modspec sym => [[ first2 >qualified ]]
+unqualified = modspec => [[ vocab-words ]]
+words = ("=>" sym+ )? => [[ [ f ] [ second ] if-empty ]]
+long = "{" ( qualified | unqualified ) words "}" => [[ rest first2 load'em ignore ]]
+short = modspec => [[ use+ ignore ]]
+wordSpec = long | short
+using = wordSpec+ ";" => [[ drop ignore ]]
+;ON-BNF
\ No newline at end of file
index cdb72f4e2403a1f233f0056f009bc5c169fb9eac..b0b1352cb244f96949d6420af3cfd597a62d3758 100644 (file)
@@ -6,5 +6,5 @@ EXE_EXTENSION=.exe
 CONSOLE_EXTENSION=.com
 DLL_EXTENSION=.dll
 SHARED_DLL_EXTENSION=.dll
-LINKER = $(CC) -shared -mno-cygwin -o 
+LINKER = $(CPP) -shared -mno-cygwin -o 
 LINK_WITH_ENGINE = -l$(DLL_PREFIX)factor$(DLL_SUFFIX)
index 06dee31a14a2f1b3e796c1ece228f9c8753e7c43..49afd608eca2253a7808054a405e88a52ae5d00e 100755 (executable)
@@ -77,7 +77,7 @@ PRIMITIVE(alien_address)
 }
 
 /* pop ( alien n ) from datastack, return alien's address plus n */
-static void *alien_pointer(void)
+static void *alien_pointer()
 {
        fixnum offset = to_fixnum(dpop());
        return unbox_alien() + offset;
@@ -128,7 +128,7 @@ PRIMITIVE(dlsym)
        gc_root<byte_array> name(dpop());
        name.untag_check();
 
-       vm_char *sym = (vm_char *)(name.untagged() + 1);
+       symbol_char *sym = name->data<symbol_char>();
 
        if(library.value() == F)
                box_alien(ffi_dlsym(NULL,sym));
@@ -182,7 +182,7 @@ VM_C_API char *alien_offset(cell obj)
 }
 
 /* pop an object representing a C pointer */
-VM_C_API char *unbox_alien(void)
+VM_C_API char *unbox_alien()
 {
        return alien_offset(dpop());
 }
index a66135cf92c556725527fe7ee8860d81f4d0c362..6235a2d6c73ffe23e89700c5e14be52db53ee0b4 100755 (executable)
@@ -39,7 +39,7 @@ PRIMITIVE(dlclose);
 PRIMITIVE(dll_validp);
 
 VM_C_API char *alien_offset(cell object);
-VM_C_API char *unbox_alien(void);
+VM_C_API char *unbox_alien();
 VM_C_API void box_alien(void *ptr);
 VM_C_API void to_value_struct(cell src, void *dest, cell size);
 VM_C_API void box_value_struct(void *src, cell size);
index 56056426ddbfc40f27f7e546aaec2b738f5d33ae..e7009183e91504fa981eba82137a4c711fed6e4a 100755 (executable)
@@ -24,10 +24,7 @@ void iterate_callstack(cell top, cell bottom, CALLSTACK_ITER iterator)
 
 void iterate_callstack_object(callstack *stack, CALLSTACK_ITER iterator)
 {
-       cell top = (cell)FIRST_STACK_FRAME(stack);
-       cell bottom = top + untag_fixnum(stack->length);
-
-       iterate_callstack(top,bottom,iterator);
+       iterate_callstack((cell)stack->top(),(cell)stack->bottom(),iterator);
 }
 
 callstack *allot_callstack(cell size)
@@ -54,7 +51,7 @@ This means that if 'callstack' is called in tail position, we
 will have popped a necessary frame... however this word is only
 called by continuation implementation, and user code shouldn't
 be calling it at all, so we leave it as it is for now. */
-stack_frame *capture_start(void)
+stack_frame *capture_start()
 {
        stack_frame *frame = stack_chain->callstack_bottom - 1;
        while(frame >= stack_chain->callstack_top
@@ -75,7 +72,7 @@ PRIMITIVE(callstack)
                size = 0;
 
        callstack *stack = allot_callstack(size);
-       memcpy(FIRST_STACK_FRAME(stack),top,size);
+       memcpy(stack->top(),top,size);
        dpush(tag<callstack>(stack));
 }
 
@@ -84,7 +81,7 @@ PRIMITIVE(set_callstack)
        callstack *stack = untag_check<callstack>(dpop());
 
        set_callstack(stack_chain->callstack_bottom,
-               FIRST_STACK_FRAME(stack),
+               stack->top(),
                untag_fixnum(stack->length),
                memcpy);
 
@@ -100,7 +97,7 @@ code_block *frame_code(stack_frame *frame)
 
 cell frame_type(stack_frame *frame)
 {
-       return frame_code(frame)->block.type;
+       return frame_code(frame)->type;
 }
 
 cell frame_executing(stack_frame *frame)
@@ -173,12 +170,11 @@ PRIMITIVE(callstack_to_array)
        dpush(tag<array>(frames));
 }
 
-stack_frame *innermost_stack_frame(callstack *callstack)
+stack_frame *innermost_stack_frame(callstack *stack)
 {
-       stack_frame *top = FIRST_STACK_FRAME(callstack);
-       cell bottom = (cell)top + untag_fixnum(callstack->length);
-
-       stack_frame *frame = (stack_frame *)bottom - 1;
+       stack_frame *top = stack->top();
+       stack_frame *bottom = stack->bottom();
+       stack_frame *frame = bottom - 1;
 
        while(frame >= top && frame_successor(frame) >= top)
                frame = frame_successor(frame);
@@ -195,9 +191,9 @@ stack_frame *innermost_stack_frame_quot(callstack *callstack)
 
 /* Some primitives implementing a limited form of callstack mutation.
 Used by the single stepper. */
-PRIMITIVE(innermost_stack_frame_quot)
+PRIMITIVE(innermost_stack_frame_executing)
 {
-       dpush(frame_executing(innermost_stack_frame_quot(untag_check<callstack>(dpop()))));
+       dpush(frame_executing(innermost_stack_frame(untag_check<callstack>(dpop()))));
 }
 
 PRIMITIVE(innermost_stack_frame_scan)
index efdbc7ba0520065443783ab05c323c39034742ac..a128cfee47de78fb7c9c648950349686aa460c11 100755 (executable)
@@ -6,8 +6,6 @@ inline static cell callstack_size(cell size)
        return sizeof(callstack) + size;
 }
 
-#define FIRST_STACK_FRAME(stack) (stack_frame *)((stack) + 1)
-
 typedef void (*CALLSTACK_ITER)(stack_frame *frame);
 
 stack_frame *fix_callstack_top(stack_frame *top, stack_frame *bottom);
@@ -22,7 +20,7 @@ cell frame_type(stack_frame *frame);
 PRIMITIVE(callstack);
 PRIMITIVE(set_callstack);
 PRIMITIVE(callstack_to_array);
-PRIMITIVE(innermost_stack_frame_quot);
+PRIMITIVE(innermost_stack_frame_executing);
 PRIMITIVE(innermost_stack_frame_scan);
 PRIMITIVE(set_innermost_stack_frame_quot);
 
old mode 100644 (file)
new mode 100755 (executable)
index 4694381..c34f651
@@ -3,9 +3,177 @@
 namespace factor
 {
 
+static relocation_type relocation_type_of(relocation_entry r)
+{
+       return (relocation_type)((r & 0xf0000000) >> 28);
+}
+
+static relocation_class relocation_class_of(relocation_entry r)
+{
+       return (relocation_class)((r & 0x0f000000) >> 24);
+}
+
+static cell relocation_offset_of(relocation_entry r)
+{
+       return  (r & 0x00ffffff);
+}
+
 void flush_icache_for(code_block *block)
 {
-       flush_icache((cell)block,block->block.size);
+       flush_icache((cell)block,block->size);
+}
+
+static int number_of_parameters(relocation_type type)
+{
+       switch(type)
+       {
+       case RT_PRIMITIVE:
+       case RT_XT:
+       case RT_XT_PIC:
+       case RT_XT_PIC_TAIL:
+       case RT_IMMEDIATE:
+       case RT_HERE:
+       case RT_UNTAGGED:
+               return 1;
+       case RT_DLSYM:
+               return 2;
+       case RT_THIS:
+       case RT_STACK_CHAIN:
+       case RT_MEGAMORPHIC_CACHE_HITS:
+               return 0;
+       default:
+               critical_error("Bad rel type",type);
+               return -1; /* Can't happen */
+       }
+}
+
+void *object_xt(cell obj)
+{
+       switch(tagged<object>(obj).type())
+       {
+       case WORD_TYPE:
+               return untag<word>(obj)->xt;
+       case QUOTATION_TYPE:
+               return untag<quotation>(obj)->xt;
+       default:
+               critical_error("Expected word or quotation",obj);
+               return NULL;
+       }
+}
+
+static void *xt_pic(word *w, cell tagged_quot)
+{
+       if(tagged_quot == F || max_pic_size == 0)
+               return w->xt;
+       else
+       {
+               quotation *quot = untag<quotation>(tagged_quot);
+               if(quot->compiledp == F)
+                       return w->xt;
+               else
+                       return quot->xt;
+       }
+}
+
+void *word_xt_pic(word *w)
+{
+       return xt_pic(w,w->pic_def);
+}
+
+void *word_xt_pic_tail(word *w)
+{
+       return xt_pic(w,w->pic_tail_def);
+}
+
+/* References to undefined symbols are patched up to call this function on
+image load */
+void undefined_symbol()
+{
+       general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
+}
+
+/* Look up an external library symbol referenced by a compiled code block */
+void *get_rel_symbol(array *literals, cell index)
+{
+       cell symbol = array_nth(literals,index);
+       cell library = array_nth(literals,index + 1);
+
+       dll *d = (library == F ? NULL : untag<dll>(library));
+
+       if(d != NULL && !d->dll)
+               return (void *)undefined_symbol;
+
+       switch(tagged<object>(symbol).type())
+       {
+       case BYTE_ARRAY_TYPE:
+               {
+                       symbol_char *name = alien_offset(symbol);
+                       void *sym = ffi_dlsym(d,name);
+
+                       if(sym)
+                               return sym;
+                       else
+                       {
+                               return (void *)undefined_symbol;
+                       }
+               }
+       case ARRAY_TYPE:
+               {
+                       cell i;
+                       array *names = untag<array>(symbol);
+                       for(i = 0; i < array_capacity(names); i++)
+                       {
+                               symbol_char *name = alien_offset(array_nth(names,i));
+                               void *sym = ffi_dlsym(d,name);
+
+                               if(sym)
+                                       return sym;
+                       }
+                       return (void *)undefined_symbol;
+               }
+       default:
+               critical_error("Bad symbol specifier",symbol);
+               return (void *)undefined_symbol;
+       }
+}
+
+cell compute_relocation(relocation_entry rel, cell index, code_block *compiled)
+{
+       array *literals = untag<array>(compiled->literals);
+       cell offset = relocation_offset_of(rel) + (cell)compiled->xt();
+
+#define ARG array_nth(literals,index)
+
+       switch(relocation_type_of(rel))
+       {
+       case RT_PRIMITIVE:
+               return (cell)primitives[untag_fixnum(ARG)];
+       case RT_DLSYM:
+               return (cell)get_rel_symbol(literals,index);
+       case RT_IMMEDIATE:
+               return ARG;
+       case RT_XT:
+               return (cell)object_xt(ARG);
+       case RT_XT_PIC:
+               return (cell)word_xt_pic(untag<word>(ARG));
+       case RT_XT_PIC_TAIL:
+               return (cell)word_xt_pic_tail(untag<word>(ARG));
+       case RT_HERE:
+               return offset + (short)untag_fixnum(ARG);
+       case RT_THIS:
+               return (cell)(compiled + 1);
+       case RT_STACK_CHAIN:
+               return (cell)&stack_chain;
+       case RT_UNTAGGED:
+               return untag_fixnum(ARG);
+       case RT_MEGAMORPHIC_CACHE_HITS:
+               return (cell)&megamorphic_cache_hits;
+       default:
+               critical_error("Bad rel type",rel);
+               return 0; /* Can't happen */
+       }
+
+#undef ARG
 }
 
 void iterate_relocations(code_block *compiled, relocation_iterator iter)
@@ -20,29 +188,8 @@ void iterate_relocations(code_block *compiled, relocation_iterator iter)
                for(cell i = 0; i < length; i++)
                {
                        relocation_entry rel = relocation->data<relocation_entry>()[i];
-
                        iter(rel,index,compiled);
-
-                       switch(REL_TYPE(rel))
-                       {
-                       case RT_PRIMITIVE:
-                       case RT_XT:
-                       case RT_XT_DIRECT:
-                       case RT_IMMEDIATE:
-                       case RT_HERE:
-                       case RT_UNTAGGED:
-                               index++;
-                               break;
-                       case RT_DLSYM:
-                               index += 2;
-                               break;
-                       case RT_THIS:
-                       case RT_STACK_CHAIN:
-                               break;
-                       default:
-                               critical_error("Bad rel type",rel);
-                               return; /* Can't happen */
-                       }
+                       index += number_of_parameters(relocation_type_of(rel));                 
                }
        }
 }
@@ -84,23 +231,26 @@ void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
        case RC_ABSOLUTE_PPC_2_2:
                store_address_2_2((cell *)offset,absolute_value);
                break;
+       case RC_ABSOLUTE_PPC_2:
+               store_address_masked((cell *)offset,absolute_value,rel_absolute_ppc_2_mask,0);
+               break;
        case RC_RELATIVE_PPC_2:
-               store_address_masked((cell *)offset,relative_value,REL_RELATIVE_PPC_2_MASK,0);
+               store_address_masked((cell *)offset,relative_value,rel_relative_ppc_2_mask,0);
                break;
        case RC_RELATIVE_PPC_3:
-               store_address_masked((cell *)offset,relative_value,REL_RELATIVE_PPC_3_MASK,0);
+               store_address_masked((cell *)offset,relative_value,rel_relative_ppc_3_mask,0);
                break;
        case RC_RELATIVE_ARM_3:
                store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
-                       REL_RELATIVE_ARM_3_MASK,2);
+                       rel_relative_arm_3_mask,2);
                break;
        case RC_INDIRECT_ARM:
                store_address_masked((cell *)offset,relative_value - sizeof(cell),
-                       REL_INDIRECT_ARM_MASK,0);
+                       rel_indirect_arm_mask,0);
                break;
        case RC_INDIRECT_ARM_PC:
                store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
-                       REL_INDIRECT_ARM_MASK,0);
+                       rel_indirect_arm_mask,0);
                break;
        default:
                critical_error("Bad rel class",klass);
@@ -110,19 +260,19 @@ void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
 
 void update_literal_references_step(relocation_entry rel, cell index, code_block *compiled)
 {
-       if(REL_TYPE(rel) == RT_IMMEDIATE)
+       if(relocation_type_of(rel) == RT_IMMEDIATE)
        {
-               cell offset = REL_OFFSET(rel) + (cell)(compiled + 1);
+               cell offset = relocation_offset_of(rel) + (cell)(compiled + 1);
                array *literals = untag<array>(compiled->literals);
                fixnum absolute_value = array_nth(literals,index);
-               store_address_in_code_block(REL_CLASS(rel),offset,absolute_value);
+               store_address_in_code_block(relocation_class_of(rel),offset,absolute_value);
        }
 }
 
 /* Update pointers to literals from compiled code. */
 void update_literal_references(code_block *compiled)
 {
-       if(!compiled->block.needs_fixup)
+       if(!compiled->needs_fixup)
        {
                iterate_relocations(compiled,update_literal_references_step);
                flush_icache_for(compiled);
@@ -133,12 +283,12 @@ void update_literal_references(code_block *compiled)
 aging and nursery collections */
 void copy_literal_references(code_block *compiled)
 {
-       if(collecting_gen >= compiled->block.last_scan)
+       if(collecting_gen >= compiled->last_scan)
        {
                if(collecting_accumulation_gen_p())
-                       compiled->block.last_scan = collecting_gen;
+                       compiled->last_scan = collecting_gen;
                else
-                       compiled->block.last_scan = collecting_gen + 1;
+                       compiled->last_scan = collecting_gen + 1;
 
                /* initialize chase pointer */
                cell scan = newspace->here;
@@ -154,52 +304,24 @@ void copy_literal_references(code_block *compiled)
        }
 }
 
-void *object_xt(cell obj)
+/* Compute an address to store at a relocation */
+void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
 {
-       switch(tagged<object>(obj).type())
-       {
-       case WORD_TYPE:
-               return untag<word>(obj)->xt;
-       case QUOTATION_TYPE:
-               return untag<quotation>(obj)->xt;
-       default:
-               critical_error("Expected word or quotation",obj);
-               return NULL;
-       }
-}
+#ifdef FACTOR_DEBUG
+       tagged<array>(compiled->literals).untag_check();
+       tagged<byte_array>(compiled->relocation).untag_check();
+#endif
 
-void *word_direct_xt(word *w)
-{
-       cell tagged_quot = w->direct_entry_def;
-       if(tagged_quot == F || max_pic_size == 0)
-               return w->xt;
-       else
-       {
-               quotation *quot = untag<quotation>(tagged_quot);
-               if(quot->compiledp == F)
-                       return w->xt;
-               else
-                       return quot->xt;
-       }
+       store_address_in_code_block(relocation_class_of(rel),
+                                   relocation_offset_of(rel) + (cell)compiled->xt(),
+                                   compute_relocation(rel,index,compiled));
 }
 
 void update_word_references_step(relocation_entry rel, cell index, code_block *compiled)
 {
-       relocation_type type = REL_TYPE(rel);
-       if(type == RT_XT || type == RT_XT_DIRECT)
-       {
-               cell offset = REL_OFFSET(rel) + (cell)(compiled + 1);
-               array *literals = untag<array>(compiled->literals);
-               cell obj = array_nth(literals,index);
-
-               void *xt;
-               if(type == RT_XT)
-                       xt = object_xt(obj);
-               else
-                       xt = word_direct_xt(untag<word>(obj));
-
-               store_address_in_code_block(REL_CLASS(rel),offset,(cell)xt);
-       }
+       relocation_type type = relocation_type_of(rel);
+       if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
+               relocate_code_block_step(rel,index,compiled);
 }
 
 /* Relocate new code blocks completely; updating references to literals,
@@ -208,7 +330,7 @@ to update references to other words, without worrying about literals
 or dlsyms. */
 void update_word_references(code_block *compiled)
 {
-       if(compiled->block.needs_fixup)
+       if(compiled->needs_fixup)
                relocate_code_block(compiled);
        /* update_word_references() is always applied to every block in
           the code heap. Since it resets all call sites to point to
@@ -217,8 +339,8 @@ void update_word_references(code_block *compiled)
           are referenced after this is done. So instead of polluting
           the code heap with dead PICs that will be freed on the next
           GC, we add them to the free list immediately. */
-       else if(compiled->block.type == PIC_TYPE)
-               heap_free(&code,&compiled->block);
+       else if(compiled->type == PIC_TYPE)
+               heap_free(&code,compiled);
        else
        {
                iterate_relocations(compiled,update_word_references_step);
@@ -248,7 +370,7 @@ void mark_code_block(code_block *compiled)
 {
        check_code_address((cell)compiled);
 
-       mark_block(&compiled->block);
+       mark_block(compiled);
 
        copy_handle(&compiled->literals);
        copy_handle(&compiled->relocation);
@@ -262,7 +384,7 @@ void mark_stack_frame_step(stack_frame *frame)
 /* Mark code blocks executing in currently active stack frames. */
 void mark_active_blocks(context *stacks)
 {
-       if(collecting_gen == TENURED)
+       if(collecting_gen == data->tenured())
        {
                cell top = (cell)stacks->callstack_top;
                cell bottom = (cell)stacks->callstack_bottom;
@@ -300,113 +422,11 @@ void mark_object_code_block(object *object)
        }
 }
 
-/* References to undefined symbols are patched up to call this function on
-image load */
-void undefined_symbol(void)
-{
-       general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
-}
-
-/* Look up an external library symbol referenced by a compiled code block */
-void *get_rel_symbol(array *literals, cell index)
-{
-       cell symbol = array_nth(literals,index);
-       cell library = array_nth(literals,index + 1);
-
-       dll *d = (library == F ? NULL : untag<dll>(library));
-
-       if(d != NULL && !d->dll)
-               return (void *)undefined_symbol;
-
-       switch(tagged<object>(symbol).type())
-       {
-       case BYTE_ARRAY_TYPE:
-               {
-                       symbol_char *name = alien_offset(symbol);
-                       void *sym = ffi_dlsym(d,name);
-
-                       if(sym)
-                               return sym;
-                       else
-                       {
-                               printf("%s\n",name);
-                               return (void *)undefined_symbol;
-                       }
-               }
-       case ARRAY_TYPE:
-               {
-                       cell i;
-                       array *names = untag<array>(symbol);
-                       for(i = 0; i < array_capacity(names); i++)
-                       {
-                               symbol_char *name = alien_offset(array_nth(names,i));
-                               void *sym = ffi_dlsym(d,name);
-
-                               if(sym)
-                                       return sym;
-                       }
-                       return (void *)undefined_symbol;
-               }
-       default:
-               critical_error("Bad symbol specifier",symbol);
-               return (void *)undefined_symbol;
-       }
-}
-
-/* Compute an address to store at a relocation */
-void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
-{
-#ifdef FACTOR_DEBUG
-       tagged<array>(compiled->literals).untag_check();
-       tagged<byte_array>(compiled->relocation).untag_check();
-#endif
-
-       cell offset = REL_OFFSET(rel) + (cell)(compiled + 1);
-       array *literals = untag<array>(compiled->literals);
-       fixnum absolute_value;
-
-       switch(REL_TYPE(rel))
-       {
-       case RT_PRIMITIVE:
-               absolute_value = (cell)primitives[untag_fixnum(array_nth(literals,index))];
-               break;
-       case RT_DLSYM:
-               absolute_value = (cell)get_rel_symbol(literals,index);
-               break;
-       case RT_IMMEDIATE:
-               absolute_value = array_nth(literals,index);
-               break;
-       case RT_XT:
-               absolute_value = (cell)object_xt(array_nth(literals,index));
-               break;
-       case RT_XT_DIRECT:
-               absolute_value = (cell)word_direct_xt(untag<word>(array_nth(literals,index)));
-               break;
-       case RT_HERE:
-               absolute_value = offset + (short)untag_fixnum(array_nth(literals,index));
-               break;
-       case RT_THIS:
-               absolute_value = (cell)(compiled + 1);
-               break;
-       case RT_STACK_CHAIN:
-               absolute_value = (cell)&stack_chain;
-               break;
-       case RT_UNTAGGED:
-               absolute_value = untag_fixnum(array_nth(literals,index));
-               break;
-       default:
-               critical_error("Bad rel type",rel);
-               return; /* Can't happen */
-       }
-
-       store_address_in_code_block(REL_CLASS(rel),offset,absolute_value);
-}
-
 /* Perform all fixups on a code block */
 void relocate_code_block(code_block *compiled)
 {
-       compiled->block.last_scan = NURSERY;
-       compiled->block.needs_fixup = false;
+       compiled->last_scan = data->nursery();
+       compiled->needs_fixup = false;
        iterate_relocations(compiled,relocate_code_block_step);
        flush_icache_for(compiled);
 }
@@ -474,9 +494,9 @@ code_block *add_code_block(
        code_block *compiled = allot_code_block(code_length);
 
        /* compiled header */
-       compiled->block.type = type;
-       compiled->block.last_scan = NURSERY;
-       compiled->block.needs_fixup = true;
+       compiled->type = type;
+       compiled->last_scan = data->nursery();
+       compiled->needs_fixup = true;
        compiled->relocation = relocation.value();
 
        /* slight space optimization */
@@ -494,7 +514,7 @@ code_block *add_code_block(
 
        /* next time we do a minor GC, we have to scan the code heap for
        literals */
-       last_code_heap_scan = NURSERY;
+       last_code_heap_scan = data->nursery();
 
        return compiled;
 }
index 9689ea541982733c29e7eef77ce8f0b24da9a0e2..d46cd9e885886d7cbe7635548043081736890c94 100644 (file)
@@ -8,10 +8,12 @@ enum relocation_type {
        RT_DLSYM,
        /* a pointer to a compiled word reference */
        RT_DISPATCH,
-       /* a word's general entry point XT */
+       /* a word or quotation's general entry point */
        RT_XT,
-       /* a word's direct entry point XT */
-       RT_XT_DIRECT,
+       /* a word's PIC entry point */
+       RT_XT_PIC,
+       /* a word's tail-call PIC entry point */
+       RT_XT_PIC_TAIL,
        /* current offset */
        RT_HERE,
        /* current code block */
@@ -22,6 +24,8 @@ enum relocation_type {
        RT_STACK_CHAIN,
        /* untagged fixnum literal */
        RT_UNTAGGED,
+       /* address of megamorphic_cache_hits var */
+       RT_MEGAMORPHIC_CACHE_HITS,
 };
 
 enum relocation_class {
@@ -31,8 +35,10 @@ enum relocation_class {
        RC_ABSOLUTE,
        /* relative address in a 32-bit location */
        RC_RELATIVE,
-       /* relative address in a PowerPC LIS/ORI sequence */
+       /* absolute address in a PowerPC LIS/ORI sequence */
        RC_ABSOLUTE_PPC_2_2,
+       /* absolute address in a PowerPC LWZ instruction */
+       RC_ABSOLUTE_PPC_2,
        /* relative address in a PowerPC LWZ/STW/BC instruction */
        RC_RELATIVE_PPC_2,
        /* relative address in a PowerPC B/BL instruction */
@@ -45,16 +51,14 @@ enum relocation_class {
        RC_INDIRECT_ARM_PC
 };
 
-#define REL_RELATIVE_PPC_2_MASK 0xfffc
-#define REL_RELATIVE_PPC_3_MASK 0x3fffffc
-#define REL_INDIRECT_ARM_MASK 0xfff
-#define REL_RELATIVE_ARM_3_MASK 0xffffff
+static const cell rel_absolute_ppc_2_mask = 0xffff;
+static const cell rel_relative_ppc_2_mask = 0xfffc;
+static const cell rel_relative_ppc_3_mask = 0x3fffffc;
+static const cell rel_indirect_arm_mask = 0xfff;
+static const cell rel_relative_arm_3_mask = 0xffffff;
 
 /* code relocation table consists of a table of entries for each fixup */
 typedef u32 relocation_entry;
-#define REL_TYPE(r) (relocation_type)(((r) & 0xf0000000) >> 28)
-#define REL_CLASS(r) (relocation_class)(((r) & 0x0f000000) >> 24)
-#define REL_OFFSET(r) ((r) & 0x00ffffff)
 
 void flush_icache_for(code_block *compiled);
 
@@ -82,7 +86,7 @@ void mark_object_code_block(object *scan);
 
 void relocate_code_block(code_block *relocating);
 
-inline static bool stack_traces_p(void)
+inline static bool stack_traces_p()
 {
        return userenv[STACK_TRACES_ENV] != F;
 }
index b86d08cf5221699fec7afc4aadfbf981cdaf3722..4710a1baa013a64375e9f5065fb7823a777202a0 100755 (executable)
@@ -22,9 +22,9 @@ void new_heap(heap *heap, cell size)
 
 static void add_to_free_list(heap *heap, free_heap_block *block)
 {
-       if(block->block.size < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT)
+       if(block->size < free_list_count * block_size_increment)
        {
-               int index = block->block.size / BLOCK_SIZE_INCREMENT;
+               int index = block->size / block_size_increment;
                block->next_free = heap->free.small_blocks[index];
                heap->free.small_blocks[index] = block;
        }
@@ -45,7 +45,7 @@ void build_free_list(heap *heap, cell size)
 
        clear_free_list(heap);
 
-       size = (size + BLOCK_SIZE_INCREMENT - 1) & ~(BLOCK_SIZE_INCREMENT - 1);
+       size = (size + block_size_increment - 1) & ~(block_size_increment - 1);
 
        heap_block *scan = first_block(heap);
        free_heap_block *end = (free_heap_block *)(heap->seg->start + size);
@@ -73,8 +73,8 @@ void build_free_list(heap *heap, cell size)
        branch is only taken after loading a new image, not after code GC */
        if((cell)(end + 1) <= heap->seg->end)
        {
-               end->block.status = B_FREE;
-               end->block.size = heap->seg->end - (cell)end;
+               end->status = B_FREE;
+               end->size = heap->seg->end - (cell)end;
 
                /* add final free block */
                add_to_free_list(heap,end);
@@ -93,7 +93,7 @@ void build_free_list(heap *heap, cell size)
 
 static void assert_free_block(free_heap_block *block)
 {
-       if(block->block.status != B_FREE)
+       if(block->status != B_FREE)
                critical_error("Invalid block in free list",(cell)block);
 }
                
@@ -101,9 +101,9 @@ static free_heap_block *find_free_block(heap *heap, cell size)
 {
        cell attempt = size;
 
-       while(attempt < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT)
+       while(attempt < free_list_count * block_size_increment)
        {
-               int index = attempt / BLOCK_SIZE_INCREMENT;
+               int index = attempt / block_size_increment;
                free_heap_block *block = heap->free.small_blocks[index];
                if(block)
                {
@@ -121,7 +121,7 @@ static free_heap_block *find_free_block(heap *heap, cell size)
        while(block)
        {
                assert_free_block(block);
-               if(block->block.size >= size)
+               if(block->size >= size)
                {
                        if(prev)
                                prev->next_free = block->next_free;
@@ -139,14 +139,14 @@ static free_heap_block *find_free_block(heap *heap, cell size)
 
 static free_heap_block *split_free_block(heap *heap, free_heap_block *block, cell size)
 {
-       if(block->block.size != size )
+       if(block->size != size )
        {
                /* split the block in two */
                free_heap_block *split = (free_heap_block *)((cell)block + size);
-               split->block.status = B_FREE;
-               split->block.size = block->block.size - size;
+               split->status = B_FREE;
+               split->size = block->size - size;
                split->next_free = block->next_free;
-               block->block.size = size;
+               block->size = size;
                add_to_free_list(heap,split);
        }
 
@@ -156,15 +156,15 @@ static free_heap_block *split_free_block(heap *heap, free_heap_block *block, cel
 /* Allocate a block of memory from the mark and sweep GC heap */
 heap_block *heap_allot(heap *heap, cell size)
 {
-       size = (size + BLOCK_SIZE_INCREMENT - 1) & ~(BLOCK_SIZE_INCREMENT - 1);
+       size = (size + block_size_increment - 1) & ~(block_size_increment - 1);
 
        free_heap_block *block = find_free_block(heap,size);
        if(block)
        {
                block = split_free_block(heap,block,size);
 
-               block->block.status = B_ALLOCATED;
-               return &block->block;
+               block->status = B_ALLOCATED;
+               return block;
        }
        else
                return NULL;
@@ -303,16 +303,16 @@ cell heap_size(heap *heap)
 }
 
 /* Compute where each block is going to go, after compaction */
-cell compute_heap_forwarding(heap *heap)
+cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding)
 {
        heap_block *scan = first_block(heap);
-       cell address = (cell)first_block(heap);
+       char *address = (char *)first_block(heap);
 
        while(scan)
        {
                if(scan->status == B_ALLOCATED)
                {
-                       scan->forwarding = (heap_block *)address;
+                       forwarding[scan] = address;
                        address += scan->size;
                }
                else if(scan->status == B_MARKED)
@@ -321,10 +321,10 @@ cell compute_heap_forwarding(heap *heap)
                scan = next_block(heap,scan);
        }
 
-       return address - heap->seg->start;
+       return (cell)address - heap->seg->start;
 }
 
-void compact_heap(heap *heap)
+void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding)
 {
        heap_block *scan = first_block(heap);
 
@@ -332,8 +332,8 @@ void compact_heap(heap *heap)
        {
                heap_block *next = next_block(heap,scan);
 
-               if(scan->status == B_ALLOCATED && scan != scan->forwarding)
-                       memcpy(scan->forwarding,scan,scan->size);
+               if(scan->status == B_ALLOCATED)
+                       memmove(forwarding[scan],scan,scan->size);
                scan = next;
        }
 }
index 3879d3c8e821da07f5e6ac2d09f3c9f9bdd5473a..1cfafb69c23f93b7383b9490cf915ff4d52fcc17 100755 (executable)
@@ -1,11 +1,11 @@
 namespace factor
 {
 
-#define FREE_LIST_COUNT 16
-#define BLOCK_SIZE_INCREMENT 32
+static const cell free_list_count = 16;
+static const cell block_size_increment = 32;
 
 struct heap_free_list {
-       free_heap_block *small_blocks[FREE_LIST_COUNT];
+       free_heap_block *small_blocks[free_list_count];
        free_heap_block *large_blocks;
 };
 
@@ -25,8 +25,8 @@ void unmark_marked(heap *heap);
 void free_unmarked(heap *heap, heap_iterator iter);
 void heap_usage(heap *h, cell *used, cell *total_free, cell *max_free);
 cell heap_size(heap *h);
-cell compute_heap_forwarding(heap *h);
-void compact_heap(heap *h);
+cell compute_heap_forwarding(heap *h, unordered_map<heap_block *,char *> &forwarding);
+void compact_heap(heap *h, unordered_map<heap_block *,char *> &forwarding);
 
 inline static heap_block *next_block(heap *h, heap_block *block)
 {
index 5dca29b4203984e6f87ac9c05215fd8f8891ca2f..c8c7639930a57a0cd9ae200ae4b0108fc9be68e2 100755 (executable)
@@ -26,8 +26,8 @@ void jit_compile_word(cell word_, cell def_, bool relocate)
 
        word->code = def->code;
 
-       if(word->direct_entry_def != F)
-               jit_compile(word->direct_entry_def,relocate);
+       if(word->pic_def != F) jit_compile(word->pic_def,relocate);
+       if(word->pic_tail_def != F) jit_compile(word->pic_tail_def,relocate);
 }
 
 /* Apply a function to every code block */
@@ -45,14 +45,14 @@ void iterate_code_heap(code_heap_iterator iter)
 
 /* Copy literals referenced from all code blocks to newspace. Only for
 aging and nursery collections */
-void copy_code_heap_roots(void)
+void copy_code_heap_roots()
 {
        iterate_code_heap(copy_literal_references);
 }
 
 /* Update pointers to words referenced from all code blocks. Only after
 defining a new word. */
-void update_code_heap_words(void)
+void update_code_heap_words()
 {
        iterate_code_heap(update_word_references);
 }
@@ -119,9 +119,11 @@ PRIMITIVE(code_room)
        dpush(tag_fixnum(max_free / 1024));
 }
 
+static unordered_map<heap_block *,char *> forwarding;
+
 code_block *forward_xt(code_block *compiled)
 {
-       return (code_block *)compiled->block.forwarding;
+       return (code_block *)forwarding[compiled];
 }
 
 void forward_frame_xt(stack_frame *frame)
@@ -132,7 +134,7 @@ void forward_frame_xt(stack_frame *frame)
        FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
 }
 
-void forward_object_xts(void)
+void forward_object_xts()
 {
        begin_scan();
 
@@ -176,7 +178,7 @@ void forward_object_xts(void)
 }
 
 /* Set the XT fields now that the heap has been compacted */
-void fixup_object_xts(void)
+void fixup_object_xts()
 {
        begin_scan();
 
@@ -209,19 +211,19 @@ void fixup_object_xts(void)
 since it makes several passes over the code and data heaps, but we only ever
 do this before saving a deployed image and exiting, so performaance is not
 critical here */
-void compact_code_heap(void)
+void compact_code_heap()
 {
        /* Free all unreachable code blocks */
        gc();
 
        /* Figure out where the code heap blocks are going to end up */
-       cell size = compute_heap_forwarding(&code);
+       cell size = compute_heap_forwarding(&code, forwarding);
 
        /* Update word and quotation code pointers */
        forward_object_xts();
 
        /* Actually perform the compaction */
-       compact_heap(&code);
+       compact_heap(&code,forwarding);
 
        /* Update word and quotation XTs */
        fixup_object_xts();
index 056a6a88c624676910d6fb98e5de3898d4f15878..6f139a47280d0dba3ab9ae92c0c770aa9deedc90 100755 (executable)
@@ -14,13 +14,13 @@ typedef void (*code_heap_iterator)(code_block *compiled);
 
 void iterate_code_heap(code_heap_iterator iter);
 
-void copy_code_heap_roots(void);
+void copy_code_heap_roots();
 
 PRIMITIVE(modify_code_heap);
 
 PRIMITIVE(code_room);
 
-void compact_code_heap(void);
+void compact_code_heap();
 
 inline static void check_code_pointer(cell ptr)
 {
index 66570abc31ea5555179de7674147858761047c48..b0a27ef18f39a32c8b021d6e85490fd47981702d 100644 (file)
@@ -8,27 +8,27 @@ namespace factor
 cell ds_size, rs_size;
 context *unused_contexts;
 
-void reset_datastack(void)
+void reset_datastack()
 {
        ds = ds_bot - sizeof(cell);
 }
 
-void reset_retainstack(void)
+void reset_retainstack()
 {
        rs = rs_bot - sizeof(cell);
 }
 
-#define RESERVED (64 * sizeof(cell))
+static const cell stack_reserved = (64 * sizeof(cell));
 
-void fix_stacks(void)
+void fix_stacks()
 {
-       if(ds + sizeof(cell) < ds_bot || ds + RESERVED >= ds_top) reset_datastack();
-       if(rs + sizeof(cell) < rs_bot || rs + RESERVED >= rs_top) reset_retainstack();
+       if(ds + sizeof(cell) < ds_bot || ds + stack_reserved >= ds_top) reset_datastack();
+       if(rs + sizeof(cell) < rs_bot || rs + stack_reserved >= rs_top) reset_retainstack();
 }
 
 /* called before entry into foreign C code. Note that ds and rs might
 be stored in registers, so callbacks must save and restore the correct values */
-void save_stacks(void)
+void save_stacks()
 {
        if(stack_chain)
        {
@@ -37,7 +37,7 @@ void save_stacks(void)
        }
 }
 
-context *alloc_context(void)
+context *alloc_context()
 {
        context *new_context;
 
@@ -63,7 +63,7 @@ void dealloc_context(context *old_context)
 }
 
 /* called on entry into a compiled callback */
-void nest_stacks(void)
+void nest_stacks()
 {
        context *new_context = alloc_context();
 
@@ -95,7 +95,7 @@ void nest_stacks(void)
 }
 
 /* called when leaving a compiled callback */
-void unnest_stacks(void)
+void unnest_stacks()
 {
        ds = stack_chain->datastack_save;
        rs = stack_chain->retainstack_save;
index 13af17f2f041f0c5eafac45ac80e045ecc7a592d..4a6f401f0b4a5df8507247d4eb7337f716ef1f28 100644 (file)
@@ -46,9 +46,9 @@ extern cell ds_size, rs_size;
 DEFPUSHPOP(d,ds)
 DEFPUSHPOP(r,rs)
 
-void reset_datastack(void);
-void reset_retainstack(void);
-void fix_stacks(void);
+void reset_datastack();
+void reset_retainstack();
+void fix_stacks();
 void init_stacks(cell ds_size, cell rs_size);
 
 PRIMITIVE(datastack);
@@ -57,9 +57,9 @@ PRIMITIVE(set_datastack);
 PRIMITIVE(set_retainstack);
 PRIMITIVE(check_datastack);
 
-VM_C_API void save_stacks(void);
-VM_C_API void nest_stacks(void);
-VM_C_API void unnest_stacks(void);
+VM_C_API void save_stacks();
+VM_C_API void nest_stacks();
+VM_C_API void unnest_stacks();
 
 }
 
index 5e77c004aa7e0897413838752fac8c58479cd6ad..a372b2b1f5d786e68fd14a513afd2ae80f503b76 100755 (executable)
@@ -2,7 +2,7 @@
 in the public domain. */
 #include "asm.h"
 
-#define DS_REG r29
+#define DS_REG r13
 
 DEF(void,primitive_fixnum_add,(void)):
        lwz r3,0(DS_REG)
@@ -45,7 +45,7 @@ multiply_overflow:
        
 /* Note that the XT is passed to the quotation in r11 */
 #define CALL_OR_JUMP_QUOT \
-       lwz r11,14(r3)     /* load quotation-xt slot */ XX \
+       lwz r11,16(r3)     /* load quotation-xt slot */ XX \
 
 #define CALL_QUOT \
        CALL_OR_JUMP_QUOT XX \
@@ -100,22 +100,22 @@ the Factor compiler treats the entire register file as volatile. */
 DEF(void,c_to_factor,(CELL quot)):
        PROLOGUE
 
-       SAVE_INT(r13,0)    /* save GPRs */
-       SAVE_INT(r14,1)
-       SAVE_INT(r15,2)
-       SAVE_INT(r16,3)
-       SAVE_INT(r17,4)
-       SAVE_INT(r18,5)
-       SAVE_INT(r19,6)
-       SAVE_INT(r20,7)
-       SAVE_INT(r21,8)
-       SAVE_INT(r22,9)
-       SAVE_INT(r23,10)
-       SAVE_INT(r24,11)
-       SAVE_INT(r25,12)
-       SAVE_INT(r26,13)
-       SAVE_INT(r27,14)
-       SAVE_INT(r28,15)
+       SAVE_INT(r15,0)    /* save GPRs */
+       SAVE_INT(r16,1)
+       SAVE_INT(r17,2)
+       SAVE_INT(r18,3)
+       SAVE_INT(r19,4)
+       SAVE_INT(r20,5)
+       SAVE_INT(r21,6)
+       SAVE_INT(r22,7)
+       SAVE_INT(r23,8)
+       SAVE_INT(r24,9)
+       SAVE_INT(r25,10)
+       SAVE_INT(r26,11)
+       SAVE_INT(r27,12)
+       SAVE_INT(r28,13)
+       SAVE_INT(r29,14)
+       SAVE_INT(r30,15)
        SAVE_INT(r31,16)
 
        SAVE_FP(f14,20) /* save FPRs */
@@ -165,22 +165,22 @@ DEF(void,c_to_factor,(CELL quot)):
        RESTORE_FP(f14,20)      /* save FPRs */
 
        RESTORE_INT(r31,16)   /* restore GPRs */
-       RESTORE_INT(r28,15)
-       RESTORE_INT(r27,14)
-       RESTORE_INT(r26,13)
-       RESTORE_INT(r25,12)
-       RESTORE_INT(r24,11)
-       RESTORE_INT(r23,10)
-       RESTORE_INT(r22,9)
-       RESTORE_INT(r21,8)
-       RESTORE_INT(r20,7)
-       RESTORE_INT(r19,6)
-       RESTORE_INT(r18,5)
-       RESTORE_INT(r17,4)
-       RESTORE_INT(r16,3)
-       RESTORE_INT(r15,2)
-       RESTORE_INT(r14,1)
-       RESTORE_INT(r13,0)
+       RESTORE_INT(r30,15)
+       RESTORE_INT(r29,14)
+       RESTORE_INT(r28,13)
+       RESTORE_INT(r27,12)
+       RESTORE_INT(r26,11)
+       RESTORE_INT(r25,10)
+       RESTORE_INT(r24,9)
+       RESTORE_INT(r23,8)
+       RESTORE_INT(r22,7)
+       RESTORE_INT(r21,6)
+       RESTORE_INT(r20,5)
+       RESTORE_INT(r19,4)
+       RESTORE_INT(r18,3)
+       RESTORE_INT(r17,2)
+       RESTORE_INT(r16,1)
+       RESTORE_INT(r15,0)
 
        EPILOGUE
        blr
@@ -234,3 +234,13 @@ DEF(void,flush_icache,(void *start, int len)):
        sync               /* finish up */
        isync
        blr
+
+DEF(void,primitive_inline_cache_miss,(void)):
+    mflr r6
+DEF(void,primitive_inline_cache_miss_tail,(void)):
+    PROLOGUE
+    mr r3,r6
+    bl MANGLE(inline_cache_miss)
+    EPILOGUE
+    mtctr r3
+    bctr
index 7e8ae05faccbe8e7e6c6cd781a38e2914961bf98..6ae2cce27d488566593b79c52d79d4d619c22792 100755 (executable)
@@ -2,16 +2,75 @@ namespace factor
 {
 
 #define FACTOR_CPU_STRING "ppc"
-#define VM_ASM_API
+#define VM_ASM_API VM_C_API
 
-register cell ds asm("r29");
-register cell rs asm("r30");
+register cell ds asm("r13");
+register cell rs asm("r14");
 
-void c_to_factor(cell quot);
-void undefined(cell word);
-void set_callstack(stack_frame *to, stack_frame *from, cell length, void *memcpy);
-void throw_impl(cell quot, stack_frame *rewind);
-void lazy_jit_compile(cell quot);
-void flush_icache(cell start, cell len);
+/* In the instruction sequence:
+
+   LOAD32 r3,...
+   B blah
+
+   the offset from the immediate operand to LOAD32 to the instruction after
+   the branch is two instructions. */
+static const fixnum xt_tail_pic_offset = 4 * 2;
+
+inline static void check_call_site(cell return_address)
+{
+#ifdef FACTOR_DEBUG
+       cell insn = *(cell *)return_address;
+       /* Check that absolute bit is 0 */
+       assert((insn & 0x2) == 0x0);
+       /* Check that instruction is branch */
+       assert((insn >> 26) == 0x12);
+#endif
+}
+
+static const cell b_mask = 0x3fffffc;
+
+inline static void *get_call_target(cell return_address)
+{
+       return_address -= sizeof(cell);
+       check_call_site(return_address);
+
+       cell insn = *(cell *)return_address;
+       cell unsigned_addr = (insn & b_mask);
+       fixnum signed_addr = (fixnum)(unsigned_addr << 6) >> 6;
+       return (void *)(signed_addr + return_address);
+}
+
+inline static void set_call_target(cell return_address, void *target)
+{
+       return_address -= sizeof(cell);
+       check_call_site(return_address);
+
+       cell insn = *(cell *)return_address;
+
+       fixnum relative_address = ((cell)target - return_address);
+       insn = ((insn & ~b_mask) | (relative_address & b_mask));
+       *(cell *)return_address = insn;
+
+       /* Flush the cache line containing the call we just patched */
+       __asm__ __volatile__ ("icbi 0, %0\n" "sync\n"::"r" (return_address):);
+}
+
+inline static bool tail_call_site_p(cell return_address)
+{
+       return_address -= sizeof(cell);
+       cell insn = *(cell *)return_address;
+       return (insn & 0x1) == 0;
+}
+
+/* Defined in assembly */
+VM_ASM_API void c_to_factor(cell quot);
+VM_ASM_API void throw_impl(cell quot, stack_frame *rewind);
+VM_ASM_API void lazy_jit_compile(cell quot);
+VM_ASM_API void flush_icache(cell start, cell len);
+
+VM_ASM_API void set_callstack(stack_frame *to,
+                              stack_frame *from,
+                              cell length,
+                              void *(*memcpy)(void*,const void*, size_t));
 
 }
index 3c0db3693543f352dca557aeeaea664fc3af5116..ff45f480660d4bca162466c7cea71c35579db604 100755 (executable)
@@ -1,9 +1,5 @@
 #include "asm.h"
 
-/* Note that primitive word definitions are compiled with
-__attribute__((regparm 2), so the pointer to the word object is passed in EAX,
-and the callstack top is passed in EDX */
-
 #define ARG0 %eax
 #define ARG1 %edx
 #define STACK_REG %esp
@@ -30,7 +26,6 @@ and the callstack top is passed in EDX */
        pop %ebx
 
 #define QUOT_XT_OFFSET 16
-#define WORD_XT_OFFSET 30
 
 /* We pass a function pointer to memcpy to work around a Mac OS X
 ABI limitation which would otherwise require us to do a bizzaro PC-relative
@@ -60,10 +55,11 @@ DEF(bool,check_sse2,(void)):
        mov %edx,%eax
        ret
 
-DEF(F_FASTCALL void,primitive_inline_cache_miss,(void)):
-       mov (%esp),%eax
+DEF(void,primitive_inline_cache_miss,(void)):
+       mov (%esp),%ebx
+DEF(void,primitive_inline_cache_miss_tail,(void)):
        sub $8,%esp
-       push %eax
+       push %ebx
        call MANGLE(inline_cache_miss)
        add $12,%esp
        jmp *%eax
index 6b6328aa4f308c0b701d0b034c176091c1c1efae..902b33b0b4371cdbf5617c6243ea956d6cae12f4 100755 (executable)
@@ -6,6 +6,6 @@ namespace factor
 register cell ds asm("esi");
 register cell rs asm("edi");
 
-#define VM_ASM_API extern "C" __attribute__ ((regparm (2)))
+#define VM_ASM_API VM_C_API __attribute__ ((regparm (2)))
 
 }
index a110bf1d51277fc09a9c180a58b4edf7d2ee2542..6b2faa1c0bbad6318ec73d23c47670bce1276a0e 100644 (file)
@@ -62,7 +62,6 @@
 #endif
 
 #define QUOT_XT_OFFSET 36
-#define WORD_XT_OFFSET 66
 
 /* We pass a function pointer to memcpy to work around a Mac OS X
 ABI limitation which would otherwise require us to do a bizzaro PC-relative
@@ -73,9 +72,11 @@ DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, voi
        call *ARG3                         /* call memcpy */
        ret                                /* return _with new stack_ */
 
-DEF(F_FASTCALL void,primitive_inline_cache_miss,(void)):
-       mov (%rsp),ARG0
+DEF(void,primitive_inline_cache_miss,(void)):
+       mov (%rsp),%rbx
+DEF(void,primitive_inline_cache_miss_tail,(void)):
        sub $STACK_PADDING,%rsp
+       mov %rbx,ARG0
        call MANGLE(inline_cache_miss)
        add $STACK_PADDING,%rsp
        jmp *%rax
old mode 100644 (file)
new mode 100755 (executable)
index be71a78..679c301
@@ -6,6 +6,6 @@ namespace factor
 register cell ds asm("r14");
 register cell rs asm("r15");
 
-#define VM_ASM_API extern "C"
+#define VM_ASM_API VM_C_API
 
 }
index c0b4651811178f924827312cdebe7ffef9a4d7bf..e5852f9ad9fc50f3ca32d6bdf344acb4d78cf1d8 100755 (executable)
@@ -7,15 +7,29 @@ namespace factor
 
 inline static void flush_icache(cell start, cell len) {}
 
+/* In the instruction sequence:
+
+   MOV EBX,...
+   JMP blah
+
+   the offset from the immediate operand to MOV to the instruction after
+   the jump is a cell for the immediate operand, 4 bytes for the JMP
+   destination, and one byte for the JMP opcode. */
+static const fixnum xt_tail_pic_offset = sizeof(cell) + 4 + 1;
+
+static const unsigned char call_opcode = 0xe8;
+static const unsigned char jmp_opcode = 0xe9;
+
+inline static unsigned char call_site_opcode(cell return_address)
+{
+       return *(unsigned char *)(return_address - 5);
+}
+
 inline static void check_call_site(cell return_address)
 {
-       /* An x86 CALL instruction looks like so:
-          |e8|..|..|..|..|
-          where the ... are a PC-relative jump address.
-          The return_address points to right after the
-          instruction. */
 #ifdef FACTOR_DEBUG
-       assert(*(unsigned char *)(return_address - 5) == 0xe8);
+       unsigned char opcode = call_site_opcode(return_address);
+       assert(opcode == call_opcode || opcode == jmp_opcode);
 #endif
 }
 
@@ -31,6 +45,11 @@ inline static void set_call_target(cell return_address, void *target)
        *(int *)(return_address - 4) = ((cell)target - return_address);
 }
 
+inline static bool tail_call_site_p(cell return_address)
+{
+       return call_site_opcode(return_address) == jmp_opcode;
+}
+
 /* Defined in assembly */
 VM_ASM_API void c_to_factor(cell quot);
 VM_ASM_API void throw_impl(cell quot, stack_frame *rewind_to);
index e26edc97212c6c29f7ecdf5ef80179d0361bdb21..bcf6387639dd3645d4b55243254f104d013efea6 100755 (executable)
@@ -9,15 +9,15 @@ bool performing_gc;
 bool performing_compaction;
 cell collecting_gen;
 
-/* if true, we collecting AGING space for the second time, so if it is still
-full, we go on to collect TENURED */
+/* if true, we collecting aging space for the second time, so if it is still
+full, we go on to collect tenured */
 bool collecting_aging_again;
 
 /* in case a generation fills up in the middle of a gc, we jump back
 up to try collecting the next generation. */
 jmp_buf gc_jmp;
 
-gc_stats stats[MAX_GEN_COUNT];
+gc_stats stats[max_gen_count];
 u64 cards_scanned;
 u64 decks_scanned;
 u64 card_scan_time;
@@ -33,10 +33,10 @@ cell last_code_heap_scan;
 bool growing_data_heap;
 data_heap *old_data_heap;
 
-void init_data_gc(void)
+void init_data_gc()
 {
        performing_gc = false;
-       last_code_heap_scan = NURSERY;
+       last_code_heap_scan = data->nursery();
        collecting_aging_again = false;
 }
 
@@ -66,11 +66,11 @@ static bool should_copy_p(object *untagged)
 {
        if(in_zone(newspace,untagged))
                return false;
-       if(collecting_gen == TENURED)
+       if(collecting_gen == data->tenured())
                return true;
-       else if(HAVE_AGING_P && collecting_gen == AGING)
-               return !in_zone(&data->generations[TENURED],untagged);
-       else if(collecting_gen == NURSERY)
+       else if(data->have_aging_p() && collecting_gen == data->aging())
+               return !in_zone(&data->generations[data->tenured()],untagged);
+       else if(collecting_gen == data->nursery())
                return in_zone(&nursery,untagged);
        else
        {
@@ -186,19 +186,19 @@ static void copy_gen_cards(cell gen)
 
        /* if we are collecting the nursery, we care about old->nursery pointers
        but not old->aging pointers */
-       if(collecting_gen == NURSERY)
+       if(collecting_gen == data->nursery())
        {
-               mask = CARD_POINTS_TO_NURSERY;
+               mask = card_points_to_nursery;
 
                /* after the collection, no old->nursery pointers remain
                anywhere, but old->aging pointers might remain in tenured
                space */
-               if(gen == TENURED)
-                       unmask = CARD_POINTS_TO_NURSERY;
+               if(gen == data->tenured())
+                       unmask = card_points_to_nursery;
                /* after the collection, all cards in aging space can be
                cleared */
-               else if(HAVE_AGING_P && gen == AGING)
-                       unmask = CARD_MARK_MASK;
+               else if(data->have_aging_p() && gen == data->aging())
+                       unmask = card_mark_mask;
                else
                {
                        critical_error("bug in copy_gen_cards",gen);
@@ -208,20 +208,20 @@ static void copy_gen_cards(cell gen)
        /* if we are collecting aging space into tenured space, we care about
        all old->nursery and old->aging pointers. no old->aging pointers can
        remain */
-       else if(HAVE_AGING_P && collecting_gen == AGING)
+       else if(data->have_aging_p() && collecting_gen == data->aging())
        {
                if(collecting_aging_again)
                {
-                       mask = CARD_POINTS_TO_AGING;
-                       unmask = CARD_MARK_MASK;
+                       mask = card_points_to_aging;
+                       unmask = card_mark_mask;
                }
                /* after we collect aging space into the aging semispace, no
                old->nursery pointers remain but tenured space might still have
                pointers to aging space. */
                else
                {
-                       mask = CARD_POINTS_TO_AGING;
-                       unmask = CARD_POINTS_TO_NURSERY;
+                       mask = card_points_to_aging;
+                       unmask = card_points_to_nursery;
                }
        }
        else
@@ -244,7 +244,7 @@ static void copy_gen_cards(cell gen)
 
 /* Scan cards in all generations older than the one being collected, copying
 old->new references */
-static void copy_cards(void)
+static void copy_cards()
 {
        u64 start = current_micros();
 
@@ -264,7 +264,7 @@ static void copy_stack_elements(segment *region, cell top)
                copy_handle((cell*)ptr);
 }
 
-static void copy_registered_locals(void)
+static void copy_registered_locals()
 {
        cell scan = gc_locals_region->start;
 
@@ -272,7 +272,7 @@ static void copy_registered_locals(void)
                copy_handle(*(cell **)scan);
 }
 
-static void copy_registered_bignums(void)
+static void copy_registered_bignums()
 {
        cell scan = gc_bignums_region->start;
 
@@ -295,7 +295,7 @@ static void copy_registered_bignums(void)
 
 /* Copy roots over at the start of GC, namely various constants, stacks,
 the user environment and extra roots registered by local_roots.hpp */
-static void copy_roots(void)
+static void copy_roots()
 {
        copy_handle(&T);
        copy_handle(&bignum_zero);
@@ -366,8 +366,8 @@ static cell copy_next_from_aging(cell scan)
        {
                obj++;
 
-               cell tenured_start = data->generations[TENURED].start;
-               cell tenured_end = data->generations[TENURED].end;
+               cell tenured_start = data->generations[data->tenured()].start;
+               cell tenured_end = data->generations[data->tenured()].end;
 
                cell newspace_start = newspace->start;
                cell newspace_end = newspace->end;
@@ -421,17 +421,17 @@ static cell copy_next_from_tenured(cell scan)
 
 void copy_reachable_objects(cell scan, cell *end)
 {
-       if(collecting_gen == NURSERY)
+       if(collecting_gen == data->nursery())
        {
                while(scan < *end)
                        scan = copy_next_from_nursery(scan);
        }
-       else if(HAVE_AGING_P && collecting_gen == AGING)
+       else if(data->have_aging_p() && collecting_gen == data->aging())
        {
                while(scan < *end)
                        scan = copy_next_from_aging(scan);
        }
-       else if(collecting_gen == TENURED)
+       else if(collecting_gen == data->tenured())
        {
                while(scan < *end)
                        scan = copy_next_from_tenured(scan);
@@ -443,12 +443,12 @@ static void begin_gc(cell requested_bytes)
 {
        if(growing_data_heap)
        {
-               if(collecting_gen != TENURED)
+               if(collecting_gen != data->tenured())
                        critical_error("Invalid parameters to begin_gc",0);
 
                old_data_heap = data;
                set_data_heap(grow_data_heap(old_data_heap,requested_bytes));
-               newspace = &data->generations[TENURED];
+               newspace = &data->generations[data->tenured()];
        }
        else if(collecting_accumulation_gen_p())
        {
@@ -491,12 +491,12 @@ static void end_gc(cell gc_elapsed)
        if(collecting_accumulation_gen_p())
        {
                /* all younger generations except are now empty.
-               if collecting_gen == NURSERY here, we only have 1 generation;
+               if collecting_gen == data->nursery() here, we only have 1 generation;
                old-school Cheney collector */
-               if(collecting_gen != NURSERY)
-                       reset_generations(NURSERY,collecting_gen - 1);
+               if(collecting_gen != data->nursery())
+                       reset_generations(data->nursery(),collecting_gen - 1);
        }
-       else if(collecting_gen == NURSERY)
+       else if(collecting_gen == data->nursery())
        {
                nursery.here = nursery.start;
        }
@@ -504,7 +504,7 @@ static void end_gc(cell gc_elapsed)
        {
                /* all generations up to and including the one
                collected are now empty */
-               reset_generations(NURSERY,collecting_gen);
+               reset_generations(data->nursery(),collecting_gen);
        }
 
        collecting_aging_again = false;
@@ -534,17 +534,17 @@ void garbage_collection(cell gen,
        {
                /* We have no older generations we can try collecting, so we
                resort to growing the data heap */
-               if(collecting_gen == TENURED)
+               if(collecting_gen == data->tenured())
                {
                        growing_data_heap = true;
 
                        /* see the comment in unmark_marked() */
                        unmark_marked(&code);
                }
-               /* we try collecting AGING space twice before going on to
-               collect TENURED */
-               else if(HAVE_AGING_P
-                       && collecting_gen == AGING
+               /* we try collecting aging space twice before going on to
+               collect tenured */
+               else if(data->have_aging_p()
+                       && collecting_gen == data->aging()
                        && !collecting_aging_again)
                {
                        collecting_aging_again = true;
@@ -575,7 +575,7 @@ void garbage_collection(cell gen,
        {
                code_heap_scans++;
 
-               if(collecting_gen == TENURED)
+               if(collecting_gen == data->tenured())
                        free_unmarked(&code,(heap_iterator)update_literal_and_word_references);
                else
                        copy_code_heap_roots();
@@ -593,9 +593,9 @@ void garbage_collection(cell gen,
        performing_gc = false;
 }
 
-void gc(void)
+void gc()
 {
-       garbage_collection(TENURED,false,0);
+       garbage_collection(data->tenured(),false,0);
 }
 
 PRIMITIVE(gc)
@@ -610,7 +610,7 @@ PRIMITIVE(gc_stats)
        cell i;
        u64 total_gc_time = 0;
 
-       for(i = 0; i < MAX_GEN_COUNT; i++)
+       for(i = 0; i < max_gen_count; i++)
        {
                gc_stats *s = &stats[i];
                result.add(allot_cell(s->collections));
@@ -633,10 +633,9 @@ PRIMITIVE(gc_stats)
        dpush(result.elements.value());
 }
 
-void clear_gc_stats(void)
+void clear_gc_stats()
 {
-       int i;
-       for(i = 0; i < MAX_GEN_COUNT; i++)
+       for(cell i = 0; i < max_gen_count; i++)
                memset(&stats[i],0,sizeof(gc_stats));
 
        cards_scanned = 0;
@@ -681,9 +680,9 @@ PRIMITIVE(become)
        compile_all_words();
 }
 
-VM_C_API void minor_gc(void)
+VM_C_API void minor_gc()
 {
-       garbage_collection(NURSERY,false,0);
+       garbage_collection(data->nursery(),false,0);
 }
 
 }
index 286917939440513d95d19818cdbdb33c1f55fe95..2d6a1ab897c1b360110da7dc5caee64dbd501903 100755 (executable)
@@ -18,16 +18,16 @@ extern bool collecting_aging_again;
 
 extern cell last_code_heap_scan;
 
-void init_data_gc(void);
+void init_data_gc();
 
-void gc(void);
+void gc();
 
-inline static bool collecting_accumulation_gen_p(void)
+inline static bool collecting_accumulation_gen_p()
 {
-       return ((HAVE_AGING_P
-               && collecting_gen == AGING
+       return ((data->have_aging_p()
+               && collecting_gen == data->aging()
                && !collecting_aging_again)
-               || collecting_gen == TENURED);
+               || collecting_gen == data->tenured());
 }
 
 void copy_handle(cell *handle);
@@ -39,7 +39,7 @@ void garbage_collection(volatile cell gen,
 /* We leave this many bytes free at the top of the nursery so that inline
 allocation (which does not call GC because of possible roots in volatile
 registers) does not run out of memory */
-#define ALLOT_BUFFER_ZONE 1024
+static const cell allot_buffer_zone = 1024;
 
 inline static object *allot_zone(zone *z, cell a)
 {
@@ -63,11 +63,11 @@ inline static object *allot_object(header header, cell size)
 
        object *obj;
 
-       if(nursery.size - ALLOT_BUFFER_ZONE > size)
+       if(nursery.size - allot_buffer_zone > size)
        {
                /* If there is insufficient room, collect the nursery */
-               if(nursery.here + ALLOT_BUFFER_ZONE + size > nursery.end)
-                       garbage_collection(NURSERY,false,0);
+               if(nursery.here + allot_buffer_zone + size > nursery.end)
+                       garbage_collection(data->nursery(),false,0);
 
                cell h = nursery.here;
                nursery.here = h + align8(size);
@@ -77,20 +77,20 @@ inline static object *allot_object(header header, cell size)
        tenured space */
        else
        {
-               zone *tenured = &data->generations[TENURED];
+               zone *tenured = &data->generations[data->tenured()];
 
                /* If tenured space does not have enough room, collect */
                if(tenured->here + size > tenured->end)
                {
                        gc();
-                       tenured = &data->generations[TENURED];
+                       tenured = &data->generations[data->tenured()];
                }
 
                /* If it still won't fit, grow the heap */
                if(tenured->here + size > tenured->end)
                {
-                       garbage_collection(TENURED,true,size);
-                       tenured = &data->generations[TENURED];
+                       garbage_collection(data->tenured(),true,size);
+                       tenured = &data->generations[data->tenured()];
                }
 
                obj = allot_zone(tenured,size);
@@ -114,7 +114,7 @@ void copy_reachable_objects(cell scan, cell *end);
 
 PRIMITIVE(gc);
 PRIMITIVE(gc_stats);
-void clear_gc_stats(void);
+void clear_gc_stats();
 PRIMITIVE(clear_gc_stats);
 PRIMITIVE(become);
 
@@ -143,6 +143,6 @@ inline static void check_tagged_pointer(cell tagged)
 #endif
 }
 
-VM_C_API void minor_gc(void);
+VM_C_API void minor_gc();
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index d83773d..d921d37
@@ -24,12 +24,12 @@ cell init_zone(zone *z, cell size, cell start)
        return z->end;
 }
 
-void init_card_decks(void)
+void init_card_decks()
 {
-       cell start = align(data->seg->start,DECK_SIZE);
-       allot_markers_offset = (cell)data->allot_markers - (start >> CARD_BITS);
-       cards_offset = (cell)data->cards - (start >> CARD_BITS);
-       decks_offset = (cell)data->decks - (start >> DECK_BITS);
+       cell start = align(data->seg->start,deck_size);
+       allot_markers_offset = (cell)data->allot_markers - (start >> card_bits);
+       cards_offset = (cell)data->cards - (start >> card_bits);
+       decks_offset = (cell)data->decks - (start >> deck_bits);
 }
 
 data_heap *alloc_data_heap(cell gens,
@@ -37,9 +37,9 @@ data_heap *alloc_data_heap(cell gens,
        cell aging_size,
        cell tenured_size)
 {
-       young_size = align(young_size,DECK_SIZE);
-       aging_size = align(aging_size,DECK_SIZE);
-       tenured_size = align(tenured_size,DECK_SIZE);
+       young_size = align(young_size,deck_size);
+       aging_size = align(aging_size,deck_size);
+       tenured_size = align(tenured_size,deck_size);
 
        data_heap *data = (data_heap *)safe_malloc(sizeof(data_heap));
        data->young_size = young_size;
@@ -58,42 +58,42 @@ data_heap *alloc_data_heap(cell gens,
                return NULL; /* can't happen */
        }
 
-       total_size += DECK_SIZE;
+       total_size += deck_size;
 
        data->seg = alloc_segment(total_size);
 
        data->generations = (zone *)safe_malloc(sizeof(zone) * data->gen_count);
        data->semispaces = (zone *)safe_malloc(sizeof(zone) * data->gen_count);
 
-       cell cards_size = total_size >> CARD_BITS;
+       cell cards_size = total_size >> card_bits;
        data->allot_markers = (cell *)safe_malloc(cards_size);
        data->allot_markers_end = data->allot_markers + cards_size;
 
        data->cards = (cell *)safe_malloc(cards_size);
        data->cards_end = data->cards + cards_size;
 
-       cell decks_size = total_size >> DECK_BITS;
+       cell decks_size = total_size >> deck_bits;
        data->decks = (cell *)safe_malloc(decks_size);
        data->decks_end = data->decks + decks_size;
 
-       cell alloter = align(data->seg->start,DECK_SIZE);
+       cell alloter = align(data->seg->start,deck_size);
 
-       alloter = init_zone(&data->generations[TENURED],tenured_size,alloter);
-       alloter = init_zone(&data->semispaces[TENURED],tenured_size,alloter);
+       alloter = init_zone(&data->generations[data->tenured()],tenured_size,alloter);
+       alloter = init_zone(&data->semispaces[data->tenured()],tenured_size,alloter);
 
        if(data->gen_count == 3)
        {
-               alloter = init_zone(&data->generations[AGING],aging_size,alloter);
-               alloter = init_zone(&data->semispaces[AGING],aging_size,alloter);
+               alloter = init_zone(&data->generations[data->aging()],aging_size,alloter);
+               alloter = init_zone(&data->semispaces[data->aging()],aging_size,alloter);
        }
 
        if(data->gen_count >= 2)
        {
-               alloter = init_zone(&data->generations[NURSERY],young_size,alloter);
-               alloter = init_zone(&data->semispaces[NURSERY],0,alloter);
+               alloter = init_zone(&data->generations[data->nursery()],young_size,alloter);
+               alloter = init_zone(&data->semispaces[data->nursery()],0,alloter);
        }
 
-       if(data->seg->end - alloter > DECK_SIZE)
+       if(data->seg->end - alloter > deck_size)
                critical_error("Bug in alloc_data_heap",alloter);
 
        return data;
@@ -141,12 +141,12 @@ void clear_allot_markers(cell from, cell to)
        /* NOTE: reverse order due to heap layout. */
        card *first_card = addr_to_allot_marker((object *)data->generations[to].start);
        card *last_card = addr_to_allot_marker((object *)data->generations[from].end);
-       memset(first_card,INVALID_ALLOT_MARKER,last_card - first_card);
+       memset(first_card,invalid_allot_marker,last_card - first_card);
 }
 
 void reset_generation(cell i)
 {
-       zone *z = (i == NURSERY ? &nursery : &data->generations[i]);
+       zone *z = (i == data->nursery() ? &nursery : &data->generations[i]);
 
        z->here = z->start;
        if(secure_gc)
@@ -169,11 +169,11 @@ void reset_generations(cell from, cell to)
 void set_data_heap(data_heap *data_)
 {
        data = data_;
-       nursery = data->generations[NURSERY];
+       nursery = data->generations[data->nursery()];
        init_card_decks();
-       clear_cards(NURSERY,TENURED);
-       clear_decks(NURSERY,TENURED);
-       clear_allot_markers(NURSERY,TENURED);
+       clear_cards(data->nursery(),data->tenured());
+       clear_decks(data->nursery(),data->tenured());
+       clear_allot_markers(data->nursery(),data->tenured());
 }
 
 void init_data_heap(cell gens,
@@ -241,7 +241,7 @@ cell unaligned_object_size(object *pointer)
                return callstack_size(untag_fixnum(((callstack *)pointer)->length));
        default:
                critical_error("Invalid header",(cell)pointer);
-               return -1; /* can't happen */
+               return 0; /* can't happen */
        }
 }
 
@@ -283,7 +283,7 @@ cell binary_payload_start(object *pointer)
                return sizeof(wrapper);
        default:
                critical_error("Invalid header",(cell)pointer);
-               return -1; /* can't happen */
+                return 0; /* can't happen */
        }
 }
 
@@ -298,7 +298,7 @@ PRIMITIVE(data_room)
        cell gen;
        for(gen = 0; gen < data->gen_count; gen++)
        {
-               zone *z = (gen == NURSERY ? &nursery : &data->generations[gen]);
+               zone *z = (gen == data->nursery() ? &nursery : &data->generations[gen]);
                a.add(tag_fixnum((z->end - z->here) >> 10));
                a.add(tag_fixnum((z->size) >> 10));
        }
@@ -312,9 +312,9 @@ references to an object for debugging purposes. */
 cell heap_scan_ptr;
 
 /* Disables GC and activates next-object ( -- obj ) primitive */
-void begin_scan(void)
+void begin_scan()
 {
-       heap_scan_ptr = data->generations[TENURED].start;
+       heap_scan_ptr = data->generations[data->tenured()].start;
        gc_off = true;
 }
 
@@ -323,12 +323,12 @@ PRIMITIVE(begin_scan)
        begin_scan();
 }
 
-cell next_object(void)
+cell next_object()
 {
        if(!gc_off)
                general_error(ERROR_HEAP_SCAN,F,F,NULL);
 
-       if(heap_scan_ptr >= data->generations[TENURED].here)
+       if(heap_scan_ptr >= data->generations[data->tenured()].here)
                return F;
 
        object *obj = (object *)heap_scan_ptr;
@@ -348,7 +348,7 @@ PRIMITIVE(end_scan)
        gc_off = false;
 }
 
-cell find_all_words(void)
+cell find_all_words()
 {
        growable_array words;
 
index bb8b35341ec05d539afad8a8c273d110faddc832..567c8f99441f429b4161c2b9d83f23cbaf72db61 100644 (file)
@@ -34,20 +34,22 @@ struct data_heap {
 
        cell *decks;
        cell *decks_end;
+       
+       /* the 0th generation is where new objects are allocated. */
+       cell nursery() { return 0; }
+       
+       /* where objects hang around */
+       cell aging() { return gen_count - 2; }
+       
+       /* the oldest generation */
+       cell tenured() { return gen_count - 1; }
+       
+       bool have_aging_p() { return gen_count > 2; }
 };
 
 extern data_heap *data;
 
-/* the 0th generation is where new objects are allocated. */
-#define NURSERY 0
-/* where objects hang around */
-#define AGING (data->gen_count-2)
-#define HAVE_AGING_P (data->gen_count>2)
-/* the oldest generation */
-#define TENURED (data->gen_count-1)
-
-#define MIN_GEN_COUNT 1
-#define MAX_GEN_COUNT 3
+static const cell max_gen_count = 3;
 
 inline static bool in_zone(zone *z, object *pointer)
 {
@@ -56,7 +58,7 @@ inline static bool in_zone(zone *z, object *pointer)
 
 cell init_zone(zone *z, cell size, cell base);
 
-void init_card_decks(void);
+void init_card_decks();
 
 data_heap *grow_data_heap(data_heap *data, cell requested_bytes);
 
@@ -86,8 +88,8 @@ cell unaligned_object_size(object *pointer);
 cell binary_payload_start(object *pointer);
 cell object_size(cell tagged);
 
-void begin_scan(void);
-cell next_object(void);
+void begin_scan();
+cell next_object();
 
 PRIMITIVE(data_room);
 PRIMITIVE(size);
@@ -99,7 +101,7 @@ PRIMITIVE(end_scan);
 /* GC is off during heap walking */
 extern bool gc_off;
 
-cell find_all_words(void);
+cell find_all_words();
 
 /* Every object has a regular representation in the runtime, which makes GC
 much simpler. Every slot of the object until binary_payload_start is a pointer
index 3cd05711ad595015f206da1db2458ea7dbe77a0f..49fdd925413bbeadd6d32342e44903b892c45dc1 100755 (executable)
@@ -155,13 +155,13 @@ void print_objects(cell *start, cell *end)
        }
 }
 
-void print_datastack(void)
+void print_datastack()
 {
        print_string("==== DATA STACK:\n");
        print_objects((cell *)ds_bot,(cell *)ds);
 }
 
-void print_retainstack(void)
+void print_retainstack()
 {
        print_string("==== RETAIN STACK:\n");
        print_objects((cell *)rs_bot,(cell *)rs);
@@ -179,7 +179,7 @@ void print_stack_frame(stack_frame *frame)
        print_string("\n");
 }
 
-void print_callstack(void)
+void print_callstack()
 {
        print_string("==== CALL STACK:\n");
        cell bottom = (cell)stack_chain->callstack_bottom;
@@ -210,7 +210,7 @@ void dump_zone(zone *z)
        print_string(", here="); print_cell(z->here - z->start); nl();
 }
 
-void dump_generations(void)
+void dump_generations()
 {
        cell i;
 
@@ -285,7 +285,7 @@ void find_data_references(cell look_for_)
 }
 
 /* Dump all code blocks for debugging */
-void dump_code_heap(void)
+void dump_code_heap()
 {
        cell reloc_size = 0, literal_size = 0;
 
@@ -325,7 +325,7 @@ void dump_code_heap(void)
        print_cell(literal_size); print_string(" bytes of literal data\n");
 }
 
-void factorbug(void)
+void factorbug()
 {
        if(fep_disabled)
        {
index 81874bf2acc7707b7f5897242ee7048198c553b9..cb84c9256c3e5f717e53aeb800e48daea9f1bdb0 100755 (executable)
@@ -3,8 +3,8 @@ namespace factor
 
 void print_obj(cell obj);
 void print_nested_obj(cell obj, fixnum nesting);
-void dump_generations(void);
-void factorbug(void);
+void dump_generations();
+void factorbug();
 void dump_zone(zone *z);
 
 PRIMITIVE(die);
old mode 100644 (file)
new mode 100755 (executable)
index bbcf20c..4a14117
@@ -8,15 +8,14 @@ cell megamorphic_cache_misses;
 
 static cell search_lookup_alist(cell table, cell klass)
 {
-       array *pairs = untag<array>(table);
-       fixnum index = array_capacity(pairs) - 1;
+       array *elements = untag<array>(table);
+       fixnum index = array_capacity(elements) - 2;
        while(index >= 0)
        {
-               array *pair = untag<array>(array_nth(pairs,index));
-               if(array_nth(pair,0) == klass)
-                       return array_nth(pair,1);
+               if(array_nth(elements,index) == klass)
+                       return array_nth(elements,index + 1);
                else
-                       index--;
+                       index -= 2;
        }
 
        return F;
@@ -103,7 +102,7 @@ static cell lookup_hairy_method(cell obj, cell methods)
                        break;
                default:
                        critical_error("Bad methods array",methods);
-                       return -1;
+                       return 0;
                }
        }
 }
index f5648c7ebeab000eac1b13d33d69f4aad7f6c984..75368191a775c5e1aac7721ac332860719dc3094 100644 (file)
@@ -1,6 +1,9 @@
 namespace factor
 {
 
+extern cell megamorphic_cache_hits;
+extern cell megamorphic_cache_misses;
+
 cell lookup_method(cell object, cell methods);
 PRIMITIVE(lookup_method);
 
index f2ba3552930f3b3ffe7be57573e125c44a979e75..610482f5762134ee140a7889911611c6658d71b8 100755 (executable)
@@ -9,7 +9,7 @@ cell signal_number;
 cell signal_fault_addr;
 stack_frame *signal_callstack_top;
 
-void out_of_memory(void)
+void out_of_memory()
 {
        print_string("Out of memory\n\n");
        dump_generations();
@@ -88,7 +88,7 @@ void type_error(cell type, cell tagged)
        general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
 }
 
-void not_implemented_error(void)
+void not_implemented_error()
 {
        general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
 }
@@ -125,7 +125,7 @@ void signal_error(int signal, stack_frame *native_stack)
        general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
 }
 
-void divide_by_zero_error(void)
+void divide_by_zero_error()
 {
        general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
 }
@@ -141,12 +141,12 @@ PRIMITIVE(unimplemented)
        not_implemented_error();
 }
 
-void memory_signal_handler_impl(void)
+void memory_signal_handler_impl()
 {
        memory_protection_error(signal_fault_addr,signal_callstack_top);
 }
 
-void misc_signal_handler_impl(void)
+void misc_signal_handler_impl()
 {
        signal_error(signal_number,signal_callstack_top);
 }
index e5968468a5349120133d9ac8782f91a4a4d5fc5e..11180508e5c840121ed527e78b69c121bd4f109d 100755 (executable)
@@ -22,7 +22,7 @@ enum vm_error_type
        ERROR_MEMORY,
 };
 
-void out_of_memory(void);
+void out_of_memory();
 void fatal_error(const char* msg, cell tagged);
 void critical_error(const char* msg, cell tagged);
 
@@ -30,11 +30,11 @@ PRIMITIVE(die);
 
 void throw_error(cell error, stack_frame *native_stack);
 void general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *native_stack);
-void divide_by_zero_error(void);
+void divide_by_zero_error();
 void memory_protection_error(cell addr, stack_frame *native_stack);
 void signal_error(int signal, stack_frame *native_stack);
 void type_error(cell type, cell tagged);
-void not_implemented_error(void);
+void not_implemented_error();
 
 PRIMITIVE(call_clear);
 PRIMITIVE(unimplemented);
@@ -45,7 +45,7 @@ extern cell signal_number;
 extern cell signal_fault_addr;
 extern stack_frame *signal_callstack_top;
 
-void memory_signal_handler_impl(void);
-void misc_signal_handler_impl(void);
+void memory_signal_handler_impl();
+void misc_signal_handler_impl();
 
 }
index b607adba6303d24c83b81a5c39c41f459a4a5845..33d8b73dfeca18ab75b0cfd749033cacbd8e343e 100755 (executable)
@@ -81,7 +81,7 @@ VM_C_API void init_parameters_from_args(vm_parameters *p, int argc, vm_char **ar
 }
 
 /* Do some initialization that we do once only */
-static void do_stage1_init(void)
+static void do_stage1_init()
 {
        print_string("*** Stage 2 early init... ");
        fflush(stdout);
@@ -134,7 +134,7 @@ VM_C_API void init_factor(vm_parameters *p)
 
        userenv[CPU_ENV] = allot_alien(F,(cell)FACTOR_CPU_STRING);
        userenv[OS_ENV] = allot_alien(F,(cell)FACTOR_OS_STRING);
-       userenv[cell_SIZE_ENV] = tag_fixnum(sizeof(cell));
+       userenv[CELL_SIZE_ENV] = tag_fixnum(sizeof(cell));
        userenv[EXECUTABLE_ENV] = allot_alien(F,(cell)p->executable_path);
        userenv[ARGS_ENV] = F;
        userenv[EMBEDDED_ENV] = F;
@@ -198,9 +198,9 @@ VM_C_API void factor_eval_free(char *result)
        free(result);
 }
 
-VM_C_API void factor_yield(void)
+VM_C_API void factor_yield()
 {
-       void (*callback)(void) = (void (*)(void))alien_offset(userenv[YIELD_CALLBACK_ENV]);
+       void (*callback)() = (void (*)())alien_offset(userenv[YIELD_CALLBACK_ENV]);
        callback();
 }
 
index e9ba920e9f471d43d8ee1b77312cf3e873735db7..6e00bc012e32122a291cd05845ce6f75b09949e5 100644 (file)
@@ -10,7 +10,7 @@ VM_C_API void start_standalone_factor(int argc, vm_char **argv);
 
 VM_C_API char *factor_eval_string(char *string);
 VM_C_API void factor_eval_free(char *result);
-VM_C_API void factor_yield(void);
+VM_C_API void factor_yield();
 VM_C_API void factor_sleep(long ms);
 
 }
index 680b1441402cb12a969c69ab9cd557a4bcfee2b4..d45ceb45149af4d3b2842e9d6704dc695d9f1eb6 100755 (executable)
@@ -319,3 +319,8 @@ _Complex float ffi_test_47(_Complex float x, _Complex double y)
 {
        return x + 2 * y;
 }
+
+short ffi_test_48(struct bool_field_test x)
+{
+       return x.parents;
+}
index 835f9e942fcdd2951b165abd8df8ab889cb96eb4..af0c0b46a4b7051ee782965c8218be28a0f01802 100755 (executable)
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
 #if defined(i386) || defined(__i386) || defined(__i386__) || defined(WIN32)
        #define F_STDCALL __attribute__((stdcall))
 #else
@@ -102,3 +104,11 @@ F_EXPORT _Complex float ffi_test_45(int x);
 F_EXPORT _Complex double ffi_test_46(int x);
 
 F_EXPORT _Complex float ffi_test_47(_Complex float x, _Complex double y);
+
+struct bool_field_test {
+       char *name;
+       bool on;
+       short parents;
+};
+
+F_EXPORT short ffi_test_48(struct bool_field_test x);
index 2aa7727136a2711ada3973271ea2cb486159e309..9205aad260d3e64dce50e55ab6f096e5833ddc93 100755 (executable)
@@ -31,7 +31,7 @@ static void load_data_heap(FILE *file, image_header *h, vm_parameters *p)
 
        clear_gc_stats();
 
-       zone *tenured = &data->generations[TENURED];
+       zone *tenured = &data->generations[data->tenured()];
 
        fixnum bytes_read = fread((void*)tenured->start,1,h->data_size,file);
 
@@ -92,10 +92,10 @@ bool save_image(const vm_char *filename)
                return false;
        }
 
-       zone *tenured = &data->generations[TENURED];
+       zone *tenured = &data->generations[data->tenured()];
 
-       h.magic = IMAGE_MAGIC;
-       h.version = IMAGE_VERSION;
+       h.magic = image_magic;
+       h.version = image_version;
        h.data_relocation_base = tenured->start;
        h.data_size = tenured->here - tenured->start;
        h.code_relocation_base = code.seg->start;
@@ -106,14 +106,8 @@ bool save_image(const vm_char *filename)
        h.bignum_pos_one = bignum_pos_one;
        h.bignum_neg_one = bignum_neg_one;
 
-       cell i;
-       for(i = 0; i < USER_ENV; i++)
-       {
-               if(i < FIRST_SAVE_ENV)
-                       h.userenv[i] = F;
-               else
-                       h.userenv[i] = userenv[i];
-       }
+       for(cell i = 0; i < USER_ENV; i++)
+               h.userenv[i] = (save_env_p(i) ? userenv[i] : F);
 
        bool ok = true;
 
@@ -149,12 +143,10 @@ PRIMITIVE(save_image_and_exit)
        path.untag_check();
 
        /* strip out userenv data which is set on startup anyway */
-       cell i;
-       for(i = 0; i < FIRST_SAVE_ENV; i++)
-               userenv[i] = F;
-
-       for(i = LAST_SAVE_ENV + 1; i < STACK_TRACES_ENV; i++)
-               userenv[i] = F;
+       for(cell i = 0; i < USER_ENV; i++)
+       {
+               if(!save_env_p(i)) userenv[i] = F;
+       }
 
        /* do a full GC + code heap compaction */
        performing_compaction = true;
@@ -173,7 +165,7 @@ static void data_fixup(cell *cell)
        if(immediate_p(*cell))
                return;
 
-       zone *tenured = &data->generations[TENURED];
+       zone *tenured = &data->generations[data->tenured()];
        *cell += (tenured->start - data_relocation_base);
 }
 
@@ -279,7 +271,7 @@ void relocate_data()
        data_fixup(&bignum_pos_one);
        data_fixup(&bignum_neg_one);
 
-       zone *tenured = &data->generations[TENURED];
+       zone *tenured = &data->generations[data->tenured()];
 
        for(relocating = tenured->start;
                relocating < tenured->here;
@@ -321,10 +313,10 @@ void load_image(vm_parameters *p)
        if(fread(&h,sizeof(image_header),1,file) != 1)
                fatal_error("Cannot read image header",0);
 
-       if(h.magic != IMAGE_MAGIC)
+       if(h.magic != image_magic)
                fatal_error("Bad image: magic number check failed",h.magic);
 
-       if(h.version != IMAGE_VERSION)
+       if(h.version != image_version)
                fatal_error("Bad image: version number check failed",h.version);
        
        load_data_heap(file,&h,p);
index c306f322def61510976ca687ce52e8742eb75e5d..807a7a6bcf5dea1dedb5ddc51faf11c1832b726f 100755 (executable)
@@ -1,8 +1,8 @@
 namespace factor
 {
 
-#define IMAGE_MAGIC 0x0f0e0d0c
-#define IMAGE_VERSION 4
+static const cell image_magic = 0x0f0e0d0c;
+static const cell image_version = 4;
 
 struct image_header {
        cell magic;
old mode 100644 (file)
new mode 100755 (executable)
index 5d9fbf0..e9e098d
@@ -21,8 +21,10 @@ void deallocate_inline_cache(cell return_address)
 {
        /* Find the call target. */
        void *old_xt = get_call_target(return_address);
+       check_code_pointer((cell)old_xt);
+
        code_block *old_block = (code_block *)old_xt - 1;
-       cell old_type = old_block->block.type;
+       cell old_type = old_block->type;
 
 #ifdef FACTOR_DEBUG
        /* The call target was either another PIC,
@@ -31,7 +33,7 @@ void deallocate_inline_cache(cell return_address)
 #endif
 
        if(old_type == PIC_TYPE)
-               heap_free(&code,&old_block->block);
+               heap_free(&code,old_block);
 }
 
 /* Figure out what kind of type check the PIC needs based on the methods
@@ -70,7 +72,7 @@ static cell determine_inline_cache_type(array *cache_entries)
        if(!seen_hi_tag && !seen_tuple) return PIC_TAG;
 
        critical_error("Oops",0);
-       return -1;
+       return 0;
 }
 
 static void update_pic_count(cell type)
@@ -84,7 +86,11 @@ struct inline_cache_jit : public jit {
        inline_cache_jit(cell generic_word_) : jit(PIC_TYPE,generic_word_) {};
 
        void emit_check(cell klass);
-       void compile_inline_cache(fixnum index, cell generic_word_, cell methods_, cell cache_entries_);
+       void compile_inline_cache(fixnum index,
+                                 cell generic_word_,
+                                 cell methods_,
+                                 cell cache_entries_,
+                                 bool tail_call_p);
 };
 
 void inline_cache_jit::emit_check(cell klass)
@@ -100,7 +106,11 @@ void inline_cache_jit::emit_check(cell klass)
 
 /* index: 0 = top of stack, 1 = item underneath, etc
    cache_entries: array of class/method pairs */
-void inline_cache_jit::compile_inline_cache(fixnum index, cell generic_word_, cell methods_, cell cache_entries_)
+void inline_cache_jit::compile_inline_cache(fixnum index,
+                                           cell generic_word_,
+                                           cell methods_,
+                                           cell cache_entries_,
+                                           bool tail_call_p)
 {
        gc_root<word> generic_word(generic_word_);
        gc_root<array> methods(methods_);
@@ -134,20 +144,25 @@ void inline_cache_jit::compile_inline_cache(fixnum index, cell generic_word_, ce
        push(methods.value());
        push(tag_fixnum(index));
        push(cache_entries.value());
-       word_jump(userenv[PIC_MISS_WORD]);
+       word_special(userenv[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
 }
 
 static code_block *compile_inline_cache(fixnum index,
-                                         cell generic_word_,
-                                         cell methods_,
-                                         cell cache_entries_)
+                                       cell generic_word_,
+                                       cell methods_,
+                                       cell cache_entries_,
+                                       bool tail_call_p)
 {
        gc_root<word> generic_word(generic_word_);
        gc_root<array> methods(methods_);
        gc_root<array> cache_entries(cache_entries_);
 
        inline_cache_jit jit(generic_word.value());
-       jit.compile_inline_cache(index,generic_word.value(),methods.value(),cache_entries.value());
+       jit.compile_inline_cache(index,
+                                generic_word.value(),
+                                methods.value(),
+                                cache_entries.value(),
+                                tail_call_p);
        code_block *code = jit.to_code_block();
        relocate_code_block(code);
        return code;
@@ -225,14 +240,18 @@ void *inline_cache_miss(cell return_address)
                xt = compile_inline_cache(index,
                                          generic_word.value(),
                                          methods.value(),
-                                         new_cache_entries.value()) + 1;
+                                         new_cache_entries.value(),
+                                         tail_call_site_p(return_address))->xt();
        }
 
        /* Install the new stub. */
        set_call_target(return_address,xt);
 
 #ifdef PIC_DEBUG
-       printf("Updated call site 0x%lx with 0x%lx\n",return_address,(cell)xt);
+       printf("Updated %s call site 0x%lx with 0x%lx\n",
+              tail_call_site_p(return_address) ? "tail" : "non-tail",
+              return_address,
+              (cell)xt);
 #endif
 
        return xt;
index 84334efc78ccfc8ab5db637f40e6ae32dea08c6a..e2a6ae8cf931edb1e8b0fd5f98bf01a8550d5765 100644 (file)
@@ -8,7 +8,8 @@ void init_inline_caching(int max_size);
 PRIMITIVE(reset_inline_cache_stats);
 PRIMITIVE(inline_cache_stats);
 PRIMITIVE(inline_cache_miss);
+PRIMITIVE(inline_cache_miss_tail);
 
-extern "C" void *inline_cache_miss(cell return_address);
+VM_C_API void *inline_cache_miss(cell return_address);
 
 }
index 2d6c94faf0ce0444515c02a771961c1c4fc1516f..5bb58346916a397160adff397f45562f772870a9 100755 (executable)
--- a/vm/io.cpp
+++ b/vm/io.cpp
@@ -14,14 +14,14 @@ The Factor library provides platform-specific code for Unix and Windows
 with many more capabilities so these words are not usually used in
 normal operation. */
 
-void init_c_io(void)
+void init_c_io()
 {
        userenv[STDIN_ENV] = allot_alien(F,(cell)stdin);
        userenv[STDOUT_ENV] = allot_alien(F,(cell)stdout);
        userenv[STDERR_ENV] = allot_alien(F,(cell)stderr);
 }
 
-void io_error(void)
+void io_error()
 {
 #ifndef WINCE
        if(errno == EINTR)
@@ -216,12 +216,12 @@ PRIMITIVE(fclose)
 /* This function is used by FFI I/O. Accessing the errno global directly is
 not portable, since on some libc's errno is not a global but a funky macro that
 reads thread-local storage. */
-VM_C_API int err_no(void)
+VM_C_API int err_no()
 {
        return errno;
 }
 
-VM_C_API void clear_err_no(void)
+VM_C_API void clear_err_no()
 {
        errno = 0;
 }
index 968e96f0b52dbecf6a4158efe0a6b4cedff77551..d94d6402d9c9c9d66d090734b3e533fc585a1ac5 100755 (executable)
--- a/vm/io.hpp
+++ b/vm/io.hpp
@@ -1,8 +1,8 @@
 namespace factor
 {
 
-void init_c_io(void);
-void io_error(void);
+void init_c_io();
+void io_error();
 
 PRIMITIVE(fopen);
 PRIMITIVE(fgetc);
@@ -18,7 +18,7 @@ PRIMITIVE(open_file);
 PRIMITIVE(existsp);
 PRIMITIVE(read_dir);
 
-VM_C_API int err_no(void);
-VM_C_API void clear_err_no(void);
+VM_C_API int err_no();
+VM_C_API void clear_err_no();
 
 }
index bb86506058e43f959130eae6746b1d752e8a8911..a3f222a9534217be167da8d851683b0f558d7828 100644 (file)
@@ -23,24 +23,21 @@ jit::jit(cell type_, cell owner_)
        if(stack_traces_p()) literal(owner.value());
 }
 
-relocation_entry jit::rel_to_emit(cell code_template, bool *rel_p)
+void jit::emit_relocation(cell code_template_)
 {
-       array *quadruple = untag<array>(code_template);
-       cell rel_class = array_nth(quadruple,1);
-       cell rel_type = array_nth(quadruple,2);
-       cell offset = array_nth(quadruple,3);
-
-       if(rel_class == F)
-       {
-               *rel_p = false;
-               return 0;
-       }
-       else
+       gc_root<array> code_template(code_template_);
+       cell capacity = array_capacity(code_template.untagged());
+       for(cell i = 1; i < capacity; i += 3)
        {
-               *rel_p = true;
-               return (untag_fixnum(rel_type) << 28)
+               cell rel_class = array_nth(code_template.untagged(),i);
+               cell rel_type = array_nth(code_template.untagged(),i + 1);
+               cell offset = array_nth(code_template.untagged(),i + 2);
+
+               relocation_entry new_entry
+                       = (untag_fixnum(rel_type) << 28)
                        | (untag_fixnum(rel_class) << 24)
                        | ((code.count + untag_fixnum(offset)));
+               relocation.append_bytes(&new_entry,sizeof(relocation_entry));
        }
 }
 
@@ -49,9 +46,7 @@ void jit::emit(cell code_template_)
 {
        gc_root<array> code_template(code_template_);
 
-       bool rel_p;
-       relocation_entry rel = rel_to_emit(code_template.value(),&rel_p);
-       if(rel_p) relocation.append_bytes(&rel,sizeof(relocation_entry));
+       emit_relocation(code_template.value());
 
        gc_root<byte_array> insns(array_nth(code_template.untagged(),0));
 
index 30b5163b4ac05d0f9f2a8114364d09766de36622..50b40eca30d23a40f98b7ffe3769d40bf96ba248 100644 (file)
@@ -14,7 +14,7 @@ struct jit {
        jit(cell jit_type, cell owner);
        void compute_position(cell offset);
 
-       relocation_entry rel_to_emit(cell code_template, bool *rel_p);
+       void emit_relocation(cell code_template);
        void emit(cell code_template);
 
        void literal(cell literal) { literals.add(literal); }
@@ -25,17 +25,23 @@ struct jit {
        }
 
        void word_jump(cell word) {
-               emit_with(userenv[JIT_WORD_JUMP],word);
+               literal(tag_fixnum(xt_tail_pic_offset));
+               literal(word);
+               emit(userenv[JIT_WORD_JUMP]);
        }
 
        void word_call(cell word) {
                emit_with(userenv[JIT_WORD_CALL],word);
        }
 
+       void word_special(cell word) {
+               emit_with(userenv[JIT_WORD_SPECIAL],word);
+       }
+
        void emit_subprimitive(cell word_) {
                gc_root<word> word(word_);
                gc_root<array> code_template(word->subprimitive);
-               if(array_nth(code_template.untagged(),1) != F) literal(T);
+               if(array_capacity(code_template.untagged()) > 1) literal(T);
                emit(code_template.value());
        }
 
index 4928fda632114b9fbc60a403fd49d6ea56422c25..40fd699e18d024eb2a123a796ea10cfa3691b521 100755 (executable)
@@ -23,8 +23,10 @@ inline static cell align(cell a, cell b)
        return (a + (b-1)) & ~(b-1);
 }
 
-#define align8(a) align(a,8)
-#define align_page(a) align(a,getpagesize())
+inline static cell align8(cell a)
+{
+       return align(a,8);
+}
 
 #define WORD_SIZE (signed)(sizeof(cell)*8)
 
@@ -93,6 +95,9 @@ class object;
 struct header {
        cell value;
 
+        /* Default ctor to make gcc 3.x happy */
+        header() { abort(); }
+
        header(cell value_) : value(value_ << TAG_BITS) {}
 
        void check_header() {
@@ -193,26 +198,19 @@ struct heap_block
        unsigned char status; /* free or allocated? */
        unsigned char type; /* this is WORD_TYPE or QUOTATION_TYPE */
        unsigned char last_scan; /* the youngest generation in which this block's literals may live */
-       char needs_fixup; /* is this a new block that needs full fixup? */
+       unsigned char needs_fixup; /* is this a new block that needs full fixup? */
 
        /* In bytes, includes this header */
        cell size;
-
-       /* Used during compaction */
-       heap_block *forwarding;
 };
 
-struct free_heap_block
+struct free_heap_block : public heap_block
 {
-       heap_block block;
-
-       /* Filled in on image load */
         free_heap_block *next_free;
 };
 
-struct code_block
+struct code_block : public heap_block
 {
-       heap_block block;
        cell literals; /* # bytes */
        cell relocation; /* tagged pointer to byte-array or f */
        
@@ -233,7 +231,9 @@ struct word : public object {
        /* TAGGED property assoc for library code */
        cell props;
        /* TAGGED alternative entry point for direct non-tail calls. Used for inline caching */
-       cell direct_entry_def;
+       cell pic_def;
+       /* TAGGED alternative entry point for direct tail calls. Used for inline caching */
+       cell pic_tail_def;
        /* TAGGED call count for profiling */
        cell counter;
        /* TAGGED machine code for sub-primitive */
@@ -299,12 +299,6 @@ struct dll : public object {
        void *dll;
 };
 
-struct callstack : public object {
-       static const cell type_number = CALLSTACK_TYPE;
-       /* tagged */
-       cell length;
-};
-
 struct stack_frame
 {
        void *xt;
@@ -312,6 +306,15 @@ struct stack_frame
        cell size;
 };
 
+struct callstack : public object {
+       static const cell type_number = CALLSTACK_TYPE;
+       /* tagged */
+       cell length;
+       
+       stack_frame *top() { return (stack_frame *)(this + 1); }
+       stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
+};
+
 struct tuple : public object {
        static const cell type_number = TUPLE_TYPE;
        /* tagged layout */
index f752c3cb8f7593986fca3a4229359fbc1d42f7be..03edf862a80efea0d20bd0dd1f4b2796e0667881 100644 (file)
@@ -169,7 +169,7 @@ mach_exception_thread (void *arg)
 }
 
 /* Initialize the Mach exception handler thread. */
-void mach_initialize (void)
+void mach_initialize ()
 {
        mach_port_t self;
        exception_mask_t mask;
index 5dd344c080b51804a1a922ef4d7ed4926935dbb0..a2ef07b0ec7bf444dc50edf39a8849e48702515a 100644 (file)
@@ -79,6 +79,6 @@ catch_exception_raise_state_identity (mach_port_t exception_port,
 namespace factor
 {
 
-void mach_initialize (void);
+void mach_initialize ();
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index fa7d7fa..6164c9e
@@ -9,6 +9,7 @@
 #include <assert.h>
 #endif
 
+/* C headers */
 #include <fcntl.h>
 #include <limits.h>
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <unistd.h>
 #include <sys/param.h>
 
+/* C++ headers */
+#if __GNUC__ == 4
+        #include <tr1/unordered_map>
+        #define unordered_map std::tr1::unordered_map
+#elif __GNUC__ == 3
+        #include <boost/unordered_map.hpp>
+        #define unordered_map boost::unordered_map
+#else
+        #error Factor requires GCC 3.x or later
+#endif
+
+/* Factor headers */
 #include "layouts.hpp"
 #include "platform.hpp"
 #include "primitives.hpp"
old mode 100644 (file)
new mode 100755 (executable)
index 57d5e4a..eff129a
@@ -24,8 +24,8 @@ PRIMITIVE(fixnum_divint)
        fixnum y = untag_fixnum(dpop()); \
        fixnum x = untag_fixnum(dpeek());
        fixnum result = x / y;
-       if(result == -FIXNUM_MIN)
-               drepl(allot_integer(-FIXNUM_MIN));
+       if(result == -fixnum_min)
+               drepl(allot_integer(-fixnum_min));
        else
                drepl(tag_fixnum(result));
 }
@@ -34,9 +34,9 @@ PRIMITIVE(fixnum_divmod)
 {
        cell y = ((cell *)ds)[0];
        cell x = ((cell *)ds)[-1];
-       if(y == tag_fixnum(-1) && x == tag_fixnum(FIXNUM_MIN))
+       if(y == tag_fixnum(-1) && x == tag_fixnum(fixnum_min))
        {
-               ((cell *)ds)[-1] = allot_integer(-FIXNUM_MIN);
+               ((cell *)ds)[-1] = allot_integer(-fixnum_min);
                ((cell *)ds)[0] = tag_fixnum(0);
        }
        else
@@ -50,9 +50,20 @@ 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 SIGN_MASK(x) ((x) >> (WORD_SIZE - 1))
-#define BRANCHLESS_MAX(x,y) ((x) - (((x) - (y)) & SIGN_MASK((x) - (y))))
-#define BRANCHLESS_ABS(x) ((x ^ SIGN_MASK(x)) - SIGN_MASK(x))
+static inline fixnum sign_mask(fixnum x)
+{
+       return x >> (WORD_SIZE - 1);
+}
+
+static inline fixnum branchless_max(fixnum x, fixnum y)
+{
+       return (x - ((x - y) & sign_mask(x - y)));
+}
+
+static inline fixnum branchless_abs(fixnum x)
+{
+       return (x ^ sign_mask(x)) - sign_mask(x);
+}
 
 PRIMITIVE(fixnum_shift)
 {
@@ -63,14 +74,14 @@ PRIMITIVE(fixnum_shift)
                return;
        else if(y < 0)
        {
-               y = BRANCHLESS_MAX(y,-WORD_SIZE + 1);
+               y = branchless_max(y,-WORD_SIZE + 1);
                drepl(tag_fixnum(x >> -y));
                return;
        }
        else if(y < WORD_SIZE - TAG_BITS)
        {
                fixnum mask = -((fixnum)1 << (WORD_SIZE - 1 - TAG_BITS - y));
-               if(!(BRANCHLESS_ABS(x) & mask))
+               if(!(branchless_abs(x) & mask))
                {
                        drepl(tag_fixnum(x << y));
                        return;
@@ -219,14 +230,14 @@ PRIMITIVE(byte_array_to_bignum)
        drepl(tag<bignum>(result));
 }
 
-cell unbox_array_size(void)
+cell unbox_array_size()
 {
        switch(tagged<object>(dpeek()).type())
        {
        case FIXNUM_TYPE:
                {
                        fixnum n = untag_fixnum(dpeek());
-                       if(n >= 0 && n < (fixnum)ARRAY_SIZE_MAX)
+                       if(n >= 0 && n < (fixnum)array_size_max)
                        {
                                dpop();
                                return n;
@@ -236,7 +247,7 @@ cell unbox_array_size(void)
        case BIGNUM_TYPE:
                {
                        bignum * zero = untag<bignum>(bignum_zero);
-                       bignum * max = cell_to_bignum(ARRAY_SIZE_MAX);
+                       bignum * max = cell_to_bignum(array_size_max);
                        bignum * n = untag<bignum>(dpeek());
                        if(bignum_compare(n,zero) != bignum_comparison_less
                                && bignum_compare(n,max) == bignum_comparison_less)
@@ -248,7 +259,7 @@ cell unbox_array_size(void)
                }
        }
 
-       general_error(ERROR_ARRAY_SIZE,dpop(),tag_fixnum(ARRAY_SIZE_MAX),NULL);
+       general_error(ERROR_ARRAY_SIZE,dpop(),tag_fixnum(array_size_max),NULL);
        return 0; /* can't happen */
 }
 
@@ -377,7 +388,7 @@ VM_C_API fixnum to_fixnum(cell tagged)
                return bignum_to_fixnum(untag<bignum>(tagged));
        default:
                type_error(FIXNUM_TYPE,tagged);
-               return -1; /* can't happen */
+               return 0; /* can't happen */
        }
 }
 
@@ -428,7 +439,7 @@ VM_C_API void box_unsigned_cell(cell cell)
 
 VM_C_API void box_signed_8(s64 n)
 {
-       if(n < FIXNUM_MIN || n > FIXNUM_MAX)
+       if(n < fixnum_min || n > fixnum_max)
                dpush(tag<bignum>(long_long_to_bignum(n)));
        else
                dpush(tag_fixnum(n));
@@ -444,13 +455,13 @@ VM_C_API s64 to_signed_8(cell obj)
                return bignum_to_long_long(untag<bignum>(obj));
        default:
                type_error(BIGNUM_TYPE,obj);
-               return -1;
+               return 0;
        }
 }
 
 VM_C_API void box_unsigned_8(u64 n)
 {
-       if(n > FIXNUM_MAX)
+       if(n > (u64)fixnum_max)
                dpush(tag<bignum>(ulong_long_to_bignum(n)));
        else
                dpush(tag_fixnum(n));
@@ -466,7 +477,7 @@ VM_C_API u64 to_unsigned_8(cell obj)
                return bignum_to_ulong_long(untag<bignum>(obj));
        default:
                type_error(BIGNUM_TYPE,obj);
-               return -1;
+               return 0;
        }
 }
 
index 763ed55f9afbb77ff4be7ff23d2e2414dacdf4c3..7828aa3e6c8905c5b47a8d8a1c7293ca60345442 100644 (file)
@@ -5,10 +5,9 @@ extern cell bignum_zero;
 extern cell bignum_pos_one;
 extern cell bignum_neg_one;
 
-#define cell_MAX (cell)(-1)
-#define FIXNUM_MAX (((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)) - 1)
-#define FIXNUM_MIN (-((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)))
-#define ARRAY_SIZE_MAX ((cell)1 << (WORD_SIZE - TAG_BITS - 2))
+static const fixnum fixnum_max = (((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)) - 1);
+static const fixnum fixnum_min = (-((fixnum)1 << (WORD_SIZE - TAG_BITS - 1)));
+static const fixnum array_size_max = ((cell)1 << (WORD_SIZE - TAG_BITS - 2));
 
 PRIMITIVE(fixnum_add);
 PRIMITIVE(fixnum_subtract);
@@ -45,7 +44,7 @@ PRIMITIVE(byte_array_to_bignum);
 
 inline static cell allot_integer(fixnum x)
 {
-       if(x < FIXNUM_MIN || x > FIXNUM_MAX)
+       if(x < fixnum_min || x > fixnum_max)
                return tag<bignum>(fixnum_to_bignum(x));
        else
                return tag_fixnum(x);
@@ -53,13 +52,13 @@ inline static cell allot_integer(fixnum x)
 
 inline static cell allot_cell(cell x)
 {
-       if(x > (cell)FIXNUM_MAX)
+       if(x > (cell)fixnum_max)
                return tag<bignum>(cell_to_bignum(x));
        else
                return tag_fixnum(x);
 }
 
-cell unbox_array_size(void);
+cell unbox_array_size();
 
 inline static double untag_float(cell tagged)
 {
index 63313f61e019509aa99e1a101c725b5e5d8dc351..d259658284bf649318f6765b57b9885b4226f48a 100644 (file)
@@ -4,7 +4,7 @@ namespace factor
 {
 
 /* From SBCL */
-const char *vm_executable_path(void)
+const char *vm_executable_path()
 {
        char path[PATH_MAX + 1];
 
index 0acf537d459ed96c1914f4a31e13ee57ec0cd1cd..7797a7199b9c44545aaf43e8e112a923fec5711e 100644 (file)
@@ -1,7 +1,7 @@
 #include <osreldate.h>
 #include <sys/sysctl.h>
 
-extern "C" int getosreldate(void);
+extern "C" int getosreldate();
 
 #ifndef KERN_PROC_PATHNAME
 #define KERN_PROC_PATHNAME 12
index 731527d20886c875f0103aa5975953c981750bac..6cca455eb747381b0e2d6d7c6763861f51c3b0aa 100755 (executable)
@@ -8,17 +8,17 @@ void c_to_factor_toplevel(cell quot)
        c_to_factor(quot);
 }
 
-void init_signals(void)
+void init_signals()
 {
        unix_init_signals();
 }
 
-void early_init(void) { }
+void early_init() { }
 
 #define SUFFIX ".image"
 #define SUFFIX_LEN 6
 
-const char *default_image_path(void)
+const char *default_image_path()
 {
        const char *path = vm_executable_path();
 
index bc12f716cfdb2cf568e7f112c94fc64847eb68dd..1972a728e6a3ce7077abc6fad0c40c9aa585568b 100644 (file)
@@ -5,9 +5,9 @@ namespace factor
 #define NULL_DLL NULL
 
 void c_to_factor_toplevel(cell quot);
-void init_signals(void);
-void early_init(void);
-const char *vm_executable_path(void);
-const char *default_image_path(void);
+void init_signals();
+void early_init();
+const char *vm_executable_path();
+const char *default_image_path();
 
 }
index ecc8973ebe9fd70d93d57efc3cb4f18e7f73a047..f5814d7f184372ce4fcfcc61a2799ce3487c6e10 100644 (file)
@@ -4,7 +4,7 @@ namespace factor
 {
 
 /* Snarfed from SBCL linux-so.c. You must free() this yourself. */
-const char *vm_executable_path(void)
+const char *vm_executable_path()
 {
        char *path = (char *)safe_malloc(PATH_MAX + 1);
 
@@ -23,7 +23,7 @@ const char *vm_executable_path(void)
 
 #ifdef SYS_inotify_init
 
-int inotify_init(void)
+int inotify_init()
 {
        return syscall(SYS_inotify_init);
 }
@@ -40,7 +40,7 @@ int inotify_rm_watch(int fd, u32 wd)
 
 #else
 
-int inotify_init(void)
+int inotify_init()
 {
        not_implemented_error();
        return -1;
index 4e2f22b95f3b1e4fc0fdf9453296f4e35aae43f9..257a6b0692389d1052a7a4505f6d4c37d409d158 100644 (file)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-int inotify_init(void);
+int inotify_init();
 int inotify_add_watch(int fd, const char *name, u32 mask);
 int inotify_rm_watch(int fd, u32 wd);
 
index aa166910f57cb95824c061a2a4f2fe9b7e663816..cdc0ff7b426bbb89a6075ba7ac18211baccf8aa7 100644 (file)
@@ -5,11 +5,11 @@ namespace factor
 #define FACTOR_OS_STRING "macosx"
 #define NULL_DLL "libfactor.dylib"
 
-void init_signals(void);
-void early_init(void);
+void init_signals();
+void early_init();
 
-const char *vm_executable_path(void);
-const char *default_image_path(void);
+const char *vm_executable_path();
+const char *default_image_path();
 
 inline static void *ucontext_stack_pointer(void *uap)
 {
index 7a3cb30652b060dbc0b9f5f096d381a013c93bf7..e280d99a8069b8aefb209114782a062a201be511 100755 (executable)
@@ -5,7 +5,7 @@ namespace factor
 
 extern "C" int main();
 
-const char *vm_executable_path(void)
+const char *vm_executable_path()
 {
        static Dl_info info = {0};
        if (!info.dli_fname)
index fc8aac8cf71f6ad0c13c660568ec1802c5589492..f763f8055f46026d76df2d68126e05a7976f8a58 100644 (file)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-const char *vm_executable_path(void)
+const char *vm_executable_path()
 {
        return NULL;
 }
index fc8aac8cf71f6ad0c13c660568ec1802c5589492..f763f8055f46026d76df2d68126e05a7976f8a58 100644 (file)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-const char *vm_executable_path(void)
+const char *vm_executable_path()
 {
        return NULL;
 }
index c0a268018e4d97f8efef20d33e4dbbc5b40a38fc..18300949bdded2952d5f81159372019acd0db0b8 100755 (executable)
@@ -19,7 +19,7 @@ void start_thread(void *(*start_routine)(void *))
 
 static void *null_dll;
 
-s64 current_micros(void)
+s64 current_micros()
 {
        struct timeval t;
        gettimeofday(&t,NULL);
@@ -31,7 +31,7 @@ void sleep_micros(cell usec)
        usleep(usec);
 }
 
-void init_ffi(void)
+void init_ffi()
 {
        /* NULL_DLL is "libfactor.dylib" for OS X and NULL for generic unix */
        null_dll = dlopen(NULL_DLL,RTLD_LAZY);
@@ -145,7 +145,7 @@ static void sigaction_safe(int signum, const struct sigaction *act, struct sigac
                fatal_error("sigaction failed", 0);
 }
 
-void unix_init_signals(void)
+void unix_init_signals()
 {
        struct sigaction memory_sigaction;
        struct sigaction misc_sigaction;
@@ -279,7 +279,7 @@ void *stdin_loop(void *arg)
        return NULL;
 }
 
-void open_console(void)
+void open_console()
 {
        int filedes[2];
 
@@ -304,7 +304,7 @@ void open_console(void)
        start_thread(stdin_loop);
 }
 
-VM_C_API void wait_for_stdin(void)
+VM_C_API void wait_for_stdin()
 {
        if(write(control_write,"X",1) != 1)
        {
index 24e8016db4d22a9205a5c74f4ca23c066d1cc10f..07ec385763f0e388b160842840a066e131a9e38e 100755 (executable)
@@ -42,18 +42,18 @@ typedef char symbol_char;
 
 void start_thread(void *(*start_routine)(void *));
 
-void init_ffi(void);
+void init_ffi();
 void ffi_dlopen(dll *dll);
 void *ffi_dlsym(dll *dll, symbol_char *symbol);
 void ffi_dlclose(dll *dll);
 
-void unix_init_signals(void);
+void unix_init_signals();
 void signal_handler(int signal, siginfo_t* siginfo, void* uap);
 void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap);
 
-s64 current_micros(void);
+s64 current_micros();
 void sleep_micros(cell usec);
 
-void open_console(void);
+void open_console();
 
 }
index 71c72e55f8e2b7bc5898433ffd9986622891f8b2..2e69a1eb5bab85f2d099085409fec25444a3c1ae 100755 (executable)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-s64 current_micros(void)
+s64 current_micros()
 {
        SYSTEMTIME st;
        FILETIME ft;
@@ -40,6 +40,6 @@ void c_to_factor_toplevel(cell quot)
        c_to_factor(quot);
 }
 
-void open_console(void) { }
+void open_console() { }
 
 }
index 49450f91c70be47e641e9ea75468b513481ac6ca..f41262e54bb8d256a7dbdd62d7001d07018e9073 100755 (executable)
@@ -22,8 +22,8 @@ char *getenv(char *name);
 #define snprintf _snprintf
 #define snwprintf _snwprintf
 
-s64 current_micros(void);
+s64 current_micros();
 void c_to_factor_toplevel(cell quot);
-void open_console(void);
+void open_console();
 
 }
index 0a63dce513ee8bac3df33650aa573a79484edf96..c4349f243b37f1156f469554575d522f2d06ab36 100755 (executable)
@@ -3,7 +3,7 @@
 namespace factor
 {
 
-s64 current_micros(void)
+s64 current_micros()
 {
        FILETIME t;
        GetSystemTimeAsFileTime(&t);
@@ -11,13 +11,13 @@ s64 current_micros(void)
                - EPOCH_OFFSET) / 10;
 }
 
-long exception_handler(PEXCEPTION_POINTERS pe)
+FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
 {
        PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
        CONTEXT *c = (CONTEXT*)pe->ContextRecord;
 
        if(in_code_heap_p(c->EIP))
-               signal_callstack_top = (void *)c->ESP;
+               signal_callstack_top = (stack_frame *)c->ESP;
        else
                signal_callstack_top = NULL;
 
@@ -43,13 +43,13 @@ long exception_handler(PEXCEPTION_POINTERS pe)
 
 void c_to_factor_toplevel(cell quot)
 {
-       if(!AddVectoredExceptionHandler(0, (void*)exception_handler))
+       if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
                fatal_error("AddVectoredExceptionHandler failed", 0);
        c_to_factor(quot);
-       RemoveVectoredExceptionHandler((void*)exception_handler);
+       RemoveVectoredExceptionHandler((void *)exception_handler);
 }
 
-void open_console(void)
+void open_console()
 {
 }
 
index 107e42ea2eed6762403940f9371ac49be2ceb03b..4371771c13aa454f3eee2b76291907b57a58e2a8 100755 (executable)
@@ -5,8 +5,8 @@
 #define UNICODE
 #endif
 
-#include <shellapi.h>
 #include <windows.h>
+#include <shellapi.h>
 
 namespace factor
 {
@@ -17,8 +17,10 @@ typedef char symbol_char;
 #define FACTOR_DLL L"factor.dll"
 #define FACTOR_DLL_NAME "factor.dll"
 
+#define FACTOR_STDCALL __attribute__((stdcall))
+
 void c_to_factor_toplevel(cell quot);
-long exception_handler(PEXCEPTION_POINTERS pe);
-void open_console(void);
+FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe);
+void open_console();
 
 }
index 796a1c718474a0586915c6bd01db53d840f903e9..7db19ff560c6e6b68c4bebc58de700e110bf8a00 100755 (executable)
@@ -5,7 +5,7 @@ namespace factor
 
 HMODULE hFactorDll;
 
-void init_ffi(void)
+void init_ffi()
 {
        hFactorDll = GetModuleHandle(FACTOR_DLL);
        if(!hFactorDll)
@@ -14,12 +14,12 @@ void init_ffi(void)
 
 void ffi_dlopen(dll *dll)
 {
-       dll->dll = LoadLibraryEx(alien_offset(dll->path), NULL, 0);
+       dll->dll = LoadLibraryEx((WCHAR *)alien_offset(dll->path), NULL, 0);
 }
 
 void *ffi_dlsym(dll *dll, symbol_char *symbol)
 {
-       return GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol);
+       return (void *)GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol);
 }
 
 void ffi_dlclose(dll *dll)
@@ -63,7 +63,7 @@ void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int len
 }
 
 /* You must free() this yourself. */
-const vm_char *default_image_path(void)
+const vm_char *default_image_path()
 {
        vm_char full_path[MAX_UNICODE_PATH];
        vm_char *ptr;
@@ -82,7 +82,7 @@ const vm_char *default_image_path(void)
 }
 
 /* You must free() this yourself. */
-const vm_char *vm_executable_path(void)
+const vm_char *vm_executable_path()
 {
        vm_char full_path[MAX_UNICODE_PATH];
        if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH))
@@ -93,7 +93,7 @@ const vm_char *vm_executable_path(void)
 
 PRIMITIVE(existsp)
 {
-       vm_char *path = (vm_char *)(untag_check<byte_array>(dpop()) + 1);
+       vm_char *path = untag_check<byte_array>(dpop())->data<vm_char>();
        box_boolean(windows_stat(path));
 }
 
@@ -113,7 +113,7 @@ segment *alloc_segment(cell size)
                getpagesize(), PAGE_NOACCESS, &ignore))
                fatal_error("Cannot allocate high guard page", (cell)mem);
 
-       segment *block = safe_malloc(sizeof(segment));
+       segment *block = (segment *)safe_malloc(sizeof(segment));
 
        block->start = (cell)mem + getpagesize();
        block->size = size;
@@ -131,7 +131,7 @@ void dealloc_segment(segment *block)
        free(block);
 }
 
-long getpagesize(void)
+long getpagesize()
 {
        static long g_pagesize = 0;
        if (! g_pagesize)
index 2926ea50a846a24844667d08a0883231c3aff107..5422216593deb960b8d6eff60e43603930557504 100755 (executable)
@@ -41,19 +41,19 @@ typedef wchar_t vm_char;
 /* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
 #define EPOCH_OFFSET 0x019db1ded53e8000LL
 
-void init_ffi(void);
+void init_ffi();
 void ffi_dlopen(dll *dll);
 void *ffi_dlsym(dll *dll, symbol_char *symbol);
 void ffi_dlclose(dll *dll);
 
 void sleep_micros(u64 msec);
 
-inline static void init_signals(void) {}
-inline static void early_init(void) {}
-const vm_char *vm_executable_path(void);
-const vm_char *default_image_path(void);
-long getpagesize (void);
+inline static void init_signals() {}
+inline static void early_init() {}
+const vm_char *vm_executable_path();
+const vm_char *default_image_path();
+long getpagesize ();
 
-s64 current_micros(void);
+s64 current_micros();
 
 }
index 08db684ff6b858c18b93e4744063a6f742b71da6..bd761625d894586376a0dd2bfde9c4c4a0cca804 100755 (executable)
@@ -135,7 +135,7 @@ const primitive_type primitives[] = {
        primitive_sleep,
        primitive_tuple_boa,
        primitive_callstack_to_array,
-       primitive_innermost_stack_frame_quot,
+       primitive_innermost_stack_frame_executing,
        primitive_innermost_stack_frame_scan,
        primitive_set_innermost_stack_frame_quot,
        primitive_call_clear,
@@ -147,6 +147,7 @@ const primitive_type primitives[] = {
        primitive_load_locals,
        primitive_check_datastack,
        primitive_inline_cache_miss,
+       primitive_inline_cache_miss_tail,
        primitive_mega_cache_miss,
        primitive_lookup_method,
        primitive_reset_dispatch_stats,
index 9651e4a27e71504207d262e119ba747af26f6d32..a3265e0ffa88fc4cf7046e4c080208d1dfde2864 100755 (executable)
@@ -5,7 +5,7 @@ namespace factor
 
 bool profiling_p;
 
-void init_profiler(void)
+void init_profiler()
 {
        profiling_p = false;
 }
index 00f3e8067bb6e5aa74db549274001743928e632c..b83ef3d3544ce3909ee89962a1d62dda6fe9d44d 100755 (executable)
@@ -2,7 +2,7 @@ namespace factor
 {
 
 extern bool profiling_p;
-void init_profiler(void);
+void init_profiler();
 code_block *compile_profiling_stub(cell word);
 PRIMITIVE(profiling);
 
index c87cf8dc8275fb2d3715e6d242809b5ec9ebacbd..b049f528e4fb72537ede9b1bf91145e7ec8d809e 100755 (executable)
@@ -152,7 +152,23 @@ void quotation_jit::iterate_quotation()
                                {
                                        if(stack_frame) emit(userenv[JIT_EPILOG]);
                                        tail_call = true;
-                                       word_jump(obj.value());
+                                       /* Inline cache misses are special-cased.
+                                          The calling convention for tail
+                                          calls stores the address of the next
+                                          instruction in a register. However,
+                                          PIC miss stubs themselves tail-call
+                                          the inline cache miss primitive, and
+                                          we don't want to clobber the saved
+                                          address. */
+                                       if(obj.value() == userenv[PIC_MISS_WORD]
+                                          || obj.value() == userenv[PIC_MISS_TAIL_WORD])
+                                       {
+                                               word_special(obj.value());
+                                       }
+                                       else
+                                       {
+                                               word_jump(obj.value());
+                                       }
                                }
                                else
                                        word_call(obj.value());
@@ -165,7 +181,6 @@ void quotation_jit::iterate_quotation()
                        /* Primitive calls */
                        if(primitive_call_p(i))
                        {
-                               emit(userenv[JIT_SAVE_STACK]);
                                emit_with(userenv[JIT_PRIMITIVE],obj.value());
 
                                i++;
@@ -187,8 +202,9 @@ void quotation_jit::iterate_quotation()
                                        jit_compile(array_nth(elements.untagged(),i + 1),relocate);
                                }
 
-                               emit_with(userenv[JIT_IF_1],array_nth(elements.untagged(),i));
-                               emit_with(userenv[JIT_IF_2],array_nth(elements.untagged(),i + 1));
+                               literal(array_nth(elements.untagged(),i));
+                               literal(array_nth(elements.untagged(),i + 1));
+                               emit(userenv[JIT_IF]);
 
                                i += 2;
 
@@ -251,7 +267,7 @@ void quotation_jit::iterate_quotation()
 
 void set_quot_xt(quotation *quot, code_block *code)
 {
-       if(code->block.type != QUOTATION_TYPE)
+       if(code->type != QUOTATION_TYPE)
                critical_error("Bad param to set_quot_xt",(cell)code);
 
        quot->code = code;
@@ -297,7 +313,7 @@ PRIMITIVE(quotation_xt)
        drepl(allot_cell((cell)quot->xt));
 }
 
-void compile_all_words(void)
+void compile_all_words()
 {
        gc_root<array> words(find_all_words());
 
index a4545f395646b6a5d2e428c37cdb6317403ed12c..719a94176ebf79b917ae4f1819394fc1ec5186ea 100755 (executable)
@@ -28,7 +28,7 @@ fixnum quot_code_offset_to_scan(cell quot, cell offset);
 
 PRIMITIVE(jit_compile);
 
-void compile_all_words(void);
+void compile_all_words();
 
 PRIMITIVE(array_to_quotation);
 PRIMITIVE(quotation_xt);
index 2204585fe5b1cbe3f1361a94de8602ac85ed0345..7527889efb4be0d5c12ff3625838588064cc9e8a 100755 (executable)
@@ -14,7 +14,7 @@ enum special_object {
        BREAK_ENV            = 5, /* quotation called by throw primitive */
        ERROR_ENV,                /* a marker consed onto kernel errors */
 
-       cell_SIZE_ENV        = 7, /* sizeof(cell) */
+       CELL_SIZE_ENV        = 7, /* sizeof(cell) */
        CPU_ENV,                  /* CPU architecture */
        OS_ENV,                   /* operating system name */
 
@@ -41,14 +41,13 @@ enum special_object {
        JIT_PRIMITIVE,
        JIT_WORD_JUMP,
        JIT_WORD_CALL,
+       JIT_WORD_SPECIAL,
        JIT_IF_WORD,
-       JIT_IF_1,
-       JIT_IF_2,
-       JIT_EPILOG          = 33,
+       JIT_IF,
+       JIT_EPILOG,
        JIT_RETURN,
        JIT_PROFILING,
        JIT_PUSH_IMMEDIATE,
-       JIT_SAVE_STACK = 38,
        JIT_DIP_WORD,
        JIT_DIP,
        JIT_2DIP_WORD,
@@ -60,7 +59,7 @@ enum special_object {
        JIT_EXECUTE_CALL,
 
        /* Polymorphic inline cache generation in inline_cache.c */
-       PIC_LOAD            = 48,
+       PIC_LOAD            = 47,
        PIC_TAG,
        PIC_HI_TAG,
        PIC_TUPLE,
@@ -69,6 +68,7 @@ enum special_object {
        PIC_CHECK,
        PIC_HIT,
        PIC_MISS_WORD,
+       PIC_MISS_TAIL_WORD,
 
        /* Megamorphic cache generation in dispatch.c */
        MEGA_LOOKUP         = 57,
@@ -93,6 +93,11 @@ enum special_object {
 #define FIRST_SAVE_ENV BOOT_ENV
 #define LAST_SAVE_ENV STAGE2_ENV
 
+inline static bool save_env_p(cell i)
+{
+       return (i >= FIRST_SAVE_ENV && i <= LAST_SAVE_ENV) || i == STACK_TRACES_ENV;
+}
+
 /* Canonical T object. It's just a word */
 extern cell T;
 
index a715b4dabcdfbdbed6e0c1aed44f96057ae9891d..36b5bc747be3134bcd0d88bdb6de09326ff5ba6f 100644 (file)
@@ -7,4 +7,9 @@ struct segment {
        cell end;
 };
 
+inline static cell align_page(cell a)
+{
+       return align(a,getpagesize());
+}
+
 }
index 4af31e17d98918770c6eb55cd75a8b5e64da7971..bc1aac81543f4c276ef8f7f50bee601eaa2793f0 100644 (file)
@@ -4,7 +4,7 @@ namespace factor
 #define DEFPUSHPOP(prefix,ptr) \
        inline static cell prefix##peek() { return *(cell *)ptr; } \
        inline static void prefix##repl(cell tagged) { *(cell *)ptr = tagged; } \
-       inline static cell prefix##pop(void) \
+       inline static cell prefix##pop() \
        { \
                cell value = prefix##peek(); \
                ptr -= sizeof(cell); \
index 532de80ed13d5a928d31dd4bd7f9ccf0b02d5281..df5c09847d9700ad8e97c40875e75098dd19e945 100755 (executable)
@@ -20,7 +20,7 @@ vm_char *safe_strdup(const vm_char *str)
 
 /* We don't use printf directly, because format directives are not portable.
 Instead we define the common cases here. */
-void nl(void)
+void nl()
 {
        fputs("\n",stdout);
 }
@@ -50,7 +50,7 @@ void print_fixnum(fixnum x)
        printf(FIXNUM_FORMAT,x);
 }
 
-cell read_cell_hex(void)
+cell read_cell_hex()
 {
        cell cell;
        if(scanf(cell_HEX_FORMAT,&cell) < 0) exit(1);
index d311b954ed066db7fe394d12488fa6a115194f37..7e7765170e7080170aaadea621c3bd8aaae1dbc1 100755 (executable)
@@ -4,12 +4,12 @@ namespace factor
 void *safe_malloc(size_t size);
 vm_char *safe_strdup(const vm_char *str);
 
-void nl(void);
+void nl();
 void print_string(const char *str);
 void print_cell(cell x);
 void print_cell_hex(cell x);
 void print_cell_hex_pad(cell x);
 void print_fixnum(fixnum x);
-cell read_cell_hex(void);
+cell read_cell_hex();
 
 }
index cb2fdf0dd6a3f463f0f01072eb8e4a4c9b956a8a..fa090c9ceaa6db19e881c4049edbb596f11cd94b 100644 (file)
@@ -16,7 +16,8 @@ word *allot_word(cell vocab_, cell name_)
        new_word->def = userenv[UNDEFINED_ENV];
        new_word->props = F;
        new_word->counter = tag_fixnum(0);
-       new_word->direct_entry_def = F;
+       new_word->pic_def = F;
+       new_word->pic_tail_def = F;
        new_word->subprimitive = F;
        new_word->profiling = NULL;
        new_word->code = NULL;
@@ -44,7 +45,7 @@ PRIMITIVE(word_xt)
        word *w = untag_check<word>(dpop());
        code_block *code = (profiling_p ? w->profiling : w->code);
        dpush(allot_cell((cell)code->xt()));
-       dpush(allot_cell((cell)code + code->block.size));
+       dpush(allot_cell((cell)code + code->size));
 }
 
 /* Allocates memory */
index 9c8e7ad57a1b325d974c1df89d88985a086d72da..f9d5a7aff46fc5847163f3421aee62a54ef5669f 100644 (file)
@@ -9,7 +9,7 @@ void update_word_xt(cell word);
 
 inline bool word_optimized_p(word *word)
 {
-       return word->code->block.type == WORD_TYPE;
+       return word->code->type == WORD_TYPE;
 }
 
 PRIMITIVE(optimized_p);
old mode 100644 (file)
new mode 100755 (executable)
index 4137b0a..0e87434
@@ -4,4 +4,8 @@ using namespace factor;
 
 cell cards_offset;
 cell decks_offset;
-cell allot_markers_offset;
+
+namespace factor
+{
+        cell allot_markers_offset;
+}
old mode 100644 (file)
new mode 100755 (executable)
index ae7fbb2..0006581
@@ -6,29 +6,30 @@ card has a slot written to.
 
 the offset of the first object is set by the allocator. */
 
+VM_C_API factor::cell cards_offset;
+VM_C_API factor::cell decks_offset;
+
 namespace factor
 {
 
-/* if CARD_POINTS_TO_NURSERY is set, CARD_POINTS_TO_AGING must also be set. */
-#define CARD_POINTS_TO_NURSERY 0x80
-#define CARD_POINTS_TO_AGING 0x40
-#define CARD_MARK_MASK (CARD_POINTS_TO_NURSERY | CARD_POINTS_TO_AGING)
+/* if card_points_to_nursery is set, card_points_to_aging must also be set. */
+static const cell card_points_to_nursery = 0x80;
+static const cell card_points_to_aging = 0x40;
+static const cell card_mark_mask = (card_points_to_nursery | card_points_to_aging);
 typedef u8 card;
 
-#define CARD_BITS 8
-#define CARD_SIZE (1<<CARD_BITS)
-#define ADDR_CARD_MASK (CARD_SIZE-1)
-
-VM_C_API cell cards_offset;
+static const cell card_bits = 8;
+static const cell card_size = (1<<card_bits);
+static const cell addr_card_mask = (card_size-1);
 
 inline static card *addr_to_card(cell a)
 {
-       return (card*)(((cell)(a) >> CARD_BITS) + cards_offset);
+       return (card*)(((cell)(a) >> card_bits) + cards_offset);
 }
 
 inline static cell card_to_addr(card *c)
 {
-       return ((cell)c - cards_offset) << CARD_BITS;
+       return ((cell)c - cards_offset) << card_bits;
 }
 
 inline static cell card_offset(card *c)
@@ -38,50 +39,48 @@ inline static cell card_offset(card *c)
 
 typedef u8 card_deck;
 
-#define DECK_BITS (CARD_BITS + 10)
-#define DECK_SIZE (1<<DECK_BITS)
-#define ADDR_DECK_MASK (DECK_SIZE-1)
-
-VM_C_API cell decks_offset;
+static const cell deck_bits = (card_bits + 10);
+static const cell deck_size = (1<<deck_bits);
+static const cell addr_deck_mask = (deck_size-1);
 
 inline static card_deck *addr_to_deck(cell a)
 {
-       return (card_deck *)(((cell)a >> DECK_BITS) + decks_offset);
+       return (card_deck *)(((cell)a >> deck_bits) + decks_offset);
 }
 
 inline static cell deck_to_addr(card_deck *c)
 {
-       return ((cell)c - decks_offset) << DECK_BITS;
+       return ((cell)c - decks_offset) << deck_bits;
 }
 
 inline static card *deck_to_card(card_deck *d)
 {
-       return (card *)((((cell)d - decks_offset) << (DECK_BITS - CARD_BITS)) + cards_offset);
+       return (card *)((((cell)d - decks_offset) << (deck_bits - card_bits)) + cards_offset);
 }
 
-#define INVALID_ALLOT_MARKER 0xff
+static const cell invalid_allot_marker = 0xff;
 
-VM_C_API cell allot_markers_offset;
+extern cell allot_markers_offset;
 
 inline static card *addr_to_allot_marker(object *a)
 {
-       return (card *)(((cell)a >> CARD_BITS) + allot_markers_offset);
+       return (card *)(((cell)a >> card_bits) + allot_markers_offset);
 }
 
 /* the write barrier must be called any time we are potentially storing a
 pointer from an older generation to a younger one */
 inline static void write_barrier(object *obj)
 {
-       *addr_to_card((cell)obj) = CARD_MARK_MASK;
-       *addr_to_deck((cell)obj) = CARD_MARK_MASK;
+       *addr_to_card((cell)obj) = card_mark_mask;
+       *addr_to_deck((cell)obj) = card_mark_mask;
 }
 
 /* we need to remember the first object allocated in the card */
 inline static void allot_barrier(object *address)
 {
        card *ptr = addr_to_allot_marker(address);
-       if(*ptr == INVALID_ALLOT_MARKER)
-               *ptr = ((cell)address & ADDR_CARD_MASK);
+       if(*ptr == invalid_allot_marker)
+               *ptr = ((cell)address & addr_card_mask);
 }
 
 }