To run it, you must first load Ed's experimental module system, which will actually become the default module system in Factor 0.89. In the UI, enter the following:
"libs/vocabs" require
USE: golden-section
golden-section-window
Slava Pestov's weblog, primarily about Factor.
"libs/vocabs" require
USE: golden-section
golden-section-window
! From http://www.ffconsultancy.com/ocaml/maze/index.html
USING: sequences namespaces math opengl arrays gadgets
gadgets-theme kernel ;
IN: maze
: line-width 8 ;
SYMBOL: visited
: unvisited? ( cell -- ? ) first2 visited get ?nth ?nth ;
: ?set-nth ( elt i seq -- )
2dup bounds-check? [ set-nth ] [ 3drop ] if ;
: visit ( cell -- ) f swap first2 visited get ?nth ?set-nth ;
: choices ( cell -- seq )
{ { -1 0 } { 1 0 } { 0 -1 } { 0 1 } }
[ v+ ] map-with
[ unvisited? ] subset ;
: random-neighbour ( cell -- newcell ) choices random ;
: vertex ( pair -- )
first2 [ 0.5 + line-width * ] 2apply glVertex2d ;
: (draw-maze) ( cell -- )
dup vertex
glEnd
GL_POINTS [ dup vertex ] do-state
GL_LINE_STRIP glBegin
dup vertex
dup visit
dup random-neighbour dup [
(draw-maze) (draw-maze)
] [
2drop
glEnd
GL_LINE_STRIP glBegin
] if ;
: draw-maze ( n -- )
line-width 2 - glLineWidth
line-width 2 - glPointSize
1.0 1.0 1.0 1.0 glColor4d
dup [ drop t <array> ] map-with visited set
GL_LINE_STRIP glBegin
{ 0 0 } dup vertex (draw-maze)
glEnd ;
TUPLE: maze dlist ;
C: maze ( -- gadget )
dup delegate>gadget
black <solid> over set-gadget-interior ;
: n ( gadget -- n ) rect-dim first2 min line-width /i ;
: delete-maze-dlist ( maze -- )
dup maze-dlist [ delete-dlist ] when*
f swap set-maze-dlist ;
: cache-maze-dlist ( maze -- dlist )
dup maze-dlist [ ] [
dup GL_COMPILE [ n draw-maze ] make-dlist
dup rot set-maze-dlist
] ?if ;
M: maze layout* delete-maze-dlist ;
M: maze ungraft* delete-maze-dlist ;
M: maze draw-gadget*
origin get [ cache-maze-dlist glCallList ] with-translation ;
M: maze pref-dim* drop { 400 400 } ;
: maze-window <maze> "Maze" open-window ;
PROVIDE: demos/maze ;
MAIN: demos/maze maze-window ;
kpreid: well, did you ask for a depth buffer? :)
! From http://www.ffconsultancy.com/ocaml/bunny/index.html
USING: alien-contrib arrays sequences math io kernel
matrices opengl shuffle gadgets http-client tools
vectors timers namespaces ;
IN: bunny
: numbers ( str -- seq )
" " split [ string>number ] map [ ] subset ;
: (parse-model) ( vs is -- vs is )
readln [
numbers {
{ [ dup length 5 = ] [ 3 head pick push ] }
{ [ dup first 3 = ] [ 1 tail over push ] }
{ [ t ] [ drop ] }
} cond (parse-model)
] when* ;
: parse-model ( stream -- vs is )
[
100000 <vector> 100000 <vector> (parse-model)
] with-stream
[
over length # " vertices, " %
dup length # " triangles" %
] "" make print ;
: n ( vs triple -- n )
[ swap nth ] map-with
dup third over first v- >r dup second swap first v- r> cross
vneg normalize ;
: normal ( ns vs triple -- )
[ n ] keep [ rot [ v+ ] change-nth ] each-with2 ;
: normals ( vs is -- ns )
over length { 0.0 0.0 0.0 } <array> -rot
[ >r 2dup r> normal ] each drop
[ normalize ] map ;
: read-model ( stream -- model )
"Reading model" print flush [
<file-reader> parse-model [ normals ] 2keep 3array
] time ;
: model-path "demos/bunny/bun_zipper.ply" ;
: model-url "http://factorcode.org/bun_zipper.ply" ;
: maybe-download ( -- path )
model-path resource-path dup exists? [
"Downloading bunny from " write
model-url dup print flush
over download
] unless ;
: draw-triangle ( ns vs triple -- )
[
dup roll nth first3 glNormal3d
swap nth first3 glVertex3d
] each-with2 ;
: draw-bunny ( ns vs is -- )
GL_TRIANGLES [ [ draw-triangle ] each-with2 ] do-state ;
: cache-bunny ( triple -- displaylist )
GL_COMPILE [ first3 draw-bunny ] make-dlist ;
TUPLE: bunny-gadget dlist model ;
C: bunny-gadget ( model -- gadget )
<gadget> over set-gadget-delegate
[ set-bunny-gadget-model ] keep ;
M: bunny-gadget graft* 10 10 add-timer ;
M: bunny-gadget ungraft*
dup remove-timer
bunny-gadget-dlist [ delete-dlist ] when* ;
M: bunny-gadget tick relayout-1 ;
: aspect ( gadget -- x ) rect-dim first2 /f ;
: cache-bunny-dlist ( gadget -- dlist )
dup bunny-gadget-dlist [ ] [
dup bunny-gadget-model cache-bunny
dup rot set-bunny-gadget-dlist
] ?if ;
M: bunny-gadget draw-gadget*
GL_DEPTH_TEST glEnable
GL_SCISSOR_TEST glDisable
1.0 glClearDepth
GL_DEPTH_BUFFER_BIT glClear
0.0 0.0 0.0 1.0 glClearColor
GL_COLOR_BUFFER_BIT glClear
GL_PROJECTION glMatrixMode
glLoadIdentity
45.0 over aspect 0.1 1.0 gluPerspective
0.0 0.12 -0.25 0.0 0.1 0.0 0.0 1.0 0.0 gluLookAt
GL_MODELVIEW glMatrixMode
glLoadIdentity
GL_LEQUAL glDepthFunc
GL_LIGHTING glEnable
GL_LIGHT0 glEnable
GL_COLOR_MATERIAL glEnable
GL_LIGHT0 GL_POSITION { 1.0 -1.0 1.0 1.0 } >float-array glLightfv
millis 24000 mod 0.015 * 0.0 1.0 0.0 glRotated
GL_FRONT_AND_BACK GL_SHININESS 100.0 glMaterialf
GL_FRONT_AND_BACK GL_SPECULAR glColorMaterial
GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE glColorMaterial
0.6 0.5 0.5 1.0 glColor4d
cache-bunny-dlist glCallList ;
M: bunny-gadget pref-dim* drop { 400 300 } ;
: bunny-window ( -- )
maybe-download read-model <bunny-gadget>
"Bunny" open-window ;
demos/sudoku
now:! Based on http://www.ffconsultancy.com/ocaml/sudoku/index.html
USING: sequences namespaces kernel math io prettyprint ;
IN: sudoku
SYMBOL: solutions
SYMBOL: board
: pair+ swapd + >r + r> ;
: row board get nth ;
: board> row nth ;
: >board row set-nth ;
: f>board f -rot >board ;
: row-contains? ( n y -- ? ) row member? ;
: col-contains? ( n x -- ? ) board get swap <column> member? ;
: cell-contains? ( n x y i -- ? ) 3 /mod pair+ board> = ;
: box-contains? ( n x y -- ? )
[ 3 /i 3 * ] 2apply
9 [ >r 3dup r> cell-contains? ] contains?
>r 3drop r> ;
DEFER: search
: assume ( n x y -- )
[ >board ] 2keep [ >r 1+ r> search ] 2keep f>board ;
: attempt ( n x y -- )
{
{ [ 3dup nip row-contains? ] [ 3drop ] }
{ [ 3dup drop col-contains? ] [ 3drop ] }
{ [ 3dup box-contains? ] [ 3drop ] }
{ [ t ] [ assume ] }
} cond ;
: solve ( x y -- ) 9 [ 1+ pick pick attempt ] each 2drop ;
: solution. ( -- ) solutions inc "Solution:" print board get . ;
: search ( x y -- )
{
{ [ over 9 = ] [ >r drop 0 r> 1+ search ] }
{ [ over 0 = over 9 = and ] [ 2drop solution. ] }
{ [ 2dup board> ] [ >r 1+ r> search ] }
{ [ t ] [ solve ] }
} cond ;
: sudoku ( board -- )
[
"Puzzle:" print dup .
0 solutions set
[ clone ] map board set
0 0 search
solutions get number>string write " solutions." print
] with-scope ;
PROVIDE: demos/sudoku ;
MAIN: demos/sudoku
{
{ f f 1 f f 5 3 f f }
{ f 5 f 4 9 f f f f }
{ f f f 1 f 2 f 6 4 }
{ f f f f f f 7 5 f }
{ 6 f f f f f f f 1 }
{ f 3 5 f f f f f f }
{ 4 6 f 9 f 3 f f f }
{ f f f f 2 4 f 9 f }
{ f f 3 6 f f 1 f f }
} sudoku ;
: proj ( v u -- w )
[ [ v. ] keep norm-sq / ] keep n*v ;
: (gram-schmidt) ( v seq -- newseq )
dupd [ proj v- ] each-with ;
: gram-schmidt ( seq -- orthogonal )
V{ } clone [ over (gram-schmidt) over push ] reduce ;
: norm-gram-schmidt ( seq -- orthonormal )
gram-schmidt [ normalize ] map ;
ucontext_t
structure, used in signal handlers, is CPU-specific.#concatenative
.
libs/mysql
.
-no-compile
first yielded an image which worked fine with a 2gb data heap. And indeed, compiling something as simple as the +
word would cause a crash. Now + is called a lot, so if it is miscompiled Factor doesn't survive long enough to read another line of input in the listener. So instead I used a trick to compile + but put the compiled definition in another word. Testing didn't reveal any problems, though;0 0 blah .
3
1 3 blah .
4
... etc, with various data types, everything worked
blah
for +
, Factor would instantly crash. Some further investigation revealed this:
0 0 blah 0 =
t
0 0 blah 0 > .
t
0 0 blah class .
bignum
+
specialized to fixnum arguments; my first suspicion was some kind of singed/unsigned integer issue in the VM, but the assembly generated was identical with a 2gb heap or a typical 64mb one:0x0516d020: lwz r3,-4(r14)
0x0516d024: lwz r4,0(r14)
0x0516d028: mtxer r0
0x0516d02c: addo. r5,r4,r3
0x0516d030: bns- 0x516d094
... code to handle overflow, if there is one ...
0x0516d094: stw r5,-4(r14)
0x0516d098: addi r14,r14,-4
0x0516d028: mtxer r0
+
was called with a pair of fixnums, some random return address was being stuffed into XER; not zero as intended! But amazingly, everything worked, until I thought to test Factor with a larger data heap. The reason it worked is also simple; the code heap is mapped in directly after the data heap, so if the code heap was mapped large enough, storing a return address into XER had the effect of enabling the overflow bit, causing the following BNS instruction to always take the branch.-no-sse2
switch.-no-sse2
switch to skip detection altogether). The code for this was written by Doug, with a bit of explanation on my part regarding some (presently undocumented) compiler internals. It serves as a simple demonstration of defining a new compiler intrinsic. Check it out.slot
, fixnum+
can bring huge performance improvements because it eliminates branching and memory transfers from inner loops, but this is optional.