UrForth: more words
[urasm.git] / dox / urforth.txt
blobecca025cf4d934d2dc7e554d968e5b81c98a8577
1 proper documentation will follow... maybe.
2 but please, read this document if you want to use UrForth.
3 UrForth is not a standard Forth system (it is a mixture of ANS, FIG,
4 and my own creations), and this document contains valuable bits of
5 knowledge about some non-standard UrForth features.
7 one of the non-standard UrForth features is locals support. it is
8 done like this:
9   : myword  ( a b -- c )
10     args: a b
11     locals: loc1 loc2
13     :a TO :loc1
14     :b TO :loc2
15     :loc1 :loc2 +
16   ;
17 here, "args:" will declare local variables, and automatically fill them
18 with arguments from the data stack. "locals:" declare "free" locals.
19 there can be more than one "locals:" section, but all such sections should
20 come before anything else. to use local, you must prepend its name with a
21 colon. the usual "TO" word is used to set local values.
23 "DOES>" works only on CREATEd words.
25 some global variables are state-local. also, each state has its own TIB,
26 independent of other states.
28 state-local vars are:
29 BASE
30 ( -- base-addr )
31 current number base.
33 TIB
34 ( -- addr )
35 current TIB.
37 >IN
38 ( -- ofs )
39 offset in current TIB.
41 (STD-TIB-ADDR)
42 ( -- )
43 default TIB address. WARNING! if this user var contains a handle, that
44 handle will be freed on destroying the task. if you want to replace the
45 default TIB, make sure that you will free the old handle (if it is a handle).
47 (USER-VAR-USED)
48 ( -- uvar-used-addr )
49 address of the variable contains first free user area address.
51 (USER-VAR-ADDR)
52 ( -- uvar-begin-addr )
53 start address of the user area.
55 (USER-VAR-SIZE)
56 ( -- uvar-size )
57 maximum user area size in bytes.
61 DEBUG:DUMP-STACK
62 ( -- )
63 dump data stack
65 DEBUG:BACKTRACE
66 ( -- )
67 show current backtrace (slow!)
69 DEBUG:DECOMPILE name
70 ( -- )
71 decompile given forth word.
73 SP0!
74 ( -- )
75 clear data stack.
77 RP0!
78 ( -- )
79 clear return stack.
81 PAD
82 ( -- pad )
83 return PAD address. this is area that can be used for storing
84 temporary values. you can assume to have at least 4096 bytes there.
85 WARNING! some words may use PAD for their own needs. this is mostly
86          words which need to create some temporary strings.
89 note that address for memory operations may be a handle too. with handles,
90 low bits are used as offset, so you can directly address some bytes in handle
91 data area. currently, low 12 bits are reserved for offset, so you can address
92 4096 bytes inside a handle. but don't hardcode it, use "FORTH:(MAX-HANDLE-OFS)"
93 constant to get the maximum allowed offset (because it may change in the future).
95 also, UrForth is 32-bit system, and stores all numbers as little-endian. this
96 will not change, so you can write your code without checking cell size, or
97 byte order.
101 ( addr -- value8 )
102 load 8-bit value.
105 ( addr -- value16 )
106 load 16-bit value.
109 ( addr -- value32 )
110 load 32-bit value.
113 ( val8 addr -- )
114 store 8-bit value.
117 ( val16 addr -- )
118 store 16-bit value.
121 ( val32 addr -- )
122 store 32-bit value.
125 ( val8 -- )
126 compile 8-bit value.
129 ( val16 -- )
130 compile 16-bit value.
133 ( val -- )
134 compile 32-bit value.
137 (LIT)
138 ( -- n )
139 read 4 bytes immediately following this word, and push them
140 to the data stack. adjust IP to skip those bytes.
142 (LITCFA)
143 ( -- n )
144 read 4 bytes immediately following this word, and push them
145 to the data stack. adjust IP to skip those bytes. this is
146 the same as "(LIT)", but used to store CFAs of words. using
147 different words for different data types helps the debugger
148 and the decompiler.
150 (LITVOCID)
151 ( -- n )
152 the same as "(LIT)", but for vocids.
154 (LITSTR8)
155 ( -- addr count )
156 inline byte-counted string literal. note that the string
157 always have a trailing zero byte (which is not counted),
158 and always padded so it ends on a 4-byte boundary.
160 (BRANCH) ( -- )
161 read next 4 bytes, and set IP to that address.
163 (TBRANCH)
164 ( flag -- )
165 skip next 4 bytes if `flag` is 0, otherwise perform "(BRANCH)".
167 (0BRANCH)
168 ( flag -- )
169 skip next 4 bytes if `flag` is not 0, otherwise perform "(BRANCH)".
171 (+0BRANCH)
172 ( num -- )
173 skip next 4 bytes if `num` is positive or 0, otherwise perform "(BRANCH)".
175 (+BRANCH)
176 ( num -- )
177 skip next 4 bytes if `num` is positive (but not 0), otherwise perform "(BRANCH)".
179 (-BRANCH)
180 ( num -- )
181 skip next 4 bytes if `num` is negative, otherwise perform "(BRANCH)".
183 EXECUTE
184 ( cfa )
185 pop word CFA address, and execute it.
187 EXECUTE-TAIL
188 ( cfa )
189 pop word CFA address, and execute it. returning from the executed
190 word will return to the upper word. i.e. this performs a tail call.
193 (EXIT)
194 internal compiler word, placed at the end of colon definition.
195 pops a number from return stack, and sets IP to that number.
197 (L-ENTER)
198 this word is used to implement local variables and arguments.
199 it doesn't matter how it works, you should not used it anyway.
200 read the source code, if you're curious.
202 (L-LEAVE)
203 this word is used to implement local variables and arguments.
204 it doesn't matter how it works, you should not used it anyway.
205 read the source code, if you're curious.
207 (LOCAL@)
208 ( idx -- value )
209 read local variable with the given index. indices are 1-based.
211 (LOCAL!)
212 ( value idx -- )
213 write local variable with the given index. indices are 1-based.
216 ( n -- n n )
217 duplicates a number on the data stack.
219 ?DUP
220 ( n -- n n ) | ( 0 -- 0 )
221 duplicates a number on the data stack, but only if that number is not 0.
223 2DUP
224 ( n0 n1 -- n0 n1 n0 n1 )
226 DROP
227 ( n -- )
229 2DROP
230 ( n0 n1 -- )
232 SWAP
233 ( n0 n1 -- n1 n0 )
235 2SWAP
236 ( n0 n1 -- n1 n0 )
238 OVER
239 ( n0 n1 -- n0 n1 n0 )
241 2OVER
242 ( n0 n1 -- n0 n1 n0 )
245 ( n0 n1 n2 -- n1 n2 n0 )
247 NROT
248 ( n0 n1 n2 -- n2 n0 n1 )
251 ( a b -- b )
253 TUCK
254 ( a b -- b a b )
256 RDUP
257 ( n -- n n )
258 the same as "DUP", but for the return stack.
260 RDROP
261 ( n -- )
262 the same as "DROP", but for the return stack.
264 RSWAP
265 ( n0 n1 -- n1 n0 )
266 the same as "SWAP", but for the return stack.
268 ROVER
269 ( n0 n1 -- n0 n1 n0 )
270 the same as "OVER", but for the return stack.
272 RROT
273 ( n0 n1 n2 -- n1 n2 n0 )
274 the same as "ROT", but for the return stack.
276 RNROT
277 ( n0 n1 n2 -- n2 n0 n1 )
278 the same as "NROT", but for the return stack.
281 ( n -- | n )
282 move number from the data stack to the return stack.
285 ( | n -- n )
286 move number from the return stack to the data stack.
289 ( | n -- n | n )
290 copy number from the return stack to the data stack.
292 PICK
293 ( idx -- n )
294 copy n-th element at the data stack. "0 PICK" is the same as "DUP".
296 RPICK
297 ( idx -- n )
298 the same as "PICK", but for the return stack.
300 ROLL
301 ( idx -- n )
302 move n-th element at the data stack to the top. "1 ROLL" is the same as "SWAP".
304 RROLL
305 ( idx -- n )
306 the same as "ROLL", but for the return stack.
308 REFILL
309 ( -- eofflag )
310 read next input line. can cross include boundaries. pushes 0 if
311 there are no more input lines. TIB contents is undefined in this case.
313 REFILL-NOCROSS
314 ( -- eofflag )
315 read next input line. cannot cross include boundaries. pushes 0 if
316 there are no more input lines. TIB contents is undefined in this case.
318 (TIB-IN)
319 ( -- addr )
320 get address of the current TIB position.
321 WARNING! do not try to emulate "TIB-GETCH" and such with this word!
322          TIB usually ends with 0 byte, and if you will advance beyond
323          that 0, Bad Things will happen.
325 TIB-PEEKCH
326 ( -- char )
327 push current TIB char, do not advance >IN.
329 TIB-PEEKCH-OFS
330 ( ofs -- char )
331 peek TIB char with the given offset. "0 TIB-PEEKCH-OFS" is the same as "TIB-PEEKCH".
333 TIB-GETCH
334 ( -- char )
335 push current TIB char, advance >IN. it is safe to call this even
336 when you reached the end of TIB. in this case, returned char code
337 will be 0. i.e. "0" means "end of TIB".
339 TIB-SKIPCH
340 ( -- )
341 skip current TIB char. it is safe to call this even when you reached
342 the end of TIB.
345 (PARSE)
346 ( delim skip-leading-delim? -- addr count TRUE / FALSE )
347 does base TIB parsing; never copies anything.
348 as our reader is line-based, returns FALSE on EOL.
349 EOL is detected after skipping leading delimiters.
350 passing -1 as delimiter skips the whole line, and always returns FALSE.
351 finishing delimiter is always skipped.
353 PARSE-SKIP-BLANKS
354 ( -- )
355 skip all chars with codes <=32.
357 (PARSE-SKIP-COMMENTS)
358 ( allow-multiline? -- )
359 skip all blanks and comments. if multiline skip is not allowed, reaching
360 end of TIB while still waiting for the comment terminator is error.
361 single-line comments are ok, though.
363 PARSE-SKIP-LINE
364 ( -- )
365 advance >IN to the end of TIB.
367 PARSE-NAME
368 ( -- addr count )
369 parse with leading blanks skipping. doesn't copy anything.
370 return empty string on EOL.
372 PARSE
373 ( delim -- addr count TRUE / FALSE )
374 parse without skipping delimiters; never copies anything.
375 as our reader is line-based, returns FALSE on EOL.
376 passing 0 as delimiter skips the whole line, and always returns FALSE.
377 finishing delimiter is always skipped.
379 EMIT
380 ( n -- )
381 print char.
383 XEMIT
384 ( n -- )
385 "safe" char printer. all non-printable chars (including newline and such)
386 will be printed as "?".
388 LASTCR?
389 ( -- bool )
390 was last printed char a newline?
392 LASTCR!
393 ( bool -- )
394 force-set the flag for "LASTCR?" word.
397 ( -- )
398 print newline.
400 SPACE
401 ( -- )
402 print space.
404 SPACES
405 ( n -- )
406 print `n` spaces. if `n` is negative, prints nothing.
408 ENDCR
409 ( -- )
410 prints newline if the last printed char was not a newline.
412 TYPE
413 ( addr count -- )
414 print the string. negative count is ok, in this case the word prints nothing.
416 XTYPE
417 ( addr count -- )
418 the same as "TYPE", but uses "XEMIT".
420 FLUSH-EMIT
421 ( -- )
422 output can be buffered. it usually flushed when newline is printed, but
423 you can flush it manually using this word.
426 ( a b -- a+b )
429 ( a b -- a-b )
432 ( a b -- a*b )
435 ( a b -- a*b )
438 ( a b -- a/b )
441 ( a b -- a/b )
444 ( a b -- a%b )
446 UMOD
447 ( a b -- a%b )
449 /MOD
450 ( a b -- a/b, a%b )
451 note that the results are swaped, contrary to ANS idiocity.
452 i don't fuckin' know why ANS morons decided to make the stack
453 effect that contradicts the word name. "/MOD" clearly indicates
454 that quotient comes first.
456 U/MOD
457 ( a b -- a/b, a%b )
458 note that the results are swaped, contrary to ANS idiocity.
459 i don't fuckin' know why ANS morons decided to make the stack
460 effect that contradicts the word name. "/MOD" clearly indicates
461 that quotient comes first.
464 ( a b c -- a*b/c )
465 this uses 64-bit intermediate value.
468 ( a b c -- a*b/c )
469 this uses 64-bit intermediate value.
471 */MOD
472 ( a b c -- a*b/c a*b%c )
473 this uses 64-bit intermediate value.
474 note that the results are swaped, contrary to ANS idiocity.
475 i don't fuckin' know why ANS morons decided to make the stack
476 effect that contradicts the word name. "/MOD" clearly indicates
477 that quotient comes first.
480 ( a b c -- a*b/c )
481 this uses 64-bit intermediate value.
484 ( a b -- lo(a*b) hi(a*b) )
485 this leaves 64-bit result.
488 ( a b -- lo(a*b) hi(a*b) )
489 this leaves 64-bit result.
491 M/MOD
492 ( alo ahi b -- a/b a%b )
493 note that the results are swaped, contrary to ANS idiocity.
494 i don't fuckin' know why ANS morons decided to make the stack
495 effect that contradicts the word name. "/MOD" clearly indicates
496 that quotient comes first.
498 UM/MOD
499 ( alo ahi b -- a/b a%b )
500 note that the results are swaped, contrary to ANS idiocity.
501 i don't fuckin' know why ANS morons decided to make the stack
502 effect that contradicts the word name. "/MOD" clearly indicates
503 that quotient comes first.
506 ( a b -- a<b )
509 ( a b -- a<b )
512 ( a b -- a>b )
515 ( a b -- a>b )
518 ( a b -- a<=b )
521 ( a b -- a<=b )
524 ( a b -- a>=b )
527 ( a b -- a>=b )
530 ( a b -- a=b )
533 ( a b -- a<>b )
536 ( a -- !a )
538 LAND
539 ( a b -- a&&b )
540 logical "and".
543 ( a b -- a||b )
544 logical "or".
547 ( a b -- a&b )
548 bitwise "and".
551 ( a b -- a|b )
552 bitwise "or".
555 ( a b -- a^b )
556 bitwise "xor".
558 BITNOT
559 ( a -- ~a )
562 ( u -- u*2 )
565 ( u -- u*2 )
568 ( u -- u*4 )
571 ( u -- u*4 )
574 ( n count -- )
575 arithmetic shift; positive `n` shifts to the left.
578 ( n count -- )
579 logical shift; positive `n` shifts to the left.
581 COMPILER:(UNESCAPE)
582 ( addr count -- addr new-count )
583 process string escapes. modifies string in-place. the resulting string is
584 never bigger than the source one. negative counts are allowed.
586 (BASED-NUMBER)
587 ( addr count allowsign? base -- num TRUE / FALSE )
588 tries to convert the given string to the number, using the given
589 default base. if "allowsign?" is non-zero, properly process leading
590 number sign. this words understands numbers in non-default bases too
591 (like "0x29a", for example).
595 switch to interpretation mode.
598 switch to compilation mode.
600 (CREATE-WORD-HEADER)
601 ( addr count word-flags -- )
602 create word header in the dictionary, link word to the current vocabulary.
603 doesn't create CFA.
605 (CREATE-NAMELESS-WORD-HEADER)
606 ( word-flags -- )
607 create nameless word header in the dictionary, link word to the current vocabulary.
608 doesn't create CFA.
610 FIND-WORD
611 ( addr count -- cfa TRUE / FALSE)
612 general word finder. checks wordlist stack, performs colon resolution.
614 (FIND-WORD-IN-VOC)
615 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
616 find word in the given wordlist. does no name resolution, and
617 doesn't look in parent wordlists.
619 FIND-WORD-IN-VOC
620 ( addr count vocid -- cfa TRUE / FALSE)
621 find word in the given wordlist. does no name resolution, and
622 doesn't look in parent wordlists. skips hidden words.
624 (FIND-WORD-IN-VOC-AND-PARENTS)
625 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
626 find word in the given wordlist. does no name resolution, but searches
627 parent wordlists if "vocid" is nested.
629 FIND-WORD-IN-VOC-AND-PARENTS
630 ( addr count vocid -- cfa TRUE / FALSE)
631 find word in the given wordlist. does no name resolution, but searches
632 parent wordlists if "vocid" is nested. skips hidden words.
634 COMPILER:?EXEC
635 check if we are in interpretation mode, and throws an error if we aren't.
637 COMPILER:?COMP
638 check if we are in compilation mode, and throws an error if we aren't.
641 string literal.
643 (VSP@)
644 ( -- vsp )
645 this word is used internally to work with wordlist stack.
647 (VSP!)
648 ( vsp -- )
649 this word is used internally to work with wordlist stack.
651 (VSP-AT@)
652 ( idx -- value )
653 this word is used internally to work with wordlist stack.
655 (VSP-AT!)
656 ( value idx -- )
657 this word is used internally to work with wordlist stack.
659 CFA->PFA
660 ( cfa -- pfa )
662 PFA->CFA
663 ( pfa -- cfa )
665 CFA->NFA
666 ( cfa -- nfa )
668 NFA->CFA
669 ( nfa -- cfa )
671 CFA->LFA
672 ( cfa -- lfa )
674 LFA->CFA
675 ( lfa -- cfa )
677 LFA->PFA
678 ( lfa -- pfa )
680 LFA->BFA
681 ( lfa -- bfa )
683 LFA->SFA
684 ( lfa -- sfa )
686 LFA->NFA
687 ( lfa -- nfa )
689 NFA->LFA
690 ( nfa -- lfa )
692 CFA->WEND
693 ( cfa -- wend-addr )
694 convert CFA to word end address.
696 DEBUG:IP->NFA
697 ( ip -- nfa / 0 )
698 convert instruction pointer to NFA. return 0 if cannot.
700 DEBUG:IP->FILE/LINE
701 ( ip -- addr count line TRUE / FALSE )
702 name is at PAD; it is safe to use PAD, because each task has its
703 own temp image.
705 DEBUG:IP->FILE-HASH/LINE
706 ( ip -- len hash line TRUE / FALSE )
707 return unique file hash and name length instead of string name.
708 used in debugger.
710 STRING:=
711 ( a0 c0 a1 c1 -- bool )
713 STRING:=CI
714 ( a0 c0 a1 c1 -- bool )
715 case-insensitive compare (only for ASCII).
717 STRING:HASH
718 ( addr count -- hash )
720 STRING:HASH-CI
721 ( addr count -- hash )
722 case-insensitive hash (only for ASCII).
724 ($DEFINE)
725 ( addr count -- )
726 add new conditional define. case-insensitive (for ASCII).
728 ($UNDEF)
729 ( addr count -- )
730 remove conditional define. case-insensitive (for ASCII).
732 ($DEFINED?)
733 ( addr count -- bool )
734 check if we have a conditional define. case-insensitive (for ASCII).
736 ERROR
737 ( addr count -- )
738 print error message and abort.
740 ?ERROR
741 ( errflag addr count -- )
742 if "errflag" is not zero, print error message and abort.
744 ?NOT-ERROR
745 ( errflag addr count -- )
746 if "errflag" is zero, print error message and abort.
748 (INCLUDE-DEPTH)
749 ( -- depth )
750 return number of items in the include stack.
752 (INCLUDE-FILE-ID)
753 ( isp -- id )
754 isp 0 is current, then 1, etc.
755 each include file has unique non-zero id.
757 (INCLUDE-FILE-LINE)
758 ( isp -- line )
760 (INCLUDE-FILE-NAME)
761 ( isp -- addr count )
762 current file name; at PAD.
764 (INCLUDE)
765 ( addr count soft? system? -- )
766 push current file to the include stack, open a new one. used internally.
768 $INCLUDE "str"
769 immediate word.
771 $INCLUDE-ONCE "str"
772 includes file only once; unreliable on shitdoze, i believe.
773 immediate word.
775 HANDLE:NEW
776 ( typeid -- hx )
777 allocate a new handle with the given typeid. typeid is just a number
778 without any special meaning. any number except "-1" is allowed.
779 new handle size is 0.
781 HANDLE:FREE
782 ( hx -- )
783 deallocate a handle, free all allocated handle memory.
784 0 is allowed.
786 HANDLE:TYPEID@
787 ( hx -- typeid )
789 HANDLE:TYPEID!
790 ( typeid hx -- )
792 HANDLE:SIZE@
793 ( hx -- size )
794 0 is allowed.
796 HANDLE:SIZE!
797 ( size hx -- )
798 resize memory allocated for handle data.
800 HANDLE:USED@
801 ( hx -- used )
802 "used" is just a number, which means nothing for most code.
803 it is used to implement dynamic arrays.
804 0 is allowed.
806 HANDLE:USED!
807 ( size hx -- )
809 HANDLE:C@
810 ( idx hx -- value )
812 HANDLE:W@
813 ( idx hx -- value )
815 HANDLE:@
816 ( idx hx -- value )
818 HANDLE:C!
819 ( value idx hx -- value )
821 HANDLE:W!
822 ( value idx hx -- )
824 HANDLE:!
825 ( value idx hx -- )
827 HANDLE:LOAD-FILE
828 ( addr count -- stx / FALSE )
829 load file with the given name into newly allocated handle.
830 return 0 (FALSE) if there is no such file.
833 ( -- rega )
834 get address register contents.
837 ( rega -- )
838 set address register contents.
840 A-SWAP
841 ( rega -- olda )
842 swap TOS and the address register.
844 +1>A
845 ( -- )
846 increment the address register.
849 ( -- | rega )
850 copy the address register to the return stack.
853 ( | rega -- )
854 restore the address register from the return stack.
857 ( -- byte )
860 ( -- word )
863 ( -- value )
866 ( byte -- )
869 ( word -- )
872 ( value -- )
874 C@A+
875 ( idx -- byte )
876 safe way to access both dictionary memory, and handle memory.
877 "idx" is used as offset from address register contents.
879 W@A+
880 ( idx -- word )
881 safe way to access both dictionary memory, and handle memory.
882 "idx" is used as offset from address register contents.
885 ( idx -- value )
886 safe way to access both dictionary memory, and handle memory.
887 "idx" is used as offset from address register contents.
889 C!A+
890 ( byte idx -- )
891 safe way to access both dictionary memory, and handle memory.
892 "idx" is used as offset from address register contents.
894 W!A+
895 ( word idx -- )
896 safe way to access both dictionary memory, and handle memory.
897 "idx" is used as offset from address register contents.
900 ( value idx -- )
901 safe way to access both dictionary memory, and handle memory.
902 "idx" is used as offset from address register contents.
904 DEBUG:(DECOMPILE-CFA)
905 ( cfa -- )
907 GET-MSECS
908 ( -- u32 )
910 (UFO-INTERPRET-FINISHED-ACTION)
911 ( -- )
912 this is called by main loop when it is out of input stream. internally,
913 it simply sets a flag to tell the VM that it should stop.
915 (UFO-INTERPRET-NEXT-LINE)
916 ( -- continue? )
917 default word used to read next input line. return FALSE to exit from
918 "INTERPRET".
920 (INTERPRET-PARSE-NAME)
921 ( -- addr count / FALSE )
922 called by INTERPRET to read next word from the input stream. calls
923 "(INTERPRET-NEXT-LINE)" to refill lines. return FALSE (without address)
924 to exit from "INTERPRET", or next parsed word.
926 (USER-INTERPRET-NEXT-LINE)
927 user variable, holds address of "get next line" word. default value is
928 CFA of "(UFO-INTERPRET-NEXT-LINE)".
930 (INTERPRET-NEXT-LINE)
931 ( -- continue? )
932 peek "(USER-INTERPRET-NEXT-LINE)" and call read CFA.
934 HERE
935 ( -- dp )
936 push current dictionary pointer to the data stack.
937 NOTE: there are actually two DPs -- normal, and temporary. "(DP-TEMP)" is
938 the temp one, and if it is 0, "(DP)" is used. UrForth has 1MB temp area
939 (that's where PAD is too), it had different addresses, and vocabularies
940 created in that area are not linked to the main voclink list. this is used,
941 for example, in locals engine, to store names of locals. so if you're using
942 locals in your word, do not use temp area while compiling that word.
944 LATEST-LFA
945 ( -- lfa )
946 push LFA of the latest defined word in the current vocabulary. note that
947 "smudge" bit doesn't matter here, it is always the last word you created
948 header for. this includes "nonamed" words (which have empty string as a name).
950 NOOP
951 ( -- )
952 does nothing. at all.
954 COMPILER:(CTLID-COLON)
955 ( -- ctlid-colon )
956 semicolon expects this on the data stack.
958 ' <name>
959 ( -- cfa )
960 find word, push its CFA to the data stack. note that the tick
961 is NOT immediate. use "[']" if you need to compile next word CFA.
964 start new word definition.
967 end new word definition.
969 ALIAS oldword newword
970 ( -- )
971 "newword" will do exactly the same as "oldword". word attributes
972 will be copied too (hidden, immediate, etc.).
974 LATEST-CFA
975 ( -- cfa )
977 LATEST-PFA
978 ( -- pfa )
980 LATEST-NFA
981 ( -- nfa )
983 LATEST-SFA
984 ( -- sfa )
986 ~AND
987 ( a b -- a&~b )
989 SWAP!
990 ( addr value -- )
993 ( value addr -- )
995 ~AND!
996 ( value addr -- )
998 XOR!
999 ( value addr -- )
1001 IMMEDIATE
1002 mark last defined word as immediate (or remove immediate mark if it is already set).
1004 (HIDDEN)
1005 mark last defined word as hidden. DO NOT USE. this is obsolete feature,
1006 and it will be removed. it is here for compatibility with my other Forth system.
1008 (PUBLIC)
1009 the opposite of "(HIDDEN)".
1011 -FIND-REQUIRED
1012 alias for the tick.
1014 PARSE-SKIP-COMMENTS
1015 ( -- )
1016 skip all comments and blanks, multiline mode.
1018 PARSE-SKIP-LINE-COMMENTS
1019 skip all comments and blanks, single line mode.
1021 (SET-DEF-WORD-FLAGS)
1022 ( flg -- )
1023 add (OR) default flag for new words.
1024 word flags are:
1025   (WFLAG-IMMEDIATE)
1026   (WFLAG-SMUDGE)
1027   (WFLAG-NORETURN)
1028   (WFLAG-HIDDEN)
1029   (WFLAG-CBLOCK)
1030   (WFLAG-VOCAB)
1031   (WFLAG-SCOLON)
1032   (WFLAG-PROTECTED)
1034 (RESET-DEF-WORD-FLAGS)
1035 ( flg -- )
1036 remove (~AND) default flag for new words.
1038 <PUBLIC-WORDS>
1039 ( -- )
1040 all following words will be public.
1042 <HIDDEN-WORDS>
1043 ( -- )
1044 all following words will be hidden.
1046 <PROTECTED-WORDS>
1047 ( -- )
1048 all following words will be protected. you cannot redefine
1049 protected words.
1051 <UNPROTECTED-WORDS>
1052 ( -- )
1053 all following words will not be protected.
1055 ONLY
1056 ( -- )
1057 clear the wordlist stack.
1059 ALSO
1060 ( -- )
1061 push context vocabulary onto the wordlist stack.
1063 PREVIOUS
1064 ( -- )
1065 pop vocabulary from the wordlist stack, and make in context.
1067 DEFINITIONS
1068 ( -- )
1069 make context vocabulary also current. "current" is the vocabulary
1070 that will receive new word definitions. "context" is the vocabulary
1071 that will be used to search words.
1074 ( a -- a+1 )
1077 ( a -- a+2 )
1080 ( a -- a+2 )
1083 ( a -- a-1 )
1086 ( a -- a-2 )
1089 ( a -- a-2 )
1092 ( n -- n==0 )
1095 ( n -- n<>0 )
1098 ( n -- n==0 )
1101 ( n -- n==0 )
1104 ( n -- n<>0 )
1107 ( n -- n<>0 )
1109 NOTNOT
1110 ( a -- !!a )
1113 ( a -- |a| )
1115 SIGN?
1116 ( n -- -1|0|1 )
1118 NEGATE
1119 ( n -- -n )
1121 LSHIFT
1122 ( n count -- n )
1124 RSHIFT
1125 ( n count -- n )
1127 ARSHIFT
1128 ( n count -- n )
1131 ( n count -- n )
1134 ( n count -- n )
1137 ( n count -- n )
1140 ( n count -- n )
1142 LO-WORD
1143 ( a -- a&0xffff )
1145 HI-WORD
1146 ( a -- [a>>16]&0xffff )
1148 LO-BYTE
1149 ( a -- a&0xff )
1151 HI-BYTE
1152 ( a -- [a>>8]&0xff )
1155 ( addr -- )
1158 ( addr -- )
1161 ( n addr -- )
1164 ( n addr -- )
1167 ( addr -- )
1170 ( addr -- )
1172 BCOUNT
1173 ( addr -- addr+1 count )
1175 COUNT
1176 ( addr -- addr+4 count )
1179 ( -- )
1181 DECIMAL
1182 ( -- )
1184 OCTAL
1185 ( -- )
1187 BINARY
1188 ( -- )
1190 WITHIN
1191 ( value a b -- value>=a&&value<b )
1193 UWITHIN
1194 ( value a b -- value>=a&&value<b )
1196 BOUNDS?
1197 ( value a b -- value>=a&&value<=b )
1198 numbers are unsigned.
1200 (HANDLE-ADDR?)
1201 ( addr -- )
1202 check if the given addres is actually a handle.
1204 COMPILER:SET-SMUDGE
1205 ( -- )
1206 set "smudge" bit for the latest word.
1208 COMPILER:RESET-SMUDGE
1209 ( -- )
1210 reset "smudge" bit for the latest word.
1212 COMPILER:SET-WARG
1213 ( warg -- )
1214 set argument type for the latest word. each word has "argument type" field,
1215 which inditates word argument type in the compiled code. arguments are:
1216   (WARG-NONE)
1217   (WARG-BRANCH)
1218   (WARG-LIT)
1219   (WARG-C4STRZ)
1220   (WARG-CFA)
1221   (WARG-CBLOCK)
1222   (WARG-VOCID)
1223   (WARG-C1STRZ)
1225 (WARG-MASK)
1226 ( -- mask )
1227 this mask can be used to get only argument type bits from the first NFA cell.
1229 COMPILER:(GET-NEW-WORD-FLAGS)
1230 ( -- flags )
1231 get sanitized new word flags. currently, only "hidden" and "protected" flags
1232 are retained, all other flags will be reset.
1234 COMPILER:(CREATE-HEADER)
1235 ( addr count -- )
1236 create new named word header with the default flags. additionally, sets
1237 "smudge" flag on the new word.
1239 COMPILER:(CREATE-NAMELESS)
1240 ( -- cfa )
1241 create new nameless word header with the default flags. additionally, sets
1242 "smudge" and "hidden" flags on the new word.
1243 return CFA address of the new word. CFA contents is not filled yet.
1245 COMPILER:(MK-CONST-VAR)
1246 ( value cfaidx -- )
1247 don't bother using this.
1249 COMPILER:FORTH-WORD?
1250 ( cfa -- bool )
1251 check if the given word is normal Forth word (i.e. defined with the colon).
1253 COMPILE
1254 ( cfa -- )
1255 compiles CFA to be executed.
1257 use the following words to compile branch destinations. this way your code
1258 will be independent of branch instruction operand format.
1260 ;; usage:
1261 ;;  compile (0branch)
1262 ;;  (mark>)
1263 ;;  ...
1264 ;;  (resolve>)
1266 ;;  (<mark)
1267 ;;  ...
1268 ;;  compile (branch)
1269 ;;  (<resolve)
1271 COMPILER:(BRANCH-ADDR!)
1272 ( destaddr addr -- )
1273 write "branch to destaddr" address to addr.
1275 COMPILER:(BRANCH-ADDR@)
1276 ( addr -- dest )  @ ;
1277 read branch address.
1280 COMPILER:(<J-MARK)
1281 ( -- addr )
1282 return addr suitable for "(<J-RESOLVE)".
1284 COMPILER:(<J-CHAIN)
1285 ( addr -- addr )
1286 use after "(<J-MARK)" to reserve jump and append it to jump chain.
1288 COMPILER:(<J-RESOLVE)
1289 ( addr -- )
1290 patch "forward jump" address to HERE. "addr" is the result of "(<J-MARK)".
1292 COMPILER:(MARK-J>)
1293 reserve room for branch address, return addr suitable for "(RESOLVE-J>)".
1295 COMPILER:(CHAIN-J>)
1296 use after "(MARK-J>)" to reserve jump and append it to jump chain.
1298 COMPILER:(RESOLVE-J>)
1299 ( addr -- )
1300 compile "forward jump" (possibly chain) from address to HERE. addr is the
1301 result of "(MARK-J>)". this resolves the whole "jump chain".
1304 COMPILER:?PAIRS
1305 ( a b -- )
1306 throw error if a <> b.
1308 ?2PAIRS
1309 ( a b c -- )
1310 throw error if a <> b and a <> c.
1312 LITERAL
1313 ( C:n -- )
1314 ( E:n -- n )
1315 compile number from the data stack as literal. NOT IMMEDIATE.
1317 IMM-LITERAL
1318 ( C:n -- )
1319 ( E:n -- n )
1320 immediate version of "LITERAL".
1322 STRLITERAL
1323 ( C:addr count -- )
1324 ( E: -- addr count )
1326 IMM-STRLITERAL
1327 immediate version of the previous word.
1329 CFALITERAL
1330 ( C:cfa -- )
1331 ( E:cfa -- cfa )
1333 IMM-CFALITERAL
1334 ( C:cfa -- )
1335 ( E:cfa -- cfa )
1337 [COMPILE] <wordname>
1338 force the next word to be compiled as normal word, even if it is an immediate one.
1341 compile next word CFA as CFA literal.
1343 COMPILER:(COMPILE-CFA-LITERAL)
1344 ( cfa -- )
1345 compile cfa literal to be compiled. ;-)
1347 COMPILER:END-COMPILE-FORTH-WORD
1348 ( -- )
1349 push colon ctlid and call ";".
1352 COMPILE <wordname>
1353 compile next word to the currently defining word.
1355 [CHAR] <char>
1356 ( -- ch )
1357 push/compile first char of the next word as char code.
1358 note that words with more than one char will cause an error.
1360 RECURSE
1361 recursively call the currently defining word. this is required
1362 due to currently defining word being invisible yet (because it
1363 is not finished).
1365 RECURSE-TAIL
1366 tail-call recursion.
1368 CONSTANT <name>
1369 ( value -- )
1370 create new constant.
1372 VARIABLE <name>
1373 ( value -- )
1374 create new variable.
1376 (CREATE)
1377 ( addr count -- )
1378 this is what "CREATE" is using to create a new word.
1380 CREATE <name>
1381 ( -- )
1382 create new word. when executed, this new word will push its PFA.
1383 note that new word is not smudged.
1385 CREATE;
1386 ( -- )
1387 finish CREATEd word. this is required to correctly set SFA.
1388 note that "DOES>" automatically takes care of SFA, so you don't have
1389 to call this if you're using "DOES>".
1391 (DOES>)
1392 ( doer-addr -- )
1393 patch CREATEd word. put doer address to its CFA, VM will do the rest.
1394 this is used internally by the compiler.
1396 (SET-DOER)
1397 ( doer-pfa cfa -- )
1398 makes CFA word to execute "doer-pfa" as doer.
1399 this is used internally by the compiler. do not try to understand this.
1401 DOES>
1402 ( -- )  ( pfa )
1403 the usual Forth "CREATE" -- "DOES>" support.
1405 4 CONSTANT CELL
1406 ANS idiocity.
1408 ALIAS 4U* CELLS  ( n -- n*cells )
1409 ANS idiocity.
1411 ALIAS 4+  CELL+  ( n -- n+cell )
1412 ANS idiocity.
1414 ALIAS 4-  CELL-  ( n -- n-cell )
1415 ANS idiocity.
1417 +CELLS
1418 ( a n -- a+n*cells )
1419 ANS idiocity.
1421 -CELLS
1422 ( a n -- a+n*cells )
1423 ANS idiocity.
1425 .( text)
1426 immediately print the text.
1428 ." text"
1429 compile text printer.
1431 N-ALLOT
1432 ( n -- stard-addr )
1433 allocate n *bytes* in the current DP, return the address of
1434 the first allocated byte.
1436 ALLOT
1437 ( n -- )
1438 allocate n *bytes* in the current DP.
1440 ALIGN-HERE
1441 ( -- )
1442 align DP to 4-byte boundary.
1444 COMPILER:(NEW-WORDLIST)
1445 ( parentvocid need-hashtable? -- vocid )
1446 create new empty wordlist.
1448 COMPILER:(CREATE-NAMED-VOCAB)
1449 ( vocid addr count -- )
1450 create vocabulary word.
1452 COMPILER:(CREATE-VOCAB) <vocname>
1453 ( vocid -- )
1454 create vocabulary word.
1456 COMPILER:(IS-VOC-WORD?)
1457 ( cfa -- bool )
1458 check if the given CFA defined as a vocabulary header.
1460 COMPILER:(WORD->VOCID)
1461 ( cfa -- vocid )
1462 get vocid from the vocabulary word. doesn't check arguments.
1464 COMPILER:(VOCID-PARENT@)
1465 ( vocid -- vocid )
1466 get vocid parent vocabulary. return 0 if there is no parent.
1467 doesn't check arguments.
1469 COMPILER:(VOCID-PARENT!)
1470 ( parent-vocid vocid -- )
1471 set vocid parent vocabulary. doesn't check arguments.
1473 COMPILER:(VOCID-TYPEID@)
1474 ( vocid -- typeid )
1475 internal helper for STRUCT support.
1477 COMPILER:(VOCID-TYPEID!)
1478 internal helper for STRUCT support.
1480 (VOCABULARY-EX)
1481 ( addr count parent need-hashtbl? -- )
1482 useful low-level words to create vocabs with already parsed names.
1484 (VOCABULARY)
1485 ( addr count -- )
1487 (SIMPLE-VOCABULARY)
1488 ( addr count -- )
1489 creates vocabulary without a hash table.
1491 (NESTED-VOCABULARY)
1492 ( addr count -- )
1494 (SIMPLE-NESTED-VOCABULARY)
1495 ( addr count -- )
1497 VOCABULARY <vocname>
1499 SIMPLE-VOCABULARY <vocname>
1501 NESTED-VOCABULARY <vocname>
1503 SIMPLE-NESTED-VOCABULARY <vocname>
1505 VOCID: <vocname>
1506 ( -- vocid )
1507 return vocid for the given vocabulary. this word is immediate.
1509 VOC-LATEST
1510 ( vocid -- latest )
1511 return latest word LFA for the given vocid.
1513 ALSO-DEFS: <vocname>
1514 ( -- )
1515 this does "ALSO <vocname> DEFINITIONS"
1517 PREV-DEFS
1518 ( -- )
1519 this does "PREVIOUS DEFINITIONS".
1521 VOCAB-IF-NONE <vocname>
1522 create vocabulary if we don't have such word yet.
1524 NESTED-VOCAB-IF-NONE <vocname>
1525 create nested vocabulary if we don't have such word yet.
1527 SIMPLE-VOCAB-IF-NONE <vocname>
1528 create vocabulary if we don't have such word yet.
1530 SIMPLE-NESTED-VOCAB-IF-NONE <vocname>
1531 create nested vocabulary if we don't have such word yet.
1533 -TO  ( n -- )  \ name
1534 decrement value by n.
1536 +TO  ( n -- )  \ name
1537 increment value by n.
1539 -1-TO  ( -- )  \ name
1540 decrement value by 1.
1542 +1-TO  ( -- )  \ name
1543 increment value by 1.
1545 0-TO  ( -- )  \ name
1546 write 0 to value.
1548 ... FORTH:(TO-EXTENDER) ...
1549 ( addr count FALSE -- addr count FALSE / TRUE )
1550 "TO" can be extended to support things it doesn't know about yet.
1551 after parsing a name, "(TO-EXTENDER)" will be called (this is
1552 scattered colon word). note that due to how scattered colon works,
1553 you'd better DON'T use "EXIT", but pass a flag if you need to stop
1554 further processing. also, do not forget to check the flag at the
1555 start of your extender, because some other extender may already
1556 did its work before yours.
1558 ... FORTH:(EXIT-EXTENDER) ...
1559 ( -- )
1560 this scattered colon word allows you to extend "EXIT". "EXIT" is
1561 the immediate word that compiles word leaving instructions. you
1562 can compile your cleanup code before the standard cleanup.
1564 ... FORTH:(INTERPRET-CHECK-WORD) ...
1565 ( addr count FALSE -- addr count FALSE / TRUE )
1566 this is called by INTERPRET before the standard word processing.
1568 ... FORTH:(INTERPRET-WORD-NOT-FOUND) ...
1569 ( addr count FALSE -- addr count FALSE / TRUE )
1570 this is called by INTERPRET when word resolution failed.
1573 UrForth supports cooperative multitasking. it is also used to implement
1574 interactive debugger. tasks are called "execution states", or simply
1575 "states".
1577 MTASK:NEW-STATE
1578 ( cfa -- stid )
1579 create new state, return state id.
1581 MTASK:FREE-STATE
1582 ( stid -- )
1583 free state. state id should be valid, and should not be an active state.
1585 MTASK:STATE-NAME@
1586 ( stid -- addr count )
1587 copy state name to PAD.
1589 MTASK:STATE-NAME!
1590 ( addr count stid -- )
1591 set new state name. maximum name length is 127 chars. state name
1592 should not include char with code 0.
1594 MTASK:STATE-FIRST
1595 ( -- stid )
1596 get first state in the list of all created states. this is used to
1597 iterate over all states.
1598 WARNING! do not mutate state list while iterating! result will be UB.
1600 MTASK:STATE-NEXT
1601 ( stid -- stid / 0 )
1602 get next state id. used to iterate over all states.
1603 WARNING! do not mutate state list while iterating! result will be UB.
1605 MTASK:YIELD-TO
1606 ( ... argc stid -- )
1607 yield to another state. move argc numbers from the current state data
1608 stack to the new state data stack. push args to the new state data
1609 stack, and then push current state id. i.e. new state data stack will
1610 look like this:
1611   ( ... argc old-stid )
1612 it is ok to swith to the currently active state (it is a no-op).
1614 MTASK:SET-SELF-AS-DEBUGGER
1615 ( -- )
1616 register current task as system debugger. you can yeild from the debugger
1617 after this.
1619 DEBUG:(BP)
1620 ( -- )
1621 breakpoint. debugger task receives debugge stid on the data stack,
1622 and `-1` as yield argument count. i.e. debugger stack will be:
1623   ( -1 old-stid )
1625 MTASK:DEBUGGER-RESUME
1626 ( stid -- )
1627 resume debugee execution.
1629 MTASK:DEBUGGER-SINGLE-STEP
1630 ( stid -- )
1631 execute one debuggee instruction, and return to debugger.
1632 this is basically "YIELD", but to use in the debugger
1633 (and it doesn't pass any arguments). debugger stack will be:
1634   ( -2 old-stid )
1636 MTASK:STATE-IP@
1637 ( stid -- ip )
1638 get state instruction pointer.
1640 MTASK:STATE-IP!
1641 ( ip stid -- )
1642 set state instruction pointer.
1644 MTASK:STATE-A>
1645 ( stid -- regA )
1646 get address register contents.
1648 MTASK:STATE->A
1649 ( rega stid -- )
1650 set address register contents.
1652 MTASK:STATE-USER@
1653 ( addr stid -- valie )
1654 get other state user area cell.
1656 MTASK:STATE-USER!
1657 ( value addr stid -- )
1658 set other state user area cell.
1660 MTASK:STATE-RPOPCFA@
1661 ( -- flag )
1662 VM has special mode when it gets next CFA from the return stack
1663 instead of the address pointed by IP. this is used to implement
1664 "EXECUTE", for example. use this word to retrieve that flag.
1666 MTASK:STATE-RPOPCFA!
1667 ( flag -- )
1668 VM has special mode when it gets next CFA from the return stack
1669 instead of the address pointed by IP. this is used to implement
1670 "EXECUTE", for example. use this word to set that flag.
1672 MTASK:ACTIVE-STATE
1673 ( -- stid )
1674 return state id of the currently executing state.
1676 MTASK:YIELDED-FROM
1677 ( -- stid / 0 )
1678 return state which called "MTASK:YIELD-TO" last.
1680 MTASK:STATE-SP@
1681 ( stid -- depth )
1682 get the data stack depth for the given state.
1684 MTASK:STATE-RP@
1685 ( stid -- depth )
1686 get the return stack depth for the given state.
1688 MTASK:STATE-LP@
1689 ( stid -- lp )
1690 get local stack ptr.
1692 MTASK:STATE-LBP@
1693 ( stid -- lbp )
1694 get local stack base ptr.
1696 MTASK:STATE-SP!
1697 ( depth stid -- )
1698 set the data stack depth for the given state.
1700 MTASK:STATE-RP!
1701 ( stid -- depth )
1702 set the return stack depth for the given state.
1704 MTASK:STATE-LP!
1705 ( lp stid -- )
1706 set local stack ptr.
1708 MTASK:STATE-LBP!
1709 ( lbp stid -- )
1710 set local stack base ptr.
1712 MTASK:STATE-DS@
1713 ( idx stid -- value )
1714 read the data stack of the given state. note that the index is bound-checked.
1716 MTASK:STATE-RS@
1717 ( idx stid -- value )
1718 read the return stack of the given state. note that the index is bound-checked.
1720 MTASK:STATE-LS@
1721 ( idx stid -- value )
1722 read the locals stack of the given state. note that the index is bound-checked.
1724 MTASK:STATE-DS!
1725 ( value idx stid -- )
1726 write the data stack of the given state. note that the index is bound-checked.
1727 i.e. if you want to push some value, increase stack depth first.
1729 MTASK:STATE-RS!
1730 ( value idx stid -- )
1731 write the return stack of the given state. note that the index is bound-checked.
1732 i.e. if you want to push some value, increase stack depth first.
1734 MTASK:STATE-LS!
1735 ( value idx stid -- )
1736 write the locals stack of the given state. note that the index is bound-checked.
1737 i.e. if you want to push some value, increase stack depth first.
1740 there are some words to work with TTY (only GNU/Linux).
1742 TTY:TTY?
1743 ( -- bool )
1744 check if input and output are valid TTY(s).
1746 TTY:RAW?
1747 ( -- bool )
1748 check if current TTY mode is raw.
1750 TTY:SIZE
1751 ( -- width height )
1752 get TTY size. for non-TTYs retur default 80x24.
1754 TTY:SET-RAW
1755 ( -- success-bool )
1756 switch TTY to raw mode.
1758 TTY:SET-COOKED
1759 ( -- success-bool )
1760 switch TTY to cooked mode.
1762 TTY:RAW-EMIT
1763 ( n -- )
1764 type char without any filtering or safety nets.
1766 TTY:RAW-TYPE
1767 ( addr count -- )
1768 type string without any filtering or safety nets.
1770 TTY:RAW-FLUSH
1771 ( -- )
1772 the output of the two words above is buffered. this words flushes
1773 the buffer. buffering is done because raw TTY is mostly used to
1774 build user interfaces, and sending accumulated terminal commands
1775 in one big chunk looks much better (most terminal emulators will
1776 process the whole chunk before refreshing their windows).
1778 TTY:RAW-READCH
1779 ( -- ch / -1 )
1780 -1 returned on error, or on EOF.
1781 read one char (without any interpretation) if TTY is in raw mode.
1782 note that 0 is a valid char (it is used to send Ctrl+Space in some
1783 terminal emulators). also note that there is no way to tell if we
1784 hit a EOF, or some error occured. in practice, it doesn't matter,
1785 because in both cases it means that TTY is unusable anymore.
1787 TTY:RAW-READY?
1788 ( -- bool )
1789 check if raw TTY has some data to read.