diff --git a/basis/bootstrap/stage2.factor b/basis/bootstrap/stage2.factor index 3b6c04329c..d25394e978 100644 --- a/basis/bootstrap/stage2.factor +++ b/basis/bootstrap/stage2.factor @@ -8,6 +8,8 @@ definitions assocs compiler.errors compiler.units math.parser generic sets debugger command-line ; IN: bootstrap.stage2 +SYMBOL: core-bootstrap-time + SYMBOL: bootstrap-time : default-image-name ( -- string ) @@ -30,11 +32,15 @@ SYMBOL: bootstrap-time : count-words ( pred -- ) all-words swap count number>string write ; -: print-report ( time -- ) +: print-time ( time -- ) 1000 /i 60 /mod swap - "Bootstrap completed in " write number>string write - " minutes and " write number>string write " seconds." print + number>string write + " minutes and " write number>string write " seconds." print ; + +: print-report ( -- ) + "Core bootstrap completed in " write core-bootstrap-time get print-time + "Bootstrap completed in " write bootstrap-time get print-time [ compiled>> ] count-words " compiled words" print [ symbol? ] count-words " symbol words" print @@ -46,7 +52,7 @@ SYMBOL: bootstrap-time [ ! We time bootstrap - millis >r + millis default-image-name "output-image" set-global @@ -71,6 +77,8 @@ SYMBOL: bootstrap-time [ load-components + millis over - core-bootstrap-time set-global + run-bootstrap-init ] with-compiler-errors :errors @@ -92,7 +100,7 @@ SYMBOL: bootstrap-time ] [ print-error 1 exit ] recover ] set-boot-quot - millis r> - dup bootstrap-time set-global + millis swap - bootstrap-time set-global print-report "output-image" get save-image-and-exit diff --git a/basis/compiler/cfg/builder/builder.factor b/basis/compiler/cfg/builder/builder.factor index 93daa601fe..17a5942af2 100755 --- a/basis/compiler/cfg/builder/builder.factor +++ b/basis/compiler/cfg/builder/builder.factor @@ -171,6 +171,7 @@ M: #if emit-node [ V{ } clone node-stack set ##prologue + begin-basic-block emit-nodes basic-block get [ ##epilogue diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index cab86dcb54..35d4d59253 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: namespaces make math math.parser sequences accessors +USING: namespaces make math math.order math.parser sequences accessors kernel kernel.private layouts assocs words summary arrays combinators classes.algebra alien alien.c-types alien.structs alien.strings alien.arrays sets threads libc continuations.private @@ -234,13 +234,26 @@ M: float-regs reg-class-variable drop float-regs ; GENERIC: inc-reg-class ( register-class -- ) -M: reg-class inc-reg-class - dup reg-class-variable inc - fp-shadows-int? [ reg-size stack-params +@ ] [ drop ] if ; +: ?dummy-stack-params ( reg-class -- ) + dummy-stack-params? [ reg-size stack-params +@ ] [ drop ] if ; + +: ?dummy-int-params ( reg-class -- ) + dummy-int-params? [ reg-size cell /i 1 max int-regs +@ ] [ drop ] if ; + +: ?dummy-fp-params ( reg-class -- ) + drop dummy-fp-params? [ float-regs inc ] when ; + +M: int-regs inc-reg-class + [ reg-class-variable inc ] + [ ?dummy-stack-params ] + [ ?dummy-fp-params ] + tri ; M: float-regs inc-reg-class - dup call-next-method - fp-shadows-int? [ reg-size cell /i int-regs +@ ] [ drop ] if ; + [ reg-class-variable inc ] + [ ?dummy-stack-params ] + [ ?dummy-int-params ] + tri ; GENERIC: reg-class-full? ( class -- ? ) diff --git a/basis/compiler/tests/templates.factor b/basis/compiler/tests/templates.factor index de87ad8c00..0a109a15eb 100644 --- a/basis/compiler/tests/templates.factor +++ b/basis/compiler/tests/templates.factor @@ -219,3 +219,14 @@ TUPLE: my-tuple ; : bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f ; [ { f f f } ] [ t bad-value-bug ] unit-test + +! PowerPC regression +TUPLE: id obj ; + +: (gc-check-bug) ( a b -- c ) + { [ id boa ] [ id boa ] } dispatch ; + +: gc-check-bug ( -- ) + 10000000 [ "hi" 0 (gc-check-bug) drop ] times ; + +[ ] [ gc-check-bug ] unit-test diff --git a/basis/compiler/tree/cleanup/cleanup-tests.factor b/basis/compiler/tree/cleanup/cleanup-tests.factor index b77a27800f..4a6198db37 100644 --- a/basis/compiler/tree/cleanup/cleanup-tests.factor +++ b/basis/compiler/tree/cleanup/cleanup-tests.factor @@ -5,7 +5,7 @@ strings sbufs sequences.private slots.private combinators definitions system layouts vectors math.partial-dispatch math.order math.functions accessors hashtables classes assocs io.encodings.utf8 io.encodings.ascii io.encodings fry slots -sorting.private combinators.short-circuit +sorting.private combinators.short-circuit grouping prettyprint compiler.tree compiler.tree.combinators compiler.tree.cleanup @@ -500,3 +500,13 @@ cell-bits 32 = [ [ { array-capacity } declare 1 fixnum+ ] cleaned-up-tree [ { [ #call? ] [ node-input-infos second literal>> 1 = ] } 1&& ] contains? ] unit-test + +[ ] [ + [ { null } declare [ 1 ] [ 2 ] if ] + build-tree normalize propagate cleanup check-nodes +] unit-test + +[ t ] [ + [ { array } declare 2 [ . . ] assoc-each ] + \ nth-unsafe inlined? +] unit-test diff --git a/basis/compiler/tree/cleanup/cleanup.factor b/basis/compiler/tree/cleanup/cleanup.factor index 4ca058b2e3..becac01cd5 100644 --- a/basis/compiler/tree/cleanup/cleanup.factor +++ b/basis/compiler/tree/cleanup/cleanup.factor @@ -102,7 +102,7 @@ M: #declare cleanup* drop f ; #! If only one branch is live we don't need to branch at #! all; just drop the condition value. dup live-children sift dup length { - { 0 [ 2drop f ] } + { 0 [ drop in-d>> #drop ] } { 1 [ first swap in-d>> #drop prefix ] } [ 2drop ] } case ; diff --git a/basis/compiler/tree/escape-analysis/escape-analysis-tests.factor b/basis/compiler/tree/escape-analysis/escape-analysis-tests.factor index 4ed194e81d..9a226b954f 100644 --- a/basis/compiler/tree/escape-analysis/escape-analysis-tests.factor +++ b/basis/compiler/tree/escape-analysis/escape-analysis-tests.factor @@ -8,6 +8,7 @@ math.private kernel tools.test accessors slots.private quotations.private prettyprint classes.tuple.private classes classes.tuple namespaces compiler.tree.propagation.info stack-checker.errors +compiler.tree.checker kernel.private ; \ escape-analysis must-infer @@ -34,6 +35,7 @@ M: node count-unboxed-allocations* drop ; propagate cleanup escape-analysis + dup check-nodes 0 swap [ count-unboxed-allocations* ] each-node ; [ 0 ] [ [ [ + ] curry ] count-unboxed-allocations ] unit-test @@ -307,7 +309,7 @@ C: ro-box : bleach-node ( quot: ( node -- ) -- ) [ bleach-node ] curry [ ] compose impeach-node ; inline recursive -[ 2 ] [ [ [ ] bleach-node ] count-unboxed-allocations ] unit-test +[ 3 ] [ [ [ ] bleach-node ] count-unboxed-allocations ] unit-test [ 0 ] [ [ dup -1 over >= [ 0 >= [ "A" throw ] unless ] [ drop ] if ] diff --git a/basis/compiler/tree/propagation/branches/branches.factor b/basis/compiler/tree/propagation/branches/branches.factor index c76217f8ae..424cd8a01c 100644 --- a/basis/compiler/tree/propagation/branches/branches.factor +++ b/basis/compiler/tree/propagation/branches/branches.factor @@ -40,8 +40,8 @@ M: #dispatch live-branches SYMBOL: infer-children-data : copy-value-info ( -- ) - value-infos [ clone ] change - constraints [ clone ] change ; + value-infos [ H{ } clone suffix ] change + constraints [ H{ } clone suffix ] change ; : no-value-info ( -- ) value-infos off diff --git a/basis/compiler/tree/propagation/constraints/constraints.factor b/basis/compiler/tree/propagation/constraints/constraints.factor index cfdf7f5169..2652547aad 100644 --- a/basis/compiler/tree/propagation/constraints/constraints.factor +++ b/basis/compiler/tree/propagation/constraints/constraints.factor @@ -32,7 +32,7 @@ TUPLE: true-constraint value ; M: true-constraint assume* [ \ f class-not swap value>> refine-value-info ] - [ constraints get at [ assume ] when* ] + [ constraints get assoc-stack [ assume ] when* ] bi ; M: true-constraint satisfied? @@ -44,7 +44,7 @@ TUPLE: false-constraint value ; M: false-constraint assume* [ \ f swap value>> refine-value-info ] - [ constraints get at [ assume ] when* ] + [ constraints get assoc-stack [ assume ] when* ] bi ; M: false-constraint satisfied? @@ -83,7 +83,7 @@ TUPLE: implication p q ; C: --> implication : assume-implication ( p q -- ) - [ constraints get [ swap suffix ] change-at ] + [ constraints get [ assoc-stack swap suffix ] 2keep peek set-at ] [ satisfied? [ assume ] [ drop ] if ] 2bi ; M: implication assume* diff --git a/basis/compiler/tree/propagation/info/info-tests.factor b/basis/compiler/tree/propagation/info/info-tests.factor index 24f4ca59dc..2c3314994b 100644 --- a/basis/compiler/tree/propagation/info/info-tests.factor +++ b/basis/compiler/tree/propagation/info/info-tests.factor @@ -70,3 +70,7 @@ TUPLE: test-tuple { x read-only } ; f f 3 3array test-tuple dup object-info value-info-intersect = ] unit-test + +[ t ] [ + null-info 3 value-info<= +] unit-test diff --git a/basis/compiler/tree/propagation/info/info.factor b/basis/compiler/tree/propagation/info/info.factor index d1d8189f7a..e89a9c6211 100644 --- a/basis/compiler/tree/propagation/info/info.factor +++ b/basis/compiler/tree/propagation/info/info.factor @@ -34,7 +34,7 @@ slots ; : null-info T{ value-info f null empty-interval } ; inline -: object-info T{ value-info f object T{ interval f { -1.0/0.0 t } { 1.0/0.0 t } } } ; inline +: object-info T{ value-info f object full-interval } ; inline : class-interval ( class -- interval ) dup real class<= @@ -43,7 +43,7 @@ slots ; : interval>literal ( class interval -- literal literal? ) #! If interval has zero length and the class is sufficiently #! precise, we can turn it into a literal - dup empty-interval eq? [ + dup special-interval? [ 2drop f f ] [ dup from>> first { @@ -243,7 +243,7 @@ DEFER: (value-info-union) : literals<= ( info1 info2 -- ? ) { { [ dup literal?>> not ] [ 2drop t ] } - { [ over literal?>> not ] [ 2drop f ] } + { [ over literal?>> not ] [ drop class>> null-class? ] } [ [ literal>> ] bi@ eql? ] } cond ; @@ -262,17 +262,19 @@ DEFER: (value-info-union) ] } cond ; -! Current value --> info mapping +! Assoc stack of current value --> info mapping SYMBOL: value-infos : value-info ( value -- info ) - resolve-copy value-infos get at null-info or ; + resolve-copy value-infos get assoc-stack null-info or ; : set-value-info ( info value -- ) - resolve-copy value-infos get set-at ; + resolve-copy value-infos get peek set-at ; : refine-value-info ( info value -- ) - resolve-copy value-infos get [ value-info-intersect ] change-at ; + resolve-copy value-infos get + [ assoc-stack value-info-intersect ] 2keep + peek set-at ; : value-literal ( value -- obj ? ) value-info >literal< ; diff --git a/basis/compiler/tree/propagation/propagation-tests.factor b/basis/compiler/tree/propagation/propagation-tests.factor index 101320f92c..760ff167aa 100644 --- a/basis/compiler/tree/propagation/propagation-tests.factor +++ b/basis/compiler/tree/propagation/propagation-tests.factor @@ -8,7 +8,7 @@ math.functions math.private strings layouts compiler.tree.propagation.info compiler.tree.def-use compiler.tree.debugger compiler.tree.checker slots.private words hashtables classes assocs locals -float-arrays system ; +float-arrays system sorting ; IN: compiler.tree.propagation.tests \ propagate must-infer @@ -592,6 +592,8 @@ MIXIN: empty-mixin [ V{ t } ] [ [ netbsd unix? ] final-literals ] unit-test +[ V{ array } ] [ [ [ <=> ] sort [ <=> ] sort ] final-classes ] unit-test + ! [ V{ string } ] [ ! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes ! ] unit-test diff --git a/basis/compiler/tree/propagation/propagation.factor b/basis/compiler/tree/propagation/propagation.factor index d82ebed433..b9822d2c6b 100644 --- a/basis/compiler/tree/propagation/propagation.factor +++ b/basis/compiler/tree/propagation/propagation.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel sequences namespaces hashtables +USING: accessors kernel sequences namespaces hashtables arrays compiler.tree compiler.tree.propagation.copy compiler.tree.propagation.info @@ -17,7 +17,7 @@ IN: compiler.tree.propagation : propagate ( node -- node ) H{ } clone copies set - H{ } clone constraints set - H{ } clone value-infos set + H{ } clone 1array value-infos set + H{ } clone 1array constraints set dup count-nodes dup (propagate) ; diff --git a/basis/compiler/tree/propagation/recursive/recursive.factor b/basis/compiler/tree/propagation/recursive/recursive.factor index 53dce813a3..7f10f87016 100644 --- a/basis/compiler/tree/propagation/recursive/recursive.factor +++ b/basis/compiler/tree/propagation/recursive/recursive.factor @@ -17,9 +17,12 @@ IN: compiler.tree.propagation.recursive [ value-info<= ] 2all? [ drop ] [ label>> f >>fixed-point drop ] if ; +: latest-input-infos ( node -- infos ) + in-d>> [ value-info ] map ; + : recursive-stacks ( #enter-recursive -- stacks initial ) [ label>> calls>> [ node-input-infos ] map flip ] - [ in-d>> [ value-info ] map ] bi ; + [ latest-input-infos ] bi ; : generalize-counter-interval ( interval initial-interval -- interval' ) { @@ -46,14 +49,13 @@ IN: compiler.tree.propagation.recursive ] if ; : propagate-recursive-phi ( #enter-recursive -- ) - [ ] [ recursive-stacks unify-recursive-stacks ] [ ] tri - [ node-output-infos check-fixed-point ] - [ out-d>> set-value-infos drop ] - 3bi ; + [ recursive-stacks unify-recursive-stacks ] keep + out-d>> set-value-infos ; M: #recursive propagate-around ( #recursive -- ) + constraints [ H{ } clone suffix ] change [ - constraints [ clone ] change + constraints [ but-last H{ } clone suffix ] change child>> [ first compute-copy-equiv ] @@ -62,6 +64,9 @@ M: #recursive propagate-around ( #recursive -- ) tri ] until-fixed-point ; +: recursive-phi-infos ( node -- infos ) + label>> enter-recursive>> node-output-infos ; + : generalize-return-interval ( info -- info' ) dup [ literal?>> ] [ class>> null-class? ] bi or [ clone [-inf,inf] >>interval ] unless ; @@ -70,12 +75,25 @@ M: #recursive propagate-around ( #recursive -- ) [ generalize-return-interval ] map ; : return-infos ( node -- infos ) - label>> [ return>> node-input-infos ] [ loop?>> ] bi - [ generalize-return ] unless ; + label>> return>> node-input-infos generalize-return ; + +: save-return-infos ( node infos -- ) + swap out-d>> set-value-infos ; + +: unless-loop ( node quot -- ) + [ dup label>> loop?>> [ drop ] ] dip if ; inline M: #call-recursive propagate-before ( #call-recursive -- ) - [ ] [ return-infos ] [ node-output-infos ] tri - [ check-fixed-point ] [ drop swap out-d>> set-value-infos ] 3bi ; + [ + [ ] [ latest-input-infos ] [ recursive-phi-infos ] tri + check-fixed-point + ] + [ + [ + [ ] [ return-infos ] [ node-output-infos ] tri + [ check-fixed-point ] [ drop save-return-infos ] 3bi + ] unless-loop + ] bi ; M: #call-recursive annotate-node dup [ in-d>> ] [ out-d>> ] bi append (annotate-node) ; @@ -83,5 +101,11 @@ M: #call-recursive annotate-node M: #enter-recursive annotate-node dup out-d>> (annotate-node) ; +M: #return-recursive propagate-before ( #return-recursive -- ) + [ + [ ] [ latest-input-infos ] [ node-input-infos ] tri + check-fixed-point + ] unless-loop ; + M: #return-recursive annotate-node dup in-d>> (annotate-node) ; diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index e4fa9419f0..b0b5b048d9 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -146,8 +146,14 @@ HOOK: struct-small-enough? cpu ( heap-size -- ? ) ! Do we pass value structs by value or hidden reference? HOOK: value-structs? cpu ( -- ? ) -! If t, fp parameters are shadowed by dummy int parameters -HOOK: fp-shadows-int? cpu ( -- ? ) +! If t, all parameters are shadowed by dummy stack parameters +HOOK: dummy-stack-params? cpu ( -- ? ) + +! If t, all FP parameters are shadowed by dummy int parameters +HOOK: dummy-int-params? cpu ( -- ? ) + +! If t, all int parameters are shadowed by dummy FP parameters +HOOK: dummy-fp-params? cpu ( -- ? ) HOOK: %prepare-unbox cpu ( -- ) diff --git a/basis/cpu/ppc/linux/linux.factor b/basis/cpu/ppc/linux/linux.factor index d92709a399..090495aa11 100644 --- a/basis/cpu/ppc/linux/linux.factor +++ b/basis/cpu/ppc/linux/linux.factor @@ -1,6 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ; +USING: accessors system kernel layouts +alien.c-types cpu.architecture cpu.ppc ; IN: cpu.ppc.linux << @@ -8,12 +9,16 @@ t "longlong" c-type (>>stack-align?) t "ulonglong" c-type (>>stack-align?) >> -M: linux reserved-area-size 2 ; +M: linux reserved-area-size 2 cells ; -M: linux lr-save 1 ; +M: linux lr-save 1 cells ; -M: float-regs param-regs { 1 2 3 4 5 6 7 8 } ; +M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ; -M: ppc value-structs? drop f ; +M: ppc value-structs? f ; -M: ppc fp-shadows-int? drop f ; +M: ppc dummy-stack-params? f ; + +M: ppc dummy-int-params? f ; + +M: ppc dummy-fp-params? f ; diff --git a/basis/cpu/ppc/macosx/macosx.factor b/basis/cpu/ppc/macosx/macosx.factor index 1e0a6caca0..877fb37d31 100644 --- a/basis/cpu/ppc/macosx/macosx.factor +++ b/basis/cpu/ppc/macosx/macosx.factor @@ -1,6 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ; +USING: accessors system kernel layouts +alien.c-types cpu.architecture cpu.ppc ; IN: cpu.ppc.macosx << @@ -9,12 +10,16 @@ IN: cpu.ppc.macosx 4 "double" c-type (>>align) >> -M: macosx reserved-area-size 6 ; +M: macosx reserved-area-size 6 cells ; -M: macosx lr-save 2 ; +M: macosx lr-save 2 cells ; -M: float-regs param-regs { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ; +M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ; -M: ppc value-structs? drop t ; +M: ppc value-structs? t ; -M: ppc fp-shadows-int? drop t ; +M: ppc dummy-stack-params? t ; + +M: ppc dummy-int-params? t ; + +M: ppc dummy-fp-params? f ; diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor index d2d1e26396..49caae4bb8 100644 --- a/basis/cpu/ppc/ppc.factor +++ b/basis/cpu/ppc/ppc.factor @@ -4,7 +4,8 @@ USING: accessors assocs sequences kernel combinators make math math.order math.ranges system namespaces locals layouts words alien alien.c-types cpu.architecture cpu.ppc.assembler compiler.cfg.registers compiler.cfg.instructions -compiler.constants compiler.codegen compiler.codegen.fixup ; +compiler.constants compiler.codegen compiler.codegen.fixup +compiler.cfg.intrinsics compiler.cfg.stack-frame ; IN: cpu.ppc ! PowerPC register assignments: @@ -15,15 +16,19 @@ IN: cpu.ppc ! f0-f29: float vregs ! f30, f31: float scratch +enable-float-intrinsics + +<< \ ##integer>float t frame-required? set-word-prop +\ ##float>integer t frame-required? set-word-prop >> + M: ppc machine-registers { { int-regs T{ range f 2 26 1 } } - { double-float-regs T{ range f 0 28 1 } } + { double-float-regs T{ range f 0 29 1 } } } ; : scratch-reg 28 ; inline -: fp-scratch-reg-1 29 ; inline -: fp-scratch-reg-2 30 ; inline +: fp-scratch-reg 30 ; inline M: ppc two-operand? f ; @@ -54,8 +59,16 @@ M: ppc %inc-d ( n -- ) ds-reg (%inc) ; M: ppc %inc-r ( n -- ) rs-reg (%inc) ; HOOK: reserved-area-size os ( -- n ) -HOOK: lr-save os ( -- n ) +! The start of the stack frame contains the size of this frame +! as well as the currently executing XT +: factor-area-size ( -- n ) 2 cells ; foldable +: next-save ( n -- i ) cell - ; +: xt-save ( n -- i ) 2 cells - ; + +! Next, we have the spill area as well as the FFI parameter area. +! They overlap, since basic blocks with FFI calls will never +! spill. : param@ ( n -- x ) reserved-area-size + ; inline : param-save-size ( -- n ) 8 cells ; foldable @@ -63,19 +76,34 @@ HOOK: lr-save os ( -- n ) : local@ ( n -- x ) reserved-area-size param-save-size + + ; inline -: factor-area-size ( -- n ) 2 cells ; foldable +: spill-integer-base ( -- n ) + stack-frame get spill-counts>> double-float-regs swap at + double-float-regs reg-size * ; -: next-save ( n -- i ) cell - ; +: spill-integer@ ( n -- offset ) + cells spill-integer-base + param@ ; -: xt-save ( n -- i ) 2 cells - ; +: spill-float@ ( n -- offset ) + double-float-regs reg-size * param@ ; + +! Some FP intrinsics need a temporary scratch area in the stack +! frame, 8 bytes in size +: scratch@ ( n -- offset ) + stack-frame get total-size>> + factor-area-size - + param-save-size - + + ; + +! Finally we have the linkage area +HOOK: lr-save os ( -- n ) M: ppc stack-frame-size ( stack-frame -- i ) [ spill-counts>> [ swap reg-size * ] { } assoc>map sum ] [ params>> ] [ return>> ] tri + + - reserved-area-size + param-save-size + + reserved-area-size + factor-area-size + 4 cells align ; @@ -198,19 +226,19 @@ M: ppc %div-float FDIV ; M:: ppc %integer>float ( dst src -- ) HEX: 4330 scratch-reg LIS - scratch-reg 1 0 param@ STW + scratch-reg 1 0 scratch@ STW scratch-reg src MR scratch-reg dup HEX: 8000 XORIS - scratch-reg 1 cell param@ STW - fp-scratch-reg-2 1 0 param@ LFD + scratch-reg 1 4 scratch@ STW + dst 1 0 scratch@ LFD scratch-reg 4503601774854144.0 %load-indirect - fp-scratch-reg-2 scratch-reg float-offset LFD - fp-scratch-reg-2 fp-scratch-reg-2 fp-scratch-reg-2 FSUB ; + fp-scratch-reg scratch-reg float-offset LFD + dst dst fp-scratch-reg FSUB ; M:: ppc %float>integer ( dst src -- ) - fp-scratch-reg-1 src FCTIWZ - fp-scratch-reg-2 1 0 param@ STFD - dst 1 4 param@ LWZ ; + fp-scratch-reg src FCTIWZ + fp-scratch-reg 1 0 scratch@ STFD + dst 1 4 scratch@ LWZ ; M: ppc %copy ( dst src -- ) MR ; @@ -218,6 +246,10 @@ M: ppc %copy-float ( dst src -- ) FMR ; M: ppc %unbox-float ( dst src -- ) float-offset LFD ; +M:: ppc %box-float ( dst src temp -- ) + dst 16 float temp %allot + src dst float-offset STFD ; + M:: ppc %unbox-any-c-ptr ( dst src temp -- ) [ { "is-byte-array" "end" "start" } [ define-label ] each @@ -349,12 +381,12 @@ M: ppc %gc "end" resolve-label ; M: ppc %prologue ( n -- ) - 0 scratch-reg LOAD32 rc-absolute-ppc-2/2 rel-this + 0 11 LOAD32 rc-absolute-ppc-2/2 rel-this 0 MFLR 1 1 pick neg ADDI - scratch-reg 1 pick xt-save STW - dup scratch-reg LI - scratch-reg 1 pick next-save STW + 11 1 pick xt-save STW + dup 11 LI + 11 1 pick next-save STW 0 1 rot lr-save + STW ; M: ppc %epilogue ( n -- ) @@ -405,32 +437,11 @@ M: ppc %compare-branch (%compare) %branch ; M: ppc %compare-imm-branch (%compare-imm) %branch ; M: ppc %compare-float-branch (%compare-float) %branch ; -: spill-integer-base ( stack-frame -- n ) - [ params>> ] [ return>> ] bi + ; +M: ppc %spill-integer ( src n -- ) spill-integer@ 1 swap STW ; +M: ppc %reload-integer ( dst n -- ) spill-integer@ 1 swap LWZ ; -: stack@ 1 swap ; inline - -: spill-integer@ ( n -- reg offset ) - cells - stack-frame get spill-integer-base - + stack@ ; - -: spill-float-base ( stack-frame -- n ) - [ spill-counts>> int-regs swap at int-regs reg-size * ] - [ params>> ] - [ return>> ] - tri + + ; - -: spill-float@ ( n -- reg offset ) - double-float-regs reg-size * - stack-frame get spill-float-base - + stack@ ; - -M: ppc %spill-integer ( src n -- ) spill-integer@ STW ; -M: ppc %reload-integer ( dst n -- ) spill-integer@ LWZ ; - -M: ppc %spill-float ( src n -- ) spill-float@ STFD ; -M: ppc %reload-float ( dst n -- ) spill-float@ LFD ; +M: ppc %spill-float ( src n -- ) spill-float@ 1 swap STFD ; +M: ppc %reload-float ( dst n -- ) spill-float@ 1 swap LFD ; M: ppc %loop-entry ; diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor index 82fa7a012e..f26d76551a 100644 --- a/basis/cpu/x86/32/32.factor +++ b/basis/cpu/x86/32/32.factor @@ -274,6 +274,12 @@ M: x86.32 %callback-return ( n -- ) [ drop 0 ] } cond RET ; +M: x86.32 dummy-stack-params? f ; + +M: x86.32 dummy-int-params? f ; + +M: x86.32 dummy-fp-params? f ; + os windows? [ cell "longlong" c-type (>>align) cell "ulonglong" c-type (>>align) diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index d45dd098b8..0d20660021 100644 --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -26,6 +26,7 @@ M: x86.64 temp-reg-2 RCX ; : param-reg-1 int-regs param-regs first ; inline : param-reg-2 int-regs param-regs second ; inline +: param-reg-3 int-regs param-regs third ; inline M: int-regs return-reg drop RAX ; M: float-regs return-reg drop XMM0 ; @@ -40,13 +41,13 @@ M: x86.64 %prologue ( n -- ) M: stack-params %load-param-reg drop - >r R11 swap stack@ MOV - r> stack@ R11 MOV ; + >r R11 swap param@ MOV + r> param@ R11 MOV ; M: stack-params %save-param-reg drop R11 swap next-stack@ MOV - stack@ R11 MOV ; + param@ R11 MOV ; : with-return-regs ( quot -- ) [ @@ -55,37 +56,6 @@ M: stack-params %save-param-reg call ] with-scope ; inline -! The ABI for passing structs by value is pretty messed up -<< "void*" c-type clone "__stack_value" define-primitive-type -stack-params "__stack_value" c-type (>>reg-class) >> - -: struct-types&offset ( struct-type -- pairs ) - fields>> [ - [ type>> ] [ offset>> ] bi 2array - ] map ; - -: split-struct ( pairs -- seq ) - [ - [ 8 mod zero? [ t , ] when , ] assoc-each - ] { } make { t } split harvest ; - -: flatten-small-struct ( c-type -- seq ) - struct-types&offset split-struct [ - [ c-type c-type-reg-class ] map - int-regs swap member? "void*" "double" ? c-type - ] map ; - -: flatten-large-struct ( c-type -- seq ) - heap-size cell align - cell /i "__stack_value" c-type ; - -M: struct-type flatten-value-type ( type -- seq ) - dup heap-size 16 > [ - flatten-large-struct - ] [ - flatten-small-struct - ] if ; - M: x86.64 %prepare-unbox ( -- ) ! First parameter is top of stack param-reg-1 R14 [] MOV @@ -102,7 +72,7 @@ M: x86.64 %unbox-long-long ( n func -- ) : %unbox-struct-field ( c-type i -- ) ! Alien must be in param-reg-1. - param-reg-1 swap cells [+] swap reg-class>> { + R11 swap cells [+] swap reg-class>> { { int-regs [ int-regs get pop swap MOV ] } { double-float-regs [ float-regs get pop swap MOVSD ] } } case ; @@ -110,20 +80,20 @@ M: x86.64 %unbox-long-long ( n func -- ) M: x86.64 %unbox-small-struct ( c-type -- ) ! Alien must be in param-reg-1. "alien_offset" f %alien-invoke - ! Move alien_offset() return value to param-reg-1 so that we don't + ! Move alien_offset() return value to R11 so that we don't ! clobber it. - param-reg-1 RAX MOV + R11 RAX MOV [ - flatten-small-struct [ %unbox-struct-field ] each-index + flatten-value-type [ %unbox-struct-field ] each-index ] with-return-regs ; M: x86.64 %unbox-large-struct ( n c-type -- ) ! Source is in param-reg-1 heap-size ! Load destination address - param-reg-2 rot stack@ LEA + param-reg-2 rot param@ LEA ! Load structure size - RDX swap MOV + param-reg-3 swap MOV ! Copy the struct to the C stack "to_value_struct" f %alien-invoke ; @@ -142,10 +112,7 @@ M: x86.64 %box ( n reg-class func -- ) M: x86.64 %box-long-long ( n func -- ) int-regs swap %box ; -M: x86.64 struct-small-enough? ( size -- ? ) - heap-size 2 cells <= ; - -: box-struct-field@ ( i -- operand ) 1+ cells stack@ ; +: box-struct-field@ ( i -- operand ) 1+ cells param@ ; : %box-struct-field ( c-type i -- ) box-struct-field@ swap reg-class>> { @@ -156,15 +123,15 @@ M: x86.64 struct-small-enough? ( size -- ? ) M: x86.64 %box-small-struct ( c-type -- ) #! Box a <= 16-byte struct. [ - [ flatten-small-struct [ %box-struct-field ] each-index ] - [ RDX swap heap-size MOV ] bi + [ flatten-value-type [ %box-struct-field ] each-index ] + [ param-reg-3 swap heap-size MOV ] bi param-reg-1 0 box-struct-field@ MOV param-reg-2 1 box-struct-field@ MOV "box_small_struct" f %alien-invoke ] with-return-regs ; : struct-return@ ( n -- operand ) - [ stack-frame get params>> ] unless* stack@ ; + [ stack-frame get params>> ] unless* param@ ; M: x86.64 %box-large-struct ( n c-type -- ) ! Struct size is parameter 2 @@ -178,7 +145,7 @@ M: x86.64 %prepare-box-struct ( -- ) ! Compute target address for value struct return RAX f struct-return@ LEA ! Store it as the first parameter - 0 stack@ RAX MOV ; + 0 param@ RAX MOV ; M: x86.64 %prepare-var-args RAX RAX XOR ; diff --git a/basis/cpu/x86/64/unix/unix.factor b/basis/cpu/x86/64/unix/unix.factor index abbd0cf21b..ddb412873a 100644 --- a/basis/cpu/x86/64/unix/unix.factor +++ b/basis/cpu/x86/64/unix/unix.factor @@ -1,7 +1,9 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel layouts system compiler.cfg.registers -cpu.architecture cpu.x86.assembler cpu.x86 ; +USING: accessors arrays sequences math splitting make assocs +kernel layouts system alien.c-types alien.structs +cpu.architecture cpu.x86.assembler cpu.x86 +compiler.codegen compiler.cfg.registers ; IN: cpu.x86.64.unix M: int-regs param-regs drop { RDI RSI RDX RCX R8 R9 } ; @@ -10,3 +12,43 @@ M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; M: x86.64 reserved-area-size 0 ; + +! The ABI for passing structs by value is pretty messed up +<< "void*" c-type clone "__stack_value" define-primitive-type +stack-params "__stack_value" c-type (>>reg-class) >> + +: struct-types&offset ( struct-type -- pairs ) + fields>> [ + [ type>> ] [ offset>> ] bi 2array + ] map ; + +: split-struct ( pairs -- seq ) + [ + [ 8 mod zero? [ t , ] when , ] assoc-each + ] { } make { t } split harvest ; + +: flatten-small-struct ( c-type -- seq ) + struct-types&offset split-struct [ + [ c-type c-type-reg-class ] map + int-regs swap member? "void*" "double" ? c-type + ] map ; + +: flatten-large-struct ( c-type -- seq ) + heap-size cell align + cell /i "__stack_value" c-type ; + +M: struct-type flatten-value-type ( type -- seq ) + dup heap-size 16 > [ + flatten-large-struct + ] [ + flatten-small-struct + ] if ; + +M: x86.64 struct-small-enough? ( size -- ? ) + heap-size 2 cells <= ; + +M: x86.64 dummy-stack-params? f ; + +M: x86.64 dummy-int-params? f ; + +M: x86.64 dummy-fp-params? f ; diff --git a/basis/cpu/x86/64/winnt/winnt.factor b/basis/cpu/x86/64/winnt/winnt.factor index d4c092f63d..0124c40877 100644 --- a/basis/cpu/x86/64/winnt/winnt.factor +++ b/basis/cpu/x86/64/winnt/winnt.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel layouts system alien.c-types compiler.cfg.registers -cpu.architecture cpu.x86.assembler cpu.x86 ; +USING: kernel layouts system math alien.c-types +compiler.cfg.registers cpu.architecture cpu.x86.assembler cpu.x86 ; IN: cpu.x86.64.winnt M: int-regs param-regs drop { RCX RDX R8 R9 } ; @@ -10,6 +10,15 @@ M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ; M: x86.64 reserved-area-size 4 cells ; +M: x86.64 struct-small-enough? ( size -- ? ) + heap-size cell <= ; + +M: x86.64 dummy-stack-params? f ; + +M: x86.64 dummy-int-params? t ; + +M: x86.64 dummy-fp-params? t ; + << "longlong" "ptrdiff_t" typedef "int" "long" typedef diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index 55675a5e42..4f72fe45e1 100644 --- a/basis/cpu/x86/x86.factor +++ b/basis/cpu/x86/x86.factor @@ -467,6 +467,8 @@ M: x86 %compare-float-branch ( label cc src1 src2 -- ) : stack@ ( n -- op ) stack-reg swap [+] ; +: param@ ( n -- op ) reserved-area-size + stack@ ; + : spill-integer-base ( stack-frame -- n ) [ params>> ] [ return>> ] bi + reserved-area-size + ; @@ -493,16 +495,16 @@ M: x86 %reload-float ( dst n -- ) spill-float@ MOVSD ; M: x86 %loop-entry 16 code-alignment [ NOP ] times ; -M: int-regs %save-param-reg drop >r stack@ r> MOV ; -M: int-regs %load-param-reg drop swap stack@ MOV ; +M: int-regs %save-param-reg drop >r param@ r> MOV ; +M: int-regs %load-param-reg drop swap param@ MOV ; GENERIC: MOVSS/D ( dst src reg-class -- ) M: single-float-regs MOVSS/D drop MOVSS ; M: double-float-regs MOVSS/D drop MOVSD ; -M: float-regs %save-param-reg >r >r stack@ r> r> MOVSS/D ; -M: float-regs %load-param-reg >r swap stack@ r> MOVSS/D ; +M: float-regs %save-param-reg >r >r param@ r> r> MOVSS/D ; +M: float-regs %load-param-reg >r swap param@ r> MOVSS/D ; GENERIC: push-return-reg ( reg-class -- ) GENERIC: load-return-reg ( n reg-class -- ) @@ -518,8 +520,6 @@ M: x86 %prepare-alien-invoke temp-reg-1 2 cells [+] ds-reg MOV temp-reg-1 3 cells [+] rs-reg MOV ; -M: x86 fp-shadows-int? ( -- ? ) f ; - M: x86 value-structs? t ; M: x86 small-enough? ( n -- ? ) diff --git a/basis/dlists/dlists-tests.factor b/basis/dlists/dlists-tests.factor index 15022452ee..92b141dca8 100644 --- a/basis/dlists/dlists-tests.factor +++ b/basis/dlists/dlists-tests.factor @@ -77,3 +77,10 @@ IN: dlists.tests [ f ] [ 3 over push-front 4 over push-back -1 swap deque-member? ] unit-test [ f ] [ 0 swap deque-member? ] unit-test + +! Make sure clone does the right thing +[ V{ 2 1 } V{ 2 1 3 } ] [ + 1 over push-front 2 over push-front + dup clone 3 over push-back + [ dlist>seq ] bi@ +] unit-test diff --git a/basis/dlists/dlists.factor b/basis/dlists/dlists.factor index 3b3cae2820..5072c3edfd 100644 --- a/basis/dlists/dlists.factor +++ b/basis/dlists/dlists.factor @@ -154,6 +154,14 @@ M: dlist clear-deque ( dlist -- ) : dlist-each ( dlist quot -- ) [ obj>> ] prepose dlist-each-node ; inline +: dlist>seq ( dlist -- seq ) + [ ] pusher [ dlist-each ] dip ; + : 1dlist ( obj -- dlist ) [ push-front ] keep ; +M: dlist clone + [ + [ push-back ] curry dlist-each + ] keep ; + INSTANCE: dlist deque diff --git a/basis/fry/fry.factor b/basis/fry/fry.factor index 395d5c3caf..87c59e18a0 100644 --- a/basis/fry/fry.factor +++ b/basis/fry/fry.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences combinators parser splitting math -quotations arrays make qualified words ; +quotations arrays make words ; IN: fry : _ ( -- * ) "Only valid inside a fry" throw ; diff --git a/basis/help/tutorial/tutorial.factor b/basis/help/tutorial/tutorial.factor index cafa758c7e..afa16bbf8a 100644 --- a/basis/help/tutorial/tutorial.factor +++ b/basis/help/tutorial/tutorial.factor @@ -1,29 +1,24 @@ USING: help.markup help.syntax ui.commands ui.operations ui.tools.search ui.tools.workspace editors vocabs.loader kernel sequences prettyprint tools.test tools.vocabs strings -unicode.categories unicode.case ; +unicode.categories unicode.case ui.tools.browser ; IN: help.tutorial ARTICLE: "first-program-start" "Creating a vocabulary for your first program" "Factor source code is organized into " { $link "vocabularies" } ". Before we can write our first program, we must create a vocabulary for it." $nl -"Start by asking Factor for the path to your ``work'' directory, where you will place your own code:" +"Start by loading the scaffold tool:" +{ $code "USE: tools.scaffold" } +"Then, ask the scaffold tool to create a new vocabulary named " { $snippet "palindrome" } ":" +{ $code "\"resource:work\" \"palindrome\" scaffold-vocab" } +"If you look at the output, you will see that a few files were created in your ``work'' directory. The following phrase will print the full path of your work directory:" { $code "\"work\" resource-path ." } -"Open the work directory in your file manager, and create a subdirectory named " { $snippet "palindrome" } ". Inside this directory, create a file named " { $snippet "palindrome.factor" } " using your favorite text editor. Leave the file empty for now." +"Open the work directory in your file manager, and open the subdirectory named " { $snippet "palindrome" } ". Inside this subdirectory you will see a file named " { $snippet "palindrome.factor" } ". We will be editing this file." $nl -"Inside the Factor listener, type" -{ $code "USE: palindrome" } -"The source file should now load. Since it is empty, it does nothing. If you get an error message, make sure you created the directory and the file in the right place and gave them the right names." -$nl -"Now, we will start filling out this source file. Go back to your editor, and type:" -{ $code - "! Copyright (C) 2008 " - "! See http://factorcode.org/license.txt for BSD license." -} -"This is the standard header for Factor source files; it consists of two " { $link "syntax-comments" } "." -$nl -"Now, we tell Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:" +"Notice that the file ends with an " { $link POSTPONE: IN: } " form telling Factor that all definitions in this source file should go into the " { $snippet "palindrome" } " vocabulary using the " { $link POSTPONE: IN: } " word:" { $code "IN: palindrome" } +"We will add new definitions after the " { $link POSTPONE: IN: } " form." +$nl "You are now ready to go on to the next section: " { $link "first-program-logic" } "." ; ARTICLE: "first-program-logic" "Writing some logic in your first program" @@ -43,20 +38,16 @@ $nl $nl "When you do this, you will get an error about the " { $link dup } " word not being found. This is because this word is part of the " { $vocab-link "kernel" } " vocabulary, but this vocabulary is not part of the source file's " { $link "vocabulary-search" } ". You must explicitly list dependencies in source files. This allows Factor to automatically load required vocabularies and makes larger programs easier to maintain." $nl -"To add the word to the search path, first convince yourself that this word is in the " { $vocab-link "kernel" } " vocabulary by entering the following in the listener:" -{ $code "\\ dup see" } -"This shows the definition of " { $link dup } ", along with an " { $link POSTPONE: IN: } " form." +"To add the word to the search path, first convince yourself that this word is in the " { $vocab-link "kernel" } " vocabulary. Enter " { $snippet "dup" } " in the listener's input area, and press " { $operation com-follow } ". This will open the documentation browser tool, viewing the help for the " { $link dup } " word. One of the subheadings in the help article will mention the word's vocabulary." $nl -"Now, add the following at the start of the source file:" +"So now, add the following at the start of the source file:" { $code "USING: kernel ;" } -"Next, find out what vocabulary " { $link reverse } " lives in:" -{ $code "\\ reverse see" } +"Next, find out what vocabulary " { $link reverse } " lives in; type the word name " { $snippet "reverse" } " in the workspace listener's input area, and press " { $operation com-follow } "." +$nl "It lives in the " { $vocab-link "sequences" } " vocabulary, so we add that to the search path:" { $code "USING: kernel sequences ;" } -"Finally, check what vocabulary " { $link = } " lives in:" -{ $code "\\ = see" } -"It's in the " { $vocab-link "kernel" } " vocabulary, which we've already added to the search path." - +"Finally, check what vocabulary " { $link = } " lives in, and confirm that it's in the " { $vocab-link "kernel" } " vocabulary, which we've already added to the search path." +$nl "Now press " { $command workspace "workflow" refresh-all } " again, and the source file should reload without any errors. You can now go on and learn about " { $link "first-program-test" } "." ; ARTICLE: "first-program-test" "Testing your first program" @@ -81,9 +72,9 @@ $nl { $code "." } "What we just did is called " { $emphasis "interactive testing" } ". A more advanced technique which comes into play with larger programs is " { $link "tools.test" } "." $nl -"Create a file named " { $snippet "palindrome-tests.factor" } " in the same directory as " { $snippet "palindrome.factor" } ". Now, we can run unit tests from the listener:" -{ $code "\"palindrome\" test" } -"We will add some unit tests corresponding to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values." +"Open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool." +$nl +"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values." $nl "Add the following three lines to " { $snippet "palindrome-tests.factor" } ":" { $code @@ -145,7 +136,7 @@ $nl ARTICLE: "first-program" "Your first program" "In this tutorial, we will write a simple Factor program which prompts the user to enter a word, and tests if it is a palindrome (that is, the word is spelled the same backwards and forwards)." $nl -"In this tutorial, you will learn about basic Factor development tools, as well as application deployment." +"In this tutorial, you will learn about basic Factor development tools. You may want to open a second workspace window by pressing " { $command workspace "workflow" workspace-window } "; this will allow you to read this tutorial and browse other documentation at the same time." { $subsection "first-program-start" } { $subsection "first-program-logic" } { $subsection "first-program-test" } diff --git a/basis/io/encodings/string/string-docs.factor b/basis/io/encodings/string/string-docs.factor index 0a35eee272..dc0f547301 100644 --- a/basis/io/encodings/string/string-docs.factor +++ b/basis/io/encodings/string/string-docs.factor @@ -4,7 +4,8 @@ USING: help.markup help.syntax byte-arrays strings ; IN: io.encodings.string ARTICLE: "io.encodings.string" "Encoding and decoding strings" -"Strings can be encoded or decoded to and from byte arrays through an encoding with the following words:" +"Strings can be encoded or decoded to and from byte arrays through an encoding by passing " +{ $link "encodings-descriptors" } " to the following words:" { $subsection encode } { $subsection decode } ; diff --git a/basis/io/servers/connection/connection-docs.factor b/basis/io/servers/connection/connection-docs.factor index 00711ce226..22c40da3d7 100644 --- a/basis/io/servers/connection/connection-docs.factor +++ b/basis/io/servers/connection/connection-docs.factor @@ -45,15 +45,20 @@ ARTICLE: "server-config-handler" "Client handler quotation" $nl "The two methods are equivalent, representing a functional versus an object-oriented approach to the problem." ; +ARTICLE: "server-examples" "Threaded server examples" +"The " { $vocab-link "time-server" } " vocabulary implements a simple threaded server which sends the current time to the client. The " { $vocab-link "concurrency.distributed" } ", " { $vocab-link "ftp.server" } ", and " { $vocab-link "http.server" } " vocabularies demonstrate more complex usage of the threaded server library." ; + ARTICLE: "io.servers.connection" "Threaded servers" "The " { $vocab-link "io.servers.connection" } " vocabulary implements a generic server abstraction for " { $link "network-connection" } ". A set of threads listen for connections, and additional threads are spawned for each client connection. In addition to this basic functionality, it provides some advanced features such as logging, connection limits and secure socket support." -{ $subsection threaded-server } -{ $subsection "server-config" } +{ $subsection "server-examples" } "Creating threaded servers with client handler quotations:" { $subsection } "Client handlers can also be implemented by subclassing a threaded server; see " { $link "server-config-handler" } " for details:" +{ $subsection threaded-server } { $subsection new-threaded-server } { $subsection handle-client* } +"The server must be configured before it can be started." +{ $subsection "server-config" } "Starting the server:" { $subsection start-server } { $subsection start-server* } diff --git a/basis/io/unix/launcher/parser/parser.factor b/basis/io/unix/launcher/parser/parser.factor index e5e83ab4e9..276ed45f27 100644 --- a/basis/io/unix/launcher/parser/parser.factor +++ b/basis/io/unix/launcher/parser/parser.factor @@ -29,5 +29,5 @@ IN: io.unix.launcher.parser PEG: tokenize-command ( command -- ast/f ) 'argument' " " token repeat1 list-of - " " token repeat0 swap over pack + " " token repeat0 tuck pack just ; diff --git a/basis/io/windows/files/files.factor b/basis/io/windows/files/files.factor old mode 100644 new mode 100755 index 3fb8029ee7..3952299543 --- a/basis/io/windows/files/files.factor +++ b/basis/io/windows/files/files.factor @@ -276,7 +276,7 @@ M: winnt file-system-info ( path -- file-system-info ) swap >>type swap >>mount-point ; -: find-first-volume ( word -- string handle ) +: find-first-volume ( -- string handle ) MAX_PATH 1+ dup length dupd FindFirstVolume dup win32-error=0/f diff --git a/basis/locals/locals-docs.factor b/basis/locals/locals-docs.factor index eb368936d4..35e0536530 100644 --- a/basis/locals/locals-docs.factor +++ b/basis/locals/locals-docs.factor @@ -1,5 +1,5 @@ USING: help.syntax help.markup kernel macros prettyprint -memoize ; +memoize combinators arrays ; IN: locals HELP: [| @@ -84,6 +84,39 @@ HELP: MEMO:: { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words +ARTICLE: "locals-literals" "Locals in array and hashtable literals" +"Certain data type literals are permitted to contain free variables. Any such literals are written into code which constructs an instance of the type with the free variable values spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables." +$nl +"The data types which receive this special handling are the following:" +{ $list + { $link "arrays" } + { $link "hashtables" } + { $link "vectors" } + { $link "tuples" } +} +"This feature changes the semantics of literal object identity. An ordinary word containing a literal pushes the same literal on the stack every time it is invoked:" +{ $example + "IN: scratchpad" + "TUPLE: person first-name last-name ;" + ": ordinary-word-test ( -- tuple )" + " T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;" + "ordinary-word-test ordinary-word-test eq? ." + "t" +} +"In a word with locals, literals expand into code which constructs the literal, and so every invocation pushes a new object:" +{ $example + "IN: scratchpad" + "TUPLE: person first-name last-name ;" + ":: ordinary-word-test ( -- tuple )" + " T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;" + "ordinary-word-test ordinary-word-test eq? ." + "f" +} +"One exception to the above rule is that array instances containing no free variables do retain identity. This allows macros such as " { $link cond } " to recognize that the array is constant and expand at compile-time." +$nl +"For example, here is an implementation of the " { $link 3array } " word which uses this feature:" +{ $code ":: 3array ( x y z -- array ) { x y z } ;" } ; + ARTICLE: "locals-mutable" "Mutable locals" "In the list of bindings supplied to " { $link POSTPONE: :: } ", " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } " or " { $link POSTPONE: [| } ", a mutable binding may be introduced by suffixing its named with " { $snippet "!" } ". Mutable bindings are read by giving their name as usual; the suffix is not part of the binding's name. To write to a mutable binding, use the binding's name with the " { $snippet "!" } " suffix." $nl @@ -139,6 +172,7 @@ $nl "Lambda abstractions:" { $subsection POSTPONE: [| } "Additional topics:" +{ $subsection "locals-literals" } { $subsection "locals-mutable" } { $subsection "locals-limitations" } "Locals complement dynamically scoped variables implemented in the " { $vocab-link "namespaces" } " vocabulary." ; diff --git a/basis/math/bitwise/bitwise-docs.factor b/basis/math/bitwise/bitwise-docs.factor index 247523369b..4f2606bda0 100644 --- a/basis/math/bitwise/bitwise-docs.factor +++ b/basis/math/bitwise/bitwise-docs.factor @@ -1,12 +1,8 @@ -USING: help.markup help.syntax math ; +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax math sequences ; IN: math.bitwise -ARTICLE: "math-bitfields" "Constructing bit fields" -"Some applications, such as binary communication protocols and assemblers, need to construct integers from elaborate bit field specifications. Hand-coding this using " { $link shift } " and " { $link bitor } " results in repetitive code. A higher-level facility exists to factor out this repetition:" -{ $subsection bitfield } ; - -ABOUT: "math-bitfields" - HELP: bitfield { $values { "values..." "a series of objects" } { "bitspec" "an array" } { "n" integer } } { $description "Constructs an integer from a series of values on the stack together with a bit field specifier, which is an array whose elements have one of the following shapes:" @@ -42,9 +38,307 @@ HELP: bits { $example "USING: math.bitwise prettyprint ;" "HEX: 123abcdef 16 bits .h" "cdef" } ; HELP: bitroll -{ $values { "x" "an integer (input)" } { "s" "an integer (shift)" } { "w" "an integer (wrap)" } { "y" integer } } +{ $values { "x" integer } { "s" "a shift integer" } { "w" "a wrap integer" } { "y" integer } +} { $description "Roll n by s bits to the left, wrapping around after w bits." } { $examples { $example "USING: math.bitwise prettyprint ;" "1 -1 32 bitroll .b" "10000000000000000000000000000000" } { $example "USING: math.bitwise prettyprint ;" "HEX: ffff0000 8 32 bitroll .h" "ff0000ff" } } ; + +HELP: bit-clear? +{ $values + { "x" integer } { "n" integer } + { "?" "a boolean" } +} +{ $description "Returns " { $link t } " if the nth bit is set to zero." } +{ $examples + { $example "USING: math.bitwise prettyprint ;" + "HEX: ff 8 bit-clear? ." + "t" + } + { $example "" "USING: math.bitwise prettyprint ;" + "HEX: ff 7 bit-clear? ." + "f" + } +} ; + +{ bit? bit-clear? set-bit clear-bit } related-words + +HELP: bit-count +{ $values + { "x" integer } + { "n" integer } +} +{ $description "Returns the number of set bits as an integer." } +{ $examples + { $example "USING: math.bitwise prettyprint ;" + "HEX: f0 bit-count ." + "4" + } + { $example "USING: math.bitwise prettyprint ;" + "-7 bit-count ." + "2" + } +} ; + +HELP: bitroll-32 +{ $values + { "n" integer } { "s" integer } + { "n'" integer } +} +{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 32 bits." } +{ $examples + { $example "USING: math.bitwise prettyprint ;" + "HEX: 1 10 bitroll-32 .h" + "400" + } + { $example "USING: math.bitwise prettyprint ;" + "HEX: 1 -10 bitroll-32 .h" + "400000" + } +} ; + +HELP: bitroll-64 +{ $values + { "n" integer } { "s" "a shift integer" } + { "n'" integer } +} +{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 64 bits." } +{ $examples + { $example "USING: math.bitwise prettyprint ;" + "HEX: 1 10 bitroll-64 .h" + "400" + } + { $example "USING: math.bitwise prettyprint ;" + "HEX: 1 -10 bitroll-64 .h" + "40000000000000" + } +} ; + +{ bitroll bitroll-32 bitroll-64 } related-words + +HELP: clear-bit +{ $values + { "x" integer } { "n" integer } + { "y" integer } +} +{ $description "Sets the nth bit of " { $snippet "x" } " to zero." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ff 7 clear-bit .h" + "7f" + } +} ; + +HELP: flags +{ $values + { "values" sequence } +} +{ $description "Constructs a constant flag value from a sequence of integers or words that output integers. The resulting constant is computed at compile-time, which makes this word as efficient as using a literal integer." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "IN: scratchpad" + ": MY-CONSTANT HEX: 1 ; inline" + "{ HEX: 20 MY-CONSTANT BIN: 100 } flags .h" + "25" + } +} ; + +HELP: mask +{ $values + { "x" integer } { "n" integer } + { "?" "a boolean" } +} +{ $description "After the operation, only the bits that were set in both the mask and the original number are set." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "BIN: 11111111 BIN: 101 mask .b" + "101" + } +} ; + +HELP: mask-bit +{ $values + { "m" integer } { "n" integer } + { "m'" integer } +} +{ $description "Turns off all bits besides the nth bit." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ff 2 mask-bit .b" + "100" + } +} ; + +HELP: mask? +{ $values + { "x" integer } { "n" integer } + { "?" "a boolean" } +} +{ $description "Returns true if all of the bits in the mask " { $snippet "n" } " are set in the integer input " { $snippet "x" } "." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ff HEX: f mask? ." + "t" + } + + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: f0 HEX: 1 mask? ." + "f" + } +} ; + +HELP: on-bits +{ $values + { "n" integer } + { "m" integer } +} +{ $description "Returns an integer with " { $snippet "n" } " bits set." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "6 on-bits .h" + "3f" + } + { $example "USING: math.bitwise kernel prettyprint ;" + "64 on-bits .h" + "ffffffffffffffff" + } +} +; + +HELP: set-bit +{ $values + { "x" integer } { "n" integer } + { "y" integer } +} +{ $description "Sets the nth bit of " { $snippet "x" } "." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "0 5 set-bit .h" + "20" + } +} ; + +HELP: shift-mod +{ $values + { "n" integer } { "s" integer } { "w" integer } + { "n" integer } +} +{ $description "" } ; + +HELP: unmask +{ $values + { "x" integer } { "n" integer } + { "?" "a boolean" } +} +{ $description "Clears the bits in " { $snippet "x" } " if they are set in the mask " { $snippet "n" } "." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ff HEX: 0f unmask .h" + "f0" + } +} ; + +HELP: unmask? +{ $values + { "x" integer } { "n" integer } + { "?" "a boolean" } +} +{ $description "Tests whether unmasking the bits in " { $snippet "x" } " would return an integer greater than zero." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ff HEX: 0f unmask? ." + "t" + } +} ; + +HELP: w* +{ $values + { "int" integer } { "int" integer } + { "int" integer } +} +{ $description "Multiplies two integers and wraps the result to 32 bits." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ffffffff HEX: 2 w* ." + "4294967294" + } +} ; + +HELP: w+ +{ $values + { "int" integer } { "int" integer } + { "int" integer } +} +{ $description "Adds two integers and wraps the result to 32 bits." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: ffffffff HEX: 2 w+ ." + "1" + } +} ; + +HELP: w- +{ $values + { "int" integer } { "int" integer } + { "int" integer } +} +{ $description "Subtracts two integers and wraps the result to 32 bits." } +{ $examples + { $example "USING: math.bitwise kernel prettyprint ;" + "HEX: 0 HEX: ff w- ." + "4294967041" + } +} ; + +HELP: wrap +{ $values + { "m" integer } { "n" integer } + { "m'" integer } +} +{ $description "Wraps an integer " { $snippet "m" } " by modding it by " { $snippet "n" } ". This word is uses bitwise arithmetic and does not actually call the modulus word, and as such can only mod by powers of two." } +{ $examples "Equivalent to modding by 8:" + { $example + "USING: math.bitwise prettyprint ;" + "HEX: ffff 8 wrap .h" + "7" + } +} ; + +ARTICLE: "math-bitfields" "Constructing bit fields" +"Some applications, such as binary communication protocols and assemblers, need to construct integers from elaborate bit field specifications. Hand-coding this using " { $link shift } " and " { $link bitor } " results in repetitive code. A higher-level facility exists to factor out this repetition:" +{ $subsection bitfield } ; + +ARTICLE: "math.bitwise" "Bitwise arithmetic" +"The " { $vocab-link "math.bitwise" } " vocabulary can implements bitwise arithmetic words that are useful for efficiency, low-level programming, and interfacing with C libraries." $nl +"Setting and clearing bits:" +{ $subsection set-bit } +{ $subsection clear-bit } +"Testing if bits are set or clear:" +{ $subsection bit? } +{ $subsection bit-clear? } +"Operations with bitmasks:" +{ $subsection mask } +{ $subsection unmask } +{ $subsection mask? } +{ $subsection unmask? } +"Generating an integer with n set bits:" +{ $subsection on-bits } +"Counting the number of set bits:" +{ $subsection bit-count } +"More efficient modding by powers of two:" +{ $subsection wrap } +"Bit-rolling:" +{ $subsection bitroll } +{ $subsection bitroll-32 } +{ $subsection bitroll-64 } +"32-bit arithmetic:" +{ $subsection w+ } +{ $subsection w- } +{ $subsection w* } +"Bitfields:" +{ $subsection flags } +{ $subsection "math-bitfields" } ; + +ABOUT: "math.bitwise" diff --git a/basis/math/bitwise/bitwise-tests.factor b/basis/math/bitwise/bitwise-tests.factor index 8b13cb23b3..4422992956 100644 --- a/basis/math/bitwise/bitwise-tests.factor +++ b/basis/math/bitwise/bitwise-tests.factor @@ -27,3 +27,5 @@ IN: math.bitwise.tests [ 3 ] [ foo ] unit-test [ 3 ] [ { a b } flags ] unit-test \ foo must-infer + +[ 1 ] [ { 1 } flags ] unit-test diff --git a/basis/math/bitwise/bitwise.factor b/basis/math/bitwise/bitwise.factor index 871f40e74c..ad1907fcb0 100644 --- a/basis/math/bitwise/bitwise.factor +++ b/basis/math/bitwise/bitwise.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007, 2008 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel math math.functions sequences sequences.private words namespaces macros hints @@ -8,28 +8,29 @@ IN: math.bitwise ! utilities : clear-bit ( x n -- y ) 2^ bitnot bitand ; inline : set-bit ( x n -- y ) 2^ bitor ; inline -: bit-clear? ( x n -- ? ) 2^ bitand zero? ; inline +: bit-clear? ( x n -- ? ) 2^ bitand 0 = ; inline : unmask ( x n -- ? ) bitnot bitand ; inline : unmask? ( x n -- ? ) unmask 0 > ; inline : mask ( x n -- ? ) bitand ; inline : mask? ( x n -- ? ) mask 0 > ; inline : wrap ( m n -- m' ) 1- bitand ; inline : bits ( m n -- m' ) 2^ wrap ; inline -: mask-bit ( m n -- m' ) 1- 2^ mask ; inline +: mask-bit ( m n -- m' ) 2^ mask ; inline +: on-bits ( n -- m ) 2^ 1- ; inline : shift-mod ( n s w -- n ) - >r shift r> 2^ wrap ; inline + [ shift ] dip 2^ wrap ; inline : bitroll ( x s w -- y ) - [ wrap ] keep - [ shift-mod ] - [ [ - ] keep shift-mod ] 3bi bitor ; inline + [ wrap ] keep + [ shift-mod ] + [ [ - ] keep shift-mod ] 3bi bitor ; inline -: bitroll-32 ( n s -- n' ) 32 bitroll ; +: bitroll-32 ( n s -- n' ) 32 bitroll ; inline HINTS: bitroll-32 bignum fixnum ; -: bitroll-64 ( n s -- n' ) 64 bitroll ; +: bitroll-64 ( n s -- n' ) 64 bitroll ; inline HINTS: bitroll-64 bignum fixnum ; @@ -40,7 +41,7 @@ HINTS: bitroll-64 bignum fixnum ; ! flags MACRO: flags ( values -- ) - [ 0 ] [ [ execute bitor ] curry compose ] reduce ; + [ 0 ] [ [ dup word? [ execute ] when bitor ] curry compose ] reduce ; ! bitfield r swapd execute r> ] [ ] ? + first2 over word? [ [ swapd execute ] dip ] [ ] ? [ shift bitor ] append 2curry ; PRIVATE> @@ -91,4 +92,4 @@ M: bignum (bit-count) PRIVATE> : bit-count ( x -- n ) - dup 0 >= [ (bit-count) ] [ bitnot (bit-count) ] if ; inline + dup 0 < [ bitnot ] when (bit-count) ; inline diff --git a/basis/math/functions/functions-tests.factor b/basis/math/functions/functions-tests.factor index cbaf37daf8..a06a67e4a1 100644 --- a/basis/math/functions/functions-tests.factor +++ b/basis/math/functions/functions-tests.factor @@ -134,3 +134,6 @@ IN: math.functions.tests [ -4.0 ] [ -4.4 round ] unit-test [ 5.0 ] [ 4.5 round ] unit-test [ 4.0 ] [ 4.4 round ] unit-test + +[ 6 59967 ] [ 3837888 factor-2s ] unit-test +[ 6 -59967 ] [ -3837888 factor-2s ] unit-test diff --git a/basis/math/functions/functions.factor b/basis/math/functions/functions.factor index 8516292e9d..43efc35c27 100644 --- a/basis/math/functions/functions.factor +++ b/basis/math/functions/functions.factor @@ -1,9 +1,12 @@ -! Copyright (C) 2004, 2007 Slava Pestov. +! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: math kernel math.constants math.private -math.libm combinators math.order ; +math.libm combinators math.order sequences ; IN: math.functions +: >fraction ( a/b -- a b ) + [ numerator ] [ denominator ] bi ; inline + ) ( x y -- z ) @@ -30,14 +33,35 @@ M: real sqrt 2dup >r >r >r odd? r> call r> 2/ r> each-bit ] if ; inline recursive -: ^n ( z w -- z^w ) - 1 swap [ - [ dupd * ] when >r sq r> - ] each-bit nip ; inline +: map-bits ( n quot: ( ? -- obj ) -- seq ) + accumulator [ each-bit ] dip ; inline + +: factor-2s ( n -- r s ) + #! factor an integer into 2^r * s + dup 0 = [ 1 ] [ + 0 swap [ dup even? ] [ [ 1+ ] [ 2/ ] bi* ] [ ] while + ] if ; inline + +fraction ] dip tuck [ ^n ] 2bi@ / ; + +M: float ^n + (^n) ; : integer^ ( x y -- z ) dup 0 > [ ^n ] [ neg ^n recip ] if ; inline +PRIVATE> + : >rect ( z -- x y ) [ real-part ] [ imaginary-part ] bi ; inline @@ -52,6 +76,8 @@ M: real sqrt : polar> ( abs arg -- z ) cis * ; inline +r >r >float-rect swap r> swap fpow r> rot * fexp /f ; inline @@ -68,6 +94,8 @@ M: real sqrt : 0^ ( x -- z ) dup zero? [ drop 0./0. ] [ 0 < 1./0. 0 ? ] if ; inline +PRIVATE> + : ^ ( x y -- z ) { { [ over zero? ] [ nip 0^ ] } diff --git a/basis/math/intervals/intervals-tests.factor b/basis/math/intervals/intervals-tests.factor index 0fdcb51291..8c29171a57 100644 --- a/basis/math/intervals/intervals-tests.factor +++ b/basis/math/intervals/intervals-tests.factor @@ -95,6 +95,10 @@ IN: math.intervals.tests [ empty-interval ] [ 0 5 (a,b] empty-interval interval-intersect ] unit-test +[ t ] [ + 0 1 (a,b) full-interval interval-intersect 0 1 (a,b) = +] unit-test + [ t ] [ empty-interval empty-interval interval-subset? ] unit-test @@ -209,22 +213,28 @@ IN: math.intervals.tests ! Interval random tester : random-element ( interval -- n ) - dup to>> first over from>> first tuck - random + - 2dup swap interval-contains? [ - nip + dup full-interval eq? [ + drop 32 random-bits 31 2^ - ] [ - drop random-element + dup to>> first over from>> first tuck - random + + 2dup swap interval-contains? [ + nip + ] [ + drop random-element + ] if ] if ; : random-interval ( -- interval ) - 2000 random 1000 - dup 2 1000 random + + - 1 random zero? [ [ neg ] bi@ swap ] when - 4 random { - { 0 [ [a,b] ] } - { 1 [ [a,b) ] } - { 2 [ (a,b) ] } - { 3 [ (a,b] ] } - } case ; + 10 random 0 = [ full-interval ] [ + 2000 random 1000 - dup 2 1000 random + + + 1 random zero? [ [ neg ] bi@ swap ] when + 4 random { + { 0 [ [a,b] ] } + { 1 [ [a,b) ] } + { 2 [ (a,b) ] } + { 3 [ (a,b] ] } + } case + ] if ; : random-unary-op ( -- pair ) { @@ -263,7 +273,7 @@ IN: math.intervals.tests { bitand interval-bitand } { bitor interval-bitor } { bitxor interval-bitxor } - { shift interval-shift } + ! { shift interval-shift } { min interval-min } { max interval-max } } diff --git a/basis/math/intervals/intervals.factor b/basis/math/intervals/intervals.factor index 33430e83c3..54ee0ac894 100644 --- a/basis/math/intervals/intervals.factor +++ b/basis/math/intervals/intervals.factor @@ -7,6 +7,8 @@ IN: math.intervals SYMBOL: empty-interval +SYMBOL: full-interval + TUPLE: interval { from read-only } { to read-only } ; : ( from to -- int ) @@ -46,8 +48,7 @@ TUPLE: interval { from read-only } { to read-only } ; : (a,inf] ( a -- interval ) 1./0. (a,b] ; inline -: [-inf,inf] ( -- interval ) - T{ interval f { -1./0. t } { 1./0. t } } ; inline +: [-inf,inf] ( -- interval ) full-interval ; inline : compare-endpoints ( p1 p2 quot -- ? ) >r over first over first r> call [ @@ -99,8 +100,10 @@ TUPLE: interval { from read-only } { to read-only } ; : do-empty-interval ( i1 i2 quot -- i3 ) { - { [ pick empty-interval eq? ] [ drop drop ] } + { [ pick empty-interval eq? ] [ 2drop ] } { [ over empty-interval eq? ] [ drop nip ] } + { [ pick full-interval eq? ] [ 2drop ] } + { [ over full-interval eq? ] [ drop nip ] } [ call ] } cond ; inline @@ -112,8 +115,10 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-intersect ( i1 i2 -- i3 ) { - { [ dup empty-interval eq? ] [ nip ] } { [ over empty-interval eq? ] [ drop ] } + { [ dup empty-interval eq? ] [ nip ] } + { [ over full-interval eq? ] [ nip ] } + { [ dup full-interval eq? ] [ drop ] } [ [ interval>points ] bi@ swapd [ [ swap endpoint< ] most ] @@ -127,8 +132,10 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-union ( i1 i2 -- i3 ) { - { [ dup empty-interval eq? ] [ drop ] } { [ over empty-interval eq? ] [ nip ] } + { [ dup empty-interval eq? ] [ drop ] } + { [ over full-interval eq? ] [ drop ] } + { [ dup full-interval eq? ] [ nip ] } [ [ interval>points 2array ] bi@ append points>interval ] } cond ; @@ -137,9 +144,11 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-contains? ( x int -- ? ) dup empty-interval eq? [ 2drop f ] [ - [ from>> first2 [ >= ] [ > ] if ] - [ to>> first2 [ <= ] [ < ] if ] - 2bi and + dup full-interval eq? [ 2drop t ] [ + [ from>> first2 [ >= ] [ > ] if ] + [ to>> first2 [ <= ] [ < ] if ] + 2bi and + ] if ] if ; : interval-zero? ( int -- ? ) @@ -160,8 +169,11 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-sq ( i1 -- i2 ) dup interval* ; +: special-interval? ( interval -- ? ) + { empty-interval full-interval } memq? ; + : interval-singleton? ( int -- ? ) - dup empty-interval eq? [ + dup special-interval? [ drop f ] [ interval>points @@ -173,6 +185,7 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-length ( int -- n ) { { [ dup empty-interval eq? ] [ drop 0 ] } + { [ dup full-interval eq? ] [ drop 1/0. ] } [ interval>points [ first ] bi@ swap - ] } cond ; @@ -211,7 +224,7 @@ TUPLE: interval { from read-only } { to read-only } ; [ [ interval-closure ] bi@ [ min ] interval-op ] do-empty-interval ; : interval-interior ( i1 -- i2 ) - dup empty-interval eq? [ + dup special-interval? [ interval>points [ first ] bi@ (a,b) ] unless ; @@ -249,6 +262,7 @@ TUPLE: interval { from read-only } { to read-only } ; : interval-abs ( i1 -- i2 ) { { [ dup empty-interval eq? ] [ ] } + { [ dup full-interval eq? ] [ drop 0 [a,inf] ] } { [ 0 over interval-contains? ] [ (interval-abs) { 0 t } suffix points>interval ] } [ (interval-abs) points>interval ] } cond ; @@ -292,7 +306,7 @@ SYMBOL: incomparable : interval< ( i1 i2 -- ? ) { - { [ 2dup [ empty-interval eq? ] either? ] [ incomparable ] } + { [ 2dup [ special-interval? ] either? ] [ incomparable ] } { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] } { [ 2dup left-endpoint-< ] [ f ] } { [ 2dup right-endpoint-< ] [ f ] } @@ -307,7 +321,7 @@ SYMBOL: incomparable : interval<= ( i1 i2 -- ? ) { - { [ 2dup [ empty-interval eq? ] either? ] [ incomparable ] } + { [ 2dup [ special-interval? ] either? ] [ incomparable ] } { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] } { [ 2dup right-endpoint-<= ] [ t ] } [ incomparable ] @@ -360,27 +374,27 @@ SYMBOL: incomparable interval-bitor ; : assume< ( i1 i2 -- i3 ) - dup empty-interval eq? [ drop ] [ + dup special-interval? [ drop ] [ to>> first [-inf,a) interval-intersect ] if ; : assume<= ( i1 i2 -- i3 ) - dup empty-interval eq? [ drop ] [ + dup special-interval? [ drop ] [ to>> first [-inf,a] interval-intersect ] if ; : assume> ( i1 i2 -- i3 ) - dup empty-interval eq? [ drop ] [ + dup special-interval? [ drop ] [ from>> first (a,inf] interval-intersect ] if ; : assume>= ( i1 i2 -- i3 ) - dup empty-interval eq? [ drop ] [ + dup special-interval? [ drop ] [ from>> first [a,inf] interval-intersect ] if ; : integral-closure ( i1 -- i2 ) - dup empty-interval eq? [ + dup special-interval? [ [ from>> first2 [ 1+ ] unless ] [ to>> first2 [ 1- ] unless ] bi [a,b] diff --git a/basis/math/ratios/ratios-docs.factor b/basis/math/ratios/ratios-docs.factor index 903017e371..7b6393dabe 100644 --- a/basis/math/ratios/ratios-docs.factor +++ b/basis/math/ratios/ratios-docs.factor @@ -1,5 +1,5 @@ USING: help.markup help.syntax math math.private -math.ratios.private ; +math.ratios.private math.functions ; IN: math.ratios ARTICLE: "rationals" "Rational numbers" diff --git a/basis/math/ratios/ratios.factor b/basis/math/ratios/ratios.factor index 5dde4fbb99..d9dea22b7b 100644 --- a/basis/math/ratios/ratios.factor +++ b/basis/math/ratios/ratios.factor @@ -3,9 +3,6 @@ USING: accessors kernel kernel.private math math.functions math.private ; IN: math.ratios -: >fraction ( a/b -- a b ) - dup numerator swap denominator ; inline - : 2>fraction ( a/b c/d -- a c b d ) [ >fraction ] bi@ swapd ; inline diff --git a/basis/opengl/opengl-docs.factor b/basis/opengl/opengl-docs.factor index 87981789a7..b1ea89178b 100644 --- a/basis/opengl/opengl-docs.factor +++ b/basis/opengl/opengl-docs.factor @@ -9,14 +9,6 @@ HELP: gl-color HELP: gl-error { $description "If the most recent OpenGL call resulted in an error, print the error to " { $link output-stream } "." } ; -HELP: do-state - { - $values - { "mode" { "One of the " { $link "opengl-geometric-primitives" } } } - { "quot" quotation } - } -{ $description "Wraps a quotation in " { $link glBegin } "/" { $link glEnd } " calls." } ; - HELP: do-enabled { $values { "what" integer } { "quot" quotation } } { $description "Wraps a quotation in " { $link glEnable } "/" { $link glDisable } " calls." } ; @@ -25,37 +17,17 @@ HELP: do-matrix { $values { "mode" { $link GL_MODELVIEW } " or " { $link GL_PROJECTION } } { "quot" quotation } } { $description "Saves and restores the matrix specified by " { $snippet "mode" } " before and after calling the quotation." } ; -HELP: gl-vertex -{ $values { "point" "a pair of integers" } } -{ $description "Wrapper for " { $link glVertex2d } " taking a point object." } ; - HELP: gl-line { $values { "a" "a pair of integers" } { "b" "a pair of integers" } } { $description "Draws a line between two points." } ; HELP: gl-fill-rect -{ $values { "loc" "a pair of integers" } { "ext" "a pair of integers" } } -{ $description "Draws a filled rectangle with top-left corner " { $snippet "loc" } " and bottom-right corner " { $snippet "ext" } "." } ; +{ $values { "dim" "a pair of integers" } } +{ $description "Draws a filled rectangle with the top-left corner at the origin and the given dimensions." } ; HELP: gl-rect -{ $values { "loc" "a pair of integers" } { "ext" "a pair of integers" } } -{ $description "Draws the outline of a rectangle with top-left corner " { $snippet "loc" } " and bottom-right corner " { $snippet "ext" } "." } ; - -HELP: rect-vertices -{ $values { "lower-left" "A pair of numbers indicating the lower-left coordinates of the rectangle." } { "upper-right" "The upper-right coordinates of the rectangle." } } -{ $description "Emits" { $link glVertex2d } " calls outlining the axis-aligned rectangle from " { $snippet "lower-left" } " to " { $snippet "upper-right" } " on the z=0 plane in counterclockwise order." } ; - -HELP: gl-fill-poly -{ $values { "points" "a sequence of pairs of integers" } } -{ $description "Draws a filled polygon." } ; - -HELP: gl-poly -{ $values { "points" "a sequence of pairs of integers" } } -{ $description "Draws the outline of a polygon." } ; - -HELP: gl-gradient -{ $values { "direction" "an orientation specifier" } { "colors" "a sequence of color specifiers" } { "dim" "a pair of integers" } } -{ $description "Draws a rectangle with top-left corner " { $snippet "{ 0 0 }" } " and dimensions " { $snippet "dim" } ", filled with a smoothly shaded transition between the colors in " { $snippet "colors" } "." } ; +{ $values { "dim" "a pair of integers" } } +{ $description "Draws the outline of a rectangle with the top-left corner at the origin and the given dimensions." } ; HELP: gen-texture { $values { "id" integer } } @@ -131,12 +103,10 @@ $nl { $subsection "opengl-low-level" } "Wrappers:" { $subsection gl-color } -{ $subsection gl-vertex } { $subsection gl-translate } { $subsection gen-texture } { $subsection bind-texture-unit } "Combinators:" -{ $subsection do-state } { $subsection do-enabled } { $subsection do-attribs } { $subsection do-matrix } @@ -146,9 +116,6 @@ $nl { $subsection gl-line } { $subsection gl-fill-rect } { $subsection gl-rect } -{ $subsection gl-fill-poly } -{ $subsection gl-poly } -{ $subsection gl-gradient } ; ABOUT: "gl-utilities" diff --git a/basis/opengl/opengl.factor b/basis/opengl/opengl.factor index bae05f4244..64326f340e 100644 --- a/basis/opengl/opengl.factor +++ b/basis/opengl/opengl.factor @@ -2,44 +2,31 @@ ! Portions copyright (C) 2007 Eduardo Cavazos. ! Portions copyright (C) 2008 Joe Groff. ! See http://factorcode.org/license.txt for BSD license. - USING: alien alien.c-types continuations kernel libc math macros - namespaces math.vectors math.constants math.functions - math.parser opengl.gl opengl.glu combinators arrays sequences - splitting words byte-arrays assocs colors accessors ; - +namespaces math.vectors math.constants math.functions +math.parser opengl.gl opengl.glu combinators arrays sequences +splitting words byte-arrays assocs colors accessors +generalizations locals memoize ; IN: opengl -: coordinates ( point1 point2 -- x1 y2 x2 y2 ) - [ first2 ] bi@ ; +: color>raw ( object -- r g b a ) + >rgba { [ red>> ] [ green>> ] [ blue>> ] [ alpha>> ] } cleave ; inline -: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 ) - [ first2 [ >fixnum ] bi@ ] bi@ ; +: gl-color ( color -- ) color>raw glColor4d ; inline -: gl-color ( color -- ) first4 glColor4d ; inline - -: gl-clear-color ( color -- ) - first4 glClearColor ; +: gl-clear-color ( color -- ) color>raw glClearColor ; : gl-clear ( color -- ) gl-clear-color GL_COLOR_BUFFER_BIT glClear ; -: color>raw ( object -- r g b a ) - >rgba { [ red>> ] [ green>> ] [ blue>> ] [ alpha>> ] } cleave ; - -: set-color ( object -- ) color>raw glColor4d ; -: set-clear-color ( object -- ) color>raw glClearColor ; - : gl-error ( -- ) glGetError dup zero? [ "GL error: " over gluErrorString append throw ] unless drop ; -: do-state ( mode quot -- ) - swap glBegin call glEnd ; inline - : do-enabled ( what quot -- ) over glEnable dip glDisable ; inline + : do-enabled-client-state ( what quot -- ) over glEnableClientState dip glDisableClientState ; inline @@ -48,6 +35,7 @@ IN: opengl : (all-enabled) ( seq quot -- ) over [ glEnable ] each dip [ glDisable ] each ; inline + : (all-enabled-client-state) ( seq quot -- ) [ dup [ glEnableClientState ] each ] dip dip @@ -55,6 +43,7 @@ IN: opengl MACRO: all-enabled ( seq quot -- ) >r words>values r> [ (all-enabled) ] 2curry ; + MACRO: all-enabled-client-state ( seq quot -- ) >r words>values r> [ (all-enabled-client-state) ] 2curry ; @@ -62,37 +51,57 @@ MACRO: all-enabled-client-state ( seq quot -- ) swap [ glMatrixMode glPushMatrix call ] keep glMatrixMode glPopMatrix ; inline -: gl-vertex ( point -- ) - dup length { - { 2 [ first2 glVertex2d ] } - { 3 [ first3 glVertex3d ] } - { 4 [ first4 glVertex4d ] } - } case ; - -: gl-normal ( normal -- ) first3 glNormal3d ; - : gl-material ( face pname params -- ) >c-float-array glMaterialfv ; +: gl-vertex-pointer ( seq -- ) + [ 2 GL_FLOAT 0 ] dip glVertexPointer ; inline + +: gl-color-pointer ( seq -- ) + [ 4 GL_FLOAT 0 ] dip glColorPointer ; inline + +: gl-texture-coord-pointer ( seq -- ) + [ 2 GL_FLOAT 0 ] dip glTexCoordPointer ; inline + +: line-vertices ( a b -- ) + append >c-float-array gl-vertex-pointer ; + : gl-line ( a b -- ) - GL_LINES [ gl-vertex gl-vertex ] do-state ; + line-vertices GL_LINES 0 2 glDrawArrays ; -: gl-fill-rect ( loc ext -- ) - coordinates glRectd ; +: (rect-vertices) ( dim -- vertices ) + { + [ drop 0 1 ] + [ first 1- 1 ] + [ [ first 1- ] [ second ] bi ] + [ second 0 swap ] + } cleave 8 narray >c-float-array ; -: gl-rect ( loc ext -- ) - GL_FRONT_AND_BACK GL_LINE glPolygonMode - >r { 0.5 0.5 } v+ r> { 0.5 0.5 } v- gl-fill-rect - GL_FRONT_AND_BACK GL_FILL glPolygonMode ; +: rect-vertices ( dim -- ) + (rect-vertices) gl-vertex-pointer ; -: (gl-poly) ( points state -- ) - [ [ gl-vertex ] each ] do-state ; +: (gl-rect) ( -- ) + GL_LINE_LOOP 0 4 glDrawArrays ; -: gl-fill-poly ( points -- ) - dup length 2 > GL_POLYGON GL_LINES ? (gl-poly) ; +: gl-rect ( dim -- ) + rect-vertices (gl-rect) ; -: gl-poly ( points -- ) - GL_LINE_LOOP (gl-poly) ; +: (fill-rect-vertices) ( dim -- vertices ) + { + [ drop 0 0 ] + [ first 0 ] + [ first2 ] + [ second 0 swap ] + } cleave 8 narray >c-float-array ; + +: fill-rect-vertices ( dim -- ) + (fill-rect-vertices) gl-vertex-pointer ; + +: (gl-fill-rect) ( -- ) + GL_QUADS 0 4 glDrawArrays ; + +: gl-fill-rect ( dim -- ) + fill-rect-vertices (gl-fill-rect) ; : circle-steps ( steps -- angles ) dup length v/n 2 pi * v*n ; @@ -109,35 +118,24 @@ MACRO: all-enabled-client-state ( seq quot -- ) : circle-points ( loc dim steps -- points ) circle-steps unit-circle adjust-points scale-points ; -: gl-circle ( loc dim steps -- ) - circle-points gl-poly ; - -: gl-fill-circle ( loc dim steps -- ) - circle-points gl-fill-poly ; - -: prepare-gradient ( direction dim -- v1 v2 ) - tuck v* [ v- ] keep ; - -: gl-gradient ( direction colors dim -- ) - GL_QUAD_STRIP [ - swap >r prepare-gradient r> - [ length dup 1- v/n ] keep [ - >r >r 2dup r> r> set-color v*n - dup gl-vertex v+ gl-vertex - ] 2each 2drop - ] do-state ; +: circle-vertices ( loc dim steps -- vertices ) + circle-points concat >c-float-array ; : (gen-gl-object) ( quot -- id ) >r 1 0 r> keep *uint ; inline + : gen-texture ( -- id ) [ glGenTextures ] (gen-gl-object) ; + : gen-gl-buffer ( -- id ) [ glGenBuffers ] (gen-gl-object) ; : (delete-gl-object) ( id quot -- ) >r 1 swap r> call ; inline + : delete-texture ( id -- ) [ glDeleteTextures ] (delete-gl-object) ; + : delete-gl-buffer ( id -- ) [ glDeleteBuffers ] (delete-gl-object) ; @@ -205,35 +203,21 @@ TUPLE: sprite loc dim dim2 dlist texture ; : gl-translate ( point -- ) first2 0.0 glTranslated ; -c-float-array ; -: top-left drop 0 0 glTexCoord2i 0.0 0.0 glVertex2d ; inline - -: top-right 1 0 glTexCoord2i first 0.0 glVertex2d ; inline - -: bottom-left 0 1 glTexCoord2i second 0.0 swap glVertex2d ; inline - -: bottom-right 1 1 glTexCoord2i gl-vertex ; inline - -PRIVATE> - -: four-sides ( dim -- ) - dup top-left dup top-right dup bottom-right bottom-left ; +: rect-texture-coords ( -- ) + (rect-texture-coords) gl-texture-coord-pointer ; : draw-sprite ( sprite -- ) - dup loc>> gl-translate - GL_TEXTURE_2D over texture>> glBindTexture - init-texture - GL_QUADS [ dim2>> four-sides ] do-state - GL_TEXTURE_2D 0 glBindTexture ; - -: rect-vertices ( lower-left upper-right -- ) - GL_QUADS [ - over first2 glVertex2d - dup first pick second glVertex2d - dup first2 glVertex2d - swap first swap second glVertex2d - ] do-state ; + GL_TEXTURE_COORD_ARRAY [ + dup loc>> gl-translate + GL_TEXTURE_2D over texture>> glBindTexture + init-texture rect-texture-coords + dim2>> fill-rect-vertices + (gl-fill-rect) + GL_TEXTURE_2D 0 glBindTexture + ] do-enabled-client-state ; : make-sprite-dlist ( sprite -- id ) GL_MODELVIEW [ @@ -256,6 +240,9 @@ PRIVATE> : with-translation ( loc quot -- ) GL_MODELVIEW [ >r gl-translate r> call ] do-matrix ; inline +: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 ) + [ first2 [ >fixnum ] bi@ ] bi@ ; + : gl-set-clip ( loc dim -- ) fix-coordinates glScissor ; diff --git a/basis/peg/ebnf/ebnf.factor b/basis/peg/ebnf/ebnf.factor index 776450ccd9..ccae0fec93 100644 --- a/basis/peg/ebnf/ebnf.factor +++ b/basis/peg/ebnf/ebnf.factor @@ -487,7 +487,7 @@ M: ebnf-terminal (transform) ( ast -- parser ) M: ebnf-foreign (transform) ( ast -- parser ) dup word>> search [ "Foreign word '" swap word>> append "' not found" append throw ] unless* - swap rule>> [ main ] unless* dupd swap rule [ + swap rule>> [ main ] unless* over rule [ nip ] [ execute diff --git a/basis/prettyprint/prettyprint-docs.factor b/basis/prettyprint/prettyprint-docs.factor index 44cf5f724f..159421c18c 100644 --- a/basis/prettyprint/prettyprint-docs.factor +++ b/basis/prettyprint/prettyprint-docs.factor @@ -1,6 +1,6 @@ USING: prettyprint.backend prettyprint.config prettyprint.sections prettyprint.private help.markup help.syntax -io kernel words definitions quotations strings ; +io kernel words definitions quotations strings generic classes ; IN: prettyprint ARTICLE: "prettyprint-numbers" "Prettyprinting numbers" @@ -150,6 +150,8 @@ $nl { $subsection pprint-cell } "Printing a definition (see " { $link "definitions" } "):" { $subsection see } +"Printing the methods defined on a generic word or class (see " { $link "objects" } "):" +{ $subsection see-methods } "More prettyprinter usage:" { $subsection "prettyprint-numbers" } { $subsection "prettyprint-stacks" } @@ -167,17 +169,26 @@ HELP: with-pprint HELP: pprint { $values { "obj" object } } -{ $description "Prettyprints an object to " { $link output-stream } ". Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ; +{ $description "Prettyprints an object to " { $link output-stream } ". Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } +{ $warning + "Unparsing a large object can take a long time and consume a lot of memory. If you need to print large objects, use " { $link pprint-short } " or set some " { $link "prettyprint-variables" } " to limit output size." +} ; { pprint pprint* with-pprint } related-words HELP: . { $values { "obj" object } } -{ $description "Prettyprints an object to " { $link output-stream } " with a trailing line break. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ; +{ $description "Prettyprints an object to " { $link output-stream } " with a trailing line break. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } +{ $warning + "Printing a large object can take a long time and consume a lot of memory. If you need to print large objects, use " { $link short. } " or set some " { $link "prettyprint-variables" } " to limit output size." +} ; HELP: unparse { $values { "obj" object } { "str" "Factor source string" } } -{ $description "Outputs a prettyprinted string representation of an object. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } ; +{ $description "Outputs a prettyprinted string representation of an object. Output is influenced by many variables; see " { $link "prettyprint-variables" } "." } +{ $warning + "Unparsing a large object can take a long time and consume a lot of memory. If you need to unparse large objects, use " { $link unparse-short } " or set some " { $link "prettyprint-variables" } " to limit output size." +} ; HELP: pprint-short { $values { "obj" object } } @@ -240,6 +251,10 @@ HELP: see { $values { "defspec" "a definition specifier" } } { $contract "Prettyprints a definition." } ; +HELP: see-methods +{ $values { "word" "a " { $link generic } " or a " { $link class } } } +{ $contract "Prettyprints the methods defined on a generic word or class." } ; + HELP: definer { $values { "defspec" "a definition specifier" } { "start" word } { "end" "a word or " { $link f } } } { $contract "Outputs the parsing words which delimit the definition." } diff --git a/basis/qualified/qualified-docs.factor b/basis/qualified/qualified-docs.factor index d62f696a74..067d221d2f 100644 --- a/basis/qualified/qualified-docs.factor +++ b/basis/qualified/qualified-docs.factor @@ -32,3 +32,14 @@ HELP: RENAME: "RENAME: + math => -" "2 3 - ! => 5" } } ; +ARTICLE: "qualified" "Qualified word lookup" +"The " { $vocab-link "qualified" } " vocabulary provides a handful of parsing words which give more control over word lookup than is offered by " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } "." +$nl +"These words are useful when there is no way to avoid using two vocabularies with identical word names in the same source file." +{ $subsection POSTPONE: QUALIFIED: } +{ $subsection POSTPONE: QUALIFIED-WITH: } +{ $subsection POSTPONE: FROM: } +{ $subsection POSTPONE: EXCLUDE: } +{ $subsection POSTPONE: RENAME: } ; + +ABOUT: "qualified" diff --git a/basis/qualified/qualified-tests.factor b/basis/qualified/qualified-tests.factor index 8f67ddf730..78efec4861 100644 --- a/basis/qualified/qualified-tests.factor +++ b/basis/qualified/qualified-tests.factor @@ -1,24 +1,33 @@ -USING: tools.test qualified ; -IN: foo +USING: tools.test qualified eval accessors parser ; +IN: qualified.tests.foo : x 1 ; -IN: bar +: y 5 ; +IN: qualified.tests.bar : x 2 ; -IN: baz +: y 4 ; +IN: qualified.tests.baz : x 3 ; -QUALIFIED: foo -QUALIFIED: bar -[ 1 2 3 ] [ foo:x bar:x x ] unit-test +QUALIFIED: qualified.tests.foo +QUALIFIED: qualified.tests.bar +[ 1 2 3 ] [ qualified.tests.foo:x qualified.tests.bar:x x ] unit-test -QUALIFIED-WITH: bar p +QUALIFIED-WITH: qualified.tests.bar p [ 2 ] [ p:x ] unit-test -RENAME: x baz => y +RENAME: x qualified.tests.baz => y [ 3 ] [ y ] unit-test -FROM: baz => x ; +FROM: qualified.tests.baz => x ; [ 3 ] [ x ] unit-test +[ 3 ] [ y ] unit-test -EXCLUDE: bar => x ; +EXCLUDE: qualified.tests.bar => x ; [ 3 ] [ x ] unit-test +[ 4 ] [ y ] unit-test +[ "USE: qualified IN: qualified.tests FROM: qualified.tests => doesnotexist ;" eval ] +[ error>> no-word-error? ] must-fail-with + +[ "USE: qualified IN: qualified.tests RENAME: doesnotexist qualified.tests => blah" eval ] +[ error>> no-word-error? ] must-fail-with diff --git a/basis/qualified/qualified.factor b/basis/qualified/qualified.factor index d636cc0152..d387ef4b0e 100644 --- a/basis/qualified/qualified.factor +++ b/basis/qualified/qualified.factor @@ -1,12 +1,12 @@ ! Copyright (C) 2007, 2008 Daniel Ehrenberg. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences assocs hashtables parser lexer -vocabs words namespaces vocabs.loader debugger sets ; +vocabs words namespaces vocabs.loader debugger sets fry ; IN: qualified : define-qualified ( vocab-name prefix-name -- ) [ load-vocab vocab-words ] [ CHAR: : suffix ] bi* - [ -rot >r append r> ] curry assoc-map + '[ [ [ _ ] dip append ] dip ] assoc-map use get push ; : QUALIFIED: @@ -19,27 +19,27 @@ IN: qualified : expect=> ( -- ) scan "=>" assert= ; -: partial-vocab ( words name -- assoc ) - dupd [ - lookup [ "No such word: " swap append throw ] unless* - ] curry map zip ; - -: partial-vocab-ignoring ( words name -- assoc ) - [ load-vocab vocab-words keys swap diff ] keep partial-vocab ; - -: EXCLUDE: - #! Syntax: EXCLUDE: vocab => words ... ; - scan expect=> - ";" parse-tokens swap partial-vocab-ignoring use get push ; parsing +: partial-vocab ( words vocab -- assoc ) + '[ dup _ lookup [ no-word-error ] unless* ] + { } map>assoc ; : FROM: #! Syntax: FROM: vocab => words... ; scan dup load-vocab drop expect=> ";" parse-tokens swap partial-vocab use get push ; parsing +: partial-vocab-excluding ( words vocab -- assoc ) + [ load-vocab vocab-words keys swap diff ] keep partial-vocab ; + +: EXCLUDE: + #! Syntax: EXCLUDE: vocab => words ... ; + scan expect=> + ";" parse-tokens swap partial-vocab-excluding use get push ; parsing + : RENAME: #! Syntax: RENAME: word vocab => newname - scan scan dup load-vocab drop lookup [ "No such word" throw ] unless* + scan scan dup load-vocab drop + dupd lookup [ ] [ no-word-error ] ?if expect=> scan associate use get push ; parsing diff --git a/basis/random/mersenne-twister/mersenne-twister.factor b/basis/random/mersenne-twister/mersenne-twister.factor index 712883e4b8..c31d338fac 100644 --- a/basis/random/mersenne-twister/mersenne-twister.factor +++ b/basis/random/mersenne-twister/mersenne-twister.factor @@ -16,7 +16,7 @@ TUPLE: mersenne-twister seq i ; : mt-a HEX: 9908b0df ; inline : calculate-y ( n seq -- y ) - [ nth 32 mask-bit ] + [ nth 31 mask-bit ] [ [ 1+ ] [ nth ] bi* 31 bits ] 2bi bitor ; inline : (mt-generate) ( n seq -- next-mt ) diff --git a/basis/tools/crossref/crossref-docs.factor b/basis/tools/crossref/crossref-docs.factor index 477ea01ef6..b7ec0d07a2 100644 --- a/basis/tools/crossref/crossref-docs.factor +++ b/basis/tools/crossref/crossref-docs.factor @@ -1,10 +1,10 @@ -USING: help.markup help.syntax words definitions ; +USING: help.markup help.syntax words definitions prettyprint ; IN: tools.crossref ARTICLE: "tools.crossref" "Cross-referencing tools" { $subsection usage. } { $subsection apropos } -{ $see-also "definitions" "words" } ; +{ $see-also "definitions" "words" see see-methods } ; ABOUT: "tools.crossref" diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor index ad1b3cbd84..ec1259c777 100755 --- a/basis/tools/deploy/windows/windows.factor +++ b/basis/tools/deploy/windows/windows.factor @@ -9,16 +9,14 @@ IN: tools.deploy.windows "resource:factor.dll" swap copy-file-into ; : copy-freetype ( bundle-name -- ) - deploy-ui? get [ - { - "resource:freetype6.dll" - "resource:zlib1.dll" - } swap copy-files-into - ] [ drop ] if ; + { + "resource:freetype6.dll" + "resource:zlib1.dll" + } swap copy-files-into ; : create-exe-dir ( vocab bundle-name -- vm ) + dup copy-dll deploy-ui? get [ - dup copy-dll dup copy-freetype dup "" copy-fonts ] when @@ -26,14 +24,14 @@ IN: tools.deploy.windows M: winnt deploy* "resource:" [ - deploy-name over deploy-config at - [ - { + dup deploy-config [ + deploy-name get + [ [ create-exe-dir ] [ image-name ] [ drop ] - [ drop deploy-config ] - } 2cleave make-deploy-image - ] - [ nip open-in-explorer ] 2bi + 2tri namespace make-deploy-image + ] + [ nip open-in-explorer ] 2bi + ] bind ] with-directory ; diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index 6659940b2b..e1076775fa 100644 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -148,7 +148,7 @@ ERROR: no-vocab vocab ; "{ $values" print [ " " write ($values.) ] [ [ nl " " write ($values.) ] unless-empty ] bi* - " }" write nl + nl "}" print ] if ] when* ; diff --git a/basis/tools/test/test-docs.factor b/basis/tools/test/test-docs.factor index 4b2521d19c..02c0ad126d 100644 --- a/basis/tools/test/test-docs.factor +++ b/basis/tools/test/test-docs.factor @@ -17,7 +17,7 @@ ARTICLE: "tools.test.run" "Running unit tests" { $subsection test-all } ; ARTICLE: "tools.test.failure" "Handling test failures" -"Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Sometimes, you want to develop a tool which inspects the test failures and takes some kind of action instead; one example is " { $vocab-link "builder" } "." +"Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Some tools inspect the test failures and takes some kind of action instead, for example, " { $vocab-link "mason" } "." $nl "The following words output an association list mapping vocabulary names to sequences of failures; a failure is an array having the shape " { $snippet "{ error test continuation }" } ", and the elements are as follows:" { $list diff --git a/basis/ui/freetype/freetype.factor b/basis/ui/freetype/freetype.factor index d2dfe56ed4..5a6118fb00 100644 --- a/basis/ui/freetype/freetype.factor +++ b/basis/ui/freetype/freetype.factor @@ -196,6 +196,7 @@ M: freetype-renderer string-height ( open-font string -- h ) :: (draw-string) ( open-font sprites string loc -- ) GL_TEXTURE_2D [ loc [ + -0.5 0.5 0.0 glTranslated string open-font string char-widths scan-sums [ [ open-font sprites ] 2dip draw-char ] 2each diff --git a/basis/ui/gadgets/buttons/buttons.factor b/basis/ui/gadgets/buttons/buttons.factor index 4ad9e14874..11fb69fc7d 100644 --- a/basis/ui/gadgets/buttons/buttons.factor +++ b/basis/ui/gadgets/buttons/buttons.factor @@ -1,12 +1,11 @@ ! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays kernel math models namespaces sequences - strings quotations assocs combinators classes colors - classes.tuple opengl math.vectors - ui.commands ui.gadgets ui.gadgets.borders - ui.gadgets.labels ui.gadgets.theme - ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures - ui.render math.geometry.rect ; +strings quotations assocs combinators classes colors +classes.tuple opengl opengl.gl math.vectors ui.commands ui.gadgets +ui.gadgets.borders ui.gadgets.labels ui.gadgets.theme +ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures +ui.render math.geometry.rect locals alien.c-types ; IN: ui.gadgets.buttons @@ -62,10 +61,10 @@ C: button-paint } cond ; M: button-paint draw-interior - button-paint draw-interior ; + button-paint dup [ draw-interior ] [ 2drop ] if ; M: button-paint draw-boundary - button-paint draw-boundary ; + button-paint dup [ draw-boundary ] [ 2drop ] if ; : align-left ( button -- button ) { 0 1/2 } >>align ; inline @@ -103,17 +102,34 @@ repeat-button H{ #! the mouse is held down. repeat-button new-button bevel-button-theme ; -TUPLE: checkmark-paint color ; +TUPLE: checkmark-paint < caching-pen color last-vertices ; -C: checkmark-paint +: ( color -- paint ) + checkmark-paint new swap >>color ; + +c-float-array ; + +PRIVATE> + +M: checkmark-paint recompute-pen + swap dim>> checkmark-vertices >>last-vertices drop ; M: checkmark-paint draw-interior - color>> set-color - origin get [ - rect-dim - { 0 0 } over gl-line - dup { 0 1 } v* swap { 1 0 } v* gl-line - ] with-translation ; + [ compute-pen ] + [ color>> gl-color ] + [ last-vertices>> gl-vertex-pointer ] tri + GL_LINES 0 4 glDrawArrays ; : checkmark-theme ( gadget -- gadget ) f @@ -148,30 +164,47 @@ TUPLE: checkbox < button ; M: checkbox model-changed swap value>> >>selected? relayout-1 ; -TUPLE: radio-paint color ; +TUPLE: radio-paint < caching-pen color interior-vertices boundary-vertices ; -C: radio-paint +: ( color -- paint ) radio-paint new swap >>color ; + + + +M: radio-paint recompute-pen + swap dim>> + [ { 4 4 } swap { 9 9 } v- circle-steps circle-vertices >>interior-vertices ] + [ { 1 1 } swap { 3 3 } v- circle-steps circle-vertices >>boundary-vertices ] bi + drop ; + +> gl-color ] bi ; + +PRIVATE> M: radio-paint draw-interior - color>> set-color - origin get { 4 4 } v+ swap rect-dim { 8 8 } v- 12 gl-fill-circle ; + [ (radio-paint) ] [ interior-vertices>> gl-vertex-pointer ] bi + GL_POLYGON 0 circle-steps glDrawArrays ; M: radio-paint draw-boundary - color>> set-color - origin get { 1 1 } v+ swap rect-dim { 2 2 } v- 12 gl-circle ; + [ (radio-paint) ] [ boundary-vertices>> gl-vertex-pointer ] bi + GL_LINE_LOOP 0 circle-steps glDrawArrays ; -: radio-knob-theme ( gadget -- gadget ) - f - f - black - black - >>interior - black >>boundary ; +:: radio-knob-theme ( gadget -- gadget ) + [let | radio-paint [ black ] | + gadget + f f radio-paint radio-paint >>interior + radio-paint >>boundary + { 16 16 } >>dim + ] ; : ( -- gadget ) - - radio-knob-theme - { 16 16 } >>dim ; + radio-knob-theme ; TUPLE: radio-control < button value ; diff --git a/basis/ui/gadgets/editors/editors.factor b/basis/ui/gadgets/editors/editors.factor index a1026ef35a..0d0611f532 100644 --- a/basis/ui/gadgets/editors/editors.factor +++ b/basis/ui/gadgets/editors/editors.factor @@ -127,10 +127,12 @@ M: editor ungraft* : draw-caret ( -- ) editor get focused?>> [ editor get - dup caret-color>> set-color - dup caret-loc origin get v+ - swap caret-dim over v+ - [ { 0.5 -0.5 } v+ ] bi@ gl-line + [ caret-color>> gl-color ] + [ + dup caret-loc origin get v+ + swap caret-dim over v+ + gl-line + ] bi ] when ; : line-translation ( n -- loc ) @@ -171,7 +173,7 @@ M: editor ungraft* : draw-lines ( -- ) \ first-visible-line get [ - editor get dup color>> set-color + editor get dup color>> gl-color dup visible-lines [ draw-line 1 translate-lines ] with each ] with-editor-translation ; @@ -180,17 +182,19 @@ M: editor ungraft* dup editor-mark* swap editor-caret* sort-pair ; : (draw-selection) ( x1 x2 -- ) - 2dup = [ 2 + ] when - 0.0 swap editor get line-height glRectd ; + over - + dup 0 = [ 2 + ] when + [ 0.0 2array ] [ editor get line-height 2array ] bi* + swap [ gl-fill-rect ] with-translation ; : draw-selected-line ( start end n -- ) [ start/end-on-line ] keep tuck - >r >r editor get offset>x r> r> + [ editor get offset>x ] 2dip editor get offset>x (draw-selection) ; : draw-selection ( -- ) - editor get selection-color>> set-color + editor get selection-color>> gl-color editor get selection-start/end over first [ 2dup [ diff --git a/basis/ui/gadgets/grid-lines/grid-lines.factor b/basis/ui/gadgets/grid-lines/grid-lines.factor index f4266adba1..0356e7fd4d 100644 --- a/basis/ui/gadgets/grid-lines/grid-lines.factor +++ b/basis/ui/gadgets/grid-lines/grid-lines.factor @@ -23,13 +23,10 @@ SYMBOL: grid-dim ] with each ; M: grid-lines draw-boundary - origin get [ - -0.5 -0.5 0.0 glTranslated - color>> set-color [ - dup grid set - dup rect-dim half-gap v- grid-dim set - compute-grid - { 0 1 } draw-grid-lines - { 1 0 } draw-grid-lines - ] with-scope - ] with-translation ; + color>> gl-color [ + dup grid set + dup rect-dim half-gap v- grid-dim set + compute-grid + { 0 1 } draw-grid-lines + { 1 0 } draw-grid-lines + ] with-scope ; diff --git a/basis/ui/gadgets/labelled/labelled.factor b/basis/ui/gadgets/labelled/labelled.factor index 8cf13c8367..79a485b711 100644 --- a/basis/ui/gadgets/labelled/labelled.factor +++ b/basis/ui/gadgets/labelled/labelled.factor @@ -30,16 +30,16 @@ M: labelled-gadget focusable-child* content>> ; : title-theme ( gadget -- gadget ) { 1 0 } >>orientation - T{ gradient f { + { T{ rgba f 0.65 0.65 1.0 1.0 } T{ rgba f 0.65 0.45 1.0 1.0 } - } } >>interior ; + } >>interior ; : ( text -- label )