go to the table of contents or go back home

in collapse os, an integer can have any value between -32768 and 32767
signed, or 0 and 65535 unsigned. if you want to work with larger numbers,
there are *probably* ways to get around it, but the os doesn't
seem to have much built-in support for things like double-length integers.

collapse os has several words that treat numbers as unsigned, where most other forths would treat them as signed. from a practical standpoint, this means that / [slash, for division] and many of the comparison operators may not work as you expect when handling negative numbers. in the arithmetic and comparison sections below, we'll show you our attempts at making words that work around this.

the aforementioned maximum integer, 65535, is equivalent to FFFF in hexadecimal. collapse os doesn't have a distinct "hex mode" like many forths do, but you can work with hex numbers fairly easily. when typing a hex number, precede it with a $ [dollar sign] so it won't be confused for either a decimal number or a word, like so: $FFFF. if you want to print a number off the stack, use . [dot] to print it in decimal, or .X [dot x] to print it in hexadecimal.

in addition to the usual + plus, - minus, * times, and / divided-by operators, here are some other ones collapse os has:

-^ [minus caret] | ( n1 n2 -- diff ) | n2 minus n1 |

MOD | ( n1 n2 -- rem ) | n1 mod n2 (the remainder of n1 divided by n2) |

/MOD [slash mod] | ( n1 n2 -- rem quot ) | the quotient and remainder of n1 divided by n2 |

to make a division operator that handles negative numbers as you probably expect it to (see the previous section):

: ABS DUP 0< IF -1 * THEN ; ( n -- |n| ) : 2ABS ABS SWAP ABS SWAP ; ( n1 n2 -- |n1| |n2| ) : ?DIFF-SIGNS 0< SWAP 0< XOR ; ( n1 n2 -- f ) : DIVIDE 2DUP 2ABS / ROT> ?DIFF-SIGNS IF -1 * THEN ; ( n1 n2 -- quot ) ( take the absolute value of both numbers before dividing. if only one of the two was negative, multiply the result by -1 to undo the absolute- value-ing. )

fun fact, ?DIFF-SIGNS is re-used from our solution to a similar problem with comparison operators.

see the "Paramater Stack" section in collapse os's doc/dict.txt. note that ROT> [rot greater-than] is the same as what's called -ROT [minus rot] in some other forths.

if you're following along with starting forth, chapter 2 has you solve some problems that expect you to use 2SWAP and 2OVER. given that collapse os does not have these words, you can solve these using the return stack, which is introduced in chapter 5. if you'd like to solve them now, here's a 2SWAP and a 2OVER you can use:

: 2SWAP >R ROT> R> ROT> ; ( d1 d2 -- d2 d1 ) : 2OVER 2>R 2DUP 2R> 2SWAP ; ( d1 d2 -- d1 d2 d1 )

see the "Logic" section in collapse os's doc/dict.txt. note that the
flag returned will be 1 for true or 0 for false, whereas many forths use
*negative* 1 for true.

using 0< [zero less-than], you can make comparison operators that will always state a positive number is greater than a negative number (because the built-in ones treat numbers as unsigned). here's our go at it:

: ?DIFF-SIGNS 0< SWAP 0< XOR ; ( n1 n2 -- f ) ( check whether n1 or n2, but not both, is negative ) : GT DUP ?DIFF-SIGNS IF DROP 0< IF 0 ELSE 1 THEN ELSE > THEN ; ( n1 n2 -- f ) ( if n1 and n2 have different signs, check which one is the negative number and say that one is lesser. if they have the same sign, use the built-in greater-than operator ) : LT DUP ?DIFF-SIGNS IF DROP 0< IF 1 ELSE 0 THEN ELSE < THEN ; ( n1 n2 -- f ) ( similar to GT, but the 0 and 1 are switched, and the > is changed to a < ) : GTE 2DUP GT ROT> = OR ; ( n1 n2 -- f ) : LTE 2DUP LT ROT> = OR ; ( n1 n2 -- f ) ( greater-than/less-than or equal )

block 120 includes some "useful little words" that aren't included
in collapse os's basic dictionary, but can be used after loading them
with `120 LOAD`

. there are definitions for MIN and MAX
included there, but since they use the built-in greater- and less-than
operators, they also might tell you a negative number is greater than
a positive one. to change this, just replace the greater-than and
less-than symbols in them with your new GT and LT words.

if you're typing a word definition into the command line and you get a "br ovfl" (buffer overflow) when you're finished, it could be because there's a mismatched number of IFs and THENs or DOs and LOOPs in what you typed.

some forths have ?DO [question-mark do], meaning "do only if the given number of iterations is greater than 0", and +LOOP [plus loop], which takes a number to increase the loop counter by rather than just increasing it by one. collapse os does not. as far as we can figure, to get the behavior of question-mark do, you just have to enclose a regular DO in an if-statement. for plus loop, it's probably easier to just use a BEGIN/UNTIL instead. we might put together some examples to get a better idea.

to exit the current word being executed, you can use ABORT. if you'd
like to include an error message along with your abort, use ABORT" [abort
quote]—like dot-quote, it prints the following text up to a closing
quotation mark. note that abort-quote does *not* take anything off
the stack, whereas some forths have it take a flag.

go to part 3 or go to the table of contents