Thuesday is a I/O specification for a string rewriting computer.
The philosophy behind Modal's I/O is that if it can't be done in rewriting alone, it's an I/O operation. Special registers are registers that do more than store a reference, they allow implementations to choose which special behavior is needed by the host platform, without impacting the core of the language. The specification below is for a collection of event handlers is called Thuesday.
ALU
The Thuesday system has a basic arithmetic engine(ALU) located in the I/O port that allows it to use numbers. As to not enforce a specific notation, assignment of values and operators is done entirely through numeral and I/O registers:
?((?: ?0 ?1 ?2) ?:) + 1 2 3 6 suffix notation ?((?0 ?: ?1) ?:) 16 - 3 13 infix notation ?((?0 ?1 ?:) ?:) 12 10 * 120 postfix notation <> (?0 ?1 `?:) ?: postfix generalized 12 34 `+ 46
Using what we have seen above, we can make sure that a token is a number by testing it against its value plus zero:
<> (?x ?x eq) (#t) <> (?x ?y eq) (#f) <> (is-number ?x) (?((?1 ?0 ?:) ?:) ?x 0 + ?x eq) .. is-number 123 #t .. is-number pig #f
The program can typeguard a against an adversary evaluation order by differentiating between intermediate results, to demonstrate this further, here is a postfix tail-recursive factorial function:
<> (?0 ?1 `?:) (Int ?:) <> (?n factorial) (Int ?n Int 1 fact) <> (Int 0 Int ?a fact) (?a) <> (Int ?n Int ?a fact) (?n 1 `- ?n ?a `* fact) .. 6 factorial 720
Viewport
Drawing is done using the same design as the ALU, where each numeric register represent an argument. Each argument in the shapes reference is ordered by register number, so the first word is bound to ?0, the second to ?1, and so on.
Write | ||
---|---|---|
size | w h | Set the screen size to w,h. |
pixel | x y color | Draw a pixel at x,y. |
line | x1 y1 x2 y2 color | Draw a line from x,y to x2,y2. |
rect | x y w h color | Draw a lined rectangle at x,y of size w,h. |
fill-rect | x y w h color | Draw a filled rectangle at x,y of size w,h. |
circ | x y r color | Draw a lined circle at x,y of radius r. |
fill-circ | x y r color | Draw a filled circle at x,y of radius r. |
Read | ||
@pixel | x y | Get the pixel color at x,y. |
@size | Get the screen size as (w h). |
For example, the following program draws the Viznut bitart pattern:
<> (?0 ?1 `?:) ?: <> (?2 ?0 ?1 ?: draw) ?: <> ((?x ?y) Eval) ( ?x ?y `+ ?x ?y `- `& 24 `% 9 `> #ffffff `* ?x ?y pixel draw (?x ?y) Viznut) <> ((?x 256) Viznut) () <> ((256 ?y) Viznut) ((0 ?((?0 ?1 ?:) ?:) ?y 1 +) Eval) <> ((?x ?y) Viznut) ((?((?0 ?1 ?:) ?:) ?x 1 + ?y) Eval) ?((?0 ?1 ?:) ?:) 256 256 size (0 0) Viznut
Event Loop
Events are incoming events that trigger an evaluation, an evaluation will rewrite until a no rule match is reached.
Mouse | ||
---|---|---|
(Move (x y buttons)) | When mouse is moved. | |
(Touch (x y buttons)) | When mouse button is changed. | |
Keyboard | ||
(Key (mod char)) | When character button is pressed. | |
(Dpad (mod char)) | When mod button is changed. | |
Time | ||
(Tic 0-59) | When a frame is requested, 60 times per second. |
Here is an example that creates a game loop and capture mouse and keyboard events to creates a basic drawing program:
<> (`?: ?0 ?1 ?2 ?3 (?4)) (?:) ?(?-) (Mouse handlers) <> ((Last ?v ?w) handle-event (Touch (?x ?y ?z))) ((Last ?x ?y)) <> ((Last ?v ?w) handle-event (Move (?x ?y 1))) ((Last ?x ?y) `line ?v ?w ?x ?y (#ff0000)) ?(?-) (Keyboard events) <> (handle-event (Key (?x q))) (?(?: ?:) quit) ?(?-) (Discard unknown events) <> (handle-event ?x) () <> (on-event ?~) (handle-event ?~ on-event Any) (Last 0 0) on-event Any
- view sources, C99(X11).