From c299bdac8c2b78c57a6fdcbb3bd0646c51b857c9 Mon Sep 17 00:00:00 2001 From: crc Date: Thu, 23 May 2024 20:02:11 +0200 Subject: [PATCH] add source from 2024.4 release --- extend.konilo | 463 ------ konilo.pali | 3748 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 2725 insertions(+), 1486 deletions(-) delete mode 100644 extend.konilo diff --git a/extend.konilo b/extend.konilo deleted file mode 100644 index 2bc71b8..0000000 --- a/extend.konilo +++ /dev/null @@ -1,463 +0,0 @@ -================================================================ - - ,dPYb, ,dPYb, - IP'`Yb IP'`Yb - I8 8I gg I8 8I - I8 8bgg, "" I8 8' - I8 dP" "8 ,ggggg, ,ggg,,ggg, gg I8 dP ,ggggg, - I8d8bggP" dP" "Y8 ,8" "8P" "8, 88 I8dP dP" "Y8 - I8P' "Yb, i8' ,8I d8 8I 8I 88 I8P i8' ,8I -,d8 `Yb,,d8, ,d8P8P 8I Yb,_,88,_,d8b,_ ,d8, ,d8' -88P Y8P"Y8888P" 8I `Y88P""Y88P'"Y88P"Y8888P" - -================================================================ - -This file provides the high level extensions to the Konilo -system. - -Stack comments are made by the `(` sigil. I define this first, -as they are useful to have. - -~~~ -&sigil:( #40 sigil:set -:) ; -~~~ - -Next is a `$` sigil, to return the character from a string. I'll -use this to setup other sigils without needing to hard code the -ASCII constants. - -~~~ -:sigil:$ #0 s:fetch process-data ; -&sigil:$ #36 sigil:set -~~~ - -For accessing variables, the `@` (fetch) and `!` (store) sigils -are defined. - -~~~ -:sigil:@ - d:lookup d:address fetch - compiling? [ &internal:lit comma comma &fetch comma ] - &fetch choose ; - -:sigil:! - d:lookup d:address fetch - compiling? [ &internal:lit comma comma &store comma ] - &store choose ; - -&sigil:@ $@ sigil:set -&sigil:! $! sigil:set -~~~ - -The last sigil is `\`, which creates a header pointing to an -address. You can use this to name quotes: - - [ ... ] \name - -or to make an alias: - - &drop \sigil:( - -~~~ -:sigil:\ d:create @Dictionary d:address store ; -&sigil:\ $\ sigil:set -~~~ - -I/O device 7 pushes the depth of the data and address stacks to -the data stack. (Excluding the pushed values). I define words to -access these should the need arise. (Mostly, I just use the -`depth/data` to make sure the data stack has the right number -of elements) - -~~~ -:depths (-nn) #7 io ; (data,_then_address_depth) -:depth/data (-n) depths drop ; -:depth/address (-n) depths nip ; -~~~ - -Scope words. I've used these for over a decade now. It lets me -hide factors from the main dictionary. This isn't realy crucial, -just a quality of life helper. - -~~~ -:{{ @Dictionary dup &sys:buffers/scope store-next store ; -:---reveal--- - '_ d:create @Dictionary &sys:buffers/scope n:inc store ; -:}} &sys:buffers/scope fetch-next swap fetch d:link store ; -~~~ - -Variables. Ones made without an initial value are set to zero. -Use the & sigil when using them. - -~~~ -:var-n (ns-) d:create comma ; -:var (s-) d:create #0 comma ; -~~~ - -~~~ -:rot (abc-bca) &swap dip swap ; -:n:between? (nlu-f) rot [ rot rot n:limit ] sip eq? ; -~~~ - -The words in `compile:` are intended to help in writing compiler -extensions for generating ilo code words. I use them to implement -`curry`, which binds a value and function together into a new -function. - -E.g., - - #678 &n:put curry \display:678 - -~~~ -:compile:lit (n-) #1 comma comma ; -:compile:call (a-) compile:lit #8 comma ; -:compile:jump (a-) compile:lit #7 comma ; - -:curry (vq-q) here [ swap compile:lit compile:jump ] dip ; -~~~ - -Arrays are important, being the data structure used for strings -and a variety of other things. This is a very simple way to -create them. - -~~~ -:a:make (...n-a) here [ dup comma &comma times ] dip ; -:a:make/temp (...n-a) [ a:make a:temp ] gc ; -~~~ - -`a:reduce` will iterate over an array and value, applying a -function to reduce the array down to a single value. For instance, -to sum an array: - - &array #0 &n:add a:reduce - -~~~ -:a:reduce (anq-n) &swap dip a:for-each ; -~~~ - -To map a function to each value in an array, I provide `a:map`. -This modifies the original array, not a copy of it. - -~~~ -:a:map (aq-a) - swap [ fetch-next [ [ fetch over call ] sip - &store sip n:inc ] times - drop-pair ] sip ; - -&a:map \s:map -~~~ - -The next couple of words allow for extracting portions of an -array into a new array. The subsets will be stored in the -temporary buffers. - -~~~ -:a:middle (afl-a) - here [ dup comma [ n:inc n:add ] dip - here swap copy ] dip dup &Free store s:temp ; - -:a:left (an-a) #0 swap a:middle ; -:a:right (an-a) over s:length over n:sub swap a:middle ; - -&a:left \s:left (sn-s) -&a:right \s:right (sn-s) -&a:middle \s:middle (sfl-s) -~~~ - -Input tokens are whitespace delimited. This presents an issue -for strings: how to add spaces? - -The solution used here is to replace (via `s:map`) underscores -with spaces. I've been doing this now for many years, and it's -not proven to be a problem. The `sigil:'` will use the latest -`s:rewrite` it can find, so you can redefine this to make other -changes if you need to. - -~~~ -:s:rewrite (s-) [ dup $_ eq? [ drop #32 ] if ] s:map ; -~~~ - -`a:indices` returns an array with the locations of a value that -matches the passed value. `a:index` returns the first location -that matches. - -~~~ -{{ - 'Count var - :prepare #0 &Count store ; - :reserve swap #0 comma ; - :patch here over n:sub n:dec over store ; - :cleanup dup s:temp swap &Free store ; - :record &Count fetch comma ; - :iterate [ (match? over eq? ) &record if - &Count v:inc ] a:for-each ; ----reveal--- - :a:indices (av-a) - prepare here [ reserve iterate drop ] dip patch cleanup ; -}} - -:a:index (av-n) [ a:indices #0 a:fetch ] gc ; -&a:index \s:index/c -~~~ - -`a:contains?` returns a flag indicating whether or not an array -contains a given value. - -~~~ -:a:contains? (an-f) - swap #0 swap [ swap [ over eq? ] dip or ] a:for-each nip ; - -&a:contains? \s:contains? (sc-f) -~~~ - -`a:filter` runs a quote against each value in an array. The quote -needs to consume the value and return a single flag. If true, the -value is added to a new array. - -~~~ -:a:filter (aq-) - [ [ over &call dip swap &comma &drop choose ] curry - here [ over fetch comma a:for-each ] dip - here over n:sub n:dec over store a:temp ] gc ; - -&a:filter \s:filter (sq-) -~~~ - -~~~ -:c:lowercase? (c-f) $a $z n:between? ; -:c:uppercase? (c-f) $A $Z n:between? ; -:c:to-upper (c-c) dup c:lowercase? [ #32 n:sub ] if ; -:c:to-lower (c-c) dup c:uppercase? [ #32 n:add ] if ; -:c:to-s (c-s) '_ s:temp tuck #0 s:store ; - -:s:to-upper (s-s) [ s:dup &c:to-upper s:map s:temp ] gc ; -:s:to-lower (s-s) [ s:dup &c:to-lower s:map s:temp ] gc ; -~~~ - -~~~ -{{ - 'Current var - :get-index &sys:buffers/loops @Current n:add ; - :prepare &Current v:inc #0 get-index store ; - :cleanup &Current v:dec ; - :inner:indexed-times - swap [ dup &call dip (next get-index v:inc ) ] dip n:dec - tuck n:-zero? &inner:indexed-times ?jump drop-pair ; ----reveal--- - :I (-n) get-index fetch ; - :J (-n) get-index #1 n:sub fetch ; - :K (-n) get-index #2 n:sub fetch ; - :indexed-times (nq-) prepare inner:indexed-times cleanup ; -}} - -:bi (xqq-) &sip dip call ; -:bi* (xyqq-) &dip dip call ; -:bi@ (xyq-) dup bi* ; -:tri (xqqq-) [ &sip dip sip ] dip call ; -:tri* (xyzqqq-) [ [ swap &dip dip ] dip dip ] dip call ; -:tri@ (xyzq-) dup dup tri* ; - -:a:eq? (aa-f) &a:hash bi@ eq? ; -&a:eq? \s:eq? (ss-f) - -:a:-eq? (aa-a) a:eq? not ; -&a:-eq? \s:-eq? (ss-f) - -:a:chop (a-a) a:temp &v:dec sip ; -&a:chop \s:chop (s-s) - -:a:behead (a-a) - a:chop [ [ n:inc dup n:inc swap ] - &a:length bi copy ] sip ; -&a:behead \s:behead (s-s) - -:a:first (a-n) #0 a:fetch ; -:a:last (a-n) dup a:length n:dec a:fetch ; - -&a:first \s:first (s-c) -&a:last \s:last (s-c) -~~~ - -The `s:trim` words remove leading, or trailing (or both) -whitespace from a string. These aren't mirrored in the `a:` -namespace. - -~~~ -:s:trim-right (s-s) - s:temp [ dup v:dec [ s:last #32 lteq? ] sip swap ] while - dup v:inc ; - -{{ - 'Start var - 'End var - 'Len var - :find-end dup s:length dup !Len over n:add n:inc !End n:inc ; - :new-size @Start over swap n:sub @Len swap n:sub ; ----reveal--- - :s:trim-left (s-s) - s:dup dup #0 s:fetch #32 eq? - [ dup !Start find-end - [ fetch-next #32 -eq? over @End -eq? and ] while - new-size (patch over store ) ] if ; -}} - -:s:trim (s-s) s:trim-left s:trim-right ; -~~~ - -`n:get` reads a number from the input device. - -~~~ -:n:get (-n) s:get/token s:temp s:to-n ; -~~~ - -================================================================ - -The block editor is an important piece of the Konilo system. -It's how code is entered, managed, and run. - -~~~ -:block:buffer (-a) &sys:buffers/block ; - -#16 'Blocks var-n (number_of_blocks_available) -#0 'Block var-n (current_block_number) -~~~ - -~~~ -:e:to-line (n-a) #64 n:mul block:buffer n:add ; -:e:line (n-) e:to-line #64 [ fetch-next c:put ] times drop nl ; - -{{ - :sep sp sp sp #6 [ '+----5---- s:put ] times '+--- s:put nl ; - :l/n I dup #10 lt? &sp if n:put sp ; - :line l/n I e:line ; - :lines #16 &line indexed-times ; - :info 'sys:info d:lookup dup n:-zero? - [ d:address fetch call ] &drop choose ; ----reveal--- - :list* (-) nl #16 [ I e:line ] indexed-times ; - :list# (-) nl lines ; - :list (-) nl sep lines sep info ; -}} - -&list 'e:Display var-n -{{ - :reset #1024 block:buffer n:dec store ; - :constrain @Block #0 @Blocks n:dec n:limit !Block ; ----reveal--- - :set (n-) !Block constrain ; - :save (-) @Block block:buffer block:save ; - :load (-) @Block block:buffer block:load reset ; - :next (-) &Block v:inc constrain load ; - :prev (-) &Block v:dec constrain load ; - :new (-) #32 block:buffer #1024 fill reset ; - :edit (n-) set load @e:Display call ; - :run (-) reset block:buffer n:dec s:evaluate ; - :use (block) set load run ; - :using (first,last) over n:sub swap use [ next run ] times ; -}} - -{{ - :handle dup #8 eq? over #127 eq? or - [ drop #-1 allot ] &comma choose ; - :process dup #10 eq? [ drop #-1 ] [ handle #0 ] choose ; ----reveal--- - :s:get/line (-s) - here [ #0 comma [ c:get process ] until ] sip - here over n:sub n:dec over !Free swap store drop - here s:temp ; -}} - -:e:erase/line (n-) e:to-line #32 swap #64 fill ; -:e:replace (sn-) n:inc swap e:to-line over n:dec s:length copy ; -:e:replace-at (snn-) [ &e:to-line dip n:add ] dip - [ over store n:inc ] s:for-each drop ; - -:e:insert (n"-) dup e:erase/line s:get/line e:replace ; -:e:insert-at (nn"-) s:get/line e:replace-at ; - -:0 ("-) #0 e:insert ; :1 ("-) #1 e:insert ; -:2 ("-) #2 e:insert ; :3 ("-) #3 e:insert ; -:4 ("-) #4 e:insert ; :5 ("-) #5 e:insert ; -:6 ("-) #6 e:insert ; :7 ("-) #7 e:insert ; -:8 ("-) #8 e:insert ; :9 ("-) #9 e:insert ; -:10 ("-) #10 e:insert ; :11 ("-) #11 e:insert ; -:12 ("-) #12 e:insert ; :13 ("-) #13 e:insert ; -:14 ("-) #14 e:insert ; :15 ("-) #15 e:insert ; -~~~ - -~~~ -:. ("-) #62 [ c:get drop ] times ; -~~~ - -The basic `use` and `using` words aren't very convienient as you -need to keep track of the exact blocks to load. `needs` allows -you to use the first part of a block title line (typically a -comment for code blocks) instead. It'll scan through the block -set, running any blocks that match the provided text. E.g., to -load a block set named "(pali)": - - '(pali) needs - -Blocks are loaded in order from 0 to N, where N is the value in -`Blocks`. This can be very slow if you have a large block set or -are loading multiple sets of blocks. You may want to consider -keeping blocks towards the low end of the block set and limiting -`Blocks` before running this. - -~~~ -{{ - 'Len var - :buffer (-a) &sys:buffers/needs ; - :check (-f) block:buffer buffer @Len compare ; - :setup (s-) dup s:length !Len n:inc buffer @Len copy ; ----reveal--- - :needs (s-) - setup @Block [ - @Blocks [ I set load check &run if ] indexed-times - ] dip !Block load ; -}} -~~~ - -For generating an index of the blocks, `titles` is provided. -This shows the block number and index line for any block with -a title line. - -~~~ -:titles (-) - @Block @Blocks - [ I set load block:buffer fetch #32 -eq? - [ I n:put sp #64 block:buffer n:dec &store &s:put bi nl ] if - ] indexed-times !Block load ; -~~~ - -`sys:info` is called by the editor. It displays a status line below -the editor output. You can write a new `sys:info`, and the the code -will use the most recent one. - -~~~ -:sys:info (-) - '___B: s:put @Block n:put $/ c:put @Blocks n:dec n:put - '___S: s:put depth/data n:put $/ c:put #32 n:put - '___M: s:put here n:put $/ c:put #59999 n:put nl ; -~~~ - -================================================================ - -The last couple of things are just to save the image and set a -startup word. The default startup word runs the code in blocks -1 and 2, then starts the editor on block 0. - -~~~ -{{ - :process (n-f) set load block:buffer fetch $( eq? &run if ; ----reveal--- - :prelude (-) #1 process #2 process ; - :startup (-) prelude ; -}} - -:rom:save (-) #4 io ; - -rom:save bye -~~~ - diff --git a/konilo.pali b/konilo.pali index faca56a..d7a355c 100644 --- a/konilo.pali +++ b/konilo.pali @@ -1,4 +1,4 @@ -================================================================ +w================================================================ ,dPYb, ,dPYb, IP'`Yb IP'`Yb @@ -92,7 +92,8 @@ organized as: | 61140 - 61141 | lexical scope | | 61142 - 61206 | needs buffer | | 61207 - 61335 | sigils table | -| 61336 - 64377 | reserved for future system use | +| 61336 - 63376 | reserved for future system use | +| 63377 - 64377 | misc. system variables | | 64378 - 65406 | string buffers (8 x 127 chars) | | 65407 - 65535 | text input buffer (127 chars) | +---------------+----------------------------------------------+ @@ -105,32 +106,53 @@ c set to 1 after the actual start to leave room for a length c cell o 60001 : sys:buffers/block - -o 60126 +o 61026 : sys:buffers/string-eval - o 61092 : sys:buffers/loops - o 61105 : sys:buffers/numeric-conversion - o 61140 : sys:buffers/scope - o 61142 : sys:buffers/needs - o 61207 : Sigils -* 128 + +c ! for fetching from variables +o 61240 +r sigil:! +c # for numbers +o 61242 +r sigil:# +c $ for characters +o 61243 +r sigil:$ +c & for pointers +o 61245 +r sigil:& +c ' for strings +o 61246 +r sigil:' +c ( for comments +o 61247 +r drop +c : for colon definitions +o 61265 +r sigil:: +c @ for fetching from variables +o 61271 +r sigil:@ +c \ for creating names +o 61299 +r sigil:\ o 61336 : sys:buffers/reserved - +o 63377 +: sys:buffers/variables o 64378 : sys:buffers/strings+arrays - o 65407 : sys:buffers/input o 65408 @@ -139,16 +161,75 @@ o 65409 : sys:buffers/input/text+1 ~~~ -After creating the labels for the system buffers, return to -address 0 to start the actual code. +~~~ +c A number of parts of the system make use of variables. I store +c these in the system buffers +o 63377 + +c Compiler tracks the compiler state (-1 for on, 0 for off) +: Compiler +d 0 + +: BaseBlock +c BaseBlock is used by the block i/o words +d 0 + +: Blocks +c number of blocks available +d 16 + +: Block +c number of the current block +d 0 + +c These are used to construct the choice table used by `choose` +: choice:true +d 0 +: choice:false +d 0 + +c ACount stores the number of matches found by `a:indices` +: ACount +d 0 + +c Current is used by `indexed-times` to track the current loop +c depth +: Current +d 0 + +c Source, End, and At are used by the string evaluation code. +: Source +d 0 +: End +d 0 +: At +d 0 + +c s:Length & s:Current are used by `s:to-n` +: s:Length +d 0 +: s:Current +d 0 + +c Next-String holds the number for the next string in the temp. +c pool +: Next-String +d 0 + +c Used by `needs` +: needs.Len +d 0 +~~~ -On startup this calls a function to populate the default sigils, -then jumps into forth. ~~~ +c After creating the labels for the system buffers, return to +c address 0 to start the actual code. + +c On startup this calls a function to populate the default +c sigils, then jumps into forth. + o 0 -i lica.... -r setup:sigils i liju.... r forth ~~~ @@ -164,290 +245,252 @@ Information about these is stored in a `dictionary`. The first set of words I'm defining map directly to the instructions in the ilo computer. -`dup` duplicates the top item on the data stack. - - +---+ +---+---+ - | 1 | ==> | 1 | 1 | - +---+ +---+---+ - ~~~ +c `dup` duplicates the top item on the data stack. +c +c +---+ +---+---+ +c | 1 | ==> | 1 | 1 | +c +---+ +---+---+ +c : dup c (n-nn) i dure.... -~~~ -`drop` discards the top item on the data stack. - - +---+---+ +---+ - | 1 | 2 | ==> | 1 | - +---+---+ +---+ - -~~~ +c `drop` discards the top item on the data stack. +c +c +---+---+ +---+ +c | 1 | 2 | ==> | 1 | +c +---+---+ +---+ +c : drop c (n-) i drre.... -~~~ -`swap` exchanges the positions of the top two values on the -data stack. - - +---+---+ +---+---+ - | 1 | 2 | ==> | 2 | 1 | - +---+---+ +---+---+ - -~~~ +c `swap` exchanges the positions of the top two values on the +c data stack. +c +c +---+---+ +---+---+ +c | 1 | 2 | ==> | 2 | 1 | +c +---+---+ +---+---+ +c : swap c (nm-mn) i swre.... -~~~ -`eq?` compares two items on the stack for equality. If they are -equal, it will push a true (-1) flag. If they are not equal, it -pushes false (0) instead. - - +---+---+ +----+ - | 1 | 1 | ==> | -1 | - +---+---+ +----+ - - +---+---+ +----+ - | 2 | 1 | ==> | 0 | - +---+---+ +----+ - -~~~ +c `eq?` compares two items on the stack for equality. If they +c are equal, it will push a true (-1) flag. If they are not +c equal, it pushes false (0) instead. +c +c +---+---+ +----+ +c | 1 | 1 | ==> | -1 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 2 | 1 | ==> | 0 | +c +---+---+ +----+ +c : eq? c (nn-f) i eqre.... -~~~ -`-eq?` compares two items on the stack for inequality. If they -are not equal, it will push a true (-1) flag. If they are equal, -it pushes false (0) instead. - - +---+---+ +----+ - | 1 | 1 | ==> | 0 | - +---+---+ +----+ - - +---+---+ +----+ - | 2 | 1 | ==> | -1 | - +---+---+ +----+ - -~~~ +c `-eq?` compares two items on the stack for inequality. If they +c are not equal, it will push a true (-1) flag. If they are +c equal, it pushes false (0) instead. +c +c +---+---+ +----+ +c | 1 | 1 | ==> | 0 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 2 | 1 | ==> | -1 | +c +---+---+ +----+ +c : neq? c (nn-f) i nere.... -~~~ - +---+---+ +----+ - | 1 | 1 | ==> | 0 | - +---+---+ +----+ - - +---+---+ +----+ - | 2 | 1 | ==> | 0 | - +---+---+ +----+ - - +---+---+ +----+ - | 1 | 2 | ==> | -1 | - +---+---+ +----+ - -~~~ +c +---+---+ +----+ +c | 1 | 1 | ==> | 0 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 2 | 1 | ==> | 0 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 1 | 2 | ==> | -1 | +c +---+---+ +----+ +c : lt? c (nn-f) i ltre.... -~~~ - +---+---+ +----+ - | 1 | 1 | ==> | 0 | - +---+---+ +----+ - - +---+---+ +----+ - | 2 | 1 | ==> | -1 | - +---+---+ +----+ - - +---+---+ +----+ - | 1 | 2 | ==> | 0 | - +---+---+ +----+ - -~~~ +c +---+---+ +----+ +c | 1 | 1 | ==> | 0 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 2 | 1 | ==> | -1 | +c +---+---+ +----+ +c +c +---+---+ +----+ +c | 1 | 2 | ==> | 0 | +c +---+---+ +----+ +c : gt? c (nn-f) i gtre.... -~~~ -~~~ : fetch c (p-n) i fere.... -~~~ -~~~ : store c (np-) i stre.... -~~~ -`n:add` adds two values, returning the result. - - +---+---+ +---+ - | 1 | 2 | ==> | 3 | - +---+---+ +---+ - -~~~ +c `n:add` adds two values, returning the result. +c +c +---+---+ +---+ +c | 1 | 2 | ==> | 3 | +c +---+---+ +---+ +c : n:add c (nn-n) i adre.... -~~~ -`n:sub` subtracts two values, returning the result. - - +---+---+ +---+ - | 3 | 1 | ==> | 2 | - +---+---+ +---+ - -~~~ +c `n:sub` subtracts two values, returning the result. +c +c +---+---+ +---+ +c | 3 | 1 | ==> | 2 | +c +---+---+ +---+ +c : n:sub c (nn-n) i sure.... -~~~ -`n:mul` multiplies two values, returning the result. - - +---+---+ +---+ - | 2 | 3 | ==> | 6 | - +---+---+ +---+ - -~~~ +c `n:mul` multiplies two values, returning the result. +c +c +---+---+ +---+ +c | 2 | 3 | ==> | 6 | +c +---+---+ +---+ +c : n:mul c (nn-n) i mure.... -~~~ -`n:divmod` divides two values, returning the result and -remainer. - -~~~ +c `n:divmod` divides two values, returning the result and +c remainer. +c : n:divmod c (nn-nn) i dire.... -~~~ -~~~ : and c (nn-n) i anre.... -~~~ -~~~ : or c (nn-n) i orre.... -~~~ -~~~ : xor c (nn-n) i xore.... -~~~ -~~~ : shift-left c (nn-n) i slre.... -~~~ -~~~ : shift-right c (nn-n) i srre.... -~~~ -`io` triggers an i/o operation. The basic ilo system provides -just a few i/o devices. - -Using this is a matter of pushing any need values to the stack, -pushing the i/o device number, then calling `io`. For a list of -devices: - -+------------+--------------------------------------+----------+ -| I/O Device | Action | Required | -+============+======================================+==========+ -| 0 | Display a character. Consumes a | Yes | -| | character from the stack. | | -| 1 | Read a character from the input | Yes | -| | device. The character is pushed to | | -| | the stack. | | -| 2 | Read a block into memory. | Yes | -| 3 | Write memory to a block. | Yes | -| 4 | Write all memory to an image/rom. | No | -| 5 | Reload the image/rom, and jump to | Yes | -| | address 0. Also empty all stacks. | | -| 6 | End execution. On a hosted system, | No | -| | exit ilo. If native, suspend | | -| | execution. | | -| 7 | Obtain stack depths. Pushes the data | Yes | -| | depth then the address depth. | | -+------------+-------------------------------------------------+ - -~~~ +c `io` triggers an i/o operation. The basic ilo system provides +c just a few i/o devices. +c +c Using this is a matter of pushing any needed values to the +c stack, pushing the i/o device number, then calling `io`. For +c a list of devices: +c +c +--------+--------------------------------------+----------+ +c | Device | Action | Required | +c +========+======================================+==========+ +c | 0 | Display a character. Consumes a | Yes | +c | | character from the stack. | | +c | 1 | Read a character from the input | Yes | +c | | device. The character is pushed to | | +c | | the stack. | | +c | 2 | Read a block into memory. | Yes | +c | 3 | Write memory to a block. | Yes | +c | 4 | Write all memory to an image/rom. | No | +c | 5 | Reload the image/rom, and jump to | Yes | +c | | address 0. Also empty all stacks. | | +c | 6 | End execution. On a hosted system, | No | +c | | exit ilo. If native, suspend | | +c | | execution. | | +c | 7 | Obtain stack depths. Pushes the data | Yes | +c | | depth then the address depth. | | +c +--------+-------------------------------------------------+ +c : io c (...n-?) i iore.... -~~~ -`copy` copies "n" cells of memory starting at p1 to p2. For -example: - - +---+---+---+---+---+---+---+---+---+ - | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - +---+---+---+---+---+---+---+---+---+ - | A | B | C | D | D | E | A | B | C | - +---+---+---+---+---+---+---+---+---+ - -With a stack of: - - #2 #6 #3 - -This would change memory to: - - +---+---+---+---+---+---+---+---+---+ - | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - +---+---+---+---+---+---+---+---+---+ - | A | B | C | D | D | B | C | D | C | - +---+---+---+---+---+---+---+---+---+ - -The ilo specification does not require the system to support -overlapping copies. If the memory areas would overlap, test -well and write a specific word to handle the overlap if needed. - -~~~ +c `copy` copies "n" cells of memory starting at p1 to p2. For +c example: +c +c +---+---+---+---+---+---+---+---+---+ +c | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +c +---+---+---+---+---+---+---+---+---+ +c | A | B | C | D | D | E | A | B | C | +c +---+---+---+---+---+---+---+---+---+ +c +c With a stack of: +c +c #2 #6 #3 +c +c This would change memory to: +c +c +---+---+---+---+---+---+---+---+---+ +c | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +c +---+---+---+---+---+---+---+---+---+ +c | A | B | C | D | D | B | C | D | C | +c +---+---+---+---+---+---+---+---+---+ +c +c The ilo specification does not require the system to support +c overlapping copies. If the memory areas would overlap, test +c and write a specific word to handle the overlap if needed. +c : copy c (ppn-) i cyre.... -~~~ -`compare` will compare "n" cells of memory starting at p1 and -p2. - -As an example: - - +---+---+---+---+---+---+---+---+---+ - | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - +---+---+---+---+---+---+---+---+---+ - | A | B | C | D | D | E | A | B | C | - +---+---+---+---+---+---+---+---+---+ - -With a stack of: - - #1 #7 #3 - -This would return true (-1) as the ABC sequences at 1 & 7 match. -But a stack of: - - #1 #5 #3 - -Would return false (0) since the sequences (ABC & DEA) do not -match. - -~~~ +c `compare` will compare "n" cells of memory starting at p1 and +c p2. +c +c As an example: +c +c +---+---+---+---+---+---+---+---+---+ +c | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +c +---+---+---+---+---+---+---+---+---+ +c | A | B | C | D | D | E | A | B | C | +c +---+---+---+---+---+---+---+---+---+ +c +c With a stack of: +c +c #1 #7 #3 +c +c This would return true (-1) as the ABC sequences at 1 & 7 +c match. +c +c But a stack of: +c +c #1 #5 #3 +c +c Would return false (0) since the sequences (ABC & DEA) do not +c match. +c : compare c (ppn-) i cpre.... @@ -455,64 +498,56 @@ i cpre.... ================================================================ -The next set makes a copy of the second item on the stack, puts -a copy of the top item under the second item, discards the -second item, discards the top two items, and makes copies of the -top two items. - - +---+---+ +---+---+---+ - | 1 | 2 | ==> | 1 | 2 | 1 | - +---+---+ +---+---+---+ - ~~~ +c The next set makes a copy of the second item on the stack, +c puts a copy of the top item under the second item, discards +c the second item, discards the top two items, and makes copies +c of the top two items. +c +c +---+---+ +---+---+---+ +c | 1 | 2 | ==> | 1 | 2 | 1 | +c +---+---+ +---+---+---+ +c : over c (xy-xyx) i puduposw i re...... -~~~ - +---+---+ +---+---+---+ - | 1 | 2 | ==> | 2 | 1 | 2 | - +---+---+ +---+---+---+ - -~~~ +c +---+---+ +---+---+---+ +c | 1 | 2 | ==> | 2 | 1 | 2 | +c +---+---+ +---+---+---+ +c : tuck c (xy-yxy) i dupuswpo i re...... -~~~ - +---+---+ +---+ - | 1 | 2 | ==> | 2 | - +---+---+ +---+ - -~~~ +c +---+---+ +---+ +c | 1 | 2 | ==> | 2 | +c +---+---+ +---+ +c : nip c (xy-y) i swdrre.. -~~~ -`drop-pair` discards the top two stack items. (In some Forths -this is called "2drop") - - +---+---+ - | 1 | 2 | ==> - +---+---+ - -~~~ +c `drop-pair` discards the top two stack items. (In some Forths +c this is called "2drop") +c +c +---+---+ +c | 1 | 2 | ==> +c +---+---+ +c : drop-pair c (xy-) i drdrre.. -~~~ -`dup-pair` makes a copy of the top two stack items. (In some -Forths this is called "2dup") - - +---+---+ +---+---+---+---+ - | 1 | 2 | ==> | 1 | 2 | 1 | 2 | - +---+---+ +---+---+---+---+ - -~~~ +c `dup-pair` makes a copy of the top two stack items. (In some +c Forths this is called "2dup") +c +c +---+---+ +---+---+---+---+ +c | 1 | 2 | ==> | 1 | 2 | 1 | 2 | +c +---+---+ +---+---+---+---+ +c : dup-pair c (xy-xyxy) i puduposw @@ -522,16 +557,17 @@ i re...... ================================================================ -There is a second stack, which holds return addresses. It's -used for subroutine calls, but you can temporarily store data -there as well. `push` and `pop` provide access to this stack. - -Note that this is more complicated than simply pushing values. -Thes definitions take the direct threading implementation into -account to ensure that code does not crash when using them, as -long as the `push` and `pop` operations are paired correctly. - ~~~ +c There is a second stack, which holds return addresses. It's +c used for subroutine calls, but you can temporarily store data +c there as well. `push` and `pop` provide access to this stack. +c +c Note that this is more complicated than simply pushing values. +c Thess definitions take the direct threading implementation +c into account to ensure that code does not crash when using +c them, as long as the `push` and `pop` operations are paired +c correctly. +c : push c (n-) (A:-n) i poswposw @@ -541,17 +577,15 @@ i pupupure c (-n) (A:n-) i popoposw i puswpure -~~~ -A better way to work with data items on the address stack is to -use `dip` and `sip`. Using these ensures that the address stack -remains balanced, and is more idomatic. - -In this case, `dip` removes the value before calling the -function, but `sip` does not. In both, the value is restored to -the stack after the function return. - -~~~ +c A better way to work with data items on the address stack is +c to use `dip` and `sip`. Using these ensures that the address +c stack remains balanced, and is more idomatic. +c +c In this case, `dip` removes the value before calling the +c function, but `sip` does not. In both, the value is restored +c to the stack after the function return. +c : dip c (np-n) i swpuca.. @@ -562,32 +596,33 @@ c (np-n) i puduposw i puca.... i pore.... + +c For those familiar with traditional Forth systems, the `push`, +c `pop`, `dip`, and `sip` are similar to: +c +c +--------------+---------------+ +c | Konilo | Traditional | +c +==============+===============+ +c | push ... pop | >R ... R> | +c | [ ... ] dip | >R ... R> | +c | [ ... ] sip | dup >R ... R> | +c +--------------+---------------+ +c ~~~ -For those familiar with traditional Forth systems, the `push`, -`pop`, `dip`, and `sip` are similar to: - -+--------------+---------------+ -| Konilo | Traditional | -+==============+===============+ -| push ... pop | >R ... R> | -| [ ... ] dip | >R ... R> | -| [ ... ] sip | dup >R ... R> | -+--------------+---------------+ - ================================================================ -Konilo provides a number of words for controlling the flow -of execution. - -The initial building blocks are calls, jumps, and returns. A -call takes an address and jumps to it, saving the previous -execution address on the return (or address) stack. Return will -take the address from the return stack and jump back to it. A -jump is like call, but does not save a return address and thus -can not be used with return. - ~~~ +c Konilo provides a number of words for controlling the flow +c of execution. +c +c The initial building blocks are calls, jumps, and returns. A +c call takes an address and jumps to it, saving the previous +c execution address on the return (or address) stack. Return +c will take the address from the return stack and jump back to +c it. A jump is like call, but does not save a return address +c and thus can not be used with return. +c : jump c (p-) i popopodr @@ -600,10 +635,10 @@ i ju...... ================================================================ -`?jump` branches to a function if a passed flag is true -(non-zero). - ~~~ +c `?jump` branches to a function if a passed flag is true +c (non-zero). + : ?jump i swline.. d 0 @@ -616,14 +651,14 @@ i drre.... # Loops -The `times` combinator takes a count and an address. It then -runs the function the specified number of times. - -An example: - - #0 #10 [ dup n:put n:inc ] times drop - ~~~ +c The `times` combinator takes a count and an address. It then +c runs the function the specified number of times. +c +c An example: +c +c #0 #10 [ dup n:put n:inc ] times drop + : times c (np-) i sw...... @@ -639,13 +674,11 @@ i popoliju r times.loop : times.done i drdrre.. -~~~ -The `until` combinator takes a function address. The function -must leave a flag on the stack. `until` runs the function -repeatedly until the flag is true (non-zero). +c The `until` combinator takes a function address. The function +c must leave a flag on the stack. `until` runs the function +c repeatedly until the flag is true (non-zero). -~~~ : until c (p-) c pointer must return a value to be used as a flag @@ -655,13 +688,11 @@ d 0 i licj.... r until i drre.... -~~~ -The `while` combinator takes a function address. The function -must leave a flag on the stack. `while` runs the function -repeatedly until the flag is false (zero). +c The `while` combinator takes a function address. The function +c must leave a flag on the stack. `while` runs the function +c repeatedly until the flag is false (zero). -~~~ : while c (p-) c pointer must return a value to be used as a flag @@ -671,11 +702,9 @@ d 0 i licj.... r while i drre.... -~~~ -`forever` runs a function repeatedly in an unending loop. +c `forever` runs a function repeatedly in an unending loop. -~~~ : forever c (p-) i dupuca.. @@ -685,21 +714,20 @@ r forever ================================================================ -`restart` triggers the reset functionality in ilo. This will -reload the image, reset the stack pointers to empty, and then -jump to address 0. ~~~ +c `restart` triggers the reset functionality in ilo. This will +c reload the image, reset the stack pointers to empty, and then +c jump to address 0. + : restart c (...-) i liio.... d 5 -~~~ -`bye` triggers the shutdown functionality it ilo. On a hosted -system, this will normally return to the system shell. +c `bye` triggers the shutdown functionality it ilo. On a hosted +c system, this will normally return to the system shell. -~~~ : bye c (-) i liio.... @@ -710,9 +738,6 @@ d 6 # Block I/O -Block loading & saving is a frequent operation for me, so I have -these here to make them a little more efficient. - ~~~ : block:load c (np-) @@ -727,16 +752,13 @@ i pulifead r BaseBlock i poliiore d 3 - -: BaseBlock -d 0 ~~~ # Maths -`n:zero?` and `n:-zero?` compare a value to zero. - ~~~ +c `n:zero?` and `n:-zero?` compare a value to zero. + : n:zero? c (n-f) i lieqre.. @@ -746,12 +768,10 @@ d 0 c (n-f) i linere.. d 0 -~~~ -`n:divmod` wraps the instruction that divides and returns the -quotient and remainder. These separate out the functionality. +c `n:divmod` wraps the instruction that divides and returns the +c quotient and remainder. These separate out the functionality. -~~~ : n:mod c (n-n) i didrre.. @@ -759,49 +779,44 @@ i didrre.. : n:div c (n-n) i diswdrre -~~~ -`n:min` returns the lesser of two values; `n:max` returns the -greater. +c `n:min` returns the lesser of two values; `n:max` returns the +c greater. -~~~ : n:min c (nn-n) -i lica.... -r dup-pair +c inline dup-pair +i puduposw +i puduposw i ltlilili r drop r nip r choose i ju...... -~~~ -~~~ : n:max c (nn-n) -i lica.... -r dup-pair +c inline dup-pair +i puduposw +i puduposw i gtlilili r drop r nip r choose i ju...... -~~~ -I use `n:min` and `n:max` to implement `n:limit`, which takes a -value, and an upper and lower limit. It will return the value -if it is in range, or the closest value in range if outside it. +c I use `n:min` and `n:max` to implement `n:limit`, which takes +c a value, and an upper and lower limit. It will return the +c value if it is in range, or the closest value in range if +c outside it. -~~~ : n:limit i swlilica r n:min r dip i liju.... r n:max -~~~ -~~~ : not c (n-n) i lixore.. @@ -812,38 +827,36 @@ d -1 # Memory -`fetch-next` takes an address. It fetches the value stored at -the address, and returns both this and the next address. - ~~~ +c `fetch-next` takes an address. It fetches the value stored at +c the address, and returns both this and the next address. + : fetch-next c (p-pn) i duliadsw d 1 i fere.... -~~~ -`store-next` takes a value and an address. It stores the value -in the address, then returns the next address. +c `store-next` takes a value and an address. It stores the value +c in the address, then returns the next address. -~~~ : store-next c (np-p) i duliadpu d 1 i stpore.. -~~~ -`fill` is used to fill a region of memory with a specified -value. +c `fill` is used to fill a region of memory with a specified +c value. +c +c Takes a value, and address, and a length. -Takes a value, and address, and a length. - -~~~ : fill c (npn-) -i pulica.. -r dup-pair +i pu...... +c inline dup-pair +i puduposw +i puduposw i stliadpo d 1 i lisuduli @@ -855,13 +868,11 @@ i liju.... r fill : fill.done i drdrdrre -~~~ -`gc` runs a function, saving and restoring the value of `Free`. -This replaces the pattern of `@Free [ ... ] dip !Free` with -`[ ... ] gc`, a shorter and more readable approach. +c `gc` runs a function, saving and restoring the value of `Free` +c This replaces the pattern of `@Free [ ... ] dip !Free` with +c `[ ... ] gc`, a shorter and more readable approach. -~~~ : gc c (p-) i lifepuca @@ -872,25 +883,19 @@ r Free # Conditionals -`choose` takes a flag and two function addresses. If the flag -is true (non-zero), it runs the first function. If false (zero), -it will run the second. - -This works by storing the pointers in a table. A pointer to the -second entry in the table (the false operation) is then placed -on the stack, and the flag is added to the pointer. If true (-1) -it will then point to the true function. I can then just fetch -and branch. - -A small bit of logic is inserted to ensure the flags are either --1 or 0. - ~~~ -: choice:true -d 0 - -: choice:false -d 0 +c `choose` takes a flag and two function addresses. If the flag +c is true (non-zero), it runs the first function. If false +c (zero), it will run the second. +c +c This works by storing the pointers in a table. A pointer to +c the second entry in the table (the false operation) is then +c placed on the stack, and the flag is added to the pointer. If +c true (-1) it will then point to the true function. I can then +c just fetch and branch. +c +c A small bit of logic is inserted to ensure the flags are +c either -1 or 0. : choose c (fpp-) @@ -905,13 +910,11 @@ d 0 r choice:false c branch to the selected target i feju.... -~~~ -`if` and `-if` each take a flag and a function pointer. `if` -will run the function if the flag is true. `-if` will run it if -the flag is false. +c `if` and `-if` each take a flag and a function pointer. `if` +c will run the function if the flag is true. `-if` will run it +c if the flag is false. -~~~ : -if c (fp-) i pulieqpo @@ -932,8 +935,9 @@ This would return true (-1) since 1 is less than or equal to 2. ~~~ : lteq? c (nn-f) -i lica.... -r dup-pair +c inline dup-pair +i puduposw +i puduposw i eqpultpo i orre.... ~~~ @@ -959,7 +963,6 @@ linked list, with the following fields: | 0 | d:link | link to previous entry | | 1 | d:hash | hash of word name | | 2 | d:address | pointer to word start | -| 3 | d:flags | special flags (immediate) | +---+-----------+---------------------------+ Note that the name of the word is not actually saved, just a @@ -1047,13 +1050,6 @@ d 1 c (d-p) i liadre.. d 2 - -: d:flags -c (d-p) -c The flags field is currently only used to track -c immediate words. -i liadre.. -d 3 ~~~ `d:exists?` checks for the presence of a word. It uses @@ -1105,10 +1101,9 @@ array and a pointer to the destination. : a:copy c (ap-) i puduposw -i feliad.. +i feliadcy d 1 -i liju.... -r copy +i re...... ~~~ `a:dup` takes a pointer to an array. It makes a copy of this @@ -1278,34 +1273,23 @@ before the items in the first. ~~~ : a:prepend c (aa-a) +i lifepusw +r Free +i poswpusw +i poswlica +r dup-pair i lica.... -r dtc -- here - -- lit -r swap -- dip -- swap - -- lit -r swap -- dip -- swap - -- dup-pair -- a:length -- swap -- a:length -- n:add -- comma - -- lit +r a:length +i swlica.. +r a:length +i adlica.. r comma -- a:for-each -- lit +i lilica.. r comma -- a:for-each -d 0 +r a:for-each +i liliju.. +r comma +r a:for-each ~~~ Use `a:append` to merge two arrays into a new one. Takes two @@ -1358,6 +1342,113 @@ i stlisure d 1 ~~~ +Arrays are important, being the data structure used for strings +and a variety of other things. This is a very simple way to +create them. + +~~~ +: a:make +c (...n-a) +i lifepu.. +r Free +i dulica.. +r comma +i lilica.. +r comma +r times +i pore.... + +: a:make/temp +c (...n-a) +i liliju.. +r a:make/temp.internal +r gc + +: a:make/temp.internal +i lica.... +r a:make +i liju.... +r s:temp +~~~ + +`a:reduce` will iterate over an array and value, applying a +function to reduce the array down to a single value. For instance, +to sum an array: + + &array #0 &n:add a:reduce + +~~~ +: a:reduce +c (anq-n) +i puswpoli +r a:for-each +i ju...... +~~~ + +To map a function to each value in an array, I provide `a:map`. +This modifies the original array, not a copy of it. + +~~~ +: a:map +c (aq-a) +i swdupu.. +i lica.... +r fetch-next +i lilica.. +r a:map.inner +r times +i drdrpore + +: a:map.inner +i dupufepu +c "over" +i duposwca +i polilica +r store +r sip +i liadre.. +d 1 +~~~ + +The next couple of words allow for extracting portions of an +array into a new array. The subsets will be stored in the +temporary buffers. + +~~~ +: a:middle +c (afl-a) +c here push dup comma push n:inc n:add pop here fetch swap copy +c pop dup !Free s:temp +i lifepu.. +r Free +i dulica.. +r comma +i puliadad +d 1 +i polifesw +r Free +i cypoduli +r Free +i stliju.. +r s:temp + +: a:left +c (an-a) +c #0 swap a:middle +i liswliju +d 0 +r a:middle + +: a:right +c (an-a) +c over fetch over n:sub swap a:middle +i puduposw +i fe...... +i puduposw +i suswliju +r a:middle +~~~ + `allot` reserves memory. Provide it a number and it'll reserve that amount of memory. You can reclaim memory by passing in a negative value. @@ -1377,6 +1468,419 @@ i listre.. r Free ~~~ +Input tokens are whitespace delimited. This presents an issue +for strings: how to add spaces? + +The solution used here is to replace (via `s:map`) underscores +with spaces. I've been doing this now for many years, and it's +not proven to be a problem. The `sigil:'` will use the latest +`s:rewrite` it can find, so you can redefine this to make other +changes if you need to. + +~~~ +: s:rewrite +c (s-) +i liliju.. +r s:rewrite.spaces +r a:map + +: s:rewrite.spaces +i dulieqli +d 95 +r s:rewrite.replace +i liju.. +r if + +: s:rewrite.replace +i drlire.. +d 32 +~~~ + +`a:indices` returns an array with the locations of a value that +matches the passed value. `a:index` returns the first location +that matches. + +~~~ +: a:indices +c (av-a) +c reset the count +i lilist.. +d 0 +r ACount +i lifepu.. +r Free +i swlilica +d 0 +r comma +i lilica.. +r a:indices.iterate +r a:for-each +i drpolife +r Free +i puduposw +i sulisu.. +d 1 +i puduposw +i stdulica +r s:temp +i swlistre.. +r Free + +: a:indices.iterate +i puduposw +i eqlilica +r a:indices.record +r if +i liliju.. +r ACount +r v:inc + +: a:indices.record +i lifeliju +r ACount +r comma + +: a:index +c (av-n) +i lifepu.. +r Free +i lica.... +r a:indices +i lilica.. +d 0 +r a:fetch +i polistre +r Free +~~~ + +~~~ +: a:contains? +c (an-f) +i swliswli +d 0 +r a:contains?.inner +i lica.... +r a:for-each +i swdrre.. + +: a:contains?.inner +i swpu.... +i puduposw +i eqpoorre +~~~ + +`a:filter` runs a quote against each value in an array. The quote +needs to consume the value and return a single flag. If true, the +value is added to a new array. + +~~~ +: a:filter +i lifepuli +r Free +r a:filter.action +i lica.... +r curry +i lifepu.. +r Free +i puduposw +i felica.. +r comma +i lica.... +r a:for-each +i polifepu +r Free +i duposwsu +i lisupudu +d 1 +i poswst.. +i lica.... +r s:temp +i polistre +r Free + +: a:filter.action +i puduposw +i puca.... +i poswlili +r comma +r drop +i liju.... +r choose +~~~ + +~~~ +: c:lowercase? +c (c-f) $a $z n:between? ; +i lililiju +d 97 +d 122 +r n:between? + +: c:uppercase? +c (c-f) $A $Z n:between? ; +i lililiju +d 65 +d 90 +r n:between? + +: c:to-upper +c (c-c) dup c:lowercase? [ #32 n:sub ] if ; +i dulica.. +r c:lowercase? +i liliju.. +r c:to-upper.change +r if + +: c:to-upper.change +i lisure.. +d 32 + +: c:to-lower +c (c-c) dup c:uppercase? [ #32 n:add ] if ; +i dulica.. +r c:uppercase? +i liliju.. +r c:to-lower.change +r if + +: c:to-lower.change +i liadre.. +d 32 + +: c:to-s +c (c-s) '_ s:temp tuck #0 s:store ; +i lilica.. +r c:to-s.temp +r s:temp +i luca.... +r tuck +i liliju.. +d 0 +r a:store + +: c:to-s.temp +s _ + +: s:to-upper +c (s-s) [ s:dup &c:to-upper s:map s:temp ] gc +i lifepu.. +r Free +i lica.... +r a:dup +i lilica.. +r c:to-upper +r a:map +i lica.... +r s:temp +i polistre +r Free + +: s:to-lower +c (s-s) [ s:dup &c:to-lower s:map s:temp ] gc ; +i lifepu.. +r Free +i lica.... +r a:dup +i lilica.. +r c:to-lower +r a:map +i lica.... +r s:temp +i polistre +r Free +~~~ + +~~~ +: bi +c (xqq-) &sip dip call ; +i pulica.. +r sip +i poju.... + +: bi@ +c (xyq-) dup bi* ; +c using fall-through here +i du...... + +: bi* +c (xyqq-) &dip dip call ; +i pulica.. +r dip +i poju.... + +: tri +c (xqqq-) [ &sip dip sip ] dip call ; +i pulilica +r sip +r dip +i lica.... +r sip +i poju.... + + +: tri@ +c (xyzq-) dup dup tri* ; +c using fall-through here +i dudu.... + +: tri* +c (xyzqqq-) [ [ swap &dip dip ] dip dip ] dip call ; +i pupusw.. +i lilica.. +r dip +r dip +i polica.. +r dip +i poju.... + +: a:eq? +c (aa-f) &a:hash bi@ eq? ; +i lilica.. +r a:hash +r bi@ +i eqre.... + +: a:-eq? +c (aa-a) &a:hash bi@ -eq? ; +i lilica.. +r a:hash +r bi@ +i nere.... + +: a:chop +c (a-a) a:temp &v:dec sip ; +i lica.... +r s:temp +i liliju.. +r v:dec +r sip + +: a:behead +c (a-a) +c a:chop [ [ n:inc dup n:inc swap ] +c &a:length bi copy ] sip ; +i lica.... +r a:chop +i dupulili +r a:behead.inner +r a:length +i lica.... +r bi +i cypore.. + +: a:behead.inner +i liadduli +d 1 +d 1 +i adswre.. + + + +: a:first +c (a-n) #0 a:fetch ; +i liliju.. +d 0 +r a:fetch + +: a:last +c (a-n) dup a:length n:dec a:fetch ; +i dulica.. +r a:length +i lisuliju +d 1 +r a:fetch +~~~ + +~~~ +: get-index +i lilifead +r sys:buffers/loops +r Current +i re...... + +: prepare +c increment Current +i lilica.. +r Current +r v:inc +c zero out the loop counter +i lilica.. +d 0 +r get-index +i stre.... + +: cleanup +c decrement Current +i liliju.. +r Current +r v:dec + +: indexed-times.inner +i swpudupu +i ca...... +i polica.. +r get-index +i lica.... +r v:inc +i polisu.. +d 1 +i lica.... +r tuck +i linelicj +d 0 +r indexed-times.inner +i drdrre.. + +: I +c (-n) +i lica.... +r get-index +i fere.... + +: J +c (-n) +i lica.... +r get-index +i lisufere +d 1 + +: K +c (-n) +i lica.... +r get-index +i lisufere +d 2 + +: indexed-times +c (nq-) +i puduposw +i lieq.... +d 0 +i lililiju +r drop-pair +r indexed-times.run +r choose + +: indexed-times.run +i lica.... +r prepare +i lica.... +r indexed-times.inner +i liju.... +r cleanup +~~~ + +~~~ +: n:get +c (-n) +i lica.... +r s:get/token +i lica.... +r s:temp +i liju.... +r s:to-n +~~~ + ================================================================ # The main entry point @@ -1506,11 +2010,12 @@ d 0 c if not found, branch to not-found i licj.... r not-found -c if found, get the address & flags from the word -i duliadfe +c if found, get the address +i liadfe.. d 2 -i swliadfe -d 3 +c if address is negative, it's immediate +i dulilt.. +d 0 c then, based on the flags, either run it (immediate) or pass c the address to handle-word for further processing i lililiju @@ -1546,15 +2051,16 @@ c be hidden by your editor. : handle-word c (p-) c if compiling (`Compiler` set to -1), comma the address into -c the current definition. If not, call the word by falling -c through into handle-immediate. +c the current definition. If not, call the word. i lifelicj r Compiler r comma +i ju...... : handle-immediate c immediate words are always called. -i ju...... +i limuju.. +d -1 ~~~ ================================================================ @@ -1563,17 +2069,6 @@ String evaluation. I am doing this by remapping `c:get` to read input from a string instead of the keyboard. This is done to ensure that evaluation and direct entry are treated the same. -~~~ -: Source -d 0 - -: End -d 0 - -: At -d 0 -~~~ - If at the end of the input buffer, reset `c:get` to the default, then return ASCII 32 (space). @@ -1721,12 +2216,6 @@ In higher level Forth: '2147483647 s:to-n bye ~~~ -: s:Length -d 0 - -: s:Current -d 0 - : s:to-n.scale c this will adjust the current sum to get it ready for adding c the next value. Basically, just multiplying by the base (10). @@ -1782,7 +2271,6 @@ i swliliju r s:Current r v:inc - : s:to-n.process-digit c processing digits is modestly involved. I start by checking c for a few characters I want to ignore: . and , @@ -2049,6 +2537,12 @@ i drre.... c this handles backspacing. Note that this does not prevent c writing to memory before the start of the TIB. i dr...... +c check to see if the buffer is empty. If so, abort this. +i lifelieq +r sys:buffers/input +d 0 +i licj.... +r s:get.loop i lifelisu r sys:buffers/input d 1 @@ -2117,42 +2611,12 @@ i liadfere r Sigils ~~~ -`setup:sigils` populates the Sigils table with the default -implementations. This is called as part of the startup process. - ~~~ -: setup:sigils +: ) c (-) - -c # for numbers -i lililica -r sigil:# -d 35 -r sigil:set - -c : for colon definitions -i lililica -r sigil:: -d 58 -r sigil:set - -c & for pointers -i lililica -r sigil:& -d 38 -r sigil:set - -c ' for strings -i lililica -r sigil:' -d 39 -r sigil:set - i re...... ~~~ -# Stubs - ~~~ : process-data i lica.... @@ -2169,6 +2633,17 @@ i liju.... r comma ~~~ +~~~ +c The $ sigil returns the first character in a string. +: sigil:$ +c (s-c) +i lilica.. +d 0 +r a:fetch +i liju.... +r process-data +~~~ + New definitions start with a `:` sigil. This sigil creates a new dictionary header (via `d:create`), then runs `compiler:dtc` to setup a call to the `dtc` word, and finally turns the `Compiler` @@ -2178,11 +2653,11 @@ on. : sigil:: c (s-) i lica.... -r dtc -- d:create -- compiler:dtc -- compiler:on -d 0 +r d:create +i lica.... +r compiler:dtc +i liju.... +r compiler:on ~~~ Numbers are provided via the `#` sigil. This is done by @@ -2255,6 +2730,145 @@ i liadfeju d 2 ~~~ +~~~ +: sigil:@ +c (s-a) +i lica.... +r d:lookup +i lica.... +r d:address +i felife.. +r Compiler +i lililiju +r sigil:@.compile +r fetch +r choose + +: sigil:@.compile +c (a-) +i lilica.. +r lit +r comma +i lica.... +r comma +i liliju.. +r fetch +r comma +~~~ + +~~~ +: sigil:! +c (ns-) +i lica.... +r d:lookup +i lica.... +r d:address +i felife.. +r Compiler +i lililiju +r sigil:!.compile +r store +r choose + +: sigil:!.compile +c (a-) +i lilica.. +r lit +r comma +i lica.... +r comma +i liliju.. +r store +r comma +~~~ + +~~~ +: sigil:\ +c (as-) +i lica.... +r d:create +i lifelica +r Latest +r d:address +i stre.... +~~~ + +~~~ +: depths +c (-nn) (data, address) +i liiore.. +d 7 + +: depth/data +i liiodrre +d 7 + +: depth/address +i liioswdr +d 7 +i re...... +~~~ + +~~~ +: {{ +i lifeduli +r Latest +r sys:buffers/scope +i lica.... +r store-next +i stre.... + +: ---reveal--- +i lilica.. +r scope.hidden +r d:create +i lifelili +r Latest +r sys:buffers/scope +d 1 +i adstre.. + +: scope.hidden +s _ + +: }} +i lilica.. +r sys:buffers/scope +r fetch-next +i swfelica +r d:link +i stre.... +~~~ + +~~~ +: var +c (s-) +i lisw.... +d 0 +c fall through into var-n +: var-n +c (ns-) +i lica.... +r d:create +i liju.... +r comma + +: rot +c (abc-bca) +i puswposw +i re...... + +: n:between? +c (nlu-f) +i puswposw +i dupu.... +i puswposw +i puswposw +i lica.... +r n:limit +i poeqre.. +~~~ + # Compiler Compilation is mostly easy. To compile code, we needs to create @@ -2263,11 +2877,6 @@ indicates we wish to compile to true (`Compiler`), lay down a call to `dtc`, then just let `interpret` and the sigils handle the actual details of laying down the addresses. -~~~ -: Compiler -d 0 -~~~ - I define helper functions to enable and disable the `Compiler`. ~~~ @@ -2360,8 +2969,7 @@ r comma :d:create here swap @Latest comma a:hash comma - dup #4 n:add comma - #0 comma + dup #3 n:add comma !Latest ; `d:create` makes a new dictionary header. @@ -2386,15 +2994,10 @@ r comma c calculate the starting address of the word and store it i duliad.. -d 4 +d 3 i lica.... r comma -c store the default flags (0) -i lilica.. -d 0 -r comma - c finally, patch Latest (`Dictionary`) to point to the start c of this entry. i listre.. @@ -2410,51 +3013,49 @@ conditionals, some stack flow, etc. ~~~ : [ c (-a) -i lica.... -r dtc c get the current Compiler state -- compiling? +i lica.... +r compiling? c begin compiling -- compiler:on +i lica.... +r compiler:on c lay down a call to `internal:quote` -- lit +i lilica.. r quote -- comma +r comma c get a pointer to `here` for later use -- here -- tuck +i lifelica +r Free +r tuck c store a dummy value for the length. This will be patched c by `]`. -- lit +i lilica.. d 0 -- comma +r comma c use `compiler:dtc` to lay down code tostart a DTC code c sequence -- compiler:dtc -d 0 +i liju.... +r compiler:dtc : ] c (a-a) -i lica.... -r dtc c lay down a 0 to end the quote definition -- lit +i lilica.. d 0 -- comma +r comma c determine the length of the quotation -- here -- over -- n:sub -- n:dec +i life.... +r Free +i puduposw +i sulisu.. +d 1 c update the dummy length with the actual length -- swap -- store +i swst.... c reset the compiler state to whatever it was prior c to invoking `[` -- lit +i list.... r Compiler -- store c if the compiler is still on, we are nested in a c defintion. In this case, we can just drop the value c on the stack. @@ -2462,13 +3063,12 @@ c c if at the interpreter, we can just increment the c value on the stack to get a pointer to the actual c code. This gets left on the stack. -- compiling? -- lit +i lifelili +r Compiler r drop -- lit r interpreting-quote -- choose -d 0 +i liju.... +r choose : interpreting-quote i liju.... @@ -2519,8 +3119,10 @@ i drre.... : dtc:walk c get the function address (and a pointer to the next address) -i lica.... -r fetch-next +i duliadsw +d 1 +i fe...... + c check to see if we are at the end (function pointer set to c zero). If so, exit the loop. i dulieqli @@ -2546,10 +3148,10 @@ and the following "quote" under an `internal:` namespace) ~~~ : lit c (-n) -i popolica -r fetch-next -i swpuswpu -i re...... +i popoduli +d 1 +i adswfesw +i puswpure ~~~ This is exposed to the Forth dictionary as `internal:quote`. @@ -2557,11 +3159,12 @@ This is exposed to the Forth dictionary as `internal:quote`. ~~~ : quote c (-p) -i popolica -r fetch-next -i swdupuad -i poswpusw -i pure.... +i popoduli +d 1 +i adswfesw +i dupuadpo +i swpuswpu +i re...... ~~~ # Numbers @@ -2580,6 +3183,51 @@ i lisure.. d 1 ~~~ +The words in `compile:` are intended to help in writing compiler +extensions for generating ilo code words. I use them to implement +`curry`, which binds a value and function together into a new +function. + +E.g., + + #678 &n:put curry \display:678 + +~~~ +: compile:lit +c (n-) +i lilica.. +d 1 +r comma +i liju.... +r comma + +: compile:call +c (a-) +i lica.... +r compile:lit +i liliju.. +d 8 +r comma + +: compile:jump +c (a-) +i lica.... +r compile:lit +i liliju.. +d 7 +r comma + +: curry +c (vq-q) +i lifepu.. +r Free +i swlica.. +r compile:lit +i lica.... +r compile:jump +i pore.... +~~~ + # Strings In Konilo, strings are arrays containing character data. @@ -2588,13 +3236,6 @@ I provide a rotating buffer of space for temporary strings (and general arrays). In a default configuation this has space for 8 items. -It starts with a variable to track the next slot. - -~~~ -: Next-String -d 0 -~~~ - I use this along with the buffer address (the rather long `sys:buffers/strings+arrays`) to calculate an address for a temporary string. @@ -2620,24 +3261,18 @@ it to a max of 8 entries. ~~~ : s:next c (-) -i lica.... -r dtc c increment Next-String -- lit +i lilica.. r Next-String -- v:inc +r v:inc c compare Next-String to 8 -- lit +i lilifeeq d 8 -- lit r Next-String -- fetch -- eq? c if 8, use "s:adjust" to reset the counter -- lit +i liliju.. r s:adjust -- if -d 0 +r if ~~~ `s:adjust` resets the "Next-String" variable to zero. It is @@ -2658,12 +3293,13 @@ r Next-String : s:temp c (s-s) i lica.... -r dtc -- s:temp-pointer -- tuck -- a:copy -- s:next -d 0 +r s:temp-pointer +i lica.... +r tuck +i lica.... +r a:copy +i liju.... +r s:next ~~~ :data:string pop pop dup fetch-next n:add push swap push ; @@ -2686,35 +3322,33 @@ active). ~~~ : s:keep c (s-s) -i lica.... -r dtc - c compile a call to `data:string` -- lit -- data:string -- comma +i lilica.. +r data:string +r comma c get a reference to here, tuck it out of the way -- here -- swap +i lifesw.. +r Free c get the string length, store it `here` -- dup -- a:length -- comma +i dulica.. +r a:length +i lica.... +r comma c then use `a:for-each` to copy the characters to `here` -- lit +i lilica.. r comma -- a:for-each +r a:for-each c finally, if compiling, drop the pointer from the stack. (If c not compiling, we just leave it on the stack) -- compiling? -- lit +i lifelili +r Compiler r drop -- if -d 0 +r if +i ju...... ~~~ `s:append` is similar to `a:append`, but specifically uses the @@ -2723,728 +3357,1796 @@ temporary buffer memory. ~~~ : s:append c (ss-s) +i lifepu.. +r Free i lica.... -r dtc -- here -- push -- s:temp-pointer -- lit +r s:temp-pointer +i listlica r Free -- store -- s:next -- a:append -- pop -- lit +r s:next +i lica.... +r a:append +i polistre r Free -- store -d 0 : s:prepend c (ss-) i swliju.. r s:append ~~~ + + +~~~ +: block:buffer +c (-a) +i lire.... +r sys:buffers/block +~~~ + +~~~ +: e:to-line +c (n-a) #64 n:mul block:buffer n:add ; +i limuliad +d 64 +r sys:buffers/block +i re.... + +: e:line +c (n-) e:to-line #64 [ fetch-next c:put ] times drop nl ; +i lica.... +r e:to-line +i lililica +d 64 +r e:line.inner +r times +i drliju.. +r nl + +: e:line.inner +i lica.... +r fetch-next +i liju.... +r c:put + +: sep +i lica.... +r sp +i lica.... +r sp +i lica.... +r sp +i lililica +d 6 +r ed.sep.mid +r times +i lilica.. +r ed.sep.end$ +r s:put +i liju.... +r nl + +: ed.sep.mid +i liliju.. +r ed.sep.mid$ +r s:put + +: ed.sep.mid$ +s +----5---- + +: ed.sep.end$ +s +--- + +: l/n +i lica.... +r I +i duliltli +d 10 +r sp +i lica.. +r if +i lica.... +r n:put +i liju.... +r sp + +: line +i lica.... +r l/n +i lica.... +r I +i liju.... +r e:line + +: list# +: lines +i lililiju +d 16 +r line +r indexed-times + +: info +i lilica.. +r info$ +r d:lookup +i duline.. +d 0 +i lililiju +r info.action +r drop +r choose + +: info.action +i lica.... +r d:address +i feju.... + +: info$ +s sys:info + +: list* +c (-) +i lililiju +d 16 +r list*.inner +r indexed-times + +: list*.inner +i lica.... +r I +i liju.... +r e:line + +: list +c (-) +i lica.... +r sep +i lica.... +r lines +i lica.... +r sep +i liju.... +r info + +: e:Display +r list +~~~ + +~~~ +: ed.reset +c #1024 block:buffer n:dec store ; +i lililisu +d 1024 +r sys:buffers/block +d 1 +i stre.... + +: ed.constrain +c @Block #0 @Blocks n:dec n:limit !Block ; +i lifeli.. +r Block +d 0 +i lifelisu +r Blocks +d 1 +i lica.... +r n:limit +i listre.. +r Block + +: set +c (n-) !Block constrain ; +i listliju +r Block +r ed.constrain + +: save +c (-) @Block block:buffer block:save ; +i lifeli.. +r Block +r sys:buffers/block +i liju.... +r block:save + +: load +c (-) @Block block:buffer block:load reset ; +i lifeli.. +r Block +r sys:buffers/block +i lica.... +r block:load +i liju.... +r ed.reset + +: next +c (-) &Block v:inc constrain load ; +i lilica.. +r Block +r v:inc +i lica.... +r ed.constrain +i liju.... +r load + +: prev +c (-) &Block v:dec constrain load ; +i lilica.. +r Block +r v:dec +i lica.... +r ed.constrain +i liju.... +r load + +: new +c (-) #32 block:buffer #1024 fill reset ; +i lilili.. +d 32 +r sys:buffers/block +d 1024 +i lica.... +r fill +i liju.... +r ed.reset + +: edit +c (n-) set load @e:Display call ; +i lica.... +r set +i lica.... +r load +i lifeju.. +r e:Display + +: run +c (-) reset block:buffer n:dec s:evaluate ; +i lica.... +r ed.reset +i lilisu.. +r sys:buffers/block +d 1 +i liju.... +r s:evaluate + +: use +c (block) set load run ; +i lica.... +r set +i lica.... +r load +i liju.... +r run + +: using +c (first,last) over n:sub swap use [ next run ] times ; +i puduposw +i suswlica +r use +i liliju.. +r using.times +r times + +: using.times +i lica.... +r next +i liju.... +r run +~~~ + +~~~ +: s:get/line.handle +i dulieqpu +d 8 +i duposwli +d 127 +i eqorlili +r s:get/line.handle:b/s +r comma +i liju.... +r choose + +: s:get/line.handle:b/s +i dr...... +i lifelife +r Free +r s:get/line.Start +i eqlicj.. +r s:get/line.process +i liliju.. +d -1 +r allot + +: s:get/line.process +i dulieqli +d 10 +r s:get/line.process:done +i liliju.. +r s:get/line.process.handle +r choose + +: s:get/line.process:done +i drlire.. +d -1 + +: s:get/line.process.handle +i lica.... +r s:get/line.handle +i lire.... +d 0 + +: s:get/line.Start +d 0 + +: s:get/line +c (-s) +c here n:inc &s:get/line.Start store +c here [ #0 comma [ c:get process ] until ] sip +c here over n:sub n:dec over !Free swap store drop +c here s:temp ; +i lifeliad +r Free +d 1 +i list.... +r s:get/line.Start +i lifedupu +r Free +i lilica.. +d 0 +r comma +i lilica.. +r s:get/line.read +r until +i polifepu +r Free +i duposwsu +i lisupudu +d 1 +i poswlist +r Free +i swstdrli +r Free +i feliju.. +r s:temp + +: s:get/line.read +i lica.... +r c:get +i liju.... +r s:get/line.process +~~~ + +~~~ +: e:erase/line +c (n-) +c e:to-line #32 swap #64 fill ; +i lica... +r e:to-line +i liswli.. +d 32 +d 64 +i liju.... +r fill + +: e:replace +c (sn-) +c n:inc swap e:to-line over n:dec s:length copy ; +i liadsw.. +d 1 +i lica.... +r e:to-line +i puduposw +i lisulica +d 1 +r a:length +i cyre.... + +: e:replace-at +c (snn-) +c [ &e:to-line dip n:add ] dip +c [ over store n:inc ] s:for-each drop ; +i pulilica +r e:to-line +r dip +i adpolili +r e:replace-at:internal +r a:for-each +i ca...... +i drre.... + +: e:replace-at:internal +i puduposw +i stliadre +d 1 + +: e:insert +c (n"-) +c dup e:erase/line s:get/line e:replace ; +i dulica.. +r e:erase/line +i lica.... +r s:get/line +i liju.... +r e:replace + +: e:insert-at +c (nn"-) +c s:get/line e:replace-at ; +i lica.... +r s:get/line +i liju.... +r e:replace-at + +: 0 +c ("-) +i liliju.. +d 0 +r e:insert + +: 1 +c ("-) +i liliju.. +d 1 +r e:insert + +: 2 +c ("-) +i liliju.. +d 2 +r e:insert + +: 3 +c ("-) +i liliju.. +d 3 +r e:insert + +: 4 +c ("-) +i liliju.. +d 4 +r e:insert + +: 5 +c ("-) +i liliju.. +d 5 +r e:insert + +: 6 +c ("-) +i liliju.. +d 6 +r e:insert + +: 7 +c ("-) +i liliju.. +d 7 +r e:insert + +: 8 +c ("-) +i liliju.. +d 8 +r e:insert + +: 9 +c ("-) +i liliju.. +d 9 +r e:insert + +: 10 +c ("-) +i liliju.. +d 10 +r e:insert + +: 11 +c ("-) +i liliju.. +d 11 +r e:insert + +: 12 +c ("-) +i liliju.. +d 12 +r e:insert + +: 13 +c ("-) +i liliju.. +d 13 +r e:insert + +: 14 +c ("-) +i liliju.. +d 14 +r e:insert + +: 15 +c ("-) +i liliju.. +d 15 +r e:insert +~~~ + +~~~ +: . +c ("-) +c #62 [ c:get drop ] times ; +i lililiju +d 62 +r .:internal +r times + +: .:internal +i lica.... +r c:get +i drre.... +~~~ + +The basic `use` and `using` words aren't very convienient as you +need to keep track of the exact blocks to load. `needs` allows +you to use the first part of a block title line (typically a +comment for code blocks) instead. It'll scan through the block +set, running any blocks that match the provided text. E.g., to +load a block set named "(pali)": + + '(pali) needs + +Blocks are loaded in order from 0 to N, where N is the value in +`Blocks`. This can be very slow if you have a large block set or +are loading multiple sets of blocks. You may want to consider +keeping blocks towards the low end of the block set and limiting +`Blocks` before running this. + +~~~ +: needs.check +c (-f) +c block:buffer &sys:buffers/needs @Len compare ; +i lililife +r sys:buffers/block +r sys:buffers/needs +r needs.Len +i cpre.... + +: needs.setup +c (s-) +c dup s:length !Len n:inc &sys:buffers/needs @Len copy ; +i dulica.. +r a:length +i listliad +r needs.Len +d 1 +i lilifecy +r sys:buffers/needs +r needs.Len +i re...... + +: needs +c (s-) +c setup @Block [ +c @Blocks [ I set load check &run if ] indexed-times +c ] dip !Block load ; +i lica.... +r needs.setup +i lifepu.. +r Block +i lifelili +r Blocks +r needs:internal +r indexed-times +i ca...... +i polist.. +r Block +i liju.... +r load + +: needs:internal +i lica.... +r I +i lica.... +r set +i lica.... +r load +i lica.... +r needs.check +i liliju.. +r run +r if +~~~ + +For generating an index of the blocks, `titles` is provided. +This shows the block number and index line for any block with +a title line. + +~~~ +: titles +c (-) +c @Block @Blocks +c [ I set load block:buffer fetch #32 -eq? +c [ I n:put sp #64 block:buffer n:dec &store &s:put bi nl ] if +c ] indexed-times !Block load ; +i lifelife +r Block +r Blocks +i lilica.. +r titles:inner +r indexed-times +i listliju +r Block +r load + +: titles:inner +i lica.... +r I +i lica.... +r set +i lica.... +r load +i lifeline +r sys:buffers/block +d 32 +i liliju.. +r titles:display +r if + +: titles:display +i lica.... +r I +i lica.... +r n:put +i lica.... +r sp +i lililisu +d 64 +r sys:buffers/block +d 1 +i lililica +r store +r s:put +r bi +i liju.... +r nl +~~~ + +`sys:info` is called by the editor. It displays a status line below +the editor output. You can write a new `sys:info`, and the the code +will use the most recent one. + +~~~ +: sys:info +c (-) +c '___B: s:put @Block n:put $/ c:put @Blocks n:dec n:put +i lilica.. +r sys:info:B$ +r s:put +i lifelica +r Block +r n:put +i lilica.. +d 47 +r c:put +i lifelisu +r Blocks +d 1 +i lica.... +r n:put + +c '___S: s:put depth/data n:put $/ c:put #32 n:put +i lilica.. +r sys:info:S$ +r s:put +i lica.... +r depth/data +i lica.... +r n:put +i lilica.. +d 47 +r c:put +i lilica.. +d 32 +r n:put + +c '___M: s:put here n:put $/ c:put #59999 n:put nl ; +i lilica.. +r sys:info:M$ +r s:put +i lifelica +r Free +r n:put +i lilica.. +d 47 +r c:put +i lilica.. +d 59999 +r n:put + +i liju.... +r nl + +: sys:info:B$ +s B: +: sys:info:S$ +s S: +: sys:info:M$ +s M: +~~~ + +================================================================ + +The last couple of things are just to save the image and set a +startup word. The default startup word runs the code in blocks +1 and 2, then starts the editor on block 0. + +~~~ +: ~startup:process +c (n-f) +i lica.... +r set +i lica.... +r load +i lifelieq +r sys:buffers/block +d 40 +i liliju.. +r run +r if + +: prelude +i lilica.. +d 1 +r ~startup:process +i liliju.. +d 2 +r ~startup:process + +: startup +i liju.... +r prelude + +: rom:save +c (-) +i liiore.. +d 4 +~~~ + ================================================================ EOF ~~~ : ENTRY.0 d 0 -d 2088204551 -r neq? -d 0 +d 177614 +r ) : ENTRY.1 r ENTRY.0 -d 193429569 -r -if -d 0 +d -1644352334 +r ---reveal--- : ENTRY.2 r ENTRY.1 -d 177632 -r ; -d -1 +d 2088204551 +r neq? : ENTRY.3 r ENTRY.2 -d 212805696 -r ?jump -d 0 +d 193429569 +r -if : ENTRY.4 r ENTRY.3 -d 67966955 -r BaseBlock -d 0 +d 177619 +r . : ENTRY.5 r ENTRY.4 -d -1210660288 -r Compiler -d 0 +d 177621 +r 0 : ENTRY.6 r ENTRY.5 -d 1264838491 -r Latest -d 0 +d 177622 +r 1 : ENTRY.7 r ENTRY.6 -d 2089116775 -r Free -d 0 +d 5861574 +r 10 : ENTRY.8 r ENTRY.7 -d -786332176 -r Sigils -d 0 +d 5861575 +r 11 : ENTRY.9 r ENTRY.8 -d 177664 -r [ -d -1 +d 5861576 +r 12 : ENTRY.10 r ENTRY.9 -d 177666 -r ] -d -1 +d 5861577 +r 13 : ENTRY.11 r ENTRY.10 -d 1539635992 -r a:append -d 0 +d 5861578 +r 14 : ENTRY.12 r ENTRY.11 -d -294312037 -r a:copy -d 0 +d 5861579 +r 15 : ENTRY.13 r ENTRY.12 -d 251383785 -r a:dup -d 0 +d 177623 +r 2 : ENTRY.14 r ENTRY.13 -d -1119160502 -r a:fetch -d 0 +d 177624 +r 3 : ENTRY.15 r ENTRY.14 -d -1309732155 -r a:for-each -d 0 +d 177625 +r 4 : ENTRY.16 r ENTRY.15 -d -294147516 -r a:hash -d 0 +d 177626 +r 5 : ENTRY.17 r ENTRY.16 -d 1957010690 -r a:length -d 0 +d 177627 +r 6 : ENTRY.18 r ENTRY.17 -d 1526142126 -r a:prepend -d 0 +d 177628 +r 7 : ENTRY.19 r ENTRY.18 -d -674869668 -r a:reverse -d 0 +d 177629 +r 8 : ENTRY.20 r ENTRY.19 -d -1103209427 -r a:store -d 0 +d 177630 +r 9 : ENTRY.21 r ENTRY.20 -d -293712106 -r s:temp -d 0 +d 177632 +R ; : ENTRY.22 r ENTRY.21 -d 2090026588 -r a:th -d 0 +d 212805696 +r ?jump : ENTRY.23 r ENTRY.22 -d 253189153 -r allot -d 0 +d 67966955 +r BaseBlock : ENTRY.24 r ENTRY.23 -d 193486360 -r and -d 0 +d 216428464 +r Block : ENTRY.25 r ENTRY.24 -d 427330826 -r block:load -d 0 +d -1447795165 +r Blocks : ENTRY.26 r ENTRY.25 -d 427567833 -r block:save -d 0 +d -1210660288 +r Compiler : ENTRY.27 r ENTRY.26 -d 193487813 -r bye -d 0 +d 1264838491 +r Latest : ENTRY.28 r ENTRY.27 -d 253758370 -r c:get -d 0 +d 2089116775 +r Free : ENTRY.29 r ENTRY.28 -d 253768699 -r c:put -d 0 +d 177646 +r I : ENTRY.30 r ENTRY.29 -d 2090140673 -r call -d 0 +d 177647 +r J : ENTRY.31 r ENTRY.30 -d -161057562 -r choose -d 0 +d 177648 +r K : ENTRY.32 r ENTRY.31 -d 255669810 -r comma -d 0 +d -786332176 +r Sigils : ENTRY.33 r ENTRY.32 -d -748339476 -r compare -d 0 +d 177664 +R [ : ENTRY.34 r ENTRY.33 -d -1979274138 -r compiling? -d 0 +d 177666 +R ] : ENTRY.35 r ENTRY.34 -d 2090156064 -r copy -d 0 +d -296263550 +r a:-eq? : ENTRY.36 r ENTRY.35 -d 352952457 -r d:address -d 0 +d 1539635992 +r a:append : ENTRY.37 r ENTRY.36 -d 626189207 -r d:create -d 0 +d 1565438329 +r a:behead : ENTRY.38 r ENTRY.37 -d 2012546722 -r d:exists? -d 0 +d -294319702 +r a:chop : ENTRY.39 r ENTRY.38 -d -1539492880 -r d:flags -d 0 +d 63806334 +r a:contains? : ENTRY.40 r ENTRY.39 -d -176741337 -r d:hash -d 0 +d -294312037 +r a:copy : ENTRY.41 r ENTRY.40 -d -176589039 -r d:link -d 0 +d 251383785 +r a:dup : ENTRY.42 r ENTRY.41 -d 975220285 -r d:lookup -d 0 +d 251384693 +r a:eq? : ENTRY.43 r ENTRY.42 -d 193489474 -r dip -d 0 +d -1119160502 +r a:fetch : ENTRY.44 r ENTRY.43 -d 2090195226 -r drop -d 0 +d 1726883814 +r a:filter : ENTRY.45 r ENTRY.44 -d 288947475 -r drop-pair -d 0 +d -1119018392 +r a:first : ENTRY.46 r ENTRY.45 -d 193489824 -r dtc -d 0 +d -1309732155 +r a:for-each : ENTRY.47 r ENTRY.46 -d 193489870 -r dup -d 0 +d -294147516 +r a:hash : ENTRY.48 r ENTRY.47 -d -59285433 -r dup-pair -d 0 +d -1115296648 +r a:index : ENTRY.49 r ENTRY.48 -d 193490778 -r eq? -d 0 +d 917819423 +r a:indices : ENTRY.50 r ENTRY.49 -d 258875503 -r fetch -d 0 +d -294003756 +r a:last : ENTRY.51 r ENTRY.50 -d -1885660229 -r fetch-next -d 0 +d -293999829 +r a:left : ENTRY.52 r ENTRY.51 -d 2090257196 -r fill -d 0 +d 1957010690 +r a:length : ENTRY.53 r ENTRY.52 -d -1163346114 -r forever -d 0 +d -293968098 +r a:make : ENTRY.54 r ENTRY.53 -d 5863407 -r gc -d 0 +d -1751031389 +r a:make/temp : ENTRY.55 r ENTRY.54 -d 193493055 -r gt? -d 0 +d 251392926 +r a:map : ENTRY.56 r ENTRY.55 -d 260584565 -r gteq? -d 0 +d 2000526863 +r a:middle : ENTRY.57 r ENTRY.56 -d 2090324905 -r here -d 0 +d 1526142126 +r a:prepend : ENTRY.58 r ENTRY.57 -d 5863476 -r if -d 0 +d -2103488936 +r a:reduce : ENTRY.59 r ENTRY.58 -d 314257922 -r interpret -d 0 +d -674869668 +r a:reverse : ENTRY.60 r ENTRY.59 -d 5863485 -r io -d 0 +d -1104799682 +r a:right : ENTRY.61 r ENTRY.60 -d 2090414049 -r jump -d 0 +d -1103209427 +r a:store : ENTRY.62 r ENTRY.61 -d -1223977595 -r lit -d 0 +d -293712106 +r s:temp : ENTRY.63 r ENTRY.62 -d -1465379862 -r quote -d 0 +d 2090026588 +r a:th : ENTRY.64 r ENTRY.63 -d 193498500 -r lt? -d 0 +d 253189153 +r allot : ENTRY.65 r ENTRY.64 -d 266514170 -r lteq? -d 0 +d 193486360 +r and : ENTRY.66 r ENTRY.65 -d 266796867 -r n:abs -d 0 +d 5863248 +r bi : ENTRY.67 r ENTRY.66 -d 266796918 -r n:add -d 0 +d 193487226 +r bi* : ENTRY.68 r ENTRY.67 -d 266800217 -r n:dec -d 0 +d 193487248 +r bi@ : ENTRY.69 r ENTRY.68 -d 266800368 -r n:div -d 0 +d 1122748452 +r block:buffer : ENTRY.70 r ENTRY.69 -d 1637942608 -r n:divmod -d 0 +d 427330826 +r block:load : ENTRY.71 r ENTRY.70 -d 266805959 -r n:inc -d 0 +d 427567833 +r block:save : ENTRY.72 r ENTRY.71 -d -1502694228 -r n:limit -d 0 +d 193487813 +r bye : ENTRY.73 r ENTRY.72 -d 266809907 -r n:max -d 0 +d 253758370 +r c:get : ENTRY.74 r ENTRY.73 -d 266810161 -r n:min -d 0 +d -157167450 +r c:lowercase? : ENTRY.75 r ENTRY.74 -d 266810349 -r n:mod -d 0 +d 253768699 +r c:put : ENTRY.76 r ENTRY.75 -d 266810555 -r n:mul -d 0 +d 153339739 +r c:to-lower : ENTRY.77 r ENTRY.76 -d 2024000897 -r n:negate -d 0 +d -215432539 +r c:to-s : ENTRY.78 r ENTRY.77 -d 266813830 -r n:put -d 0 +d 164041342 +r c:to-upper : ENTRY.79 r ENTRY.78 -d 266817079 -r n:sub -d 0 +d 430999977 +r c:uppercase? : ENTRY.80 r ENTRY.79 -d 215056784 -r n:to-s -d 0 +d 2090140673 +r call : ENTRY.81 r ENTRY.80 -d -1486229492 -r n:zero? -d 0 +d -161057562 +r choose : ENTRY.82 r ENTRY.81 -d -494948871 -r n:-zero? -d 0 +d 255669810 +r comma : ENTRY.83 r ENTRY.82 -d 193500364 -r nip -d 0 +d -748339476 +r compare : ENTRY.84 r ENTRY.83 -d 5863647 -r nl -d 0 +d 425733796 +r compile:call : ENTRY.85 r ENTRY.84 -d 193500566 -r not -d 0 +d 426007172 +r compile:jump : ENTRY.86 r ENTRY.85 -d 5863686 -r or -d 0 +d -898142575 +r compile:lit : ENTRY.87 r ENTRY.86 -d 2090594561 -r over -d 0 +d -1979274138 +r compiling? : ENTRY.88 r ENTRY.87 -d 193502740 -r pop -d 0 +d 2090156064 +r copy : ENTRY.89 r ENTRY.88 -d -853324053 -r process-data -d 0 +d 255891066 +r curry : ENTRY.90 r ENTRY.89 -d 2090629861 -r push -d 0 +d 352952457 +r d:address : ENTRY.91 r ENTRY.90 -d 1059716234 -r restart -d 0 +d 626189207 +r d:create : ENTRY.92 r ENTRY.91 -d -127536406 -r s:append -d 0 +d 2012546722 +r d:exists? : ENTRY.93 r ENTRY.92 -d 410125037 -r a:copy -d 0 +d -176741337 +r d:hash : ENTRY.94 r ENTRY.93 -d 272730363 -r a:dup -d 0 +d -176589039 +r d:link : ENTRY.95 r ENTRY.94 -d 102250697 -r s:evaluate -d 0 +d 975220285 +r d:lookup : ENTRY.96 r ENTRY.95 -d 652426460 -r a:fetch -d 0 +d -1182620049 +r depth/address : ENTRY.97 r ENTRY.96 -d -89307369 -r a:for-each -d 0 +d -214216093 +r depth/data : ENTRY.98 r ENTRY.97 -d 704009186 -r s:get/token -d 0 +d -125438899 +r depths : ENTRY.99 r ENTRY.98 -d 410289558 -r a:hash -d 0 +d 193489474 +r dip : ENTRY.100 r ENTRY.99 -d 410401271 -r s:keep -d 0 +d 2090195226 +r drop : ENTRY.101 r ENTRY.100 -d 289838292 -r a:length -d 0 +d 288947475 +r drop-pair : ENTRY.102 r ENTRY.101 -d -1950939456 -r s:prepend -d 0 +d 193489824 +r dtc : ENTRY.103 r ENTRY.102 -d 272743435 -r s:put -d 0 +d 193489870 +r dup : ENTRY.104 r ENTRY.103 -d 143016046 -r a:reverse -d 0 +d -59285433 +r dup-pair : ENTRY.105 r ENTRY.104 -d 668377535 -r a:store -d 0 +d -572166886 +r e:Display : ENTRY.106 r ENTRY.105 -d 410724968 -r s:temp -d 0 +d 1606468171 +r e:erase/line : ENTRY.107 r ENTRY.106 -d 2090673454 -r a:th -d 0 +d 525535321 +r e:insert : ENTRY.108 r ENTRY.107 -d 410733744 -r s:to-n -d 0 +d 1191682587 +r e:insert-at : ENTRY.109 r ENTRY.108 -d -38720901 -r shift-left -d 0 +d -137453652 +r e:line : ENTRY.110 r ENTRY.109 -d -1270529650 -r shift-right -d 0 +d -1454437472 +r e:replace : ENTRY.111 r ENTRY.110 -d -1801857825 -r drop -d 0 +d 1632613378 +r e:replace-at : ENTRY.112 r ENTRY.111 -d -1801857830 -r sigil:# -d 0 +d 1440404764 +r e:to-line : ENTRY.113 r ENTRY.112 -d -1801857827 -r sigil:& -d 0 +d 2090215723 +r edit : ENTRY.114 r ENTRY.113 -d -1801857826 -r sigil:' -d 0 +d 193490778 +r eq? : ENTRY.115 r ENTRY.114 -d -1801857807 -r sigil:: -d 0 +d 258875503 +r fetch : ENTRY.116 r ENTRY.115 -d 576954903 -r sigil:get -d 0 +d -1885660229 +r fetch-next : ENTRY.117 r ENTRY.116 -d 576967971 -r sigil:set -d 0 +d 2090257196 +r fill : ENTRY.118 r ENTRY.117 -d 193505809 -r sip -d 0 +d -1163346114 +r forever : ENTRY.119 r ENTRY.118 -d 5863816 -r sp -d 0 +d 5863407 +r gc : ENTRY.120 r ENTRY.119 -d 274826578 -r store -d 0 +d 193493055 +r gt? : ENTRY.121 r ENTRY.120 -d 1976567422 -r store-next -d 0 +d 260584565 +r gteq? : ENTRY.122 r ENTRY.121 -d 2090739264 -r swap -d 0 +d 2090324905 +r here : ENTRY.123 r ENTRY.122 -d -1371592987 -r sys:buffers/block -d 0 +d 5863476 +r if : ENTRY.124 r ENTRY.123 -d -1359625529 -r sys:buffers/loops -d 0 +d 123652725 +r indexed-times : ENTRY.125 r ENTRY.124 -d 942827360 -r sys:buffers/numeric-conversion -d 0 +d -1223977595 +r lit : ENTRY.126 r ENTRY.125 -d -1351755340 -r sys:buffers/scope -d 0 +d -1465379862 +r quote : ENTRY.127 r ENTRY.126 -d -1357624343 -r sys:buffers/needs -d 0 +d 314257922 +r interpret : ENTRY.128 r ENTRY.127 -d 1106725658 -r sys:buffers/reserved -d 0 +d 5863485 +r io : ENTRY.129 r ENTRY.128 -d 1438625409 -r sys:buffers/strings+arrays -d 0 +d 2090414049 +r jump : ENTRY.130 r ENTRY.129 -d -1363217974 -r sys:buffers/input -d 0 +d 2090473057 +r list : ENTRY.131 r ENTRY.130 -d 193506620 -r tab -d 0 +d 266134180 +r list# : ENTRY.132 r ENTRY.131 -d 275614599 -r times -d 0 +d 266134187 +r list* : ENTRY.133 r ENTRY.132 -d 2090773084 -r tuck -d 0 +d 2090478981 +r load : ENTRY.134 r ENTRY.133 -d 276987953 -r until -d 0 +d 193498500 +r lt? : ENTRY.135 r ENTRY.134 -d 276287585 -r v:dec -d 0 +d 266514170 +r lteq? : ENTRY.136 r ENTRY.135 -d 276293327 -r v:inc -d 0 +d -494948871 +r n:-zero? : ENTRY.137 r ENTRY.136 -d 279132286 -r while -d 0 +d 266796867 +r n:abs : ENTRY.138 r ENTRY.137 +d 266796918 +r n:add +: ENTRY.139 +r ENTRY.138 +d 1032861494 +r n:between? +: ENTRY.140 +r ENTRY.139 +d 266800217 +r n:dec +: ENTRY.141 +r ENTRY.140 +d 266800368 +r n:div +: ENTRY.142 +r ENTRY.141 +d 1637942608 +r n:divmod +: ENTRY.143 +r ENTRY.142 +d 266803501 +r n:get +: ENTRY.144 +r ENTRY.143 +d 266805959 +r n:inc +: ENTRY.145 +r ENTRY.144 +d -1502694228 +r n:limit +: ENTRY.146 +r ENTRY.145 +d 266809907 +r n:max +: ENTRY.147 +r ENTRY.146 +d 266810161 +r n:min +: ENTRY.148 +r ENTRY.147 +d 266810349 +r n:mod +: ENTRY.149 +r ENTRY.148 +d 266810555 +r n:mul +: ENTRY.150 +r ENTRY.149 +d 2024000897 +r n:negate +: ENTRY.151 +r ENTRY.150 +d 266813830 +r n:put +: ENTRY.152 +r ENTRY.151 +d 266817079 +r n:sub +: ENTRY.153 +r ENTRY.152 +d 215056784 +r n:to-s +: ENTRY.154 +r ENTRY.153 +d -1486229492 +r n:zero? +: ENTRY.155 +r ENTRY.154 +d 268346580 +r needs +: ENTRY.156 +r ENTRY.155 +d 193500239 +r new +: ENTRY.157 +r ENTRY.156 +d 2090540740 +r next +: ENTRY.158 +r ENTRY.157 +d 193500364 +r nip +: ENTRY.159 +r ENTRY.158 +d 5863647 +r nl +: ENTRY.160 +r ENTRY.159 +d 193500566 +r not +: ENTRY.161 +r ENTRY.160 +d 5863686 +r or +: ENTRY.162 +r ENTRY.161 +d 2090594561 +r over +: ENTRY.163 +r ENTRY.162 +d 193502740 +r pop +: ENTRY.164 +r ENTRY.163 +d -1031328682 +r prelude +: ENTRY.165 +r ENTRY.164 +d 2090626146 +r prev +: ENTRY.166 +r ENTRY.165 +d -853324053 +r process-data +: ENTRY.167 +r ENTRY.166 +d 2090629861 +r push +: ENTRY.168 +r ENTRY.167 +d 1059716234 +r restart +: ENTRY.169 +r ENTRY.168 +d 337707900 +r rom:save +: ENTRY.170 +r ENTRY.169 +d 193504922 +r rot +: ENTRY.171 +r ENTRY.170 +d 193505114 +r run +: ENTRY.172 +r ENTRY.171 +d 408173524 +r a:-eq? +: ENTRY.173 +r ENTRY.172 +d -127536406 +r s:append +: ENTRY.174 +r ENTRY.173 +d -101734069 +r a:behead +: ENTRY.175 +r ENTRY.174 +d 410117372 +r a:chop +: ENTRY.176 +r ENTRY.175 +d 1683118608 +r a:contains? +: ENTRY.177 +r ENTRY.176 +d 410125037 +r a:copy +: ENTRY.178 +r ENTRY.177 +d 272730363 +r a:dup +: ENTRY.179 +r ENTRY.178 +d 272731271 +r a:eq? +: ENTRY.180 +r ENTRY.179 +d 102250697 +r s:evaluate +: ENTRY.181 +r ENTRY.180 +d 652426460 +r a:fetch +: ENTRY.182 +r ENTRY.181 +d 59711416 +r a:filter +: ENTRY.183 +r ENTRY.182 +d 652568570 +r a:first +: ENTRY.184 +r ENTRY.183 +d -89307369 +r a:for-each +: ENTRY.185 +r ENTRY.184 +d -369411895 +r s:get/line +: ENTRY.186 +r ENTRY.185 +d 704009186 +r s:get/token +: ENTRY.187 +r ENTRY.186 +d 410289558 +r a:hash +: ENTRY.188 +r ENTRY.187 +d 1735582460 +r a:index +: ENTRY.189 +r ENTRY.188 +d 1735705137 +r a:indices +: ENTRY.190 +r ENTRY.189 +d 410401271 +r s:keep +: ENTRY.191 +r ENTRY.190 +d 410433318 +r a:last +: ENTRY.192 +r ENTRY.191 +d 410437245 +r a:left +: ENTRY.193 +r ENTRY.192 +d 289838292 +r a:length +: ENTRY.194 +r ENTRY.193 +d 272739504 +r a:map +: ENTRY.195 +r ENTRY.194 +d 333354465 +r a:middle +: ENTRY.196 +r ENTRY.195 +d -1950939456 +r s:prepend +: ENTRY.197 +r ENTRY.196 +d 272743435 +r s:put +: ENTRY.198 +r ENTRY.197 +d 524305962 +r a:reduce +: ENTRY.199 +r ENTRY.198 +d 143016046 +r a:reverse +: ENTRY.200 +r ENTRY.199 +d 144659380 +r s:rewrite +: ENTRY.201 +r ENTRY.200 +d 666787280 +r a:right +: ENTRY.202 +r ENTRY.201 +d 668377535 +r a:store +: ENTRY.203 +r ENTRY.202 +d 410724968 +r s:temp +: ENTRY.204 +r ENTRY.203 +d 2090673454 +r a:th +: ENTRY.205 +r ENTRY.204 +d 1238161771 +r s:to-lower +: ENTRY.206 +r ENTRY.205 +d 410733744 +r s:to-n +: ENTRY.207 +r ENTRY.206 +d 1248863374 +r s:to-upper +: ENTRY.208 +r ENTRY.207 +d 2090715988 +r save +: ENTRY.209 +r ENTRY.208 +d 193505681 +r set +: ENTRY.210 +r ENTRY.209 +d -38720901 +r shift-left +: ENTRY.211 +r ENTRY.210 +d -1270529650 +r shift-right +: ENTRY.212 +r ENTRY.211 +d -1801857832 +r sigil:! +: ENTRY.213 +r ENTRY.212 +d -1801857830 +r sigil:# +: ENTRY.214 +r ENTRY.213 +d -1801857829 +r sigil:$ +: ENTRY.215 +r ENTRY.214 +d -1801857827 +r sigil:& +: ENTRY.216 +r ENTRY.215 +d -1801857826 +r sigil:' +: ENTRY.217 +r ENTRY.216 +d -1801857825 +r drop +: ENTRY.218 +r ENTRY.217 +d -1801857807 +r sigil:: +: ENTRY.219 +r ENTRY.218 +d -1801857801 +r sigil:@ +: ENTRY.220 +r ENTRY.219 +d -1801857773 +r sigil:\ +: ENTRY.221 +r ENTRY.220 +d 576954903 +r sigil:get +: ENTRY.222 +r ENTRY.221 +d 576967971 +r sigil:set +: ENTRY.223 +r ENTRY.222 +d 193505809 +r sip +: ENTRY.224 +r ENTRY.223 +d 5863816 +r sp +: ENTRY.225 +r ENTRY.224 +d -1378149864 +r startup +: ENTRY.226 +r ENTRY.225 +d 274826578 +r store +: ENTRY.227 +r ENTRY.226 +d 1976567422 +r store-next +: ENTRY.228 +r ENTRY.227 +d 2090739264 +r swap +: ENTRY.229 +r ENTRY.228 +d -1371592987 +r sys:buffers/block +: ENTRY.230 +r ENTRY.229 +d -1363217974 +r sys:buffers/input +: ENTRY.231 +r ENTRY.230 +d -1359625529 +r sys:buffers/loops +: ENTRY.232 +r ENTRY.231 +d -1357624343 +r sys:buffers/needs +: ENTRY.233 +r ENTRY.232 +d 942827360 +r sys:buffers/numeric-conversion +: ENTRY.234 +r ENTRY.233 +d 1106725658 +r sys:buffers/reserved +: ENTRY.235 +r ENTRY.234 +d -1351755340 +r sys:buffers/scope +: ENTRY.236 +r ENTRY.235 +d 1438625409 +r sys:buffers/strings+arrays +: ENTRY.237 +r ENTRY.236 +d 1558645459 +r sys:buffers/variables +: ENTRY.238 +r ENTRY.237 +d 270722346 +r sys:info +: ENTRY.239 +r ENTRY.238 +d 193506620 +r tab +: ENTRY.240 +r ENTRY.239 +d 275614599 +r times +: ENTRY.241 +r ENTRY.240 +d 505606010 +r titles +: ENTRY.242 +r ENTRY.241 +d 193507188 +r tri +: ENTRY.243 +r ENTRY.242 +d 2090769950 +r tri* +: ENTRY.244 +r ENTRY.243 +d 2090769972 +r tri@ +: ENTRY.245 +r ENTRY.244 +d 2090773084 +r tuck +: ENTRY.246 +r ENTRY.245 +d 276987953 +r until +: ENTRY.247 +r ENTRY.246 +d 193508306 +r use +: ENTRY.248 +r ENTRY.247 +d 277155819 +r using +: ENTRY.249 +r ENTRY.248 +d 276287585 +r v:dec +: ENTRY.250 +r ENTRY.249 +d 276293327 +r v:inc +: ENTRY.251 +r ENTRY.250 +d 193508814 +r var +: ENTRY.252 +r ENTRY.251 +d 277702537 +r var-n +: ENTRY.253 +r ENTRY.252 +d 279132286 +r while +: ENTRY.254 +r ENTRY.253 d 193511454 r xor -d 0 +: ENTRY.255 +r ENTRY.254 +d 5864091 +r {{ +: ENTRY.256 +r ENTRY.255 +d 5864159 +r }} : Latest -r ENTRY.138 +r ENTRY.256 : FREE-SPACE ~~~