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

db4
Doug Coleman 2008-07-14 09:16:44 -05:00
commit 24c5d56731
56 changed files with 1034 additions and 361 deletions

View File

@ -151,8 +151,9 @@ M: byte-array byte-length length ;
swap dup length memcpy ;
: (define-nth) ( word type quot -- )
>r heap-size [ rot * >fixnum ] swap prefix
r> append define-inline ;
[
\ swap , [ heap-size , [ * >fixnum ] % ] [ % ] bi*
] [ ] make define-inline ;
: nth-word ( name vocab -- word )
>r "-nth" append r> create ;

View File

@ -44,10 +44,11 @@ ARTICLE: "assocs-protocol" "Associative mapping protocol"
{ $subsection set-at }
{ $subsection delete-at }
{ $subsection clear-assoc }
"The following two words are optional:"
"The following three words are optional:"
{ $subsection value-at* }
{ $subsection new-assoc }
{ $subsection assoc-like }
"Assocs should also implement methods on the " { $link clone } ", " { $link equal? } " and " { $link hashcode } " generic words. Two utility words will help with the implementation of the last two:"
"Assocs should also implement methods on the " { $link clone } ", " { $link equal? } " and " { $link hashcode* } " generic words. Two utility words will help with the implementation of the last two:"
{ $subsection assoc= }
{ $subsection assoc-hashcode }
"Finally, assoc classes should define a word for converting other types of assocs; conventionally, such words are named " { $snippet ">" { $emphasis "class" } } " where " { $snippet { $emphasis "class" } } " is the class name. Such a word can be implemented using a utility:"

View File

@ -121,7 +121,7 @@ bootstrapping? on
[ [ dup pair? [ first2 create ] when ] map ] map ;
: define-builtin-slots ( class slots -- )
prepare-slots 1 make-slots
prepare-slots make-slots 1 finalize-slots
[ "slots" set-word-prop ] [ define-accessors ] 2bi ;
: define-builtin ( symbol slotspec -- )
@ -273,18 +273,16 @@ bi
{ "echelon" { "fixnum" "math" } read-only }
} define-builtin
"tuple" "kernel" create {
[ { } define-builtin ]
[ { "delegate" } "slot-names" set-word-prop ]
[ define-tuple-layout ]
[
{ "delegate" }
[ drop ] [ generate-tuple-slots ] 2bi
[ "slots" set-word-prop ]
[ define-accessors ]
2bi
]
} cleave
"tuple" "kernel" create
[ { } define-builtin ]
[ define-tuple-layout ]
[
{ "delegate" } make-slots
[ drop ] [ finalize-tuple-slots ] 2bi
[ "slots" set-word-prop ]
[ define-accessors ]
2bi
] tri
! Create special tombstone values
"tombstone" "hashtables.private" create

View File

@ -1,35 +1,44 @@
IN: classes.tuple.parser.tests
USING: accessors classes.tuple.parser lexer words classes
sequences math kernel slots tools.test parser compiler.units ;
sequences math kernel slots tools.test parser compiler.units
arrays classes.tuple ;
TUPLE: test-1 ;
[ t ] [ test-1 "slot-names" word-prop empty? ] unit-test
[ t ] [ test-1 "slots" word-prop empty? ] unit-test
TUPLE: test-2 < test-1 ;
[ t ] [ test-2 "slot-names" word-prop empty? ] unit-test
[ t ] [ test-2 "slots" word-prop empty? ] unit-test
[ test-1 ] [ test-2 superclass ] unit-test
TUPLE: test-3 a ;
[ { "a" } ] [ test-3 "slot-names" word-prop ] unit-test
[ { "a" } ] [ test-3 "slots" word-prop [ name>> ] map ] unit-test
[ object ] [ "a" test-3 "slots" word-prop slot-named class>> ] unit-test
TUPLE: test-4 < test-3 b ;
[ { "b" } ] [ test-4 "slot-names" word-prop ] unit-test
[ { "b" } ] [ test-4 "slots" word-prop [ name>> ] map ] unit-test
TUPLE: test-5 { a integer } ;
[ { { "a" integer } } ] [ test-5 "slot-names" word-prop ] unit-test
[ { { "a" integer } } ]
[
test-5 "slots" word-prop
[ [ name>> ] [ class>> ] bi 2array ] map
] unit-test
TUPLE: test-6 < test-5 { b integer } ;
[ integer ] [ "b" test-6 "slots" word-prop slot-named class>> ] unit-test
[ { { "b" integer } } ] [ test-6 "slot-names" word-prop ] unit-test
[ { { "b" integer } } ]
[
test-6 "slots" word-prop
[ [ name>> ] [ class>> ] bi 2array ] map
] unit-test
TUPLE: test-7 { b integer initial: 3 } ;
@ -39,6 +48,8 @@ TUPLE: test-8 { b integer read-only } ;
[ t ] [ "b" test-8 "slots" word-prop slot-named read-only>> ] unit-test
DEFER: foo
[ "IN: classes.tuple.parser.tests TUPLE: foo < test-1 < ;" eval ]
[ error>> invalid-slot-name? ]
must-fail-with
@ -51,17 +62,33 @@ must-fail-with
[ error>> unexpected-eof? ]
must-fail-with
[ "IN: classes.tuple.parser.tests USE: alien TUPLE: foo { slot dll } ;" eval ]
[ error>> no-initial-value? ]
2 [
[ "IN: classes.tuple.parser.tests USE: alien TUPLE: foo { slot dll } ;" eval ]
[ error>> no-initial-value? ]
must-fail-with
[ f ] [ \ foo tuple-class? ] unit-test
] times
2 [
[ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo { slot array initial: 5 } ;" eval ]
[ error>> bad-initial-value? ]
must-fail-with
[ f ] [ \ foo tuple-class? ] unit-test
] times
[ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo slot { slot array } ;" eval ]
[ error>> duplicate-slot-names? ]
must-fail-with
[ "IN: classes.tuple.parser.tests USE: arrays TUPLE: foo { slot array initial: 5 } ;" eval ]
[ error>> bad-initial-value? ]
must-fail-with
[ f ] [ \ foo tuple-class? ] unit-test
[ ] [
[
{ test-1 test-2 test-3 test-4 test-5 test-6 test-7 test-8 }
{ test-1 test-2 test-3 test-4 test-5 test-6 test-7 test-8 foo }
[ dup class? [ forget-class ] [ drop ] if ] each
] with-compilation-unit
] unit-test

View File

@ -4,10 +4,11 @@ USING: accessors kernel sets namespaces sequences summary parser
lexer combinators words classes.parser classes.tuple arrays ;
IN: classes.tuple.parser
: slot-names ( slots -- seq )
[ dup array? [ first ] when ] map ;
: shadowed-slots ( superclass slots -- shadowed )
[ all-slots [ name>> ] map ]
[ [ dup array? [ first ] when ] map ]
bi* intersect ;
[ all-slots [ name>> ] map ] [ slot-names ] bi* intersect ;
: check-slot-shadowing ( class superclass slots -- )
shadowed-slots [
@ -20,11 +21,19 @@ IN: classes.tuple.parser
] "" make note.
] with each ;
ERROR: duplicate-slot-names names ;
M: duplicate-slot-names summary
drop "Duplicate slot names" ;
: check-duplicate-slots ( slots -- )
slot-names duplicates
dup empty? [ drop ] [ duplicate-slot-names ] if ;
ERROR: invalid-slot-name name ;
M: invalid-slot-name summary
drop
"Invalid slot name" ;
drop "Invalid slot name" ;
: parse-long-slot-name ( -- )
[ scan , \ } parse-until % ] { } make ;
@ -38,7 +47,7 @@ M: invalid-slot-name summary
#! : ...
{
{ [ dup not ] [ unexpected-eof ] }
{ [ dup { ":" "(" "<" "\"" } member? ] [ invalid-slot-name ] }
{ [ dup { ":" "(" "<" "\"" "!" } member? ] [ invalid-slot-name ] }
{ [ dup ";" = ] [ drop f ] }
[ dup "{" = [ drop parse-long-slot-name ] when , t ]
} cond ;
@ -52,4 +61,6 @@ M: invalid-slot-name summary
{ ";" [ tuple f ] }
{ "<" [ scan-word [ parse-tuple-slots ] { } make ] }
[ tuple swap [ parse-slot-name [ parse-tuple-slots ] when ] { } make ]
} case 3dup check-slot-shadowing ;
} case
dup check-duplicate-slots
3dup check-slot-shadowing ;

View File

@ -346,11 +346,9 @@ HELP: tuple
$nl
"Tuple classes have additional word properties:"
{ $list
{ { $snippet "\"constructor\"" } " - a word for creating instances of this tuple class" }
{ { $snippet "\"predicate\"" } " - a quotation which tests if the top of the stack is an instance of this tuple class" }
{ { $snippet "\"slots\"" } " - a sequence of " { $link slot-spec } " instances" }
{ { $snippet "\"slot-names\"" } " - a sequence of strings naming the tuple's slots" }
{ { $snippet "\"tuple-size\"" } " - the number of slots" }
{ { $snippet "\"tuple-layout\"" } " - a " { $link tuple-layout } " instance" }
} } ;
HELP: define-tuple-predicate

View File

@ -443,36 +443,36 @@ TUPLE: redefinition-problem-2 ;
! Hardcore unit tests
USE: threads
\ thread slot-names "slot-names" set
\ thread "slots" word-prop "slots" set
[ ] [
[
\ thread tuple { "xxx" } "slot-names" get append
\ thread tuple { "xxx" } "slots" get append
define-tuple-class
] with-compilation-unit
[ 1337 sleep ] "Test" spawn drop
[
\ thread tuple "slot-names" get
\ thread tuple "slots" get
define-tuple-class
] with-compilation-unit
] unit-test
USE: vocabs
\ vocab slot-names "slot-names" set
\ vocab "slots" word-prop "slots" set
[ ] [
[
\ vocab tuple { "xxx" } "slot-names" get append
\ vocab tuple { "xxx" } "slots" get append
define-tuple-class
] with-compilation-unit
all-words drop
[
\ vocab tuple "slot-names" get
\ vocab tuple "slots" get
define-tuple-class
] with-compilation-unit
] unit-test

View File

@ -22,18 +22,6 @@ ERROR: not-a-tuple object ;
<PRIVATE
: (tuple) ( layout -- tuple )
#! In non-optimized code, this word simply calls the
#! <tuple> primitive. In optimized code, an intrinsic
#! is generated which allocates a tuple but does not set
#! any of its slots. This means that any code that uses
#! (tuple) must fill in the slots before the next
#! call to GC.
#!
#! This word is only used in the expansion of <tuple-boa>,
#! where this invariant is guaranteed to hold.
<tuple> ;
: tuple-layout ( class -- layout )
"layout" word-prop ;
@ -86,9 +74,6 @@ M: tuple-class slots>tuple
: >tuple ( seq -- tuple )
unclip slots>tuple ;
: slot-names ( class -- seq )
"slot-names" word-prop ;
ERROR: bad-superclass class ;
<PRIVATE
@ -116,7 +101,7 @@ ERROR: bad-superclass class ;
: superclass-size ( class -- n )
superclasses but-last-slice
[ slot-names length ] sigma ;
[ "slots" word-prop length ] sigma ;
: (instance-check-quot) ( class -- quot )
[
@ -150,19 +135,18 @@ ERROR: bad-superclass class ;
: define-tuple-prototype ( class -- )
dup tuple-prototype "prototype" set-word-prop ;
: generate-tuple-slots ( class slots -- slot-specs )
over superclass-size 2 + make-slots deprecated-slots ;
: finalize-tuple-slots ( class slots -- slots )
over superclass-size 2 + finalize-slots deprecated-slots ;
: define-tuple-slots ( class -- )
dup dup "slot-names" word-prop generate-tuple-slots
[ "slots" set-word-prop ]
dup dup "slots" word-prop finalize-tuple-slots
[ define-accessors ] ! new
[ define-slots ] ! old
2tri ;
2bi ;
: make-tuple-layout ( class -- layout )
[ ]
[ [ superclass-size ] [ slot-names length ] bi + ]
[ [ superclass-size ] [ "slots" word-prop length ] bi + ]
[ superclasses dup length 1- ] tri
<tuple-layout> ;
@ -223,8 +207,9 @@ M: tuple-class update-class
} cleave ;
: define-new-tuple-class ( class superclass slots -- )
make-slots
[ drop f f tuple-class define-class ]
[ nip "slot-names" set-word-prop ]
[ nip "slots" set-word-prop ]
[ 2drop update-classes ]
3tri ;
@ -248,7 +233,7 @@ M: tuple-class update-class
3bi ;
: tuple-class-unchanged? ( class superclass slots -- ? )
rot tuck [ superclass = ] [ slot-names = ] 2bi* and ;
rot tuck [ superclass = ] [ "slots" word-prop = ] 2bi* and ;
: valid-superclass? ( class -- ? )
[ tuple-class? ] [ tuple eq? ] bi or ;
@ -293,7 +278,7 @@ M: tuple-class reset-class
[ call-next-method ]
[
{
"layout" "slots" "slot-names" "boa-check" "prototype"
"layout" "slots" "boa-check" "prototype"
} reset-props
] bi
] bi ;

View File

@ -162,8 +162,6 @@ PREDICATE: small-slot < integer cells small-enough? ;
PREDICATE: small-tagged < integer v>operand small-enough? ;
PREDICATE: inline-array < integer 32 < ;
: if-small-struct ( n size true false -- ? )
>r >r over not over struct-small-enough? and
[ nip r> call r> drop ] [ r> drop r> call ] if ;

View File

@ -1,8 +1,9 @@
! Copyright (C) 2007, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private kernel namespaces system
cpu.ppc.assembler generator.fixup compiler.units
compiler.constants math layouts words vocabs ;
USING: bootstrap.image.private kernel kernel.private namespaces
system cpu.ppc.assembler generator.fixup compiler.units
compiler.constants math math.private layouts words words.private
vocabs slots.private ;
IN: bootstrap.ppc
4 \ cell set
@ -11,9 +12,7 @@ big-endian on
4 jit-code-format set
: ds-reg 14 ;
: quot-reg 3 ;
: temp-reg 6 ;
: aux-reg 11 ;
: rs-reg 15 ;
: factor-area-size 4 bootstrap-cells ;
@ -24,86 +23,286 @@ big-endian on
: xt-save stack-frame 2 bootstrap-cells - ;
[
! Load word
0 temp-reg LOAD32
temp-reg dup 0 LWZ
! Bump profiling counter
aux-reg temp-reg profile-count-offset LWZ
aux-reg dup 1 tag-fixnum ADDI
aux-reg temp-reg profile-count-offset STW
! Load word->code
aux-reg temp-reg word-code-offset LWZ
! Compute word XT
aux-reg dup compiled-header-size ADDI
! Jump to XT
aux-reg MTCTR
0 6 LOAD32
6 dup 0 LWZ
11 6 profile-count-offset LWZ
11 11 1 tag-fixnum ADDI
11 6 profile-count-offset STW
11 6 word-code-offset LWZ
11 11 compiled-header-size ADDI
11 MTCTR
BCTR
] rc-absolute-ppc-2/2 rt-literal 1 jit-profiling jit-define
[
0 temp-reg LOAD32 ! load XT
0 MFLR ! load return address
1 1 stack-frame neg ADDI ! create stack frame
temp-reg 1 xt-save STW ! save XT
stack-frame temp-reg LI ! load frame size
temp-reg 1 next-save STW ! save frame size
0 1 lr-save stack-frame + STW ! save return address
0 6 LOAD32
0 MFLR
1 1 stack-frame SUBI
6 1 xt-save STW
stack-frame 6 LI
6 1 next-save STW
0 1 lr-save stack-frame + STW
] rc-absolute-ppc-2/2 rt-label 1 jit-prolog jit-define
[
0 temp-reg LOAD32 ! load literal
temp-reg dup 0 LWZ ! indirection
temp-reg ds-reg 4 STWU ! push literal
0 6 LOAD32
6 dup 0 LWZ
6 ds-reg 4 STWU
] rc-absolute-ppc-2/2 rt-literal 1 jit-push-literal jit-define
[
0 temp-reg LOAD32 ! load primitive address
4 1 MR ! pass stack pointer to primitive
temp-reg MTCTR ! jump to primitive
0 6 LOAD32
6 ds-reg 4 STWU
] rc-absolute-ppc-2/2 rt-immediate 1 jit-push-immediate jit-define
[
0 6 LOAD32
4 1 MR
6 MTCTR
BCTR
] rc-absolute-ppc-2/2 rt-primitive 1 jit-primitive jit-define
[
0 BL
] rc-relative-ppc-3 rt-xt 0 jit-word-call jit-define
[ 0 BL ] rc-relative-ppc-3 rt-xt 0 jit-word-call jit-define
[
0 B
] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define
[ 0 B ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define
: jit-call-quot ( -- )
temp-reg quot-reg quot-xt-offset LWZ ! load quotation-xt
temp-reg MTCTR ! jump to quotation-xt
4 3 quot-xt-offset LWZ
4 MTCTR
BCTR ;
[
0 quot-reg LOAD32 ! point quot-reg at false branch
temp-reg ds-reg 0 LWZ ! load boolean
0 temp-reg \ f tag-number CMPI ! compare it with f
2 BNE ! skip next insn if its not f
quot-reg dup 4 ADDI ! point quot-reg at true branch
quot-reg dup 0 LWZ ! load the branch
ds-reg dup 4 SUBI ! pop boolean
0 3 LOAD32
6 ds-reg 0 LWZ
0 6 \ f tag-number CMPI
2 BNE
3 3 4 ADDI
3 3 0 LWZ
ds-reg dup 4 SUBI
jit-call-quot
] rc-absolute-ppc-2/2 rt-literal 1 jit-if-jump jit-define
[
0 quot-reg LOAD32 ! load dispatch array
quot-reg dup 0 LWZ ! indirection
temp-reg ds-reg 0 LWZ ! load index
temp-reg dup 1 SRAWI ! turn it into an array offset
quot-reg dup temp-reg ADD ! compute quotation location
quot-reg dup array-start-offset LWZ ! load quotation
ds-reg dup 4 SUBI ! pop index
0 3 LOAD32
3 3 0 LWZ
6 ds-reg 0 LWZ
6 6 1 SRAWI
3 3 6 ADD
3 3 array-start-offset LWZ
ds-reg dup 4 SUBI
jit-call-quot
] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define
[
0 1 lr-save stack-frame + LWZ ! load return address
1 1 stack-frame ADDI ! pop stack frame
0 MTLR ! get ready to return
0 1 lr-save stack-frame + LWZ
1 1 stack-frame ADDI
0 MTLR
] f f f jit-epilog jit-define
[ BLR ] f f f jit-return jit-define
! Sub-primitives
! Quotations and words
[
3 ds-reg 0 LWZ
ds-reg dup 4 SUBI
jit-call-quot
] f f f \ (call) define-sub-primitive
[
3 ds-reg 0 LWZ
ds-reg dup 4 SUBI
4 3 word-xt-offset LWZ
4 MTCTR
BCTR
] f f f \ (execute) define-sub-primitive
! Objects
[
3 ds-reg 0 LWZ
3 3 tag-mask get ANDI
3 3 tag-bits get SLWI
3 ds-reg 0 STW
] f f f \ tag define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZU
3 3 1 SRAWI
4 4 0 0 31 tag-bits get - RLWINM
4 3 3 LWZX
3 ds-reg 0 STW
] f f f \ slot define-sub-primitive
! Shufflers
[
ds-reg dup 4 SUBI
] f f f \ drop define-sub-primitive
[
ds-reg dup 8 SUBI
] f f f \ 2drop define-sub-primitive
[
ds-reg dup 12 SUBI
] f f f \ 3drop define-sub-primitive
[
3 ds-reg 0 LWZ
3 ds-reg 4 STWU
] f f f \ dup define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
ds-reg dup 8 ADDI
3 ds-reg 0 STW
4 ds-reg -4 STW
] f f f \ 2dup define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
5 ds-reg -8 LWZ
ds-reg dup 12 ADDI
3 ds-reg 0 STW
4 ds-reg -4 STW
5 ds-reg -8 STW
] f f f \ 3dup define-sub-primitive
[
3 ds-reg 0 LWZ
ds-reg dup 4 SUBI
3 ds-reg 0 STW
] f f f \ nip define-sub-primitive
[
3 ds-reg 0 LWZ
ds-reg dup 8 SUBI
3 ds-reg 0 STW
] f f f \ 2nip define-sub-primitive
[
3 ds-reg -4 LWZ
3 ds-reg 4 STWU
] f f f \ over define-sub-primitive
[
3 ds-reg -8 LWZ
3 ds-reg 4 STWU
] f f f \ pick define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
4 ds-reg 0 STW
3 ds-reg 4 STWU
] f f f \ dupd define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
3 ds-reg 4 STWU
4 ds-reg -4 STW
3 ds-reg -8 STW
] f f f \ tuck define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
3 ds-reg -4 STW
4 ds-reg 0 STW
] f f f \ swap define-sub-primitive
[
3 ds-reg -4 LWZ
4 ds-reg -8 LWZ
3 ds-reg -8 STW
4 ds-reg -4 STW
] f f f \ swapd define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
5 ds-reg -8 LWZ
4 ds-reg -8 STW
3 ds-reg -4 STW
5 ds-reg 0 STW
] f f f \ rot define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZ
5 ds-reg -8 LWZ
3 ds-reg -8 STW
5 ds-reg -4 STW
4 ds-reg 0 STW
] f f f \ -rot define-sub-primitive
[
3 ds-reg 0 LWZ
ds-reg dup 4 SUBI
3 rs-reg 4 STWU
] f f f \ >r define-sub-primitive
[
3 rs-reg 0 LWZ
rs-reg dup 4 SUBI
3 ds-reg 4 STWU
] f f f \ r> define-sub-primitive
! Comparisons
: jit-compare ( insn -- )
0 3 LOAD32
3 3 0 LWZ
4 ds-reg 0 LWZ
5 ds-reg -4 LWZU
5 0 4 CMP
2 swap execute ! magic number
\ f tag-number 3 LI
3 ds-reg 0 STW ;
: define-jit-compare ( insn word -- )
[ [ jit-compare ] curry rc-absolute-ppc-2/2 rt-literal 1 ] dip
define-sub-primitive ;
\ BEQ \ eq? define-jit-compare
\ BGE \ fixnum>= define-jit-compare
\ BLE \ fixnum<= define-jit-compare
\ BGT \ fixnum> define-jit-compare
\ BLT \ fixnum< define-jit-compare
! Math
: jit-math ( insn -- )
3 ds-reg 0 LWZ
4 ds-reg -4 LWZU
[ 5 3 4 ] dip execute
5 ds-reg 0 STW ;
[ \ ADD jit-math ] f f f \ fixnum+fast define-sub-primitive
[ \ SUBF jit-math ] f f f \ fixnum-fast define-sub-primitive
[
3 ds-reg 0 LWZ
4 ds-reg -4 LWZU
4 4 tag-bits get SRAWI
5 3 4 MULLW
5 ds-reg 0 STW
] f f f \ fixnum*fast define-sub-primitive
[ \ AND jit-math ] f f f \ fixnum-bitand define-sub-primitive
[ \ OR jit-math ] f f f \ fixnum-bitor define-sub-primitive
[ \ XOR jit-math ] f f f \ fixnum-bitxor define-sub-primitive
[
3 ds-reg 0 LWZ
3 3 NOT
3 3 tag-mask get XORI
3 ds-reg 0 STW
] f f f \ fixnum-bitnot define-sub-primitive
[ "bootstrap.ppc" forget-vocab ] with-compilation-unit

View File

@ -1,14 +1,13 @@
! Copyright (C) 2005, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.accessors alien.c-types arrays cpu.ppc.assembler
cpu.ppc.architecture cpu.ppc.allot cpu.architecture kernel
kernel.private math math.private namespaces sequences words
generic quotations byte-arrays hashtables hashtables.private
generator generator.registers generator.fixup sequences.private
sbufs vectors system layouts math.floats.private
classes classes.tuple classes.tuple.private sbufs.private
vectors.private strings.private slots.private combinators
compiler.constants ;
USING: accessors alien alien.accessors alien.c-types arrays
cpu.ppc.assembler cpu.ppc.architecture cpu.ppc.allot
cpu.architecture kernel kernel.private math math.private
namespaces sequences words generic quotations byte-arrays
hashtables hashtables.private generator generator.registers
generator.fixup sequences.private sbufs vectors system layouts
math.floats.private classes slots.private combinators
compiler.constants optimizer.allot ;
IN: cpu.ppc.intrinsics
: %slot-literal-known-tag
@ -445,38 +444,33 @@ IN: cpu.ppc.intrinsics
! Store tagged ptr in reg
"tuple" get tuple %store-tagged
] H{
{ +input+ { { [ tuple-layout? ] "layout" } } }
{ +input+ { { [ ] "layout" } } }
{ +scratch+ { { f "tuple" } } }
{ +output+ { "tuple" } }
} define-intrinsic
\ <array> [
\ (array) [
array "n" get 2 + cells %allot
! Store length
"n" operand 12 LI
12 11 cell STW
! Store initial element
"n" get [ "initial" operand 11 rot 2 + cells STW ] each
! Store tagged ptr in reg
"array" get object %store-tagged
] H{
{ +input+ { { [ inline-array? ] "n" } { f "initial" } } }
{ +input+ { { [ ] "n" } } }
{ +scratch+ { { f "array" } } }
{ +output+ { "array" } }
} define-intrinsic
\ <byte-array> [
\ (byte-array) [
byte-array "n" get 2 cells + %allot
! Store length
"n" operand 12 LI
12 11 cell STW
! Store initial element
0 12 LI
"n" get cell align cell /i [ 12 11 rot 2 + cells STW ] each
! Store tagged ptr in reg
"array" get object %store-tagged
] H{
{ +input+ { { [ inline-array? ] "n" } } }
{ +input+ { { [ ] "n" } } }
{ +scratch+ { { f "array" } } }
{ +output+ { "array" } }
} define-intrinsic

View File

@ -6,8 +6,7 @@ kernel.private math math.private namespaces quotations sequences
words generic byte-arrays hashtables hashtables.private
generator generator.registers generator.fixup sequences.private
sbufs sbufs.private vectors vectors.private layouts system
classes.tuple.private strings.private slots.private
compiler.constants ;
strings.private slots.private compiler.constants optimizer.allot ;
IN: cpu.x86.intrinsics
! Type checks
@ -298,37 +297,33 @@ IN: cpu.x86.intrinsics
"tuple" get tuple %store-tagged
] %allot
] H{
{ +input+ { { [ tuple-layout? ] "layout" } } }
{ +input+ { { [ ] "layout" } } }
{ +scratch+ { { f "tuple" } { f "scratch" } } }
{ +output+ { "tuple" } }
} define-intrinsic
\ <array> [
\ (array) [
array "n" get 2 + cells [
! Store length
1 object@ "n" operand MOV
! Zero out the rest of the tuple
"n" get [ 2 + object@ "initial" operand MOV ] each
! Store tagged ptr in reg
"array" get object %store-tagged
] %allot
] H{
{ +input+ { { [ inline-array? ] "n" } { f "initial" } } }
{ +input+ { { [ ] "n" } } }
{ +scratch+ { { f "array" } } }
{ +output+ { "array" } }
} define-intrinsic
\ <byte-array> [
\ (byte-array) [
byte-array "n" get 2 cells + [
! Store length
1 object@ "n" operand MOV
! Store initial element
"n" get cell align cell /i [ 2 + object@ 0 MOV ] each
! Store tagged ptr in reg
"array" get object %store-tagged
] %allot
] H{
{ +input+ { { [ inline-array? ] "n" } } }
{ +input+ { { [ ] "n" } } }
{ +scratch+ { { f "array" } } }
{ +output+ { "array" } }
} define-intrinsic

View File

@ -212,6 +212,12 @@ M: not-a-tuple summary
M: bad-superclass summary
drop "Tuple classes can only inherit from other tuple classes" ;
M: no-initial-value summary
drop "Initial value must be provided for slots specialized to this class" ;
M: bad-initial-value summary
drop "Incompatible initial value" ;
M: no-cond summary
drop "Fall-through in cond" ;

View File

@ -93,11 +93,6 @@ HELP: hash-deleted+
{ $description "Called to increment the deleted entry counter when an entry is removed with " { $link delete-at } }
{ $side-effects "hash" } ;
HELP: (set-hash)
{ $values { "value" "a value" } { "key" "a key to add" } { "hash" hashtable } { "new?" "a boolean" } }
{ $description "Stores the key/value pair into the hashtable. This word does not grow the hashtable if it exceeds capacity, therefore a hang can result. User code should use " { $link set-at } " instead, which grows the hashtable if necessary." }
{ $side-effects "hash" } ;
HELP: grow-hash
{ $values { "hash" hashtable } }
{ $description "Enlarges the capacity of a hashtable. User code does not need to call this word directly." }

View File

@ -164,3 +164,16 @@ H{ } "x" set
[ { "one" "two" 3 } ] [
{ 1 2 3 } H{ { 1 "one" } { 2 "two" } } substitute
] unit-test
! We want this to work
[ ] [ hashtable new "h" set ] unit-test
[ 0 ] [ "h" get assoc-size ] unit-test
[ f f ] [ "goo" "h" get at* ] unit-test
[ ] [ 1 2 "h" get set-at ] unit-test
[ 1 ] [ "h" get assoc-size ] unit-test
[ 1 ] [ 2 "h" get at ] unit-test

View File

@ -20,15 +20,18 @@ TUPLE: hashtable
: probe ( array i -- array i )
2 fixnum+fast over wrap ; inline
: (key@) ( key keys i -- array n ? )
: no-key ( key array -- array n ? ) nip f f ; inline
: (key@) ( key array i -- array n ? )
3dup swap array-nth
dup ((empty)) eq?
[ 3drop nip f f ] [
[ 3drop no-key ] [
= [ rot drop t ] [ probe (key@) ] if
] if ; inline
: key@ ( key hash -- array n ? )
array>> 2dup hash@ (key@) ; inline
array>> dup array-capacity 0 eq?
[ no-key ] [ 2dup hash@ (key@) ] if ; inline
: <hash-array> ( n -- array )
1+ next-power-of-2 4 * ((empty)) <array> ; inline
@ -63,25 +66,20 @@ TUPLE: hashtable
: hash-deleted+ ( hash -- )
[ 1+ ] change-deleted drop ; inline
: (set-hash) ( value key hash -- new? )
2dup new-key@
[ rot hash-count+ set-nth-pair t ]
[ rot drop set-nth-pair f ] if ; inline
: (rehash) ( hash alist -- )
swap [ swapd (set-hash) drop ] curry assoc-each ;
swap [ swapd set-at ] curry assoc-each ; inline
: hash-large? ( hash -- ? )
[ count>> 3 fixnum*fast ]
[ array>> array-capacity ] bi > ;
[ count>> 3 fixnum*fast 1 fixnum+fast ]
[ array>> array-capacity ] bi fixnum> ; inline
: hash-stale? ( hash -- ? )
[ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ;
[ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ; inline
: grow-hash ( hash -- )
[ dup >alist swap assoc-size 1+ ] keep
[ reset-hash ] keep
swap (rehash) ;
swap (rehash) ; inline
: ?grow-hash ( hash -- )
dup hash-large? [
@ -122,7 +120,10 @@ M: hashtable assoc-size ( hash -- n )
r> (rehash) ;
M: hashtable set-at ( value key hash -- )
dup >r (set-hash) [ r> ?grow-hash ] [ r> drop ] if ;
dup ?grow-hash
2dup new-key@
[ rot hash-count+ set-nth-pair ]
[ rot drop set-nth-pair ] if ;
: associate ( value key -- hash )
2 <hashtable> [ set-at ] keep ;

View File

@ -540,9 +540,6 @@ set-primitive-effect
\ <tuple> { tuple-layout } { tuple } <effect> set-primitive-effect
\ <tuple> make-flushable
\ (tuple) { tuple-layout } { tuple } <effect> set-primitive-effect
\ (tuple) make-flushable
\ <tuple-layout> { word fixnum array fixnum } { tuple-layout } <effect> set-primitive-effect
\ <tuple-layout> make-foldable

View File

@ -33,10 +33,10 @@ SYMBOL: +editable+
: write-value ( mirror key -- )
<value-ref> write-slot-editor ;
: describe-row ( obj key n -- )
: describe-row ( mirror key n -- )
[
+number-rows+ get [ pprint-cell ] [ drop ] if
2dup write-key write-value
[ write-key ] [ write-value ] 2bi
] with-row ;
: summary. ( obj -- ) [ summary ] keep write-object nl ;
@ -48,21 +48,19 @@ SYMBOL: +editable+
sort-keys values
] [ keys ] if ;
: describe* ( obj flags -- )
clone [
dup summary.
make-mirror dup sorted-keys dup empty? [
2drop
] [
dup enum? [ +sequence+ on ] when
standard-table-style [
dup length
rot [ -rot describe-row ] curry 2each
] tabular-output
] if
] bind ;
: describe* ( obj mirror keys -- )
rot summary.
dup empty? [
2drop
] [
dup enum? [ +sequence+ on ] when
standard-table-style [
swap [ -rot describe-row ] curry each-index
] tabular-output
] if ;
: describe ( obj -- ) H{ } describe* ;
: describe ( obj -- )
dup make-mirror dup sorted-keys describe* ;
M: tuple error. describe ;
@ -78,19 +76,21 @@ M: tuple error. describe ;
SYMBOL: inspector-hook
[ H{ { +number-rows+ t } } describe* ] inspector-hook set-global
[ t +number-rows+ [ describe* ] with-variable ] inspector-hook set-global
SYMBOL: inspector-stack
SYMBOL: me
: reinspect ( obj -- )
dup me set
dup make-mirror dup mirror set keys \ keys set
inspector-hook get call ;
[ me set ]
[
dup make-mirror dup mirror set dup sorted-keys dup \ keys set
inspector-hook get call
] bi ;
: (inspect) ( obj -- )
dup inspector-stack get push reinspect ;
[ inspector-stack get push ] [ reinspect ] bi ;
: key@ ( n -- key ) \ keys get nth ;
@ -123,6 +123,7 @@ SYMBOL: me
"&add ( value key -- ) add new slot" print
"&delete ( n -- ) remove a slot" print
"&rename ( key n -- ) change a slot's key" print
"&globals ( -- ) inspect global namespace" print
"&help -- display this message" print
nl ;
@ -133,3 +134,5 @@ SYMBOL: me
: inspect ( obj -- )
inspector-stack get [ (inspect) ] [ inspector ] if ;
: &globals ( -- ) global inspect ;

View File

@ -0,0 +1,100 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors sequences sequences.private classes.tuple
classes.tuple.private kernel effects words quotations namespaces
definitions math math.order layouts alien.accessors
slots.private arrays byte-arrays inference.dataflow
inference.known-words inference.state optimizer.inlining
optimizer.backend ;
IN: optimizer.allot
! Expand memory allocation primitives into simpler constructs
! to simplify the backend.
: first-input ( #call -- obj ) dup in-d>> first node-literal ;
: (tuple) ( layout -- tuple ) "BUG: missing (tuple) intrinsic" throw ;
\ (tuple) { tuple-layout } { tuple } <effect> set-primitive-effect
\ (tuple) make-flushable
! if the input to new is a literal tuple class, we can expand it
: literal-new? ( #call -- ? )
first-input tuple-class? ;
: new-quot ( class -- quot )
dup all-slots 1 tail ! delegate slot
[ [ initial>> literalize , ] each literalize , \ boa , ] [ ] make ;
: expand-new ( #call -- node )
dup first-input
[ +inlined+ depends-on ] [ new-quot ] bi
f splice-quot ;
\ new {
{ [ dup literal-new? ] [ expand-new ] }
} define-optimizers
: tuple-boa-quot ( layout -- quot )
[
dup ,
[ nip (tuple) ] %
size>> 1 - [ 3 + ] map <reversed>
[ [ set-slot ] curry [ keep ] curry % ] each
[ f over 2 set-slot ] %
] [ ] make ;
: expand-tuple-boa ( #call -- node )
dup in-d>> peek value-literal tuple-boa-quot f splice-quot ;
\ <tuple-boa> {
{ [ t ] [ expand-tuple-boa ] }
} define-optimizers
: (array) ( n -- array ) "BUG: missing (array) intrinsic" throw ;
\ (array) { integer } { array } <effect> set-primitive-effect
\ (array) make-flushable
: <array>-quot ( n -- quot )
[
dup ,
[ (array) ] %
[ \ 2dup , , [ swap set-array-nth ] % ] each
\ 2nip ,
] [ ] make ;
: literal-<array>? ( #call -- ? )
first-input dup integer? [ 0 32 between? ] [ drop f ] if ;
: expand-<array> ( #call -- node )
dup first-input <array>-quot f splice-quot ;
\ <array> {
{ [ dup literal-<array>? ] [ expand-<array> ] }
} define-optimizers
: (byte-array) ( n -- byte-array ) "BUG: missing (byte-array) intrinsic" throw ;
\ (byte-array) { integer } { byte-array } <effect> set-primitive-effect
\ (byte-array) make-flushable
: bytes>cells ( m -- n ) cell align cell /i ;
: <byte-array>-quot ( n -- quot )
[
dup ,
[ nip (byte-array) ] %
bytes>cells [ cell * ] map
[ [ 0 over ] % , [ set-alien-unsigned-cell ] % ] each
] [ ] make ;
: literal-<byte-array>? ( #call -- ? )
first-input dup integer? [ 0 128 between? ] [ drop f ] if ;
: expand-<byte-array> ( #call -- node )
dup first-input <byte-array>-quot f splice-quot ;
\ <byte-array> {
{ [ dup literal-<byte-array>? ] [ expand-<byte-array> ] }
} define-optimizers

View File

@ -9,7 +9,7 @@ classes.tuple classes.predicate classes.tuple.private classes
classes.algebra sequences.private combinators byte-arrays
byte-vectors slots.private inference.dataflow inference.state
inference.class optimizer.def-use optimizer.backend
optimizer.pattern-match optimizer.inlining ;
optimizer.pattern-match optimizer.inlining optimizer.allot ;
IN: optimizer.known-words
{ <tuple> <tuple-boa> (tuple) } [
@ -25,37 +25,6 @@ IN: optimizer.known-words
dup class? [ drop tuple ] unless 1array f
] "output-classes" set-word-prop
! if the input to new is a literal tuple class, we can expand it
: literal-new? ( #call -- ? )
dup in-d>> first node-literal tuple-class? ;
: new-quot ( class -- quot )
dup all-slots 1 tail ! delegate slot
[ [ initial>> literalize , ] each literalize , \ boa , ] [ ] make ;
: expand-new ( #call -- node )
dup dup in-d>> first node-literal
[ +inlined+ depends-on ] [ new-quot ] bi
f splice-quot ;
\ new {
{ [ dup literal-new? ] [ expand-new ] }
} define-optimizers
: tuple-boa-quot ( layout -- quot )
[ (tuple) ]
swap size>> 1 - [ 3 + ] map <reversed>
[ [ set-slot ] curry [ keep ] curry ] map concat
[ f over 2 set-slot ]
3append ;
: expand-tuple-boa ( #call -- node )
dup in-d>> peek value-literal tuple-boa-quot f splice-quot ;
\ <tuple-boa> {
{ [ t ] [ expand-tuple-boa ] }
} define-optimizers
! the output of clone has the same type as the input
{ clone (clone) } [
[

View File

@ -406,7 +406,7 @@ most-negative-fixnum most-positive-fixnum [a,b]
: convert-mod-to-and ( #call -- node )
dup
dup node-in-d second node-literal 1-
dup in-d>> second node-literal 1-
[ nip bitand ] curry f splice-quot ;
\ mod [
@ -438,6 +438,19 @@ most-negative-fixnum most-positive-fixnum [a,b]
}
} define-optimizers
: convert-*-to-shift? ( #call -- ? )
dup in-d>> second node-literal
dup integer? [ power-of-2? ] [ drop f ] if ;
: convert-*-to-shift ( #call -- ? )
dup dup in-d>> second node-literal log2
[ nip fixnum-shift-fast ] curry
f splice-quot ;
\ fixnum*fast {
{ [ dup convert-*-to-shift? ] [ convert-*-to-shift ] }
} define-optimizers
{ + - * / }
[ { number number } "input-classes" set-word-prop ] each

View File

@ -384,3 +384,10 @@ PREDICATE: list < improper-list
[ 1 [ "hi" + drop ] compile-call ] must-fail
[ "hi" f [ <array> drop ] compile-call ] must-fail
TUPLE: some-tuple x ;
: allot-regression ( a -- b )
[ ] curry some-tuple boa ;
[ T{ some-tuple f [ 3 ] } ] [ 3 allot-regression ] unit-test

View File

@ -1,8 +1,9 @@
! Copyright (C) 2006, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel namespaces optimizer.backend optimizer.def-use
optimizer.known-words optimizer.math optimizer.control
optimizer.collect optimizer.inlining inference.class ;
optimizer.known-words optimizer.math optimizer.allot
optimizer.control optimizer.collect optimizer.inlining
inference.class ;
IN: optimizer
: optimize-1 ( node -- newnode ? )

View File

@ -277,13 +277,32 @@ M: array pprint-slot-name
f <inset unclip text pprint-elements block>
\ } pprint-word block> ;
: unparse-slot ( slot-spec -- array )
[
dup name>> ,
dup class>> object eq? [
dup class>> ,
initial: ,
dup initial>> ,
] unless
dup read-only>> [
read-only ,
] when
drop
] { } make ;
: pprint-slot ( slot-spec -- )
unparse-slot
dup length 1 = [ first ] when
pprint-slot-name ;
M: tuple-class see-class*
<colon \ TUPLE: pprint-word
dup pprint-word
dup superclass tuple eq? [
"<" text dup superclass pprint-word
] unless
<block slot-names [ pprint-slot-name ] each block>
<block "slots" word-prop [ pprint-slot ] each block>
pprint-; block> ;
M: word see-class* drop ;

View File

@ -124,16 +124,28 @@ ARTICLE: "sequences-combinators" "Sequence combinators"
{ $subsection each }
{ $subsection reduce }
{ $subsection interleave }
{ $subsection 2each }
{ $subsection 2reduce }
"Mapping:"
{ $subsection map }
{ $subsection 2map }
{ $subsection map-as }
{ $subsection accumulate }
{ $subsection produce }
"Filtering:"
{ $subsection push-if }
{ $subsection filter } ;
{ $subsection filter }
"Testing if a sequence contains elements satisfying a predicate:"
{ $subsection contains? }
{ $subsection all? }
"Testing how elements are related:"
{ $subsection monotonic? }
{ $subsection "sequence-2combinators" } ;
ARTICLE: "sequence-2combinators" "Pair-wise sequence combinators"
"There is a set of combinators which traverse two sequences pairwise. If one sequence is shorter than the other, than only the prefix having the length of the minimum of the two is examined."
{ $subsection 2each }
{ $subsection 2reduce }
{ $subsection 2map }
{ $subsection 2map-as }
{ $subsection 2all? } ;
ARTICLE: "sequences-tests" "Testing sequences"
"Testing for an empty sequence:"
@ -147,12 +159,7 @@ ARTICLE: "sequences-tests" "Testing sequences"
{ $subsection head? }
{ $subsection tail? }
{ $subsection subseq? }
"Testing if a sequence contains elements satisfying a predicate:"
{ $subsection contains? }
{ $subsection all? }
{ $subsection 2all? }
"Testing how elements are related:"
{ $subsection monotonic? }
{ $subsection all-eq? }
{ $subsection all-equal? } ;
@ -456,6 +463,15 @@ HELP: map
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( old -- new )" } } { "newseq" "a new sequence" } }
{ $description "Applies the quotation to each element of the sequence in order. The new elements are collected into a sequence of the same class as the input sequence." } ;
HELP: map-as
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( old -- new )" } } { "newseq" "a new sequence" } { "exemplar" sequence } }
{ $description "Applies the quotation to each element of the sequence in order. The new elements are collected into a sequence of the same class as " { $snippet "exemplar" } "." }
{ $examples
"The following example converts a string into an array of one-element strings:"
{ $example "USING: prettyprint strings sequences ;" "\"Hello\" [ 1string ] { } map-as ." "{ \"H\" \"e\" \"l\" \"l\" \"o\" }" }
"Note that " { $link map } " could not be used here, because it would create another string to hold results, and one-element strings cannot themselves be elements of strings."
} ;
HELP: change-nth
{ $values { "i" "a non-negative integer" } { "seq" "a mutable sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- newelt )" } } }
{ $description "Applies the quotation to the " { $snippet "i" } "th element of the sequence, storing the result back into the sequence." }
@ -478,8 +494,7 @@ HELP: max-length
HELP: 2each
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt1 elt2 -- )" } } }
{ $description "Applies the quotation to pairs of elements from " { $snippet "seq1" } " and " { $snippet "seq2" } "." }
{ $notes "If one sequence is shorter than the other, than only the prefix having the length of the minimum of the two is examined." } ;
{ $description "Applies the quotation to pairs of elements from " { $snippet "seq1" } " and " { $snippet "seq2" } "." } ;
HELP: 2reduce
{ $values { "seq1" sequence }
@ -488,18 +503,19 @@ HELP: 2reduce
{ "quot" "a quotation with stack effect "
{ $snippet "( prev elt1 elt2 -- next )" } }
{ "result" "the final result" } }
{ $description "Combines successive pairs of elements from the two sequences using a ternary operation. The first input value at each iteration except the first one is the result of the previous iteration. The first input value at the first iteration is " { $snippet "identity" } "." }
{ $notes "If one sequence is shorter than the other, then only the prefix having the length of the minimum of the two is examined." } ;
{ $description "Combines successive pairs of elements from the two sequences using a ternary operation. The first input value at each iteration except the first one is the result of the previous iteration. The first input value at the first iteration is " { $snippet "identity" } "." } ;
HELP: 2map
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt1 elt2 -- new )" } } { "newseq" "a new sequence" } }
{ $description "Applies the quotation to each pair of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "seq1" } "." }
{ $notes "If one sequence is shorter than the other, than only the prefix having the length of the minimum of the two is examined." } ;
{ $description "Applies the quotation to each pair of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "seq1" } "." } ;
HELP: 2map-as
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt1 elt2 -- new )" } } { "exemplar" sequence } { "newseq" "a new sequence" } }
{ $description "Applies the quotation to each pair of elements in turn, yielding new elements which are collected into a new sequence having the same class as " { $snippet "exemplar" } "." } ;
HELP: 2all?
{ $values { "seq1" sequence } { "seq2" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt1 elt2 -- ? )" } } { "?" "a boolean" } }
{ $description "Tests the predicate pairwise against elements of " { $snippet "seq1" } " and " { $snippet "seq2" } "." }
{ $notes "If one sequence is shorter than the other, than only the prefix having the length of the minimum of the two is examined." } ;
{ $description "Tests the predicate pairwise against elements of " { $snippet "seq1" } " and " { $snippet "seq2" } "." } ;
HELP: find
{ $values { "seq" sequence }

View File

@ -383,10 +383,13 @@ PRIVATE>
: 2reduce ( seq1 seq2 identity quot -- result )
>r -rot r> 2each ; inline
: 2map ( seq1 seq2 quot -- newseq )
pick >r (2each) over r>
: 2map-as ( seq1 seq2 quot exemplar -- newseq )
>r (2each) over r>
[ [ collect ] keep ] new-like ; inline
: 2map ( seq1 seq2 quot -- newseq )
pick 2map-as ; inline
: 2all? ( seq1 seq2 quot -- ? )
(2each) all-integers? ; inline

View File

@ -8,6 +8,7 @@ $nl
{ $subsection prune }
"Test for duplicates:"
{ $subsection all-unique? }
{ $subsection duplicates }
"Set operations on sequences:"
{ $subsection diff }
{ $subsection intersect }
@ -64,6 +65,13 @@ HELP: prune
{ $example "USING: sets prettyprint ;" "{ 1 1 t 3 t } prune ." "V{ 1 t 3 }" }
} ;
HELP: duplicates
{ $values { "seq" "a sequence" } { "newseq" "a sequence" } }
{ $description "Outputs a new sequence consisting of elements which occur more than once in " { $snippet "seq" } "." }
{ $examples
{ $example "USING: sets prettyprint ;" "{ 1 2 3 1 2 1 } duplicates ." "{ 1 2 1 }" }
} ;
HELP: all-unique?
{ $values { "seq" sequence } { "?" "a boolean" } }
{ $description "Tests whether a sequence contains any repeated elements." }

View File

@ -16,6 +16,9 @@ IN: sets
[ ] [ length <hashtable> ] [ length <vector> ] tri
[ [ (prune) ] 2curry each ] keep ;
: duplicates ( seq -- newseq )
H{ } clone [ [ key? ] [ conjoin ] 2bi ] curry filter ;
: gather ( seq quot -- newseq )
map concat prune ; inline

View File

@ -188,9 +188,14 @@ M: array make-slot
[ dup empty? not ] [ peel-off-attributes ] [ ] while drop
check-initial-value ;
: make-slots ( slots base -- specs )
over length [ + ] with map
[ [ make-slot ] dip >>offset ] 2map ;
M: slot-spec make-slot
check-initial-value ;
: make-slots ( slots -- specs )
[ make-slot ] map ;
: finalize-slots ( specs base -- specs )
over length [ + ] with map [ >>offset ] 2map ;
: slot-named ( name specs -- spec/f )
[ slot-spec-name = ] with find nip ;
[ name>> = ] with find nip ;

View File

@ -140,8 +140,6 @@ $nl
{ { $snippet "\"constructor\"" } { $link "tuple-constructors" } }
{ { $snippet "\"slot-names\"" } { $link "tuples" } }
{ { $snippet "\"type\"" } { $link "builtin-classes" } }
{ { { $snippet "\"superclass\"" } ", " { $snippet "\"predicate-definition\"" } } { $link "predicates" } }

View File

@ -0,0 +1,14 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math.ranges math.parser math.vectors sets sequences
kernel io ;
IN: benchmark.beust1
: count-numbers ( max -- n )
1 [a,b] [ number>string all-unique? ] count ; inline
: beust ( -- )
10000000 count-numbers
number>string " unique numbers." append print ;
MAIN: beust

View File

@ -0,0 +1,41 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math math.ranges math.parser sequences kernel io locals ;
IN: benchmark.beust2
! http://crazybob.org/BeustSequence.java.html
:: (count-numbers) ( remaining first value used max listener -- ? )
10 first - [| i |
[let* | digit [ i first + ]
mask [ digit 2^ ]
value' [ i value + ] |
used mask bitand zero? [
value max > [ t ] [
remaining 1 <= [
listener call f
] [
remaining 1-
0
value' 10 *
used mask bitor
max
listener
(count-numbers)
] if
] if
] [ f ] if
]
] contains? ; inline
:: count-numbers ( max listener -- )
10 [ 1+ 1 1 0 max listener (count-numbers) ] contains? drop ;
inline
:: beust ( -- )
[let | i! [ 0 ] |
10000000000 [ i 1+ i! ] count-numbers
i number>string " unique numbers." append print
] ;
MAIN: beust

View File

@ -1,4 +1,4 @@
USING: help.syntax help.markup kernel prettyprint sequences strings ;
USING: help.syntax help.markup kernel prettyprint sequences strings words math ;
IN: ctags
ARTICLE: "ctags" "Ctags file"
@ -6,7 +6,10 @@ ARTICLE: "ctags" "Ctags file"
{ $subsection ctags }
{ $subsection ctags-write }
{ $subsection ctag-strings }
{ $subsection ctag } ;
{ $subsection ctag }
{ $subsection ctag-word }
{ $subsection ctag-path }
{ $subsection ctag-lineno } ;
HELP: ctags ( path -- )
{ $values { "path" "a pathname string" } }
@ -57,4 +60,41 @@ HELP: ctag ( seq -- str )
}
} ;
HELP: ctag-lineno ( ctag -- n )
{ $values { "ctag" sequence }
{ "n" integer } }
{ $description "Provides de line number " { $snippet "n" } " from a sequence in ctag format " }
{ $examples
{ $example
"USING: kernel ctags prettyprint ;"
"{ if { \"resource:extra/unix/unix.factor\" 91 } } ctag-lineno ."
"91"
}
} ;
HELP: ctag-path ( ctag -- path )
{ $values { "ctag" sequence }
{ "path" string } }
{ $description "Provides a path string " { $snippet "path" } " from a sequence in ctag format" }
{ $examples
{ $example
"USING: kernel ctags prettyprint ;"
"{ if { \"resource:extra/unix/unix.factor\" 91 } } ctag-path ."
"\"resource:extra/unix/unix.factor\""
}
} ;
HELP: ctag-word ( ctag -- word )
{ $values { "ctag" sequence }
{ "word" word } }
{ $description "Provides the " { $snippet "word" } " from a sequence in ctag format " }
{ $examples
{ $example
"USING: kernel ctags prettyprint ;"
"{ if { \"resource:extra/unix/unix.factor\" 91 } } ctag-word ."
"if"
}
} ;
ABOUT: "ctags"

View File

@ -1,6 +1,21 @@
USING: kernel ctags tools.test io.backend sequences arrays prettyprint ;
IN: ctags.tests
[ t ] [
91
{ { if { "resource:extra/unix/unix.factor" 91 } } } ctag-lineno =
] unit-test
[ t ] [
"resource:extra/unix/unix.factor"
{ { if { "resource:extra/unix/unix.factor" 91 } } } ctag-path =
] unit-test
[ t ] [
if
{ { if { "resource:extra/unix/unix.factor" 91 } } } ctag-word =
] unit-test
[ t ] [
"if\t" "resource:extra/unix/unix.factor" normalize-path "\t91" 3append
{ if { "resource:extra/unix/unix.factor" 91 } } ctag =
@ -9,4 +24,5 @@ IN: ctags.tests
[ t ] [
"if\t" "resource:extra/unix/unix.factor" normalize-path "\t91" 3append 1array
{ { if { "resource:extra/unix/unix.factor" 91 } } } ctag-strings =
] unit-test
] unit-test

View File

@ -9,29 +9,36 @@ io.encodings.ascii math.parser vocabs definitions
namespaces words sorting ;
IN: ctags
: ctag-word ( ctag -- word )
first ;
: ctag-path ( ctag -- path )
second first ;
: ctag-lineno ( ctag -- n )
second second ;
: ctag ( seq -- str )
[
dup first ?word-name %
dup ctag-word ?word-name %
"\t" %
second dup first normalize-path %
dup ctag-path normalize-path %
"\t" %
second number>string %
ctag-lineno number>string %
] "" make ;
: ctag-strings ( seq1 -- seq2 )
{ } swap [ ctag suffix ] each ;
[ ctag ] map ;
: ctags-write ( seq path -- )
[ ctag-strings ] dip ascii set-file-lines ;
: (ctags) ( -- seq )
{ } all-words [
all-words [
dup where [
2array suffix
] [
drop
] if*
] each ;
2array
] when*
] map [ sequence? ] filter ;
: ctags ( path -- )
(ctags) sort-keys swap ctags-write ;

View File

@ -0,0 +1 @@
Alfredo Beaumont

View File

@ -0,0 +1,39 @@
USING: help.syntax help.markup kernel prettyprint sequences strings words math ;
IN: ctags.etags
ARTICLE: "etags" "Etags file"
{ $emphasis "Etags" } " generates a index file of every factor word in etags format as supported by emacs and other editors. More information can be found at " { $url "http://en.wikipedia.org/wiki/Ctags#Etags_2" } "."
{ $subsection etags }
{ $subsection etags-write }
{ $subsection etag-strings }
{ $subsection etag-header }
HELP: etags ( path -- )
{ $values { "path" string } }
{ $description "Generates a index file in etags format and stores in " { $snippet "path" } "." }
{ $examples
{ $unchecked-example
"USING: ctags.etags ;"
"\"ETAGS\" etags"
""
}
} ;
HELP: etags-write ( alist path -- )
{ $values { "alist" sequence }
{ "path" string } }
{ $description "Stores a " { $snippet "alist" } " in " { $snippet "path" } ". " { $snippet "alist" } " must be an association list with etags format: its key must be a resource path and its value a vector, containing pairs of words and lines" }
{ $examples
{ $unchecked-example
"USING: kernel etags.ctags ;"
"{ { \"resource:extra/unix/unix.factor\" V{ { dup2 91 } } } } \"ETAGS\" etags-write"
""
}
} ;
HELP: etag-strings ( alist -- seq )
{ $values { "alist" sequence }
{ "seq" sequence } }
{ $description "Converts an " { $snippet "alist" } " with etag format (a path as key and a vector containing word/line pairs) in a " { $snippet "seq" } " of strings." } ;
ABOUT: "etags" ;

View File

@ -0,0 +1,72 @@
USING: kernel ctags ctags.etags tools.test io.backend sequences arrays prettyprint hashtables assocs ;
IN: ctags.etags.tests
! etag-at
[ t ]
[
V{ }
"path" H{ } clone etag-at =
] unit-test
[ t ]
[
V{ if { "path" 1 } }
"path" H{ { "path" V{ if { "path" 1 } } } } etag-at =
] unit-test
! etag-vector
[ t ]
[
V{ }
{ if { "path" 1 } } H{ } clone etag-vector =
] unit-test
[ t ]
[
V{ if { "path" 1 } }
{ if { "path" 1 } }
{ { "path" V{ if { "path" 1 } } } } >hashtable
etag-vector =
] unit-test
! etag-pair
[ t ]
[
{ if 28 }
{ if { "resource:core/kernel/kernel.factor" 28 } } etag-pair =
] unit-test
! etag-add
[ t ]
[
H{ { "path" V{ { if 1 } } } }
{ if { "path" 1 } } H{ } clone [ etag-add ] keep =
] unit-test
! etag-hash
[ t ]
[
H{ { "path" V{ { if 1 } } } }
{ { if { "path" 1 } } } etag-hash =
] unit-test
! line-bytes (note that for each line implicit \n is counted)
[ t ]
[
17
{ "1234567890" "12345" } 2 lines>bytes =
] unit-test
! etag
[ t ]
[
"if2,11"
{ "1234567890" "12345" } { if 2 } etag =
] unit-test
! etag-length
[ t ]
[
14
V{ "if2,11" "if2,11" } etag-length =
] unit-test

View File

@ -0,0 +1,75 @@
! Copyright (C) 2008 Alfredo Beaumont
! See http://factorcode.org/license.txt for BSD license.
! Emacs Etags generator
! Alfredo Beaumont <alfredo.beaumont@gmail.com>
USING: kernel sequences sorting assocs words prettyprint ctags
io.encodings.ascii io.files math math.parser namespaces strings locals
shuffle io.backend arrays ;
IN: ctags.etags
: etag-at ( key hash -- vector )
at [ V{ } clone ] unless* ;
: etag-vector ( alist hash -- vector )
[ ctag-path ] dip etag-at ;
: etag-pair ( ctag -- seq )
dup [
first ,
second second ,
] { } make ;
: etag-add ( ctag hash -- )
[ etag-vector ] 2keep [
[ etag-pair ] [ ctag-path ] bi [ suffix ] dip
] dip set-at ;
: etag-hash ( seq -- hash )
H{ } clone swap [ swap [ etag-add ] keep ] each ;
: lines>bytes ( seq n -- bytes )
head 0 [ length 1+ + ] reduce ;
: file>lines ( path -- lines )
ascii file-lines ;
: etag ( lines seq -- str )
[
dup first ?word-name %
1 HEX: 7f <string> %
second dup number>string %
1 CHAR: , <string> %
1- lines>bytes number>string %
] "" make ;
: etag-length ( vector -- n )
0 [ length + ] reduce ;
: (etag-header) ( n path -- str )
[
%
1 CHAR: , <string> %
number>string %
] "" make ;
: etag-header ( vec1 n resource -- vec2 )
normalize-path (etag-header) prefix
1 HEX: 0c <string> prefix ;
: etag-strings ( alist -- seq )
{ } swap [
[
[ first file>lines ]
[ second ] bi
[ etag ] with map
dup etag-length
] keep first
etag-header append
] each ;
: etags-write ( alist path -- )
[ etag-strings ] dip ascii set-file-lines ;
: etags ( path -- )
[ (ctags) sort-values etag-hash >alist ] dip etags-write ;

View File

@ -0,0 +1 @@
Etags generator

View File

@ -1,9 +1,21 @@
! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license.
USING: help.syntax help.markup kernel sequences quotations
math ;
math arrays ;
IN: generalizations
HELP: narray
{ $values { "n" integer } }
{ $description "A generalization of " { $link 1array } ", "
{ $link 2array } ", " { $link 3array } " and " { $link 4array } " "
"that constructs an array from the top " { $snippet "n" } " elements of the stack."
} ;
HELP: firstn
{ $values { "n" integer } }
{ $description "A generalization of " { $link first } ", "
{ $link first2 } ", " { $link first3 } " and " { $link first4 } " "
"that pushes the first " { $snippet "n" } " elements of a sequence on the stack."
} ;
HELP: npick
{ $values { "n" integer } }
{ $description "A generalization of " { $link dup } ", "
@ -119,6 +131,7 @@ ARTICLE: "generalizations" "Generalized shuffle words and combinators"
"macros where the arity of the input quotations depends on an "
"input parameter."
{ $subsection narray }
{ $subsection firstn }
{ $subsection ndup }
{ $subsection npick }
{ $subsection nrot }

View File

@ -32,3 +32,7 @@ IN: generalizations.tests
[ [ dup 2^ 2array ] 5 napply ] must-infer
[ { "xyc" "xyd" } ] [ "x" "y" { "c" "d" } [ 3append ] 2 nwith map ] unit-test
[ 1 2 3 4 ] [ { 1 2 3 4 } 4 firstn ] unit-test
[ ] [ { } 0 firstn ] unit-test
[ "a" ] [ { "a" } 1 firstn ] unit-test

View File

@ -1,14 +1,20 @@
! Copyright (C) 2007, 2008 Chris Double, Doug Coleman.
! Copyright (C) 2007, 2008 Chris Double, Doug Coleman, Eduardo
! Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences sequences.private namespaces math math.ranges
combinators macros quotations fry locals arrays ;
USING: kernel sequences sequences.private namespaces math
math.ranges combinators macros quotations fry arrays ;
IN: generalizations
MACRO: narray ( n -- quot )
dup [ f <array> ] curry
swap <reversed> [
[ swap [ set-nth-unsafe ] keep ] curry
] map concat append ;
[ <reversed> ] [ '[ , f <array> ] ] bi
[ '[ @ [ , swap set-nth-unsafe ] keep ] ] reduce ;
MACRO: firstn ( n -- )
dup zero? [ drop [ drop ] ] [
[ [ '[ , _ nth-unsafe ] ] map ]
[ 1- '[ , _ bounds-check 2drop ] ]
bi prefix '[ , cleave ]
] if ;
MACRO: npick ( n -- )
1- dup saver [ dup ] rot [ r> swap ] n*quot 3append ;
@ -32,7 +38,7 @@ MACRO: ntuck ( n -- )
2 + [ dupd -nrot ] curry ;
MACRO: nrev ( n -- quot )
1 [a,b] [ '[ , -nrot ] ] map concat ;
1 [a,b] [ ] [ '[ @ , -nrot ] ] reduce ;
MACRO: ndip ( quot n -- )
dup saver -rot restorer 3append ;
@ -44,11 +50,11 @@ MACRO: nkeep ( n -- )
[ ] [ 1+ ] [ ] tri
'[ [ , ndup ] dip , -nrot , nslip ] ;
MACRO: ncurry ( n -- ) [ curry ] n*quot ;
MACRO: ncurry ( n -- )
[ curry ] n*quot ;
MACRO:: nwith ( quot n -- )
[let | n' [ n 1+ ] |
[ n' -nrot [ n' nrot quot call ] n ncurry ] ] ;
MACRO: nwith ( n -- )
[ with ] n*quot ;
MACRO: napply ( n -- )
2 [a,b]

View File

@ -1,5 +1,7 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences io.files io.launcher io.encodings.ascii
io.streams.string http.client sequences.lib combinators
io.streams.string http.client generalizations combinators
math.parser math.vectors math.intervals interval-maps memoize
csv accessors assocs strings math splitting grouping arrays ;
IN: geo-ip

View File

@ -4,8 +4,8 @@ IN: math.ranges
ARTICLE: "ranges" "Ranges"
"A " { $emphasis "range" } " is a virtual sequence with elements "
"ranging from a to b by step."
"A " { $emphasis "range" } " is a virtual sequence with real elements "
"ranging from " { $emphasis "a" } " to " { $emphasis "b" } " by " { $emphasis "step" } "."
$nl

View File

@ -134,7 +134,12 @@ $nl
"When using models which are not associated with controls (or when unit testing controls), you must activate and deactivate models manually:"
{ $subsection activate-model }
{ $subsection deactivate-model }
{ $subsection "models-impl" } ;
{ $subsection "models-impl" }
{ $subsection "models-filter" }
{ $subsection "models-compose" }
{ $subsection "models-history" }
{ $subsection "models-range" }
{ $subsection "models-delay" } ;
ARTICLE: "models-impl" "Implementing models"
"New types of models can be defined, for example see " { $vocab-link "models.filter" } "."

View File

@ -2,7 +2,7 @@
! USING: kernel quotations namespaces sequences assocs.lib ;
USING: kernel namespaces namespaces.private quotations sequences
assocs.lib math.parser math sequences.lib locals mirrors ;
assocs.lib math.parser math generalizations locals mirrors ;
IN: namespaces.lib

View File

@ -58,6 +58,7 @@ MATCH-VARS: ?a ?b ?c ;
{ { { ?a ?b ?c } { ?a ?b ?c ?a ?b ?c } } [ 3dup ] }
{ { { ?a ?b } { ?a ?b ?a } } [ over ] }
{ { { ?b ?a } { ?a ?b } } [ swap ] }
{ { { ?a ?b } { ?b ?a ?b } } [ tuck ] }
{ { { ?a ?b ?c } { ?a ?b ?c ?a } } [ pick ] }
{ { { ?a ?b ?c } { ?c ?a ?b } } [ -rot ] }
{ { { ?a ?b ?c } { ?b ?c ?a } } [ rot ] }

View File

@ -67,11 +67,6 @@ IN: sequences.lib.tests
{ 13 } [ 1 2 { 3 4 } [ + + ] 2 each-withn + ] unit-test
[ { 910 911 912 } ] [ 10 900 3 [ + + ] map-with2 ] unit-test
[ 1 2 3 4 ] [ { 1 2 3 4 } 4 firstn ] unit-test
[ ] [ { } 0 firstn ] unit-test
[ "a" ] [ { "a" } 1 firstn ] unit-test
[ "empty" ] [ { } [ "not empty" ] [ "empty" ] if-seq ] unit-test
[ { 1 } "not empty" ] [ { 1 } [ "not empty" ] [ "empty" ] if-seq ] unit-test

View File

@ -20,11 +20,6 @@ IN: sequences.lib
: map-with2 ( obj obj list quot -- newseq ) 2 map-withn ; inline
MACRO: firstn ( n -- )
[ [ swap nth ] curry [ keep ] curry ] map
concat >quotation
[ drop ] compose ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: each-percent ( seq quot -- )

View File

@ -20,13 +20,11 @@ TUPLE: browser-gadget < track pane history ;
"handbook" >link <history> >>history drop ;
: <browser-gadget> ( -- gadget )
{ 0 1 } browser-gadget new-track
{ 0 1 } browser-gadget new-track
dup init-history
[
toolbar,
g <help-pane> g-> set-browser-gadget-pane
<scroller> 1 track,
] make-gadget ;
dup <toolbar> f track-add*
dup <help-pane> >>pane
dup pane>> <scroller> 1 track-add* ;
M: browser-gadget call-tool* show-help ;

View File

@ -1,6 +1,6 @@
! Copyright (C) 2006, 2007 Slava Pestov.
! Copyright (C) 2006, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: ui.tools.workspace inspector kernel ui.commands
USING: accessors ui.tools.workspace inspector kernel ui.commands
ui.gadgets ui.gadgets.panes ui.gadgets.scrollers
ui.gadgets.slots ui.gadgets.tracks ui.gestures
ui.gadgets.buttons namespaces ;
@ -9,8 +9,10 @@ IN: ui.tools.inspector
TUPLE: inspector-gadget < track object pane ;
: refresh ( inspector -- )
dup inspector-gadget-object swap inspector-gadget-pane [
H{ { +editable+ t } { +number-rows+ t } } describe*
[ object>> ] [ pane>> ] bi [
+editable+ on
+number-rows+ on
describe
] with-pane ;
: <inspector-gadget> ( -- gadget )
@ -20,16 +22,14 @@ TUPLE: inspector-gadget < track object pane ;
<pane> g-> set-inspector-gadget-pane <scroller> 1 track,
] make-gadget ;
: inspect-object ( obj inspector -- )
[ set-inspector-gadget-object ] keep refresh ;
: inspect-object ( obj mirror keys inspector -- )
2nip swap >>object refresh ;
\ &push H{ { +nullary+ t } { +listener+ t } } define-command
\ &back H{ { +nullary+ t } { +listener+ t } } define-command
: globals ( -- ) global inspect ;
\ globals H{ { +nullary+ t } { +listener+ t } } define-command
\ &globals H{ { +nullary+ t } { +listener+ t } } define-command
: inspector-help ( -- ) "ui-inspector" help-window ;
@ -39,7 +39,7 @@ inspector-gadget "toolbar" f {
{ T{ update-object } refresh }
{ f &push }
{ f &back }
{ f globals }
{ f &globals }
{ T{ key-down f f "F1" } inspector-help }
} define-command-map

View File

@ -1,10 +1,11 @@
! Copyright (C) 2006, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors continuations kernel models namespaces
prettyprint ui ui.commands ui.gadgets ui.gadgets.labelled assocs
ui.gadgets.tracks ui.gadgets.buttons ui.gadgets.panes
ui.gadgets.status-bar ui.gadgets.scrollers ui.gestures sequences
hashtables inspector ;
prettyprint ui ui.commands ui.gadgets ui.gadgets.labelled assocs
ui.gadgets.tracks ui.gadgets.buttons ui.gadgets.panes
ui.gadgets.status-bar ui.gadgets.scrollers ui.gestures sequences
hashtables inspector ;
IN: ui.tools.traceback
: <callstack-display> ( model -- gadget )
@ -24,20 +25,18 @@ TUPLE: traceback-gadget < track ;
M: traceback-gadget pref-dim* drop { 550 600 } ;
: <traceback-gadget> ( model -- gadget )
{ 0 1 } traceback-gadget new-track
swap >>model
[
g model>>
[
[
[ <datastack-display> 1/2 track, ]
[ <retainstack-display> 1/2 track, ]
bi
] { 1 0 } make-track 1/3 track,
]
[ <callstack-display> 2/3 track, ] bi
toolbar,
] make-gadget ;
{ 0 1 } traceback-gadget new-track
swap >>model
dup model>>
{ 1 0 } <track>
over <datastack-display> 1/2 track-add*
swap <retainstack-display> 1/2 track-add*
1/3 track-add*
dup model>> <callstack-display> 2/3 track-add*
dup <toolbar> f track-add* ;
: <namestack-display> ( model -- gadget )
[ [ continuation-name namestack. ] when* ]

View File

@ -61,12 +61,11 @@ M: walker-gadget focusable-child*
swap >>continuation
swap >>status
dup continuation>> <traceback-gadget> >>traceback
[
toolbar,
g status>> self <thread-status> f track,
g traceback>> 1 track,
] make-gadget ;
dup <toolbar> f track-add*
dup status>> self <thread-status> f track-add*
dup traceback>> 1 track-add* ;
: walker-help ( -- ) "ui-walker" help-window ;
\ walker-help H{ { +nullary+ t } } define-command

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: io.files io.encodings.ascii sequences sequences.lib
USING: io.files io.encodings.ascii sequences generalizations
math.parser combinators kernel memoize csv symbols summary
words accessors math.order sorting ;
IN: usa-cities

View File

@ -103,20 +103,6 @@ DEF(void,c_to_factor,(CELL quot)):
EPILOGUE
blr
/* We must pass the XT to the quotation in r11. */
DEF(void,primitive_call,(void)):
lwz r3,0(r14) /* load quotation from data stack */
subi r14,r14,4 /* pop quotation from data stack */
JUMP_QUOT
/* We must preserve r4 here in case we're calling a primitive */
DEF(void,primitive_execute,(void)):
lwz r3,0(r14) /* load word from data stack */
lwz r11,29(r3) /* load word-xt slot */
mtctr r11 /* prepare to call XT */
subi r14,r14,4 /* pop word from data stack */
bctr /* go */
/* We pass a function pointer to memcpy in r6 to work around a Mac OS X ABI
limitation which would otherwise require us to do a bizzaro PC-relative
trampoline to retrieve the function address */