4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <fcode/private.h>
35 #include <fcode/log.h>
37 void (*semi_ptr
)(fcode_env_t
*env
) = do_semi
;
38 void (*does_ptr
)(fcode_env_t
*env
) = install_does
;
39 void (*quote_ptr
)(fcode_env_t
*env
) = do_quote
;
40 void (*blit_ptr
)(fcode_env_t
*env
) = do_literal
;
41 void (*tlit_ptr
)(fcode_env_t
*env
) = do_literal
;
42 void (*do_bdo_ptr
)(fcode_env_t
*env
) = do_bdo
;
43 void (*do_bqdo_ptr
)(fcode_env_t
*env
) = do_bqdo
;
44 void (*create_ptr
)(fcode_env_t
*env
) = do_creator
;
45 void (*do_leave_ptr
)(fcode_env_t
*env
) = do_bleave
;
46 void (*do_loop_ptr
)(fcode_env_t
*env
) = do_bloop
;
47 void (*do_ploop_ptr
)(fcode_env_t
*env
) = do_bploop
;
49 void unaligned_lstore(fcode_env_t
*);
50 void unaligned_wstore(fcode_env_t
*);
51 void unaligned_lfetch(fcode_env_t
*);
52 void unaligned_wfetch(fcode_env_t
*);
54 /* start with the simple maths functions */
62 CHECK_DEPTH(env
, 2, "+");
68 subtract(fcode_env_t
*env
)
72 CHECK_DEPTH(env
, 2, "-");
78 multiply(fcode_env_t
*env
)
82 CHECK_DEPTH(env
, 2, "*");
88 slash_mod(fcode_env_t
*env
)
90 fstack_t d
, o
, t
, rem
;
93 CHECK_DEPTH(env
, 2, "/mod");
98 throw_from_fclib(env
, 1, "/mod divide by zero");
100 sign
= ((d
^ t
) < 0);
114 if ((o
^ sign
) < 0) {
127 * 'u/mod' Fcode implementation.
130 uslash_mod(fcode_env_t
*env
)
134 CHECK_DEPTH(env
, 2, "u/mod");
139 forth_abort(env
, "u/mod: divide by zero");
145 divide(fcode_env_t
*env
)
147 CHECK_DEPTH(env
, 2, "/");
153 mod(fcode_env_t
*env
)
155 CHECK_DEPTH(env
, 2, "mod");
161 and(fcode_env_t
*env
)
165 CHECK_DEPTH(env
, 2, "and");
175 CHECK_DEPTH(env
, 2, "or");
181 xor(fcode_env_t
*env
)
185 CHECK_DEPTH(env
, 2, "xor");
191 invert(fcode_env_t
*env
)
193 CHECK_DEPTH(env
, 1, "invert");
198 lshift(fcode_env_t
*env
)
202 CHECK_DEPTH(env
, 2, "lshift");
208 rshift(fcode_env_t
*env
)
212 CHECK_DEPTH(env
, 2, "rshift");
214 TOS
= ((ufstack_t
)TOS
) >> d
;
218 rshifta(fcode_env_t
*env
)
222 CHECK_DEPTH(env
, 2, ">>a");
224 TOS
= ((s_lforth_t
)TOS
) >> d
;
228 negate(fcode_env_t
*env
)
230 CHECK_DEPTH(env
, 1, "negate");
235 f_abs(fcode_env_t
*env
)
237 CHECK_DEPTH(env
, 1, "abs");
238 if (TOS
< 0) TOS
= -TOS
;
242 f_min(fcode_env_t
*env
)
246 CHECK_DEPTH(env
, 2, "min");
248 if (d
< TOS
) TOS
= d
;
252 f_max(fcode_env_t
*env
)
256 CHECK_DEPTH(env
, 2, "max");
258 if (d
> TOS
) TOS
= d
;
262 to_r(fcode_env_t
*env
)
264 CHECK_DEPTH(env
, 1, ">r");
269 from_r(fcode_env_t
*env
)
271 CHECK_RETURN_DEPTH(env
, 1, "r>");
276 rfetch(fcode_env_t
*env
)
278 CHECK_RETURN_DEPTH(env
, 1, "r@");
283 f_exit(fcode_env_t
*env
)
285 CHECK_RETURN_DEPTH(env
, 1, "exit");
286 IP
= (token_t
*)POP(RS
);
289 #define COMPARE(cmp, rhs) ((((s_lforth_t)TOS) cmp((s_lforth_t)(rhs))) ? \
291 #define UCOMPARE(cmp, rhs) ((((u_lforth_t)TOS) cmp((u_lforth_t)(rhs))) ? \
296 #define LESSEQUALS <=
297 #define GREATERTHAN >
298 #define GREATEREQUALS >=
301 zero_equals(fcode_env_t
*env
)
303 CHECK_DEPTH(env
, 1, "0=");
304 TOS
= COMPARE(EQUALS
, 0);
308 zero_not_equals(fcode_env_t
*env
)
310 CHECK_DEPTH(env
, 1, "0<>");
311 TOS
= COMPARE(NOTEQUALS
, 0);
315 zero_less(fcode_env_t
*env
)
317 CHECK_DEPTH(env
, 1, "0<");
318 TOS
= COMPARE(LESSTHAN
, 0);
322 zero_less_equals(fcode_env_t
*env
)
324 CHECK_DEPTH(env
, 1, "0<=");
325 TOS
= COMPARE(LESSEQUALS
, 0);
329 zero_greater(fcode_env_t
*env
)
331 CHECK_DEPTH(env
, 1, "0>");
332 TOS
= COMPARE(GREATERTHAN
, 0);
336 zero_greater_equals(fcode_env_t
*env
)
338 CHECK_DEPTH(env
, 1, "0>=");
339 TOS
= COMPARE(GREATEREQUALS
, 0);
343 less(fcode_env_t
*env
)
347 CHECK_DEPTH(env
, 2, "<");
349 TOS
= COMPARE(LESSTHAN
, d
);
353 greater(fcode_env_t
*env
)
357 CHECK_DEPTH(env
, 2, ">");
359 TOS
= COMPARE(GREATERTHAN
, d
);
363 equals(fcode_env_t
*env
)
367 CHECK_DEPTH(env
, 2, "=");
369 TOS
= COMPARE(EQUALS
, d
);
373 not_equals(fcode_env_t
*env
)
377 CHECK_DEPTH(env
, 2, "<>");
379 TOS
= COMPARE(NOTEQUALS
, d
);
384 unsign_greater(fcode_env_t
*env
)
388 CHECK_DEPTH(env
, 2, "u>");
390 TOS
= UCOMPARE(GREATERTHAN
, d
);
394 unsign_less_equals(fcode_env_t
*env
)
398 CHECK_DEPTH(env
, 2, "u<=");
400 TOS
= UCOMPARE(LESSEQUALS
, d
);
404 unsign_less(fcode_env_t
*env
)
408 CHECK_DEPTH(env
, 2, "u<");
410 TOS
= UCOMPARE(LESSTHAN
, d
);
414 unsign_greater_equals(fcode_env_t
*env
)
418 CHECK_DEPTH(env
, 2, "u>=");
420 TOS
= UCOMPARE(GREATEREQUALS
, d
);
424 greater_equals(fcode_env_t
*env
)
428 CHECK_DEPTH(env
, 2, ">=");
430 TOS
= COMPARE(GREATEREQUALS
, d
);
434 less_equals(fcode_env_t
*env
)
438 CHECK_DEPTH(env
, 2, "<=");
440 TOS
= COMPARE(LESSEQUALS
, d
);
444 between(fcode_env_t
*env
)
448 CHECK_DEPTH(env
, 3, "between");
449 hi
= (u_lforth_t
)POP(DS
);
450 lo
= (u_lforth_t
)POP(DS
);
451 TOS
= (((u_lforth_t
)TOS
>= lo
) && ((u_lforth_t
)TOS
<= hi
) ? -1 : 0);
455 within(fcode_env_t
*env
)
459 CHECK_DEPTH(env
, 3, "within");
460 hi
= (u_lforth_t
)POP(DS
);
461 lo
= (u_lforth_t
)POP(DS
);
462 TOS
= ((((u_lforth_t
)TOS
>= lo
) && ((u_lforth_t
)TOS
< hi
)) ? -1 : 0);
466 do_literal(fcode_env_t
*env
)
473 literal(fcode_env_t
*env
)
476 COMPILE_TOKEN(&blit_ptr
);
482 do_also(fcode_env_t
*env
)
486 if (env
->order_depth
< (MAX_ORDER
- 1)) {
487 env
->order
[++env
->order_depth
] = d
;
488 debug_msg(DEBUG_CONTEXT
, "CONTEXT:also: %d/%p/%p\n",
489 env
->order_depth
, CONTEXT
, env
->current
);
491 log_message(MSG_WARN
, "Vocabulary search order exceeds: %d\n",
496 do_previous(fcode_env_t
*env
)
498 if (env
->order_depth
) {
500 debug_msg(DEBUG_CONTEXT
, "CONTEXT:previous: %d/%p/%p\n",
501 env
->order_depth
, CONTEXT
, env
->current
);
507 do_order(fcode_env_t
*env
)
511 log_message(MSG_INFO
, "Order: Depth: %ld: ", env
->order_depth
);
512 for (i
= env
->order_depth
; i
>= 0 && env
->order
[i
]; i
--)
513 log_message(MSG_INFO
, "%p ", (void *)env
->order
[i
]);
514 log_message(MSG_INFO
, "\n");
519 noop(fcode_env_t
*env
)
521 /* what a waste of cycles */
525 #define FW_PER_FL (sizeof (lforth_t)/sizeof (wforth_t))
528 lwsplit(fcode_env_t
*env
)
531 u_wforth_t l_wf
[FW_PER_FL
];
536 CHECK_DEPTH(env
, 1, "lwsplit");
538 for (i
= 0; i
< FW_PER_FL
; i
++)
539 PUSH(DS
, d
.l_wf
[(FW_PER_FL
- 1) - i
]);
543 wljoin(fcode_env_t
*env
)
546 u_wforth_t l_wf
[FW_PER_FL
];
551 CHECK_DEPTH(env
, FW_PER_FL
, "wljoin");
552 for (i
= 0; i
< FW_PER_FL
; i
++)
558 lwflip(fcode_env_t
*env
)
561 u_wforth_t l_wf
[FW_PER_FL
];
566 CHECK_DEPTH(env
, 1, "lwflip");
568 for (i
= 0; i
< FW_PER_FL
; i
++)
569 c
.l_wf
[i
] = d
.l_wf
[(FW_PER_FL
- 1) - i
];
574 lbsplit(fcode_env_t
*env
)
577 uchar_t l_bytes
[sizeof (lforth_t
)];
582 CHECK_DEPTH(env
, 1, "lbsplit");
584 for (i
= 0; i
< sizeof (lforth_t
); i
++)
585 PUSH(DS
, d
.l_bytes
[(sizeof (lforth_t
) - 1) - i
]);
589 bljoin(fcode_env_t
*env
)
592 uchar_t l_bytes
[sizeof (lforth_t
)];
597 CHECK_DEPTH(env
, sizeof (lforth_t
), "bljoin");
598 for (i
= 0; i
< sizeof (lforth_t
); i
++)
599 d
.l_bytes
[i
] = POP(DS
);
600 PUSH(DS
, (fstack_t
)d
.l_lf
);
604 lbflip(fcode_env_t
*env
)
607 uchar_t l_bytes
[sizeof (lforth_t
)];
612 CHECK_DEPTH(env
, 1, "lbflip");
614 for (i
= 0; i
< sizeof (lforth_t
); i
++)
615 c
.l_bytes
[i
] = d
.l_bytes
[(sizeof (lforth_t
) - 1) - i
];
620 wbsplit(fcode_env_t
*env
)
623 uchar_t w_bytes
[sizeof (wforth_t
)];
628 CHECK_DEPTH(env
, 1, "wbsplit");
630 for (i
= 0; i
< sizeof (wforth_t
); i
++)
631 PUSH(DS
, d
.w_bytes
[(sizeof (wforth_t
) - 1) - i
]);
635 bwjoin(fcode_env_t
*env
)
638 uchar_t w_bytes
[sizeof (wforth_t
)];
643 CHECK_DEPTH(env
, sizeof (wforth_t
), "bwjoin");
644 for (i
= 0; i
< sizeof (wforth_t
); i
++)
645 d
.w_bytes
[i
] = POP(DS
);
650 wbflip(fcode_env_t
*env
)
653 uchar_t w_bytes
[sizeof (wforth_t
)];
658 CHECK_DEPTH(env
, 1, "wbflip");
660 for (i
= 0; i
< sizeof (wforth_t
); i
++)
661 c
.w_bytes
[i
] = d
.w_bytes
[(sizeof (wforth_t
) - 1) - i
];
666 upper_case(fcode_env_t
*env
)
668 CHECK_DEPTH(env
, 1, "upc");
673 lower_case(fcode_env_t
*env
)
675 CHECK_DEPTH(env
, 1, "lcc");
680 pack_str(fcode_env_t
*env
)
686 CHECK_DEPTH(env
, 3, "pack");
687 buf
= (char *)POP(DS
);
688 len
= (size_t)POP(DS
);
691 *buf
++ = (uchar_t
)len
;
692 strncpy(buf
, str
, (len
&0xff));
696 count_str(fcode_env_t
*env
)
700 CHECK_DEPTH(env
, 1, "count");
701 len
= (uchar_t
*)TOS
;
707 to_body(fcode_env_t
*env
)
709 CHECK_DEPTH(env
, 1, ">body");
710 TOS
= (fstack_t
)(((acf_t
)TOS
)+1);
714 to_acf(fcode_env_t
*env
)
716 CHECK_DEPTH(env
, 1, "body>");
717 TOS
= (fstack_t
)(((acf_t
)TOS
)-1);
721 * 'unloop' Fcode implementation, drop 3 loop ctrl elements off return stack.
724 unloop(fcode_env_t
*env
)
726 CHECK_RETURN_DEPTH(env
, 3, "unloop");
731 * 'um*' Fcode implementation.
734 um_multiply(fcode_env_t
*env
)
739 CHECK_DEPTH(env
, 2, "um*");
747 * um/mod (d.lo d.hi u -- urem uquot)
750 um_slash_mod(fcode_env_t
*env
)
753 uint32_t u
, urem
, uquot
;
755 CHECK_DEPTH(env
, 3, "um/mod");
756 u
= (uint32_t)POP(DS
);
765 * d+ (d1.lo d1.hi d2.lo d2.hi -- dsum.lo dsum.hi)
768 d_plus(fcode_env_t
*env
)
772 CHECK_DEPTH(env
, 4, "d+");
773 d2
= pop_double(env
);
774 d1
= pop_double(env
);
776 push_double(env
, d1
);
780 * d- (d1.lo d1.hi d2.lo d2.hi -- ddif.lo ddif.hi)
783 d_minus(fcode_env_t
*env
)
787 CHECK_DEPTH(env
, 4, "d-");
788 d2
= pop_double(env
);
789 d1
= pop_double(env
);
791 push_double(env
, d1
);
795 set_here(fcode_env_t
*env
, uchar_t
*new_here
, char *where
)
797 if (new_here
< HERE
) {
798 if (strcmp(where
, "temporary_execute")) {
800 * Other than temporary_execute, no one should set
803 log_message(MSG_WARN
, "Warning: set_here(%s) back: old:"
804 " %p new: %p\n", where
, HERE
, new_here
);
807 if (new_here
>= env
->base
+ dict_size
)
808 forth_abort(env
, "Here (%p) set past dictionary end (%p)",
809 new_here
, env
->base
+ dict_size
);
814 unaligned_store(fcode_env_t
*env
)
816 extern void unaligned_xstore(fcode_env_t
*);
818 if (sizeof (fstack_t
) == sizeof (lforth_t
))
819 unaligned_lstore(env
);
821 unaligned_xstore(env
);
825 unaligned_fetch(fcode_env_t
*env
)
827 extern void unaligned_xfetch(fcode_env_t
*);
829 if (sizeof (fstack_t
) == sizeof (lforth_t
))
830 unaligned_lfetch(env
);
832 unaligned_xfetch(env
);
836 comma(fcode_env_t
*env
)
838 CHECK_DEPTH(env
, 1, ",");
839 DEBUGF(COMMA
, dump_comma(env
, ","));
840 PUSH(DS
, (fstack_t
)HERE
);
841 unaligned_store(env
);
842 set_here(env
, HERE
+ sizeof (fstack_t
), "comma");
846 lcomma(fcode_env_t
*env
)
848 CHECK_DEPTH(env
, 1, "l,");
849 DEBUGF(COMMA
, dump_comma(env
, "l,"));
850 PUSH(DS
, (fstack_t
)HERE
);
851 unaligned_lstore(env
);
852 set_here(env
, HERE
+ sizeof (u_lforth_t
), "lcomma");
856 wcomma(fcode_env_t
*env
)
858 CHECK_DEPTH(env
, 1, "w,");
859 DEBUGF(COMMA
, dump_comma(env
, "w,"));
860 PUSH(DS
, (fstack_t
)HERE
);
861 unaligned_wstore(env
);
862 set_here(env
, HERE
+ sizeof (u_wforth_t
), "wcomma");
866 ccomma(fcode_env_t
*env
)
868 CHECK_DEPTH(env
, 1, "c,");
869 DEBUGF(COMMA
, dump_comma(env
, "c,"));
870 PUSH(DS
, (fstack_t
)HERE
);
872 set_here(env
, HERE
+ sizeof (uchar_t
), "ccomma");
876 token_roundup(fcode_env_t
*env
, char *where
)
878 if ((((token_t
)HERE
) & (sizeof (token_t
) - 1)) != 0) {
879 set_here(env
, (uchar_t
*)TOKEN_ROUNDUP(HERE
), where
);
884 compile_comma(fcode_env_t
*env
)
886 CHECK_DEPTH(env
, 1, "compile,");
887 DEBUGF(COMMA
, dump_comma(env
, "compile,"));
888 token_roundup(env
, "compile,");
889 PUSH(DS
, (fstack_t
)HERE
);
890 unaligned_store(env
);
891 set_here(env
, HERE
+ sizeof (fstack_t
), "compile,");
895 unaligned_lfetch(fcode_env_t
*env
)
900 CHECK_DEPTH(env
, 1, "unaligned-l@");
902 for (i
= 0; i
< sizeof (lforth_t
); i
++, addr
++) {
911 unaligned_lstore(fcode_env_t
*env
)
916 CHECK_DEPTH(env
, 2, "unaligned-l!");
919 for (i
= 0; i
< sizeof (lforth_t
); i
++, addr
++) {
926 unaligned_wfetch(fcode_env_t
*env
)
931 CHECK_DEPTH(env
, 1, "unaligned-w@");
933 for (i
= 0; i
< sizeof (wforth_t
); i
++, addr
++) {
942 unaligned_wstore(fcode_env_t
*env
)
947 CHECK_DEPTH(env
, 2, "unaligned-w!");
950 for (i
= 0; i
< sizeof (wforth_t
); i
++, addr
++) {
957 * 'lbflips' Fcode implementation.
960 lbflips(fcode_env_t
*env
)
965 CHECK_DEPTH(env
, 2, "lbflips");
968 for (i
= 0; i
< len
; i
+= sizeof (lforth_t
),
969 addr
+= sizeof (lforth_t
)) {
971 unaligned_lfetch(env
);
974 unaligned_lstore(env
);
979 * 'wbflips' Fcode implementation.
982 wbflips(fcode_env_t
*env
)
987 CHECK_DEPTH(env
, 2, "wbflips");
990 for (i
= 0; i
< len
; i
+= sizeof (wforth_t
),
991 addr
+= sizeof (wforth_t
)) {
993 unaligned_wfetch(env
);
996 unaligned_wstore(env
);
1001 * 'lwflips' Fcode implementation.
1004 lwflips(fcode_env_t
*env
)
1009 CHECK_DEPTH(env
, 2, "lwflips");
1012 for (i
= 0; i
< len
; i
+= sizeof (lforth_t
),
1013 addr
+= sizeof (lforth_t
)) {
1015 unaligned_lfetch(env
);
1018 unaligned_lstore(env
);
1023 base(fcode_env_t
*env
)
1025 PUSH(DS
, (fstack_t
)&env
->num_base
);
1029 dot_s(fcode_env_t
*env
)
1031 output_data_stack(env
, MSG_INFO
);
1035 state(fcode_env_t
*env
)
1037 PUSH(DS
, (fstack_t
)&env
->state
);
1041 is_digit(char digit
, int num_base
, fstack_t
*dptr
)
1046 if (num_base
< 10) {
1047 base
= '0' + (num_base
-1);
1049 base
= 'a' + (num_base
- 10);
1053 if (digit
> '9') digit
|= 0x20;
1054 if (((digit
< '0') || (digit
> base
)) ||
1055 ((digit
> '9') && (digit
< 'a') && (num_base
> 10)))
1061 digit
= digit
- 'a' + 10;
1068 dollar_number(fcode_env_t
*env
)
1072 int len
, sign
= 1, error
= 0;
1074 CHECK_DEPTH(env
, 2, "$number");
1075 buf
= pop_a_string(env
, &len
);
1082 while (len
-- && !error
) {
1089 value
*= env
->num_base
;
1090 error
= is_digit(*buf
++, env
->num_base
, &digit
);
1103 digit(fcode_env_t
*env
)
1108 CHECK_DEPTH(env
, 2, "digit");
1110 if (is_digit(TOS
, base
, &value
))
1119 space(fcode_env_t
*env
)
1125 backspace(fcode_env_t
*env
)
1131 bell(fcode_env_t
*env
)
1137 fc_bounds(fcode_env_t
*env
)
1141 CHECK_DEPTH(env
, 2, "bounds");
1149 here(fcode_env_t
*env
)
1151 PUSH(DS
, (fstack_t
)HERE
);
1155 aligned(fcode_env_t
*env
)
1159 CHECK_DEPTH(env
, 1, "aligned");
1160 a
= (TOS
& (sizeof (lforth_t
) - 1));
1162 TOS
+= (sizeof (lforth_t
) - a
);
1166 instance(fcode_env_t
*env
)
1168 env
->instance_mode
|= 1;
1172 semi(fcode_env_t
*env
)
1176 COMPILE_TOKEN(&semi_ptr
);
1179 * check if we need to supress expose action;
1180 * If so this is an internal word and has no link field
1181 * or it is a temporary compile
1184 if (env
->state
== 0) {
1185 expose_acf(env
, "<semi>");
1187 if (env
->state
& 8) {
1193 do_create(fcode_env_t
*env
)
1195 PUSH(DS
, (fstack_t
)WA
);
1199 drop(fcode_env_t
*env
)
1201 CHECK_DEPTH(env
, 1, "drop");
1206 f_dup(fcode_env_t
*env
)
1210 CHECK_DEPTH(env
, 1, "dup");
1216 over(fcode_env_t
*env
)
1220 CHECK_DEPTH(env
, 2, "over");
1226 swap(fcode_env_t
*env
)
1230 CHECK_DEPTH(env
, 2, "swap");
1238 rot(fcode_env_t
*env
)
1242 CHECK_DEPTH(env
, 3, "rot");
1250 minus_rot(fcode_env_t
*env
)
1254 CHECK_DEPTH(env
, 3, "-rot");
1262 tuck(fcode_env_t
*env
)
1266 CHECK_DEPTH(env
, 2, "tuck");
1273 nip(fcode_env_t
*env
)
1275 CHECK_DEPTH(env
, 2, "nip");
1281 qdup(fcode_env_t
*env
)
1285 CHECK_DEPTH(env
, 1, "?dup");
1292 depth(fcode_env_t
*env
)
1301 pick(fcode_env_t
*env
)
1305 CHECK_DEPTH(env
, 1, "pick");
1307 if (p
< 0 || p
>= (env
->ds
- env
->ds0
))
1308 forth_abort(env
, "pick: invalid pick value: %d\n", (int)p
);
1314 roll(fcode_env_t
*env
)
1318 CHECK_DEPTH(env
, 1, "roll");
1320 if (r
<= 0 || r
>= (env
->ds
- env
->ds0
))
1321 forth_abort(env
, "roll: invalid roll value: %d\n", (int)r
);
1325 DS
[-r
] = DS
[ -(r
-1) ];
1332 two_drop(fcode_env_t
*env
)
1334 CHECK_DEPTH(env
, 2, "2drop");
1339 two_dup(fcode_env_t
*env
)
1341 CHECK_DEPTH(env
, 2, "2dup");
1348 two_over(fcode_env_t
*env
)
1352 CHECK_DEPTH(env
, 4, "2over");
1360 two_swap(fcode_env_t
*env
)
1364 CHECK_DEPTH(env
, 4, "2swap");
1374 two_rot(fcode_env_t
*env
)
1378 CHECK_DEPTH(env
, 6, "2rot");
1390 two_slash(fcode_env_t
*env
)
1392 CHECK_DEPTH(env
, 1, "2/");
1397 utwo_slash(fcode_env_t
*env
)
1399 CHECK_DEPTH(env
, 1, "u2/");
1400 TOS
= (ufstack_t
)((ufstack_t
)TOS
) >> 1;
1404 two_times(fcode_env_t
*env
)
1406 CHECK_DEPTH(env
, 1, "2*");
1407 TOS
= (ufstack_t
)((ufstack_t
)TOS
) << 1;
1411 slash_c(fcode_env_t
*env
)
1413 PUSH(DS
, sizeof (char));
1417 slash_w(fcode_env_t
*env
)
1419 PUSH(DS
, sizeof (wforth_t
));
1423 slash_l(fcode_env_t
*env
)
1425 PUSH(DS
, sizeof (lforth_t
));
1429 slash_n(fcode_env_t
*env
)
1431 PUSH(DS
, sizeof (fstack_t
));
1435 ca_plus(fcode_env_t
*env
)
1439 CHECK_DEPTH(env
, 2, "ca+");
1441 TOS
+= d
* sizeof (char);
1445 wa_plus(fcode_env_t
*env
)
1449 CHECK_DEPTH(env
, 2, "wa+");
1451 TOS
+= d
* sizeof (wforth_t
);
1455 la_plus(fcode_env_t
*env
)
1459 CHECK_DEPTH(env
, 2, "la+");
1461 TOS
+= d
* sizeof (lforth_t
);
1465 na_plus(fcode_env_t
*env
)
1469 CHECK_DEPTH(env
, 2, "na+");
1471 TOS
+= d
* sizeof (fstack_t
);
1475 char_plus(fcode_env_t
*env
)
1477 CHECK_DEPTH(env
, 1, "char+");
1478 TOS
+= sizeof (char);
1482 wa1_plus(fcode_env_t
*env
)
1484 CHECK_DEPTH(env
, 1, "wa1+");
1485 TOS
+= sizeof (wforth_t
);
1489 la1_plus(fcode_env_t
*env
)
1491 CHECK_DEPTH(env
, 1, "la1+");
1492 TOS
+= sizeof (lforth_t
);
1496 cell_plus(fcode_env_t
*env
)
1498 CHECK_DEPTH(env
, 1, "cell+");
1499 TOS
+= sizeof (fstack_t
);
1503 do_chars(fcode_env_t
*env
)
1505 CHECK_DEPTH(env
, 1, "chars");
1509 slash_w_times(fcode_env_t
*env
)
1511 CHECK_DEPTH(env
, 1, "/w*");
1512 TOS
*= sizeof (wforth_t
);
1516 slash_l_times(fcode_env_t
*env
)
1518 CHECK_DEPTH(env
, 1, "/l*");
1519 TOS
*= sizeof (lforth_t
);
1523 cells(fcode_env_t
*env
)
1525 CHECK_DEPTH(env
, 1, "cells");
1526 TOS
*= sizeof (fstack_t
);
1530 do_on(fcode_env_t
*env
)
1534 CHECK_DEPTH(env
, 1, "on");
1535 d
= (variable_t
*)POP(DS
);
1540 do_off(fcode_env_t
*env
)
1544 CHECK_DEPTH(env
, 1, "off");
1545 d
= (variable_t
*)POP(DS
);
1550 fetch(fcode_env_t
*env
)
1552 CHECK_DEPTH(env
, 1, "@");
1553 TOS
= *((variable_t
*)TOS
);
1557 lfetch(fcode_env_t
*env
)
1559 CHECK_DEPTH(env
, 1, "l@");
1560 TOS
= *((lforth_t
*)TOS
);
1564 wfetch(fcode_env_t
*env
)
1566 CHECK_DEPTH(env
, 1, "w@");
1567 TOS
= *((wforth_t
*)TOS
);
1571 swfetch(fcode_env_t
*env
)
1573 CHECK_DEPTH(env
, 1, "<w@");
1574 TOS
= *((s_wforth_t
*)TOS
);
1578 cfetch(fcode_env_t
*env
)
1580 CHECK_DEPTH(env
, 1, "c@");
1581 TOS
= *((uchar_t
*)TOS
);
1585 store(fcode_env_t
*env
)
1589 CHECK_DEPTH(env
, 2, "!");
1590 dptr
= (variable_t
*)POP(DS
);
1595 addstore(fcode_env_t
*env
)
1599 CHECK_DEPTH(env
, 2, "+!");
1600 dptr
= (variable_t
*)POP(DS
);
1601 *dptr
= POP(DS
) + *dptr
;
1605 lstore(fcode_env_t
*env
)
1609 CHECK_DEPTH(env
, 2, "l!");
1610 dptr
= (lforth_t
*)POP(DS
);
1611 *dptr
= (lforth_t
)POP(DS
);
1615 wstore(fcode_env_t
*env
)
1619 CHECK_DEPTH(env
, 2, "w!");
1620 dptr
= (wforth_t
*)POP(DS
);
1621 *dptr
= (wforth_t
)POP(DS
);
1625 cstore(fcode_env_t
*env
)
1629 CHECK_DEPTH(env
, 2, "c!");
1630 dptr
= (uchar_t
*)POP(DS
);
1631 *dptr
= (uchar_t
)POP(DS
);
1635 two_fetch(fcode_env_t
*env
)
1639 CHECK_DEPTH(env
, 1, "2@");
1640 d
= (variable_t
*)POP(DS
);
1641 PUSH(DS
, (fstack_t
)(d
+ 1));
1642 unaligned_fetch(env
);
1643 PUSH(DS
, (fstack_t
)d
);
1644 unaligned_fetch(env
);
1648 two_store(fcode_env_t
*env
)
1652 CHECK_DEPTH(env
, 3, "2!");
1653 d
= (variable_t
*)POP(DS
);
1654 PUSH(DS
, (fstack_t
)d
);
1655 unaligned_store(env
);
1656 PUSH(DS
, (fstack_t
)(d
+ 1));
1657 unaligned_store(env
);
1661 * 'move' Fcode reimplemented in fcdriver to check for mapped addresses.
1664 fc_move(fcode_env_t
*env
)
1669 CHECK_DEPTH(env
, 3, "move");
1670 len
= (size_t)POP(DS
);
1671 dest
= (void *)POP(DS
);
1672 src
= (void *)POP(DS
);
1674 memmove(dest
, src
, len
);
1678 fc_fill(fcode_env_t
*env
)
1684 CHECK_DEPTH(env
, 3, "fill");
1685 val
= (uchar_t
)POP(DS
);
1686 len
= (size_t)POP(DS
);
1687 dest
= (void *)POP(DS
);
1688 memset(dest
, val
, len
);
1692 fc_comp(fcode_env_t
*env
)
1698 CHECK_DEPTH(env
, 3, "comp");
1699 len
= (size_t)POP(DS
);
1700 str1
= (char *)POP(DS
);
1701 str2
= (char *)POP(DS
);
1702 res
= memcmp(str2
, str1
, len
);
1711 set_temporary_compile(fcode_env_t
*env
)
1714 token_roundup(env
, "set_temporary_compile");
1715 PUSH(RS
, (fstack_t
)HERE
);
1717 COMPILE_TOKEN(&do_colon
);
1722 bmark(fcode_env_t
*env
)
1724 set_temporary_compile(env
);
1726 PUSH(DS
, (fstack_t
)HERE
);
1730 temporary_execute(fcode_env_t
*env
)
1732 uchar_t
*saved_here
;
1734 if ((env
->level
== 0) && (env
->state
& 2)) {
1735 fstack_t d
= POP(RS
);
1740 /* execute the temporary definition */
1745 /* now wind the dictionary back! */
1746 if (saved_here
!= HERE
) {
1747 debug_msg(DEBUG_COMMA
, "Ignoring set_here in"
1748 " temporary_execute\n");
1750 set_here(env
, (uchar_t
*)d
, "temporary_execute");
1755 bresolve(fcode_env_t
*env
)
1757 token_t
*prev
= (token_t
*)POP(DS
);
1760 *prev
= (token_t
)HERE
;
1761 temporary_execute(env
);
1764 #define BRANCH_IP(ipp) ((token_t *)(*((token_t *)(ipp))))
1767 do_bbranch(fcode_env_t
*env
)
1773 do_bqbranch(fcode_env_t
*env
)
1777 CHECK_DEPTH(env
, 1, "b?branch");
1787 do_bofbranch(fcode_env_t
*env
)
1791 CHECK_DEPTH(env
, 2, "bofbranch");
1802 do_bleave(fcode_env_t
*env
)
1804 CHECK_RETURN_DEPTH(env
, 3, "do_bleave");
1807 IP
= (token_t
*)POP(RS
);
1811 loop_inc(fcode_env_t
*env
, fstack_t inc
)
1815 CHECK_RETURN_DEPTH(env
, 2, "loop_inc");
1818 * Note: end condition is when the sign bit of R[0] changes.
1822 if (((a
^ RS
[0]) & SIGN_BIT
) == 0) {
1830 do_bloop(fcode_env_t
*env
)
1836 do_bploop(fcode_env_t
*env
)
1840 CHECK_DEPTH(env
, 1, "+loop");
1846 loop_common(fcode_env_t
*env
, fstack_t ptr
)
1848 short offset
= get_short(env
);
1857 bloop(fcode_env_t
*env
)
1859 loop_common(env
, (fstack_t
)&do_loop_ptr
);
1863 bplusloop(fcode_env_t
*env
)
1865 loop_common(env
, (fstack_t
)&do_ploop_ptr
);
1869 common_do(fcode_env_t
*env
, fstack_t endpt
, fstack_t start
, fstack_t limit
)
1874 * Same computation as OBP, sets up so that loop_inc will terminate
1875 * when the sign bit of RS[0] changes.
1877 i
= (start
- limit
) - SIGN_BIT
;
1878 l
= limit
+ SIGN_BIT
;
1885 do_bdo(fcode_env_t
*env
)
1890 CHECK_DEPTH(env
, 2, "bdo");
1891 endpt
= (fstack_t
)BRANCH_IP(IP
);
1895 common_do(env
, endpt
, lo
, hi
);
1899 do_bqdo(fcode_env_t
*env
)
1904 CHECK_DEPTH(env
, 2, "b?do");
1905 endpt
= (fstack_t
)BRANCH_IP(IP
);
1910 IP
= (token_t
*)endpt
;
1912 common_do(env
, endpt
, lo
, hi
);
1917 compile_do_common(fcode_env_t
*env
, fstack_t ptr
)
1919 set_temporary_compile(env
);
1927 bdo(fcode_env_t
*env
)
1929 short offset
= (short)get_short(env
);
1930 compile_do_common(env
, (fstack_t
)&do_bdo_ptr
);
1934 bqdo(fcode_env_t
*env
)
1936 short offset
= (short)get_short(env
);
1937 compile_do_common(env
, (fstack_t
)&do_bqdo_ptr
);
1941 loop_i(fcode_env_t
*env
)
1945 CHECK_RETURN_DEPTH(env
, 2, "i");
1951 loop_j(fcode_env_t
*env
)
1955 CHECK_RETURN_DEPTH(env
, 5, "j");
1956 j
= RS
[-3] + RS
[-4];
1961 bleave(fcode_env_t
*env
)
1965 COMPILE_TOKEN(&do_leave_ptr
);
1970 push_string(fcode_env_t
*env
, char *str
, int len
)
1973 static int string_count
= 0;
1974 static int buflen
[NSTRINGS
];
1975 static char *buffer
[NSTRINGS
];
1983 if (len
!= buflen
[string_count
]) {
1984 if (buffer
[string_count
]) FREE(buffer
[string_count
]);
1985 buffer
[ string_count
] = (char *)MALLOC(len
+1);
1986 buflen
[ string_count
] = len
;
1988 dest
= buffer
[ string_count
++ ];
1989 string_count
= string_count
%NSTRINGS
;
1990 memcpy(dest
, str
, len
);
1992 PUSH(DS
, (fstack_t
)dest
);
1998 parse_word(fcode_env_t
*env
)
2001 char *next
, *dest
, *here
= "";
2004 here
= env
->input
->scanptr
;
2005 while (*here
== env
->input
->separator
) here
++;
2006 next
= strchr(here
, env
->input
->separator
);
2009 while (*next
== env
->input
->separator
) next
++;
2014 env
->input
->scanptr
= next
;
2016 push_string(env
, here
, len
);
2020 install_does(fcode_env_t
*env
)
2024 dptr
= (token_t
*)LINK_TO_ACF(env
->lastlink
);
2026 log_message(MSG_WARN
, "install_does: Last acf at: %p\n", (void *)dptr
);
2028 *dptr
= ((token_t
)(IP
+1)) | 1;
2032 does(fcode_env_t
*env
)
2036 token_roundup(env
, "does");
2039 COMPILE_TOKEN(&does_ptr
);
2040 COMPILE_TOKEN(&semi_ptr
);
2042 dptr
= (token_t
*)LINK_TO_ACF(env
->lastlink
);
2043 log_message(MSG_WARN
, "does: Last acf at: %p\n", (void *)dptr
);
2044 *dptr
= ((token_t
)(HERE
)) | 1;
2047 COMPILE_TOKEN(&do_colon
);
2051 do_current(fcode_env_t
*env
)
2053 debug_msg(DEBUG_CONTEXT
, "CONTEXT:pushing &CURRENT\n");
2054 PUSH(DS
, (fstack_t
)&env
->current
);
2058 do_context(fcode_env_t
*env
)
2060 debug_msg(DEBUG_CONTEXT
, "CONTEXT:pushing &CONTEXT\n");
2061 PUSH(DS
, (fstack_t
)&CONTEXT
);
2065 do_definitions(fcode_env_t
*env
)
2067 env
->current
= CONTEXT
;
2068 debug_msg(DEBUG_CONTEXT
, "CONTEXT:definitions: %d/%p/%p\n",
2069 env
->order_depth
, CONTEXT
, env
->current
);
2073 make_header(fcode_env_t
*env
, int flags
)
2078 name
= parse_a_string(env
, &len
);
2079 header(env
, name
, len
, flags
);
2083 do_creator(fcode_env_t
*env
)
2085 make_header(env
, 0);
2086 COMPILE_TOKEN(&do_create
);
2087 expose_acf(env
, "<create>");
2091 create(fcode_env_t
*env
)
2094 COMPILE_TOKEN(&create_ptr
);
2100 colon(fcode_env_t
*env
)
2102 make_header(env
, 0);
2104 COMPILE_TOKEN(&do_colon
);
2108 recursive(fcode_env_t
*env
)
2110 expose_acf(env
, "<recursive>");
2114 compile_string(fcode_env_t
*env
)
2117 uchar_t
*str
, *tostr
;
2119 COMPILE_TOKEN("e_ptr
);
2121 str
= (uchar_t
*)POP(DS
);
2127 set_here(env
, tostr
, "compile_string");
2128 token_roundup(env
, "compile_string");
2132 run_quote(fcode_env_t
*env
)
2136 osep
= env
->input
->separator
;
2137 env
->input
->separator
= '"';
2139 env
->input
->separator
= osep
;
2142 compile_string(env
);
2147 does_vocabulary(fcode_env_t
*env
)
2150 debug_msg(DEBUG_CONTEXT
, "CONTEXT:vocabulary: %d/%p/%p\n",
2151 env
->order_depth
, CONTEXT
, env
->current
);
2155 do_vocab(fcode_env_t
*env
)
2157 make_header(env
, 0);
2158 COMPILE_TOKEN(does_vocabulary
);
2161 expose_acf(env
, "<vocabulary>");
2165 do_forth(fcode_env_t
*env
)
2167 CONTEXT
= (token_t
*)(&env
->forth_voc_link
);
2168 debug_msg(DEBUG_CONTEXT
, "CONTEXT:forth: %d/%p/%p\n",
2169 env
->order_depth
, CONTEXT
, env
->current
);
2173 voc_find(fcode_env_t
*env
)
2177 char *find_name
, *name
;
2179 voc
= (token_t
*)POP(DS
);
2180 find_name
= pop_a_string(env
, NULL
);
2182 for (dptr
= (token_t
*)(*voc
); dptr
; dptr
= (token_t
*)(*dptr
)) {
2183 if ((name
= get_name(dptr
)) == NULL
)
2185 if (strcmp(find_name
, name
) == 0) {
2186 debug_msg(DEBUG_VOC_FIND
, "%s -> %p\n", find_name
,
2188 return (LINK_TO_ACF(dptr
));
2191 debug_msg(DEBUG_VOC_FIND
, "%s not found\n", find_name
);
2196 dollar_find(fcode_env_t
*env
)
2201 CHECK_DEPTH(env
, 2, "$find");
2202 for (i
= env
->order_depth
; i
>= 0 && env
->order
[i
] && !acf
; i
--) {
2204 PUSH(DS
, (fstack_t
)env
->order
[i
]);
2205 acf
= voc_find(env
);
2209 PUSH(DS
, (fstack_t
)acf
);
2216 interpret(fcode_env_t
*env
)
2230 flags
= LINK_TO_FLAGS(ACF_TO_LINK(TOS
));
2233 ((*flags
& IMMEDIATE
) == 0)) {
2234 /* Compile in references */
2246 name
= pop_a_string(env
, NULL
);
2247 log_message(MSG_INFO
, "%s?\n", name
);
2261 evaluate(fcode_env_t
*env
)
2263 input_typ
*old_input
= env
->input
;
2264 input_typ
*eval_bufp
= MALLOC(sizeof (input_typ
));
2266 CHECK_DEPTH(env
, 2, "evaluate");
2267 eval_bufp
->separator
= ' ';
2268 eval_bufp
->maxlen
= POP(DS
);
2269 eval_bufp
->buffer
= (char *)POP(DS
);
2270 eval_bufp
->scanptr
= eval_bufp
->buffer
;
2271 env
->input
= eval_bufp
;
2274 env
->input
= old_input
;
2278 make_common_access(fcode_env_t
*env
,
2279 char *name
, int len
,
2282 void (*acf_instance
)(fcode_env_t
*env
),
2283 void (*acf_static
)(fcode_env_t
*env
),
2284 void (*set_action
)(fcode_env_t
*env
, int))
2286 if (instance_mode
&& !MYSELF
) {
2287 system_message(env
, "No instance context");
2290 debug_msg(DEBUG_ACTIONS
, "make_common_access:%s '%s', %d\n",
2291 (instance_mode
? "instance" : ""),
2292 (name
? name
: ""), ncells
);
2295 header(env
, name
, len
, 0);
2296 if (instance_mode
) {
2300 COMPILE_TOKEN(acf_instance
);
2301 dptr
= alloc_instance_data(env
, INIT_DATA
, ncells
, &offset
);
2302 debug_msg(DEBUG_ACTIONS
, "Data: %p, offset %d\n", (char *)dptr
,
2307 *dptr
++ = MYSELF
->data
[INIT_DATA
][offset
++] = POP(DS
);
2308 env
->instance_mode
= 0;
2310 COMPILE_TOKEN(acf_static
);
2314 expose_acf(env
, name
);
2316 set_action(env
, instance_mode
);
2320 do_constant(fcode_env_t
*env
)
2322 PUSH(DS
, (variable_t
)(*WA
));
2326 do_crash(fcode_env_t
*env
)
2328 forth_abort(env
, "Unitialized defer");
2332 * 'behavior' Fcode retrieve execution behavior for a defer word.
2335 behavior(fcode_env_t
*env
)
2341 CHECK_DEPTH(env
, 1, "behavior");
2342 defer_xt
= (acf_t
)POP(DS
);
2344 contents_xt
= (token_t
*)(token
& ~1);
2345 if ((token
& 1) == 0 || *contents_xt
!= (token_t
)&do_default_action
)
2346 forth_abort(env
, "behavior: bad xt: %p indir: %x/%p\n",
2347 defer_xt
, token
& 1, *contents_xt
);
2349 PUSH(DS
, *((variable_t
*)defer_xt
));
2353 fc_abort(fcode_env_t
*env
, char *type
)
2355 forth_abort(env
, "%s Fcode '%s' Executed", type
,
2356 acf_to_name(env
, WA
- 1));
2360 f_abort(fcode_env_t
*env
)
2362 fc_abort(env
, "Abort");
2366 * Fcodes chosen not to support.
2369 fc_unimplemented(fcode_env_t
*env
)
2371 fc_abort(env
, "Unimplemented");
2375 * Fcodes that are Obsolete per P1275-1994.
2378 fc_obsolete(fcode_env_t
*env
)
2380 fc_abort(env
, "Obsolete");
2384 * Fcodes that are Historical per P1275-1994
2387 fc_historical(fcode_env_t
*env
)
2389 fc_abort(env
, "Historical");
2393 catch(fcode_env_t
*env
)
2397 CHECK_DEPTH(env
, 1, "catch");
2398 new = MALLOC(sizeof (error_frame
));
2401 new->myself
= MYSELF
;
2402 new->next
= env
->catch_frame
;
2404 env
->catch_frame
= new;
2406 PUSH(DS
, new->code
);
2407 env
->catch_frame
= new->next
;
2412 throw_from_fclib(fcode_env_t
*env
, fstack_t errcode
, char *fmt
, ...)
2419 vsprintf(msg
, fmt
, ap
);
2423 env
->last_error
= errcode
;
2426 * No catch frame set => fatal error
2428 efp
= env
->catch_frame
;
2430 forth_abort(env
, "%s: No catch frame", msg
);
2432 debug_msg(DEBUG_TRACING
, "throw_from_fclib: throw: %s\n", msg
);
2435 * Setting IP=0 will force the unwinding of the calls
2436 * (see execute) which is how we will return (eventually)
2437 * to the test in catch that follows 'execute'.
2441 MYSELF
= efp
->myself
;
2443 efp
->code
= errcode
;
2448 throw(fcode_env_t
*env
)
2452 CHECK_DEPTH(env
, 1, "throw");
2454 if (t
>= -20 && t
<= 20)
2455 throw_from_fclib(env
, t
, "throw Fcode errcode: 0x%x", (int)t
);
2458 log_message(MSG_ERROR
, "throw: errcode: 0x%x\n",
2460 throw_from_fclib(env
, t
, "throw Fcode err: %s", (char *)t
);
2465 tick_literal(fcode_env_t
*env
)
2468 COMPILE_TOKEN(&tlit_ptr
);
2474 do_tick(fcode_env_t
*env
)
2484 bracket_tick(fcode_env_t
*env
)
2494 fcode_env_t
*env
= initial_env
;
2499 ANSI(0x019, 0, "i", loop_i
);
2500 ANSI(0x01a, 0, "j", loop_j
);
2501 ANSI(0x01d, 0, "execute", execute
);
2502 ANSI(0x01e, 0, "+", add
);
2503 ANSI(0x01f, 0, "-", subtract
);
2504 ANSI(0x020, 0, "*", multiply
);
2505 ANSI(0x021, 0, "/", divide
);
2506 ANSI(0x022, 0, "mod", mod
);
2507 FORTH(0, "/mod", slash_mod
);
2508 ANSI(0x023, 0, "and", and);
2509 ANSI(0x024, 0, "or", or);
2510 ANSI(0x025, 0, "xor", xor);
2511 ANSI(0x026, 0, "invert", invert
);
2512 ANSI(0x027, 0, "lshift", lshift
);
2513 ANSI(0x028, 0, "rshift", rshift
);
2514 ANSI(0x029, 0, ">>a", rshifta
);
2515 ANSI(0x02a, 0, "/mod", slash_mod
);
2516 ANSI(0x02b, 0, "u/mod", uslash_mod
);
2517 ANSI(0x02c, 0, "negate", negate
);
2518 ANSI(0x02d, 0, "abs", f_abs
);
2519 ANSI(0x02e, 0, "min", f_min
);
2520 ANSI(0x02f, 0, "max", f_max
);
2521 ANSI(0x030, 0, ">r", to_r
);
2522 ANSI(0x031, 0, "r>", from_r
);
2523 ANSI(0x032, 0, "r@", rfetch
);
2524 ANSI(0x033, 0, "exit", f_exit
);
2525 ANSI(0x034, 0, "0=", zero_equals
);
2526 ANSI(0x035, 0, "0<>", zero_not_equals
);
2527 ANSI(0x036, 0, "0<", zero_less
);
2528 ANSI(0x037, 0, "0<=", zero_less_equals
);
2529 ANSI(0x038, 0, "0>", zero_greater
);
2530 ANSI(0x039, 0, "0>=", zero_greater_equals
);
2531 ANSI(0x03a, 0, "<", less
);
2532 ANSI(0x03b, 0, ">", greater
);
2533 ANSI(0x03c, 0, "=", equals
);
2534 ANSI(0x03d, 0, "<>", not_equals
);
2535 ANSI(0x03e, 0, "u>", unsign_greater
);
2536 ANSI(0x03f, 0, "u<=", unsign_less_equals
);
2537 ANSI(0x040, 0, "u<", unsign_less
);
2538 ANSI(0x041, 0, "u>=", unsign_greater_equals
);
2539 ANSI(0x042, 0, ">=", greater_equals
);
2540 ANSI(0x043, 0, "<=", less_equals
);
2541 ANSI(0x044, 0, "between", between
);
2542 ANSI(0x045, 0, "within", within
);
2543 ANSI(0x046, 0, "drop", drop
);
2544 ANSI(0x047, 0, "dup", f_dup
);
2545 ANSI(0x048, 0, "over", over
);
2546 ANSI(0x049, 0, "swap", swap
);
2547 ANSI(0x04a, 0, "rot", rot
);
2548 ANSI(0x04b, 0, "-rot", minus_rot
);
2549 ANSI(0x04c, 0, "tuck", tuck
);
2550 ANSI(0x04d, 0, "nip", nip
);
2551 ANSI(0x04e, 0, "pick", pick
);
2552 ANSI(0x04f, 0, "roll", roll
);
2553 ANSI(0x050, 0, "?dup", qdup
);
2554 ANSI(0x051, 0, "depth", depth
);
2555 ANSI(0x052, 0, "2drop", two_drop
);
2556 ANSI(0x053, 0, "2dup", two_dup
);
2557 ANSI(0x054, 0, "2over", two_over
);
2558 ANSI(0x055, 0, "2swap", two_swap
);
2559 ANSI(0x056, 0, "2rot", two_rot
);
2560 ANSI(0x057, 0, "2/", two_slash
);
2561 ANSI(0x058, 0, "u2/", utwo_slash
);
2562 ANSI(0x059, 0, "2*", two_times
);
2563 ANSI(0x05a, 0, "/c", slash_c
);
2564 ANSI(0x05b, 0, "/w", slash_w
);
2565 ANSI(0x05c, 0, "/l", slash_l
);
2566 ANSI(0x05d, 0, "/n", slash_n
);
2567 ANSI(0x05e, 0, "ca+", ca_plus
);
2568 ANSI(0x05f, 0, "wa+", wa_plus
);
2569 ANSI(0x060, 0, "la+", la_plus
);
2570 ANSI(0x061, 0, "na+", na_plus
);
2571 ANSI(0x062, 0, "char+", char_plus
);
2572 ANSI(0x063, 0, "wa1+", wa1_plus
);
2573 ANSI(0x064, 0, "la1+", la1_plus
);
2574 ANSI(0x065, 0, "cell+", cell_plus
);
2575 ANSI(0x066, 0, "chars", do_chars
);
2576 ANSI(0x067, 0, "/w*", slash_w_times
);
2577 ANSI(0x068, 0, "/l*", slash_l_times
);
2578 ANSI(0x069, 0, "cells", cells
);
2579 ANSI(0x06a, 0, "on", do_on
);
2580 ANSI(0x06b, 0, "off", do_off
);
2581 ANSI(0x06c, 0, "+!", addstore
);
2582 ANSI(0x06d, 0, "@", fetch
);
2583 ANSI(0x06e, 0, "l@", lfetch
);
2584 ANSI(0x06f, 0, "w@", wfetch
);
2585 ANSI(0x070, 0, "<w@", swfetch
);
2586 ANSI(0x071, 0, "c@", cfetch
);
2587 ANSI(0x072, 0, "!", store
);
2588 ANSI(0x073, 0, "l!", lstore
);
2589 ANSI(0x074, 0, "w!", wstore
);
2590 ANSI(0x075, 0, "c!", cstore
);
2591 ANSI(0x076, 0, "2@", two_fetch
);
2592 ANSI(0x077, 0, "2!", two_store
);
2593 ANSI(0x078, 0, "move", fc_move
);
2594 ANSI(0x079, 0, "fill", fc_fill
);
2595 ANSI(0x07a, 0, "comp", fc_comp
);
2596 ANSI(0x07b, 0, "noop", noop
);
2597 ANSI(0x07c, 0, "lwsplit", lwsplit
);
2598 ANSI(0x07d, 0, "wljoin", wljoin
);
2599 ANSI(0x07e, 0, "lbsplit", lbsplit
);
2600 ANSI(0x07f, 0, "bljoin", bljoin
);
2601 ANSI(0x080, 0, "wbflip", wbflip
);
2602 ANSI(0x081, 0, "upc", upper_case
);
2603 ANSI(0x082, 0, "lcc", lower_case
);
2604 ANSI(0x083, 0, "pack", pack_str
);
2605 ANSI(0x084, 0, "count", count_str
);
2606 ANSI(0x085, 0, "body>", to_acf
);
2607 ANSI(0x086, 0, ">body", to_body
);
2609 ANSI(0x089, 0, "unloop", unloop
);
2611 ANSI(0x09f, 0, ".s", dot_s
);
2612 ANSI(0x0a0, 0, "base", base
);
2613 FCODE(0x0a1, 0, "convert", fc_historical
);
2614 ANSI(0x0a2, 0, "$number", dollar_number
);
2615 ANSI(0x0a3, 0, "digit", digit
);
2617 ANSI(0x0a9, 0, "bl", space
);
2618 ANSI(0x0aa, 0, "bs", backspace
);
2619 ANSI(0x0ab, 0, "bell", bell
);
2620 ANSI(0x0ac, 0, "bounds", fc_bounds
);
2621 ANSI(0x0ad, 0, "here", here
);
2623 ANSI(0x0af, 0, "wbsplit", wbsplit
);
2624 ANSI(0x0b0, 0, "bwjoin", bwjoin
);
2626 P1275(0x0cb, 0, "$find", dollar_find
);
2628 ANSI(0x0d0, 0, "c,", ccomma
);
2629 ANSI(0x0d1, 0, "w,", wcomma
);
2630 ANSI(0x0d2, 0, "l,", lcomma
);
2631 ANSI(0x0d3, 0, ",", comma
);
2632 ANSI(0x0d4, 0, "um*", um_multiply
);
2633 ANSI(0x0d5, 0, "um/mod", um_slash_mod
);
2635 ANSI(0x0d8, 0, "d+", d_plus
);
2636 ANSI(0x0d9, 0, "d-", d_minus
);
2638 ANSI(0x0dc, 0, "state", state
);
2639 ANSI(0x0de, 0, "behavior", behavior
);
2640 ANSI(0x0dd, 0, "compile,", compile_comma
);
2642 ANSI(0x216, 0, "abort", f_abort
);
2643 ANSI(0x217, 0, "catch", catch);
2644 ANSI(0x218, 0, "throw", throw);
2646 ANSI(0x226, 0, "lwflip", lwflip
);
2647 ANSI(0x227, 0, "lbflip", lbflip
);
2648 ANSI(0x228, 0, "lbflips", lbflips
);
2650 ANSI(0x236, 0, "wbflips", wbflips
);
2651 ANSI(0x237, 0, "lwflips", lwflips
);
2653 FORTH(0, "forth", do_forth
);
2654 FORTH(0, "current", do_current
);
2655 FORTH(0, "context", do_context
);
2656 FORTH(0, "definitions", do_definitions
);
2657 FORTH(0, "vocabulary", do_vocab
);
2658 FORTH(IMMEDIATE
, ":", colon
);
2659 FORTH(IMMEDIATE
, ";", semi
);
2660 FORTH(IMMEDIATE
, "create", create
);
2661 FORTH(IMMEDIATE
, "does>", does
);
2662 FORTH(IMMEDIATE
, "recursive", recursive
);
2663 FORTH(0, "parse-word", parse_word
);
2664 FORTH(IMMEDIATE
, "\"", run_quote
);
2665 FORTH(IMMEDIATE
, "order", do_order
);
2666 FORTH(IMMEDIATE
, "also", do_also
);
2667 FORTH(IMMEDIATE
, "previous", do_previous
);
2668 FORTH(IMMEDIATE
, "'", do_tick
);
2669 FORTH(IMMEDIATE
, "[']", bracket_tick
);
2670 FORTH(0, "unaligned-l@", unaligned_lfetch
);
2671 FORTH(0, "unaligned-l!", unaligned_lstore
);
2672 FORTH(0, "unaligned-w@", unaligned_wfetch
);
2673 FORTH(0, "unaligned-w!", unaligned_wstore
);