Merge commit 'origin/master' into emacs

db4
Jose A. Ortega Ruiz 2009-06-10 12:20:17 +02:00
commit 13a37ccf40
36 changed files with 610 additions and 188 deletions

View File

@ -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

View File

@ -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> ;

View File

@ -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 }

View File

@ -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 ;

View File

@ -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

View File

@ -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 -- )

View File

@ -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

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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 )
{ {

View File

@ -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

View File

@ -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 -- )

View File

@ -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 -- )

View File

@ -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

View File

@ -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

View File

@ -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 ;

View File

@ -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

View File

@ -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

View File

@ -1 +1,3 @@
Chris Double Chris Double
Peter Burns
Philipp Winkler

View File

@ -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

View File

@ -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>) ;

View File

@ -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." } ;

View File

@ -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 ;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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." }

View File

@ -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 )

View File

@ -0,0 +1 @@
John Benediktsson

View File

@ -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 } ;

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
Brainfuck programming language.

View File

@ -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

18
misc/bash/cdfactor.sh Executable file
View File

@ -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
}