UrForth: accessors now call optimiser when compiling access code
[urasm.git] / dox / urforth.txt
blob3a511668c3b82bbdf9f33abd48132ef032e4da0b
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 note that "/MOD" and other such words are the exact opposites of what the
26 standard says. "/MOD" return stack is "( quot rem )". i.e. the remainder is
27 always on top. in 83/ANS standards TOS is the quotient.
29 "ERROR" word accepts address and counter, and is fatal error (it cannot be
30 CATCHed). there are "?ERROR" and "?NOT-ERROR" words to check error coditions
31 too.
33 "VARIABLE" expects initial value on the stack (like in FIG-Forth). but
34 "DEFER" doesn't, and initialises new defered words with "NOOP" by default.
36 note that "LITERAL" is not immediate. use "IMM-LITERAL" if you need immediate
37 version. the same is for "STRLITERAL" -- there is "IMM-STRLITERAL".
39 there is no "POSTPONE" word. i was never able to understand what the fuck it
40 does. so "[COMPILE]" simply compiles the next word CFA to the current word,
41 regardless of its "immediate" flag. and "COMPILE" makes the current compiling
42 word compile next word on execution.
44 always use "COMPILE," to compile CFAs to the current word. this guarantees
45 that your code will survive internal VM changes (mostly). also, look into
46 "20-base-creatori.f" and "30-ifthen.f" to learn how to compile branches.
47 there are special words to put branch destinations, and if you will use
48 them instead of direct "!" or ",", your code will have a better chance to
49 work if i'll change "BRANCH" to be relative, for example.
52 there is "CASE" thing there. in addition to normal "OF", it has several more:
53   "NOT-OF", "<OF", "<=OF", ">OF", ">=OF", "U<OF", "U<=OF",
54   "U>OF", "U>=OF", "&OF", "AND-OF", "~AND-OF", "WITHIN-OF",
55   "UWITHIN-OF", "BOUNDS-OF"
57 there is also special "?OF", which takes the prepared boolean. basically, other
58 "OF"s could be written like this:
59   "OF" -> "DUP <number> = ?OF" (note "DUP" here)
61 and there are two Very Special forms: "IF-OF" and "IFNOT-OF". they are useful
62 to build several conditional checks in a row without endless "endif" sequence
63 at the end. the difference is that "IF-OF" doesn't do "DROP" on success. but
64 note that if you will not use "OTHERWISE", "ENDCASE" will compile "DROP" anyway.
66 ah, yes. there is optional "OTHERWISE" clause. it simply forbids dropping TOS
67 in "ENDCASE" (and doesn't drop anything itself). i.e. you can use it if none
68 of the cases were hit, and check the result in any way you want. it is basically
69 the same as "TRUE IF-OF".
72 some global variables are state-local. also, each state has its own TIB,
73 independent of other states.
75 state-local vars are:
76 BASE
77 ( -- base-addr )
78 current number base.
80 TIB
81 ( -- addr )
82 current TIB.
84 >IN
85 ( -- ofs )
86 offset in current TIB.
88 PAD
89 ( -- pad )
90 return PAD address. this memory area can be used for storing temporary
91 values (like strings). you can assume to have at least 4096 bytes there.
92 WARNING! some words may use PAD for their own needs. this is mostly
93          words which does some string manipulation, like building strings
94          from parts, and such. note that number conversion buffer is
95          independent of PAD.
97 (STD-TIB-ADDR)
98 ( -- )
99 default TIB address. WARNING! if this user var contains a handle, that
100 handle will be freed on destroying the task. if you want to replace the
101 default TIB, make sure that you will free the old handle (if it is a handle).
103 STATE
104 ( -- addr )
105 current system state. `0` for interpretation, any other value for compilation.
107 CONTEXT
108 ( -- addr )
109 context vocabulary, i.e. vocabulary that will be used to look for words. note
110 that there is a stack of vocabularies there (see "ALSO" and other words), and
111 all of them will be searched after context one.
113 CURRENT
114 ( -- addr )
115 this is vocabulary that will be used to record new words. it is only checked
116 for duplicate word definitions, but otherwise is not participating in word
117 searching mechanics.
119 (SELF)
120 ( -- addr )
121 this is used in OOF. it holds address of the active class instance (object).
123 (USER-INTERPRET-NEXT-LINE)
124 ( -- addr )
125 this holds the address of a word which will be called by INTERPRET when it
126 hits EOL, and needs to read a new line to interpret (or compile).
128 (EXC-FRAME-PTR)
129 ( -- addr )
130 this is used in THROW/CATCH implementation, and holds current exception frame
131 address.
133 (USER-VAR-USED)
134 ( -- uvar-used-addr )
135 address of the variable contains first free user area address.
137 (USER-VAR-ADDR)
138 ( -- uvar-begin-addr )
139 start address of the user area.
141 (USER-VAR-SIZE)
142 ( -- uvar-size )
143 maximum user area size in bytes.
147 DEBUG:DUMP-STACK
148 ( -- )
149 dump data stack
151 DEBUG:BACKTRACE
152 ( -- )
153 show current backtrace (slow!)
155 DEBUG:DECOMPILE name
156 ( -- )
157 decompile given forth word.
159 SP0!
160 ( -- )
161 clear data stack.
163 RP0!
164 ( -- )
165 clear return stack.
167 note that address for memory operations may be a handle too. with handles,
168 low bits are used as offset, so you can directly address some bytes in handle
169 data area. currently, low 12 bits are reserved for offset, so you can address
170 4096 bytes inside a handle. but don't hardcode it, use "FORTH:(MAX-HANDLE-OFS)"
171 constant to get the maximum allowed offset (because it may change in the future).
173 also, UrForth is 32-bit system, and stores all numbers as little-endian. this
174 will not change, so you can write your code without checking cell size, or
175 byte order.
179 ( addr -- value8 )
180 load 8-bit value.
183 ( addr -- value16 )
184 load 16-bit value.
187 ( addr -- value32 )
188 load 32-bit value.
191 ( val8 addr -- )
192 store 8-bit value.
195 ( val16 addr -- )
196 store 16-bit value.
199 ( val32 addr -- )
200 store 32-bit value.
202 C!+1>A
203 ( byte -- )
204 store byte via A, advance A by 1.
206 W!+2>A
207 ( word -- )
208 store word via A, advance A by 2.
210 !+4>A
211 ( value -- )
212 store cell via A, advance A by 4.
214 C@+1>A
215 ( -- byte )
216 load byte via A, advance A by 1.
218 W@+2>A
219 ( -- word )
220 load word via A, advance A by 2.
222 @+4>A
223 ( -- value )
224 load cell via A, advance A by 4.
226 (DIRECT:@)
227 ( -- val32 )
228 address is code argument.
230 (DIRECT:0:!)
231 ( -- )
232 address is code argument.
234 (DIRECT:1:!)
235 ( -- )
236 address is code argument.
238 (DIRECT:-1:!)
239 ( -- )
240 address is code argument.
242 (DIRECT:!)
243 ( val32 -- )
244 address is code argument.
246 (DIRECT:+!)
247 ( val32 -- )
248 address is code argument.
250 (DIRECT:-!)
251 ( val32 -- )
252 address is code argument.
254 (DIRECT:+:@)
255 ( addr -- val32 )
256 addr offset is code argument. this is used for struct access.
258 (DIRECT:+:!)
259 ( val32 addr -- )
260 addr offset is code argument. this is used for struct access.
262 ~AND
263 ( a b -- a&~b )
265 SWAP!
266 ( addr value -- )
268 SWAP-C!
269 ( addr value -- )
271 SWAP-W!
272 ( addr value -- )
275 ( value addr -- )
277 OR-C!
278 ( value addr -- )
280 OR-W!
281 ( value addr -- )
283 ~AND!
284 ( value addr -- )
286 ~AND-C!
287 ( value addr -- )
289 ~AND-W!
290 ( value addr -- )
292 XOR!
293 ( value addr -- )
295 XOR-C!
296 ( value addr -- )
298 XOR-W!
299 ( value addr -- )
302 ( val8 -- )
303 compile 8-bit value.
306 ( val16 -- )
307 compile 16-bit value.
310 ( val -- )
311 compile 32-bit value.
314 (LIT)
315 ( -- n )
316 read 4 bytes immediately following this word, and push them
317 to the data stack. adjust IP to skip those bytes.
319 (LITCFA)
320 ( -- n )
321 read 4 bytes immediately following this word, and push them
322 to the data stack. adjust IP to skip those bytes. this is
323 the same as "(LIT)", but used to store CFAs of words. using
324 different words for different data types helps the debugger
325 and the decompiler.
327 (LITVOCID)
328 ( -- n )
329 the same as "(LIT)", but for vocids.
331 (LITSTR8)
332 ( -- addr count )
333 inline byte-counted string literal. note that the string
334 always have a trailing zero byte (which is not counted),
335 and always padded so it ends on a 4-byte boundary.
337 (BRANCH) ( -- )
338 read next 4 bytes, and set IP to that address.
340 (TBRANCH)
341 ( flag -- )
342 skip next 4 bytes if `flag` is 0, otherwise perform "(BRANCH)".
344 (0BRANCH)
345 ( flag -- )
346 skip next 4 bytes if `flag` is not 0, otherwise perform "(BRANCH)".
348 (+0BRANCH)
349 ( num -- )
350 skip next 4 bytes if `num` is positive or 0, otherwise perform "(BRANCH)".
352 (+BRANCH)
353 ( num -- )
354 skip next 4 bytes if `num` is positive (but not 0), otherwise perform "(BRANCH)".
356 (-BRANCH)
357 ( num -- )
358 skip next 4 bytes if `num` is negative, otherwise perform "(BRANCH)".
360 (OR-BRANCH)
361 ( !0 -- !0 ) -- jmp
362 ( 0 -- ) -- no jmp
363 useful for short-circuit logic, "OR" case. if TOS is not zero, do not
364 touch the stack, and perform the jump. if TOS is zero, drop zero, and
365 do not jump.
367 (AND-BRANCH)
368 ( 0 -- 0 ) -- jmp
369 ( !0 -- ) -- no jmp
370 useful for short-circuit logic, "AND" case. if TOS is zero, do not touch
371 the stack, and perform the jump. if TOS is not zero, drop zero, and do not
372 jump.
374 (?DUP-0BRANCH)
375 ( 0 -- ) -- jmp
376 ( !0 -- !0 ) -- no jmp
377 can be used to optimise "?DUP IF".
379 (CASE-BRANCH)
380 ( 0 -- ) -- jmp
381 ( n !0 -- ) -- no jmp
382 useful to implement "CASE". if TOS is zero, drop TOS and perform the jump.
383 if TOS is non-zero, drop TOS and one more value ("CASE" value), do not jump.
385 (DATASKIP)
386 ( -- )
387 read next 4 bytes, advance IP. then increment IP by the read number.
388 this is used to tell the decompiler that it should skip some inline
389 data instead of trying to decompile it.
391 EXECUTE
392 ( cfa )
393 pop word CFA address, and execute it.
395 EXECUTE-TAIL
396 ( cfa )
397 pop word CFA address, and execute it. returning from the executed
398 word will return to the upper word. i.e. this performs a tail call.
400 (FORTH-CALL)
401 ( pfa )
402 call forth code. it should end with "FORTH:(EXIT)".
404 (FORTH-TAIL-CALL)
405 ( pfa )
406 tail-calls forth code. it should end with "FORTH:(EXIT)".
408 (EXIT)
409 internal compiler word, placed at the end of colon definition.
410 pops a number from return stack, and sets IP to that number.
412 (L-ENTER)
413 this word is used to implement local variables and arguments.
414 it doesn't matter how it works, you should not used it anyway.
415 read the source code, if you're curious.
417 (L-LEAVE)
418 this word is used to implement local variables and arguments.
419 it doesn't matter how it works, you should not used it anyway.
420 read the source code, if you're curious.
422 (LOCAL@)
423 ( idx -- value )
424 read local variable with the given index. indices are 1-based.
426 (LOCAL!)
427 ( value idx -- )
428 write local variable with the given index. indices are 1-based.
431 ( n -- n n )
432 duplicates a number on the data stack.
434 ?DUP
435 ( n -- n n ) | ( 0 -- 0 )
436 duplicates a number on the data stack, but only if that number is not 0.
438 2DUP
439 ( n0 n1 -- n0 n1 n0 n1 )
441 DROP
442 ( n -- )
444 2DROP
445 ( n0 n1 -- )
447 SWAP
448 ( n0 n1 -- n1 n0 )
450 2SWAP
451 ( n0 n1 -- n1 n0 )
453 OVER
454 ( n0 n1 -- n0 n1 n0 )
456 2OVER
457 ( n0 n1 -- n0 n1 n0 )
460 ( n0 n1 n2 -- n1 n2 n0 )
462 NROT
463 ( n0 n1 n2 -- n2 n0 n1 )
466 ( a b -- b )
468 TUCK
469 ( a b -- b a b )
471 RDUP
472 ( n -- n n )
473 the same as "DUP", but for the return stack.
475 RDROP
476 ( n -- )
477 the same as "DROP", but for the return stack.
479 RSWAP
480 ( n0 n1 -- n1 n0 )
481 the same as "SWAP", but for the return stack.
483 ROVER
484 ( n0 n1 -- n0 n1 n0 )
485 the same as "OVER", but for the return stack.
487 RROT
488 ( n0 n1 n2 -- n1 n2 n0 )
489 the same as "ROT", but for the return stack.
491 RNROT
492 ( n0 n1 n2 -- n2 n0 n1 )
493 the same as "NROT", but for the return stack.
496 ( n -- | n )
497 move number from the data stack to the return stack.
500 ( | n -- n )
501 move number from the return stack to the data stack.
504 ( | n -- n | n )
505 copy number from the return stack to the data stack.
507 PICK
508 ( idx -- n )
509 copy n-th element at the data stack. "0 PICK" is the same as "DUP".
511 RPICK
512 ( idx -- n )
513 the same as "PICK", but for the return stack.
515 ROLL
516 ( idx -- n )
517 move n-th element at the data stack to the top. "1 ROLL" is the same as "SWAP".
519 RROLL
520 ( idx -- n )
521 the same as "ROLL", but for the return stack.
523 REFILL
524 ( -- eofflag )
525 read next input line. can cross include boundaries. pushes 0 if
526 there are no more input lines. TIB contents is undefined in this case.
528 REFILL-NOCROSS
529 ( -- eofflag )
530 read next input line. cannot cross include boundaries. pushes 0 if
531 there are no more input lines. TIB contents is undefined in this case.
533 (TIB-IN)
534 ( -- addr )
535 get address of the current TIB position.
536 WARNING! do not try to emulate "TIB-GETCH" and such with this word!
537          TIB usually ends with 0 byte, and if you will advance beyond
538          that 0, Bad Things will happen.
540 TIB-PEEKCH
541 ( -- char )
542 push current TIB char, do not advance >IN.
544 TIB-PEEKCH-OFS
545 ( ofs -- char )
546 peek TIB char with the given offset. "0 TIB-PEEKCH-OFS" is the same as "TIB-PEEKCH".
548 TIB-GETCH
549 ( -- char )
550 push current TIB char, advance >IN. it is safe to call this even
551 when you reached the end of TIB. in this case, returned char code
552 will be 0. i.e. "0" means "end of TIB".
554 TIB-SKIPCH
555 ( -- )
556 skip current TIB char. it is safe to call this even when you reached
557 the end of TIB.
560 (PARSE)
561 ( delim skip-leading-delim? -- addr count TRUE / FALSE )
562 does base TIB parsing; never copies anything.
563 as our reader is line-based, returns FALSE on EOL.
564 EOL is detected after skipping leading delimiters.
565 passing -1 as delimiter skips the whole line, and always returns FALSE.
566 finishing delimiter is always skipped.
568 PARSE-SKIP-BLANKS
569 ( -- )
570 skip all chars with codes <=32.
572 (PARSE-SKIP-COMMENTS)
573 ( allow-multiline? -- )
574 skip all blanks and comments. if multiline skip is not allowed, reaching
575 end of TIB while still waiting for the comment terminator is error.
576 single-line comments are ok, though.
578 PARSE-SKIP-LINE
579 ( -- )
580 advance >IN to the end of TIB.
582 PARSE-NAME
583 ( -- addr count )
584 parse with leading blanks skipping. doesn't copy anything.
585 return empty string on EOL.
587 PARSE
588 ( delim -- addr count TRUE / FALSE )
589 parse without skipping delimiters; never copies anything.
590 as our reader is line-based, returns FALSE on EOL.
591 passing 0 as delimiter skips the whole line, and always returns FALSE.
592 finishing delimiter is always skipped.
594 EMIT
595 ( n -- )
596 print char.
598 XEMIT
599 ( n -- )
600 "safe" char printer. all non-printable chars (including newline and such)
601 will be printed as "?".
603 LASTCR?
604 ( -- bool )
605 was last printed char a newline?
607 LASTCR!
608 ( bool -- )
609 force-set the flag for "LASTCR?" word.
612 ( -- )
613 print newline.
615 SPACE
616 ( -- )
617 print space.
619 SPACES
620 ( n -- )
621 print `n` spaces. if `n` is negative, prints nothing.
623 ENDCR
624 ( -- )
625 prints newline if the last printed char was not a newline.
627 TYPE
628 ( addr count -- )
629 print the string. negative count is ok, in this case the word prints nothing.
631 XTYPE
632 ( addr count -- )
633 the same as "TYPE", but uses "XEMIT".
635 FLUSH-EMIT
636 ( -- )
637 output can be buffered. it usually flushed when newline is printed, but
638 you can flush it manually using this word.
641 ( a b -- a+b )
644 ( a b -- a-b )
647 ( a b -- a*b )
650 ( a b -- a*b )
653 ( a b -- a/b )
656 ( a b -- a/b )
659 ( a b -- a%b )
661 UMOD
662 ( a b -- a%b )
664 /MOD
665 ( a b -- a/b, a%b )
666 note that the results are swaped, contrary to ANS idiocity.
667 i don't fuckin' know why ANS morons decided to make the stack
668 effect that contradicts the word name. "/MOD" clearly indicates
669 that quotient comes first.
671 U/MOD
672 ( a b -- a/b, a%b )
673 note that the results are swaped, contrary to ANS idiocity.
674 i don't fuckin' know why ANS morons decided to make the stack
675 effect that contradicts the word name. "/MOD" clearly indicates
676 that quotient comes first.
679 ( a b c -- a*b/c )
680 this uses 64-bit intermediate value.
683 ( a b c -- a*b/c )
684 this uses 64-bit intermediate value.
686 */MOD
687 ( a b c -- a*b/c a*b%c )
688 this uses 64-bit intermediate value.
689 note that the results are swaped, contrary to ANS idiocity.
690 i don't fuckin' know why ANS morons decided to make the stack
691 effect that contradicts the word name. "/MOD" clearly indicates
692 that quotient comes first.
695 ( a b c -- a*b/c )
696 this uses 64-bit intermediate value.
699 ( a b -- lo(a*b) hi(a*b) )
700 this leaves 64-bit result.
703 ( a b -- lo(a*b) hi(a*b) )
704 this leaves 64-bit result.
706 M/MOD
707 ( alo ahi b -- a/b a%b )
708 note that the results are swaped, contrary to ANS idiocity.
709 i don't fuckin' know why ANS morons decided to make the stack
710 effect that contradicts the word name. "/MOD" clearly indicates
711 that quotient comes first.
713 UM/MOD
714 ( alo ahi b -- a/b a%b )
715 note that the results are swaped, contrary to ANS idiocity.
716 i don't fuckin' know why ANS morons decided to make the stack
717 effect that contradicts the word name. "/MOD" clearly indicates
718 that quotient comes first.
721 ( a b -- a<b )
724 ( a b -- a<b )
727 ( a b -- a>b )
730 ( a b -- a>b )
733 ( a b -- a<=b )
736 ( a b -- a<=b )
739 ( a b -- a>=b )
742 ( a b -- a>=b )
745 ( a b -- a=b )
748 ( a b -- a<>b )
751 ( a -- !a )
753 LAND
754 ( a b -- a&&b )
755 logical "and".
758 ( a b -- a||b )
759 logical "or".
762 ( a b -- a&b )
763 bitwise "and".
766 ( a b -- a|b )
767 bitwise "or".
770 ( a b -- a^b )
771 bitwise "xor".
773 BITNOT
774 ( a -- ~a )
777 ( u -- u<<1 )
780 ( u -- u<<2 )
783 ( u -- u<<3 )
786 ( n -- n>>1 )
789 ( n -- n>>2 )
792 ( n -- n>>3 )
795 ( u -- u>>1 )
798 ( u -- u>>2 )
801 ( u -- u>>3 )
804 ( n count -- )
805 arithmetic shift; positive `n` shifts to the left.
808 ( n count -- )
809 logical shift; positive `n` shifts to the left.
811 COMPILER:(UNESCAPE)
812 ( addr count -- addr new-count )
813 process string escapes. modifies string in-place. the resulting string is
814 never bigger than the source one. negative counts are allowed.
816 (BASED-NUMBER)
817 ( addr count allowsign? base -- num TRUE / FALSE )
818 tries to convert the given string to the number, using the given
819 default base. if "allowsign?" is non-zero, properly process leading
820 number sign. this words understands numbers in non-default bases too
821 (like "0x29a", for example).
825 switch to interpretation mode.
828 switch to compilation mode.
830 (CREATE-WORD-HEADER)
831 ( addr count word-flags -- )
832 create word header in the dictionary, link word to the current vocabulary.
833 doesn't create CFA.
835 (CREATE-NAMELESS-WORD-HEADER)
836 ( word-flags -- )
837 create nameless word header in the dictionary, link word to the current vocabulary.
838 doesn't create CFA.
840 COMPILER:CFA,  ( cfa -- )
841 create CFA field.
843 FIND-WORD
844 ( addr count -- cfa TRUE / FALSE)
845 general word finder. checks wordlist stack, performs colon resolution.
847 (FIND-WORD-IN-VOC)
848 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
849 find word in the given wordlist. does no name resolution, and
850 doesn't look in parent wordlists.
852 FIND-WORD-IN-VOC
853 ( addr count vocid -- cfa TRUE / FALSE)
854 find word in the given wordlist. does no name resolution, and
855 doesn't look in parent wordlists. skips hidden words.
857 (FIND-WORD-IN-VOC-AND-PARENTS)
858 ( addr count vocid allowhidden? -- cfa TRUE / FALSE)
859 find word in the given wordlist. does no name resolution, but searches
860 parent wordlists if "vocid" is nested.
862 FIND-WORD-IN-VOC-AND-PARENTS
863 ( addr count vocid -- cfa TRUE / FALSE)
864 find word in the given wordlist. does no name resolution, but searches
865 parent wordlists if "vocid" is nested. skips hidden words.
867 COMPILER:?EXEC
868 check if we are in interpretation mode, and throws an error if we aren't.
870 COMPILER:?COMP
871 check if we are in compilation mode, and throws an error if we aren't.
874 string literal.
876 (VSP@)
877 ( -- vsp )
878 this word is used internally to work with wordlist stack.
880 (VSP!)
881 ( vsp -- )
882 this word is used internally to work with wordlist stack.
884 (VSP-AT@)
885 ( idx -- value )
886 this word is used internally to work with wordlist stack.
888 (VSP-AT!)
889 ( value idx -- )
890 this word is used internally to work with wordlist stack.
892 CFA->PFA
893 ( cfa -- pfa )
895 PFA->CFA
896 ( pfa -- cfa )
898 CFA->NFA
899 ( cfa -- nfa )
901 NFA->CFA
902 ( nfa -- cfa )
904 CFA->LFA
905 ( cfa -- lfa )
907 LFA->CFA
908 ( lfa -- cfa )
910 LFA->PFA
911 ( lfa -- pfa )
913 LFA->BFA
914 ( lfa -- bfa )
916 LFA->SFA
917 ( lfa -- sfa )
919 LFA->NFA
920 ( lfa -- nfa )
922 NFA->LFA
923 ( nfa -- lfa )
925 CFA->WEND
926 ( cfa -- wend-addr )
927 convert CFA to word end address.
929 DEBUG:IP->NFA
930 ( ip -- nfa / 0 )
931 convert instruction pointer to NFA. return 0 if cannot.
933 DEBUG:IP->FILE/LINE
934 ( ip -- addr count line TRUE / FALSE )
935 name is at PAD; it is safe to use PAD, because each task has its
936 own temp image.
938 DEBUG:IP->FILE-HASH/LINE
939 ( ip -- len hash line TRUE / FALSE )
940 return unique file hash and name length instead of string name.
941 used in debugger.
943 STRING:=
944 ( a0 c0 a1 c1 -- bool )
946 STRING:=CI
947 ( a0 c0 a1 c1 -- bool )
948 case-insensitive compare (only for ASCII).
950 STRING:HASH
951 ( addr count -- hash )
953 STRING:HASH-CI
954 ( addr count -- hash )
955 case-insensitive hash (only for ASCII).
957 ($DEFINE)
958 ( addr count -- )
959 add new conditional define. case-insensitive (for ASCII).
961 ($UNDEF)
962 ( addr count -- )
963 remove conditional define. case-insensitive (for ASCII).
965 ($DEFINED?)
966 ( addr count -- bool )
967 check if we have a conditional define. case-insensitive (for ASCII).
969 ERROR
970 ( addr count -- )
971 print error message and abort.
973 ?ERROR
974 ( errflag addr count -- )
975 if "errflag" is not zero, print error message and abort.
977 ?NOT-ERROR
978 ( errflag addr count -- )
979 if "errflag" is zero, print error message and abort.
981 (INCLUDE-BUILD-NAME)
982 ( addr count soft? system? -- addr count )
983 build include name, put it to PAD as cell-counted string.
984 return string address.
986 (INCLUDE-LINE-FOFS)
987 ( -- fofs )
988 return file offset of the current TIB line. offset is at the
989 start of the line.
991 (INCLUDE-LINE-SEEK)
992 ( lidx fofs -- )
993 move current include file position to the given one. doesn't
994 reset TIB, doesn't re-read line. sets file index to the given
995 one too. note that this index will be incremented on next REFILL.
997 (INCLUDE-DEPTH)
998 ( -- depth )
999 return number of items in the include stack.
1001 (INCLUDE-FILE-ID)
1002 ( isp -- id )
1003 isp 0 is current, then 1, etc.
1004 each include file has unique non-zero id.
1006 (INCLUDE-FILE-LINE)
1007 ( isp -- line )
1009 (INCLUDE-FILE-NAME)
1010 ( isp -- addr count )
1011 current file name; at PAD.
1013 (INCLUDE)
1014 ( addr count soft? system? -- )
1015 push current file to the include stack, open a new one. used internally.
1017 (INCLUDE-NO-REFILL)
1018 ( addr count soft? system? -- )
1019 the same as "(INCLUDE)", but doesn't do automatic "REFILL".
1021 (INCLUDE-DROP)
1022 ( -- )
1023 drop (close) current include file, and return to the previous one.
1024 doesn't do automatic "REFILL".
1026 $INCLUDE "str"
1027 immediate word.
1029 $INCLUDE-ONCE "str"
1030 includes file only once; unreliable on shitdoze, i believe.
1031 immediate word.
1033 HANDLE:NEW
1034 ( typeid -- hx )
1035 allocate a new handle with the given typeid. typeid is just a number
1036 without any special meaning. any number except "-1" is allowed.
1037 new handle size is 0.
1039 HANDLE:FREE
1040 ( hx -- )
1041 deallocate a handle, free all allocated handle memory.
1042 0 is allowed.
1044 HANDLE:TYPEID@
1045 ( hx -- typeid )
1047 HANDLE:TYPEID!
1048 ( typeid hx -- )
1050 HANDLE:SIZE@
1051 ( hx -- size )
1052 0 is allowed.
1054 HANDLE:SIZE!
1055 ( size hx -- )
1056 resize memory allocated for handle data.
1058 HANDLE:USED@
1059 ( hx -- used )
1060 "used" is just a number, which means nothing for most code.
1061 it is used to implement dynamic arrays.
1062 0 is allowed.
1064 HANDLE:USED!
1065 ( size hx -- )
1067 HANDLE:C@
1068 ( idx hx -- value )
1070 HANDLE:W@
1071 ( idx hx -- value )
1073 HANDLE:@
1074 ( idx hx -- value )
1076 HANDLE:C!
1077 ( value idx hx -- value )
1079 HANDLE:W!
1080 ( value idx hx -- )
1082 HANDLE:!
1083 ( value idx hx -- )
1085 HANDLE:LOAD-FILE
1086 ( addr count -- stx / FALSE )
1087 load file with the given name into newly allocated handle.
1088 return 0 (FALSE) if there is no such file.
1091 ( -- rega )
1092 get address register contents.
1095 ( rega -- )
1096 set address register contents.
1098 A-SWAP
1099 ( rega -- olda )
1100 swap TOS and the address register.
1102 +1>A
1103 ( -- )
1104 increment the address register.
1106 +2>A
1107 ( -- )
1108 increment the address register.
1110 +4>A
1111 ( -- )
1112 increment the address register.
1114 -1>A
1115 ( -- )
1116 decrement the address register.
1118 -2>A
1119 ( -- )
1120 decrement the address register.
1122 -4>A
1123 ( -- )
1124 decrement the address register.
1127 ( -- | rega )
1128 copy the address register to the return stack.
1131 ( | rega -- )
1132 restore the address register from the return stack.
1135 ( -- byte )
1138 ( -- word )
1141 ( -- value )
1144 ( byte -- )
1147 ( word -- )
1150 ( value -- )
1152 C@A+
1153 ( idx -- byte )
1154 safe way to access both dictionary memory, and handle memory.
1155 "idx" is used as offset from address register contents.
1157 W@A+
1158 ( idx -- word )
1159 safe way to access both dictionary memory, and handle memory.
1160 "idx" is used as offset from address register contents.
1163 ( idx -- value )
1164 safe way to access both dictionary memory, and handle memory.
1165 "idx" is used as offset from address register contents.
1167 C!A+
1168 ( byte idx -- )
1169 safe way to access both dictionary memory, and handle memory.
1170 "idx" is used as offset from address register contents.
1172 W!A+
1173 ( word idx -- )
1174 safe way to access both dictionary memory, and handle memory.
1175 "idx" is used as offset from address register contents.
1178 ( value idx -- )
1179 safe way to access both dictionary memory, and handle memory.
1180 "idx" is used as offset from address register contents.
1182 DEBUG:(DECOMPILE-CFA)
1183 ( cfa -- )
1185 GET-MSECS
1186 ( -- u32 )
1188 (UFO-INTERPRET-FINISHED-ACTION)
1189 ( -- )
1190 this is called by main loop when it is out of input stream. internally,
1191 it simply sets a flag to tell the VM that it should stop.
1193 (UFO-INTERPRET-NEXT-LINE)
1194 ( -- continue? )
1195 default word used to read next input line. return FALSE to exit from
1196 "INTERPRET".
1198 (INTERPRET-PARSE-NAME)
1199 ( -- addr count / FALSE )
1200 called by INTERPRET to read next word from the input stream. calls
1201 "(INTERPRET-NEXT-LINE)" to refill lines. return FALSE (without address)
1202 to exit from "INTERPRET", or next parsed word.
1204 (USER-INTERPRET-NEXT-LINE)
1205 user variable, holds address of "get next line" word. default value is
1206 CFA of "(UFO-INTERPRET-NEXT-LINE)".
1208 (INTERPRET-NEXT-LINE)
1209 ( -- continue? )
1210 peek "(USER-INTERPRET-NEXT-LINE)" and call read CFA.
1212 HERE
1213 ( -- dp )
1214 push current dictionary pointer to the data stack.
1215 NOTE: there are actually two DPs -- normal, and temporary. "(DP-TEMP)" is
1216 the temp one, and if it is 0, "(DP)" is used. UrForth has 1MB temp area
1217 (that's where PAD is too), it had different addresses, and vocabularies
1218 created in that area are not linked to the main voclink list. this is used,
1219 for example, in locals engine, to store names of locals. so if you're using
1220 locals in your word, do not use temp area while compiling that word.
1222 LATEST-LFA
1223 ( -- lfa )
1224 push LFA of the latest defined word in the current vocabulary. note that
1225 "smudge" bit doesn't matter here, it is always the last word you created
1226 header for. this includes "nonamed" words (which have empty string as a name).
1228 NOOP
1229 ( -- )
1230 does nothing. at all.
1232 COMPILER:(CTLID-COLON)
1233 ( -- ctlid-colon )
1234 semicolon expects this on the data stack.
1236 ' <name>
1237 ( -- cfa )
1238 find word, push its CFA to the data stack. note that the tick
1239 is NOT immediate. use "[']" if you need to compile next word CFA.
1242 start new word definition.
1245 end new word definition.
1247 ALIAS-FOR oldword IS newword
1248 ( -- )
1249 "newword" will do exactly the same as "oldword". word attributes
1250 will be copied too (hidden, immediate, etc.).
1252 LATEST-CFA
1253 ( -- cfa )
1255 LATEST-PFA
1256 ( -- pfa )
1258 LATEST-NFA
1259 ( -- nfa )
1261 LATEST-SFA
1262 ( -- sfa )
1264 ~AND
1265 ( a b -- a&~b )
1267 SWAP!
1268 ( addr value -- )
1271 ( value addr -- )
1273 ~AND!
1274 ( value addr -- )
1276 XOR!
1277 ( value addr -- )
1279 IMMEDIATE
1280 mark last defined word as immediate (or remove immediate mark if it is already set).
1282 (HIDDEN)
1283 mark last defined word as hidden. DO NOT USE. this is obsolete feature,
1284 and it will be removed. it is here for compatibility with my other Forth system.
1286 (PUBLIC)
1287 the opposite of "(HIDDEN)".
1289 -FIND-REQUIRED
1290 alias for the tick.
1292 PARSE-SKIP-COMMENTS
1293 ( -- )
1294 skip all comments and blanks, multiline mode.
1296 PARSE-SKIP-LINE-COMMENTS
1297 skip all comments and blanks, single line mode.
1299 (SET-DEF-WORD-FLAGS)
1300 ( flg -- )
1301 add (OR) default flag for new words.
1302 word flags are:
1303   (WFLAG-IMMEDIATE)
1304   (WFLAG-SMUDGE)
1305   (WFLAG-NORETURN)
1306   (WFLAG-HIDDEN)
1307   (WFLAG-CBLOCK)
1308   (WFLAG-VOCAB)
1309   (WFLAG-SCOLON)
1310   (WFLAG-PROTECTED)
1312 (RESET-DEF-WORD-FLAGS)
1313 ( flg -- )
1314 remove (~AND) default flag for new words.
1316 <PUBLIC-WORDS>
1317 ( -- )
1318 all following words will be public.
1320 <HIDDEN-WORDS>
1321 ( -- )
1322 all following words will be hidden.
1324 <PROTECTED-WORDS>
1325 ( -- )
1326 all following words will be protected. you cannot redefine
1327 protected words.
1329 <UNPROTECTED-WORDS>
1330 ( -- )
1331 all following words will not be protected.
1333 ONLY
1334 ( -- )
1335 clear the wordlist stack.
1337 ALSO
1338 ( -- )
1339 push context vocabulary onto the wordlist stack.
1341 PREVIOUS
1342 ( -- )
1343 pop vocabulary from the wordlist stack, and make in context.
1345 DEFINITIONS
1346 ( -- )
1347 make context vocabulary also current. "current" is the vocabulary
1348 that will receive new word definitions. "context" is the vocabulary
1349 that will be used to search words.
1352 ( a -- a+1 )
1355 ( a -- a+2 )
1358 ( a -- a+2 )
1361 ( a -- a-1 )
1364 ( a -- a-2 )
1367 ( a -- a-2 )
1370 ( n -- n==0 )
1373 ( n -- n<>0 )
1376 ( n -- n==0 )
1379 ( n -- n==0 )
1382 ( n -- n<>0 )
1385 ( n -- n<>0 )
1387 NOTNOT
1388 ( a -- !!a )
1391 ( a -- |a| )
1393 SIGN?
1394 ( n -- -1|0|1 )
1396 NEGATE
1397 ( n -- -n )
1399 LSHIFT
1400 ( n count -- n )
1402 RSHIFT
1403 ( n count -- n )
1405 ARSHIFT
1406 ( n count -- n )
1409 ( n count -- n )
1412 ( n count -- n )
1415 ( n count -- n )
1418 ( n count -- n )
1420 LO-WORD
1421 ( a -- a&0xffff )
1423 HI-WORD
1424 ( a -- [a>>16]&0xffff )
1426 LO-BYTE
1427 ( a -- a&0xff )
1429 HI-BYTE
1430 ( a -- [a>>8]&0xff )
1433 ( a b -- min[a,b] )
1436 ( a b -- max[a,b] )
1438 UMIN
1439 ( a b -- umin[a,b] )
1441 UMAX
1442 ( a b -- umax[a,b] )
1444 BSWAP16
1445 ( a -- n )
1447 BSWAP32
1448 ( a -- n )
1451 ( addr -- )
1454 ( addr -- )
1457 ( n addr -- )
1460 ( n addr -- )
1463 ( addr -- )
1466 ( addr -- )
1468 BCOUNT
1469 ( addr -- addr+1 count )
1471 COUNT
1472 ( addr -- addr+4 count )
1475 ( -- )
1477 DECIMAL
1478 ( -- )
1480 OCTAL
1481 ( -- )
1483 BINARY
1484 ( -- )
1486 WITHIN
1487 ( value a b -- value>=a&&value<b )
1489 UWITHIN
1490 ( value a b -- value>=a&&value<b )
1492 BOUNDS?
1493 ( value a b -- value>=a&&value<=b )
1494 numbers are unsigned.
1496 (HANDLE-ADDR?)
1497 ( addr -- )
1498 check if the given addres is actually a handle.
1500 COMPILER:SET-SMUDGE
1501 ( -- )
1502 set "smudge" bit for the latest word.
1504 COMPILER:RESET-SMUDGE
1505 ( -- )
1506 reset "smudge" bit for the latest word.
1508 COMPILER:SET-WARG
1509 ( warg -- )
1510 set argument type for the latest word. each word has "argument type" field,
1511 which inditates word argument type in the compiled code. arguments are:
1512   (WARG-NONE)
1513   (WARG-BRANCH)
1514   (WARG-LIT)
1515   (WARG-C4STRZ)
1516   (WARG-CFA)
1517   (WARG-CBLOCK)
1518   (WARG-VOCID)
1519   (WARG-C1STRZ)
1521 (WARG-MASK)
1522 ( -- mask )
1523 this mask can be used to get only argument type bits from the first NFA cell.
1525 COMPILER:(GET-NEW-WORD-FLAGS)
1526 ( -- flags )
1527 get sanitized new word flags. currently, only "hidden" and "protected" flags
1528 are retained, all other flags will be reset.
1530 COMPILER:(CREATE-HEADER)
1531 ( addr count -- )
1532 create new named word header with the default flags. additionally, sets
1533 "smudge" flag on the new word.
1535 COMPILER:(CREATE-NAMELESS)
1536 ( -- cfa )
1537 create new nameless word header with the default flags. additionally, sets
1538 "smudge" and "hidden" flags on the new word.
1539 return CFA address of the new word. CFA contents is not filled yet.
1541 COMPILER:(MK-CONST-VAR)
1542 ( value cfaidx -- )
1543 don't bother using this.
1545 COMPILER:FORTH-WORD?
1546 ( cfa -- bool )
1547 check if the given word is normal Forth word (i.e. defined with the colon).
1549 COMPILE
1550 ( cfa -- )
1551 compiles CFA to be executed.
1553 use the following words to compile branch destinations. this way your code
1554 will be independent of branch instruction operand format.
1556 ;; usage:
1557 ;;  compile (0branch)
1558 ;;  (mark>)
1559 ;;  ...
1560 ;;  (resolve>)
1562 ;;  (<mark)
1563 ;;  ...
1564 ;;  compile (branch)
1565 ;;  (<resolve)
1567 COMPILER:(BRANCH-ADDR!)
1568 ( destaddr addr -- )
1569 write "branch to destaddr" address to addr.
1571 COMPILER:(BRANCH-ADDR@)
1572 ( addr -- dest )  @ ;
1573 read branch address.
1575 COMPILER:(<J-MARK)
1576 ( -- addr )
1577 return addr suitable for "(<J-RESOLVE)".
1579 COMPILER:(<J-CHAIN)
1580 ( addr -- addr )
1581 use after "(<J-MARK)" to reserve jump and append it to jump chain.
1583 COMPILER:(<J-RESOLVE)
1584 ( addr -- )
1585 patch "forward jump" address to HERE. "addr" is the result of "(<J-MARK)".
1587 COMPILER:(MARK-J>)
1588 reserve room for branch address, return addr suitable for "(RESOLVE-J>)".
1590 COMPILER:(CHAIN-J>)
1591 use after "(MARK-J>)" to reserve jump and append it to jump chain.
1593 COMPILER:(RESOLVE-J>)
1594 ( addr -- )
1595 compile "forward jump" (possibly chain) from address to HERE. addr is the
1596 result of "(MARK-J>)". this resolves the whole "jump chain".
1599 COMPILER:?PAIRS
1600 ( a b -- )
1601 throw error if a <> b.
1603 ?2PAIRS
1604 ( a b c -- )
1605 throw error if a <> b and a <> c.
1607 LITERAL
1608 ( C:n -- )
1609 ( E:n -- n )
1610 compile number from the data stack as literal. NOT IMMEDIATE.
1612 IMM-LITERAL
1613 ( C:n -- )
1614 ( E:n -- n )
1615 immediate version of "LITERAL".
1617 STRLITERAL
1618 ( C:addr count -- )
1619 ( E: -- addr count )
1621 IMM-STRLITERAL
1622 immediate version of the previous word.
1624 CFALITERAL
1625 ( C:cfa -- )
1626 ( E:cfa -- cfa )
1628 IMM-CFALITERAL
1629 ( C:cfa -- )
1630 ( E:cfa -- cfa )
1632 [COMPILE] <wordname>
1633 force the next word to be compiled as normal word, even if it is an immediate one.
1636 compile next word CFA as CFA literal.
1638 COMPILER:(COMPILE-CFA-LITERAL)
1639 ( cfa -- )
1640 compile cfa literal to be compiled. ;-)
1642 COMPILE <wordname>
1643 compile next word to the currently defining word.
1645 [CHAR] <char>
1646 ( -- ch )
1647 push/compile first char of the next word as char code.
1648 note that words with more than one char will cause an error.
1650 RECURSE
1651 recursively call the currently defining word. this is required
1652 due to currently defining word being invisible yet (because it
1653 is not finished).
1655 RECURSE-TAIL
1656 tail-call recursion.
1658 CONSTANT <name>
1659 ( value -- )
1660 create new constant.
1662 VARIABLE <name>
1663 ( value -- )
1664 create new variable.
1666 (CREATE)
1667 ( addr count -- )
1668 this is what "CREATE" is using to create a new word.
1670 CREATE <name>
1671 ( -- )
1672 create new word. when executed, this new word will push its PFA.
1673 note that new word is not smudged.
1675 CREATE;
1676 ( -- )
1677 finish CREATEd word. this is required to correctly set SFA.
1678 note that "DOES>" automatically takes care of SFA, so you don't have
1679 to call this if you're using "DOES>".
1681 (DOES>)
1682 ( doer-addr -- )
1683 patch CREATEd word. put doer address to its CFA, VM will do the rest.
1684 this is used internally by the compiler.
1686 (SET-DOER)
1687 ( doer-pfa cfa -- )
1688 makes CFA word to execute "doer-pfa" as doer.
1689 this is used internally by the compiler. do not try to understand this.
1691 DOES>
1692 ( -- )  ( pfa )
1693 the usual Forth "CREATE" -- "DOES>" support.
1695 CELL
1696 ANS idiocity.
1698 CELLS
1699 ( n -- n*cells )
1700 ANS idiocity.
1702 CELL+
1703 ( n -- n+cell )
1704 ANS idiocity.
1706 CELL-
1707 ( n -- n-cell )
1708 ANS idiocity.
1710 +CELLS
1711 ( a n -- a+n*cells )
1712 ANS idiocity.
1714 -CELLS
1715 ( a n -- a+n*cells )
1716 ANS idiocity.
1718 .( text)
1719 immediately print the text.
1721 ." text"
1722 compile text printer.
1724 N-ALLOT
1725 ( n -- stard-addr )
1726 allocate n *bytes* in the current DP, return the address of
1727 the first allocated byte.
1729 ALLOT
1730 ( n -- )
1731 allocate n *bytes* in the current DP.
1733 ALIGN-HERE
1734 ( -- )
1735 align DP to 4-byte boundary.
1737 COMPILER:(NEW-WORDLIST)
1738 ( parentvocid need-hashtable? -- vocid )
1739 create new empty wordlist.
1741 COMPILER:(CREATE-NAMED-VOCAB)
1742 ( vocid addr count -- )
1743 create vocabulary word.
1745 COMPILER:(CREATE-VOCAB) <vocname>
1746 ( vocid -- )
1747 create vocabulary word.
1749 COMPILER:(IS-VOC-WORD?)
1750 ( cfa -- bool )
1751 check if the given CFA defined as a vocabulary header.
1753 COMPILER:(WORD->VOCID)
1754 ( cfa -- vocid )
1755 get vocid from the vocabulary word. doesn't check arguments.
1757 COMPILER:(VOCID-PARENT@)
1758 ( vocid -- vocid )
1759 get vocid parent vocabulary. return 0 if there is no parent.
1760 doesn't check arguments.
1762 COMPILER:(VOCID-PARENT!)
1763 ( parent-vocid vocid -- )
1764 set vocid parent vocabulary. doesn't check arguments.
1766 COMPILER:(VOCID-TYPEID@)
1767 ( vocid -- typeid )
1768 internal helper for STRUCT support.
1770 COMPILER:(VOCID-TYPEID!)
1771 internal helper for STRUCT support.
1773 (VOCABULARY-EX)
1774 ( addr count parent need-hashtbl? -- )
1775 useful low-level words to create vocabs with already parsed names.
1777 (VOCABULARY)
1778 ( addr count -- )
1780 (SIMPLE-VOCABULARY)
1781 ( addr count -- )
1782 creates vocabulary without a hash table.
1784 (NESTED-VOCABULARY)
1785 ( addr count -- )
1787 (SIMPLE-NESTED-VOCABULARY)
1788 ( addr count -- )
1790 VOCABULARY <vocname>
1792 SIMPLE-VOCABULARY <vocname>
1794 NESTED-VOCABULARY <vocname>
1796 SIMPLE-NESTED-VOCABULARY <vocname>
1798 VOCID: <vocname>
1799 ( -- vocid )
1800 return vocid for the given vocabulary. this word is immediate.
1802 VOC-LATEST
1803 ( vocid -- latest )
1804 return latest word LFA for the given vocid.
1806 ALSO-DEFS: <vocname>
1807 ( -- )
1808 this does "ALSO <vocname> DEFINITIONS"
1810 PREV-DEFS
1811 ( -- )
1812 this does "PREVIOUS DEFINITIONS".
1814 VOCAB-IF-NONE <vocname>
1815 create vocabulary if we don't have such word yet.
1817 NESTED-VOCAB-IF-NONE <vocname>
1818 create nested vocabulary if we don't have such word yet.
1820 SIMPLE-VOCAB-IF-NONE <vocname>
1821 create vocabulary if we don't have such word yet.
1823 SIMPLE-NESTED-VOCAB-IF-NONE <vocname>
1824 create nested vocabulary if we don't have such word yet.
1826 -TO  ( n -- )  \ name
1827 decrement value by n.
1829 +TO  ( n -- )  \ name
1830 increment value by n.
1832 -1-TO  ( -- )  \ name
1833 decrement value by 1.
1835 +1-TO  ( -- )  \ name
1836 increment value by 1.
1838 0-TO  ( -- )  \ name
1839 write 0 to value.
1841 ... FORTH:(TO-EXTENDER) ...
1842 ( addr count FALSE -- addr count FALSE / TRUE )
1843 "TO" can be extended to support things it doesn't know about yet.
1844 after parsing a name, "(TO-EXTENDER)" will be called (this is
1845 scattered colon word). note that due to how scattered colon works,
1846 you'd better DON'T use "EXIT", but pass a flag if you need to stop
1847 further processing. also, do not forget to check the flag at the
1848 start of your extender, because some other extender may already
1849 did its work before yours.
1851 ... FORTH:(EXIT-EXTENDER) ...
1852 ( -- )
1853 this scattered colon word allows you to extend "EXIT". "EXIT" is
1854 the immediate word that compiles word leaving instructions. you
1855 can compile your cleanup code before the standard cleanup.
1857 ... FORTH:(INTERPRET-CHECK-WORD) ...
1858 ( addr count FALSE -- addr count FALSE / TRUE )
1859 this is called by INTERPRET before the standard word processing.
1861 ... FORTH:(INTERPRET-WORD-NOT-FOUND) ...
1862 ( addr count FALSE -- addr count FALSE / TRUE )
1863 this is called by INTERPRET when word resolution failed.
1866 UrForth supports cooperative multitasking. it is also used to implement
1867 interactive debugger. tasks are called "execution states", or simply
1868 "states".
1870 MTASK:NEW-STATE
1871 ( cfa -- stid )
1872 create new state, return state id.
1874 MTASK:FREE-STATE
1875 ( stid -- )
1876 free state. state id should be valid, and should not be an active state.
1878 MTASK:STATE-NAME@
1879 ( stid -- addr count )
1880 copy state name to PAD.
1882 MTASK:STATE-NAME!
1883 ( addr count stid -- )
1884 set new state name. maximum name length is 127 chars. state name
1885 should not include char with code 0.
1887 MTASK:STATE-FIRST
1888 ( -- stid )
1889 get first state in the list of all created states. this is used to
1890 iterate over all states.
1891 WARNING! do not mutate state list while iterating! result will be UB.
1893 MTASK:STATE-NEXT
1894 ( stid -- stid / 0 )
1895 get next state id. used to iterate over all states.
1896 WARNING! do not mutate state list while iterating! result will be UB.
1898 MTASK:YIELD-TO
1899 ( ... argc stid -- )
1900 yield to another state. move argc numbers from the current state data
1901 stack to the new state data stack. push args to the new state data
1902 stack, and then push current state id. i.e. new state data stack will
1903 look like this:
1904   ( ... argc old-stid )
1905 it is ok to swith to the currently active state (it is a no-op).
1907 MTASK:SET-SELF-AS-DEBUGGER
1908 ( -- )
1909 register current task as system debugger. you can yeild from the debugger
1910 after this.
1912 DEBUG:(BP)
1913 ( -- )
1914 breakpoint. debugger task receives debugge stid on the data stack,
1915 and `-1` as yield argument count. i.e. debugger stack will be:
1916   ( -1 old-stid )
1918 MTASK:DEBUGGER-RESUME
1919 ( stid -- )
1920 resume debugee execution.
1922 DEBUG:SINGLE-STEP@
1923 ( -- enabled? )
1924 get "single stepping enabled" flag.
1926 MTASK:DEBUGGER-SINGLE-STEP
1927 ( stid -- )
1928 execute one debuggee instruction, and return to debugger.
1929 this is basically "YIELD", but to use in the debugger
1930 (and it doesn't pass any arguments). debugger stack will be:
1931   ( -2 old-stid )
1933 MTASK:STATE-IP@
1934 ( stid -- ip )
1935 get state instruction pointer.
1937 MTASK:STATE-IP!
1938 ( ip stid -- )
1939 set state instruction pointer.
1941 MTASK:STATE-A>
1942 ( stid -- regA )
1943 get address register contents.
1945 MTASK:STATE->A
1946 ( rega stid -- )
1947 set address register contents.
1949 MTASK:STATE-USER@
1950 ( addr stid -- valie )
1951 get other state user area cell.
1953 MTASK:STATE-USER!
1954 ( value addr stid -- )
1955 set other state user area cell.
1957 MTASK:STATE-RPOPCFA@
1958 ( -- flag )
1959 VM has special mode when it gets next CFA from the return stack
1960 instead of the address pointed by IP. this is used to implement
1961 "EXECUTE", for example. use this word to retrieve that flag.
1963 MTASK:STATE-RPOPCFA!
1964 ( flag -- )
1965 VM has special mode when it gets next CFA from the return stack
1966 instead of the address pointed by IP. this is used to implement
1967 "EXECUTE", for example. use this word to set that flag.
1969 MTASK:ACTIVE-STATE
1970 ( -- stid )
1971 return state id of the currently executing state.
1973 MTASK:YIELDED-FROM
1974 ( -- stid / 0 )
1975 return state which called "MTASK:YIELD-TO" last.
1977 MTASK:STATE-SP@
1978 ( stid -- depth )
1979 get the data stack depth for the given state.
1981 MTASK:STATE-RP@
1982 ( stid -- depth )
1983 get the return stack depth for the given state.
1985 MTASK:STATE-LP@
1986 ( stid -- lp )
1987 get local stack ptr.
1989 MTASK:STATE-LBP@
1990 ( stid -- lbp )
1991 get local stack base ptr.
1993 MTASK:STATE-SP!
1994 ( depth stid -- )
1995 set the data stack depth for the given state.
1997 MTASK:STATE-RP!
1998 ( stid -- depth )
1999 set the return stack depth for the given state.
2001 MTASK:STATE-LP!
2002 ( lp stid -- )
2003 set local stack ptr.
2005 MTASK:STATE-LBP!
2006 ( lbp stid -- )
2007 set local stack base ptr.
2009 MTASK:STATE-DS@
2010 ( idx stid -- value )
2011 read the data stack of the given state. note that the index is bound-checked.
2013 MTASK:STATE-RS@
2014 ( idx stid -- value )
2015 read the return stack of the given state. note that the index is bound-checked.
2017 MTASK:STATE-LS@
2018 ( idx stid -- value )
2019 read the locals stack of the given state. note that the index is bound-checked.
2021 MTASK:STATE-DS!
2022 ( value idx stid -- )
2023 write the data stack of the given state. note that the index is bound-checked.
2024 i.e. if you want to push some value, increase stack depth first.
2026 MTASK:STATE-RS!
2027 ( value idx stid -- )
2028 write the return stack of the given state. note that the index is bound-checked.
2029 i.e. if you want to push some value, increase stack depth first.
2031 MTASK:STATE-LS!
2032 ( value idx stid -- )
2033 write the locals stack of the given state. note that the index is bound-checked.
2034 i.e. if you want to push some value, increase stack depth first.
2036 MTASK:STATE-VSP@
2037 ( stid -- vsp )
2038 get wordlist stack pointer.
2040 MTASK:STATE-VSP!
2041 ( vsp stid -- )
2042 set wordlist stack pointer.
2044 MTASK:STATE-VSP-AT@
2045 ( idx stid -- )
2046 get wordlist stack contents.
2048 MTASK:STATE-VSP-AT!
2049 ( value idx stid -- )
2050 set wordlist stack contents.
2053 there are some words to work with TTY (only GNU/Linux).
2055 TTY:TTY?
2056 ( -- bool )
2057 check if input and output are valid TTY(s).
2059 TTY:RAW?
2060 ( -- bool )
2061 check if current TTY mode is raw.
2063 TTY:SIZE
2064 ( -- width height )
2065 get TTY size. for non-TTYs retur default 80x24.
2067 TTY:SET-RAW
2068 ( -- success-bool )
2069 switch TTY to raw mode.
2071 TTY:SET-COOKED
2072 ( -- success-bool )
2073 switch TTY to cooked mode.
2075 TTY:RAW-EMIT
2076 ( n -- )
2077 type char without any filtering or safety nets.
2079 TTY:RAW-TYPE
2080 ( addr count -- )
2081 type string without any filtering or safety nets.
2083 TTY:RAW-FLUSH
2084 ( -- )
2085 the output of the two words above is buffered. this words flushes
2086 the buffer. buffering is done because raw TTY is mostly used to
2087 build user interfaces, and sending accumulated terminal commands
2088 in one big chunk looks much better (most terminal emulators will
2089 process the whole chunk before refreshing their windows).
2091 TTY:RAW-READCH
2092 ( -- ch / -1 )
2093 -1 returned on error, or on EOF.
2094 read one char (without any interpretation) if TTY is in raw mode.
2095 note that 0 is a valid char (it is used to send Ctrl+Space in some
2096 terminal emulators). also note that there is no way to tell if we
2097 hit a EOF, or some error occured. in practice, it doesn't matter,
2098 because in both cases it means that TTY is unusable anymore.
2100 TTY:RAW-READY?
2101 ( -- bool )
2102 check if raw TTY has some data to read.
2105 file i/o words.
2107 FILES:ERRNO
2108 ( -- errno )
2109 last libc `errno`. can be used after failure to inspect error code.
2111 FILES:UNLINK
2112 ( addr count -- success? )
2113 delete file.
2115 FILES:OPEN-R/O
2116 ( addr count -- handle TRUE / FALSE )
2117 open file for reading. `handle` is always positive.
2119 FILES:OPEN-R/W
2120 ( addr count -- handle TRUE / FALSE )
2121 open file for writing. `handle` is always positive.
2123 FILES:CREATE
2124 ( addr count -- handle TRUE / FALSE )
2125 create new file, or truncate existing. `handle` can be any number, including
2126 `0` and negative numbers.
2128 FILES:CLOSE
2129 ( handle -- success? )
2130 close opened file.
2132 FILES:TELL
2133 ( handle -- ofs TRUE / FALSE )
2134 get current file position.
2136 FILES:SEEK-EX
2137 ( ofs whence handle -- TRUE / FALSE )
2138 set current file position. `whence` can be one of "FILES:SEEK-SET",
2139 "FILES:SEEK-CUR", "FILES:SEEK-END".
2141 FILES:SEEK
2142 ( ofs handle -- TRUE / FALSE )
2143 set current file position. the same as calling "SEEK-EX" with `whence`
2144 equal to "SEEK-SET".
2146 FILES:SIZE
2147 ( handle -- size TRUE / FALSE )
2148 get file size. `handle` cannot be 0.
2149 WARNING! on failure on valid handle, file position for that handle is undefined.
2151 FILES:READ
2152 ( addr count handle -- rdsize TRUE / FALSE )
2153 read bytes from file. this word can read less bytes than requirested. `count`
2154 can be 0 (in this case the function always succeeds). note that this function
2155 can read 0 bytes, and this is success too.
2157 FILES:READ-EXACT
2158 ( addr count handle -- TRUE / FALSE )
2159 read bytes from file. reading less then requested number of bytes is error.
2160 `count` can be 0 (in this case the function always succeeds).
2162 FILES:WRITE
2163 ( addr count handle -- TRUE / FALSE )
2164 write bytes from file. writing less bytes than requested is error. `count`
2165 can be 0 (in this case the function always succeeds).