Merge commit 'origin/master' into emacs
commit
13a37ccf40
|
@ -13,6 +13,7 @@ circular strings ;
|
||||||
|
|
||||||
[ [ 1 2 3 ] ] [ { 1 2 3 } <circular> [ ] like ] unit-test
|
[ [ 1 2 3 ] ] [ { 1 2 3 } <circular> [ ] like ] unit-test
|
||||||
[ [ 2 3 1 ] ] [ { 1 2 3 } <circular> [ rotate-circular ] keep [ ] like ] unit-test
|
[ [ 2 3 1 ] ] [ { 1 2 3 } <circular> [ rotate-circular ] keep [ ] like ] unit-test
|
||||||
|
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> [ rotate-circular ] keep [ rotate-circular ] keep [ ] like ] unit-test
|
||||||
[ [ 2 3 1 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start [ ] like ] unit-test
|
[ [ 2 3 1 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start [ ] like ] unit-test
|
||||||
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start 1 over change-circular-start [ ] like ] unit-test
|
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start 1 over change-circular-start [ ] like ] unit-test
|
||||||
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> -100 over change-circular-start [ ] like ] unit-test
|
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> -100 over change-circular-start [ ] like ] unit-test
|
||||||
|
|
|
@ -28,10 +28,10 @@ M: circular virtual-seq seq>> ;
|
||||||
circular-wrap (>>start) ;
|
circular-wrap (>>start) ;
|
||||||
|
|
||||||
: rotate-circular ( circular -- )
|
: rotate-circular ( circular -- )
|
||||||
[ start>> 1 + ] keep circular-wrap (>>start) ;
|
[ 1 ] dip change-circular-start ;
|
||||||
|
|
||||||
: push-circular ( elt circular -- )
|
: push-circular ( elt circular -- )
|
||||||
[ set-first ] [ 1 swap change-circular-start ] bi ;
|
[ set-first ] [ rotate-circular ] bi ;
|
||||||
|
|
||||||
: <circular-string> ( n -- circular )
|
: <circular-string> ( n -- circular )
|
||||||
0 <string> <circular> ;
|
0 <string> <circular> ;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel arrays vectors accessors
|
USING: kernel arrays vectors accessors
|
||||||
namespaces make fry sequences ;
|
namespaces math make fry sequences ;
|
||||||
IN: compiler.cfg
|
IN: compiler.cfg
|
||||||
|
|
||||||
TUPLE: basic-block < identity-tuple
|
TUPLE: basic-block < identity-tuple
|
||||||
id
|
{ id integer }
|
||||||
number
|
number
|
||||||
{ instructions vector }
|
{ instructions vector }
|
||||||
{ successors vector }
|
{ successors vector }
|
||||||
|
|
|
@ -16,6 +16,9 @@ ERROR: last-insn-not-a-jump insn ;
|
||||||
[ ##return? ]
|
[ ##return? ]
|
||||||
[ ##callback-return? ]
|
[ ##callback-return? ]
|
||||||
[ ##jump? ]
|
[ ##jump? ]
|
||||||
|
[ ##fixnum-add-tail? ]
|
||||||
|
[ ##fixnum-sub-tail? ]
|
||||||
|
[ ##fixnum-mul-tail? ]
|
||||||
[ ##call? ]
|
[ ##call? ]
|
||||||
} 1|| [ drop ] [ last-insn-not-a-jump ] if ;
|
} 1|| [ drop ] [ last-insn-not-a-jump ] if ;
|
||||||
|
|
||||||
|
|
|
@ -226,18 +226,41 @@ SYMBOL: spill-counts
|
||||||
: assign-free-register ( new registers -- )
|
: assign-free-register ( new registers -- )
|
||||||
pop >>reg add-active ;
|
pop >>reg add-active ;
|
||||||
|
|
||||||
: next-intersection ( new inactive -- n )
|
: relevant-ranges ( new inactive -- new' inactive' )
|
||||||
2drop 0 ;
|
! Slice off all ranges of 'inactive' that precede the start of 'new'
|
||||||
|
[ [ ranges>> ] bi@ ] [ nip start>> ] 2bi '[ to>> _ >= ] filter ;
|
||||||
|
|
||||||
|
: intersect-live-range ( range1 range2 -- n/f )
|
||||||
|
2dup [ from>> ] bi@ > [ swap ] when
|
||||||
|
2dup [ to>> ] [ from>> ] bi* >= [ nip from>> ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
: intersect-live-ranges ( ranges1 ranges2 -- n )
|
||||||
|
{
|
||||||
|
{ [ over empty? ] [ 2drop 1/0. ] }
|
||||||
|
{ [ dup empty? ] [ 2drop 1/0. ] }
|
||||||
|
[
|
||||||
|
2dup [ first ] bi@ intersect-live-range dup [ 2nip ] [
|
||||||
|
drop
|
||||||
|
2dup [ first from>> ] bi@ <
|
||||||
|
[ [ rest-slice ] dip ] [ rest-slice ] if
|
||||||
|
intersect-live-ranges
|
||||||
|
] if
|
||||||
|
]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: intersect-inactive ( new inactive -- n )
|
||||||
|
relevant-ranges intersect-live-ranges ;
|
||||||
|
|
||||||
: intersecting-inactive ( new -- live-intervals )
|
: intersecting-inactive ( new -- live-intervals )
|
||||||
dup vreg>> inactive-intervals-for
|
dup vreg>> inactive-intervals-for
|
||||||
[ tuck next-intersection ] with { } map>assoc ;
|
[ tuck intersect-inactive ] with { } map>assoc ;
|
||||||
|
|
||||||
: fits-in-hole ( new pair -- )
|
: fits-in-hole ( new pair -- )
|
||||||
first reuse-register ;
|
first reuse-register ;
|
||||||
|
|
||||||
: split-before-use ( new pair -- before after )
|
: split-before-use ( new pair -- before after )
|
||||||
! Find optimal split position
|
! Find optimal split position
|
||||||
|
! Insert move instruction
|
||||||
second split-interval ;
|
second split-interval ;
|
||||||
|
|
||||||
: assign-inactive-register ( new live-intervals -- )
|
: assign-inactive-register ( new live-intervals -- )
|
||||||
|
@ -264,7 +287,7 @@ SYMBOL: spill-counts
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
! Main loop
|
! Main loop
|
||||||
: reg-classes ( -- seq ) { int-regs double-float-regs } ; inline
|
CONSTANT: reg-classes { int-regs double-float-regs }
|
||||||
|
|
||||||
: reg-class-assoc ( quot -- assoc )
|
: reg-class-assoc ( quot -- assoc )
|
||||||
[ reg-classes ] dip { } map>assoc ; inline
|
[ reg-classes ] dip { } map>assoc ; inline
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel math assocs namespaces sequences heaps
|
USING: accessors kernel math assocs namespaces sequences heaps
|
||||||
fry make combinators
|
fry make combinators sets
|
||||||
cpu.architecture
|
cpu.architecture
|
||||||
compiler.cfg.def-use
|
compiler.cfg.def-use
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
|
compiler.cfg.linear-scan.allocation
|
||||||
compiler.cfg.linear-scan.live-intervals ;
|
compiler.cfg.linear-scan.live-intervals ;
|
||||||
IN: compiler.cfg.linear-scan.assignment
|
IN: compiler.cfg.linear-scan.assignment
|
||||||
|
|
||||||
|
@ -30,25 +31,44 @@ SYMBOL: unhandled-intervals
|
||||||
: init-unhandled ( live-intervals -- )
|
: init-unhandled ( live-intervals -- )
|
||||||
[ add-unhandled ] each ;
|
[ add-unhandled ] each ;
|
||||||
|
|
||||||
|
! Mapping spill slots to vregs
|
||||||
|
SYMBOL: spill-slots
|
||||||
|
|
||||||
|
: spill-slots-for ( vreg -- assoc )
|
||||||
|
reg-class>> spill-slots get at ;
|
||||||
|
|
||||||
|
: record-spill ( live-interval -- )
|
||||||
|
[ dup spill-to>> ] [ vreg>> spill-slots-for ] bi
|
||||||
|
2dup key? [ "BUG: Already spilled" throw ] [ set-at ] if ;
|
||||||
|
|
||||||
: insert-spill ( live-interval -- )
|
: insert-spill ( live-interval -- )
|
||||||
[ reg>> ] [ vreg>> reg-class>> ] [ spill-to>> ] tri
|
[ reg>> ] [ vreg>> reg-class>> ] [ spill-to>> ] tri _spill ;
|
||||||
dup [ _spill ] [ 3drop ] if ;
|
|
||||||
|
: handle-spill ( live-interval -- )
|
||||||
|
dup spill-to>> [ [ record-spill ] [ insert-spill ] bi ] [ drop ] if ;
|
||||||
|
|
||||||
: expire-old-intervals ( n -- )
|
: expire-old-intervals ( n -- )
|
||||||
active-intervals get
|
active-intervals get
|
||||||
[ swap '[ end>> _ = ] partition ] change-seq drop
|
[ swap '[ end>> _ = ] partition ] change-seq drop
|
||||||
[ insert-spill ] each ;
|
[ handle-spill ] each ;
|
||||||
|
|
||||||
|
: record-reload ( live-interval -- )
|
||||||
|
[ reload-from>> ] [ vreg>> spill-slots-for ] bi
|
||||||
|
2dup key? [ delete-at ] [ "BUG: Already reloaded" throw ] if ;
|
||||||
|
|
||||||
: insert-reload ( live-interval -- )
|
: insert-reload ( live-interval -- )
|
||||||
[ reg>> ] [ vreg>> reg-class>> ] [ reload-from>> ] tri
|
[ reg>> ] [ vreg>> reg-class>> ] [ reload-from>> ] tri _reload ;
|
||||||
dup [ _reload ] [ 3drop ] if ;
|
|
||||||
|
: handle-reload ( live-interval -- )
|
||||||
|
dup reload-from>> [ [ record-reload ] [ insert-reload ] bi ] [ drop ] if ;
|
||||||
|
|
||||||
: activate-new-intervals ( n -- )
|
: activate-new-intervals ( n -- )
|
||||||
#! Any live intervals which start on the current instruction
|
#! Any live intervals which start on the current instruction
|
||||||
#! are added to the active set.
|
#! are added to the active set.
|
||||||
unhandled-intervals get dup heap-empty? [ 2drop ] [
|
unhandled-intervals get dup heap-empty? [ 2drop ] [
|
||||||
2dup heap-peek drop start>> = [
|
2dup heap-peek drop start>> = [
|
||||||
heap-pop drop [ add-active ] [ insert-reload ] bi
|
heap-pop drop
|
||||||
|
[ add-active ] [ handle-reload ] bi
|
||||||
activate-new-intervals
|
activate-new-intervals
|
||||||
] [ 2drop ] if
|
] [ 2drop ] if
|
||||||
] if ;
|
] if ;
|
||||||
|
@ -71,8 +91,7 @@ M: insn assign-before drop ;
|
||||||
active-intervals get seq>> [ [ vreg>> ] [ reg>> ] bi ] { } map>assoc ;
|
active-intervals get seq>> [ [ vreg>> ] [ reg>> ] bi ] { } map>assoc ;
|
||||||
|
|
||||||
: compute-live-spill-slots ( -- spill-slots )
|
: compute-live-spill-slots ( -- spill-slots )
|
||||||
unhandled-intervals get
|
spill-slots get values [ values ] map concat
|
||||||
heap-values [ reload-from>> ] filter
|
|
||||||
[ [ vreg>> ] [ reload-from>> ] bi ] { } map>assoc ;
|
[ [ vreg>> ] [ reload-from>> ] bi ] { } map>assoc ;
|
||||||
|
|
||||||
M: ##gc assign-after
|
M: ##gc assign-after
|
||||||
|
@ -88,6 +107,7 @@ M: insn assign-after drop ;
|
||||||
: init-assignment ( live-intervals -- )
|
: init-assignment ( live-intervals -- )
|
||||||
<active-intervals> active-intervals set
|
<active-intervals> active-intervals set
|
||||||
<min-heap> unhandled-intervals set
|
<min-heap> unhandled-intervals set
|
||||||
|
[ H{ } clone ] reg-class-assoc spill-slots set
|
||||||
init-unhandled ;
|
init-unhandled ;
|
||||||
|
|
||||||
: assign-registers-in-block ( bb -- )
|
: assign-registers-in-block ( bb -- )
|
||||||
|
|
|
@ -1290,3 +1290,88 @@ USING: math.private compiler.cfg.debugger ;
|
||||||
{ { int-regs { 0 1 2 3 } } }
|
{ { int-regs { 0 1 2 3 } } }
|
||||||
allocate-registers drop
|
allocate-registers drop
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
! Spill slot liveness was computed incorrectly, leading to a FEP
|
||||||
|
! early in bootstrap on x86-32
|
||||||
|
[ t ] [
|
||||||
|
T{ basic-block
|
||||||
|
{ instructions
|
||||||
|
V{
|
||||||
|
T{ ##gc f V int-regs 6 V int-regs 7 }
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##peek f V int-regs 1 D 1 }
|
||||||
|
T{ ##peek f V int-regs 2 D 2 }
|
||||||
|
T{ ##peek f V int-regs 3 D 3 }
|
||||||
|
T{ ##peek f V int-regs 4 D 4 }
|
||||||
|
T{ ##peek f V int-regs 5 D 5 }
|
||||||
|
T{ ##replace f V int-regs 0 D 1 }
|
||||||
|
T{ ##replace f V int-regs 1 D 2 }
|
||||||
|
T{ ##replace f V int-regs 2 D 3 }
|
||||||
|
T{ ##replace f V int-regs 3 D 4 }
|
||||||
|
T{ ##replace f V int-regs 4 D 5 }
|
||||||
|
T{ ##replace f V int-regs 5 D 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} dup 1array { { int-regs V{ 0 1 2 3 } } } (linear-scan)
|
||||||
|
instructions>> first live-spill-slots>> empty?
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ f ] [
|
||||||
|
T{ live-range f 0 10 }
|
||||||
|
T{ live-range f 20 30 }
|
||||||
|
intersect-live-range
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 10 ] [
|
||||||
|
T{ live-range f 0 10 }
|
||||||
|
T{ live-range f 10 30 }
|
||||||
|
intersect-live-range
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 5 ] [
|
||||||
|
T{ live-range f 0 10 }
|
||||||
|
T{ live-range f 5 30 }
|
||||||
|
intersect-live-range
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 5 ] [
|
||||||
|
T{ live-range f 5 30 }
|
||||||
|
T{ live-range f 0 10 }
|
||||||
|
intersect-live-range
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 5 ] [
|
||||||
|
T{ live-range f 5 10 }
|
||||||
|
T{ live-range f 0 15 }
|
||||||
|
intersect-live-range
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 50 ] [
|
||||||
|
{
|
||||||
|
T{ live-range f 0 10 }
|
||||||
|
T{ live-range f 20 30 }
|
||||||
|
T{ live-range f 40 50 }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
T{ live-range f 11 15 }
|
||||||
|
T{ live-range f 31 35 }
|
||||||
|
T{ live-range f 50 55 }
|
||||||
|
}
|
||||||
|
intersect-live-ranges
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 5 ] [
|
||||||
|
T{ live-interval
|
||||||
|
{ start 0 }
|
||||||
|
{ end 10 }
|
||||||
|
{ uses { 0 10 } }
|
||||||
|
{ ranges V{ T{ live-range f 0 10 } } }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ start 5 }
|
||||||
|
{ end 10 }
|
||||||
|
{ uses { 5 10 } }
|
||||||
|
{ ranges V{ T{ live-range f 5 10 } } }
|
||||||
|
}
|
||||||
|
intersect-inactive
|
||||||
|
] unit-test
|
|
@ -25,13 +25,15 @@ IN: compiler.cfg.linear-scan
|
||||||
! by Omri Traub, Glenn Holloway, Michael D. Smith
|
! by Omri Traub, Glenn Holloway, Michael D. Smith
|
||||||
! http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.8435
|
! http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.8435
|
||||||
|
|
||||||
: (linear-scan) ( rpo -- )
|
: (linear-scan) ( rpo machine-registers -- )
|
||||||
dup number-instructions
|
[
|
||||||
dup compute-live-intervals
|
dup number-instructions
|
||||||
machine-registers allocate-registers assign-registers ;
|
dup compute-live-intervals
|
||||||
|
] dip
|
||||||
|
allocate-registers assign-registers ;
|
||||||
|
|
||||||
: linear-scan ( cfg -- cfg' )
|
: linear-scan ( cfg -- cfg' )
|
||||||
[
|
[
|
||||||
dup reverse-post-order (linear-scan)
|
dup reverse-post-order machine-registers (linear-scan)
|
||||||
spill-counts get >>spill-counts
|
spill-counts get >>spill-counts
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
|
@ -11,9 +11,17 @@ compiler.cfg.dce
|
||||||
compiler.cfg.write-barrier
|
compiler.cfg.write-barrier
|
||||||
compiler.cfg.liveness
|
compiler.cfg.liveness
|
||||||
compiler.cfg.rpo
|
compiler.cfg.rpo
|
||||||
compiler.cfg.phi-elimination ;
|
compiler.cfg.phi-elimination
|
||||||
|
compiler.cfg.checker ;
|
||||||
IN: compiler.cfg.optimizer
|
IN: compiler.cfg.optimizer
|
||||||
|
|
||||||
|
SYMBOL: check-optimizer?
|
||||||
|
|
||||||
|
: ?check ( cfg -- cfg' )
|
||||||
|
check-optimizer? get [
|
||||||
|
dup check-cfg
|
||||||
|
] when ;
|
||||||
|
|
||||||
: optimize-cfg ( cfg -- cfg' )
|
: optimize-cfg ( cfg -- cfg' )
|
||||||
[
|
[
|
||||||
compute-predecessors
|
compute-predecessors
|
||||||
|
@ -27,4 +35,5 @@ IN: compiler.cfg.optimizer
|
||||||
eliminate-dead-code
|
eliminate-dead-code
|
||||||
eliminate-write-barriers
|
eliminate-write-barriers
|
||||||
eliminate-phis
|
eliminate-phis
|
||||||
|
?check
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays kernel sequences make compiler.cfg.instructions
|
USING: accessors kernel sequences make compiler.cfg.instructions
|
||||||
compiler.cfg.rpo cpu.architecture ;
|
compiler.cfg.local cpu.architecture ;
|
||||||
IN: compiler.cfg.two-operand
|
IN: compiler.cfg.two-operand
|
||||||
|
|
||||||
! On x86, instructions take the form x = x op y
|
! On x86, instructions take the form x = x op y
|
||||||
! Our SSA IR is x = y op z
|
! Our SSA IR is x = y op z
|
||||||
|
|
||||||
! We don't bother with ##add, ##add-imm or ##sub-imm since x86
|
! We don't bother with ##add, ##add-imm, ##sub-imm or ##mul-imm
|
||||||
! has a LEA instruction which is effectively a three-operand
|
! since x86 has LEA and IMUL instructions which are effectively
|
||||||
! addition
|
! three-operand addition and multiplication, respectively.
|
||||||
|
|
||||||
: make-copy ( dst src -- insn ) \ ##copy new-insn ; inline
|
: make-copy ( dst src -- insn ) \ ##copy new-insn ; inline
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ M: ##not convert-two-operand*
|
||||||
|
|
||||||
M: ##sub convert-two-operand* convert-two-operand/integer ;
|
M: ##sub convert-two-operand* convert-two-operand/integer ;
|
||||||
M: ##mul convert-two-operand* convert-two-operand/integer ;
|
M: ##mul convert-two-operand* convert-two-operand/integer ;
|
||||||
M: ##mul-imm convert-two-operand* convert-two-operand/integer ;
|
|
||||||
M: ##and convert-two-operand* convert-two-operand/integer ;
|
M: ##and convert-two-operand* convert-two-operand/integer ;
|
||||||
M: ##and-imm convert-two-operand* convert-two-operand/integer ;
|
M: ##and-imm convert-two-operand* convert-two-operand/integer ;
|
||||||
M: ##or convert-two-operand* convert-two-operand/integer ;
|
M: ##or convert-two-operand* convert-two-operand/integer ;
|
||||||
|
@ -54,9 +53,7 @@ M: insn convert-two-operand* , ;
|
||||||
|
|
||||||
: convert-two-operand ( cfg -- cfg' )
|
: convert-two-operand ( cfg -- cfg' )
|
||||||
two-operand? [
|
two-operand? [
|
||||||
dup [
|
[ drop ]
|
||||||
[
|
[ [ [ convert-two-operand* ] each ] V{ } make ]
|
||||||
[ [ convert-two-operand* ] each ] V{ } make
|
local-optimization
|
||||||
] change-instructions drop
|
|
||||||
] each-basic-block
|
|
||||||
] when ;
|
] when ;
|
||||||
|
|
|
@ -8,6 +8,7 @@ continuations.private fry cpu.architecture
|
||||||
source-files.errors
|
source-files.errors
|
||||||
compiler.errors
|
compiler.errors
|
||||||
compiler.alien
|
compiler.alien
|
||||||
|
compiler.constants
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
compiler.cfg.stack-frame
|
compiler.cfg.stack-frame
|
||||||
|
@ -94,7 +95,9 @@ M: _dispatch generate-insn
|
||||||
[ src>> register ] [ temp>> register ] bi %dispatch ;
|
[ src>> register ] [ temp>> register ] bi %dispatch ;
|
||||||
|
|
||||||
M: _dispatch-label generate-insn
|
M: _dispatch-label generate-insn
|
||||||
label>> lookup-label %dispatch-label ;
|
label>> lookup-label
|
||||||
|
cell 0 <repetition> %
|
||||||
|
rc-absolute-cell label-fixup ;
|
||||||
|
|
||||||
: >slot< ( insn -- dst obj slot tag )
|
: >slot< ( insn -- dst obj slot tag )
|
||||||
{
|
{
|
||||||
|
|
|
@ -193,7 +193,8 @@ M: optimizing-compiler recompile ( words -- alist )
|
||||||
] each
|
] each
|
||||||
compile-queue get compile-loop
|
compile-queue get compile-loop
|
||||||
compiled get >alist
|
compiled get >alist
|
||||||
] with-scope ;
|
] with-scope
|
||||||
|
"trace-compilation" get [ "--- compile done" print flush ] when ;
|
||||||
|
|
||||||
: with-optimizer ( quot -- )
|
: with-optimizer ( quot -- )
|
||||||
[ optimizing-compiler compiler-impl ] dip with-variable ; inline
|
[ optimizing-compiler compiler-impl ] dip with-variable ; inline
|
||||||
|
|
|
@ -55,7 +55,6 @@ HOOK: %jump-label cpu ( label -- )
|
||||||
HOOK: %return cpu ( -- )
|
HOOK: %return cpu ( -- )
|
||||||
|
|
||||||
HOOK: %dispatch cpu ( src temp -- )
|
HOOK: %dispatch cpu ( src temp -- )
|
||||||
HOOK: %dispatch-label cpu ( label -- )
|
|
||||||
|
|
||||||
HOOK: %slot cpu ( dst obj slot tag temp -- )
|
HOOK: %slot cpu ( dst obj slot tag temp -- )
|
||||||
HOOK: %slot-imm cpu ( dst obj slot tag -- )
|
HOOK: %slot-imm cpu ( dst obj slot tag -- )
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
USING: accessors assocs sequences kernel combinators make math
|
USING: accessors assocs sequences kernel combinators make math
|
||||||
math.order math.ranges system namespaces locals layouts words
|
math.order math.ranges system namespaces locals layouts words
|
||||||
alien alien.accessors alien.c-types literals cpu.architecture
|
alien alien.accessors alien.c-types literals cpu.architecture
|
||||||
cpu.ppc.assembler cpu.ppc.assembler.backend literals compiler.cfg.registers
|
cpu.ppc.assembler cpu.ppc.assembler.backend compiler.cfg.registers
|
||||||
compiler.cfg.instructions compiler.constants compiler.codegen
|
compiler.cfg.instructions compiler.constants compiler.codegen
|
||||||
compiler.codegen.fixup compiler.cfg.intrinsics
|
compiler.codegen.fixup compiler.cfg.intrinsics
|
||||||
compiler.cfg.stack-frame compiler.units ;
|
compiler.cfg.stack-frame compiler.cfg.build-stack-frame
|
||||||
|
compiler.units ;
|
||||||
FROM: cpu.ppc.assembler => B ;
|
FROM: cpu.ppc.assembler => B ;
|
||||||
IN: cpu.ppc
|
IN: cpu.ppc
|
||||||
|
|
||||||
|
@ -461,16 +462,18 @@ M:: ppc %write-barrier ( src card# table -- )
|
||||||
src card# deck-bits SRWI
|
src card# deck-bits SRWI
|
||||||
table scratch-reg card# STBX ;
|
table scratch-reg card# STBX ;
|
||||||
|
|
||||||
M: ppc %gc
|
M:: ppc %gc ( temp1 temp2 gc-roots gc-root-count -- )
|
||||||
"end" define-label
|
"end" define-label
|
||||||
12 load-zone-ptr
|
temp2 load-zone-ptr
|
||||||
11 12 cell LWZ ! nursery.here -> r11
|
temp1 temp2 cell LWZ
|
||||||
12 12 3 cells LWZ ! nursery.end -> r12
|
temp2 temp2 3 cells LWZ
|
||||||
11 11 1024 ADDI ! add ALLOT_BUFFER_ZONE to here
|
temp1 temp1 1024 ADDI ! add ALLOT_BUFFER_ZONE to here
|
||||||
11 0 12 CMP ! is here >= end?
|
temp1 0 temp2 CMP ! is here >= end?
|
||||||
"end" get BLE
|
"end" get BLE
|
||||||
%prepare-alien-invoke
|
%prepare-alien-invoke
|
||||||
"minor_gc" f %alien-invoke
|
0 3 LI
|
||||||
|
0 4 LI
|
||||||
|
"inline_gc" f %alien-invoke
|
||||||
"end" resolve-label ;
|
"end" resolve-label ;
|
||||||
|
|
||||||
M: ppc %prologue ( n -- )
|
M: ppc %prologue ( n -- )
|
||||||
|
|
|
@ -64,3 +64,11 @@ IN: cpu.x86.assembler.tests
|
||||||
[ { HEX: 48 HEX: d3 HEX: e9 } ] [ [ RCX CL SHR ] { } make ] unit-test
|
[ { HEX: 48 HEX: d3 HEX: e9 } ] [ [ RCX CL SHR ] { } make ] unit-test
|
||||||
|
|
||||||
[ { HEX: f7 HEX: c1 HEX: d2 HEX: 04 HEX: 00 HEX: 00 } ] [ [ ECX 1234 TEST ] { } make ] unit-test
|
[ { HEX: f7 HEX: c1 HEX: d2 HEX: 04 HEX: 00 HEX: 00 } ] [ [ ECX 1234 TEST ] { } make ] unit-test
|
||||||
|
|
||||||
|
[ { HEX: 4d HEX: 6b HEX: c0 HEX: 03 } ] [ [ R8 R8 3 IMUL3 ] { } make ] unit-test
|
||||||
|
[ { HEX: 49 HEX: 6b HEX: c0 HEX: 03 } ] [ [ RAX R8 3 IMUL3 ] { } make ] unit-test
|
||||||
|
[ { HEX: 4c HEX: 6b HEX: c0 HEX: 03 } ] [ [ R8 RAX 3 IMUL3 ] { } make ] unit-test
|
||||||
|
[ { HEX: 48 HEX: 6b HEX: c1 HEX: 03 } ] [ [ RAX RCX 3 IMUL3 ] { } make ] unit-test
|
||||||
|
[ { HEX: 48 HEX: 69 HEX: c1 HEX: 44 HEX: 03 HEX: 00 HEX: 00 } ] [ [ RAX RCX HEX: 344 IMUL3 ] { } make ] unit-test
|
||||||
|
|
||||||
|
[ { 15 183 195 } ] [ [ EAX BX MOVZX ] { } make ] unit-test
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2005, 2009 Slava Pestov.
|
! Copyright (C) 2005, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays io.binary kernel combinators
|
USING: arrays io.binary kernel combinators kernel.private math
|
||||||
kernel.private math namespaces make sequences words system layouts
|
namespaces make sequences words system layouts math.order accessors
|
||||||
math.order accessors cpu.x86.assembler.syntax ;
|
cpu.x86.assembler.syntax ;
|
||||||
IN: cpu.x86.assembler
|
IN: cpu.x86.assembler
|
||||||
|
|
||||||
! A postfix assembler for x86-32 and x86-64.
|
! A postfix assembler for x86-32 and x86-64.
|
||||||
|
@ -402,20 +402,26 @@ M: operand TEST OCT: 204 2-operand ;
|
||||||
: SHR ( dst n -- ) BIN: 101 (SHIFT) ;
|
: SHR ( dst n -- ) BIN: 101 (SHIFT) ;
|
||||||
: SAR ( dst n -- ) BIN: 111 (SHIFT) ;
|
: SAR ( dst n -- ) BIN: 111 (SHIFT) ;
|
||||||
|
|
||||||
GENERIC: IMUL2 ( dst src -- )
|
: IMUL2 ( dst src -- )
|
||||||
M: immediate IMUL2 swap dup reg-code t HEX: 68 3array immediate-1/4 ;
|
OCT: 257 extended-opcode (2-operand) ;
|
||||||
M: operand IMUL2 OCT: 257 extended-opcode (2-operand) ;
|
|
||||||
|
: IMUL3 ( dst src imm -- )
|
||||||
|
dup fits-in-byte? [
|
||||||
|
[ swap HEX: 6a 2-operand ] dip 1,
|
||||||
|
] [
|
||||||
|
[ swap HEX: 68 2-operand ] dip 4,
|
||||||
|
] if ;
|
||||||
|
|
||||||
: MOVSX ( dst src -- )
|
: MOVSX ( dst src -- )
|
||||||
dup register-32? OCT: 143 OCT: 276 extended-opcode ?
|
swap
|
||||||
over register-16? [ BIN: 1 opcode-or ] when
|
over register-32? OCT: 143 OCT: 276 extended-opcode ?
|
||||||
swapd
|
pick register-16? [ BIN: 1 opcode-or ] when
|
||||||
(2-operand) ;
|
(2-operand) ;
|
||||||
|
|
||||||
: MOVZX ( dst src -- )
|
: MOVZX ( dst src -- )
|
||||||
|
swap
|
||||||
OCT: 266 extended-opcode
|
OCT: 266 extended-opcode
|
||||||
over register-16? [ BIN: 1 opcode-or ] when
|
pick register-16? [ BIN: 1 opcode-or ] when
|
||||||
swapd
|
|
||||||
(2-operand) ;
|
(2-operand) ;
|
||||||
|
|
||||||
! Conditional move
|
! Conditional move
|
||||||
|
|
|
@ -91,9 +91,6 @@ M: x86 %return ( -- ) 0 RET ;
|
||||||
: align-code ( n -- )
|
: align-code ( n -- )
|
||||||
0 <repetition> % ;
|
0 <repetition> % ;
|
||||||
|
|
||||||
M: x86 %dispatch-label ( label -- )
|
|
||||||
0 cell, rc-absolute-cell label-fixup ;
|
|
||||||
|
|
||||||
:: (%slot) ( obj slot tag temp -- op )
|
:: (%slot) ( obj slot tag temp -- op )
|
||||||
temp slot obj [+] LEA
|
temp slot obj [+] LEA
|
||||||
temp tag neg [+] ; inline
|
temp tag neg [+] ; inline
|
||||||
|
@ -111,7 +108,7 @@ M: x86 %add-imm [+] LEA ;
|
||||||
M: x86 %sub nip SUB ;
|
M: x86 %sub nip SUB ;
|
||||||
M: x86 %sub-imm neg [+] LEA ;
|
M: x86 %sub-imm neg [+] LEA ;
|
||||||
M: x86 %mul nip swap IMUL2 ;
|
M: x86 %mul nip swap IMUL2 ;
|
||||||
M: x86 %mul-imm nip IMUL2 ;
|
M: x86 %mul-imm IMUL3 ;
|
||||||
M: x86 %and nip AND ;
|
M: x86 %and nip AND ;
|
||||||
M: x86 %and-imm nip AND ;
|
M: x86 %and-imm nip AND ;
|
||||||
M: x86 %or nip OR ;
|
M: x86 %or nip OR ;
|
||||||
|
|
|
@ -77,6 +77,9 @@ IN: formatting.tests
|
||||||
[ t ] [ "[####monkey]" "monkey" "[%'#10s]" sprintf = ] unit-test
|
[ t ] [ "[####monkey]" "monkey" "[%'#10s]" sprintf = ] unit-test
|
||||||
[ t ] [ "[many monke]" "many monkeys" "[%10.10s]" sprintf = ] unit-test
|
[ t ] [ "[many monke]" "many monkeys" "[%10.10s]" sprintf = ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ "{ 1, 2, 3 }" { 1 2 3 } "%[%s, %]" sprintf = ] unit-test
|
||||||
|
[ t ] [ "{ 1:2, 3:4 }" H{ { 1 2 } { 3 4 } } "%[%s: %s %]" sprintf = ] unit-test
|
||||||
|
|
||||||
|
|
||||||
[ "%H:%M:%S" strftime ] must-infer
|
[ "%H:%M:%S" strftime ] must-infer
|
||||||
|
|
||||||
|
@ -95,3 +98,4 @@ IN: formatting.tests
|
||||||
[ t ] [ "Thu Oct 09 12:03:15 2008" testtime "%c" strftime = ] unit-test
|
[ t ] [ "Thu Oct 09 12:03:15 2008" testtime "%c" strftime = ] unit-test
|
||||||
[ t ] [ "PM" testtime "%p" strftime = ] unit-test
|
[ t ] [ "PM" testtime "%p" strftime = ] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: assocs continuations fry help help.lint.checks
|
USING: assocs continuations fry help help.lint.checks
|
||||||
help.topics io kernel namespaces parser sequences
|
help.topics io kernel namespaces parser sequences
|
||||||
source-files.errors vocabs.hierarchy vocabs words classes
|
source-files.errors vocabs.hierarchy vocabs words classes
|
||||||
locals tools.errors ;
|
locals tools.errors listener ;
|
||||||
FROM: help.lint.checks => all-vocabs ;
|
FROM: help.lint.checks => all-vocabs ;
|
||||||
IN: help.lint
|
IN: help.lint
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
Chris Double
|
Chris Double
|
||||||
|
Peter Burns
|
||||||
|
Philipp Winkler
|
||||||
|
|
|
@ -19,6 +19,8 @@ IN: json.reader.tests
|
||||||
{ 10.25 } [ "1025e-2" json> ] unit-test
|
{ 10.25 } [ "1025e-2" json> ] unit-test
|
||||||
{ 0.125 } [ "0.125" json> ] unit-test
|
{ 0.125 } [ "0.125" json> ] unit-test
|
||||||
{ -0.125 } [ "-0.125" json> ] unit-test
|
{ -0.125 } [ "-0.125" json> ] unit-test
|
||||||
|
{ -0.00125 } [ "-0.125e-2" json> ] unit-test
|
||||||
|
{ -012.5 } [ "-0.125e+2" json> ] unit-test
|
||||||
|
|
||||||
! not widely supported by javascript, but allowed in the grammar, and a nice
|
! not widely supported by javascript, but allowed in the grammar, and a nice
|
||||||
! feature to get
|
! feature to get
|
||||||
|
@ -31,6 +33,7 @@ IN: json.reader.tests
|
||||||
{ 8 9 10 12 13 34 47 92 } >string 1array [ <" "\b\t\n\f\r\"\/\\" "> json> ] unit-test
|
{ 8 9 10 12 13 34 47 92 } >string 1array [ <" "\b\t\n\f\r\"\/\\" "> json> ] unit-test
|
||||||
{ HEX: abcd } >string 1array [ <" "\uaBCd" "> json> ] unit-test
|
{ HEX: abcd } >string 1array [ <" "\uaBCd" "> json> ] unit-test
|
||||||
|
|
||||||
|
{ H{ { "a" { } } { "b" 123 } } } [ "{\"a\":[],\"b\":123}" json> ] unit-test
|
||||||
{ { } } [ "[]" json> ] unit-test
|
{ { } } [ "[]" json> ] unit-test
|
||||||
{ { 1 "two" 3.0 } } [ <" [1, "two", 3.0] "> json> ] unit-test
|
{ { 1 "two" 3.0 } } [ <" [1, "two", 3.0] "> json> ] unit-test
|
||||||
{ H{ } } [ "{}" json> ] unit-test
|
{ H{ } } [ "{}" json> ] unit-test
|
||||||
|
|
|
@ -1,61 +1,103 @@
|
||||||
! Copyright (C) 2008 Peter Burns.
|
! Copyright (C) 2008 Peter Burns, 2009 Philipp Winkler
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel peg peg.ebnf math.parser math.parser.private strings math
|
USING: arrays assocs combinators io io.streams.string json
|
||||||
math.functions sequences arrays vectors hashtables assocs
|
kernel math math.parser math.parser.private prettyprint
|
||||||
prettyprint json ;
|
sequences strings vectors ;
|
||||||
IN: json.reader
|
IN: json.reader
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
: value ( char -- num char )
|
||||||
|
1string " \t\r\n,:}]" read-until
|
||||||
|
[
|
||||||
|
append
|
||||||
|
[ string>float ]
|
||||||
|
[ [ "eE." index ] any? [ >integer ] unless ] bi
|
||||||
|
] dip ;
|
||||||
|
|
||||||
: grammar-list>vector ( seq -- vec ) first2 values swap prefix ;
|
DEFER: j-string
|
||||||
|
|
||||||
! Grammar for JSON from RFC 4627
|
: convert-string ( str -- str )
|
||||||
EBNF: (json>)
|
read1
|
||||||
|
{
|
||||||
|
{ CHAR: b [ 8 ] }
|
||||||
|
{ CHAR: f [ 12 ] }
|
||||||
|
{ CHAR: n [ CHAR: \n ] }
|
||||||
|
{ CHAR: r [ CHAR: \r ] }
|
||||||
|
{ CHAR: t [ CHAR: \t ] }
|
||||||
|
{ CHAR: u [ 4 read hex> ] }
|
||||||
|
[ ]
|
||||||
|
} case
|
||||||
|
dup
|
||||||
|
[ 1string append j-string append ]
|
||||||
|
[ drop ] if ;
|
||||||
|
|
||||||
ws = (" " | "\r" | "\t" | "\n")*
|
: j-string ( -- str )
|
||||||
|
"\\\"" read-until CHAR: \" =
|
||||||
|
[ convert-string ] unless ;
|
||||||
|
|
||||||
true = "true" => [[ t ]]
|
: second-last ( seq -- second-last )
|
||||||
false = "false" => [[ f ]]
|
[ length 2 - ] keep nth ; inline
|
||||||
null = "null" => [[ json-null ]]
|
|
||||||
|
|
||||||
hex = [0-9a-fA-F]
|
: third-last ( seq -- third-last )
|
||||||
char = '\\"' [[ CHAR: " ]]
|
[ length 3 - ] keep nth ; inline
|
||||||
| "\\\\" [[ CHAR: \ ]]
|
|
||||||
| "\\/" [[ CHAR: / ]]
|
|
||||||
| "\\b" [[ 8 ]]
|
|
||||||
| "\\f" [[ 12 ]]
|
|
||||||
| "\\n" [[ CHAR: \n ]]
|
|
||||||
| "\\r" [[ CHAR: \r ]]
|
|
||||||
| "\\t" [[ CHAR: \t ]]
|
|
||||||
| "\\u" (hex hex hex hex) [[ hex> ]] => [[ second ]]
|
|
||||||
| [^"\]
|
|
||||||
string = '"' char*:cs '"' => [[ cs >string ]]
|
|
||||||
|
|
||||||
sign = ("-" | "+")? => [[ "-" = "-" "" ? ]]
|
: last2 ( seq -- second-last last )
|
||||||
digits = [0-9]+ => [[ >string ]]
|
[ second-last ] [ last ] bi ; inline
|
||||||
decimal = "." digits => [[ concat ]]
|
|
||||||
exp = ("e" | "E") sign digits => [[ concat ]]
|
|
||||||
number = sign digits decimal? exp? => [[ dup concat swap fourth [ string>float ] [ string>number ] if ]]
|
|
||||||
|
|
||||||
elements = value ("," value)* => [[ grammar-list>vector ]]
|
: last3 ( seq -- third-last second-last last )
|
||||||
array = "[" elements?:arr "]" => [[ arr >array ]]
|
[ third-last ] [ last2 ] bi ; inline
|
||||||
|
|
||||||
pair = ws string:key ws ":" value:val => [[ { key val } ]]
|
: v-over-push ( vec -- vec' )
|
||||||
members = pair ("," pair)* => [[ grammar-list>vector ]]
|
dup length 2 >=
|
||||||
object = "{" members?:hash "}" => [[ hash >hashtable ]]
|
[
|
||||||
|
dup
|
||||||
|
[ pop ]
|
||||||
|
[ last ] bi push
|
||||||
|
] when ;
|
||||||
|
|
||||||
val = true
|
: v-pick-push ( vec -- vec' )
|
||||||
| false
|
dup length 3 >=
|
||||||
| null
|
[
|
||||||
| string
|
dup
|
||||||
| number
|
[ pop ]
|
||||||
| array
|
[ second-last ] bi push
|
||||||
| object
|
] when ;
|
||||||
|
|
||||||
value = ws val:v ws => [[ v ]]
|
: (close-array) ( accum -- accum' )
|
||||||
|
dup last vector? [ v-over-push ] unless
|
||||||
|
dup pop >array over push ;
|
||||||
|
|
||||||
;EBNF
|
: (close-hash) ( accum -- accum' )
|
||||||
|
dup length 3 >= [ v-over-push ] when
|
||||||
|
dup dup [ pop ] dip pop swap
|
||||||
|
zip H{ } assoc-clone-like over push ;
|
||||||
|
|
||||||
|
: scan ( accum char -- accum )
|
||||||
|
! 2dup . . ! Great for debug...
|
||||||
|
[
|
||||||
|
{
|
||||||
|
{ CHAR: \" [ j-string over push ] }
|
||||||
|
{ CHAR: [ [ V{ } clone over push ] }
|
||||||
|
{ CHAR: , [ v-over-push ] }
|
||||||
|
{ CHAR: ] [ (close-array) ] }
|
||||||
|
{ CHAR: { [ 2 [ V{ } clone over push ] times ] }
|
||||||
|
{ CHAR: : [ v-pick-push ] }
|
||||||
|
{ CHAR: } [ (close-hash) ] }
|
||||||
|
{ CHAR: \u000020 [ ] }
|
||||||
|
{ CHAR: \t [ ] }
|
||||||
|
{ CHAR: \r [ ] }
|
||||||
|
{ CHAR: \n [ ] }
|
||||||
|
{ CHAR: t [ 3 read drop t over push ] }
|
||||||
|
{ CHAR: f [ 4 read drop f over push ] }
|
||||||
|
{ CHAR: n [ 3 read drop json-null over push ] }
|
||||||
|
[ value [ over push ] dip [ scan ] when* ]
|
||||||
|
} case
|
||||||
|
] when* ;
|
||||||
|
|
||||||
|
: (json-parser>) ( string -- object )
|
||||||
|
[ V{ } clone [ read1 dup ] [ scan ] while drop first ] with-string-reader ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: json> ( string -- object ) (json>) ;
|
: json> ( string -- object )
|
||||||
|
(json-parser>) ;
|
|
@ -13,6 +13,10 @@ ARTICLE: "listener-watch" "Watching variables in the listener"
|
||||||
"Hiding all visible variables:"
|
"Hiding all visible variables:"
|
||||||
{ $subsection hide-all-vars } ;
|
{ $subsection hide-all-vars } ;
|
||||||
|
|
||||||
|
HELP: only-use-vocabs
|
||||||
|
{ $values { "vocabs" "a sequence of vocabulary specifiers" } }
|
||||||
|
{ $description "Replaces the current manifest's vocabulary search path with the given set of vocabularies." } ;
|
||||||
|
|
||||||
HELP: show-var
|
HELP: show-var
|
||||||
{ $values { "var" "a variable name" } }
|
{ $values { "var" "a variable name" } }
|
||||||
{ $description "Adds a variable to the watch list; its value will be printed by the listener after every expression." } ;
|
{ $description "Adds a variable to the watch list; its value will be printed by the listener after every expression." } ;
|
||||||
|
|
|
@ -4,7 +4,7 @@ USING: arrays hashtables io kernel math math.parser memory
|
||||||
namespaces parser lexer sequences strings io.styles
|
namespaces parser lexer sequences strings io.styles
|
||||||
vectors words generic system combinators continuations debugger
|
vectors words generic system combinators continuations debugger
|
||||||
definitions compiler.units accessors colors prettyprint fry
|
definitions compiler.units accessors colors prettyprint fry
|
||||||
sets vocabs.parser source-files.errors locals ;
|
sets vocabs.parser source-files.errors locals vocabs vocabs.loader ;
|
||||||
IN: listener
|
IN: listener
|
||||||
|
|
||||||
GENERIC: stream-read-quot ( stream -- quot/f )
|
GENERIC: stream-read-quot ( stream -- quot/f )
|
||||||
|
@ -124,6 +124,78 @@ t error-summary? set-global
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
SYMBOL: interactive-vocabs
|
||||||
|
|
||||||
|
{
|
||||||
|
"accessors"
|
||||||
|
"arrays"
|
||||||
|
"assocs"
|
||||||
|
"combinators"
|
||||||
|
"compiler"
|
||||||
|
"compiler.errors"
|
||||||
|
"compiler.units"
|
||||||
|
"continuations"
|
||||||
|
"debugger"
|
||||||
|
"definitions"
|
||||||
|
"editors"
|
||||||
|
"help"
|
||||||
|
"help.apropos"
|
||||||
|
"help.lint"
|
||||||
|
"help.vocabs"
|
||||||
|
"inspector"
|
||||||
|
"io"
|
||||||
|
"io.files"
|
||||||
|
"io.pathnames"
|
||||||
|
"kernel"
|
||||||
|
"listener"
|
||||||
|
"math"
|
||||||
|
"math.order"
|
||||||
|
"memory"
|
||||||
|
"namespaces"
|
||||||
|
"parser"
|
||||||
|
"prettyprint"
|
||||||
|
"see"
|
||||||
|
"sequences"
|
||||||
|
"slicing"
|
||||||
|
"sorting"
|
||||||
|
"stack-checker"
|
||||||
|
"strings"
|
||||||
|
"syntax"
|
||||||
|
"tools.annotations"
|
||||||
|
"tools.crossref"
|
||||||
|
"tools.disassembler"
|
||||||
|
"tools.errors"
|
||||||
|
"tools.memory"
|
||||||
|
"tools.profiler"
|
||||||
|
"tools.test"
|
||||||
|
"tools.threads"
|
||||||
|
"tools.time"
|
||||||
|
"vocabs"
|
||||||
|
"vocabs.loader"
|
||||||
|
"vocabs.refresh"
|
||||||
|
"vocabs.hierarchy"
|
||||||
|
"words"
|
||||||
|
"scratchpad"
|
||||||
|
} interactive-vocabs set-global
|
||||||
|
|
||||||
|
: only-use-vocabs ( vocabs -- )
|
||||||
|
clear-manifest
|
||||||
|
[ vocab ] filter
|
||||||
|
[
|
||||||
|
vocab
|
||||||
|
[ find-vocab-root not ]
|
||||||
|
[ source-loaded?>> +done+ eq? ] bi or
|
||||||
|
] filter
|
||||||
|
[ use-vocab ] each ;
|
||||||
|
|
||||||
|
: with-interactive-vocabs ( quot -- )
|
||||||
|
[
|
||||||
|
<manifest> manifest set
|
||||||
|
"scratchpad" set-current-vocab
|
||||||
|
interactive-vocabs get only-use-vocabs
|
||||||
|
call
|
||||||
|
] with-scope ; inline
|
||||||
|
|
||||||
: listener ( -- )
|
: listener ( -- )
|
||||||
[ [ { } (listener) ] with-interactive-vocabs ] with-return ;
|
[ [ { } (listener) ] with-interactive-vocabs ] with-return ;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ kernel math namespaces parser prettyprint prettyprint.config
|
||||||
prettyprint.sections sequences tools.test vectors words
|
prettyprint.sections sequences tools.test vectors words
|
||||||
effects splitting generic.standard prettyprint.private
|
effects splitting generic.standard prettyprint.private
|
||||||
continuations generic compiler.units tools.continuations
|
continuations generic compiler.units tools.continuations
|
||||||
tools.continuations.private eval accessors make vocabs.parser see ;
|
tools.continuations.private eval accessors make vocabs.parser see
|
||||||
|
listener ;
|
||||||
IN: prettyprint.tests
|
IN: prettyprint.tests
|
||||||
|
|
||||||
[ "4" ] [ 4 unparse ] unit-test
|
[ "4" ] [ 4 unparse ] unit-test
|
||||||
|
|
|
@ -277,8 +277,6 @@ IN: tools.deploy.shaker
|
||||||
compiled-generic-crossref
|
compiled-generic-crossref
|
||||||
compiler-impl
|
compiler-impl
|
||||||
compiler.errors:compiler-errors
|
compiler.errors:compiler-errors
|
||||||
! definition-observers
|
|
||||||
interactive-vocabs
|
|
||||||
lexer-factory
|
lexer-factory
|
||||||
print-use-hook
|
print-use-hook
|
||||||
root-cache
|
root-cache
|
||||||
|
|
|
@ -112,68 +112,6 @@ SYMBOL: bootstrap-syntax
|
||||||
call
|
call
|
||||||
] with-scope ; inline
|
] with-scope ; inline
|
||||||
|
|
||||||
SYMBOL: interactive-vocabs
|
|
||||||
|
|
||||||
{
|
|
||||||
"accessors"
|
|
||||||
"arrays"
|
|
||||||
"assocs"
|
|
||||||
"combinators"
|
|
||||||
"compiler"
|
|
||||||
"compiler.errors"
|
|
||||||
"compiler.units"
|
|
||||||
"continuations"
|
|
||||||
"debugger"
|
|
||||||
"definitions"
|
|
||||||
"editors"
|
|
||||||
"help"
|
|
||||||
"help.apropos"
|
|
||||||
"help.lint"
|
|
||||||
"help.vocabs"
|
|
||||||
"inspector"
|
|
||||||
"io"
|
|
||||||
"io.files"
|
|
||||||
"io.pathnames"
|
|
||||||
"kernel"
|
|
||||||
"listener"
|
|
||||||
"math"
|
|
||||||
"math.order"
|
|
||||||
"memory"
|
|
||||||
"namespaces"
|
|
||||||
"parser"
|
|
||||||
"prettyprint"
|
|
||||||
"see"
|
|
||||||
"sequences"
|
|
||||||
"slicing"
|
|
||||||
"sorting"
|
|
||||||
"stack-checker"
|
|
||||||
"strings"
|
|
||||||
"syntax"
|
|
||||||
"tools.annotations"
|
|
||||||
"tools.crossref"
|
|
||||||
"tools.disassembler"
|
|
||||||
"tools.errors"
|
|
||||||
"tools.memory"
|
|
||||||
"tools.profiler"
|
|
||||||
"tools.test"
|
|
||||||
"tools.threads"
|
|
||||||
"tools.time"
|
|
||||||
"vocabs"
|
|
||||||
"vocabs.loader"
|
|
||||||
"vocabs.refresh"
|
|
||||||
"vocabs.hierarchy"
|
|
||||||
"words"
|
|
||||||
"scratchpad"
|
|
||||||
} interactive-vocabs set-global
|
|
||||||
|
|
||||||
: with-interactive-vocabs ( quot -- )
|
|
||||||
[
|
|
||||||
<manifest> manifest set
|
|
||||||
"scratchpad" set-current-vocab
|
|
||||||
interactive-vocabs get only-use-vocabs
|
|
||||||
call
|
|
||||||
] with-scope ; inline
|
|
||||||
|
|
||||||
SYMBOL: print-use-hook
|
SYMBOL: print-use-hook
|
||||||
|
|
||||||
print-use-hook [ [ ] ] initialize
|
print-use-hook [ [ ] ] initialize
|
||||||
|
|
|
@ -65,7 +65,6 @@ $nl
|
||||||
"Words for working with the current manifest:"
|
"Words for working with the current manifest:"
|
||||||
{ $subsection use-vocab }
|
{ $subsection use-vocab }
|
||||||
{ $subsection unuse-vocab }
|
{ $subsection unuse-vocab }
|
||||||
{ $subsection only-use-vocabs }
|
|
||||||
{ $subsection add-qualified }
|
{ $subsection add-qualified }
|
||||||
{ $subsection add-words-from }
|
{ $subsection add-words-from }
|
||||||
{ $subsection add-words-excluding }
|
{ $subsection add-words-excluding }
|
||||||
|
@ -117,10 +116,6 @@ HELP: unuse-vocab
|
||||||
{ $description "Removes a vocabulary from the current manifest." }
|
{ $description "Removes a vocabulary from the current manifest." }
|
||||||
{ $notes "This word is used to implement " { $link POSTPONE: UNUSE: } "." } ;
|
{ $notes "This word is used to implement " { $link POSTPONE: UNUSE: } "." } ;
|
||||||
|
|
||||||
HELP: only-use-vocabs
|
|
||||||
{ $values { "vocabs" "a sequence of vocabulary specifiers" } }
|
|
||||||
{ $description "Replaces the current manifest's vocabulary search path with the given set of vocabularies." } ;
|
|
||||||
|
|
||||||
HELP: add-qualified
|
HELP: add-qualified
|
||||||
{ $values { "vocab" "a vocabulary specifier" } { "prefix" string } }
|
{ $values { "vocab" "a vocabulary specifier" } { "prefix" string } }
|
||||||
{ $description "Adds the vocabulary's words, prefixed with the given string, to the current manifest." }
|
{ $description "Adds the vocabulary's words, prefixed with the given string, to the current manifest." }
|
||||||
|
|
|
@ -52,8 +52,6 @@ M: extra-words equal?
|
||||||
|
|
||||||
C: <extra-words> extra-words
|
C: <extra-words> extra-words
|
||||||
|
|
||||||
<PRIVATE
|
|
||||||
|
|
||||||
: clear-manifest ( -- )
|
: clear-manifest ( -- )
|
||||||
manifest get
|
manifest get
|
||||||
[ search-vocab-names>> clear-assoc ]
|
[ search-vocab-names>> clear-assoc ]
|
||||||
|
@ -61,6 +59,8 @@ C: <extra-words> extra-words
|
||||||
[ qualified-vocabs>> delete-all ]
|
[ qualified-vocabs>> delete-all ]
|
||||||
tri ;
|
tri ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
: (add-qualified) ( qualified -- )
|
: (add-qualified) ( qualified -- )
|
||||||
manifest get qualified-vocabs>> push ;
|
manifest get qualified-vocabs>> push ;
|
||||||
|
|
||||||
|
@ -126,9 +126,6 @@ TUPLE: no-current-vocab ;
|
||||||
2bi
|
2bi
|
||||||
] [ drop ] if ;
|
] [ drop ] if ;
|
||||||
|
|
||||||
: only-use-vocabs ( vocabs -- )
|
|
||||||
clear-manifest [ vocab ] filter [ use-vocab ] each ;
|
|
||||||
|
|
||||||
TUPLE: qualified vocab prefix words ;
|
TUPLE: qualified vocab prefix words ;
|
||||||
|
|
||||||
: <qualified> ( vocab prefix -- qualified )
|
: <qualified> ( vocab prefix -- qualified )
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
John Benediktsson
|
|
@ -0,0 +1,49 @@
|
||||||
|
! Copyright (C) 2009 John Benediktsson
|
||||||
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
|
USING: help.syntax help.markup brainfuck strings ;
|
||||||
|
|
||||||
|
IN: brainfuck
|
||||||
|
|
||||||
|
HELP: run-brainfuck
|
||||||
|
{ $values { "code" string } }
|
||||||
|
{ $description
|
||||||
|
"A brainfuck program is a sequence of eight commands that are "
|
||||||
|
"executed sequentially. An instruction pointer begins at the first "
|
||||||
|
"command, and each command is executed until the program terminates "
|
||||||
|
"when the instruction pointer moves beyond the last command.\n"
|
||||||
|
"\n"
|
||||||
|
"The eight language commands, each consisting of a single character, "
|
||||||
|
"are the following:\n"
|
||||||
|
{ $table
|
||||||
|
{ "Character" "Meaning" }
|
||||||
|
{ ">" "increment the data pointer (to point to the next cell to the right)." }
|
||||||
|
{ "<" "decrement the data pointer (to point to the next cell to the left)." }
|
||||||
|
{ "+" "increment (increase by one) the byte at the data pointer." }
|
||||||
|
{ "-" "decrement (decrease by one) the byte at the data pointer." }
|
||||||
|
{ "." "output the value of the byte at the data pointer." }
|
||||||
|
{ "," "accept one byte of input, storing its value in the byte at the data pointer." }
|
||||||
|
{ "[" "if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ] command*." }
|
||||||
|
{ "]" "if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching [ command*." }
|
||||||
|
}
|
||||||
|
"\n"
|
||||||
|
"Brainfuck programs can be translated into C using the following "
|
||||||
|
"substitutions, assuming ptr is of type unsigned char* and has been "
|
||||||
|
"initialized to point to an array of zeroed bytes:\n"
|
||||||
|
{ $table
|
||||||
|
{ "Character" "C equivalent" }
|
||||||
|
{ ">" "++ptr;" }
|
||||||
|
{ "<" "--ptr;" }
|
||||||
|
{ "+" "++*ptr;" }
|
||||||
|
{ "-" "--*ptr;" }
|
||||||
|
{ "." "putchar(*ptr);" }
|
||||||
|
{ "," "*ptr=getchar();" }
|
||||||
|
{ "[" "while (*ptr) {" }
|
||||||
|
{ "]" "}" }
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
HELP: get-brainfuck
|
||||||
|
{ $values { "code" string } { "result" string } }
|
||||||
|
{ $description "Returns the output from a brainfuck program as a result string." }
|
||||||
|
{ $see-also run-brainfuck } ;
|
|
@ -0,0 +1,62 @@
|
||||||
|
! Copyright (C) 2009 John Benediktsson
|
||||||
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
|
USING: brainfuck kernel io.streams.string math math.parser math.ranges
|
||||||
|
multiline quotations sequences tools.test ;
|
||||||
|
|
||||||
|
|
||||||
|
[ "+" run-brainfuck ] must-infer
|
||||||
|
[ "+" get-brainfuck ] must-infer
|
||||||
|
|
||||||
|
! Hello World!
|
||||||
|
|
||||||
|
[ "Hello World!\n" ] [ <" ++++++++++[>+++++++>++++++++++>+++>+<<<<-]
|
||||||
|
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.
|
||||||
|
------.--------.>+.>. "> get-brainfuck ] unit-test
|
||||||
|
|
||||||
|
! Addition (single-digit)
|
||||||
|
|
||||||
|
[ "8" ] [ "35" [ ",>++++++[<-------->-],[<+>-]<."
|
||||||
|
get-brainfuck ] with-string-reader ] unit-test
|
||||||
|
|
||||||
|
! Multiplication (single-digit)
|
||||||
|
|
||||||
|
[ "8\0" ] [ "24" [ <" ,>,>++++++++[<------<------>>-]
|
||||||
|
<<[>[>+>+<<-]>>[<<+>>-]<<<-]
|
||||||
|
>>>++++++[<++++++++>-],<.>. ">
|
||||||
|
get-brainfuck ] with-string-reader ] unit-test
|
||||||
|
|
||||||
|
! Division (single-digit, integer)
|
||||||
|
|
||||||
|
[ "3" ] [ "62" [ <" ,>,>++++++[-<--------<-------->>]
|
||||||
|
<<[
|
||||||
|
>[->+>+<<]
|
||||||
|
>[-<<-
|
||||||
|
[>]>>>[<[>>>-<<<[-]]>>]<<]
|
||||||
|
>>>+
|
||||||
|
<<[-<<+>>]
|
||||||
|
<<<]
|
||||||
|
>[-]>>>>[-<<<<<+>>>>>]
|
||||||
|
<<<<++++++[-<++++++++>]<. ">
|
||||||
|
get-brainfuck ] with-string-reader ] unit-test
|
||||||
|
|
||||||
|
! Uppercase
|
||||||
|
|
||||||
|
[ "A" ] [ "a\n" [ ",----------[----------------------.,----------]"
|
||||||
|
get-brainfuck ] with-string-reader ] unit-test
|
||||||
|
|
||||||
|
! cat
|
||||||
|
|
||||||
|
[ "ABC" ] [ "ABC\0" [ ",[.,]" get-brainfuck ] with-string-reader ] unit-test
|
||||||
|
|
||||||
|
! Squares of numbers from 0 to 100
|
||||||
|
|
||||||
|
100 [0,b] [ dup * number>string ] map "\n" join "\n" append 1quotation
|
||||||
|
[ <" ++++[>+++++<-]>[<+++++>-]+<+[
|
||||||
|
>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+
|
||||||
|
>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]
|
||||||
|
<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>
|
||||||
|
[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-] ">
|
||||||
|
get-brainfuck ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
! Copyright (C) 2009 John Benediktsson
|
||||||
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
|
USING: accessors assocs fry io io.streams.string kernel macros math
|
||||||
|
peg.ebnf prettyprint quotations sequences strings ;
|
||||||
|
|
||||||
|
IN: brainfuck
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
TUPLE: brainfuck pointer memory ;
|
||||||
|
|
||||||
|
: <brainfuck> ( -- brainfuck )
|
||||||
|
0 H{ } clone brainfuck boa ;
|
||||||
|
|
||||||
|
: get-memory ( brainfuck -- brainfuck value )
|
||||||
|
dup [ pointer>> ] [ memory>> ] bi at 0 or ;
|
||||||
|
|
||||||
|
: set-memory ( brainfuck value -- brainfuck )
|
||||||
|
over [ pointer>> ] [ memory>> ] bi set-at ;
|
||||||
|
|
||||||
|
: (+) ( brainfuck n -- brainfuck )
|
||||||
|
[ get-memory ] dip + 255 bitand set-memory ;
|
||||||
|
|
||||||
|
: (-) ( brainfuck n -- brainfuck )
|
||||||
|
[ get-memory ] dip - 255 bitand set-memory ;
|
||||||
|
|
||||||
|
: (?) ( brainfuck -- brainfuck t/f )
|
||||||
|
get-memory 0 = not ;
|
||||||
|
|
||||||
|
: (.) ( brainfuck -- brainfuck )
|
||||||
|
get-memory 1string write ;
|
||||||
|
|
||||||
|
: (,) ( brainfuck -- brainfuck )
|
||||||
|
read1 set-memory ;
|
||||||
|
|
||||||
|
: (>) ( brainfuck n -- brainfuck )
|
||||||
|
[ dup pointer>> ] dip + >>pointer ;
|
||||||
|
|
||||||
|
: (<) ( brainfuck n -- brainfuck )
|
||||||
|
[ dup pointer>> ] dip - >>pointer ;
|
||||||
|
|
||||||
|
: (#) ( brainfuck -- brainfuck )
|
||||||
|
dup
|
||||||
|
[ "ptr=" write pointer>> pprint ]
|
||||||
|
[ ",mem=" write memory>> pprint nl ] bi ;
|
||||||
|
|
||||||
|
: compose-all ( seq -- quot )
|
||||||
|
[ ] [ compose ] reduce ;
|
||||||
|
|
||||||
|
EBNF: parse-brainfuck
|
||||||
|
|
||||||
|
inc-ptr = (">")+ => [[ length 1quotation [ (>) ] append ]]
|
||||||
|
dec-ptr = ("<")+ => [[ length 1quotation [ (<) ] append ]]
|
||||||
|
inc-mem = ("+")+ => [[ length 1quotation [ (+) ] append ]]
|
||||||
|
dec-mem = ("-")+ => [[ length 1quotation [ (-) ] append ]]
|
||||||
|
output = "." => [[ [ (.) ] ]]
|
||||||
|
input = "," => [[ [ (,) ] ]]
|
||||||
|
debug = "#" => [[ [ (#) ] ]]
|
||||||
|
space = (" "|"\t"|"\r\n"|"\n")+ => [[ [ ] ]]
|
||||||
|
unknown = (.) => [[ "Invalid input" throw ]]
|
||||||
|
|
||||||
|
ops = inc-ptr|dec-ptr|inc-mem|dec-mem|output|input|debug|space
|
||||||
|
loop = "[" {loop|ops}+ "]" => [[ second compose-all 1quotation [ [ (?) ] ] prepend [ while ] append ]]
|
||||||
|
|
||||||
|
code = (loop|ops|unknown)* => [[ compose-all ]]
|
||||||
|
|
||||||
|
;EBNF
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
MACRO: run-brainfuck ( code -- )
|
||||||
|
[ <brainfuck> ] swap parse-brainfuck [ drop flush ] 3append ;
|
||||||
|
|
||||||
|
: get-brainfuck ( code -- result )
|
||||||
|
[ run-brainfuck ] with-string-writer ; inline
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Brainfuck programming language.
|
|
@ -4,7 +4,8 @@
|
||||||
USING: accessors arrays assocs combinators help help.crossref
|
USING: accessors arrays assocs combinators help help.crossref
|
||||||
help.markup help.topics io io.streams.string kernel make namespaces
|
help.markup help.topics io io.streams.string kernel make namespaces
|
||||||
parser prettyprint sequences summary help.vocabs
|
parser prettyprint sequences summary help.vocabs
|
||||||
vocabs vocabs.loader vocabs.hierarchy vocabs.metadata words see ;
|
vocabs vocabs.loader vocabs.hierarchy vocabs.metadata words see
|
||||||
|
listener ;
|
||||||
|
|
||||||
IN: fuel.help
|
IN: fuel.help
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# change directories to a factor module
|
||||||
|
function cdfactor {
|
||||||
|
code=$(printf "USING: io io.pathnames vocabs vocabs.loader ; "
|
||||||
|
printf "\"%s\" <vocab> vocab-source-path (normalize-path) print" $1)
|
||||||
|
echo $code > $HOME/.cdfactor
|
||||||
|
fn=$(factor $HOME/.cdfactor)
|
||||||
|
dn=$(dirname $fn)
|
||||||
|
echo $dn
|
||||||
|
if [ -z "$dn" ]; then
|
||||||
|
echo "Warning: directory '$1' not found" 1>&2
|
||||||
|
else
|
||||||
|
cd $dn
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue