Merge branch 'master' of git://factorcode.org/git/factor

db4
John Benediktsson 2008-09-13 16:10:56 -07:00
commit ea621cd888
41 changed files with 641 additions and 345 deletions

View File

@ -13,10 +13,8 @@ compiler.tree.builder
compiler.tree.recursive compiler.tree.recursive
compiler.tree.normalization compiler.tree.normalization
compiler.tree.propagation compiler.tree.propagation
compiler.tree.checker ; compiler.tree.checker
compiler.tree.debugger ;
: cleaned-up-tree ( quot -- nodes )
build-tree analyze-recursive normalize propagate cleanup dup check-nodes ;
[ t ] [ [ [ 1 ] [ 2 ] if ] cleaned-up-tree [ #if? ] contains-node? ] unit-test [ t ] [ [ [ 1 ] [ 2 ] if ] cleaned-up-tree [ #if? ] contains-node? ] unit-test
@ -34,12 +32,6 @@ compiler.tree.checker ;
[ t ] [ [ t recursive-test ] cleaned-up-tree [ #recursive? ] contains-node? ] unit-test [ t ] [ [ t recursive-test ] cleaned-up-tree [ #recursive? ] contains-node? ] unit-test
: inlined? ( quot seq/word -- ? )
[ cleaned-up-tree ] dip
dup word? [ 1array ] when
'[ dup #call? [ word>> _ member? ] [ drop f ] if ]
contains-node? not ;
[ f ] [ [ f ] [
[ { integer } declare >fixnum ] [ { integer } declare >fixnum ]
\ >fixnum inlined? \ >fixnum inlined?
@ -498,3 +490,7 @@ cell-bits 32 = [
[ 2 swap >fixnum ribs ] [ 2 swap >fixnum ribs ]
{ <-integer-fixnum +-integer-fixnum } inlined? { <-integer-fixnum +-integer-fixnum } inlined?
] unit-test ] unit-test
[ t ] [
[ hashtable new ] \ new inlined?
] unit-test

View File

@ -64,14 +64,6 @@ GENERIC: cleanup* ( node -- node/nodes )
] [ body>> cleanup ] bi ; ] [ body>> cleanup ] bi ;
! Removing overflow checks ! Removing overflow checks
: no-overflow-variant ( op -- fast-op )
H{
{ fixnum+ fixnum+fast }
{ fixnum- fixnum-fast }
{ fixnum* fixnum*fast }
{ fixnum-shift fixnum-shift-fast }
} at ;
: (remove-overflow-check?) ( #call -- ? ) : (remove-overflow-check?) ( #call -- ? )
node-output-infos first class>> fixnum class<= ; node-output-infos first class>> fixnum class<= ;

View File

@ -36,7 +36,7 @@ M: #branch remove-dead-code*
'[ _ nth _ key? ] filter ; inline '[ _ nth _ key? ] filter ; inline
: drop-indexed-values ( values indices -- node ) : drop-indexed-values ( values indices -- node )
[ drop filter-live ] [ nths ] 2bi [ drop filter-live ] [ swap nths ] 2bi
[ make-values ] keep [ make-values ] keep
[ drop ] [ zip ] 2bi [ drop ] [ zip ] 2bi
#shuffle ; #shuffle ;

View File

@ -84,7 +84,7 @@ M:: #recursive remove-dead-code* ( node -- nodes )
drop-outputs [ node drop-recursive-outputs ] | drop-outputs [ node drop-recursive-outputs ] |
node [ (remove-dead-code) ] change-child drop node [ (remove-dead-code) ] change-child drop
node label>> [ filter-live ] change-enter-out drop node label>> [ filter-live ] change-enter-out drop
drop-inputs node drop-outputs 3array { drop-inputs node drop-outputs }
] ; ] ;
M: #return-recursive remove-dead-code* ; M: #return-recursive remove-dead-code* ;

View File

@ -1,13 +1,21 @@
! Copyright (C) 2006, 2008 Slava Pestov. ! Copyright (C) 2006, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel assocs fry match accessors namespaces make effects USING: kernel assocs match fry accessors namespaces make effects
sequences sequences.private quotations generic macros arrays sequences sequences.private quotations generic macros arrays
prettyprint prettyprint.backend prettyprint.sections math words prettyprint prettyprint.backend prettyprint.sections math words
combinators io sorting hints combinators io sorting hints qualified
compiler.tree compiler.tree
compiler.tree.recursive
compiler.tree.normalization
compiler.tree.cleanup
compiler.tree.propagation
compiler.tree.propagation.info
compiler.tree.def-use
compiler.tree.builder compiler.tree.builder
compiler.tree.optimizer compiler.tree.optimizer
compiler.tree.combinators ; compiler.tree.combinators
compiler.tree.checker ;
RENAME: _ match => __
IN: compiler.tree.debugger IN: compiler.tree.debugger
! A simple tool for turning tree IR into quotations and ! A simple tool for turning tree IR into quotations and
@ -42,7 +50,7 @@ MATCH-VARS: ?a ?b ?c ;
{ { { ?a ?b ?c } { ?b ?c ?a } } [ rot ] } { { { ?a ?b ?c } { ?b ?c ?a } } [ rot ] }
{ { { ?a ?b } { ?b } } [ nip ] } { { { ?a ?b } { ?b } } [ nip ] }
{ { { ?a ?b ?c } { ?c } } [ 2nip ] } { { { ?a ?b ?c } { ?c } } [ 2nip ] }
{ _ f } { __ f }
} match-choose ; } match-choose ;
TUPLE: shuffle-node { effect effect } ; TUPLE: shuffle-node { effect effect } ;
@ -146,3 +154,32 @@ SYMBOL: node-count
: optimizer-report. ( word -- ) : optimizer-report. ( word -- )
make-report report. ; make-report report. ;
! More utilities
: final-info ( quot -- seq )
build-tree
analyze-recursive
normalize
propagate
compute-def-use
dup check-nodes
peek node-input-infos ;
: final-classes ( quot -- seq )
final-info [ class>> ] map ;
: final-literals ( quot -- seq )
final-info [ literal>> ] map ;
: cleaned-up-tree ( quot -- nodes )
[
check-optimizer? on
build-tree optimize-tree
] with-scope ;
: inlined? ( quot seq/word -- ? )
[ cleaned-up-tree ] dip
dup word? [ 1array ] when
'[ dup #call? [ word>> _ member? ] [ drop f ] if ]
contains-node? not ;

View File

@ -0,0 +1,10 @@
USING: kernel tools.test compiler.tree compiler.tree.builder
compiler.tree.def-use compiler.tree.def-use.simplified accessors
sequences sorting classes ;
IN: compiler.tree.def-use.simplified
[ { #call #return } ] [
[ 1 dup reverse ] build-tree compute-def-use
first out-d>> first actually-used-by
[ node>> class ] map natural-sort
] unit-test

View File

@ -0,0 +1,40 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: sequences sequences.deep kernel
compiler.tree compiler.tree.def-use ;
IN: compiler.tree.def-use.simplified
! Simplified def-use follows chains of copies.
! A 'real' usage is a usage of a value that is not a #renaming.
TUPLE: real-usage value node ;
GENERIC: actually-used-by* ( value node -- real-usages )
! Def
GENERIC: actually-defined-by* ( value node -- real-usage )
: actually-defined-by ( value -- real-usage )
dup defined-by actually-defined-by* ;
M: #renaming actually-defined-by*
inputs/outputs swap [ index ] dip nth actually-defined-by ;
M: #return-recursive actually-defined-by* real-usage boa ;
M: node actually-defined-by* real-usage boa ;
! Use
: (actually-used-by) ( value -- real-usages )
dup used-by [ actually-used-by* ] with map ;
M: #renaming actually-used-by*
inputs/outputs [ indices ] dip nths
[ (actually-used-by) ] map ;
M: #return-recursive actually-used-by* real-usage boa ;
M: node actually-used-by* real-usage boa ;
: actually-used-by ( value -- real-usages )
(actually-used-by) flatten ;

View File

@ -6,27 +6,20 @@ classes.tuple.private slots.private combinators layouts
byte-arrays alien.accessors byte-arrays alien.accessors
compiler.intrinsics compiler.intrinsics
compiler.tree compiler.tree
compiler.tree.builder compiler.tree.combinators
compiler.tree.recursive
compiler.tree.normalization
compiler.tree.propagation
compiler.tree.propagation.info compiler.tree.propagation.info
compiler.tree.cleanup compiler.tree.late-optimizations ;
compiler.tree.def-use
compiler.tree.dead-code
compiler.tree.combinators ;
IN: compiler.tree.finalization IN: compiler.tree.finalization
! This is a late-stage optimization.
! See the comment in compiler.tree.late-optimizations.
! This pass runs after propagation, so that it can expand ! This pass runs after propagation, so that it can expand
! built-in type predicates and memory allocation; these cannot ! built-in type predicates and memory allocation; these cannot
! be expanded before propagation since we need to see 'fixnum?' ! be expanded before propagation since we need to see 'fixnum?'
! instead of 'tag 0 eq?' and so on, for semantic reasoning. ! instead of 'tag 0 eq?' and so on, for semantic reasoning.
! We also delete empty stack shuffles and copies to facilitate ! We also delete empty stack shuffles and copies to facilitate
! tail call optimization in the code generator. After this pass ! tail call optimization in the code generator.
! runs, stack flow information is no longer accurate, since we
! punt in 'splice-quot' and don't update everything that we
! should; this simplifies the code, improves performance, and we
! don't need the stack flow information after this pass anyway.
GENERIC: finalize* ( node -- nodes ) GENERIC: finalize* ( node -- nodes )
@ -37,18 +30,6 @@ M: #shuffle finalize*
[ in>> ] [ out>> ] bi sequence= [ in>> ] [ out>> ] bi sequence=
[ drop f ] when ; [ drop f ] when ;
: splice-quot ( quot -- nodes )
[
build-tree
analyze-recursive
normalize
propagate
cleanup
compute-def-use
remove-dead-code
but-last
] with-scope ;
: builtin-predicate? ( #call -- ? ) : builtin-predicate? ( #call -- ? )
word>> "predicating" word-prop builtin-class? ; word>> "predicating" word-prop builtin-class? ;

View File

@ -0,0 +1,29 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: sequences namespaces compiler.tree.builder
compiler.tree.recursive
compiler.tree.normalization
compiler.tree.propagation
compiler.tree.propagation.info
compiler.tree.cleanup
compiler.tree.def-use
compiler.tree.dead-code ;
IN: compiler.tree.late-optimizations
! Late optimizations modify the tree such that stack flow
! information is no longer accurate, since we punt in
! 'splice-quot' and don't update everything that we should;
! this simplifies the code, improves performance, and we
! don't need the stack flow information after this pass anyway.
: splice-quot ( quot -- nodes )
[
build-tree
analyze-recursive
normalize
propagate
cleanup
compute-def-use
remove-dead-code
but-last
] with-scope ;

View File

@ -0,0 +1,130 @@
IN: compiler.tree.modular-arithmetic.tests
USING: kernel kernel.private tools.test math math.partial-dispatch
math.private accessors slots.private sequences strings sbufs
compiler.tree.builder
compiler.tree.optimizer
compiler.tree.debugger ;
: test-modular-arithmetic ( quot -- quot' )
build-tree optimize-tree nodes>quot ;
[ [ >r >fixnum r> >fixnum fixnum+fast ] ]
[ [ { integer integer } declare + >fixnum ] test-modular-arithmetic ] unit-test
[ [ +-integer-integer dup >fixnum ] ]
[ [ { integer integer } declare + dup >fixnum ] test-modular-arithmetic ] unit-test
[ [ >r >fixnum r> >fixnum fixnum+fast 4 fixnum*fast ] ]
[ [ { integer integer } declare + 4 * >fixnum ] test-modular-arithmetic ] unit-test
TUPLE: declared-fixnum { x fixnum } ;
[ t ] [
[ { declared-fixnum } declare [ 1 + ] change-x ]
{ + fixnum+ >fixnum } inlined?
] unit-test
[ t ] [
[ { declared-fixnum } declare x>> drop ]
{ slot } inlined?
] unit-test
[ f ] [
[ { integer } declare -63 shift 4095 bitand ]
\ shift inlined?
] unit-test
[ t ] [
[ { integer } declare 127 bitand 3 + ]
{ + +-integer-fixnum bitand } inlined?
] unit-test
[ f ] [
[ { integer } declare 127 bitand 3 + ]
{ >fixnum } inlined?
] unit-test
[ t ] [
[
{ integer } declare
dup 0 >= [
615949 * 797807 + 20 2^ mod dup 19 2^ -
] [ dup ] if
] { * + shift mod fixnum-mod fixnum* fixnum+ fixnum- } inlined?
] unit-test
[ t ] [
[
{ fixnum } declare
615949 * 797807 + 20 2^ mod dup 19 2^ -
] { >fixnum } inlined?
] unit-test
[ t ] [
[
{ integer } declare 0 swap
[
drop 615949 * 797807 + 20 2^ rem dup 19 2^ -
] map
] { * + shift rem mod fixnum-mod fixnum* fixnum+ fixnum- } inlined?
] unit-test
[ t ] [
[
{ fixnum } declare 0 swap
[
drop 615949 * 797807 + 20 2^ rem dup 19 2^ -
] map
] { * + shift rem mod fixnum-mod fixnum* fixnum+ fixnum- >fixnum } inlined?
] unit-test
[ t ] [
[ { string sbuf } declare ] \ push-all def>> append \ + inlined?
] unit-test
[ t ] [
[ { string sbuf } declare ] \ push-all def>> append \ fixnum+ inlined?
] unit-test
[ t ] [
[ { string sbuf } declare ] \ push-all def>> append \ >fixnum inlined?
] unit-test
[ t ] [
[
{ integer } declare [ 256 mod ] map
] { mod fixnum-mod } inlined?
] unit-test
[ f ] [
[
256 mod
] { mod fixnum-mod } inlined?
] unit-test
[ f ] [
[
dup 0 >= [ 256 mod ] when
] { mod fixnum-mod } inlined?
] unit-test
[ t ] [
[
{ integer } declare dup 0 >= [ 256 mod ] when
] { mod fixnum-mod } inlined?
] unit-test
[ t ] [
[
{ integer } declare 256 rem
] { mod fixnum-mod } inlined?
] unit-test
[ t ] [
[
{ integer } declare [ 256 rem ] map
] { mod fixnum-mod rem } inlined?
] unit-test

View File

@ -0,0 +1,108 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math math.partial-dispatch namespaces sequences sets
accessors assocs words kernel memoize fry combinators
compiler.tree
compiler.tree.combinators
compiler.tree.def-use
compiler.tree.def-use.simplified
compiler.tree.late-optimizations ;
IN: compiler.tree.modular-arithmetic
! This is a late-stage optimization.
! See the comment in compiler.tree.late-optimizations.
! Modular arithmetic optimization pass.
!
! { integer integer } declare + >fixnum
! ==>
! [ >fixnum ] bi@ fixnum+fast
{ + - * bitand bitor bitxor } [
[
t "modular-arithmetic" set-word-prop
] each-integer-derived-op
] each
{ bitand bitor bitxor bitnot }
[ t "modular-arithmetic" set-word-prop ] each
SYMBOL: modularize-values
: modular-value? ( value -- ? )
modularize-values get key? ;
: modularize-value ( value -- ) modularize-values get conjoin ;
GENERIC: maybe-modularize* ( value node -- )
: maybe-modularize ( value -- )
actually-defined-by [ value>> ] [ node>> ] bi
over actually-used-by length 1 = [
maybe-modularize*
] [ 2drop ] if ;
M: #call maybe-modularize*
dup word>> "modular-arithmetic" word-prop [
[ modularize-value ]
[ in-d>> [ maybe-modularize ] each ] bi*
] [ 2drop ] if ;
M: node maybe-modularize* 2drop ;
GENERIC: compute-modularized-values* ( node -- )
M: #call compute-modularized-values*
dup word>> {
{ [ \ >fixnum eq? ] [ in-d>> first maybe-modularize ] }
! { [
! {
! mod-integer-fixnum
! mod-integer-integer
! mod-fixnum-integer
! } memq?
! ] [ ] }
[ drop ]
} cond ;
M: node compute-modularized-values* drop ;
: compute-modularized-values ( nodes -- )
[ compute-modularized-values* ] each-node ;
GENERIC: optimize-modular-arithmetic* ( node -- nodes )
: redundant->fixnum? ( #call -- ? )
in-d>> first actually-defined-by value>> modular-value? ;
: optimize->fixnum ( #call -- nodes )
dup redundant->fixnum? [ drop f ] when ;
MEMO: fixnum-coercion ( flags -- nodes )
[ [ ] [ >fixnum ] ? ] map '[ _ spread ] splice-quot ;
: optimize-modular-op ( #call -- nodes )
dup out-d>> first modular-value? [
[ in-d>> ] [ word>> integer-op-input-classes ] [ ] tri
[
[
[ actually-defined-by value>> modular-value? ]
[ fixnum eq? ]
bi* or
] 2map fixnum-coercion
] [ [ modular-variant ] change-word ] bi* suffix
] when ;
M: #call optimize-modular-arithmetic*
dup word>> {
{ [ dup \ >fixnum eq? ] [ drop optimize->fixnum ] }
{ [ dup "modular-arithmetic" word-prop ] [ drop optimize-modular-op ] }
[ drop ]
} cond ;
M: node optimize-modular-arithmetic* ;
: optimize-modular-arithmetic ( nodes -- nodes' )
H{ } clone modularize-values set
dup compute-modularized-values
[ optimize-modular-arithmetic* ] map-nodes ;

View File

@ -10,7 +10,7 @@ compiler.tree.tuple-unboxing
compiler.tree.identities compiler.tree.identities
compiler.tree.def-use compiler.tree.def-use
compiler.tree.dead-code compiler.tree.dead-code
compiler.tree.strength-reduction compiler.tree.modular-arithmetic
compiler.tree.finalization compiler.tree.finalization
compiler.tree.checker ; compiler.tree.checker ;
IN: compiler.tree.optimizer IN: compiler.tree.optimizer
@ -27,9 +27,10 @@ SYMBOL: check-optimizer?
apply-identities apply-identities
compute-def-use compute-def-use
remove-dead-code remove-dead-code
! strength-reduce
check-optimizer? get [ check-optimizer? get [
compute-def-use compute-def-use
dup check-nodes dup check-nodes
] when ] when
compute-def-use
optimize-modular-arithmetic
finalize ; finalize ;

View File

@ -3,7 +3,7 @@
USING: accessors kernel arrays sequences math math.order USING: accessors kernel arrays sequences math math.order
math.partial-dispatch generic generic.standard generic.math math.partial-dispatch generic generic.standard generic.math
classes.algebra classes.union sets quotations assocs combinators classes.algebra classes.union sets quotations assocs combinators
words namespaces words namespaces continuations
compiler.tree compiler.tree
compiler.tree.builder compiler.tree.builder
compiler.tree.recursive compiler.tree.recursive
@ -33,7 +33,7 @@ M: quotation splicing-nodes
body>> (propagate) ; body>> (propagate) ;
! Dispatch elimination ! Dispatch elimination
: eliminate-dispatch ( #call class/f word/f -- ? ) : eliminate-dispatch ( #call class/f word/quot/f -- ? )
dup [ dup [
[ >>class ] dip [ >>class ] dip
over method>> over = [ drop ] [ over method>> over = [ drop ] [
@ -156,12 +156,19 @@ SYMBOL: history
: always-inline-word? ( word -- ? ) : always-inline-word? ( word -- ? )
{ curry compose } memq? ; { curry compose } memq? ;
: custom-inlining? ( word -- ? )
"custom-inlining" word-prop ;
: inline-custom ( #call word -- ? )
[ dup 1array ] [ "custom-inlining" word-prop ] bi* with-datastack
first object swap eliminate-dispatch ;
: do-inlining ( #call word -- ? ) : do-inlining ( #call word -- ? )
{ {
{ [ dup custom-inlining? ] [ inline-custom ] }
{ [ dup always-inline-word? ] [ inline-word ] } { [ dup always-inline-word? ] [ inline-word ] }
{ [ dup standard-generic? ] [ inline-standard-method ] } { [ dup standard-generic? ] [ inline-standard-method ] }
{ [ dup math-generic? ] [ inline-math-method ] } { [ dup math-generic? ] [ inline-math-method ] }
{ [ dup math-partial? ] [ inline-math-partial ] }
{ [ dup method-body? ] [ inline-method-body ] } { [ dup method-body? ] [ inline-method-body ] }
[ 2drop f ] [ 2drop f ]
} cond ; } cond ;

View File

@ -230,6 +230,32 @@ generic-comparison-ops [
] "outputs" set-word-prop ] "outputs" set-word-prop
] assoc-each ] assoc-each
{
mod-integer-integer
mod-integer-fixnum
mod-fixnum-integer
fixnum-mod
rem
} [
[
in-d>> second value-info >literal<
[ power-of-2? [ 1- bitand ] f ? ] when
] "custom-inlining" set-word-prop
] each
{
bitand-integer-integer
bitand-integer-fixnum
bitand-fixnum-integer
} [
[
in-d>> second value-info >literal< [
0 most-positive-fixnum between?
[ [ >fixnum ] bi@ fixnum-bitand ] f ?
] when
] "custom-inlining" set-word-prop
] each
{ {
alien-signed-1 alien-signed-1
alien-unsigned-1 alien-unsigned-1

View File

@ -6,27 +6,13 @@ alien.accessors alien.c-types sequences.private
byte-arrays classes.algebra classes.tuple.private byte-arrays classes.algebra classes.tuple.private
math.functions math.private strings layouts math.functions math.private strings layouts
compiler.tree.propagation.info compiler.tree.def-use compiler.tree.propagation.info compiler.tree.def-use
compiler.tree.checker slots.private words hashtables compiler.tree.debugger compiler.tree.checker
classes assocs ; slots.private words hashtables classes assocs locals
float-arrays ;
IN: compiler.tree.propagation.tests IN: compiler.tree.propagation.tests
\ propagate must-infer \ propagate must-infer
: final-info ( quot -- seq )
build-tree
analyze-recursive
normalize
propagate
compute-def-use
dup check-nodes
peek node-input-infos ;
: final-classes ( quot -- seq )
final-info [ class>> ] map ;
: final-literals ( quot -- seq )
final-info [ literal>> ] map ;
[ V{ } ] [ [ ] final-classes ] unit-test [ V{ } ] [ [ ] final-classes ] unit-test
[ V{ fixnum } ] [ [ 1 ] final-classes ] unit-test [ V{ fixnum } ] [ [ 1 ] final-classes ] unit-test
@ -594,6 +580,16 @@ MIXIN: empty-mixin
[ { float } declare 0 eq? ] final-classes [ { float } declare 0 eq? ] final-classes
] unit-test ] unit-test
[ V{ integer } ] [
[ { integer fixnum } declare mod ] final-classes
] unit-test
[ V{ integer } ] [
[ { fixnum integer } declare bitand ] final-classes
] unit-test
[ V{ float-array } ] [ [| | F{ } ] final-classes ] unit-test
! [ V{ string } ] [ ! [ V{ string } ] [
! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes ! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes
! ] unit-test ! ] unit-test

View File

@ -1,119 +0,0 @@
! TUPLE: declared-fixnum { x fixnum } ;
!
! [ t ] [
! [ { declared-fixnum } declare [ 1 + ] change-x ]
! { + fixnum+ >fixnum } inlined?
! ] unit-test
!
! [ t ] [
! [ { declared-fixnum } declare x>> drop ]
! { slot } inlined?
! ] unit-test
!
! [ t ] [
! [ hashtable new ] \ new inlined?
! ] unit-test
!
! [ t ] [
! [ dup hashtable eq? [ new ] when ] \ new inlined?
! ] unit-test
!
! [ f ] [
! [ { integer } declare -63 shift 4095 bitand ]
! \ shift inlined?
! ] unit-test
!
! [ t ] [
! [ { integer } declare 127 bitand 3 + ]
! { + +-integer-fixnum +-integer-fixnum-fast bitand } inlined?
! ] unit-test
!
! [ f ] [
! [ { integer } declare 127 bitand 3 + ]
! { >fixnum } inlined?
! ] unit-test
!
! [ t ] [
! [
! { integer } declare
! dup 0 >= [
! 615949 * 797807 + 20 2^ mod dup 19 2^ -
! ] [ dup ] if
! ] { * + shift mod fixnum-mod fixnum* fixnum+ fixnum- } inlined?
! ] unit-test
!
! [ t ] [
! [
! { fixnum } declare
! 615949 * 797807 + 20 2^ mod dup 19 2^ -
! ] { >fixnum } inlined?
! ] unit-test
!
! [ t ] [
! [
! { integer } declare 0 swap
! [
! drop 615949 * 797807 + 20 2^ rem dup 19 2^ -
! ] map
! ] { * + shift rem mod fixnum-mod fixnum* fixnum+ fixnum- } inlined?
! ] unit-test
!
! [ t ] [
! [
! { fixnum } declare 0 swap
! [
! drop 615949 * 797807 + 20 2^ rem dup 19 2^ -
! ] map
! ] { * + shift rem mod fixnum-mod fixnum* fixnum+ fixnum- >fixnum } inlined?
! ] unit-test
!
! [ t ] [
! [ { string sbuf } declare ] \ push-all def>> append \ + inlined?
! ] unit-test
!
! [ t ] [
! [ { string sbuf } declare ] \ push-all def>> append \ fixnum+ inlined?
! ] unit-test
!
! [ t ] [
! [ { string sbuf } declare ] \ push-all def>> append \ >fixnum inlined?
! ] unit-test
!
!
!
! [ t ] [
! [
! { integer } declare [ 256 mod ] map
! ] { mod fixnum-mod } inlined?
! ] unit-test
!
!
! [ f ] [
! [
! 256 mod
! ] { mod fixnum-mod } inlined?
! ] unit-test
!
! [ f ] [
! [
! dup 0 >= [ 256 mod ] when
! ] { mod fixnum-mod } inlined?
! ] unit-test
!
! [ t ] [
! [
! { integer } declare dup 0 >= [ 256 mod ] when
! ] { mod fixnum-mod } inlined?
! ] unit-test
!
! [ t ] [
! [
! { integer } declare 256 rem
! ] { mod fixnum-mod } inlined?
! ] unit-test
!
! [ t ] [
! [
! { integer } declare [ 256 rem ] map
! ] { mod fixnum-mod rem } inlined?
! ] unit-test

View File

@ -1,5 +0,0 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: compiler.tree.strength-reduction
: strength-reduce ( nodes -- nodes' ) ;

View File

@ -62,10 +62,6 @@ M: float-regs store-return-reg load/store-float-return FSTP ;
: with-aligned-stack ( n quot -- ) : with-aligned-stack ( n quot -- )
swap dup align-sub slip align-add ; inline swap dup align-sub slip align-add ; inline
! On x86, we can always use an address as an operand
! directly.
M: x86.32 address-operand ;
M: x86.32 fixnum>slot@ 1 SHR ; M: x86.32 fixnum>slot@ 1 SHR ;
M: x86.32 prepare-division CDQ ; M: x86.32 prepare-division CDQ ;

View File

@ -33,13 +33,6 @@ M: float-regs vregs
M: float-regs param-regs M: float-regs param-regs
drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
M: x86.64 address-operand ( address -- operand )
#! On AMD64, we have to load 64-bit addresses into a
#! scratch register first. The usage of R11 here is a hack.
#! This word can only be called right before a subroutine
#! call, where all vregs have been flushed anyway.
temp-reg v>operand [ swap MOV ] keep ;
M: x86.64 fixnum>slot@ drop ; M: x86.64 fixnum>slot@ drop ;
M: x86.64 prepare-division CQO ; M: x86.64 prepare-division CQO ;
@ -49,8 +42,8 @@ M: x86.64 load-indirect ( literal reg -- )
M: stack-params %load-param-reg M: stack-params %load-param-reg
drop drop
>r temp-reg v>operand swap stack@ MOV >r R11 swap stack@ MOV
r> stack@ temp-reg v>operand MOV ; r> stack@ R11 MOV ;
M: stack-params %save-param-reg M: stack-params %save-param-reg
>r stack-frame* + cell + swap r> %load-param-reg ; >r stack-frame* + cell + swap r> %load-param-reg ;
@ -138,7 +131,9 @@ M: x86.64 %alien-global
[ 0 MOV rc-absolute-cell rel-dlsym ] [ dup [] MOV ] bi ; [ 0 MOV rc-absolute-cell rel-dlsym ] [ dup [] MOV ] bi ;
M: x86.64 %alien-invoke M: x86.64 %alien-invoke
0 address-operand >r rc-absolute-cell rel-dlsym r> CALL ; R11 0 MOV
rc-absolute-cell rel-dlsym
R11 CALL ;
M: x86.64 %prepare-alien-indirect ( -- ) M: x86.64 %prepare-alien-indirect ( -- )
"unbox_alien" f %alien-invoke "unbox_alien" f %alien-invoke

View File

@ -39,8 +39,6 @@ GENERIC: store-return-reg ( stack@ reg-class -- )
HOOK: temp-reg-1 cpu ( -- reg ) HOOK: temp-reg-1 cpu ( -- reg )
HOOK: temp-reg-2 cpu ( -- reg ) HOOK: temp-reg-2 cpu ( -- reg )
HOOK: address-operand cpu ( address -- operand )
HOOK: fixnum>slot@ cpu ( op -- ) HOOK: fixnum>slot@ cpu ( op -- )
HOOK: prepare-division cpu ( -- ) HOOK: prepare-division cpu ( -- )

View File

@ -20,9 +20,24 @@ HELP: specialized-def
{ $description "Outputs the definition of a word after it has been split into specialized branches. This is the definition which will actually be compiled by the compiler." } ; { $description "Outputs the definition of a word after it has been split into specialized branches. This is the definition which will actually be compiled by the compiler." } ;
HELP: HINTS: HELP: HINTS:
{ $values { "word" word } { "hints..." "a list of sequences of classes" } } { $values { "defspec" "a definition specifier" } { "hints..." "a list of sequences of classes" } }
{ $description "Defines specialization hints for each words. Each sequence of classes in the list will cause a specialized version of the word to be compiled." } { $description "Defines specialization hints for a word or a method."
$nl
"Each sequence of classes in the list will cause a specialized version of the word to be compiled." }
{ $examples "The " { $link append } " word has a specializer for the very common case where two strings or two arrays are appended:" { $examples "The " { $link append } " word has a specializer for the very common case where two strings or two arrays are appended:"
{ $code "HINTS: append { string string } { array array } ;" } } ; { $code "HINTS: append { string string } { array array } ;" }
"Specializers can also be defined on methods:"
{ $code
"GENERIC: count-occurrences ( elt obj -- n )"
""
"M: sequence count-occurrences [ = ] with count ;"
""
"M: assoc count-occurrences"
" swap [ = nip ] curry assoc-filter assoc-size ;"
""
"HINTS: { sequence count-occurrences } { object array } ;"
"HINTS: { assoc count-occurrences } { object hashtable } ;"
}
} ;
ABOUT: "hints" ABOUT: "hints"

View File

@ -42,11 +42,11 @@ IN: hints
: specialized-def ( word -- quot ) : specialized-def ( word -- quot )
dup def>> swap { dup def>> swap {
{ [ dup standard-method? ] [ specialize-method ] }
{ {
[ dup "specializer" word-prop ] [ dup "specializer" word-prop ]
[ "specializer" word-prop specialize-quot ] [ "specializer" word-prop specialize-quot ]
} }
{ [ dup standard-method? ] [ specialize-method ] }
[ drop ] [ drop ]
} cond ; } cond ;
@ -54,7 +54,8 @@ IN: hints
dup [ array? ] all? [ first ] when length ; dup [ array? ] all? [ first ] when length ;
: HINTS: : HINTS:
scan-word scan-object
dup method-spec? [ first2 method ] when
[ redefined ] [ redefined ]
[ parse-definition "specializer" set-word-prop ] bi ; [ parse-definition "specializer" set-word-prop ] bi ;
parsing parsing

View File

@ -330,3 +330,5 @@ M:: sequence method-with-locals ( a -- y ) a reverse ;
[ T{ slice f 0 3 "abc" } ] [ T{ slice f 0 3 "abc" } ]
[ 0 3 "abc" [| from to seq | T{ slice f from to seq } ] call ] unit-test [ 0 3 "abc" [| from to seq | T{ slice f from to seq } ] call ] unit-test
{ 3 1 } [| from to seq | T{ slice f from to seq } ] must-infer-as

View File

@ -6,7 +6,7 @@ quotations debugger macros arrays macros splitting combinators
prettyprint.backend definitions prettyprint hashtables prettyprint.backend definitions prettyprint hashtables
prettyprint.sections sets sequences.private effects prettyprint.sections sets sequences.private effects
effects.parser generic generic.parser compiler.units accessors effects.parser generic generic.parser compiler.units accessors
locals.backend memoize macros.expander lexer locals.backend memoize macros.expander lexer classes
stack-checker.known-words ; stack-checker.known-words ;
IN: locals IN: locals
@ -195,70 +195,41 @@ M: block lambda-rewrite*
swap point-free , swap point-free ,
] keep length \ curry <repetition> % ; ] keep length \ curry <repetition> % ;
GENERIC: rewrite-element ( obj -- )
: rewrite-elements ( seq -- )
[ rewrite-element ] each ;
: rewrite-sequence ( seq -- )
[ rewrite-elements ] [ length , ] [ , ] tri \ nsequence , ;
M: array rewrite-element rewrite-sequence ;
M: vector rewrite-element rewrite-sequence ;
M: hashtable rewrite-element >alist rewrite-sequence \ >hashtable , ;
M: tuple rewrite-element
[ tuple-slots rewrite-elements ] [ class , ] bi \ boa , ;
M: local rewrite-element , ;
M: word rewrite-element literalize , ;
M: object rewrite-element , ;
M: array local-rewrite* rewrite-element ;
M: vector local-rewrite* rewrite-element ;
M: tuple local-rewrite* rewrite-element ;
M: hashtable local-rewrite* rewrite-element ;
M: object lambda-rewrite* , ; M: object lambda-rewrite* , ;
M: object local-rewrite* , ; M: object local-rewrite* , ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Broil is used to support locals in literals
DEFER: [broil]
DEFER: [broil-hashtable]
DEFER: [broil-tuple]
: broil-element ( obj -- quot )
{
{ [ dup number? ] [ 1quotation ] }
{ [ dup string? ] [ 1quotation ] }
{ [ dup sequence? ] [ [broil] ] }
{ [ dup hashtable? ] [ [broil-hashtable] ] }
{ [ dup tuple? ] [ [broil-tuple] ] }
{ [ dup local? ] [ 1quotation ] }
{ [ dup word? ] [ literalize 1quotation ] }
{ [ t ] [ 1quotation ] }
}
cond ;
: [broil] ( seq -- quot )
[ [ broil-element ] map concat >quotation ]
[ length ]
[ ]
tri
[ nsequence ] curry curry compose ;
MACRO: broil ( seq -- quot ) [broil] ;
: [broil-hashtable] ( hashtable -- quot )
>alist
[ [ broil-element ] map concat >quotation ]
[ length ]
[ ]
tri
[ nsequence >hashtable ] curry curry compose ;
MACRO: broil-hashtable ( hashtable -- quot ) [broil-hashtable] ;
: [broil-tuple] ( tuple -- quot )
tuple>array
[ [ broil-element ] map concat >quotation ]
[ length ]
[ ]
tri
[ nsequence >tuple ] curry curry compose ;
MACRO: broil-tuple ( tuple -- quot ) [broil-tuple] ;
! Engage broil on arrays and vectors. Can't do it on 'sequence'
! because that will pick up strings and integers. What do do...
M: array local-rewrite* ( array -- ) [broil] % ;
M: vector local-rewrite* ( vector -- ) [broil] % ;
M: tuple local-rewrite* ( tuple -- ) [broil-tuple] % ;
M: hashtable local-rewrite* ( hashtable -- ) [broil-hashtable] % ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: make-local ( name -- word ) : make-local ( name -- word )
"!" ?tail [ "!" ?tail [
<local-reader> <local-reader>

View File

@ -1,5 +1,6 @@
IN: math.partial-dispatch.tests IN: math.partial-dispatch.tests
USING: math.partial-dispatch tools.test math kernel sequences ; USING: math.partial-dispatch math.private
tools.test math kernel sequences ;
[ t ] [ \ + integer fixnum math-both-known? ] unit-test [ t ] [ \ + integer fixnum math-both-known? ] unit-test
[ t ] [ \ + bignum fixnum math-both-known? ] unit-test [ t ] [ \ + bignum fixnum math-both-known? ] unit-test
@ -10,3 +11,17 @@ USING: math.partial-dispatch tools.test math kernel sequences ;
[ f ] [ \ number= fixnum object math-both-known? ] unit-test [ f ] [ \ number= fixnum object math-both-known? ] unit-test
[ t ] [ \ number= integer fixnum math-both-known? ] unit-test [ t ] [ \ number= integer fixnum math-both-known? ] unit-test
[ f ] [ \ >fixnum \ shift derived-ops memq? ] unit-test [ f ] [ \ >fixnum \ shift derived-ops memq? ] unit-test
[ { integer fixnum } ] [ \ +-integer-fixnum integer-op-input-classes ] unit-test
[ { fixnum fixnum } ] [ \ fixnum+ integer-op-input-classes ] unit-test
[ { fixnum fixnum } ] [ \ fixnum+fast integer-op-input-classes ] unit-test
[ { integer } ] [ \ bitnot integer-op-input-classes ] unit-test
[ shift ] [ \ fixnum-shift generic-variant ] unit-test
[ fixnum-shift-fast ] [ \ fixnum-shift no-overflow-variant ] unit-test
[ fixnum-shift-fast ] [ \ shift modular-variant ] unit-test
[ fixnum-bitnot ] [ \ bitnot modular-variant ] unit-test
[ fixnum+fast ] [ \ fixnum+ modular-variant ] unit-test
[ fixnum+fast ] [ \ fixnum+fast modular-variant ] unit-test

View File

@ -6,13 +6,41 @@ generic generic.math hashtables effects compiler.units
classes.algebra ; classes.algebra ;
IN: math.partial-dispatch IN: math.partial-dispatch
! Partial dispatch.
! This code will be overhauled and generalized when
! multi-methods go into the core.
PREDICATE: math-partial < word PREDICATE: math-partial < word
"derived-from" word-prop >boolean ; "derived-from" word-prop >boolean ;
GENERIC: integer-op-input-classes ( word -- classes )
M: math-partial integer-op-input-classes
"derived-from" word-prop rest ;
M: word integer-op-input-classes
"input-classes" word-prop
[ "Bug: integer-op-input-classes" throw ] unless* ;
: generic-variant ( op -- generic-op/f )
dup "derived-from" word-prop [ first ] [ ] ?if ;
: no-overflow-variant ( op -- fast-op )
H{
{ fixnum+ fixnum+fast }
{ fixnum- fixnum-fast }
{ fixnum* fixnum*fast }
{ fixnum-shift fixnum-shift-fast }
} at ;
: modular-variant ( op -- fast-op )
generic-variant dup H{
{ + fixnum+fast }
{ - fixnum-fast }
{ * fixnum*fast }
{ shift fixnum-shift-fast }
{ bitand fixnum-bitand }
{ bitor fixnum-bitor }
{ bitxor fixnum-bitxor }
{ bitnot fixnum-bitnot }
} at swap or ;
:: fixnum-integer-op ( a b fix-word big-word -- c ) :: fixnum-integer-op ( a b fix-word big-word -- c )
b tag 0 eq? [ b tag 0 eq? [
a b fix-word execute a b fix-word execute
@ -69,10 +97,17 @@ PREDICATE: math-partial < word
} swap [ prefix ] curry map ; } swap [ prefix ] curry map ;
: define-integer-ops ( word fix-word big-word -- ) : define-integer-ops ( word fix-word big-word -- )
>r >r integer-op-triples r> r> [
rot tuck
[ fixnum fixnum 3array "derived-from" set-word-prop ]
[ bignum bignum 3array "derived-from" set-word-prop ]
2bi*
] [
[ integer-op-triples ] 2dip
[ define-integer-op-words ] [ define-integer-op-words ]
[ 2drop [ dup integer-op-word ] { } map>assoc % ] [ 2drop [ dup integer-op-word ] { } map>assoc % ]
3bi ; 3bi
] 3bi ;
: define-math-ops ( op -- ) : define-math-ops ( op -- )
{ fixnum bignum float } { fixnum bignum float }
@ -125,6 +160,9 @@ SYMBOL: fast-math-ops
: each-fast-derived-op ( word quot -- ) : each-fast-derived-op ( word quot -- )
>r fast-derived-ops r> each ; inline >r fast-derived-ops r> each ; inline
: each-integer-derived-op ( word quot -- )
>r integer-derived-ops r> each ; inline
[ [
[ [
\ + define-math-ops \ + define-math-ops

View File

@ -11,7 +11,7 @@ HELP: mime-db
HELP: mime-type HELP: mime-type
{ $values { $values
{ "path" "a pathname string" } { "filename" "a filename" }
{ "mime-type" "a MIME type string" } } { "mime-type" "a MIME type string" } }
{ $description "Outputs the MIME type associtated with a path by parsing the path's file extension and looking it up in the table returned by " { $link mime-types } "." } ; { $description "Outputs the MIME type associtated with a path by parsing the path's file extension and looking it up in the table returned by " { $link mime-types } "." } ;

View File

@ -3,7 +3,7 @@
USING: accessors kernel words parser io summary quotations USING: accessors kernel words parser io summary quotations
sequences prettyprint continuations effects definitions sequences prettyprint continuations effects definitions
compiler.units namespaces assocs tools.walker generic compiler.units namespaces assocs tools.walker generic
inspector ; inspector fry ;
IN: tools.annotations IN: tools.annotations
GENERIC: reset ( word -- ) GENERIC: reset ( word -- )
@ -49,20 +49,18 @@ M: word reset
.s .s
] if* "\\--" print flush ; ] if* "\\--" print flush ;
: (watch) ( word def -- def ) : (watch) ( word def -- def ) over '[ _ entering @ _ leaving ] ;
over [ entering ] curry
rot [ leaving ] curry
swapd 3append ;
: watch ( word -- ) : watch ( word -- )
dup [ (watch) ] annotate ; dup [ (watch) ] annotate ;
: (watch-vars) ( quot word vars -- newquot ) : (watch-vars) ( quot word vars -- newquot )
[ rot
"--- Entering: " write swap . '[
"--- Variable values:" print "--- Entering: " write _ .
[ dup get ] H{ } map>assoc describe "--- Variable values:" print _ [ dup get ] H{ } map>assoc describe
] 2curry prepose ; @
] ;
: watch-vars ( word vars -- ) : watch-vars ( word vars -- )
dupd [ (watch-vars) ] 2curry annotate ; dupd [ (watch-vars) ] 2curry annotate ;

View File

@ -250,10 +250,10 @@ unit-test
[ 50 ] [ 100 [ even? ] count ] unit-test [ 50 ] [ 100 [ even? ] count ] unit-test
[ 50 ] [ 100 [ odd? ] count ] unit-test [ 50 ] [ 100 [ odd? ] count ] unit-test
[ { "b" "d" } ] [ { "a" "b" "c" "d" } { 1 3 } nths ] unit-test [ { "b" "d" } ] [ { 1 3 } { "a" "b" "c" "d" } nths ] unit-test
[ { "a" "b" "c" "d" } ] [ { "a" "b" "c" "d" } { 0 1 2 3 } nths ] unit-test [ { "a" "b" "c" "d" } ] [ { 0 1 2 3 } { "a" "b" "c" "d" } nths ] unit-test
[ { "d" "c" "b" "a" } ] [ { "a" "b" "c" "d" } { 3 2 1 0 } nths ] unit-test [ { "d" "c" "b" "a" } ] [ { 3 2 1 0 } { "a" "b" "c" "d" } nths ] unit-test
[ { "d" "a" "b" "c" } ] [ { "a" "b" "c" "d" } { 3 0 1 2 } nths ] unit-test [ { "d" "a" "b" "c" } ] [ { 3 0 1 2 } { "a" "b" "c" "d" } nths ] unit-test
TUPLE: bogus-hashcode ; TUPLE: bogus-hashcode ;
@ -265,6 +265,6 @@ M: bogus-hashcode hashcode* 2drop 0 >bignum ;
[ { 1 3 7 } ] [ 2 { 1 3 5 7 } remove-nth ] unit-test [ { 1 3 7 } ] [ 2 { 1 3 5 7 } remove-nth ] unit-test
[ { 1 3 "X" 5 7 } ] [ "X" 2 { 1 3 5 7 } insert-nth ] [ { 1 3 "X" 5 7 } ] [ "X" 2 { 1 3 5 7 } insert-nth ] unit-test
[ V{ 0 2 } ] [ "a" { "a" "b" "a" } indices ] unit-test [ V{ 0 2 } ] [ "a" { "a" "b" "a" } indices ] unit-test

View File

@ -51,7 +51,7 @@ M: sequence shorten 2dup length < [ set-length ] [ 2drop ] if ;
: push ( elt seq -- ) [ length ] [ set-nth ] bi ; : push ( elt seq -- ) [ length ] [ set-nth ] bi ;
: bounds-check? ( n seq -- ? ) : bounds-check? ( n seq -- ? )
length 1- 0 swap between? ; inline dupd length < [ 0 >= ] [ drop f ] if ; inline
ERROR: bounds-error index seq ; ERROR: bounds-error index seq ;
@ -485,8 +485,8 @@ PRIVATE>
[ rot = [ over push ] [ drop ] if ] [ rot = [ over push ] [ drop ] if ]
curry each-index ; curry each-index ;
: nths ( seq indices -- seq' ) : nths ( indices seq -- seq' )
swap [ nth ] curry map ; [ nth ] curry map ;
: contains? ( seq quot -- ? ) : contains? ( seq quot -- ? )
find drop >boolean ; inline find drop >boolean ; inline

View File

@ -3,7 +3,7 @@
USING: arrays accessors float-arrays io io.files USING: arrays accessors float-arrays io io.files
io.encodings.binary kernel math math.functions math.vectors io.encodings.binary kernel math math.functions math.vectors
math.parser make sequences sequences.private words ; math.parser make sequences sequences.private words hints ;
IN: benchmark.raytracer IN: benchmark.raytracer
! parameters ! parameters
@ -38,34 +38,40 @@ TUPLE: sphere { center float-array read-only } { radius float read-only } ;
C: <sphere> sphere C: <sphere> sphere
: sphere-v ( sphere ray -- v ) : sphere-v ( sphere ray -- v )
swap center>> swap orig>> v- ; inline [ center>> ] [ orig>> ] bi* v- ; inline
: sphere-b ( ray v -- b ) swap dir>> v. ; inline : sphere-b ( v ray -- b )
dir>> v. ; inline
: sphere-disc ( sphere v b -- d ) : sphere-d ( sphere b v -- d )
sq swap norm-sq - swap radius>> sq + ; inline [ radius>> sq ] [ sq ] [ norm-sq ] tri* - + ; inline
: -+ ( x y -- x-y x+y ) [ - ] 2keep + ; inline : -+ ( x y -- x-y x+y )
[ - ] [ + ] 2bi ; inline
: sphere-b/d ( b d -- t ) : sphere-t ( b d -- t )
-+ dup 0.0 < -+ dup 0.0 <
[ 2drop 1.0/0.0 ] [ [ [ 0.0 > ] keep ] dip ? ] if ; inline [ 2drop 1.0/0.0 ] [ [ [ 0.0 > ] keep ] dip ? ] if ; inline
: ray-sphere ( sphere ray -- t ) : sphere-b&v ( sphere ray -- b v )
2dup sphere-v tuck sphere-b [ sphere-disc ] keep [ sphere-v ] [ nip ] 2bi
over 0.0 < [ 2drop 1.0/0.0 ] [ swap sqrt sphere-b/d ] if ; [ sphere-b ] [ drop ] 2bi ; inline
inline
: sphere-n ( ray sphere l -- n ) : ray-sphere ( sphere ray -- t )
pick dir>> n*v swap center>> v- swap orig>> v+ ; [ drop ] [ sphere-b&v ] 2bi
inline [ drop ] [ sphere-d ] 3bi
dup 0.0 < [ 3drop 1/0. ] [ sqrt sphere-t nip ] if ; inline
: if-ray-sphere ( hit ray sphere quot -- hit ) : if-ray-sphere ( hit ray sphere quot -- hit )
#! quot: hit ray sphere l -- hit #! quot: hit ray sphere l -- hit
[ [
pick lambda>> [ 2dup swap ray-sphere dup ] dip >= [ ] [ swap ray-sphere nip ] [ 2drop lambda>> ] 3tri
[ 3drop ] [ drop ] [ < ] 2bi
] dip if ; inline ] dip [ 3drop ] if ; inline
: sphere-n ( ray sphere l -- n )
[ [ orig>> ] [ dir>> ] bi ] [ center>> ] [ ] tri*
swap [ v*n ] dip v- v+ ; inline
M: sphere intersect-scene ( hit ray sphere -- hit ) M: sphere intersect-scene ( hit ray sphere -- hit )
[ [ sphere-n normalize ] keep <hit> nip ] if-ray-sphere ; [ [ sphere-n normalize ] keep <hit> nip ] if-ray-sphere ;
@ -79,21 +85,17 @@ TUPLE: group < sphere { objs array read-only } ;
swap [ { } make ] dip <group> ; inline swap [ { } make ] dip <group> ; inline
M: group intersect-scene ( hit ray group -- hit ) M: group intersect-scene ( hit ray group -- hit )
[ [ drop objs>> [ intersect-scene ] with each ] if-ray-sphere ;
drop
objs>> [ [ tuck ] dip intersect-scene swap ] each
drop
] if-ray-sphere ;
: initial-hit T{ hit f F{ 0.0 0.0 0.0 } 1.0/0.0 } ; inline : initial-hit T{ hit f F{ 0.0 0.0 0.0 } 1/0. } ; inline
: initial-intersect ( ray scene -- hit ) : initial-intersect ( ray scene -- hit )
initial-hit -rot intersect-scene ; inline [ initial-hit ] 2dip intersect-scene ; inline
: ray-o ( ray hit -- o ) : ray-o ( ray hit -- o )
over dir>> over lambda>> v*n [ [ orig>> ] [ normal>> delta v*n ] bi* ]
swap normal>> delta v*n v+ [ [ dir>> ] [ lambda>> ] bi* v*n ]
swap orig>> v+ ; inline 2bi v+ v+ ; inline
: sray-intersect ( ray scene hit -- ray ) : sray-intersect ( ray scene hit -- ray )
swap [ ray-o light vneg <ray> ] dip initial-intersect ; inline swap [ ray-o light vneg <ray> ] dip initial-intersect ; inline
@ -101,10 +103,10 @@ M: group intersect-scene ( hit ray group -- hit )
: ray-g ( hit -- g ) normal>> light v. ; inline : ray-g ( hit -- g ) normal>> light v. ; inline
: cast-ray ( ray scene -- g ) : cast-ray ( ray scene -- g )
2dup initial-intersect dup lambda>> 1.0/0.0 = [ 2dup initial-intersect dup lambda>> 1/0. = [
3drop 0.0 3drop 0.0
] [ ] [
[ sray-intersect lambda>> 1.0/0.0 = ] keep swap [ sray-intersect lambda>> 1/0. = ] keep swap
[ ray-g neg ] [ drop 0.0 ] if [ ray-g neg ] [ drop 0.0 ] if
] if ; inline ] if ; inline

View File

@ -32,8 +32,10 @@ IN: benchmark.spectral-norm
: eval-AtA-times-u ( u n -- seq ) : eval-AtA-times-u ( u n -- seq )
[ eval-A-times-u ] [ eval-At-times-u ] bi ; inline [ eval-A-times-u ] [ eval-At-times-u ] bi ; inline
: ones ( n -- seq ) [ 1.0 ] F{ } replicate-as ; inline
:: u/v ( n -- u v ) :: u/v ( n -- u v )
n 1.0 <repetition> >float-array dup n ones dup
10 [ 10 [
drop drop
n eval-AtA-times-u n eval-AtA-times-u
@ -41,7 +43,7 @@ IN: benchmark.spectral-norm
] times ; inline ] times ; inline
: spectral-norm ( n -- norm ) : spectral-norm ( n -- norm )
u/v [ v. ] keep norm-sq /f sqrt ; u/v [ v. ] [ norm-sq ] bi /f sqrt ;
HINTS: spectral-norm fixnum ; HINTS: spectral-norm fixnum ;

View File

@ -39,7 +39,7 @@ PRIVATE>
twiddle [ nPk ] keep factorial / ; twiddle [ nPk ] keep factorial / ;
: permutation ( n seq -- seq ) : permutation ( n seq -- seq )
tuck permutation-indices nths ; tuck permutation-indices swap nths ;
: all-permutations ( seq -- seq ) : all-permutations ( seq -- seq )
[ [

View File

@ -9,7 +9,7 @@ IN: project-euler.186
55 [1,b] [ (generator) ] map <circular> ; 55 [1,b] [ (generator) ] map <circular> ;
: advance ( lag -- ) : advance ( lag -- )
[ { 0 31 } nths sum 1000000 rem ] keep push-circular ; [ { 0 31 } swap nths sum 1000000 rem ] keep push-circular ;
: next ( lag -- n ) : next ( lag -- n )
[ first ] [ advance ] bi ; [ first ] [ advance ] bi ;

View File

@ -21,7 +21,6 @@ TUPLE: regexp
0 >>state 0 >>state
V{ } clone >>stack V{ } clone >>stack
V{ } clone >>new-states V{ } clone >>new-states
H{ } clone >>options
H{ } clone >>visited-states ; H{ } clone >>visited-states ;
SYMBOL: current-regexp SYMBOL: current-regexp

View File

@ -15,7 +15,7 @@ IN: regexp2.dfa
eps swap find-delta ; eps swap find-delta ;
: find-epsilon-closure ( states regexp -- new-states ) : find-epsilon-closure ( states regexp -- new-states )
'[ dup , (find-epsilon-closure) union ] [ length ] while-changes '[ dup _ (find-epsilon-closure) union ] [ length ] while-changes
natural-sort ; natural-sort ;
: find-closure ( states transition regexp -- new-states ) : find-closure ( states transition regexp -- new-states )

View File

@ -291,6 +291,8 @@ ERROR: bad-escaped-literals seq ;
{ CHAR: f [ HEX: c <constant> ] } { CHAR: f [ HEX: c <constant> ] }
{ CHAR: a [ HEX: 7 <constant> ] } { CHAR: a [ HEX: 7 <constant> ] }
{ CHAR: e [ HEX: 1b <constant> ] } { CHAR: e [ HEX: 1b <constant> ] }
{ CHAR: $ [ CHAR: $ <constant> ] }
{ CHAR: ^ [ CHAR: ^ <constant> ] }
{ CHAR: d [ digit-class ] } { CHAR: d [ digit-class ] }
{ CHAR: D [ digit-class <negation> ] } { CHAR: D [ digit-class <negation> ] }

View File

@ -222,6 +222,8 @@ IN: regexp2-tests
<regexp> drop <regexp> drop
] unit-test ] unit-test
[ ] [ "(\\$[\\p{XDigit}]|[\\p{Digit}])" <regexp> drop ] unit-test
! Comment ! Comment
[ t ] [ "ac" "a(?#boo)c" <regexp> matches? ] unit-test [ t ] [ "ac" "a(?#boo)c" <regexp> matches? ] unit-test

View File

@ -3,7 +3,8 @@
USING: accessors combinators kernel math math.ranges USING: accessors combinators kernel math math.ranges
sequences regexp2.backend regexp2.utils memoize sets sequences regexp2.backend regexp2.utils memoize sets
regexp2.parser regexp2.nfa regexp2.dfa regexp2.traversal regexp2.parser regexp2.nfa regexp2.dfa regexp2.traversal
regexp2.transition-tables ; regexp2.transition-tables assocs prettyprint.backend
make ;
IN: regexp2 IN: regexp2
: default-regexp ( string -- regexp ) : default-regexp ( string -- regexp )
@ -14,6 +15,7 @@ IN: regexp2
<transition-table> >>minimized-table <transition-table> >>minimized-table
H{ } clone >>nfa-traversal-flags H{ } clone >>nfa-traversal-flags
H{ } clone >>dfa-traversal-flags H{ } clone >>dfa-traversal-flags
H{ } clone >>options
reset-regexp ; reset-regexp ;
: construct-regexp ( regexp -- regexp' ) : construct-regexp ( regexp -- regexp' )
@ -60,3 +62,30 @@ IN: regexp2
: R` CHAR: ` <regexp> ; parsing : R` CHAR: ` <regexp> ; parsing
: R{ CHAR: } <regexp> ; parsing : R{ CHAR: } <regexp> ; parsing
: R| CHAR: | <regexp> ; parsing : R| CHAR: | <regexp> ; parsing
: find-regexp-syntax ( string -- prefix suffix )
{
{ "R/ " "/" }
{ "R! " "!" }
{ "R\" " "\"" }
{ "R# " "#" }
{ "R' " "'" }
{ "R( " ")" }
{ "R@ " "@" }
{ "R[ " "]" }
{ "R` " "`" }
{ "R{ " "}" }
{ "R| " "|" }
} swap [ subseq? not nip ] curry assoc-find drop ;
: option? ( option regexp -- ? )
options>> key? ;
M: regexp pprint*
[
[
dup raw>>
dup find-regexp-syntax swap % swap % %
case-insensitive swap option? [ "i" % ] when
] "" make
] keep present-text ;

View File

@ -45,7 +45,9 @@ TUPLE: dfa-traverser
] when text-finished? ; ] when text-finished? ;
: increment-state ( dfa-traverser state -- dfa-traverser ) : increment-state ( dfa-traverser state -- dfa-traverser )
>r [ 1+ ] change-current-index dup current-state>> >>last-state r> [
[ 1+ ] change-current-index dup current-state>> >>last-state
] dip
first >>current-state ; first >>current-state ;
: match-failed ( dfa-traverser -- dfa-traverser ) : match-failed ( dfa-traverser -- dfa-traverser )

View File

@ -9,7 +9,7 @@ IN: regexp2.utils
: (while-changes) ( obj quot pred pred-ret -- obj ) : (while-changes) ( obj quot pred pred-ret -- obj )
! quot: ( obj -- obj' ) ! quot: ( obj -- obj' )
! pred: ( obj -- <=> ) ! pred: ( obj -- <=> )
>r >r dup slip r> pick over call r> dupd = [ [ dup slip ] dip pick over call ] dip dupd =
[ 3drop ] [ (while-changes) ] if ; inline recursive [ 3drop ] [ (while-changes) ] if ; inline recursive
: while-changes ( obj quot pred -- obj' ) : while-changes ( obj quot pred -- obj' )