Merge branch 'master' of git://factorcode.org/git/factor
						commit
						65d0ad0bbd
					
				|  | @ -171,6 +171,7 @@ M: #if emit-node | |||
|             [ | ||||
|                 V{ } clone node-stack set | ||||
|                 ##prologue | ||||
|                 begin-basic-block | ||||
|                 emit-nodes | ||||
|                 basic-block get [ | ||||
|                     ##epilogue | ||||
|  |  | |||
|  | @ -219,3 +219,14 @@ TUPLE: my-tuple ; | |||
| : bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f <array> ; | ||||
| 
 | ||||
| [ { f f f } ] [ t bad-value-bug ] unit-test | ||||
| 
 | ||||
| ! PowerPC regression | ||||
| TUPLE: id obj ; | ||||
| 
 | ||||
| : (gc-check-bug) ( a b -- c ) | ||||
|     { [ id boa ] [ id boa ] } dispatch ; | ||||
| 
 | ||||
| : gc-check-bug ( -- ) | ||||
|     10000000 [ "hi" 0 (gc-check-bug) drop ] times ; | ||||
| 
 | ||||
| [ ] [ gc-check-bug ] unit-test | ||||
|  |  | |||
|  | @ -4,7 +4,8 @@ USING: accessors assocs sequences kernel combinators make math | |||
| math.order math.ranges system namespaces locals layouts words | ||||
| alien alien.c-types cpu.architecture cpu.ppc.assembler | ||||
| compiler.cfg.registers compiler.cfg.instructions | ||||
| compiler.constants compiler.codegen compiler.codegen.fixup ; | ||||
| compiler.constants compiler.codegen compiler.codegen.fixup | ||||
| compiler.cfg.intrinsics compiler.cfg.stack-frame ; | ||||
| IN: cpu.ppc | ||||
| 
 | ||||
| ! PowerPC register assignments: | ||||
|  | @ -15,15 +16,19 @@ IN: cpu.ppc | |||
| ! f0-f29: float vregs | ||||
| ! f30, f31: float scratch | ||||
| 
 | ||||
| enable-float-intrinsics | ||||
| 
 | ||||
| << \ ##integer>float t frame-required? set-word-prop | ||||
| \ ##float>integer t frame-required? set-word-prop >> | ||||
| 
 | ||||
| M: ppc machine-registers | ||||
|     { | ||||
|         { int-regs T{ range f 2 26 1 } } | ||||
|         { double-float-regs T{ range f 0 28 1 } } | ||||
|         { double-float-regs T{ range f 0 29 1 } } | ||||
|     } ; | ||||
| 
 | ||||
| : scratch-reg 28 ; inline | ||||
| : fp-scratch-reg-1 29 ; inline | ||||
| : fp-scratch-reg-2 30 ; inline | ||||
| : fp-scratch-reg 30 ; inline | ||||
| 
 | ||||
| M: ppc two-operand? f ; | ||||
| 
 | ||||
|  | @ -54,8 +59,16 @@ M: ppc %inc-d ( n -- ) ds-reg (%inc) ; | |||
| M: ppc %inc-r ( n -- ) rs-reg (%inc) ; | ||||
| 
 | ||||
| HOOK: reserved-area-size os ( -- n ) | ||||
| HOOK: lr-save os ( -- n ) | ||||
| 
 | ||||
| ! The start of the stack frame contains the size of this frame | ||||
| ! as well as the currently executing XT | ||||
| : factor-area-size ( -- n ) 2 cells ; foldable | ||||
| : next-save ( n -- i ) cell - ; | ||||
| : xt-save ( n -- i ) 2 cells - ; | ||||
| 
 | ||||
| ! Next, we have the spill area as well as the FFI parameter area. | ||||
| ! They overlap, since basic blocks with FFI calls will never | ||||
| ! spill. | ||||
| : param@ ( n -- x ) reserved-area-size + ; inline | ||||
| 
 | ||||
| : param-save-size ( -- n ) 8 cells ; foldable | ||||
|  | @ -63,19 +76,34 @@ HOOK: lr-save os ( -- n ) | |||
| : local@ ( n -- x ) | ||||
|     reserved-area-size param-save-size + + ; inline | ||||
| 
 | ||||
| : factor-area-size ( -- n ) 2 cells ; foldable | ||||
| : spill-integer-base ( -- n ) | ||||
|     stack-frame get spill-counts>> double-float-regs swap at | ||||
|     double-float-regs reg-size * ; | ||||
| 
 | ||||
| : next-save ( n -- i ) cell - ; | ||||
| : spill-integer@ ( n -- offset ) | ||||
|     cells spill-integer-base + param@ ; | ||||
| 
 | ||||
| : xt-save ( n -- i ) 2 cells - ; | ||||
| : spill-float@ ( n -- offset ) | ||||
|     double-float-regs reg-size * param@ ; | ||||
| 
 | ||||
| ! Some FP intrinsics need a temporary scratch area in the stack | ||||
| ! frame, 8 bytes in size | ||||
| : scratch@ ( n -- offset ) | ||||
|     stack-frame get total-size>> | ||||
|     factor-area-size - | ||||
|     param-save-size - | ||||
|     + ; | ||||
| 
 | ||||
| ! Finally we have the linkage area | ||||
| HOOK: lr-save os ( -- n ) | ||||
| 
 | ||||
| M: ppc stack-frame-size ( stack-frame -- i ) | ||||
|     [ spill-counts>> [ swap reg-size * ] { } assoc>map sum ] | ||||
|     [ params>> ] | ||||
|     [ return>> ] | ||||
|     tri + + | ||||
|     reserved-area-size + | ||||
|     param-save-size + | ||||
|     reserved-area-size + | ||||
|     factor-area-size + | ||||
|     4 cells align ; | ||||
| 
 | ||||
|  | @ -198,19 +226,19 @@ M: ppc %div-float FDIV ; | |||
| 
 | ||||
| M:: ppc %integer>float ( dst src -- ) | ||||
|     HEX: 4330 scratch-reg LIS | ||||
|     scratch-reg 1 0 param@ STW | ||||
|     scratch-reg 1 0 scratch@ STW | ||||
|     scratch-reg src MR | ||||
|     scratch-reg dup HEX: 8000 XORIS | ||||
|     scratch-reg 1 cell param@ STW | ||||
|     fp-scratch-reg-2 1 0 param@ LFD | ||||
|     scratch-reg 1 4 scratch@ STW | ||||
|     dst 1 0 scratch@ LFD | ||||
|     scratch-reg 4503601774854144.0 %load-indirect | ||||
|     fp-scratch-reg-2 scratch-reg float-offset LFD | ||||
|     fp-scratch-reg-2 fp-scratch-reg-2 fp-scratch-reg-2 FSUB ; | ||||
|     fp-scratch-reg scratch-reg float-offset LFD | ||||
|     dst dst fp-scratch-reg FSUB ; | ||||
| 
 | ||||
| M:: ppc %float>integer ( dst src -- ) | ||||
|     fp-scratch-reg-1 src FCTIWZ | ||||
|     fp-scratch-reg-2 1 0 param@ STFD | ||||
|     dst 1 4 param@ LWZ ; | ||||
|     fp-scratch-reg src FCTIWZ | ||||
|     fp-scratch-reg 1 0 scratch@ STFD | ||||
|     dst 1 4 scratch@ LWZ ; | ||||
| 
 | ||||
| M: ppc %copy ( dst src -- ) MR ; | ||||
| 
 | ||||
|  | @ -218,6 +246,10 @@ M: ppc %copy-float ( dst src -- ) FMR ; | |||
| 
 | ||||
| M: ppc %unbox-float ( dst src -- ) float-offset LFD ; | ||||
| 
 | ||||
| M:: ppc %box-float ( dst src temp -- ) | ||||
|     dst 16 float temp %allot | ||||
|     src dst float-offset STFD ; | ||||
| 
 | ||||
| M:: ppc %unbox-any-c-ptr ( dst src temp -- ) | ||||
|     [ | ||||
|         { "is-byte-array" "end" "start" } [ define-label ] each | ||||
|  | @ -349,11 +381,6 @@ M: ppc %gc | |||
|     "end" resolve-label ; | ||||
| 
 | ||||
| M: ppc %prologue ( n -- ) | ||||
|     #! We use a volatile register (r11) here for scratch. Because | ||||
|     #! callback bodies have a prologue too, we cannot assume | ||||
|     #! that c_to_factor saved all non-volatile registers, so | ||||
|     #! we have to respect the C calling convention. Also, we | ||||
|     #! cannot touch any param-regs either. | ||||
|     0 11 LOAD32 rc-absolute-ppc-2/2 rel-this | ||||
|     0 MFLR | ||||
|     1 1 pick neg ADDI | ||||
|  | @ -410,32 +437,11 @@ M: ppc %compare-branch (%compare) %branch ; | |||
| M: ppc %compare-imm-branch (%compare-imm) %branch ; | ||||
| M: ppc %compare-float-branch (%compare-float) %branch ; | ||||
| 
 | ||||
| : spill-integer-base ( stack-frame -- n ) | ||||
|     [ params>> ] [ return>> ] bi + ; | ||||
| M: ppc %spill-integer ( src n -- ) spill-integer@ 1 swap STW ; | ||||
| M: ppc %reload-integer ( dst n -- ) spill-integer@ 1 swap LWZ ; | ||||
| 
 | ||||
| : stack@ 1 swap ; inline | ||||
| 
 | ||||
| : spill-integer@ ( n -- reg offset ) | ||||
|     cells | ||||
|     stack-frame get spill-integer-base | ||||
|     + stack@ ; | ||||
| 
 | ||||
| : spill-float-base ( stack-frame -- n ) | ||||
|     [ spill-counts>> int-regs swap at int-regs reg-size * ] | ||||
|     [ params>> ] | ||||
|     [ return>> ] | ||||
|     tri + + ; | ||||
| 
 | ||||
| : spill-float@ ( n -- reg offset ) | ||||
|     double-float-regs reg-size * | ||||
|     stack-frame get spill-float-base | ||||
|     + stack@ ; | ||||
| 
 | ||||
| M: ppc %spill-integer ( src n -- ) spill-integer@ STW ; | ||||
| M: ppc %reload-integer ( dst n -- ) spill-integer@ LWZ ; | ||||
| 
 | ||||
| M: ppc %spill-float ( src n -- ) spill-float@ STFD ; | ||||
| M: ppc %reload-float ( dst n -- ) spill-float@ LFD ; | ||||
| M: ppc %spill-float ( src n -- ) spill-float@ 1 swap STFD ; | ||||
| M: ppc %reload-float ( dst n -- ) spill-float@ 1 swap LFD ; | ||||
| 
 | ||||
| M: ppc %loop-entry ; | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,5 +29,5 @@ IN: io.unix.launcher.parser | |||
| 
 | ||||
| PEG: tokenize-command ( command -- ast/f ) | ||||
|     'argument' " " token repeat1 list-of | ||||
|     " " token repeat0 swap over pack | ||||
|     " " token repeat0 tuck pack | ||||
|     just ; | ||||
|  |  | |||
|  | @ -487,7 +487,7 @@ M: ebnf-terminal (transform) ( ast -- parser ) | |||
| M: ebnf-foreign (transform) ( ast -- parser ) | ||||
|   dup word>> search | ||||
|   [ "Foreign word '" swap word>> append "' not found" append throw ] unless* | ||||
|   swap rule>> [ main ] unless* dupd swap rule [ | ||||
|   swap rule>> [ main ] unless* over rule [ | ||||
|     nip | ||||
|   ] [ | ||||
|     execute | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ ARTICLE: "tools.test.run" "Running unit tests" | |||
| { $subsection test-all } ; | ||||
| 
 | ||||
| ARTICLE: "tools.test.failure" "Handling test failures" | ||||
| "Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Sometimes, you want to develop a tool which inspects the test failures and takes some kind of action instead; one example is " { $vocab-link "builder" } "." | ||||
| "Most of the time the words documented in " { $link "tools.test.run" } " are used because they print all test failures in human-readable form. Some tools inspect the test failures and takes some kind of action instead, for example, " { $vocab-link "mason" } "." | ||||
| $nl | ||||
| "The following words output an association list mapping vocabulary names to sequences of failures; a failure is an array having the shape " { $snippet "{ error test continuation }" } ", and the elements are as follows:" | ||||
| { $list | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ M: labelled-gadget focusable-child* content>> ; | |||
| 
 | ||||
| : <title-bar> ( title quot -- gadget ) | ||||
|     <frame> | ||||
|         swap dup [ <close-box> @left grid-add ] [ drop ] if | ||||
|         swap [ <close-box> @left grid-add ] when* | ||||
|         swap <title-label> @center grid-add ; | ||||
| 
 | ||||
| TUPLE: closable-gadget < frame content ; | ||||
|  |  | |||
|  | @ -4,7 +4,8 @@ USING: accessors arrays ui.gadgets ui.gadgets.viewports | |||
| ui.gadgets.frames ui.gadgets.grids ui.gadgets.theme | ||||
| ui.gadgets.sliders ui.gestures kernel math namespaces sequences | ||||
| models models.range models.compose | ||||
| combinators math.vectors classes.tuple math.geometry.rect ; | ||||
| combinators math.vectors classes.tuple math.geometry.rect | ||||
| combinators.short-circuit ; | ||||
| IN: ui.gadgets.scrollers | ||||
| 
 | ||||
| TUPLE: scroller < frame viewport x y follows ; | ||||
|  | @ -70,13 +71,10 @@ scroller H{ | |||
| : relative-scroll-rect ( rect gadget scroller -- newrect ) | ||||
|     viewport>> gadget-child relative-loc offset-rect ; | ||||
| 
 | ||||
| : find-scroller* ( gadget -- scroller ) | ||||
|     dup find-scroller dup [ | ||||
|         2dup viewport>> gadget-child | ||||
|         swap child? [ nip ] [ 2drop f ] if | ||||
|     ] [ | ||||
|         2drop f | ||||
|     ] if ; | ||||
| : find-scroller* ( gadget -- scroller/f ) | ||||
|     dup find-scroller | ||||
|     { [ nip ] [ viewport>> gadget-child swap child? ] [ nip ] } | ||||
|     2&& ; | ||||
| 
 | ||||
| : scroll>rect ( rect gadget -- ) | ||||
|     dup find-scroller* dup [ | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ HELP: standard-combination | |||
| { $examples | ||||
|     "A generic word for append strings and characters to a sequence, dispatching on the object underneath the top of the stack:" | ||||
|     { $code | ||||
|         "G: build-string 1 standard-combination ;" | ||||
|         "GENERIC# build-string 1 ( elt str -- )" | ||||
|         "M: string build-string swap push-all ;" | ||||
|         "M: integer build-string push ;" | ||||
|     } | ||||
|  |  | |||
|  | @ -1,46 +0,0 @@ | |||
| 
 | ||||
| USING: io.files io.launcher io.encodings.utf8 prettyprint | ||||
|        builder.util builder.common builder.child builder.release | ||||
|        builder.report builder.email builder.cleanup ; | ||||
| 
 | ||||
| IN: builder.build | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : create-build-dir ( -- ) | ||||
|   datestamp >stamp | ||||
|   build-dir make-directory ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : enter-build-dir  ( -- ) build-dir set-current-directory ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : clone-builds-factor ( -- ) | ||||
|   { "git" "clone" builds/factor } to-strings try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : record-id ( -- ) | ||||
|   "factor" | ||||
|     [ git-id "../git-id" utf8 [ . ] with-file-writer ] | ||||
|   with-directory ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : build ( -- ) | ||||
|   reset-status | ||||
|   create-build-dir | ||||
|   enter-build-dir | ||||
|   clone-builds-factor | ||||
|   record-id | ||||
|   build-child | ||||
|   release | ||||
|   report | ||||
|   email-report | ||||
|   cleanup ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| MAIN: build | ||||
|  | @ -1,21 +0,0 @@ | |||
| 
 | ||||
| USING: kernel debugger io.files threads calendar  | ||||
|        builder.common | ||||
|        builder.updates | ||||
|        builder.build ; | ||||
| 
 | ||||
| IN: builder | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : build-loop ( -- ) | ||||
|   builds-check | ||||
|   [ | ||||
|     builds/factor set-current-directory | ||||
|     new-code-available? [ build ] when | ||||
|   ] | ||||
|   try | ||||
|   5 minutes sleep | ||||
|   build-loop ; | ||||
| 
 | ||||
| MAIN: build-loop | ||||
|  | @ -1,68 +0,0 @@ | |||
| 
 | ||||
| USING: namespaces debugger io.files io.launcher accessors bootstrap.image | ||||
|        calendar builder.util builder.common ; | ||||
| 
 | ||||
| IN: builder.child | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : make-clean ( -- ) { gnu-make "clean" } to-strings try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : make-vm ( -- ) | ||||
|   <process> | ||||
|     gnu-make         >>command | ||||
|     "../compile-log" >>stdout | ||||
|     +stdout+         >>stderr | ||||
|   try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : builds-factor-image ( -- img ) builds/factor my-boot-image-name append-path ; | ||||
| 
 | ||||
| : copy-image ( -- ) | ||||
|   builds-factor-image ".." copy-file-into | ||||
|   builds-factor-image "."  copy-file-into ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : boot-cmd ( -- cmd ) | ||||
|   { "./factor" { "-i=" my-boot-image-name } "-no-user-init" } to-strings ; | ||||
| 
 | ||||
| : boot ( -- ) | ||||
|   <process> | ||||
|     boot-cmd      >>command | ||||
|     +closed+      >>stdin | ||||
|     "../boot-log" >>stdout | ||||
|     +stdout+      >>stderr | ||||
|     60 minutes    >>timeout | ||||
|   try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : test-cmd ( -- cmd ) { "./factor" "-run=builder.test" } ; | ||||
| 
 | ||||
| : test ( -- ) | ||||
|   <process> | ||||
|     test-cmd      >>command | ||||
|     +closed+      >>stdin | ||||
|     "../test-log" >>stdout | ||||
|     +stdout+      >>stderr | ||||
|     240 minutes   >>timeout | ||||
|   try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : (build-child) ( -- ) | ||||
|   make-clean | ||||
|   make-vm      status-vm   on | ||||
|   copy-image | ||||
|   boot         status-boot on | ||||
|   test         status-test on | ||||
|                status      on ; | ||||
| 
 | ||||
| : build-child ( -- ) | ||||
|   "factor" set-current-directory | ||||
|     [ (build-child) ] try | ||||
|   ".." set-current-directory ; | ||||
|  | @ -1,26 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces io.files io.launcher bootstrap.image | ||||
|        builder.util builder.common ; | ||||
| 
 | ||||
| IN: builder.cleanup | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: builder-debug | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : compress-image ( -- ) { "bzip2" my-boot-image-name } to-strings try-process ; | ||||
| 
 | ||||
| : delete-child-factor ( -- ) | ||||
|   build-dir [ { "rm" "-rf" "factor" } try-process ] with-directory ; | ||||
| 
 | ||||
| : cleanup ( -- ) | ||||
|   builder-debug get f = | ||||
|     [ | ||||
|       "test-log" delete-file | ||||
|       delete-child-factor | ||||
|       compress-image | ||||
|     ] | ||||
|   when ; | ||||
| 
 | ||||
|  | @ -1,54 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces sequences splitting | ||||
|        io io.files io.launcher io.encodings.utf8 prettyprint | ||||
|        vars builder.util ; | ||||
| 
 | ||||
| IN: builder.common | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: upload-to-factorcode | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: builds-dir | ||||
| 
 | ||||
| : builds ( -- path ) | ||||
|   builds-dir get | ||||
|   home "/builds" append | ||||
|   or ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| VAR: stamp | ||||
| 
 | ||||
| : builds/factor ( -- path ) builds "factor" append-path ; | ||||
| : build-dir     ( -- path ) builds stamp>   append-path ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : prepare-build-machine ( -- ) | ||||
|   builds make-directory | ||||
|   builds | ||||
|     [ { "git" "clone" "git://factorcode.org/git/factor.git" } try-process ] | ||||
|   with-directory ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : builds-check ( -- ) builds exists? not [ prepare-build-machine ] when ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: status-vm | ||||
| SYMBOL: status-boot | ||||
| SYMBOL: status-test | ||||
| SYMBOL: status-build | ||||
| SYMBOL: status-release | ||||
| SYMBOL: status | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : reset-status ( -- ) | ||||
|   { status-vm status-boot status-test status-build status-release status } | ||||
|     [ off ] | ||||
|   each ; | ||||
|  | @ -1,24 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces accessors smtp builder.util builder.common ; | ||||
| 
 | ||||
| IN: builder.email | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: builder-from | ||||
| SYMBOL: builder-recipients | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : subject-status ( -- str ) status get [ "report" ] [ "error" ] if ; | ||||
| 
 | ||||
| : subject ( -- str ) { "builder@" host-name* ": " subject-status } to-string ; | ||||
| 
 | ||||
| : email-report ( -- ) | ||||
|   <email> | ||||
|     builder-from get       >>from | ||||
|     builder-recipients get >>to | ||||
|     subject                >>subject | ||||
|     "report" file>string   >>body | ||||
|   send-email ; | ||||
| 
 | ||||
|  | @ -1,69 +0,0 @@ | |||
| 
 | ||||
| USING: kernel combinators system sequences io.files io.launcher prettyprint | ||||
|        builder.util | ||||
|        builder.common ; | ||||
| 
 | ||||
| IN: builder.release.archive | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : base-name ( -- string ) | ||||
|   { "factor" [ os unparse ] cpu- stamp> } to-strings "-" join ; | ||||
| 
 | ||||
| : extension ( -- extension ) | ||||
|   { | ||||
|     { [ os winnt?  ] [ ".zip"    ] }   | ||||
|     { [ os macosx? ] [ ".dmg"    ] } | ||||
|     { [ os unix?   ] [ ".tar.gz" ] } | ||||
|   } | ||||
|   cond ; | ||||
| 
 | ||||
| : archive-name ( -- string ) base-name extension append ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : windows-archive-cmd ( -- cmd ) { "zip" "-r" archive-name "factor" } ; | ||||
| 
 | ||||
| ! : macosx-archive-cmd ( -- cmd ) | ||||
| !   { "hdiutil" "create" | ||||
| !               "-srcfolder" "factor" | ||||
| !               "-fs" "HFS+" | ||||
| !               "-volname" "factor" | ||||
| !               archive-name } ; | ||||
| 
 | ||||
| : macosx-archive-cmd ( -- cmd ) | ||||
|   { "mkdir" "dmg-root" }                         try-process | ||||
|   { "cp" "-r" "factor" "dmg-root" }              try-process | ||||
|   { "hdiutil" "create" | ||||
|               "-srcfolder" "dmg-root" | ||||
|               "-fs" "HFS+" | ||||
|               "-volname" "factor" | ||||
|               archive-name }          to-strings try-process | ||||
|   { "rm" "-rf" "dmg-root" }                      try-process | ||||
|   { "true" } ; | ||||
| 
 | ||||
| : unix-archive-cmd ( -- cmd ) { "tar" "-cvzf" archive-name "factor" } ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : archive-cmd ( -- cmd ) | ||||
|   { | ||||
|     { [ os windows? ] [ windows-archive-cmd ] } | ||||
|     { [ os macosx?  ] [ macosx-archive-cmd  ] } | ||||
|     { [ os unix?    ] [ unix-archive-cmd    ] } | ||||
|   } | ||||
|   cond ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : make-archive ( -- ) archive-cmd to-strings try-process ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : releases ( -- path ) | ||||
|   builds "releases" append-path | ||||
|   dup exists? not | ||||
|     [ dup make-directory ] | ||||
|   when ; | ||||
| 
 | ||||
| : save-archive ( -- ) archive-name releases move-file-into ; | ||||
|  | @ -1,40 +0,0 @@ | |||
| 
 | ||||
| USING: kernel system namespaces sequences prettyprint io.files io.launcher | ||||
|        bootstrap.image | ||||
|        builder.util | ||||
|        builder.common ; | ||||
| 
 | ||||
| IN: builder.release.branch | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : branch-name ( -- string ) "clean-" platform append ; | ||||
| 
 | ||||
| : refspec ( -- string ) "master:" branch-name append ; | ||||
| 
 | ||||
| : push-to-clean-branch ( -- ) | ||||
|   { "git" "push" "factorcode.org:/git/factor.git" refspec } | ||||
|   to-strings | ||||
|   try-process ; | ||||
| 
 | ||||
| : upload-clean-image ( -- ) | ||||
|   { | ||||
|     "scp" | ||||
|     my-boot-image-name | ||||
|     { "factorcode.org:/var/www/factorcode.org/newsite/images/clean/" platform } | ||||
|   } | ||||
|   to-strings | ||||
|   try-process ; | ||||
| 
 | ||||
| : (update-clean-branch) ( -- ) | ||||
|   "factor" | ||||
|     [ | ||||
|       push-to-clean-branch | ||||
|       upload-clean-image | ||||
|     ] | ||||
|   with-directory ; | ||||
| 
 | ||||
| : update-clean-branch ( -- ) | ||||
|   upload-to-factorcode get | ||||
|     [ (update-clean-branch) ] | ||||
|   when ; | ||||
|  | @ -1,27 +0,0 @@ | |||
| 
 | ||||
| USING: kernel debugger system namespaces sequences splitting combinators | ||||
|        io io.files io.launcher prettyprint bootstrap.image | ||||
|        combinators.cleave | ||||
|        builder.util | ||||
|        builder.common | ||||
|        builder.release.branch | ||||
|        builder.release.tidy | ||||
|        builder.release.archive | ||||
|        builder.release.upload ; | ||||
| 
 | ||||
| IN: builder.release | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : (release) ( -- ) | ||||
|   update-clean-branch | ||||
|   tidy | ||||
|   make-archive | ||||
|   upload | ||||
|   save-archive | ||||
|   status-release on ; | ||||
| 
 | ||||
| : clean-build? ( -- ? ) | ||||
|   { "load-everything-vocabs" "test-all-vocabs" } [ eval-file empty? ] all? ; | ||||
| 
 | ||||
| : release ( -- ) [ clean-build? [ (release) ] when ] try ; | ||||
|  | @ -1,29 +0,0 @@ | |||
| 
 | ||||
| USING: kernel system io.files io.launcher builder.util ; | ||||
| 
 | ||||
| IN: builder.release.tidy | ||||
| 
 | ||||
| : common-files ( -- seq ) | ||||
|   { | ||||
|     "boot.x86.32.image" | ||||
|     "boot.x86.64.image" | ||||
|     "boot.macosx-ppc.image" | ||||
|     "boot.linux-ppc.image" | ||||
|     "vm" | ||||
|     "temp" | ||||
|     "logs" | ||||
|     ".git" | ||||
|     ".gitignore" | ||||
|     "Makefile" | ||||
|     "unmaintained" | ||||
|     "build-support" | ||||
|   } ; | ||||
| 
 | ||||
| : remove-common-files ( -- ) | ||||
|   { "rm" "-rf" common-files } to-strings try-process ; | ||||
| 
 | ||||
| : remove-factor-app ( -- ) | ||||
|   os macosx? not [ { "rm" "-rf" "Factor.app" } try-process ] when ; | ||||
| 
 | ||||
| : tidy ( -- ) | ||||
|   "factor" [ remove-factor-app remove-common-files ] with-directory ; | ||||
|  | @ -1,54 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces make sequences arrays io io.files | ||||
|        builder.util | ||||
|        builder.common | ||||
|        builder.release.archive ; | ||||
| 
 | ||||
| IN: builder.release.upload | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| SYMBOL: upload-host | ||||
| 
 | ||||
| SYMBOL: upload-username | ||||
| 
 | ||||
| SYMBOL: upload-directory | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : remote-location ( -- dest ) | ||||
|   upload-directory get platform append ; | ||||
| 
 | ||||
| : remote-archive-name ( -- dest ) | ||||
|   remote-location "/" archive-name 3append ; | ||||
| 
 | ||||
| : temp-archive-name ( -- dest ) | ||||
|   remote-archive-name ".incomplete" append ; | ||||
| 
 | ||||
| : upload-command ( -- args ) | ||||
|   "scp" | ||||
|   archive-name | ||||
|   [ upload-username get % "@" % upload-host get % ":" % temp-archive-name % ] "" make | ||||
|   3array ; | ||||
| 
 | ||||
| : rename-command ( -- args ) | ||||
|   [ | ||||
|     "ssh" , | ||||
|     upload-host get , | ||||
|     "-l" , | ||||
|     upload-username get , | ||||
|     "mv" , | ||||
|     temp-archive-name , | ||||
|     remote-archive-name , | ||||
|   ] { } make ; | ||||
| 
 | ||||
| : upload-temp-file ( -- ) | ||||
|   upload-command [ "Error uploading binary to factorcode" print ] run-or-bail ; | ||||
| 
 | ||||
| : rename-temp-file ( -- ) | ||||
|   rename-command [ "Error renaming binary on factorcode" print ] run-or-bail ; | ||||
| 
 | ||||
| : upload ( -- ) | ||||
|   upload-to-factorcode get | ||||
|     [ upload-temp-file rename-temp-file ] | ||||
|   when ; | ||||
|  | @ -1,35 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces debugger system io io.files io.sockets | ||||
|        io.encodings.utf8 prettyprint benchmark | ||||
|        builder.util builder.common ; | ||||
| 
 | ||||
| IN: builder.report | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : (report) ( -- ) | ||||
| 
 | ||||
|   "Build machine:   " write host-name             print | ||||
|   "CPU:             " write cpu                   . | ||||
|   "OS:              " write os                    . | ||||
|   "Build directory: " write build-dir             print | ||||
|   "git id:          " write "git-id" eval-file    print nl | ||||
| 
 | ||||
|   status-vm   get f = [ "compile-log"  cat   "vm compile error" throw ] when | ||||
|   status-boot get f = [ "boot-log" 100 cat-n "Boot error"       throw ] when | ||||
|   status-test get f = [ "test-log" 100 cat-n "Test error"       throw ] when | ||||
| 
 | ||||
|   "Boot time: " write "boot-time" eval-file milli-seconds>time print | ||||
|   "Load time: " write "load-time" eval-file milli-seconds>time print | ||||
|   "Test time: " write "test-time" eval-file milli-seconds>time print nl | ||||
| 
 | ||||
|   "Did not pass load-everything: " print "load-everything-vocabs" cat | ||||
|        | ||||
|   "Did not pass test-all: "        print "test-all-vocabs"        cat | ||||
|                                          "test-failures"          cat | ||||
|        | ||||
|   "help-lint results:"             print "help-lint"              cat | ||||
| 
 | ||||
|   "Benchmarks: " print "benchmarks" eval-file benchmarks. ; | ||||
| 
 | ||||
| : report ( -- ) "report" utf8 [ [ (report) ] try ] with-file-writer ; | ||||
|  | @ -1,35 +0,0 @@ | |||
| 
 | ||||
| USING: kernel namespaces assocs | ||||
|        io.files io.encodings.utf8 prettyprint  | ||||
|        help.lint | ||||
|        benchmark | ||||
|        tools.time | ||||
|        bootstrap.stage2 | ||||
|        tools.test tools.vocabs | ||||
|        builder.util ; | ||||
| 
 | ||||
| IN: builder.test | ||||
| 
 | ||||
| : do-load ( -- ) | ||||
|   try-everything keys "../load-everything-vocabs" utf8 [ . ] with-file-writer ; | ||||
| 
 | ||||
| : do-tests ( -- ) | ||||
|   run-all-tests | ||||
|     [ keys "../test-all-vocabs" utf8 [ .              ] with-file-writer ] | ||||
|     [      "../test-failures"   utf8 [ test-failures. ] with-file-writer ] | ||||
|   bi ; | ||||
| 
 | ||||
| : do-help-lint ( -- ) | ||||
|   "" run-help-lint "../help-lint" utf8 [ typos. ] with-file-writer ; | ||||
| 
 | ||||
| : do-benchmarks ( -- ) | ||||
|   run-benchmarks "../benchmarks" utf8 [ . ] with-file-writer ; | ||||
| 
 | ||||
| : do-all ( -- ) | ||||
|   bootstrap-time get   "../boot-time" utf8 [ . ] with-file-writer | ||||
|   [ do-load  ] benchmark "../load-time" utf8 [ . ] with-file-writer | ||||
|   [ do-tests ] benchmark "../test-time" utf8 [ . ] with-file-writer | ||||
|   do-help-lint | ||||
|   do-benchmarks ; | ||||
| 
 | ||||
| MAIN: do-all | ||||
|  | @ -1,31 +0,0 @@ | |||
| 
 | ||||
| USING: kernel io.launcher bootstrap.image bootstrap.image.download | ||||
|        builder.util builder.common ; | ||||
| 
 | ||||
| IN: builder.updates | ||||
| 
 | ||||
| : git-pull-cmd ( -- cmd ) | ||||
|   { | ||||
|     "git" | ||||
|     "pull" | ||||
|     "--no-summary" | ||||
|     "git://factorcode.org/git/factor.git" | ||||
|     "master" | ||||
|   } ; | ||||
| 
 | ||||
| : updates-available? ( -- ? ) | ||||
|   git-id | ||||
|   git-pull-cmd try-process | ||||
|   git-id | ||||
|   = not ; | ||||
| 
 | ||||
| : new-image-available? ( -- ? ) | ||||
|   my-boot-image-name need-new-image? | ||||
|     [ download-my-image t ] | ||||
|     [ f ] | ||||
|   if ; | ||||
| 
 | ||||
| : new-code-available? ( -- ? ) | ||||
|   updates-available? | ||||
|   new-image-available? | ||||
|   or ; | ||||
|  | @ -1,106 +0,0 @@ | |||
| 
 | ||||
| USING: kernel words namespaces classes parser continuations | ||||
|        io io.files io.launcher io.sockets | ||||
|        math math.parser | ||||
|        system | ||||
|        combinators sequences splitting quotations arrays strings tools.time | ||||
|        sequences.deep accessors assocs.lib | ||||
|        io.encodings.utf8 | ||||
|        combinators.cleave calendar calendar.format eval ; | ||||
| 
 | ||||
| IN: builder.util | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : minutes>ms ( min -- ms ) 60 * 1000 * ; | ||||
| 
 | ||||
| : file>string ( file -- string ) utf8 file-contents ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| DEFER: to-strings | ||||
| 
 | ||||
| : to-string ( obj -- str ) | ||||
|   dup class | ||||
|     { | ||||
|       { \ string    [ ] } | ||||
|       { \ quotation [ call ] } | ||||
|       { \ word      [ execute ] } | ||||
|       { \ fixnum    [ number>string ] } | ||||
|       { \ array     [ to-strings concat ] } | ||||
|     } | ||||
|   case ; | ||||
| 
 | ||||
| : to-strings ( seq -- str ) | ||||
|   dup [ string? ] all? | ||||
|     [ ] | ||||
|     [ [ to-string ] map flatten ] | ||||
|   if ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : host-name* ( -- name ) host-name "." split first ; | ||||
| 
 | ||||
| : datestamp ( -- string ) | ||||
|   now | ||||
|     { year>> month>> day>> hour>> minute>> } <arr> | ||||
|   [ pad-00 ] map "-" join ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : milli-seconds>time ( n -- string ) | ||||
|   1000 /i 60 /mod >r 60 /mod r> 3array [ pad-00 ] map ":" join ; | ||||
| 
 | ||||
| : eval-file ( file -- obj ) utf8 file-contents eval ; | ||||
| 
 | ||||
| : cat ( file -- ) utf8 file-contents print ; | ||||
| 
 | ||||
| : run-or-bail ( desc quot -- ) | ||||
|   [ [ try-process ] curry   ] | ||||
|   [ [ throw       ] compose ] | ||||
|   bi* | ||||
|   recover ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| USING: bootstrap.image bootstrap.image.download io.streams.null ; | ||||
| 
 | ||||
| : retrieve-image ( -- ) [ my-arch download-image ] with-null-stream ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : longer? ( seq seq -- ? ) [ length ] bi@ > ;  | ||||
| 
 | ||||
| : maybe-tail* ( seq n -- seq ) | ||||
|   2dup longer? | ||||
|     [ tail* ] | ||||
|     [ drop  ] | ||||
|   if ; | ||||
| 
 | ||||
| : cat-n ( file n -- ) | ||||
|   [ utf8 file-lines ] [ ] bi* | ||||
|   maybe-tail* | ||||
|   [ print ] each ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| USE: prettyprint | ||||
| 
 | ||||
| : to-file ( object file -- ) utf8 [ . ] with-file-writer ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : cpu- ( -- cpu ) cpu unparse "." split "-" join ; | ||||
| 
 | ||||
| : platform ( -- string ) { [ os unparse ] cpu- } to-strings "-" join ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : gnu-make ( -- string ) | ||||
|   os { freebsd openbsd netbsd } member? [ "gmake" ] [ "make" ] if ; | ||||
| 
 | ||||
| ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
| 
 | ||||
| : git-id ( -- id ) | ||||
|   { "git" "show" } utf8 <process-reader> [ readln ] with-input-stream | ||||
|   " " split second ; | ||||
|  | @ -0,0 +1,5 @@ | |||
| USING: project-euler.215 tools.test ; | ||||
| IN: project-euler.215.tests | ||||
| 
 | ||||
| [ 8 ] [ 9 3 solve ] unit-test | ||||
| [ 806844323190414 ] [ euler215 ] unit-test | ||||
|  | @ -0,0 +1,56 @@ | |||
| USING: accessors kernel locals math ; | ||||
| IN: project-euler.215 | ||||
| 
 | ||||
| TUPLE: block two three ; | ||||
| TUPLE: end { ways integer } ; | ||||
| 
 | ||||
| C: <block> block | ||||
| C: <end> end | ||||
| : <failure> 0 <end> ; inline | ||||
| : <success> 1 <end> ; inline | ||||
| 
 | ||||
| : failure? ( t -- ? ) ways>> 0 = ; inline | ||||
| 
 | ||||
| : choice ( t p q -- t t ) [ [ two>> ] [ three>> ] bi ] 2dip bi* ; inline | ||||
| 
 | ||||
| GENERIC: merge ( t t -- t ) | ||||
| GENERIC# block-merge 1 ( t t -- t ) | ||||
| GENERIC# end-merge 1 ( t t -- t ) | ||||
| M: block merge block-merge ; | ||||
| M: end   merge end-merge ; | ||||
| M: block block-merge [ [ two>>   ] bi@ merge ] | ||||
|                      [ [ three>> ] bi@ merge ] 2bi <block> ; | ||||
| M: end   block-merge nip ; | ||||
| M: block end-merge drop ; | ||||
| M: end   end-merge [ ways>> ] bi@ + <end> ; | ||||
| 
 | ||||
| GENERIC: h-1 ( t -- t ) | ||||
| GENERIC: h0 ( t -- t ) | ||||
| GENERIC: h1 ( t -- t ) | ||||
| GENERIC: h2 ( t -- t ) | ||||
| 
 | ||||
| M: block h-1 [ h1 ] [ h2 ] choice merge ; | ||||
| M: block h0 drop <failure> ; | ||||
| M: block h1 [ [ h1 ] [ h2 ] choice merge ] | ||||
|             [ [ h0 ] [ h1 ] choice merge ] bi <block> ; | ||||
| M: block h2 [ h1 ] [ h2 ] choice merge <failure> swap <block> ; | ||||
| 
 | ||||
| M: end h-1 drop <failure> ; | ||||
| M: end h0 ; | ||||
| M: end h1 drop <failure> ; | ||||
| M: end h2 dup failure? [ <failure> <block> ] unless ; | ||||
| 
 | ||||
| : next-row ( t -- t ) [ h-1 ] [ h1 ] choice swap <block> ; | ||||
| 
 | ||||
| : first-row ( n -- t ) | ||||
|   [ <failure> <success> <failure> ] dip | ||||
|   1- [| a b c | b c <block> a b ] times 2drop ; | ||||
| 
 | ||||
| GENERIC: total ( t -- n ) | ||||
| M: block total [ total ] dup choice + ; | ||||
| M: end   total ways>> ; | ||||
| 
 | ||||
| : solve ( width height -- ways ) | ||||
|   [ first-row ] dip 1- [ next-row ] times total ; | ||||
| 
 | ||||
| : euler215 ( -- ways ) 32 10 solve ; | ||||
		Loading…
	
		Reference in New Issue