UrForth: some new words for debuggers
[urasm.git] / dox / urforth.txt
blob3694e5aca8d43261eadbe009125efdb1ae9ac8f0
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)".
172 EXECUTE
173 ( cfa )
174 pop word CFA address, and execute it.
176 EXECUTE-TAIL
177 ( cfa )
178 pop word CFA address, and execute it. returning from the executed
179 word will return to the upper word. i.e. this performs a tail call.
182 (EXIT)
183 internal compiler word, placed at the end of colon definition.
184 pops a number from return stack, and sets IP to that number.
186 (L-ENTER)
187 this word is used to implement local variables and arguments.
188 it doesn't matter how it works, you should not used it anyway.
189 read the source code, if you're curious.
191 (L-LEAVE)
192 this word is used to implement local variables and arguments.
193 it doesn't matter how it works, you should not used it anyway.
194 read the source code, if you're curious.
196 (LOCAL@)
197 ( idx -- value )
198 read local variable with the given index. indices are 1-based.
200 (LOCAL!)
201 ( value idx -- )
202 write local variable with the given index. indices are 1-based.
205 ( n -- n n )
206 duplicates a number on the data stack.
208 ?DUP
209 ( n -- n n ) | ( 0 -- 0 )
210 duplicates a number on the data stack, but only if that number is not 0.
212 2DUP
213 ( n0 n1 -- n0 n1 n0 n1 )
215 DROP
216 ( n -- )
218 2DROP
219 ( n0 n1 -- )
221 SWAP
222 ( n0 n1 -- n1 n0 )
224 2SWAP
225 ( n0 n1 -- n1 n0 )
227 OVER
228 ( n0 n1 -- n0 n1 n0 )
230 2OVER
231 ( n0 n1 -- n0 n1 n0 )
234 ( n0 n1 n2 -- n1 n2 n0 )
236 NROT
237 ( n0 n1 n2 -- n2 n0 n1 )
240 ( a b -- b )
242 TUCK
243 ( a b -- b a b )
245 RDUP
246 ( n -- n n )
247 the same as "DUP", but for the return stack.
249 RDROP
250 ( n -- )
251 the same as "DROP", but for the return stack.
253 RSWAP
254 ( n0 n1 -- n1 n0 )
255 the same as "SWAP", but for the return stack.
257 ROVER
258 ( n0 n1 -- n0 n1 n0 )
259 the same as "OVER", but for the return stack.
261 RROT
262 ( n0 n1 n2 -- n1 n2 n0 )
263 the same as "ROT", but for the return stack.
265 RNROT
266 ( n0 n1 n2 -- n2 n0 n1 )
267 the same as "NROT", but for the return stack.
270 ( n -- | n )
271 move number from the data stack to the return stack.
274 ( | n -- n )
275 move number from the return stack to the data stack.
278 ( | n -- n | n )
279 copy number from the return stack to the data stack.
281 PICK
282 ( idx -- n )
283 copy n-th element at the data stack. "0 PICK" is the same as "DUP".
285 RPICK
286 ( idx -- n )
287 the same as "PICK", but for the return stack.
289 ROLL
290 ( idx -- n )
291 move n-th element at the data stack to the top. "1 ROLL" is the same as "SWAP".
293 RROLL
294 ( idx -- n )
295 the same as "ROLL", but for the return stack.
297 REFILL
298 ( -- eofflag )
299 read next input line. can cross include boundaries. pushes 0 if
300 there are no more input lines. TIB contents is undefined in this case.
302 REFILL-NOCROSS
303 ( -- eofflag )
304 read next input line. cannot cross include boundaries. pushes 0 if
305 there are no more input lines. TIB contents is undefined in this case.
307 (TIB-IN)
308 ( -- addr )
309 get address of the current TIB position.
310 WARNING! do not try to emulate "TIB-GETCH" and such with this word!
311          TIB usually ends with 0 byte, and if you will advance beyond
312          that 0, Bad Things will happen.
314 TIB-PEEKCH
315 ( -- char )
316 push current TIB char, do not advance >IN.
318 TIB-PEEKCH-OFS
319 ( ofs -- char )
320 peek TIB char with the given offset. "0 TIB-PEEKCH-OFS" is the same as "TIB-PEEKCH".
322 TIB-GETCH
323 ( -- char )
324 push current TIB char, advance >IN. it is safe to call this even
325 when you reached the end of TIB. in this case, returned char code
326 will be 0. i.e. "0" means "end of TIB".
328 TIB-SKIPCH
329 ( -- )
330 skip current TIB char. it is safe to call this even when you reached
331 the end of TIB.
334 (PARSE)
335 ( delim skip-leading-delim? -- addr count TRUE / FALSE )
336 does base TIB parsing; never copies anything.
337 as our reader is line-based, returns FALSE on EOL.
338 EOL is detected after skipping leading delimiters.
339 passing -1 as delimiter skips the whole line, and always returns FALSE.
340 finishing delimiter is always skipped.
342 PARSE-SKIP-BLANKS
343 ( -- )
344 skip all chars with codes <=32.
346 (PARSE-SKIP-COMMENTS)
347 ( allow-multiline? -- )
348 skip all blanks and comments. if multiline skip is not allowed, reaching
349 end of TIB while still waiting for the comment terminator is error.
350 single-line comments are ok, though.
352 PARSE-SKIP-LINE
353 ( -- )
354 advance >IN to the end of TIB.
356 PARSE-NAME
357 ( -- addr count )
358 parse with leading blanks skipping. doesn't copy anything.
359 return empty string on EOL.
361 PARSE
362 ( delim -- addr count TRUE / FALSE )
363 parse without skipping delimiters; never copies anything.
364 as our reader is line-based, returns FALSE on EOL.
365 passing 0 as delimiter skips the whole line, and always returns FALSE.
366 finishing delimiter is always skipped.
368 EMIT
369 ( n -- )
370 print char.
372 XEMIT
373 ( n -- )
374 "safe" char printer. all non-printable chars (including newline and such)
375 will be printed as "?".
377 LASTCR?
378 ( -- bool )
379 was last printed char a newline?
381 LASTCR!
382 ( bool -- )
383 force-set the flag for "LASTCR?" word.
386 ( -- )
387 print newline.
389 SPACE
390 ( -- )
391 print space.
393 SPACES
394 ( n -- )
395 print `n` spaces. if `n` is negative, prints nothing.
397 ENDCR
398 ( -- )
399 prints newline if the last printed char was not a newline.
401 TYPE
402 ( addr count -- )
403 print the string. negative count is ok, in this case the word prints nothing.
405 XTYPE
406 ( addr count -- )
407 the same as "TYPE", but uses "XEMIT".
409 FLUSH-EMIT
410 ( -- )
411 output can be buffered. it usually flushed when newline is printed, but
412 you can flush it manually using this word.
415 ( a b -- a+b )
418 ( a b -- a-b )
421 ( a b -- a*b )
424 ( a b -- a*b )
427 ( a b -- a/b )
430 ( a b -- a/b )
433 ( a b -- a%b )
435 UMOD
436 ( a b -- a%b )
438 /MOD
439 ( a b -- a/b, a%b )
440 note that the results are swaped, contrary to ANS idiocity.
441 i don't fuckin' know why ANS morons decided to make the stack
442 effect that contradicts the word name. "/MOD" clearly indicates
443 that quotient comes first.
445 U/MOD
446 ( a b -- a/b, a%b )
447 note that the results are swaped, contrary to ANS idiocity.
448 i don't fuckin' know why ANS morons decided to make the stack
449 effect that contradicts the word name. "/MOD" clearly indicates
450 that quotient comes first.
453 ( a b c -- a*b/c )
454 this uses 64-bit intermediate value.
457 ( a b c -- a*b/c )
458 this uses 64-bit intermediate value.
460 */MOD
461 ( a b c -- a*b/c a*b%c )
462 this uses 64-bit intermediate value.
463 note that the results are swaped, contrary to ANS idiocity.
464 i don't fuckin' know why ANS morons decided to make the stack
465 effect that contradicts the word name. "/MOD" clearly indicates
466 that quotient comes first.
469 ( a b c -- a*b/c )
470 this uses 64-bit intermediate value.
473 ( a b -- lo(a*b) hi(a*b) )
474 this leaves 64-bit result.
477 ( a b -- lo(a*b) hi(a*b) )
478 this leaves 64-bit result.
480 M/MOD
481 ( alo ahi b -- a/b a%b )
482 note that the results are swaped, contrary to ANS idiocity.
483 i don't fuckin' know why ANS morons decided to make the stack
484 effect that contradicts the word name. "/MOD" clearly indicates
485 that quotient comes first.
487 UM/MOD
488 ( alo ahi b -- a/b a%b )
489 note that the results are swaped, contrary to ANS idiocity.
490 i don't fuckin' know why ANS morons decided to make the stack
491 effect that contradicts the word name. "/MOD" clearly indicates
492 that quotient comes first.
495 ( a b -- a<b )
498 ( a b -- a<b )
501 ( a b -- a>b )
504 ( a b -- a>b )
507 ( a b -- a<=b )
510 ( a b -- a<=b )
513 ( a b -- a>=b )
516 ( a b -- a>=b )
519 ( a b -- a=b )
522 ( a b -- a<>b )
525 ( a -- !a )
527 LAND
528 ( a b -- a&&b )
529 logical "and".
532 ( a b -- a||b )
533 logical "or".
536 ( a b -- a&b )
537 bitwise "and".
540 ( a b -- a|b )
541 bitwise "or".
544 ( a b -- a^b )
545 bitwise "xor".
547 BITNOT
548 ( a -- ~a )
551 ( u -- u*2 )
554 ( u -- u*2 )
557 ( u -- u*4 )
560 ( u -- u*4 )
563 ( n count -- )
564 arithmetic shift; positive `n` shifts to the left.
567 ( n count -- )
568 logical shift; positive `n` shifts to the left.
570 COMPILER:(UNESCAPE)
571 ( addr count -- addr new-count )
572 process string escapes. modifies string in-place. the resulting string is
573 never bigger than the source one. negative counts are allowed.
575 (BASED-NUMBER)
576 ( addr count allowsign? base -- num TRUE / FALSE )
577 tries to convert the given string to the number, using the given
578 default base. if "allowsign?" is non-zero, properly process leading
579 number sign. this words understands numbers in non-default bases too
580 (like "0x29a", for example).
584 switch to interpretation mode.
587 switch to compilation mode.
589 (CREATE-WORD-HEADER)
590 ( addr count word-flags -- )
591 create word header in the dictionary, link word to the current vocabulary.
592 doesn't create CFA.
594 (CREATE-NAMELESS-WORD-HEADER)
595 ( word-flags -- )
596 create nameless word header in the dictionary, link word to the current vocabulary.
597 doesn't create CFA.
599 FIND-WORD
600 ( addr count -- cfa TRUE / FALSE)
601 general word finder. checks wordlist stack, performs colon resolution.
603 (FIND-WORD-IN-VOC)
604 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
605 find word in the given wordlist. does no name resolution, and
606 doesn't look in parent wordlists.
608 FIND-WORD-IN-VOC
609 ( addr count vocid -- cfa TRUE / FALSE)
610 find word in the given wordlist. does no name resolution, and
611 doesn't look in parent wordlists. skips hidden words.
613 (FIND-WORD-IN-VOC-AND-PARENTS)
614 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
615 find word in the given wordlist. does no name resolution, but searches
616 parent wordlists if "vocid" is nested.
618 FIND-WORD-IN-VOC-AND-PARENTS
619 ( addr count vocid -- cfa TRUE / FALSE)
620 find word in the given wordlist. does no name resolution, but searches
621 parent wordlists if "vocid" is nested. skips hidden words.
623 COMPILER:?EXEC
624 check if we are in interpretation mode, and throws an error if we aren't.
626 COMPILER:?COMP
627 check if we are in compilation mode, and throws an error if we aren't.
630 string literal.
632 (VSP@)
633 ( -- vsp )
634 this word is used internally to work with wordlist stack.
636 (VSP!)
637 ( vsp -- )
638 this word is used internally to work with wordlist stack.
640 (VSP-AT@)
641 ( idx -- value )
642 this word is used internally to work with wordlist stack.
644 (VSP-AT!)
645 ( value idx -- )
646 this word is used internally to work with wordlist stack.
648 CFA->PFA
649 ( cfa -- pfa )
651 PFA->CFA
652 ( pfa -- cfa )
654 CFA->NFA
655 ( cfa -- nfa )
657 NFA->CFA
658 ( nfa -- cfa )
660 CFA->LFA
661 ( cfa -- lfa )
663 LFA->CFA
664 ( lfa -- cfa )
666 LFA->PFA
667 ( lfa -- pfa )
669 LFA->BFA
670 ( lfa -- bfa )
672 LFA->SFA
673 ( lfa -- sfa )
675 LFA->NFA
676 ( lfa -- nfa )
678 NFA->LFA
679 ( nfa -- lfa )
681 CFA->WEND
682 ( cfa -- wend-addr )
683 convert CFA to word end address.
685 DEBUG:IP->NFA
686 ( ip -- nfa / 0 )
687 convert instruction pointer to NFA. return 0 if cannot.
689 DEBUG:IP->FILE/LINE
690 ( ip -- addr count line TRUE / FALSE )
691 name is at PAD; it is safe to use PAD, because each task has its
692 own temp image.
694 DEBUG:IP->FILE-HASH/LINE
695 ( ip -- len hash line TRUE / FALSE )
696 return unique file hash and name length instead of string name.
697 used in debugger.
699 STRING:=
700 ( a0 c0 a1 c1 -- bool )
702 STRING:=CI
703 ( a0 c0 a1 c1 -- bool )
704 case-insensitive compare (only for ASCII).
706 STRING:HASH
707 ( addr count -- hash )
709 STRING:HASH-CI
710 ( addr count -- hash )
711 case-insensitive hash (only for ASCII).
713 ($DEFINE)
714 ( addr count -- )
715 add new conditional define. case-insensitive (for ASCII).
717 ($UNDEF)
718 ( addr count -- )
719 remove conditional define. case-insensitive (for ASCII).
721 ($DEFINED?)
722 ( addr count -- bool )
723 check if we have a conditional define. case-insensitive (for ASCII).
725 ERROR
726 ( addr count -- )
727 print error message and abort.
729 ?ERROR
730 ( errflag addr count -- )
731 if "errflag" is not zero, print error message and abort.
733 ?NOT-ERROR
734 ( errflag addr count -- )
735 if "errflag" is zero, print error message and abort.
737 (INCLUDE-DEPTH)
738 ( -- depth )
739 return number of items in the include stack.
741 (INCLUDE-FILE-ID)
742 ( isp -- id )
743 isp 0 is current, then 1, etc.
744 each include file has unique non-zero id.
746 (INCLUDE-FILE-LINE)
747 ( isp -- line )
749 (INCLUDE-FILE-NAME)
750 ( isp -- addr count )
751 current file name; at PAD.
753 (INCLUDE)
754 ( addr count soft? system? -- )
755 push current file to the include stack, open a new one. used internally.
757 $INCLUDE "str"
758 immediate word.
760 $INCLUDE-ONCE "str"
761 includes file only once; unreliable on shitdoze, i believe.
762 immediate word.
764 HANDLE:NEW
765 ( typeid -- hx )
766 allocate a new handle with the given typeid. typeid is just a number
767 without any special meaning. any number except "-1" is allowed.
768 new handle size is 0.
770 HANDLE:FREE
771 ( hx -- )
772 deallocate a handle, free all allocated handle memory.
773 0 is allowed.
775 HANDLE:TYPEID@
776 ( hx -- typeid )
778 HANDLE:TYPEID!
779 ( typeid hx -- )
781 HANDLE:SIZE@
782 ( hx -- size )
783 0 is allowed.
785 HANDLE:SIZE!
786 ( size hx -- )
787 resize memory allocated for handle data.
789 HANDLE:USED@
790 ( hx -- used )
791 "used" is just a number, which means nothing for most code.
792 it is used to implement dynamic arrays.
793 0 is allowed.
795 HANDLE:USED!
796 ( size hx -- )
798 HANDLE:C@
799 ( idx hx -- value )
801 HANDLE:W@
802 ( idx hx -- value )
804 HANDLE:@
805 ( idx hx -- value )
807 HANDLE:C!
808 ( value idx hx -- value )
810 HANDLE:W!
811 ( value idx hx -- )
813 HANDLE:!
814 ( value idx hx -- )
816 HANDLE:LOAD-FILE
817 ( addr count -- stx / FALSE )
818 load file with the given name into newly allocated handle.
819 return 0 (FALSE) if there is no such file.
822 ( -- rega )
823 get address register contents.
826 ( rega -- )
827 set address register contents.
829 A-SWAP
830 ( rega -- olda )
831 swap TOS and the address register.
833 +1>A
834 ( -- )
835 increment the address register.
838 ( -- | rega )
839 copy the address register to the return stack.
842 ( | rega -- )
843 restore the address register from the return stack.
846 ( -- byte )
849 ( -- word )
852 ( -- value )
855 ( byte -- )
858 ( word -- )
861 ( value -- )
863 C@A+
864 ( idx -- byte )
865 safe way to access both dictionary memory, and handle memory.
866 "idx" is used as offset from address register contents.
868 W@A+
869 ( idx -- word )
870 safe way to access both dictionary memory, and handle memory.
871 "idx" is used as offset from address register contents.
874 ( idx -- value )
875 safe way to access both dictionary memory, and handle memory.
876 "idx" is used as offset from address register contents.
878 C!A+
879 ( byte idx -- )
880 safe way to access both dictionary memory, and handle memory.
881 "idx" is used as offset from address register contents.
883 W!A+
884 ( word idx -- )
885 safe way to access both dictionary memory, and handle memory.
886 "idx" is used as offset from address register contents.
889 ( value idx -- )
890 safe way to access both dictionary memory, and handle memory.
891 "idx" is used as offset from address register contents.
893 DEBUG:(DECOMPILE-CFA)
894 ( cfa -- )
896 GET-MSECS
897 ( -- u32 )
899 DEFER (UFO-INTERPRET-FINISHED)
900 ( -- )
901 this is called by INTERPRET when it is out of input stream. internally,
902 it simply sets a flag to tell the VM that it should stop.
905 HERE
906 ( -- dp )
907 push current dictionary pointer to the data stack.
908 NOTE: there are actually two DPs -- normal, and temporary. "(DP-TEMP)" is
909 the temp one, and if it is 0, "(DP)" is used. UrForth has 1MB temp area
910 (that's where PAD is too), it had different addresses, and vocabularies
911 created in that area are not linked to the main voclink list. this is used,
912 for example, in locals engine, to store names of locals. so if you're using
913 locals in your word, do not use temp area while compiling that word.
915 LATEST-LFA
916 ( -- lfa )
917 push LFA of the latest defined word in the current vocabulary. note that
918 "smudge" bit doesn't matter here, it is always the last word you created
919 header for. this includes "nonamed" words (which have empty string as a name).
921 NOOP
922 ( -- )
923 does nothing. at all.
925 COMPILER:(TRACE-COLON) DEFER
926 ( -- )
927 this defered word is called in colon, after creating word header and CFA.
928 you can compile your own debug code into the new word.
930 COMPILER:(TRACE-SEMI)
931 ( -- )
932 this is called by semicolon, right before compiling "(EXIT)" and such.
933 you can compile your own debug code into the new word.
935 COMPILER:(TRACE-DOES)
936 ( -- )
937 this is called by "DOES>".
938 you can compile your own debug code into the new word.
940 COMPILER:(CTLID-COLON)
941 ( -- ctlid-colon )
942 semicolon expects this on the data stack.
944 ' <name>
945 ( -- cfa )
946 find word, push its CFA to the data stack. note that the tick
947 is NOT immediate. use "[']" if you need to compile next word CFA.
950 start new word definition.
953 end new word definition.
955 ALIAS oldword newword
956 ( -- )
957 "newword" will do exactly the same as "oldword". word attributes
958 will be copied too (hidden, immediate, etc.).
960 LATEST-CFA
961 ( -- cfa )
963 LATEST-PFA
964 ( -- pfa )
966 LATEST-NFA
967 ( -- nfa )
969 LATEST-SFA
970 ( -- sfa )
972 ~AND
973 ( a b -- a&~b )
975 SWAP!
976 ( addr value -- )
979 ( value addr -- )
981 ~AND!
982 ( value addr -- )
984 XOR!
985 ( value addr -- )
987 IMMEDIATE
988 mark last defined word as immediate (or remove immediate mark if it is already set).
990 (HIDDEN)
991 mark last defined word as hidden. DO NOT USE. this is obsolete feature,
992 and it will be removed. it is here for compatibility with my other Forth system.
994 (PUBLIC)
995 the opposite of "(HIDDEN)".
997 -FIND-REQUIRED
998 alias for the tick.
1000 PARSE-SKIP-COMMENTS
1001 ( -- )
1002 skip all comments and blanks, multiline mode.
1004 PARSE-SKIP-LINE-COMMENTS
1005 skip all comments and blanks, single line mode.
1007 (SET-DEF-WORD-FLAGS)
1008 ( flg -- )
1009 add (OR) default flag for new words.
1010 word flags are:
1011   (WFLAG-IMMEDIATE)
1012   (WFLAG-SMUDGE)
1013   (WFLAG-NORETURN)
1014   (WFLAG-HIDDEN)
1015   (WFLAG-CBLOCK)
1016   (WFLAG-VOCAB)
1017   (WFLAG-SCOLON)
1018   (WFLAG-PROTECTED)
1020 (RESET-DEF-WORD-FLAGS)
1021 ( flg -- )
1022 remove (~AND) default flag for new words.
1024 <PUBLIC-WORDS>
1025 ( -- )
1026 all following words will be public.
1028 <HIDDEN-WORDS>
1029 ( -- )
1030 all following words will be hidden.
1032 <PROTECTED-WORDS>
1033 ( -- )
1034 all following words will be protected. you cannot redefine
1035 protected words.
1037 <UNPROTECTED-WORDS>
1038 ( -- )
1039 all following words will not be protected.
1041 ONLY
1042 ( -- )
1043 clear the wordlist stack.
1045 ALSO
1046 ( -- )
1047 push context vocabulary onto the wordlist stack.
1049 PREVIOUS
1050 ( -- )
1051 pop vocabulary from the wordlist stack, and make in context.
1053 DEFINITIONS
1054 ( -- )
1055 make context vocabulary also current. "current" is the vocabulary
1056 that will receive new word definitions. "context" is the vocabulary
1057 that will be used to search words.
1060 ( a -- a+1 )
1063 ( a -- a+2 )
1066 ( a -- a+2 )
1069 ( a -- a-1 )
1072 ( a -- a-2 )
1075 ( a -- a-2 )
1078 ( n -- n==0 )
1081 ( n -- n<>0 )
1084 ( n -- n==0 )
1087 ( n -- n==0 )
1090 ( n -- n<>0 )
1093 ( n -- n<>0 )
1095 NOTNOT
1096 ( a -- !!a )
1099 ( a -- |a| )
1101 SIGN?
1102 ( n -- -1|0|1 )
1104 NEGATE
1105 ( n -- -n )
1107 LSHIFT
1108 ( n count -- n )
1110 RSHIFT
1111 ( n count -- n )
1113 ARSHIFT
1114 ( n count -- n )
1117 ( n count -- n )
1120 ( n count -- n )
1123 ( n count -- n )
1126 ( n count -- n )
1128 LO-WORD
1129 ( a -- a&0xffff )
1131 HI-WORD
1132 ( a -- [a>>16]&0xffff )
1134 LO-BYTE
1135 ( a -- a&0xff )
1137 HI-BYTE
1138 ( a -- [a>>8]&0xff )
1141 ( addr -- )
1144 ( addr -- )
1147 ( n addr -- )
1150 ( n addr -- )
1153 ( addr -- )
1156 ( addr -- )
1158 BCOUNT
1159 ( addr -- addr+1 count )
1161 COUNT
1162 ( addr -- addr+4 count )
1165 ( -- )
1167 DECIMAL
1168 ( -- )
1170 OCTAL
1171 ( -- )
1173 BINARY
1174 ( -- )
1176 WITHIN
1177 ( value a b -- value>=a&&value<b )
1179 UWITHIN
1180 ( value a b -- value>=a&&value<b )
1182 BOUNDS?
1183 ( value a b -- value>=a&&value<=b )
1184 numbers are unsigned.
1186 (HANDLE-ADDR?)
1187 ( addr -- )
1188 check if the given addres is actually a handle.
1190 COMPILER:SET-SMUDGE
1191 ( -- )
1192 set "smudge" bit for the latest word.
1194 COMPILER:RESET-SMUDGE
1195 ( -- )
1196 reset "smudge" bit for the latest word.
1198 COMPILER:SET-WARG
1199 ( warg -- )
1200 set argument type for the latest word. each word has "argument type" field,
1201 which inditates word argument type in the compiled code. arguments are:
1202   (WARG-NONE)
1203   (WARG-BRANCH)
1204   (WARG-LIT)
1205   (WARG-C4STRZ)
1206   (WARG-CFA)
1207   (WARG-CBLOCK)
1208   (WARG-VOCID)
1209   (WARG-C1STRZ)
1211 (WARG-MASK)
1212 ( -- mask )
1213 this mask can be used to get only argument type bits from the first NFA cell.
1215 COMPILER:(GET-NEW-WORD-FLAGS)
1216 ( -- flags )
1217 get sanitized new word flags. currently, only "hidden" and "protected" flags
1218 are retained, all other flags will be reset.
1220 COMPILER:(CREATE-HEADER)
1221 ( addr count -- )
1222 create new named word header with the default flags. additionally, sets
1223 "smudge" flag on the new word.
1225 COMPILER:(CREATE-NAMELESS)
1226 ( -- cfa )
1227 create new nameless word header with the default flags. additionally, sets
1228 "smudge" and "hidden" flags on the new word.
1229 return CFA address of the new word. CFA contents is not filled yet.
1231 COMPILER:(MK-CONST-VAR)
1232 ( value cfaidx -- )
1233 don't bother using this.
1235 COMPILER:FORTH-WORD?
1236 ( cfa -- bool )
1237 check if the given word is normal Forth word (i.e. defined with the colon).
1239 COMPILE
1240 ( cfa -- )
1241 compiles CFA to be executed.
1243 use the following words to compile branch destinations. this way your code
1244 will be independent of branch instruction operand format.
1246 ;; usage:
1247 ;;  compile (0branch)
1248 ;;  (mark>)
1249 ;;  ...
1250 ;;  (resolve>)
1252 ;;  (<mark)
1253 ;;  ...
1254 ;;  compile (branch)
1255 ;;  (<resolve)
1257 COMPILER:(BRANCH-ADDR!)
1258 ( destaddr addr -- )
1259 write "branch to destaddr" address to addr.
1261 COMPILER:(BRANCH-ADDR@)
1262 ( addr -- dest )  @ ;
1263 read branch address.
1266 COMPILER:(<J-MARK)
1267 ( -- addr )
1268 return addr suitable for "(<J-RESOLVE)".
1270 COMPILER:(<J-CHAIN)
1271 ( addr -- addr )
1272 use after "(<J-MARK)" to reserve jump and append it to jump chain.
1274 COMPILER:(<J-RESOLVE)
1275 ( addr -- )
1276 patch "forward jump" address to HERE. "addr" is the result of "(<J-MARK)".
1278 COMPILER:(MARK-J>)
1279 reserve room for branch address, return addr suitable for "(RESOLVE-J>)".
1281 COMPILER:(CHAIN-J>)
1282 use after "(MARK-J>)" to reserve jump and append it to jump chain.
1284 COMPILER:(RESOLVE-J>)
1285 ( addr -- )
1286 compile "forward jump" (possibly chain) from address to HERE. addr is the
1287 result of "(MARK-J>)". this resolves the whole "jump chain".
1290 COMPILER:?PAIRS
1291 ( a b -- )
1292 throw error if a <> b.
1294 ?2PAIRS
1295 ( a b c -- )
1296 throw error if a <> b and a <> c.
1298 LITERAL
1299 ( C:n -- )
1300 ( E:n -- n )
1301 compile number from the data stack as literal. NOT IMMEDIATE.
1303 IMM-LITERAL
1304 ( C:n -- )
1305 ( E:n -- n )
1306 immediate version of "LITERAL".
1308 STRLITERAL
1309 ( C:addr count -- )
1310 ( E: -- addr count )
1312 IMM-STRLITERAL
1313 immediate version of the previous word.
1315 CFALITERAL
1316 ( C:cfa -- )
1317 ( E:cfa -- cfa )
1319 IMM-CFALITERAL
1320 ( C:cfa -- )
1321 ( E:cfa -- cfa )
1323 [COMPILE] <wordname>
1324 force the next word to be compiled as normal word, even if it is an immediate one.
1327 compile next word CFA as CFA literal.
1329 COMPILER:(COMPILE-CFA-LITERAL)
1330 ( cfa -- )
1331 compile cfa literal to be compiled. ;-)
1333 COMPILER:END-COMPILE-FORTH-WORD
1334 ( -- )
1335 push colon ctlid and call ";".
1338 COMPILE <wordname>
1339 compile next word to the currently defining word.
1341 [CHAR] <char>
1342 ( -- ch )
1343 push/compile first char of the next word as char code.
1344 note that words with more than one char will cause an error.
1346 RECURSE
1347 recursively call the currently defining word. this is required
1348 due to currently defining word being invisible yet (because it
1349 is not finished).
1351 RECURSE-TAIL
1352 tail-call recursion.
1354 CONSTANT <name>
1355 ( value -- )
1356 create new constant.
1358 VARIABLE <name>
1359 ( value -- )
1360 create new variable.
1362 (CREATE)
1363 ( addr count -- )
1364 this is what "CREATE" is using to create a new word.
1366 CREATE <name>
1367 ( -- )
1368 create new word. when executed, this new word will push its PFA.
1369 note that new word is not smudged.
1371 CREATE;
1372 ( -- )
1373 finish CREATEd word. this is required to correctly set SFA.
1374 note that "DOES>" automatically takes care of SFA, so you don't have
1375 to call this if you're using "DOES>".
1377 (DOES>)
1378 ( doer-addr -- )
1379 patch CREATEd word. put doer address to its CFA, VM will do the rest.
1380 this is used internally by the compiler.
1382 (SET-DOER)
1383 ( doer-pfa cfa -- )
1384 makes CFA word to execute "doer-pfa" as doer.
1385 this is used internally by the compiler. do not try to understand this.
1387 DOES>
1388 ( -- )  ( pfa )
1389 the usual Forth "CREATE" -- "DOES>" support.
1391 4 CONSTANT CELL
1392 ANS idiocity.
1394 ALIAS 4U* CELLS  ( n -- n*cells )
1395 ANS idiocity.
1397 ALIAS 4+  CELL+  ( n -- n+cell )
1398 ANS idiocity.
1400 ALIAS 4-  CELL-  ( n -- n-cell )
1401 ANS idiocity.
1403 +CELLS
1404 ( a n -- a+n*cells )
1405 ANS idiocity.
1407 -CELLS
1408 ( a n -- a+n*cells )
1409 ANS idiocity.
1411 .( text)
1412 immediately print the text.
1414 ." text"
1415 compile text printer.
1417 N-ALLOT
1418 ( n -- stard-addr )
1419 allocate n *bytes* in the current DP, return the address of
1420 the first allocated byte.
1422 ALLOT
1423 ( n -- )
1424 allocate n *bytes* in the current DP.
1426 ALIGN-HERE
1427 ( -- )
1428 align DP to 4-byte boundary.
1430 COMPILER:(NEW-WORDLIST)
1431 ( parentvocid need-hashtable? -- vocid )
1432 create new empty wordlist.
1434 COMPILER:(CREATE-NAMED-VOCAB)
1435 ( vocid addr count -- )
1436 create vocabulary word.
1438 COMPILER:(CREATE-VOCAB) <vocname>
1439 ( vocid -- )
1440 create vocabulary word.
1442 COMPILER:(IS-VOC-WORD?)
1443 ( cfa -- bool )
1444 check if the given CFA defined as a vocabulary header.
1446 COMPILER:(WORD->VOCID)
1447 ( cfa -- vocid )
1448 get vocid from the vocabulary word. doesn't check arguments.
1450 COMPILER:(VOCID-PARENT@)
1451 ( vocid -- vocid )
1452 get vocid parent vocabulary. return 0 if there is no parent.
1453 doesn't check arguments.
1455 COMPILER:(VOCID-PARENT!)
1456 ( parent-vocid vocid -- )
1457 set vocid parent vocabulary. doesn't check arguments.
1459 COMPILER:(VOCID-TYPEID@)
1460 ( vocid -- typeid )
1461 internal helper for STRUCT support.
1463 COMPILER:(VOCID-TYPEID!)
1464 internal helper for STRUCT support.
1466 (VOCABULARY-EX)
1467 ( addr count parent need-hashtbl? -- )
1468 useful low-level words to create vocabs with already parsed names.
1470 (VOCABULARY)
1471 ( addr count -- )
1473 (SIMPLE-VOCABULARY)
1474 ( addr count -- )
1475 creates vocabulary without a hash table.
1477 (NESTED-VOCABULARY)
1478 ( addr count -- )
1480 (SIMPLE-NESTED-VOCABULARY)
1481 ( addr count -- )
1483 VOCABULARY <vocname>
1485 SIMPLE-VOCABULARY <vocname>
1487 NESTED-VOCABULARY <vocname>
1489 SIMPLE-NESTED-VOCABULARY <vocname>
1491 VOCID: <vocname>
1492 ( -- vocid )
1493 return vocid for the given vocabulary. this word is immediate.
1495 VOC-LATEST
1496 ( vocid -- latest )
1497 return latest word LFA for the given vocid.
1499 ALSO-DEFS: <vocname>
1500 ( -- )
1501 this does "ALSO <vocname> DEFINITIONS"
1503 PREV-DEFS
1504 ( -- )
1505 this does "PREVIOUS DEFINITIONS".
1507 VOCAB-IF-NONE <vocname>
1508 create vocabulary if we don't have such word yet.
1510 NESTED-VOCAB-IF-NONE <vocname>
1511 create nested vocabulary if we don't have such word yet.
1513 -TO  ( n -- )  \ name
1514 decrement value by n.
1516 +TO  ( n -- )  \ name
1517 increment value by n.
1519 -1-TO  ( -- )  \ name
1520 decrement value by 1.
1522 +1-TO  ( -- )  \ name
1523 increment value by 1.
1525 0-TO  ( -- )  \ name
1526 write 0 to value.
1528 ... FORTH:(TO-EXTENDER) ...
1529 ( addr count FALSE -- addr count FALSE / TRUE )
1530 "TO" can be extended to support things it doesn't know about yet.
1531 after parsing a name, "(TO-EXTENDER)" will be called (this is
1532 scattered colon word). note that due to how scattered colon works,
1533 you'd better DON'T use "EXIT", but pass a flag if you need to stop
1534 further processing. also, do not forget to check the flag at the
1535 start of your extender, because some other extender may already
1536 did its work before yours.
1538 ... FORTH:(EXIT-EXTENDER) ...
1539 ( -- )
1540 this scattered colon word allows you to extend "EXIT". "EXIT" is
1541 the immediate word that compiles word leaving instructions. you
1542 can compile your cleanup code before the standard cleanup.
1544 ... FORTH:(INTERPRET-CHECK-WORD) ...
1545 ( addr count FALSE -- addr count FALSE / TRUE )
1546 this is called by INTERPRET before the standard word processing.
1548 ... FORTH:(INTERPRET-WORD-NOT-FOUND) ...
1549 ( addr count FALSE -- addr count FALSE / TRUE )
1550 this is called by INTERPRET when word resolution failed.
1553 UrForth supports cooperative multitasking. it is also used to implement
1554 interactive debugger. tasks are called "execution states", or simply
1555 "states".
1557 MTASK:NEW-STATE
1558 ( cfa -- stid )
1559 create new state, return state id.
1561 MTASK:FREE-STATE
1562 ( stid -- )
1563 free state. state id should be valid, and should not be an active state.
1565 MTASK:STATE-NAME@
1566 ( stid -- addr count )
1567 copy state name to PAD.
1569 MTASK:STATE-NAME!
1570 ( addr count stid -- )
1571 set new state name. maximum name length is 127 chars. state name
1572 should not include char with code 0.
1574 MTASK:STATE-FIRST
1575 ( -- stid )
1576 get first state in the list of all created states. this is used to
1577 iterate over all states.
1578 WARNING! do not mutate state list while iterating! result will be UB.
1580 MTASK:STATE-NEXT
1581 ( stid -- stid / 0 )
1582 get next state id. used to iterate over all states.
1583 WARNING! do not mutate state list while iterating! result will be UB.
1585 MTASK:YIELD-TO
1586 ( ... argc stid -- )
1587 yield to another state. move argc numbers from the current state data
1588 stack to the new state data stack. push args to the new state data
1589 stack, and then push current state id. i.e. new state data stack will
1590 look like this:
1591   ( ... argc old-stid )
1592 it is ok to swith to the currently active state (it is a no-op).
1594 MTASK:SET-SELF-AS-DEBUGGER
1595 ( -- )
1596 register current task as system debugger. you can yeild from the debugger
1597 after this.
1599 DEBUG:(BP)
1600 ( -- )
1601 breakpoint. debugger task receives debugge stid on the data stack,
1602 and `-1` as yield argument count. i.e. debugger stack will be:
1603   ( -1 old-stid )
1605 MTASK:DEBUGGER-RESUME
1606 ( stid -- )
1607 resume debugee execution.
1609 MTASK:DEBUGGER-SINGLE-STEP
1610 ( stid -- )
1611 execute one debuggee instruction, and return to debugger.
1612 this is basically "YIELD", but to use in the debugger
1613 (and it doesn't pass any arguments). debugger stack will be:
1614   ( -2 old-stid )
1616 MTASK:STATE-IP@
1617 ( stid -- ip )
1618 get state instruction pointer.
1620 MTASK:STATE-IP!
1621 ( ip stid -- )
1622 set state instruction pointer.
1624 MTASK:STATE-A>
1625 ( stid -- regA )
1626 get address register contents.
1628 MTASK:STATE->A
1629 ( rega stid -- )
1630 set address register contents.
1632 MTASK:STATE-USER@
1633 ( addr stid -- valie )
1634 get other state user area cell.
1636 MTASK:STATE-USER!
1637 ( value addr stid -- )
1638 set other state user area cell.
1640 MTASK:STATE-RPOPCFA@
1641 ( -- flag )
1642 VM has special mode when it gets next CFA from the return stack
1643 instead of the address pointed by IP. this is used to implement
1644 "EXECUTE", for example. use this word to retrieve that flag.
1646 MTASK:STATE-RPOPCFA!
1647 ( flag -- )
1648 VM has special mode when it gets next CFA from the return stack
1649 instead of the address pointed by IP. this is used to implement
1650 "EXECUTE", for example. use this word to set that flag.
1652 MTASK:ACTIVE-STATE
1653 ( -- stid )
1654 return state id of the currently executing state.
1656 MTASK:YIELDED-FROM
1657 ( -- stid / 0 )
1658 return state which called "MTASK:YIELD-TO" last.
1660 MTASK:STATE-SP@
1661 ( stid -- depth )
1662 get the data stack depth for the given state.
1664 MTASK:STATE-RP@
1665 ( stid -- depth )
1666 get the return stack depth for the given state.
1668 MTASK:STATE-LP@
1669 ( stid -- lp )
1670 get local stack ptr.
1672 MTASK:STATE-LBP@
1673 ( stid -- lbp )
1674 get local stack base ptr.
1676 MTASK:STATE-SP!
1677 ( depth stid -- )
1678 set the data stack depth for the given state.
1680 MTASK:STATE-RP!
1681 ( stid -- depth )
1682 set the return stack depth for the given state.
1684 MTASK:STATE-LP!
1685 ( lp stid -- )
1686 set local stack ptr.
1688 MTASK:STATE-LBP!
1689 ( lbp stid -- )
1690 set local stack base ptr.
1692 MTASK:STATE-DS@
1693 ( idx stid -- value )
1694 read the data stack of the given state. note that the index is bound-checked.
1696 MTASK:STATE-RS@
1697 ( idx stid -- value )
1698 read the return stack of the given state. note that the index is bound-checked.
1700 MTASK:STATE-LS@
1701 ( idx stid -- value )
1702 read the locals stack of the given state. note that the index is bound-checked.
1704 MTASK:STATE-DS!
1705 ( value idx stid -- )
1706 write the data stack of the given state. note that the index is bound-checked.
1707 i.e. if you want to push some value, increase stack depth first.
1709 MTASK:STATE-RS!
1710 ( value idx stid -- )
1711 write the return stack of the given state. note that the index is bound-checked.
1712 i.e. if you want to push some value, increase stack depth first.
1714 MTASK:STATE-LS!
1715 ( value idx stid -- )
1716 write the locals stack of the given state. note that the index is bound-checked.
1717 i.e. if you want to push some value, increase stack depth first.
1720 there are some words to work with TTY (only GNU/Linux).
1722 TTY:TTY?
1723 ( -- bool )
1724 check if input and output are valid TTY(s).
1726 TTY:RAW?
1727 ( -- bool )
1728 check if current TTY mode is raw.
1730 TTY:SIZE
1731 ( -- width height )
1732 get TTY size. for non-TTYs retur default 80x24.
1734 TTY:SET-RAW
1735 ( -- success-bool )
1736 switch TTY to raw mode.
1738 TTY:SET-COOKED
1739 ( -- success-bool )
1740 switch TTY to cooked mode.
1742 TTY:RAW-EMIT
1743 ( n -- )
1744 type char without any filtering or safety nets.
1746 TTY:RAW-TYPE
1747 ( addr count -- )
1748 type string without any filtering or safety nets.
1750 TTY:RAW-FLUSH
1751 ( -- )
1752 the output of the two words above is buffered. this words flushes
1753 the buffer. buffering is done because raw TTY is mostly used to
1754 build user interfaces, and sending accumulated terminal commands
1755 in one big chunk looks much better (most terminal emulators will
1756 process the whole chunk before refreshing their windows).
1758 TTY:RAW-READCH
1759 ( -- ch / -1 )
1760 -1 returned on error, or on EOF.
1761 read one char (without any interpretation) if TTY is in raw mode.
1762 note that 0 is a valid char (it is used to send Ctrl+Space in some
1763 terminal emulators). also note that there is no way to tell if we
1764 hit a EOF, or some error occured. in practice, it doesn't matter,
1765 because in both cases it means that TTY is unusable anymore.
1767 TTY:RAW-READY?
1768 ( -- bool )
1769 check if raw TTY has some data to read.